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 Descriptor *Desc; 32 }; 33 34 /// Describes a base class. 35 struct Base { 36 const RecordDecl *Decl; 37 unsigned Offset; 38 Descriptor *Desc; 39 Record *R; 40 }; 41 42 /// Mapping from identifiers to field descriptors. 43 using FieldList = llvm::SmallVector<Field, 8>; 44 /// Mapping from identifiers to base classes. 45 using BaseList = llvm::SmallVector<Base, 8>; 46 /// List of virtual base classes. 47 using VirtualBaseList = llvm::SmallVector<Base, 2>; 48 49 public: 50 /// Returns the underlying declaration. getDecl()51 const RecordDecl *getDecl() const { return Decl; } 52 /// Returns the name of the underlying declaration. getName()53 const std::string getName() const { return Decl->getNameAsString(); } 54 /// Checks if the record is a union. isUnion()55 bool isUnion() const { return getDecl()->isUnion(); } 56 /// Returns the size of the record. getSize()57 unsigned getSize() const { return BaseSize; } 58 /// Returns the full size of the record, including records. getFullSize()59 unsigned getFullSize() const { return BaseSize + VirtualSize; } 60 /// Returns a field. 61 const Field *getField(const FieldDecl *FD) const; 62 /// Returns a base descriptor. 63 const Base *getBase(const RecordDecl *FD) const; 64 /// Returns a virtual base descriptor. 65 const Base *getVirtualBase(const RecordDecl *RD) const; 66 // Returns the destructor of the record, if any. getDestructor()67 const CXXDestructorDecl *getDestructor() const { 68 if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(Decl)) 69 return CXXDecl->getDestructor(); 70 return nullptr; 71 } 72 73 using const_field_iter = FieldList::const_iterator; fields()74 llvm::iterator_range<const_field_iter> fields() const { 75 return llvm::make_range(Fields.begin(), Fields.end()); 76 } 77 getNumFields()78 unsigned getNumFields() const { return Fields.size(); } getField(unsigned I)79 const Field *getField(unsigned I) const { return &Fields[I]; } getField(unsigned I)80 Field *getField(unsigned I) { return &Fields[I]; } 81 82 using const_base_iter = BaseList::const_iterator; bases()83 llvm::iterator_range<const_base_iter> bases() const { 84 return llvm::make_range(Bases.begin(), Bases.end()); 85 } 86 getNumBases()87 unsigned getNumBases() const { return Bases.size(); } getBase(unsigned I)88 Base *getBase(unsigned I) { return &Bases[I]; } 89 90 using const_virtual_iter = VirtualBaseList::const_iterator; virtual_bases()91 llvm::iterator_range<const_virtual_iter> virtual_bases() const { 92 return llvm::make_range(VirtualBases.begin(), VirtualBases.end()); 93 } 94 getNumVirtualBases()95 unsigned getNumVirtualBases() const { return VirtualBases.size(); } getVirtualBase(unsigned I)96 Base *getVirtualBase(unsigned I) { return &VirtualBases[I]; } 97 98 private: 99 /// Constructor used by Program to create record descriptors. 100 Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields, 101 VirtualBaseList &&VirtualBases, unsigned VirtualSize, 102 unsigned BaseSize); 103 104 private: 105 friend class Program; 106 107 /// Original declaration. 108 const RecordDecl *Decl; 109 /// List of all base classes. 110 BaseList Bases; 111 /// List of all the fields in the record. 112 FieldList Fields; 113 /// List o fall virtual bases. 114 VirtualBaseList VirtualBases; 115 116 /// Mapping from declarations to bases. 117 llvm::DenseMap<const RecordDecl *, Base *> BaseMap; 118 /// Mapping from field identifiers to descriptors. 119 llvm::DenseMap<const FieldDecl *, Field *> FieldMap; 120 /// Mapping from declarations to virtual bases. 121 llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap; 122 /// Size of the structure. 123 unsigned BaseSize; 124 /// Size of all virtual bases. 125 unsigned VirtualSize; 126 }; 127 128 } // namespace interp 129 } // namespace clang 130 131 #endif 132