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