| 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 | 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>(Val: 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(x: Fields.begin(), y: 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(x: Bases.begin(), y: 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(x: VirtualBases.begin(), y: 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(OS&: 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 |  | 
|---|