clang API Documentation

RecordLayoutBuilder.h

Go to the documentation of this file.
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