diff options
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGRecordLayout.h | 51 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 29 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 33 | 
7 files changed, 75 insertions, 76 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 027264f25bb..87ec159a601 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -14,6 +14,7 @@  #include "CodeGenFunction.h"  #include "CodeGenModule.h"  #include "CGCall.h" +#include "CGRecordLayout.h"  #include "CGObjCRuntime.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h" @@ -1468,7 +1469,9 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {  LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,                                                const FieldDecl* Field,                                                unsigned CVRQualifiers) { -  CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); +  const CGRecordLayout &RL = +    CGM.getTypes().getCGRecordLayout(Field->getParent()); +  const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);    // FIXME: CodeGenTypes should expose a method to get the appropriate type for    // FieldTy (the appropriate type is ABI-dependent). @@ -1496,7 +1499,9 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,    if (Field->isBitField())      return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers); -  unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); +  const CGRecordLayout &RL = +    CGM.getTypes().getCGRecordLayout(Field->getParent()); +  unsigned idx = RL.getLLVMFieldNo(Field);    llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");    // Match union field type. @@ -1531,7 +1536,9 @@ CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue,    if (!FieldType->isReferenceType())      return EmitLValueForField(BaseValue, Field, CVRQualifiers); -  unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); +  const CGRecordLayout &RL = +    CGM.getTypes().getCGRecordLayout(Field->getParent()); +  unsigned idx = RL.getLLVMFieldNo(Field);    llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");    assert(!FieldType.getObjCGCAttr() && "fields cannot have GC attrs"); diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index c86c6aa2d65..172a77d78e5 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1012,7 +1012,9 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {           E = RD->field_end(); I != E; ++I) {        const FieldDecl *FD = *I; -      unsigned FieldNo = getTypes().getLLVMFieldNo(FD); +      const CGRecordLayout &RL = +        getTypes().getCGRecordLayout(FD->getParent()); +      unsigned FieldNo = RL.getLLVMFieldNo(FD);        Elements[FieldNo] = EmitNullConstant(FD->getType());      } @@ -1048,7 +1050,9 @@ CodeGenModule::EmitPointerToDataMember(const FieldDecl *FD) {    const llvm::StructType *ClassLTy =      cast<llvm::StructType>(getTypes().ConvertType(ClassType)); -  unsigned FieldNo = getTypes().getLLVMFieldNo(FD); +  const CGRecordLayout &RL = +    getTypes().getCGRecordLayout(FD->getParent()); +  unsigned FieldNo = RL.getLLVMFieldNo(FD);    uint64_t Offset =       getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 1ed41d005f3..883ed98511e 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -13,6 +13,7 @@  #include "CGObjCRuntime.h" +#include "CGRecordLayout.h"  #include "CodeGenModule.h"  #include "CodeGenFunction.h"  #include "clang/AST/ASTContext.h" @@ -3134,8 +3135,10 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,      FieldDecl *Field = RecFields[i];      uint64_t FieldOffset;      if (RD) { +      const CGRecordLayout &RL = +        CGM.getTypes().getCGRecordLayout(Field->getParent());        if (Field->isBitField()) { -        CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); +        const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);          const llvm::Type *Ty =            CGM.getTypes().ConvertTypeForMemRecursive(Field->getType()); @@ -3144,7 +3147,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,          FieldOffset = Info.FieldNo * TypeSize;        } else          FieldOffset = -          Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); +          Layout->getElementOffset(RL.getLLVMFieldNo(Field));      } else        FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)); diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 7581cdbd8f1..d0d8f984a9e 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -10,6 +10,8 @@  #ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H  #define CLANG_CODEGEN_CGRECORDLAYOUT_H +#include "llvm/ADT/DenseMap.h" +#include "clang/AST/Decl.h"  namespace llvm {    class Type;  } @@ -19,31 +21,72 @@ namespace CodeGen {  /// CGRecordLayout - This class handles struct and union layout info while  /// lowering AST types to LLVM types. +/// +/// These layout objects are only created on demand as IR generation requires.  class CGRecordLayout { +  friend class CodeGenTypes; +    CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT    void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT +public: +  struct BitFieldInfo { +    BitFieldInfo(unsigned FieldNo, +                 unsigned Start, +                 unsigned Size) +      : FieldNo(FieldNo), Start(Start), Size(Size) {} + +    unsigned FieldNo; +    unsigned Start; +    unsigned Size; +  }; + +private:    /// The LLVMType corresponding to this record layout.    const llvm::Type *LLVMType; +  /// Map from (non-bit-field) struct field to the corresponding llvm struct +  /// type field no. This info is populated by record builder. +  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo; + +  /// Map from (bit-field) struct field to the corresponding llvm struct type +  /// field no. This info is populated by record builder. +  llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields; +    /// Whether one of the fields in this record layout is a pointer to data    /// member, or a struct that contains pointer to data member. -  bool ContainsPointerToDataMember; +  bool ContainsPointerToDataMember : 1;  public:    CGRecordLayout(const llvm::Type *T, bool ContainsPointerToDataMember)      : LLVMType(T), ContainsPointerToDataMember(ContainsPointerToDataMember) {} -  /// getLLVMType - Return llvm type associated with this record. +  /// \brief Return the LLVM type associated with this record.    const llvm::Type *getLLVMType() const {      return LLVMType;    } -  /// containsPointerToDataMember - Whether this struct contains pointers to -  /// data members. +  /// \brief Check whether this struct contains pointers to data members.    bool containsPointerToDataMember() const {      return ContainsPointerToDataMember;    } + +  /// \brief Return the BitFieldInfo that corresponds to the field FD. +  unsigned getLLVMFieldNo(const FieldDecl *FD) const { +    assert(!FD->isBitField() && "Invalid call for bit-field decl!"); +    assert(FieldInfo.count(FD) && "Invalid field for record!"); +    return FieldInfo.lookup(FD); +  } + +  /// \brief Return llvm::StructType element number that corresponds to the +  /// field FD. +  const BitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const { +    assert(FD->isBitField() && "Invalid call for non bit-field decl!"); +    llvm::DenseMap<const FieldDecl *, BitFieldInfo>::const_iterator +      it = BitFields.find(FD); +    assert(it != BitFields.end()  && "Unable to find bitfield info"); +    return it->second; +  }  };  }  // end namespace CodeGen diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 3ddf1b58d5a..daebabddc61 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -490,12 +490,15 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {           getTargetData().getTypeAllocSize(Ty) &&           "Type size mismatch!"); +  CGRecordLayout *RL = +    new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember); +    // Add all the field numbers.    for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) {      const FieldDecl *FD = Builder.LLVMFields[i].first;      unsigned FieldNo = Builder.LLVMFields[i].second; -    addFieldInfo(FD, FieldNo); +    RL->FieldInfo.insert(std::make_pair(FD, FieldNo));    }    // Add bitfield info. @@ -503,8 +506,9 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {      const CGRecordLayoutBuilder::LLVMBitFieldInfo &Info =        Builder.LLVMBitFields[i]; -    addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size); +    CGRecordLayout::BitFieldInfo BFI(Info.FieldNo, Info.Start, Info.Size); +    RL->BitFields.insert(std::make_pair(Info.FD, BFI));    } -  return new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember); +  return RL;  } diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 8f341b51fb2..f53dd83d703 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -459,35 +459,6 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {    return ResultHolder.get();  } -/// getLLVMFieldNo - Return llvm::StructType element number -/// that corresponds to the field FD. -unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { -  assert(!FD->isBitField() && "Don't use getLLVMFieldNo on bit fields!"); - -  llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD); -  assert (I != FieldInfo.end()  && "Unable to find field info"); -  return I->second; -} - -/// addFieldInfo - Assign field number to field FD. -void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) { -  FieldInfo[FD] = No; -} - -/// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field FD. -CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) { -  llvm::DenseMap<const FieldDecl *, BitFieldInfo>::iterator -    I = BitFields.find(FD); -  assert (I != BitFields.end()  && "Unable to find bitfield info"); -  return I->second; -} - -/// addBitFieldInfo - Assign a start bit and a size to field FD. -void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, -                                   unsigned Start, unsigned Size) { -  BitFields.insert(std::make_pair(FD, BitFieldInfo(FieldNo, Start, Size))); -} -  /// getCGRecordLayout - Return record layout info for the given llvm::Type.  const CGRecordLayout &  CodeGenTypes::getCGRecordLayout(const RecordDecl *TD) const { diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 22d06713377..70166b1e227 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -81,28 +81,10 @@ class CodeGenTypes {    /// record layout info.    llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts; -  /// FieldInfo - This maps struct field with corresponding llvm struct type -  /// field no. This info is populated by record organizer. -  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo; -    /// FunctionInfos - Hold memoized CGFunctionInfo results.    llvm::FoldingSet<CGFunctionInfo> FunctionInfos; -public: -  struct BitFieldInfo { -    BitFieldInfo(unsigned FieldNo, -                 unsigned Start, -                 unsigned Size) -      : FieldNo(FieldNo), Start(Start), Size(Size) {} - -    unsigned FieldNo; -    unsigned Start; -    unsigned Size; -  }; -  private: -  llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields; -    /// TypeCache - This map keeps cache of llvm::Types (through PATypeHolder)    /// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is    /// used instead of llvm::Type because it allows us to bypass potential @@ -150,10 +132,6 @@ public:    const CGRecordLayout &getCGRecordLayout(const RecordDecl*) const; -  /// getLLVMFieldNo - Return llvm::StructType element number -  /// that corresponds to the field FD. -  unsigned getLLVMFieldNo(const FieldDecl *FD); -    /// UpdateCompletedType - When we find the full definition for a TagDecl,    /// replace the 'opaque' type we previously made for it if applicable.    void UpdateCompletedType(const TagDecl *TD); @@ -202,17 +180,6 @@ public:    CGRecordLayout *ComputeRecordLayout(const RecordDecl *D);  public:  // These are internal details of CGT that shouldn't be used externally. -  /// addFieldInfo - Assign field number to field FD. -  void addFieldInfo(const FieldDecl *FD, unsigned FieldNo); - -  /// addBitFieldInfo - Assign a start bit and a size to field FD. -  void addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, -                       unsigned Start, unsigned Size); - -  /// getBitFieldInfo - Return the BitFieldInfo  that corresponds to the field -  /// FD. -  BitFieldInfo getBitFieldInfo(const FieldDecl *FD); -    /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or    /// enum.    const llvm::Type *ConvertTagDeclType(const TagDecl *TD);  | 

