From fc3b8e9c1381d5e6ec361591d649c56a870ff971 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 6 Feb 2008 05:18:32 +0000 Subject: [PATCH] split tagged decl layout into its own method. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46803 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CodeGenTypes.cpp | 204 ++++++++++++++++++++------------------- CodeGen/CodeGenTypes.h | 7 +- 2 files changed, 111 insertions(+), 100 deletions(-) diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index f81df0d0f6..62781cae1a 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -284,105 +284,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { break; case Type::Tagged: - const TagType &TT = cast(Ty); - const TagDecl *TD = TT.getDecl(); - llvm::DenseMap::iterator TDTI = - TagDeclTypes.find(TD); - - // If corresponding llvm type is not a opaque struct type - // then use it. - if (TDTI != TagDeclTypes.end() && // Don't have a type? - // Have a type, but it was opaque before and now we have a definition. - (!isa(TDTI->second.get()) || !TD->isDefinition())) - return TDTI->second; - - llvm::Type *ResultType = 0; - - if (!TD->isDefinition()) { - ResultType = llvm::OpaqueType::get(); - TagDeclTypes.insert(std::make_pair(TD, ResultType)); - } else if (TD->getKind() == Decl::Enum) { - // Don't bother storing enums in TagDeclTypes. - return ConvertType(cast(TD)->getIntegerType()); - } else if (TD->getKind() == Decl::Struct) { - const RecordDecl *RD = cast(TD); - - // If this is nested record and this RecordDecl is already under - // process then return associated OpaqueType for now. - if (TDTI == TagDeclTypes.end()) { - // Create new OpaqueType now for later use in case this is a recursive - // type. This will later be refined to the actual type. - ResultType = llvm::OpaqueType::get(); - TagDeclTypes.insert(std::make_pair(TD, ResultType)); - TypeHolderMap.insert(std::make_pair(T.getTypePtr(), ResultType)); - } - - // Layout fields. - RecordOrganizer RO(*this); - for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) - RO.addField(RD->getMember(i)); - const ASTRecordLayout &RL = Context.getASTRecordLayout(RD, - SourceLocation()); - RO.layoutStructFields(RL); - - // Get llvm::StructType. - CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(), - RO.getPaddingFields()); - ResultType = RLI->getLLVMType(); - TagDeclTypes.insert(std::make_pair(TD, ResultType)); - CGRecordLayouts[TD] = RLI; - - // Refining away Opaque could cause ResultType to become invalidated. - // Keep it in a happy little type holder to handle this. - llvm::PATypeHolder Holder(ResultType); - - // Refine the OpaqueType associated with this RecordDecl. - cast(TagDeclTypes.find(TD)->second.get()) - ->refineAbstractTypeTo(ResultType); - - ResultType = Holder.get(); - } else if (TD->getKind() == Decl::Union) { - const RecordDecl *RD = cast(TD); - // Just use the largest element of the union, breaking ties with the - // highest aligned member. - - if (RD->getNumMembers() != 0) { - RecordOrganizer RO(*this); - for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) - RO.addField(RD->getMember(i)); - RO.layoutUnionFields(); - - // Get llvm::StructType. - CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(), - RO.getPaddingFields()); - ResultType = RLI->getLLVMType(); - TagDeclTypes.insert(std::make_pair(TD, ResultType)); - CGRecordLayouts[TD] = RLI; - } else { - std::vector Fields; - ResultType = llvm::StructType::get(Fields); - TagDeclTypes.insert(std::make_pair(TD, ResultType)); - } - } else { - assert(0 && "FIXME: Implement tag decl kind!"); - } - - std::string TypeName(TD->getKindName()); - TypeName += '.'; - - // Name the codegen type after the typedef name - // if there is no tag type name available - if (TD->getIdentifier() == 0) { - if (T->getTypeClass() == Type::TypeName) { - const TypedefType *TdT = cast(T); - TypeName += TdT->getDecl()->getName(); - } else - TypeName += "anon"; - } else - TypeName += TD->getName(); - - TheModule.addTypeName(TypeName, ResultType); - return ResultType; + return ConvertTagDeclType(T, cast(Ty).getDecl()); } // FIXME: implement. @@ -408,6 +310,110 @@ void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP, } } +/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or +/// enum. +const llvm::Type *CodeGenTypes::ConvertTagDeclType(QualType T, + const TagDecl *TD) { + llvm::DenseMap::iterator TDTI = + TagDeclTypes.find(TD); + + // If corresponding llvm type is not a opaque struct type + // then use it. + if (TDTI != TagDeclTypes.end() && // Don't have a type? + // Have a type, but it was opaque before and now we have a definition. + (!isa(TDTI->second.get()) || !TD->isDefinition())) + return TDTI->second; + + llvm::Type *ResultType = 0; + + if (!TD->isDefinition()) { + ResultType = llvm::OpaqueType::get(); + TagDeclTypes.insert(std::make_pair(TD, ResultType)); + } else if (TD->getKind() == Decl::Enum) { + // Don't bother storing enums in TagDeclTypes. + return ConvertType(cast(TD)->getIntegerType()); + } else if (TD->getKind() == Decl::Struct) { + const RecordDecl *RD = cast(TD); + + // If this is nested record and this RecordDecl is already under + // process then return associated OpaqueType for now. + if (TDTI == TagDeclTypes.end()) { + // Create new OpaqueType now for later use in case this is a recursive + // type. This will later be refined to the actual type. + ResultType = llvm::OpaqueType::get(); + TagDeclTypes.insert(std::make_pair(TD, ResultType)); + TypeHolderMap.insert(std::make_pair(T.getTypePtr(), ResultType)); + } + + // Layout fields. + RecordOrganizer RO(*this); + for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) + RO.addField(RD->getMember(i)); + const ASTRecordLayout &RL = Context.getASTRecordLayout(RD, + SourceLocation()); + RO.layoutStructFields(RL); + + // Get llvm::StructType. + CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(), + RO.getPaddingFields()); + ResultType = RLI->getLLVMType(); + TagDeclTypes.insert(std::make_pair(TD, ResultType)); + CGRecordLayouts[TD] = RLI; + + // Refining away Opaque could cause ResultType to become invalidated. + // Keep it in a happy little type holder to handle this. + llvm::PATypeHolder Holder(ResultType); + + // Refine the OpaqueType associated with this RecordDecl. + cast(TagDeclTypes.find(TD)->second.get()) + ->refineAbstractTypeTo(ResultType); + + ResultType = Holder.get(); + } else if (TD->getKind() == Decl::Union) { + const RecordDecl *RD = cast(TD); + // Just use the largest element of the union, breaking ties with the + // highest aligned member. + + if (RD->getNumMembers() != 0) { + RecordOrganizer RO(*this); + for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) + RO.addField(RD->getMember(i)); + RO.layoutUnionFields(); + + // Get llvm::StructType. + CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(), + RO.getPaddingFields()); + ResultType = RLI->getLLVMType(); + TagDeclTypes.insert(std::make_pair(TD, ResultType)); + CGRecordLayouts[TD] = RLI; + } else { + std::vector Fields; + ResultType = llvm::StructType::get(Fields); + TagDeclTypes.insert(std::make_pair(TD, ResultType)); + } + } else { + assert(0 && "FIXME: Implement tag decl kind!"); + } + + std::string TypeName(TD->getKindName()); + TypeName += '.'; + + // Name the codegen type after the typedef name + // if there is no tag type name available + if (TD->getIdentifier() == 0) { + if (T->getTypeClass() == Type::TypeName) { + const TypedefType *TdT = cast(T); + TypeName += TdT->getDecl()->getName(); + } else + TypeName += "anon"; + } else { + TypeName += TD->getName(); + } + + TheModule.addTypeName(TypeName, ResultType); + return ResultType; +} + /// getLLVMFieldNo - Return llvm::StructType element number /// that corresponds to the field FD. unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { diff --git a/CodeGen/CodeGenTypes.h b/CodeGen/CodeGenTypes.h index 2ce718579b..166d10300b 100644 --- a/CodeGen/CodeGenTypes.h +++ b/CodeGen/CodeGenTypes.h @@ -152,8 +152,13 @@ public: // These are internal details of CGT that shouldn't be used externally. /// addBitFieldInfo - Assign a start bit and a size to field FD. void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size); - /// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field FD. + /// 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(QualType T, const TagDecl *TD); }; } // end namespace CodeGen -- 2.40.0