diff options
| author | John McCall <rjmccall@apple.com> | 2010-02-04 22:26:26 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-02-04 22:26:26 +0000 |
| commit | 67da35c832e66d3310ed67486cb46306f20cc642 (patch) | |
| tree | fb9a44adb34cad6cc2686e6cca6427c8c0c489ed /clang/lib/CodeGen | |
| parent | 1de1707bfc789e9cf9467c2d37af2a584db6520b (diff) | |
| download | bcm5719-llvm-67da35c832e66d3310ed67486cb46306f20cc642.tar.gz bcm5719-llvm-67da35c832e66d3310ed67486cb46306f20cc642.zip | |
Extract a common structure for holding information about the definition
of a C++ record. Exposed a lot of problems where various routines were
silently doing The Wrong Thing (or The Acceptable Thing in The Wrong Order)
when presented with a non-definition. Also cuts down on memory usage.
llvm-svn: 95330
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGRTTI.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 24 |
2 files changed, 17 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp index 29552ce4441..5236d206348 100644 --- a/clang/lib/CodeGen/CGRTTI.cpp +++ b/clang/lib/CodeGen/CGRTTI.cpp @@ -256,6 +256,9 @@ bool ShouldUseExternalRTTIDescriptor(QualType Ty) { if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); + if (!RD->hasDefinition()) + return false; + if (!RD->isDynamicClass()) return false; @@ -469,7 +472,7 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()); - if (!RD->getNumBases()) { + if (!RD->hasDefinition() || !RD->getNumBases()) { // abi::__class_type_info. VtableName = "_ZTVN10__cxxabiv117__class_type_infoE"; } else if (CanUseSingleInheritance(RD)) { @@ -566,7 +569,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) { case Type::Record: { const CXXRecordDecl *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()); - if (!RD->getNumBases()) { + if (!RD->hasDefinition() || !RD->getNumBases()) { // We don't need to emit any fields. break; } diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 838f62a5cb1..e2f45fe0761 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -399,18 +399,6 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { /// enum. const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) { - // FIXME. This may have to move to a better place. - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) { - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - if (!i->isVirtual()) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - ConvertTagDeclType(Base); - } - } - } - // TagDecl's are not necessarily unique, instead use the (clang) // type connected to the decl. const Type *Key = @@ -446,6 +434,18 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) { const RecordDecl *RD = cast<const RecordDecl>(TD); + // Force conversion of non-virtual base classes recursively. + if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) { + for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), + e = RD->bases_end(); i != e; ++i) { + if (!i->isVirtual()) { + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + ConvertTagDeclType(Base); + } + } + } + // Layout fields. CGRecordLayout *Layout = CGRecordLayoutBuilder::ComputeLayout(*this, RD); |

