zcov: / include/clang/AST/RecordLayout.h


Files: 1 Branches Taken: 95.2% 20 / 21
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 21 / 21
Line Coverage: 100.0% 79 / 79


Programs: 17 Runs 40921


       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             2683:     PrimaryBaseInfo() {}
      54                 : 
      55              187:     PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
                      137: branch 0 taken
                       50: branch 1 taken
                       46: branch 2 taken
                       91: branch 3 taken
      56              187:       : 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            10318:     const CXXRecordDecl *getBase() const { return Value.getPointer(); }
      64                 :   
      65                 :     /// isVirtual - Returns whether the primary base is virtual or not.
      66             7685:     bool isVirtual() const { return Value.getInt(); }
      67                 : 
      68               28:     friend bool operator==(const PrimaryBaseInfo &X, const PrimaryBaseInfo &Y) {
      69               28:       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               21:     primary_base_info_iterator() {}
      81               21:     primary_base_info_iterator(PrimaryBaseInfo Info) : Current(Info) {}
      82                 : 
      83                7:     const PrimaryBaseInfo &operator*() const { return Current; }
      84                 : 
      85                7:     primary_base_info_iterator& operator++() {
      86                7:       const CXXRecordDecl *RD = Current.getBase();
      87                7:       Current = RD->getASTContext().getASTRecordLayout(RD).getPrimaryBaseInfo();
      88                7:       return *this;
      89                 :     }
      90                 : 
      91                 :     friend bool operator==(const primary_base_info_iterator &X,
      92               28:                            const primary_base_info_iterator &Y) {
      93               28:       return X.Current == Y.Current;
      94                 :     }
      95                 :     friend bool operator!=(const primary_base_info_iterator &X,
      96               28:                            const primary_base_info_iterator &Y) {
      97               28:       return !(X == Y);
      98                 :     }
      99                 :   };
     100                 :     
     101                 : private:
     102                 :   /// CXXRecordLayoutInfo - Contains C++ specific layout information.
     103             1719:   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                 :     /// PrimaryBase - The primary base info for this record.
     113                 :     PrimaryBaseInfo PrimaryBase;
     114                 :     
     115                 :     /// BaseOffsets - Contains a map from base classes to their offset.
     116                 :     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
     117                 :     llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
     118                 : 
     119                 :     /// VBaseOffsets - Contains a map from vbase classes to their offset.
     120                 :     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
     121                 :     llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
     122                 :   };
     123                 : 
     124                 :   /// CXXInfo - If the record layout is for a C++ record, this will have
     125                 :   /// C++ specific information about the record.
     126                 :   CXXRecordLayoutInfo *CXXInfo;
     127                 : 
     128                 :   friend class ASTContext;
     129                 :   friend class ASTRecordLayoutBuilder;
     130                 : 
     131                 :   ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize,
     132              938:                   const uint64_t *fieldoffsets, unsigned fieldcount)
     133                 :   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
     134              938:     FieldCount(fieldcount), CXXInfo(0) {
                      812: branch 0 taken
                      126: branch 1 taken
     135              938:     if (FieldCount > 0)  {
     136              812:       FieldOffsets = new uint64_t[FieldCount];
                     1905: branch 0 taken
                      812: branch 1 taken
     137             2717:       for (unsigned i = 0; i < FieldCount; ++i)
     138             1905:         FieldOffsets[i] = fieldoffsets[i];
     139                 :     }
     140              938:   }
     141                 : 
     142                 :   // Constructor for C++ records.
     143                 :   ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
     144                 :                   const uint64_t *fieldoffsets, unsigned fieldcount,
     145                 :                   uint64_t nonvirtualsize, unsigned nonvirtualalign,
     146                 :                   const PrimaryBaseInfo &PrimaryBase,
     147                 :                   const std::pair<const CXXRecordDecl *, uint64_t> *bases,
     148                 :                   unsigned numbases,
     149                 :                   const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
     150              862:                   unsigned numvbases)
     151                 :   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
     152              862:   FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
                      351: branch 0 taken
                      511: branch 1 taken
     153              862:     if (FieldCount > 0)  {
     154              351:       FieldOffsets = new uint64_t[FieldCount];
                      537: branch 0 taken
                      351: branch 1 taken
     155              888:       for (unsigned i = 0; i < FieldCount; ++i)
     156              537:         FieldOffsets[i] = fieldoffsets[i];
     157                 :     }
     158                 : 
     159              862:     CXXInfo->PrimaryBase = PrimaryBase;
     160              862:     CXXInfo->NonVirtualSize = nonvirtualsize;
     161              862:     CXXInfo->NonVirtualAlign = nonvirtualalign;
                      257: branch 0 taken
                      862: branch 1 taken
     162             1119:     for (unsigned i = 0; i != numbases; ++i)
     163              257:       CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
                      339: branch 0 taken
                      862: branch 1 taken
     164             1201:     for (unsigned i = 0; i != numvbases; ++i)
     165              339:       CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
     166              862:   }
     167                 : 
     168             1783:   ~ASTRecordLayout() {
                     1148: branch 0 taken
                      635: branch 1 taken
     169             1783:     delete [] FieldOffsets;
                      857: branch 0 taken
                      926: branch 1 taken
     170             1783:     delete CXXInfo;
     171             1783:   }
     172                 : 
     173                 :   ASTRecordLayout(const ASTRecordLayout&);   // DO NOT IMPLEMENT
     174                 :   void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
     175                 : public:
     176                 : 
     177                 :   /// getAlignment - Get the record alignment in bits.
     178             3715:   unsigned getAlignment() const { return Alignment; }
     179                 : 
     180                 :   /// getSize - Get the record size in bits.
     181             5817:   uint64_t getSize() const { return Size; }
     182                 : 
     183                 :   /// getFieldCount - Get the number of fields in the layout.
     184               42:   unsigned getFieldCount() const { return FieldCount; }
     185                 : 
     186                 :   /// getFieldOffset - Get the offset of the given field index, in
     187                 :   /// bits.
     188             4793:   uint64_t getFieldOffset(unsigned FieldNo) const {
                        0: branch 0 not taken
     189             4793:     assert (FieldNo < FieldCount && "Invalid Field No");
     190             4793:     return FieldOffsets[FieldNo];
     191                 :   }
     192                 : 
     193                 :   /// getDataSize() - Get the record data size, which is the record size
     194                 :   /// without tail padding, in bits.
     195              118:   uint64_t getDataSize() const {
     196              118:     return DataSize;
     197                 :   }
     198                 : 
     199                 :   /// getNonVirtualSize - Get the non-virtual size (in bits) of an object,
     200                 :   /// which is the size of the object without virtual bases.
     201              542:   uint64_t getNonVirtualSize() const {
     202              542:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     203                 : 
     204              542:     return CXXInfo->NonVirtualSize;
     205                 :   }
     206                 : 
     207                 :   /// getNonVirtualSize - Get the non-virtual alignment (in bits) of an object,
     208                 :   /// which is the alignment of the object without virtual bases.
     209              432:   unsigned getNonVirtualAlign() const {
     210              432:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     211                 : 
     212              432:     return CXXInfo->NonVirtualAlign;
     213                 :   }
     214                 : 
     215                 :   /// getPrimaryBaseInfo - Get the primary base info.
     216            14836:   const PrimaryBaseInfo &getPrimaryBaseInfo() const {
     217            14836:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     218                 : 
     219            14836:     return CXXInfo->PrimaryBase;
     220                 :   }
     221                 : 
     222                 :   // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
     223             7352:   const CXXRecordDecl *getPrimaryBase() const {
     224             7352:     return getPrimaryBaseInfo().getBase();
     225                 :   }
     226                 : 
     227                 :   // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
     228             6979:   bool getPrimaryBaseWasVirtual() const {
     229             6979:     return getPrimaryBaseInfo().isVirtual();
     230                 :   }
     231                 : 
     232                 :   /// getBaseClassOffset - Get the offset, in bits, for the given base class.
     233             3371:   uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const {
     234             3371:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     235             3371:     assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
     236                 : 
     237             3371:     return CXXInfo->BaseOffsets[Base];
     238                 :   }
     239                 : 
     240                 :   /// getVBaseClassOffset - Get the offset, in bits, for the given base class.
     241             4144:   uint64_t getVBaseClassOffset(const CXXRecordDecl *VBase) const {
     242             4144:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     243             4144:     assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
     244                 : 
     245             4144:     return CXXInfo->VBaseOffsets[VBase];
     246                 :   }
     247                 :   
     248               21:   primary_base_info_iterator primary_base_begin() const {
     249               21:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     250                 :   
     251               21:     return primary_base_info_iterator(getPrimaryBaseInfo());
     252                 :   }
     253                 : 
     254               21:   primary_base_info_iterator primary_base_end() const {
     255               21:     assert(CXXInfo && "Record layout does not have C++ specific info!");
     256                 :     
     257               21:     return primary_base_info_iterator();
     258                 :   }
     259                 : };
     260                 : 
     261                 : }  // end namespace clang
     262                 : 
     263                 : #endif

Generated: 2010-02-10 01:31 by zcov