diff options
author | Devang Patel <dpatel@apple.com> | 2007-12-21 19:35:28 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2007-12-21 19:35:28 +0000 |
commit | 3c40085b373d8e6e4523812e06f73a0cb9d5142c (patch) | |
tree | cd00c4710fa34e6f4d3b14a2e834a12722998090 /CodeGen/CodeGenTypes.cpp | |
parent | dd6ecdb68b511cf672413f0f1bec027742de90f9 (diff) |
Convert opaque type when struct definition is seen.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CodeGenTypes.cpp')
-rw-r--r-- | CodeGen/CodeGenTypes.cpp | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 6fa0c2a746..97519c3428 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -114,12 +114,33 @@ CodeGenTypes::~CodeGenTypes() { CGRecordLayouts.clear(); } +/// isOpaqueTypeDefinition - Return true if LT is a llvm::OpaqueType +/// and T is tag definition. This helper routine does not check +/// relationship between T and LT. +static bool isOpaqueTypeDefinition(QualType T, llvm::Type *LT) { + + if (!isa<llvm::OpaqueType>(LT)) + return false; + + const clang::Type &Ty = *T.getCanonicalType(); + if (Ty.getTypeClass() == Type::Tagged) { + const TagType &TT = cast<TagType>(Ty); + const TagDecl *TD = TT.getDecl(); + if (TD->isDefinition()) + return true; + } + + return false; +} + /// ConvertType - Convert the specified type to its LLVM form. const llvm::Type *CodeGenTypes::ConvertType(QualType T) { // See if type is already cached. llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator I = TypeHolderMap.find(T.getTypePtr()); - if (I != TypeHolderMap.end()) + // If type is found in map and this is not a definition for a opaque + // place holder type then use it. Otherwise convert type T. + if (I != TypeHolderMap.end() && !isOpaqueTypeDefinition(T, I->second.get())) return I->second.get(); const llvm::Type *ResultType = ConvertNewType(T); @@ -261,7 +282,9 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { const TagDecl *TD = TT.getDecl(); llvm::Type *&ResultType = TagDeclTypes[TD]; - if (ResultType) + // If corresponding llvm type is not a opaque struct type + // then use it. + if (ResultType && !isOpaqueTypeDefinition(T, ResultType)) return ResultType; if (!TD->isDefinition()) { @@ -278,14 +301,19 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { if (OpaqueI != RecordTypesToResolve.end()) return OpaqueI->second; - // Create new OpaqueType now for later use. - // FIXME: This creates a lot of opaque types, most of them are not - // needed. Reevaluate this when performance analyis finds tons of - // opaque types. - llvm::OpaqueType *OpaqueTy = llvm::OpaqueType::get(); + llvm::OpaqueType *OpaqueTy = NULL; + if (ResultType) + OpaqueTy = dyn_cast<llvm::OpaqueType>(ResultType); + if (!OpaqueTy) { + // Create new OpaqueType now for later use. + // FIXME: This creates a lot of opaque types, most of them are not + // needed. Reevaluate this when performance analyis finds tons of + // opaque types. + OpaqueTy = llvm::OpaqueType::get(); + TypeHolderMap.insert(std::make_pair(T.getTypePtr(), + llvm::PATypeHolder(OpaqueTy))); + } RecordTypesToResolve[RD] = OpaqueTy; - TypeHolderMap.insert(std::make_pair(T.getTypePtr(), - llvm::PATypeHolder(OpaqueTy))); // Layout fields. RecordOrganizer RO(*this); |