• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &&parameter) {
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