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