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