]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/RecordLayout.h
Merge Cavium Octeon SDK 2.0 Simple Executive; this brings some fixes and new
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / RecordLayout.h
1 //===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines the RecordLayout interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_AST_LAYOUTINFO_H
15 #define LLVM_CLANG_AST_LAYOUTINFO_H
16
17 #include "llvm/System/DataTypes.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "clang/AST/DeclCXX.h"
20
21 namespace clang {
22   class ASTContext;
23   class FieldDecl;
24   class RecordDecl;
25   class CXXRecordDecl;
26
27 /// ASTRecordLayout -
28 /// This class contains layout information for one RecordDecl,
29 /// which is a struct/union/class.  The decl represented must be a definition,
30 /// not a forward declaration.
31 /// This class is also used to contain layout information for one
32 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
33 /// These objects are managed by ASTContext.
34 class ASTRecordLayout {
35   /// Size - Size of record in bits.
36   uint64_t Size;
37
38   /// DataSize - Size of record in bits without tail padding.
39   uint64_t DataSize;
40
41   /// FieldOffsets - Array of field offsets in bits.
42   uint64_t *FieldOffsets;
43
44   // Alignment - Alignment of record in bits.
45   unsigned Alignment;
46
47   // FieldCount - Number of fields.
48   unsigned FieldCount;
49
50 public:
51   /// PrimaryBaseInfo - Contains info about a primary base.
52   struct PrimaryBaseInfo {
53     PrimaryBaseInfo() {}
54
55     PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
56       : Value(Base, Base && IsVirtual) {}
57
58     /// Value - Points to the primary base. The single-bit value
59     /// will be non-zero when the primary base is virtual.
60     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Value;
61     
62     /// getBase - Returns the primary base.
63     const CXXRecordDecl *getBase() const { return Value.getPointer(); }
64   
65     /// isVirtual - Returns whether the primary base is virtual or not.
66     bool isVirtual() const { return Value.getInt(); }
67
68     friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
69       return X.Value == Y.Value;
70     }
71   }; 
72   
73   /// primary_base_info_iterator - An iterator for iterating the primary base
74   /// class chain.
75   class primary_base_info_iterator {
76     /// Current - The current base class info.
77     PrimaryBaseInfo Current;
78     
79   public:
80     primary_base_info_iterator() {}
81     primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
82
83     const PrimaryBaseInfo &operator*() const { return Current; }
84
85     primary_base_info_iterator& operator++() {
86       const CXXRecordDecl *RD = Current.getBase();
87       Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
88       return *this;
89     }
90
91     friend bool operator==(const primary_base_info_iterator &X,
92                            const primary_base_info_iterator &Y) {
93       return X.Current == Y.Current;
94     }
95     friend bool operator!=(const primary_base_info_iterator &X,
96                            const primary_base_info_iterator &Y) {
97       return !(X == Y);
98     }
99   };
100     
101 private:
102   /// CXXRecordLayoutInfo - Contains C++ specific layout information.
103   struct CXXRecordLayoutInfo {
104     /// NonVirtualSize - The non-virtual size (in bits) of an object, which is
105     /// the size of the object without virtual bases.
106     uint64_t NonVirtualSize;
107
108     /// NonVirtualAlign - The non-virtual alignment (in bits) of an object,
109     /// which is the alignment of the object without virtual bases.
110     uint64_t NonVirtualAlign;
111
112     /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
113     /// (either a base or a member). Will be zero if the class doesn't contain
114     /// any empty subobjects.
115     uint64_t SizeOfLargestEmptySubobject;
116     
117     /// PrimaryBase - The primary base info for this record.
118     PrimaryBaseInfo PrimaryBase;
119     
120     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
121     typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
122     
123     /// BaseOffsets - Contains a map from base classes to their offset.
124     BaseOffsetsMapTy BaseOffsets;
125
126     /// VBaseOffsets - Contains a map from vbase classes to their offset.
127     BaseOffsetsMapTy VBaseOffsets;
128   };
129
130   /// CXXInfo - If the record layout is for a C++ record, this will have
131   /// C++ specific information about the record.
132   CXXRecordLayoutInfo *CXXInfo;
133
134   friend class ASTContext;
135
136   ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
137                   unsigned datasize, const uint64_t *fieldoffsets,
138                   unsigned fieldcount);
139
140   // Constructor for C++ records.
141   typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
142   ASTRecordLayout(ASTContext &Ctx,
143                   uint64_t size, unsigned alignment, uint64_t datasize,
144                   const uint64_t *fieldoffsets, unsigned fieldcount,
145                   uint64_t nonvirtualsize, unsigned nonvirtualalign,
146                   uint64_t SizeOfLargestEmptySubobject,
147                   const CXXRecordDecl *PrimaryBase,
148                   bool PrimaryBaseIsVirtual,
149                   const BaseOffsetsMapTy& BaseOffsets,
150                   const BaseOffsetsMapTy& VBaseOffsets);
151
152   ~ASTRecordLayout() {}
153
154   void Destroy(ASTContext &Ctx);
155
156   ASTRecordLayout(const ASTRecordLayout&);   // DO NOT IMPLEMENT
157   void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
158 public:
159
160   /// getAlignment - Get the record alignment in bits.
161   unsigned getAlignment() const { return Alignment; }
162
163   /// getSize - Get the record size in bits.
164   uint64_t getSize() const { return Size; }
165
166   /// getFieldCount - Get the number of fields in the layout.
167   unsigned getFieldCount() const { return FieldCount; }
168
169   /// getFieldOffset - Get the offset of the given field index, in
170   /// bits.
171   uint64_t getFieldOffset(unsigned FieldNo) const {
172     assert (FieldNo < FieldCount && "Invalid Field No");
173     return FieldOffsets[FieldNo];
174   }
175
176   /// getDataSize() - Get the record data size, which is the record size
177   /// without tail padding, in bits.
178   uint64_t getDataSize() const {
179     return DataSize;
180   }
181
182   /// getNonVirtualSize - Get the non-virtual size (in bits) of an object,
183   /// which is the size of the object without virtual bases.
184   uint64_t getNonVirtualSize() const {
185     assert(CXXInfo && "Record layout does not have C++ specific info!");
186
187     return CXXInfo->NonVirtualSize;
188   }
189
190   /// getNonVirtualSize - Get the non-virtual alignment (in bits) of an object,
191   /// which is the alignment of the object without virtual bases.
192   unsigned getNonVirtualAlign() const {
193     assert(CXXInfo && "Record layout does not have C++ specific info!");
194
195     return CXXInfo->NonVirtualAlign;
196   }
197
198   /// getPrimaryBaseInfo - Get the primary base info.
199   const PrimaryBaseInfo &getPrimaryBaseInfo() const {
200     assert(CXXInfo && "Record layout does not have C++ specific info!");
201
202     return CXXInfo->PrimaryBase;
203   }
204
205   // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
206   const CXXRecordDecl *getPrimaryBase() const {
207     return getPrimaryBaseInfo().getBase();
208   }
209
210   // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
211   bool getPrimaryBaseWasVirtual() const {
212     return getPrimaryBaseInfo().isVirtual();
213   }
214
215   /// getBaseClassOffset - Get the offset, in bits, for the given base class.
216   uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const {
217     assert(CXXInfo && "Record layout does not have C++ specific info!");
218     assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
219
220     return CXXInfo->BaseOffsets[Base];
221   }
222
223   /// getVBaseClassOffset - Get the offset, in bits, for the given base class.
224   uint64_t getVBaseClassOffset(const CXXRecordDecl *VBase) const {
225     assert(CXXInfo && "Record layout does not have C++ specific info!");
226     assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
227
228     return CXXInfo->VBaseOffsets[VBase];
229   }
230   
231   uint64_t getSizeOfLargestEmptySubobject() const {
232     assert(CXXInfo && "Record layout does not have C++ specific info!");
233     return CXXInfo->SizeOfLargestEmptySubobject;
234   }
235
236   primary_base_info_iterator primary_base_begin() const {
237     assert(CXXInfo && "Record layout does not have C++ specific info!");
238   
239     return primary_base_info_iterator(getPrimaryBaseInfo());
240   }
241
242   primary_base_info_iterator primary_base_end() const {
243     assert(CXXInfo && "Record layout does not have C++ specific info!");
244     
245     return primary_base_info_iterator();
246   }
247 };
248
249 }  // end namespace clang
250
251 #endif