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