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