1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef IR_REPRESENTATION_H_
16 #define IR_REPRESENTATION_H_
17
18 #include <list>
19 #include <map>
20 #include <memory>
21 #include <set>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25
26
27 namespace header_checker {
28 namespace repr {
29
30
31 // Classes which act as middle-men between clang AST parsing routines and
32 // message format specific dumpers.
33
34 template <typename T>
35 using AbiElementMap = std::map<std::string, T>;
36
37 template <typename T>
38 using AbiElementUnorderedMap = std::unordered_map<std::string, T>;
39
40 enum TextFormatIR {
41 ProtobufTextFormat = 0,
42 Json = 1,
43 };
44
45 enum CompatibilityStatusIR {
46 Compatible = 0,
47 UnreferencedChanges = 1,
48 Extension = 4,
49 Incompatible = 8,
50 ElfIncompatible = 16
51 };
52
53 static inline CompatibilityStatusIR operator|(CompatibilityStatusIR f,
54 CompatibilityStatusIR s) {
55 return static_cast<CompatibilityStatusIR>(
56 static_cast<std::underlying_type<CompatibilityStatusIR>::type>(f) |
57 static_cast<std::underlying_type<CompatibilityStatusIR>::type>(s));
58 }
59
60 static inline CompatibilityStatusIR operator&(CompatibilityStatusIR f,
61 CompatibilityStatusIR s) {
62 return static_cast<CompatibilityStatusIR>(
63 static_cast<std::underlying_type<CompatibilityStatusIR>::type>(f) &
64 static_cast<std::underlying_type<CompatibilityStatusIR>::type>(s));
65 }
66
67 enum AccessSpecifierIR {
68 PublicAccess = 1,
69 ProtectedAccess = 2,
70 PrivateAccess = 3
71 };
72
IsAccessDowngraded(AccessSpecifierIR old_access,AccessSpecifierIR new_access)73 static inline bool IsAccessDowngraded(AccessSpecifierIR old_access,
74 AccessSpecifierIR new_access) {
75 return old_access < new_access;
76 }
77
78 enum LinkableMessageKind {
79 RecordTypeKind,
80 EnumTypeKind,
81 PointerTypeKind,
82 QualifiedTypeKind,
83 ArrayTypeKind,
84 LvalueReferenceTypeKind,
85 RvalueReferenceTypeKind,
86 BuiltinTypeKind,
87 FunctionTypeKind,
88 FunctionKind,
89 GlobalVarKind
90 };
91
92 template <typename K, typename V>
CreateInverseMap(const std::map<K,V> & m)93 std::map<V, K> CreateInverseMap(const std::map<K, V> &m) {
94 std::map<V, K> inverse_map;
95 for (auto it : m) {
96 inverse_map[it.second] = it.first;
97 }
98 return inverse_map;
99 }
100
FormatMultiDefinitionTypeId(const std::string & type_id,const std::string & compilation_unit_path)101 static inline std::string FormatMultiDefinitionTypeId(
102 const std::string &type_id, const std::string &compilation_unit_path) {
103 return type_id + "#ODR:" + compilation_unit_path;
104 }
105
ExtractMultiDefinitionTypeId(std::string_view type_id)106 static inline std::string_view ExtractMultiDefinitionTypeId(
107 std::string_view type_id) {
108 return type_id.substr(0, type_id.find("#ODR:"));
109 }
110
111 class LinkableMessageIR {
112 public:
~LinkableMessageIR()113 virtual ~LinkableMessageIR() {}
114
GetLinkerSetKey()115 const std::string &GetLinkerSetKey() const {
116 return linker_set_key_;
117 }
118
SetSourceFile(const std::string & source_file)119 void SetSourceFile(const std::string &source_file) {
120 source_file_ = source_file;
121 }
122
SetLinkerSetKey(const std::string & linker_set_key)123 void SetLinkerSetKey(const std::string &linker_set_key) {
124 linker_set_key_ = linker_set_key;
125 }
126
GetSourceFile()127 const std::string &GetSourceFile() const {
128 return source_file_;
129 }
130
131 virtual LinkableMessageKind GetKind() const = 0;
132
133 protected:
134 // The source file where this message comes from. This will be an empty string
135 // for built-in types.
136 std::string source_file_;
137 std::string linker_set_key_;
138 };
139
140 class ReferencesOtherType {
141 public:
ReferencesOtherType(const std::string & referenced_type)142 ReferencesOtherType(const std::string &referenced_type)
143 : referenced_type_(referenced_type) {}
144
ReferencesOtherType(std::string && referenced_type)145 ReferencesOtherType(std::string &&referenced_type)
146 : referenced_type_(std::move(referenced_type)) {}
147
ReferencesOtherType()148 ReferencesOtherType() {}
149
SetReferencedType(const std::string & referenced_type)150 void SetReferencedType(const std::string &referenced_type) {
151 referenced_type_ = referenced_type;
152 }
153
GetReferencedType()154 const std::string &GetReferencedType() const {
155 return referenced_type_;
156 }
157
158 protected:
159 std::string referenced_type_;
160 };
161
162 // TODO: Break this up into types with sizes and those without types?
163 class TypeIR : public LinkableMessageIR, public ReferencesOtherType {
164 public:
~TypeIR()165 virtual ~TypeIR() {}
166
SetSelfType(const std::string & self_type)167 void SetSelfType(const std::string &self_type) {
168 self_type_ = self_type;
169 }
170
GetSelfType()171 const std::string &GetSelfType() const {
172 return self_type_;
173 }
174
SetName(const std::string & name)175 void SetName(const std::string &name) {
176 name_ = name;
177 }
178
GetName()179 const std::string &GetName() const {
180 return name_;
181 }
182
SetSize(uint64_t size)183 void SetSize(uint64_t size) {
184 size_ = size;
185 }
186
GetSize()187 uint64_t GetSize() const {
188 return size_;
189 }
190
SetAlignment(uint32_t alignment)191 void SetAlignment(uint32_t alignment) {
192 alignment_ = alignment;
193 }
194
GetAlignment()195 uint32_t GetAlignment() const {
196 return alignment_;
197 }
198
199 protected:
200 std::string name_;
201 std::string self_type_;
202 uint64_t size_ = 0;
203 uint32_t alignment_ = 0;
204 };
205
206 class VTableComponentIR {
207 public:
208 enum Kind {
209 VCallOffset = 0,
210 VBaseOffset = 1,
211 OffsetToTop = 2,
212 RTTI = 3,
213 FunctionPointer = 4,
214 CompleteDtorPointer = 5,
215 DeletingDtorPointer = 6,
216 UnusedFunctionPointer = 7
217 };
218
VTableComponentIR(const std::string & name,Kind kind,int64_t value,bool is_pure)219 VTableComponentIR(const std::string &name, Kind kind, int64_t value,
220 bool is_pure)
221 : component_name_(name), kind_(kind), value_(value), is_pure_(is_pure) {}
222
VTableComponentIR()223 VTableComponentIR() {}
224
GetKind()225 Kind GetKind() const {
226 return kind_;
227 }
228
GetValue()229 int64_t GetValue() const {
230 return value_;
231 }
232
GetName()233 const std::string &GetName() const {
234 return component_name_;
235 }
236
GetIsPure()237 bool GetIsPure() const {
238 return is_pure_;
239 }
240
241 protected:
242 std::string component_name_;
243 Kind kind_;
244 int64_t value_ = 0;
245 bool is_pure_;
246 };
247
248 class VTableLayoutIR {
249 public:
AddVTableComponent(VTableComponentIR && vtable_component)250 void AddVTableComponent(VTableComponentIR &&vtable_component) {
251 vtable_components_.emplace_back(std::move(vtable_component));
252 }
253
GetVTableComponents()254 const std::vector<VTableComponentIR> &GetVTableComponents() const {
255 return vtable_components_;
256 }
257
GetVTableNumEntries()258 uint64_t GetVTableNumEntries() const {
259 return vtable_components_.size();
260 }
261
262 protected:
263 std::vector<VTableComponentIR> vtable_components_;
264 };
265
266 class CXXBaseSpecifierIR : public ReferencesOtherType {
267 public:
CXXBaseSpecifierIR(const std::string & type,bool is_virtual,AccessSpecifierIR access)268 CXXBaseSpecifierIR(const std::string &type, bool is_virtual,
269 AccessSpecifierIR access)
270 : ReferencesOtherType(type), is_virtual_(is_virtual), access_(access) {}
271
CXXBaseSpecifierIR()272 CXXBaseSpecifierIR() {}
273
IsVirtual()274 bool IsVirtual() const {
275 return is_virtual_;
276 }
277
GetAccess()278 AccessSpecifierIR GetAccess() const {
279 return access_;
280 }
281
282 protected:
283 bool is_virtual_ = false;
284 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
285 };
286
287 class TemplateElementIR : public ReferencesOtherType {
288 public:
TemplateElementIR(std::string && type)289 TemplateElementIR(std::string &&type)
290 : ReferencesOtherType(std::move(type)) {}
291
TemplateElementIR(const std::string & type)292 TemplateElementIR(const std::string &type)
293 : ReferencesOtherType(type) {}
294
TemplateElementIR()295 TemplateElementIR() {}
296 };
297
298 class TemplateInfoIR {
299 public:
AddTemplateElement(TemplateElementIR && element)300 void AddTemplateElement(TemplateElementIR &&element) {
301 template_elements_.emplace_back(element);
302 }
303
GetTemplateElements()304 const std::vector<TemplateElementIR> &GetTemplateElements() const {
305 return template_elements_;
306 }
307
GetTemplateElements()308 std::vector<TemplateElementIR> &GetTemplateElements() {
309 return template_elements_;
310 }
311
312 protected:
313 std::vector<TemplateElementIR> template_elements_;
314 };
315
316 class TemplatedArtifactIR {
317 public:
SetTemplateInfo(TemplateInfoIR && template_info)318 void SetTemplateInfo(TemplateInfoIR &&template_info) {
319 template_info_ = std::move(template_info);
320 }
321
GetTemplateElements()322 const std::vector<TemplateElementIR> &GetTemplateElements() const {
323 return template_info_.GetTemplateElements();
324 }
325
GetTemplateElements()326 std::vector<TemplateElementIR> &GetTemplateElements() {
327 return template_info_.GetTemplateElements();
328 }
329
330 protected:
331 TemplateInfoIR template_info_;
332 };
333
334 class RecordFieldIR : public ReferencesOtherType {
335 public:
RecordFieldIR(const std::string & name,const std::string & type,uint64_t offset,AccessSpecifierIR access)336 RecordFieldIR(const std::string &name, const std::string &type,
337 uint64_t offset, AccessSpecifierIR access)
338 : ReferencesOtherType(type), name_(name), offset_(offset),
339 access_(access) {}
340
RecordFieldIR()341 RecordFieldIR() {}
342
GetName()343 const std::string &GetName() const {
344 return name_;
345 }
346
GetOffset()347 uint64_t GetOffset() const {
348 return offset_;
349 }
350
GetAccess()351 AccessSpecifierIR GetAccess() const {
352 return access_;
353 }
354
355 protected:
356 std::string name_;
357 uint64_t offset_ = 0;
358 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
359 };
360
361 class RecordTypeIR : public TypeIR, public TemplatedArtifactIR {
362 public:
363 enum RecordKind {
364 struct_kind,
365 class_kind,
366 union_kind
367 };
368
AddRecordField(RecordFieldIR && field)369 void AddRecordField(RecordFieldIR &&field) {
370 fields_.emplace_back(std::move(field));
371 }
372
SetRecordFields(std::vector<RecordFieldIR> && fields)373 void SetRecordFields(std::vector<RecordFieldIR> &&fields) {
374 fields_ = std::move(fields);
375 }
376
SetVTableLayout(VTableLayoutIR && vtable_layout)377 void SetVTableLayout(VTableLayoutIR &&vtable_layout) {
378 vtable_layout_ = std::move(vtable_layout);
379 }
380
GetVTableLayout()381 const VTableLayoutIR &GetVTableLayout() const {
382 return vtable_layout_;
383 }
384
AddCXXBaseSpecifier(CXXBaseSpecifierIR && base_specifier)385 void AddCXXBaseSpecifier(CXXBaseSpecifierIR &&base_specifier) {
386 bases_.emplace_back(std::move(base_specifier));
387 }
388
SetCXXBaseSpecifiers(std::vector<CXXBaseSpecifierIR> && bases)389 void SetCXXBaseSpecifiers(std::vector<CXXBaseSpecifierIR> &&bases) {
390 bases_ = std::move(bases);
391 }
392
GetBases()393 const std::vector<CXXBaseSpecifierIR> &GetBases() const {
394 return bases_;
395 }
396
GetBases()397 std::vector<CXXBaseSpecifierIR> &GetBases() {
398 return bases_;
399 }
400
SetAccess(AccessSpecifierIR access)401 void SetAccess(AccessSpecifierIR access) { access_ = access;}
402
GetAccess()403 AccessSpecifierIR GetAccess() const {
404 return access_;
405 }
406
GetFields()407 const std::vector<RecordFieldIR> &GetFields() const {
408 return fields_;
409 }
410
GetFields()411 std::vector<RecordFieldIR> &GetFields() {
412 return fields_;
413 }
414
GetKind()415 LinkableMessageKind GetKind() const override {
416 return LinkableMessageKind::RecordTypeKind;
417 }
418
GetVTableNumEntries()419 uint64_t GetVTableNumEntries() const {
420 return vtable_layout_.GetVTableNumEntries();
421 }
422
SetRecordKind(RecordKind record_kind)423 void SetRecordKind(RecordKind record_kind) {
424 record_kind_ = record_kind;
425 }
426
GetRecordKind()427 RecordKind GetRecordKind() const {
428 return record_kind_;
429 }
430
SetAnonymity(bool is_anonymous)431 void SetAnonymity(bool is_anonymous) {
432 is_anonymous_ = is_anonymous;
433 }
434
IsAnonymous()435 bool IsAnonymous() const {
436 return is_anonymous_;
437 }
438
439 protected:
440 std::vector<RecordFieldIR> fields_;
441 VTableLayoutIR vtable_layout_;
442 std::vector<CXXBaseSpecifierIR> bases_;
443 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
444 bool is_anonymous_ = false;
445 RecordKind record_kind_;
446 };
447
448 class EnumFieldIR {
449 public:
EnumFieldIR(const std::string & name,int64_t value)450 EnumFieldIR(const std::string &name, int64_t value)
451 : name_(name), signed_value_(value), is_signed_(true) {}
452
EnumFieldIR(const std::string & name,uint64_t value)453 EnumFieldIR(const std::string &name, uint64_t value)
454 : name_(name), unsigned_value_(value), is_signed_(false) {}
455
GetName()456 const std::string &GetName() const {
457 return name_;
458 }
459
IsSigned()460 bool IsSigned() const { return is_signed_; }
461
GetSignedValue()462 int64_t GetSignedValue() const { return signed_value_; }
463
GetUnsignedValue()464 uint64_t GetUnsignedValue() const { return unsigned_value_; }
465
466 protected:
467 std::string name_;
468 union {
469 int64_t signed_value_;
470 uint64_t unsigned_value_;
471 };
472 bool is_signed_;
473 };
474
475 class EnumTypeIR : public TypeIR {
476 public:
477 // Add Methods to get information from the IR.
AddEnumField(EnumFieldIR && field)478 void AddEnumField(EnumFieldIR &&field) {
479 fields_.emplace_back(std::move(field));
480 }
481
SetAccess(AccessSpecifierIR access)482 void SetAccess(AccessSpecifierIR access) { access_ = access;}
483
GetKind()484 LinkableMessageKind GetKind() const override {
485 return LinkableMessageKind::EnumTypeKind;
486 }
487
GetAccess()488 AccessSpecifierIR GetAccess() const {
489 return access_;
490 }
491
SetUnderlyingType(std::string && underlying_type)492 void SetUnderlyingType(std::string &&underlying_type) {
493 underlying_type_ = std::move(underlying_type);
494 }
495
SetUnderlyingType(const std::string & underlying_type)496 void SetUnderlyingType(const std::string &underlying_type) {
497 underlying_type_ = underlying_type;
498 }
499
GetUnderlyingType()500 const std::string &GetUnderlyingType() const {
501 return underlying_type_;
502 }
503
SetFields(std::vector<EnumFieldIR> && fields)504 void SetFields(std::vector<EnumFieldIR> &&fields) {
505 fields_ = std::move(fields);
506 }
507
GetFields()508 const std::vector<EnumFieldIR> &GetFields() const {
509 return fields_;
510 }
511
512 protected:
513 std::vector<EnumFieldIR> fields_;
514 std::string underlying_type_;
515 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
516 };
517
518 class ArrayTypeIR : public TypeIR {
519 public:
SetUnknownBound(bool is_of_unknown_bound)520 void SetUnknownBound(bool is_of_unknown_bound) {
521 is_of_unknown_bound_ = is_of_unknown_bound;
522 }
523
IsOfUnknownBound()524 bool IsOfUnknownBound() const { return is_of_unknown_bound_; }
525
GetKind()526 LinkableMessageKind GetKind() const override {
527 return LinkableMessageKind::ArrayTypeKind;
528 }
529
530 private:
531 bool is_of_unknown_bound_ = false;
532 };
533
534 class PointerTypeIR : public TypeIR {
535 public:
GetKind()536 LinkableMessageKind GetKind() const override {
537 return LinkableMessageKind::PointerTypeKind;
538 }
539 };
540
541 class BuiltinTypeIR : public TypeIR {
542 public:
SetSignedness(bool is_unsigned)543 void SetSignedness(bool is_unsigned) {
544 is_unsigned_ = is_unsigned;
545 }
546
IsUnsigned()547 bool IsUnsigned() const {
548 return is_unsigned_;
549 }
550
SetIntegralType(bool is_integral_type)551 void SetIntegralType(bool is_integral_type) {
552 is_integral_type_ = is_integral_type;
553 }
554
IsIntegralType()555 bool IsIntegralType() const {
556 return is_integral_type_;
557 }
558
559 public:
GetKind()560 LinkableMessageKind GetKind() const override {
561 return LinkableMessageKind::BuiltinTypeKind;
562 }
563
564 protected:
565 bool is_unsigned_ = false;
566 bool is_integral_type_ = false;
567 };
568
569 class LvalueReferenceTypeIR : public TypeIR {
570 public:
GetKind()571 LinkableMessageKind GetKind() const override {
572 return LinkableMessageKind::LvalueReferenceTypeKind;
573 }
574 };
575
576 class RvalueReferenceTypeIR : public TypeIR {
577 public:
GetKind()578 LinkableMessageKind GetKind() const override {
579 return LinkableMessageKind::RvalueReferenceTypeKind;
580 }
581 };
582
583 class QualifiedTypeIR : public TypeIR {
584 public:
SetConstness(bool is_const)585 void SetConstness(bool is_const) {
586 is_const_ = is_const;
587 }
588
IsConst()589 bool IsConst() const {
590 return is_const_;
591 }
592
SetRestrictedness(bool is_restricted)593 void SetRestrictedness(bool is_restricted) {
594 is_restricted_ = is_restricted;
595 }
596
IsRestricted()597 bool IsRestricted() const {
598 return is_restricted_;
599 }
600
SetVolatility(bool is_volatile)601 void SetVolatility(bool is_volatile) {
602 is_volatile_ = is_volatile;
603 }
604
IsVolatile()605 bool IsVolatile() const {
606 return is_volatile_;
607 }
608
609 public:
GetKind()610 LinkableMessageKind GetKind() const override {
611 return LinkableMessageKind::QualifiedTypeKind;
612 }
613
614 protected:
615 bool is_const_;
616 bool is_restricted_;
617 bool is_volatile_;
618 };
619
620 class GlobalVarIR : public LinkableMessageIR , public ReferencesOtherType {
621 public:
622 // Add Methods to get information from the IR.
SetName(std::string && name)623 void SetName(std::string &&name) {
624 name_ = std::move(name);
625 }
626
SetName(const std::string & name)627 void SetName(const std::string &name) {
628 name_ = name;
629 }
630
GetName()631 const std::string &GetName() const {
632 return name_;
633 }
634
SetAccess(AccessSpecifierIR access)635 void SetAccess(AccessSpecifierIR access) {
636 access_ = access;
637 }
638
GetAccess()639 AccessSpecifierIR GetAccess() const {
640 return access_;
641 }
642
GetKind()643 LinkableMessageKind GetKind() const override {
644 return LinkableMessageKind::GlobalVarKind;
645 }
646
647 protected:
648 std::string name_;
649 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
650 };
651
652 class ParamIR : public ReferencesOtherType {
653 public:
ParamIR(const std::string & type,bool is_default,bool is_this_ptr)654 ParamIR(const std::string &type, bool is_default, bool is_this_ptr)
655 : ReferencesOtherType(type) , is_default_(is_default),
656 is_this_ptr_(is_this_ptr) {}
657
GetIsDefault()658 bool GetIsDefault() const {
659 return is_default_;
660 }
661
GetIsThisPtr()662 bool GetIsThisPtr() const {
663 return is_this_ptr_;
664 }
665
666 protected:
667 bool is_default_ = false;
668 bool is_this_ptr_ = false;
669 };
670
671 class CFunctionLikeIR {
672 public:
SetReturnType(const std::string & type)673 void SetReturnType(const std::string &type) {
674 return_type_ = type;
675 }
676
GetReturnType()677 const std::string &GetReturnType() const {
678 return return_type_;
679 }
680
AddParameter(ParamIR && parameter)681 void AddParameter(ParamIR &¶meter) {
682 parameters_.emplace_back(std::move(parameter));
683 }
684
GetParameters()685 const std::vector<ParamIR> &GetParameters() const {
686 return parameters_;
687 }
688
GetParameters()689 std::vector<ParamIR> &GetParameters() {
690 return parameters_;
691 }
692
693 protected:
694 std::string return_type_; // return type reference
695 std::vector<ParamIR> parameters_;
696 };
697
698 class FunctionTypeIR : public TypeIR, public CFunctionLikeIR {
699 public:
GetKind()700 LinkableMessageKind GetKind() const override {
701 return LinkableMessageKind::FunctionTypeKind;
702 }
703 };
704
705 class FunctionIR : public LinkableMessageIR, public TemplatedArtifactIR,
706 public CFunctionLikeIR {
707 public:
SetAccess(AccessSpecifierIR access)708 void SetAccess(AccessSpecifierIR access) {
709 access_ = access;
710 }
711
GetAccess()712 AccessSpecifierIR GetAccess() const {
713 return access_;
714 }
715
GetKind()716 LinkableMessageKind GetKind() const override {
717 return LinkableMessageKind::FunctionKind;
718 }
719
SetName(const std::string & name)720 void SetName(const std::string &name) {
721 name_ = name;
722 }
723
GetName()724 const std::string &GetName() const {
725 return name_;
726 }
727
728 protected:
729 std::string linkage_name_;
730 std::string name_;
731 AccessSpecifierIR access_ = AccessSpecifierIR::PublicAccess;
732 };
733
734 class ElfSymbolIR {
735 public:
736 enum ElfSymbolKind {
737 ElfFunctionKind,
738 ElfObjectKind,
739 };
740
741 enum ElfSymbolBinding {
742 Weak,
743 Global,
744 };
745
746 enum ElfSymbolVisibility {
747 Default,
748 Protected,
749 };
750
751 public:
ElfSymbolIR(const std::string & name,ElfSymbolBinding binding)752 ElfSymbolIR(const std::string &name, ElfSymbolBinding binding)
753 : name_(name), binding_(binding) {}
754
~ElfSymbolIR()755 virtual ~ElfSymbolIR() {}
756
GetName()757 const std::string GetName() const {
758 return name_;
759 }
760
GetBinding()761 ElfSymbolBinding GetBinding() const {
762 return binding_;
763 }
764
765 virtual ElfSymbolKind GetKind() const = 0;
766
767 protected:
768 std::string name_;
769 ElfSymbolBinding binding_;
770 };
771
772 class ElfFunctionIR : public ElfSymbolIR {
773 public:
ElfFunctionIR(const std::string & name,ElfSymbolBinding binding)774 ElfFunctionIR(const std::string &name, ElfSymbolBinding binding)
775 : ElfSymbolIR(name, binding) {}
776
GetKind()777 ElfSymbolKind GetKind() const override {
778 return ElfFunctionKind;
779 }
780 };
781
782 class ElfObjectIR : public ElfSymbolIR {
783 public:
ElfObjectIR(const std::string & name,ElfSymbolBinding binding)784 ElfObjectIR(const std::string &name, ElfSymbolBinding binding)
785 : ElfSymbolIR(name, binding) {}
786
GetKind()787 ElfSymbolKind GetKind() const override {
788 return ElfObjectKind;
789 }
790 };
791
792 class TypeDefinition {
793 public:
TypeDefinition(const TypeIR * type_ir,const std::string * compilation_unit_path)794 TypeDefinition(const TypeIR *type_ir,
795 const std::string *compilation_unit_path)
796 : type_ir_(type_ir), compilation_unit_path_(*compilation_unit_path) {}
797
798 const TypeIR *type_ir_;
799 const std::string &compilation_unit_path_;
800 };
801
802 class ModuleIR {
803 public:
ModuleIR(const std::set<std::string> * exported_headers)804 ModuleIR(const std::set<std::string> *exported_headers)
805 : exported_headers_(exported_headers) {}
806
GetCompilationUnitPath()807 const std::string &GetCompilationUnitPath() const {
808 return compilation_unit_path_;
809 }
810
SetCompilationUnitPath(const std::string & compilation_unit_path)811 void SetCompilationUnitPath(const std::string &compilation_unit_path) {
812 compilation_unit_path_ = compilation_unit_path;
813 }
814
GetFunctions()815 const AbiElementMap<FunctionIR> &GetFunctions() const {
816 return functions_;
817 }
818
GetGlobalVariables()819 const AbiElementMap<GlobalVarIR> &GetGlobalVariables() const {
820 return global_variables_;
821 }
822
GetRecordTypes()823 const AbiElementMap<RecordTypeIR> &GetRecordTypes() const {
824 return record_types_;
825 }
826
GetFunctionTypes()827 const AbiElementMap<FunctionTypeIR> &GetFunctionTypes() const {
828 return function_types_;
829 }
830
GetEnumTypes()831 const AbiElementMap<EnumTypeIR> &GetEnumTypes() const {
832 return enum_types_;
833 }
834
GetLvalueReferenceTypes()835 const AbiElementMap<LvalueReferenceTypeIR> &GetLvalueReferenceTypes() const {
836 return lvalue_reference_types_;
837 }
838
GetRvalueReferenceTypes()839 const AbiElementMap<RvalueReferenceTypeIR> &GetRvalueReferenceTypes() const {
840 return rvalue_reference_types_;
841 }
842
GetQualifiedTypes()843 const AbiElementMap<QualifiedTypeIR> &GetQualifiedTypes() const {
844 return qualified_types_;
845 }
846
GetArrayTypes()847 const AbiElementMap<ArrayTypeIR> &GetArrayTypes() const {
848 return array_types_;
849 }
850
GetPointerTypes()851 const AbiElementMap<PointerTypeIR> &GetPointerTypes() const {
852 return pointer_types_;
853 }
854
GetBuiltinTypes()855 const AbiElementMap<BuiltinTypeIR> &GetBuiltinTypes() const {
856 return builtin_types_;
857 }
858
GetElfFunctions()859 const AbiElementMap<ElfFunctionIR> &GetElfFunctions() const {
860 return elf_functions_;
861 }
862
GetElfObjects()863 const AbiElementMap<ElfObjectIR> &GetElfObjects() const {
864 return elf_objects_;
865 }
866
GetTypeGraph()867 const AbiElementMap<const TypeIR *> &GetTypeGraph() const {
868 return type_graph_;
869 }
870
871 const AbiElementUnorderedMap<std::list<TypeDefinition>> &
GetODRListMap()872 GetODRListMap() const {
873 return odr_list_map_;
874 }
875
876
877 bool AddLinkableMessage(const LinkableMessageIR &);
878
879 void AddFunction(FunctionIR &&function);
880
881 void AddGlobalVariable(GlobalVarIR &&global_var);
882
883 void AddRecordType(RecordTypeIR &&record_type);
884
885 void AddFunctionType(FunctionTypeIR &&function_type);
886
887 void AddEnumType(EnumTypeIR &&enum_type);
888
889 void AddLvalueReferenceType(LvalueReferenceTypeIR &&lvalue_reference_type);
890
891 void AddRvalueReferenceType(RvalueReferenceTypeIR &&rvalue_reference_type);
892
893 void AddQualifiedType(QualifiedTypeIR &&qualified_type);
894
895 void AddArrayType(ArrayTypeIR &&array_type);
896
897 void AddPointerType(PointerTypeIR &&pointer_type);
898
899 void AddBuiltinType(BuiltinTypeIR &&builtin_type);
900
901 bool AddElfSymbol(const ElfSymbolIR &);
902
903 void AddElfFunction(ElfFunctionIR &&elf_function);
904
905 void AddElfObject(ElfObjectIR &&elf_object);
906
907 // Find the compilation unit path of a RecordTypeIR, FunctionTypeIR, or
908 // EnumTypeIR in odr_list_map_. Return an empty string if the type is not in
909 // the map.
910 std::string GetCompilationUnitPath(const TypeIR *type_ir) const;
911
AddToODRListMap(const std::string & key,const TypeIR * type_ir,const std::string & compilation_unit_path)912 void AddToODRListMap(const std::string &key, const TypeIR *type_ir,
913 const std::string &compilation_unit_path) {
914 auto compilation_unit_path_it =
915 compilation_unit_paths_.emplace(compilation_unit_path).first;
916 auto map_it = odr_list_map_.find(key);
917 TypeDefinition value(type_ir, &*compilation_unit_path_it);
918 if (map_it == odr_list_map_.end()) {
919 odr_list_map_.emplace(key, std::list<TypeDefinition>({value}));
920 return;
921 }
922 odr_list_map_[key].emplace_back(value);
923 }
924
925
926 private:
927 bool IsLinkableMessageInExportedHeaders(
928 const LinkableMessageIR *linkable_message) const;
929
930
931 public:
932 // File path to the compilation unit (*.sdump)
933 std::string compilation_unit_path_;
934
935 AbiElementMap<FunctionIR> functions_;
936 AbiElementMap<GlobalVarIR> global_variables_;
937 AbiElementMap<RecordTypeIR> record_types_;
938 AbiElementMap<FunctionTypeIR> function_types_;
939 AbiElementMap<EnumTypeIR> enum_types_;
940 // These maps which contain generic referring types as values are used while
941 // looking up whether in the parent graph, a particular referring type refers
942 // to a certain type id. The mechanism is useful while trying to determine
943 // whether a generic referring type needs to be newly added to the parent
944 // graph or not.
945 AbiElementMap<PointerTypeIR> pointer_types_;
946 AbiElementMap<LvalueReferenceTypeIR> lvalue_reference_types_;
947 AbiElementMap<RvalueReferenceTypeIR> rvalue_reference_types_;
948 AbiElementMap<ArrayTypeIR> array_types_;
949 AbiElementMap<BuiltinTypeIR> builtin_types_;
950 AbiElementMap<QualifiedTypeIR> qualified_types_;
951 AbiElementMap<ElfFunctionIR> elf_functions_;
952 AbiElementMap<ElfObjectIR> elf_objects_;
953 // type-id -> LinkableMessageIR * map
954 AbiElementMap<const TypeIR *> type_graph_;
955 // maps unique_id + source_file -> TypeDefinition
956 AbiElementUnorderedMap<std::list<TypeDefinition>> odr_list_map_;
957
958
959 private:
960 // The compilation unit paths referenced by odr_list_map_;
961 std::set<std::string> compilation_unit_paths_;
962 const std::set<std::string> *exported_headers_;
963 };
964
965
966 } // namespace repr
967 } // namespace header_checker
968
969
970 #endif // IR_REPRESENTATION_H_
971