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