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