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
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 the destructor of the record, if any.
65 const CXXDestructorDecl *getDestructor() const {
66 if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(Val: Decl))
67 return CXXDecl->getDestructor();
68 return nullptr;
69 }
70
71 /// Returns true for anonymous unions and records
72 /// with no destructor or for those with a trivial destructor.
73 bool hasTrivialDtor() const;
74
75 using const_field_iter = FieldList::const_iterator;
76 llvm::iterator_range<const_field_iter> fields() const {
77 return llvm::make_range(x: Fields.begin(), y: Fields.end());
78 }
79
80 unsigned getNumFields() const { return Fields.size(); }
81 const Field *getField(unsigned I) const { return &Fields[I]; }
82 /// Returns a field.
83 const Field *getField(const FieldDecl *FD) const;
84
85 using const_base_iter = BaseList::const_iterator;
86 llvm::iterator_range<const_base_iter> bases() const {
87 return llvm::make_range(x: Bases.begin(), y: Bases.end());
88 }
89
90 unsigned getNumBases() const { return Bases.size(); }
91 const Base *getBase(unsigned I) const {
92 assert(I < getNumBases());
93 return &Bases[I];
94 }
95 /// Returns a base descriptor.
96 const Base *getBase(QualType T) const;
97 /// Returns a base descriptor.
98 const Base *getBase(const RecordDecl *FD) const;
99
100 using const_virtual_iter = VirtualBaseList::const_iterator;
101 llvm::iterator_range<const_virtual_iter> virtual_bases() const {
102 return llvm::make_range(x: VirtualBases.begin(), y: VirtualBases.end());
103 }
104
105 unsigned getNumVirtualBases() const { return VirtualBases.size(); }
106 const Base *getVirtualBase(unsigned I) const { return &VirtualBases[I]; }
107 /// Returns a virtual base descriptor.
108 const Base *getVirtualBase(const RecordDecl *RD) const;
109
110 void dump(llvm::raw_ostream &OS, unsigned Indentation = 0,
111 unsigned Offset = 0) const;
112 void dump() const { dump(OS&: 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 interp
149} // namespace clang
150
151#endif
152