1 //===--- Record.h - struct and class metadata for the VM --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // A record is part of a program to describe the layout and methods of a struct. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_AST_INTERP_RECORD_H 14 #define LLVM_CLANG_AST_INTERP_RECORD_H 15 16 #include "Descriptor.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclCXX.h" 19 20 namespace clang { 21 namespace interp { 22 class Program; 23 24 /// Structure/Class descriptor. 25 class Record final { 26 public: 27 /// Describes a record field. 28 struct Field { 29 const FieldDecl *Decl; 30 unsigned Offset; 31 const Descriptor *Desc; 32 bool isBitField() const { return Decl->isBitField(); } 33 bool isUnnamedBitField() const { return Decl->isUnnamedBitField(); } 34 }; 35 36 /// Describes a base class. 37 struct Base { 38 const RecordDecl *Decl; 39 unsigned Offset; 40 const Descriptor *Desc; 41 const Record *R; 42 }; 43 44 /// Mapping from identifiers to field descriptors. 45 using FieldList = llvm::SmallVector<Field, 8>; 46 /// Mapping from identifiers to base classes. 47 using BaseList = llvm::SmallVector<Base, 8>; 48 /// List of virtual base classes. 49 using VirtualBaseList = llvm::SmallVector<Base, 2>; 50 51 public: 52 /// Returns the underlying declaration. 53 const RecordDecl *getDecl() const { return Decl; } 54 /// Returns the name of the underlying declaration. 55 const std::string getName() const; 56 /// Checks if the record is a union. 57 bool isUnion() const { return IsUnion; } 58 /// Checks if the record is an anonymous union. 59 bool isAnonymousUnion() const { return IsAnonymousUnion; } 60 /// Returns the size of the record. 61 unsigned getSize() const { return BaseSize; } 62 /// Returns the full size of the record, including records. 63 unsigned getFullSize() const { return BaseSize + VirtualSize; } 64 /// Returns a field. 65 const Field *getField(const FieldDecl *FD) const; 66 /// Returns a base descriptor. 67 const Base *getBase(const RecordDecl *FD) const; 68 /// Returns a base descriptor. 69 const Base *getBase(QualType T) const; 70 /// Returns a virtual base descriptor. 71 const Base *getVirtualBase(const RecordDecl *RD) const; 72 /// Returns the destructor of the record, if any. 73 const CXXDestructorDecl *getDestructor() const { 74 if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(Decl)) 75 return CXXDecl->getDestructor(); 76 return nullptr; 77 } 78 79 using const_field_iter = FieldList::const_iterator; 80 llvm::iterator_range<const_field_iter> fields() const { 81 return llvm::make_range(Fields.begin(), Fields.end()); 82 } 83 84 unsigned getNumFields() const { return Fields.size(); } 85 const Field *getField(unsigned I) const { return &Fields[I]; } 86 87 using const_base_iter = BaseList::const_iterator; 88 llvm::iterator_range<const_base_iter> bases() const { 89 return llvm::make_range(Bases.begin(), Bases.end()); 90 } 91 92 unsigned getNumBases() const { return Bases.size(); } 93 const Base *getBase(unsigned I) const { 94 assert(I < getNumBases()); 95 return &Bases[I]; 96 } 97 98 using const_virtual_iter = VirtualBaseList::const_iterator; 99 llvm::iterator_range<const_virtual_iter> virtual_bases() const { 100 return llvm::make_range(VirtualBases.begin(), VirtualBases.end()); 101 } 102 103 unsigned getNumVirtualBases() const { return VirtualBases.size(); } 104 const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; } 105 106 void dump(llvm::raw_ostream &OS, unsigned Indentation = 0, 107 unsigned Offset = 0) const; 108 void dump() const { dump(llvm::errs()); } 109 110 private: 111 /// Constructor used by Program to create record descriptors. 112 Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields, 113 VirtualBaseList &&VirtualBases, unsigned VirtualSize, 114 unsigned BaseSize); 115 116 private: 117 friend class Program; 118 119 /// Original declaration. 120 const RecordDecl *Decl; 121 /// List of all base classes. 122 BaseList Bases; 123 /// List of all the fields in the record. 124 FieldList Fields; 125 /// List o fall virtual bases. 126 VirtualBaseList VirtualBases; 127 128 /// Mapping from declarations to bases. 129 llvm::DenseMap<const RecordDecl *, const Base *> BaseMap; 130 /// Mapping from field identifiers to descriptors. 131 llvm::DenseMap<const FieldDecl *, const Field *> FieldMap; 132 /// Mapping from declarations to virtual bases. 133 llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap; 134 /// Size of the structure. 135 unsigned BaseSize; 136 /// Size of all virtual bases. 137 unsigned VirtualSize; 138 /// If this record is a union. 139 bool IsUnion; 140 /// If this is an anonymous union. 141 bool IsAnonymousUnion; 142 }; 143 144 } // namespace interp 145 } // namespace clang 146 147 #endif 148