Home | History | Annotate | Download | only in repr
      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>
     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:
    101   virtual ~LinkableMessageIR() {}
    102 
    103   const std::string &GetLinkerSetKey() const {
    104     return linker_set_key_;
    105   }
    106 
    107   void SetSourceFile(const std::string &source_file) {
    108     source_file_ = source_file;
    109   }
    110 
    111   void SetLinkerSetKey(const std::string &linker_set_key) {
    112     linker_set_key_ = linker_set_key;
    113   }
    114 
    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:
    130   ReferencesOtherType(const std::string &referenced_type)
    131       : referenced_type_(referenced_type) {}
    132 
    133   ReferencesOtherType(std::string &&referenced_type)
    134       : referenced_type_(std::move(referenced_type)) {}
    135 
    136   ReferencesOtherType() {}
    137 
    138   void SetReferencedType(const std::string &referenced_type) {
    139     referenced_type_ = referenced_type;
    140   }
    141 
    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:
    153   virtual ~TypeIR() {}
    154 
    155   void SetSelfType(const std::string &self_type) {
    156     self_type_ = self_type;
    157   }
    158 
    159   const std::string &GetSelfType() const {
    160     return self_type_;
    161   }
    162 
    163   void SetName(const std::string &name) {
    164     name_ = name;
    165   }
    166 
    167   const std::string &GetName() const {
    168     return name_;
    169   }
    170 
    171   void SetSize(uint64_t size) {
    172     size_ = size;
    173   }
    174 
    175   uint64_t GetSize() const {
    176     return size_;
    177   }
    178 
    179   void SetAlignment(uint32_t alignment) {
    180     alignment_ = alignment;
    181   }
    182 
    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:
    196   const std::string &GetUniqueId() const {
    197     return unique_id_;
    198   }
    199 
    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 
    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 
    225   VTableComponentIR() {}
    226 
    227   Kind GetKind() const {
    228     return kind_;
    229   }
    230 
    231   int64_t GetValue() const {
    232     return value_;
    233   }
    234 
    235   const std::string &GetName() const {
    236     return component_name_;
    237   }
    238 
    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:
    252   void AddVTableComponent(VTableComponentIR &&vtable_component) {
    253     vtable_components_.emplace_back(std::move(vtable_component));
    254   }
    255 
    256   const std::vector<VTableComponentIR> &GetVTableComponents() const {
    257     return vtable_components_;
    258   }
    259 
    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:
    270   CXXBaseSpecifierIR(const std::string &type, bool is_virtual,
    271                      AccessSpecifierIR access)
    272       : ReferencesOtherType(type), is_virtual_(is_virtual), access_(access) {}
    273 
    274   CXXBaseSpecifierIR() {}
    275 
    276   bool IsVirtual() const {
    277     return is_virtual_;
    278   }
    279 
    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:
    291   TemplateElementIR(std::string &&type)
    292       : ReferencesOtherType(std::move(type)) {}
    293 
    294   TemplateElementIR(const std::string &type)
    295       : ReferencesOtherType(type) {}
    296 
    297   TemplateElementIR() {}
    298 };
    299 
    300 class TemplateInfoIR {
    301  public:
    302   void AddTemplateElement(TemplateElementIR &&element) {
    303     template_elements_.emplace_back(element);
    304   }
    305 
    306   const std::vector<TemplateElementIR> &GetTemplateElements() const {
    307     return template_elements_;
    308   }
    309 
    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:
    320   void SetTemplateInfo(TemplateInfoIR &&template_info) {
    321     template_info_ = std::move(template_info);
    322   }
    323 
    324   const std::vector<TemplateElementIR> &GetTemplateElements() const {
    325     return template_info_.GetTemplateElements();
    326   }
    327 
    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:
    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 
    343   RecordFieldIR() {}
    344 
    345   const std::string &GetName() const {
    346     return name_;
    347   }
    348 
    349   uint64_t GetOffset() const {
    350     return offset_;
    351   }
    352 
    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 
    372   void AddRecordField(RecordFieldIR &&field) {
    373     fields_.emplace_back(std::move(field));
    374   }
    375 
    376   void SetRecordFields(std::vector<RecordFieldIR> &&fields) {
    377     fields_ = std::move(fields);
    378   }
    379 
    380   void SetVTableLayout(VTableLayoutIR &&vtable_layout) {
    381     vtable_layout_ = std::move(vtable_layout);
    382   }
    383 
    384   const VTableLayoutIR &GetVTableLayout() const {
    385     return vtable_layout_;
    386   }
    387 
    388   void AddCXXBaseSpecifier(CXXBaseSpecifierIR &&base_specifier) {
    389     bases_.emplace_back(std::move(base_specifier));
    390   }
    391 
    392   void SetCXXBaseSpecifiers(std::vector<CXXBaseSpecifierIR> &&bases) {
    393     bases_ = std::move(bases);
    394   }
    395 
    396   const std::vector<CXXBaseSpecifierIR> &GetBases() const {
    397     return bases_;
    398   }
    399 
    400   std::vector<CXXBaseSpecifierIR> &GetBases() {
    401     return bases_;
    402   }
    403 
    404   void SetAccess(AccessSpecifierIR access) { access_ = access;}
    405 
    406   AccessSpecifierIR GetAccess() const {
    407     return access_;
    408   }
    409 
    410   const std::vector<RecordFieldIR> &GetFields() const {
    411     return fields_;
    412   }
    413 
    414   std::vector<RecordFieldIR> &GetFields() {
    415     return fields_;
    416   }
    417 
    418   LinkableMessageKind GetKind() const override {
    419     return LinkableMessageKind::RecordTypeKind;
    420   }
    421 
    422   uint64_t GetVTableNumEntries() const {
    423     return vtable_layout_.GetVTableNumEntries();
    424   }
    425 
    426   void SetRecordKind(RecordKind record_kind) {
    427     record_kind_ = record_kind;
    428   }
    429 
    430   RecordKind GetRecordKind() const {
    431     return record_kind_;
    432   }
    433 
    434   void SetAnonymity(bool is_anonymous) {
    435     is_anonymous_ = is_anonymous;
    436   }
    437 
    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:
    453   EnumFieldIR(const std::string &name, int value)
    454       : name_(name), value_(value) {}
    455 
    456   const std::string &GetName() const {
    457     return name_;
    458   }
    459 
    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.
    472   void AddEnumField(EnumFieldIR &&field) {
    473     fields_.emplace_back(std::move(field));
    474   }
    475 
    476   void SetAccess(AccessSpecifierIR access) { access_ = access;}
    477 
    478   LinkableMessageKind GetKind() const override {
    479     return LinkableMessageKind::EnumTypeKind;
    480   }
    481 
    482   AccessSpecifierIR GetAccess() const {
    483     return access_;
    484   }
    485 
    486   void SetUnderlyingType(std::string &&underlying_type) {
    487     underlying_type_ = std::move(underlying_type);
    488   }
    489 
    490   void SetUnderlyingType(const std::string &underlying_type) {
    491     underlying_type_ = underlying_type;
    492   }
    493 
    494   const std::string &GetUnderlyingType() const {
    495     return underlying_type_;
    496   }
    497 
    498   void SetFields(std::vector<EnumFieldIR> &&fields) {
    499     fields_ = std::move(fields);
    500   }
    501 
    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:
    514   LinkableMessageKind GetKind() const override {
    515     return LinkableMessageKind::ArrayTypeKind;
    516   }
    517 };
    518 
    519 class PointerTypeIR : public TypeIR {
    520  public:
    521   LinkableMessageKind GetKind() const override {
    522     return LinkableMessageKind::PointerTypeKind;
    523   }
    524 };
    525 
    526 class BuiltinTypeIR : public TypeIR {
    527  public:
    528   void SetSignedness(bool is_unsigned) {
    529     is_unsigned_ = is_unsigned;
    530   }
    531 
    532   bool IsUnsigned() const {
    533     return is_unsigned_;
    534   }
    535 
    536   void SetIntegralType(bool is_integral_type) {
    537     is_integral_type_ = is_integral_type;
    538   }
    539 
    540   bool IsIntegralType() const {
    541     return is_integral_type_;
    542   }
    543 
    544  public:
    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:
    556   LinkableMessageKind GetKind() const override {
    557     return LinkableMessageKind::LvalueReferenceTypeKind;
    558   }
    559 };
    560 
    561 class RvalueReferenceTypeIR : public TypeIR {
    562  public:
    563   LinkableMessageKind GetKind() const override {
    564     return LinkableMessageKind::RvalueReferenceTypeKind;
    565   }
    566 };
    567 
    568 class QualifiedTypeIR : public TypeIR {
    569  public:
    570   void SetConstness(bool is_const) {
    571     is_const_ = is_const;
    572   }
    573 
    574   bool IsConst() const {
    575     return is_const_;
    576   }
    577 
    578   void SetRestrictedness(bool is_restricted) {
    579     is_restricted_ = is_restricted;
    580   }
    581 
    582   bool IsRestricted() const {
    583     return is_restricted_;
    584   }
    585 
    586   void SetVolatility(bool is_volatile) {
    587     is_volatile_ = is_volatile;
    588   }
    589 
    590   bool IsVolatile() const {
    591     return is_volatile_;
    592   }
    593 
    594  public:
    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.
    608   void SetName(std::string &&name) {
    609     name_ = std::move(name);
    610   }
    611 
    612   void SetName(const std::string &name) {
    613     name_ = name;
    614   }
    615 
    616   const std::string &GetName() const {
    617     return name_;
    618   }
    619 
    620   void SetAccess(AccessSpecifierIR access) {
    621     access_ = access;
    622   }
    623 
    624   AccessSpecifierIR GetAccess() const {
    625     return access_;
    626   }
    627 
    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:
    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 
    643   bool GetIsDefault() const {
    644     return is_default_;
    645   }
    646 
    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:
    658   void SetReturnType(const std::string &type) {
    659     return_type_ = type;
    660   }
    661 
    662   const std::string &GetReturnType() const {
    663     return return_type_;
    664   }
    665 
    666   void AddParameter(ParamIR &&parameter) {
    667     parameters_.emplace_back(std::move(parameter));
    668   }
    669 
    670   const std::vector<ParamIR> &GetParameters() const {
    671     return parameters_;
    672   }
    673 
    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:
    685   LinkableMessageKind GetKind() const override {
    686     return LinkableMessageKind::FunctionTypeKind;
    687   }
    688 };
    689 
    690 class FunctionIR : public LinkableMessageIR, public TemplatedArtifactIR,
    691                    public CFunctionLikeIR {
    692  public:
    693   void SetAccess(AccessSpecifierIR access) {
    694     access_ = access;
    695   }
    696 
    697   AccessSpecifierIR GetAccess() const {
    698     return access_;
    699   }
    700 
    701   LinkableMessageKind GetKind() const override {
    702     return LinkableMessageKind::FunctionKind;
    703   }
    704 
    705   void SetName(const std::string &name) {
    706     name_ = name;
    707   }
    708 
    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:
    737   ElfSymbolIR(const std::string &name, ElfSymbolBinding binding)
    738       : name_(name), binding_(binding) {}
    739 
    740   virtual ~ElfSymbolIR() {}
    741 
    742   const std::string GetName() const {
    743     return name_;
    744   }
    745 
    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:
    759   ElfFunctionIR(const std::string &name, ElfSymbolBinding binding)
    760       : ElfSymbolIR(name, binding) {}
    761 
    762   ElfSymbolKind GetKind() const override {
    763     return ElfFunctionKind;
    764   }
    765 };
    766 
    767 class ElfObjectIR : public ElfSymbolIR {
    768  public:
    769   ElfObjectIR(const std::string &name, ElfSymbolBinding binding)
    770       : ElfSymbolIR(name, binding) {}
    771 
    772   ElfSymbolKind GetKind() const override {
    773     return ElfObjectKind;
    774   }
    775 };
    776 
    777 class ModuleIR {
    778  public:
    779   ModuleIR(const std::set<std::string> *exported_headers)
    780       : exported_headers_(exported_headers) {}
    781 
    782   const AbiElementMap<FunctionIR> &GetFunctions() const {
    783     return functions_;
    784   }
    785 
    786   const AbiElementMap<GlobalVarIR> &GetGlobalVariables() const {
    787     return global_variables_;
    788   }
    789 
    790   const AbiElementMap<RecordTypeIR> &GetRecordTypes() const {
    791     return record_types_;
    792   }
    793 
    794   const AbiElementMap<FunctionTypeIR> &GetFunctionTypes() const {
    795     return function_types_;
    796   }
    797 
    798   const AbiElementMap<EnumTypeIR> &GetEnumTypes() const {
    799     return enum_types_;
    800   }
    801 
    802   const AbiElementMap<LvalueReferenceTypeIR> &GetLvalueReferenceTypes() const {
    803     return lvalue_reference_types_;
    804   }
    805 
    806   const AbiElementMap<RvalueReferenceTypeIR> &GetRvalueReferenceTypes() const {
    807     return rvalue_reference_types_;
    808   }
    809 
    810   const AbiElementMap<QualifiedTypeIR> &GetQualifiedTypes() const {
    811     return qualified_types_;
    812   }
    813 
    814   const AbiElementMap<ArrayTypeIR> &GetArrayTypes() const {
    815     return array_types_;
    816   }
    817 
    818   const AbiElementMap<PointerTypeIR> &GetPointerTypes() const {
    819     return pointer_types_;
    820   }
    821 
    822   const AbiElementMap<BuiltinTypeIR> &GetBuiltinTypes() const {
    823     return builtin_types_;
    824   }
    825 
    826   const AbiElementMap<ElfFunctionIR> &GetElfFunctions() const {
    827     return elf_functions_;
    828   }
    829 
    830   const AbiElementMap<ElfObjectIR> &GetElfObjects() const {
    831     return elf_objects_;
    832   }
    833 
    834   const AbiElementMap<const TypeIR *> &GetTypeGraph() const {
    835     return type_graph_;
    836   }
    837 
    838   const AbiElementUnorderedMap<std::list<const TypeIR *>> &
    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   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