clang API Documentation
00001 //===- ASTRecordLayoutBuilder.h - Helper class for building record layouts ===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H 00011 #define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H 00012 00013 #include "clang/AST/RecordLayout.h" 00014 #include "llvm/ADT/SmallVector.h" 00015 #include "llvm/ADT/SmallSet.h" 00016 #include "llvm/System/DataTypes.h" 00017 #include <map> 00018 00019 namespace clang { 00020 class ASTContext; 00021 class ASTRecordLayout; 00022 class CXXRecordDecl; 00023 class FieldDecl; 00024 class ObjCImplementationDecl; 00025 class ObjCInterfaceDecl; 00026 class RecordDecl; 00027 00028 class ASTRecordLayoutBuilder { 00029 ASTContext &Context; 00030 00031 /// Size - The current size of the record layout. 00032 uint64_t Size; 00033 00034 /// Alignment - The current alignment of the record layout. 00035 unsigned Alignment; 00036 00037 llvm::SmallVector<uint64_t, 16> FieldOffsets; 00038 00039 /// Packed - Whether the record is packed or not. 00040 bool Packed; 00041 00042 /// UnfilledBitsInLastByte - If the last field laid out was a bitfield, 00043 /// this contains the number of bits in the last byte that can be used for 00044 /// an adjacent bitfield if necessary. 00045 unsigned char UnfilledBitsInLastByte; 00046 00047 /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 00048 /// #pragma pack. 00049 unsigned MaxFieldAlignment; 00050 00051 /// DataSize - The data size of the record being laid out. 00052 uint64_t DataSize; 00053 00054 bool IsUnion; 00055 00056 uint64_t NonVirtualSize; 00057 unsigned NonVirtualAlignment; 00058 00059 /// PrimaryBase - the primary base class (if one exists) of the class 00060 /// we're laying out. 00061 ASTRecordLayout::PrimaryBaseInfo PrimaryBase; 00062 00063 /// Bases - base classes and their offsets in the record. 00064 ASTRecordLayout::BaseOffsetsMapTy Bases; 00065 00066 // VBases - virtual base classes and their offsets in the record. 00067 ASTRecordLayout::BaseOffsetsMapTy VBases; 00068 00069 /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 00070 /// primary base classes for some other direct or indirect base class. 00071 llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases; 00072 00073 /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 00074 /// inheritance graph order. Used for determining the primary base class. 00075 const CXXRecordDecl *FirstNearlyEmptyVBase; 00076 00077 /// VisitedVirtualBases - A set of all the visited virtual bases, used to 00078 /// avoid visiting virtual bases more than once. 00079 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 00080 00081 /// SizeOfLargestEmptySubobject - When laying out C++ classes, this holds the 00082 /// size of the largest empty subobject (either a base or a member). 00083 /// Will be zero if the record being built doesn't contain any empty classes. 00084 uint64_t SizeOfLargestEmptySubobject; 00085 00086 /// EmptyClassOffsets - A map from offsets to empty record decls. 00087 typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy; 00088 EmptyClassOffsetsTy EmptyClassOffsets; 00089 00090 ASTRecordLayoutBuilder(ASTContext &Ctx); 00091 00092 void Layout(const RecordDecl *D); 00093 void Layout(const CXXRecordDecl *D); 00094 void Layout(const ObjCInterfaceDecl *D, 00095 const ObjCImplementationDecl *Impl); 00096 00097 void LayoutFields(const RecordDecl *D); 00098 void LayoutField(const FieldDecl *D); 00099 void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize); 00100 void LayoutBitField(const FieldDecl *D); 00101 00102 /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 00103 /// member subobject that is empty. 00104 void ComputeEmptySubobjectSizes(const CXXRecordDecl *RD); 00105 00106 /// DeterminePrimaryBase - Determine the primary base of the given class. 00107 void DeterminePrimaryBase(const CXXRecordDecl *RD); 00108 00109 void SelectPrimaryVBase(const CXXRecordDecl *RD); 00110 00111 /// IdentifyPrimaryBases - Identify all virtual base classes, direct or 00112 /// indirect, that are primary base classes for some other direct or indirect 00113 /// base class. 00114 void IdentifyPrimaryBases(const CXXRecordDecl *RD); 00115 00116 bool IsNearlyEmpty(const CXXRecordDecl *RD) const; 00117 00118 /// LayoutNonVirtualBases - Determines the primary base class (if any) and 00119 /// lays it out. Will then proceed to lay out all non-virtual base clasess. 00120 void LayoutNonVirtualBases(const CXXRecordDecl *RD); 00121 00122 /// LayoutNonVirtualBase - Lays out a single non-virtual base. 00123 void LayoutNonVirtualBase(const CXXRecordDecl *RD); 00124 00125 void AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset, 00126 const CXXRecordDecl *MostDerivedClass); 00127 00128 /// LayoutVirtualBases - Lays out all the virtual bases. 00129 void LayoutVirtualBases(const CXXRecordDecl *RD, 00130 const CXXRecordDecl *MostDerivedClass); 00131 00132 /// LayoutVirtualBase - Lays out a single virtual base. 00133 void LayoutVirtualBase(const CXXRecordDecl *RD); 00134 00135 /// LayoutBase - Will lay out a base and return the offset where it was 00136 /// placed, in bits. 00137 uint64_t LayoutBase(const CXXRecordDecl *RD); 00138 00139 /// canPlaceRecordAtOffset - Return whether a record (either a base class 00140 /// or a field) can be placed at the given offset. 00141 /// Returns false if placing the record will result in two components 00142 /// (direct or indirect) of the same type having the same offset. 00143 bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset, 00144 bool CheckVBases) const; 00145 00146 /// canPlaceFieldAtOffset - Return whether a field can be placed at the given 00147 /// offset. 00148 bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const; 00149 00150 /// UpdateEmptyClassOffsets - Called after a record (either a base class 00151 /// or a field) has been placed at the given offset. Will update the 00152 /// EmptyClassOffsets map if the class is empty or has any empty bases or 00153 /// fields. 00154 void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset, 00155 bool UpdateVBases); 00156 00157 /// UpdateEmptyClassOffsets - Called after a field has been placed at the 00158 /// given offset. 00159 void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset); 00160 00161 /// FinishLayout - Finalize record layout. Adjust record size based on the 00162 /// alignment. 00163 void FinishLayout(); 00164 00165 void UpdateAlignment(unsigned NewAlignment); 00166 00167 ASTRecordLayoutBuilder(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT 00168 void operator=(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT 00169 public: 00170 static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx, 00171 const RecordDecl *RD); 00172 static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx, 00173 const ObjCInterfaceDecl *D, 00174 const ObjCImplementationDecl *Impl); 00175 static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD); 00176 }; 00177 00178 } // end namespace clang 00179 00180 #endif 00181