152 lines · c
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-exception6//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_H14#define LLVM_CLANG_AST_INTERP_RECORD_H15 16#include "Descriptor.h"17#include "clang/AST/Decl.h"18#include "clang/AST/DeclCXX.h"19 20namespace clang {21namespace interp {22class Program;23 24/// Structure/Class descriptor.25class Record final {26public: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 51public: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>(Decl))75 return CXXDecl->getDestructor();76 return nullptr;77 }78 79 /// Returns true for anonymous unions and records80 /// with no destructor or for those with a trivial destructor.81 bool hasTrivialDtor() const;82 83 using const_field_iter = FieldList::const_iterator;84 llvm::iterator_range<const_field_iter> fields() const {85 return llvm::make_range(Fields.begin(), Fields.end());86 }87 88 unsigned getNumFields() const { return Fields.size(); }89 const Field *getField(unsigned I) const { return &Fields[I]; }90 91 using const_base_iter = BaseList::const_iterator;92 llvm::iterator_range<const_base_iter> bases() const {93 return llvm::make_range(Bases.begin(), Bases.end());94 }95 96 unsigned getNumBases() const { return Bases.size(); }97 const Base *getBase(unsigned I) const {98 assert(I < getNumBases());99 return &Bases[I];100 }101 102 using const_virtual_iter = VirtualBaseList::const_iterator;103 llvm::iterator_range<const_virtual_iter> virtual_bases() const {104 return llvm::make_range(VirtualBases.begin(), VirtualBases.end());105 }106 107 unsigned getNumVirtualBases() const { return VirtualBases.size(); }108 const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; }109 110 void dump(llvm::raw_ostream &OS, unsigned Indentation = 0,111 unsigned Offset = 0) const;112 void dump() const { dump(llvm::errs()); }113 114private:115 /// Constructor used by Program to create record descriptors.116 Record(const RecordDecl *, BaseList &&Bases, FieldList &&Fields,117 VirtualBaseList &&VirtualBases, unsigned VirtualSize,118 unsigned BaseSize);119 120private:121 friend class Program;122 123 /// Original declaration.124 const RecordDecl *Decl;125 /// List of all base classes.126 BaseList Bases;127 /// List of all the fields in the record.128 FieldList Fields;129 /// List o fall virtual bases.130 VirtualBaseList VirtualBases;131 132 /// Mapping from declarations to bases.133 llvm::DenseMap<const RecordDecl *, const Base *> BaseMap;134 /// Mapping from field identifiers to descriptors.135 llvm::DenseMap<const FieldDecl *, const Field *> FieldMap;136 /// Mapping from declarations to virtual bases.137 llvm::DenseMap<const RecordDecl *, Base *> VirtualBaseMap;138 /// Size of the structure.139 unsigned BaseSize;140 /// Size of all virtual bases.141 unsigned VirtualSize;142 /// If this record is a union.143 bool IsUnion;144 /// If this is an anonymous union.145 bool IsAnonymousUnion;146};147 148} // namespace interp149} // namespace clang150 151#endif152