1 //===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the RecordLayout interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_LAYOUTINFO_H
15 #define LLVM_CLANG_AST_LAYOUTINFO_H
17 #include "llvm/Support/DataTypes.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "clang/AST/CharUnits.h"
20 #include "clang/AST/DeclCXX.h"
29 /// This class contains layout information for one RecordDecl,
30 /// which is a struct/union/class. The decl represented must be a definition,
31 /// not a forward declaration.
32 /// This class is also used to contain layout information for one
33 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
34 /// These objects are managed by ASTContext.
35 class ASTRecordLayout {
36 /// Size - Size of record in characters.
39 /// DataSize - Size of record in characters without tail padding.
42 /// FieldOffsets - Array of field offsets in bits.
43 uint64_t *FieldOffsets;
45 // Alignment - Alignment of record in characters.
48 // FieldCount - Number of fields.
51 /// CXXRecordLayoutInfo - Contains C++ specific layout information.
52 struct CXXRecordLayoutInfo {
53 /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
54 /// the size of the object without virtual bases.
55 CharUnits NonVirtualSize;
57 /// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
58 /// which is the alignment of the object without virtual bases.
59 CharUnits NonVirtualAlign;
61 /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
62 /// (either a base or a member). Will be zero if the class doesn't contain
63 /// any empty subobjects.
64 CharUnits SizeOfLargestEmptySubobject;
66 /// VFPtrOffset - Virtual function table offset (Microsoft-only).
67 CharUnits VFPtrOffset;
69 /// VBPtrOffset - Virtual base table offset (Microsoft-only).
70 CharUnits VBPtrOffset;
72 /// PrimaryBase - The primary base info for this record.
73 llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
75 /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
76 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
78 /// BaseOffsets - Contains a map from base classes to their offset.
79 BaseOffsetsMapTy BaseOffsets;
81 /// VBaseOffsets - Contains a map from vbase classes to their offset.
82 BaseOffsetsMapTy VBaseOffsets;
85 /// CXXInfo - If the record layout is for a C++ record, this will have
86 /// C++ specific information about the record.
87 CXXRecordLayoutInfo *CXXInfo;
89 friend class ASTContext;
91 ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
92 CharUnits datasize, const uint64_t *fieldoffsets,
95 // Constructor for C++ records.
96 typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
97 ASTRecordLayout(const ASTContext &Ctx,
98 CharUnits size, CharUnits alignment,
99 CharUnits vfptroffset, CharUnits vbptroffset,
101 const uint64_t *fieldoffsets, unsigned fieldcount,
102 CharUnits nonvirtualsize, CharUnits nonvirtualalign,
103 CharUnits SizeOfLargestEmptySubobject,
104 const CXXRecordDecl *PrimaryBase,
105 bool IsPrimaryBaseVirtual,
106 const BaseOffsetsMapTy& BaseOffsets,
107 const BaseOffsetsMapTy& VBaseOffsets);
109 ~ASTRecordLayout() {}
111 void Destroy(ASTContext &Ctx);
113 ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
114 void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
117 /// getAlignment - Get the record alignment in characters.
118 CharUnits getAlignment() const { return Alignment; }
120 /// getSize - Get the record size in characters.
121 CharUnits getSize() const { return Size; }
123 /// getFieldCount - Get the number of fields in the layout.
124 unsigned getFieldCount() const { return FieldCount; }
126 /// getFieldOffset - Get the offset of the given field index, in
128 uint64_t getFieldOffset(unsigned FieldNo) const {
129 assert (FieldNo < FieldCount && "Invalid Field No");
130 return FieldOffsets[FieldNo];
133 /// getDataSize() - Get the record data size, which is the record size
134 /// without tail padding, in characters.
135 CharUnits getDataSize() const {
139 /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
140 /// which is the size of the object without virtual bases.
141 CharUnits getNonVirtualSize() const {
142 assert(CXXInfo && "Record layout does not have C++ specific info!");
144 return CXXInfo->NonVirtualSize;
147 /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
148 /// which is the alignment of the object without virtual bases.
149 CharUnits getNonVirtualAlign() const {
150 assert(CXXInfo && "Record layout does not have C++ specific info!");
152 return CXXInfo->NonVirtualAlign;
155 /// getPrimaryBase - Get the primary base for this record.
156 const CXXRecordDecl *getPrimaryBase() const {
157 assert(CXXInfo && "Record layout does not have C++ specific info!");
159 return CXXInfo->PrimaryBase.getPointer();
162 /// isPrimaryBaseVirtual - Get whether the primary base for this record
163 /// is virtual or not.
164 bool isPrimaryBaseVirtual() const {
165 assert(CXXInfo && "Record layout does not have C++ specific info!");
167 return CXXInfo->PrimaryBase.getInt();
170 /// getBaseClassOffset - Get the offset, in chars, for the given base class.
171 CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
172 assert(CXXInfo && "Record layout does not have C++ specific info!");
173 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
175 return CXXInfo->BaseOffsets[Base];
178 /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
179 CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
180 assert(CXXInfo && "Record layout does not have C++ specific info!");
181 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
183 return CXXInfo->VBaseOffsets[VBase];
186 /// getBaseClassOffsetInBits - Get the offset, in bits, for the given
188 uint64_t getBaseClassOffsetInBits(const CXXRecordDecl *Base) const {
189 assert(CXXInfo && "Record layout does not have C++ specific info!");
190 assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
192 return getBaseClassOffset(Base).getQuantity() *
193 Base->getASTContext().getCharWidth();
196 /// getVBaseClassOffsetInBits - Get the offset, in bits, for the given
198 uint64_t getVBaseClassOffsetInBits(const CXXRecordDecl *VBase) const {
199 assert(CXXInfo && "Record layout does not have C++ specific info!");
200 assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
202 return getVBaseClassOffset(VBase).getQuantity() *
203 VBase->getASTContext().getCharWidth();
206 CharUnits getSizeOfLargestEmptySubobject() const {
207 assert(CXXInfo && "Record layout does not have C++ specific info!");
208 return CXXInfo->SizeOfLargestEmptySubobject;
211 /// getVFPtrOffset - Get the offset for virtual function table pointer.
212 /// This is only meaningful with the Microsoft ABI.
213 CharUnits getVFPtrOffset() const {
214 assert(CXXInfo && "Record layout does not have C++ specific info!");
215 return CXXInfo->VFPtrOffset;
218 /// getVBPtrOffset - Get the offset for virtual base table pointer.
219 /// This is only meaningful with the Microsoft ABI.
220 CharUnits getVBPtrOffset() const {
221 assert(CXXInfo && "Record layout does not have C++ specific info!");
222 return CXXInfo->VBPtrOffset;
226 } // end namespace clang