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