]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/RecordLayoutBuilder.h
Update clang to r89205.
[FreeBSD/FreeBSD.git] / lib / AST / RecordLayoutBuilder.h
1 //===- ASTRecordLayoutBuilder.h - Helper class for building record layouts ===//
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 #ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
11 #define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
12
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/SmallSet.h"
15 #include "llvm/System/DataTypes.h"
16 #include <map>
17
18 namespace clang {
19   class ASTContext;
20   class ASTRecordLayout;
21   class CXXRecordDecl;
22   class FieldDecl;
23   class ObjCImplementationDecl;
24   class ObjCInterfaceDecl;
25   class RecordDecl;
26
27 class ASTRecordLayoutBuilder {
28   ASTContext &Ctx;
29
30   uint64_t Size;
31   unsigned Alignment;
32   llvm::SmallVector<uint64_t, 16> FieldOffsets;
33
34   /// Packed - Whether the record is packed or not.
35   bool Packed;
36   
37   /// MaxFieldAlignment - The maximum allowed field alignment. This is set by
38   /// #pragma pack. 
39   unsigned MaxFieldAlignment;
40   
41   /// DataSize - The data size of the record being laid out.
42   uint64_t DataSize;
43   
44   bool IsUnion;
45
46   uint64_t NonVirtualSize;
47   unsigned NonVirtualAlignment;
48   const CXXRecordDecl *PrimaryBase;
49   bool PrimaryBaseWasVirtual;
50
51   typedef llvm::SmallVector<std::pair<const CXXRecordDecl *, 
52                                       uint64_t>, 4> BaseOffsetsTy;
53   
54   /// Bases - base classes and their offsets from the record.
55   BaseOffsetsTy Bases;
56   
57   // VBases - virtual base classes and their offsets from the record.
58   BaseOffsetsTy VBases;
59
60   /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
61   /// primary base classes for some other direct or indirect base class.
62   llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
63   
64   /// EmptyClassOffsets - A map from offsets to empty record decls.
65   typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
66   EmptyClassOffsetsTy EmptyClassOffsets;
67   
68   ASTRecordLayoutBuilder(ASTContext &Ctx);
69
70   void Layout(const RecordDecl *D);
71   void Layout(const CXXRecordDecl *D);
72   void Layout(const ObjCInterfaceDecl *D,
73               const ObjCImplementationDecl *Impl);
74
75   void LayoutFields(const RecordDecl *D);
76   void LayoutField(const FieldDecl *D);
77
78   void SelectPrimaryBase(const CXXRecordDecl *RD);
79   void SelectPrimaryVBase(const CXXRecordDecl *RD,
80                           const CXXRecordDecl *&FirstPrimary);
81   
82   /// IdentifyPrimaryBases - Identify all virtual base classes, direct or 
83   /// indirect, that are primary base classes for some other direct or indirect 
84   /// base class.
85   void IdentifyPrimaryBases(const CXXRecordDecl *RD);
86   
87   void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
88     PrimaryBase = PB;
89     PrimaryBaseWasVirtual = Virtual;
90   }
91   
92   bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
93   
94   /// LayoutBase - Will lay out a base and return the offset where it was 
95   /// placed, in bits.
96   uint64_t LayoutBase(const CXXRecordDecl *RD);
97   
98   void LayoutVtable(const CXXRecordDecl *RD);
99   void LayoutNonVirtualBases(const CXXRecordDecl *RD);
100   void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
101   void LayoutVirtualBase(const CXXRecordDecl *RD);
102   void LayoutVirtualBases(const CXXRecordDecl *Class, const CXXRecordDecl *RD,
103                           const CXXRecordDecl *PB, uint64_t Offset, 
104                           llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
105                      llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
106
107   /// canPlaceRecordAtOffset - Return whether a record (either a base class
108   /// or a field) can be placed at the given offset. 
109   /// Returns false if placing the record will result in two components 
110   /// (direct or indirect) of the same type having the same offset.
111   bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
112
113   /// canPlaceFieldAtOffset - Return whether a field can be placed at the given
114   /// offset.
115   bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
116
117   /// UpdateEmptyClassOffsets - Called after a record (either a base class
118   /// or a field) has been placed at the given offset. Will update the
119   /// EmptyClassOffsets map if the class is empty or has any empty bases or
120   /// fields.
121   void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset);
122
123   /// UpdateEmptyClassOffsets - Called after a field has been placed at the 
124   /// given offset.
125   void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
126   
127   /// getBaseOffset - Get the offset of a direct base class.
128   uint64_t getBaseOffset(const CXXRecordDecl *Base);
129
130   /// FinishLayout - Finalize record layout. Adjust record size based on the
131   /// alignment.
132   void FinishLayout();
133
134   void UpdateAlignment(unsigned NewAlignment);
135
136   ASTRecordLayoutBuilder(const ASTRecordLayoutBuilder&);   // DO NOT IMPLEMENT
137   void operator=(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT
138 public:
139   static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
140                                               const RecordDecl *RD);
141   static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
142                                               const ObjCInterfaceDecl *D,
143                                             const ObjCImplementationDecl *Impl);
144 };
145
146 } // end namespace clang
147
148 #endif
149