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