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 &&parameter) {
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