summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CodeGenTypes.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2007-12-21 19:35:28 +0000
committerDevang Patel <dpatel@apple.com>2007-12-21 19:35:28 +0000
commit505b4f1fd4413ef30d08b5e45fec67a7f3b6e7c0 (patch)
tree9f10635292d155c83ba486bb2cbc1d5d3d5e2338 /clang/CodeGen/CodeGenTypes.cpp
parent8c5822802ec9baf92531191a1f70bf8cd1a3a0cb (diff)
downloadbcm5719-llvm-505b4f1fd4413ef30d08b5e45fec67a7f3b6e7c0.tar.gz
bcm5719-llvm-505b4f1fd4413ef30d08b5e45fec67a7f3b6e7c0.zip
Convert opaque type when struct definition is seen.
llvm-svn: 45287
Diffstat (limited to 'clang/CodeGen/CodeGenTypes.cpp')
-rw-r--r--clang/CodeGen/CodeGenTypes.cpp46
1 files changed, 37 insertions, 9 deletions
diff --git a/clang/CodeGen/CodeGenTypes.cpp b/clang/CodeGen/CodeGenTypes.cpp
index 6fa0c2a7464..97519c3428a 100644
--- a/clang/CodeGen/CodeGenTypes.cpp
+++ b/clang/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);
OpenPOWER on IntegriCloud