From: Douglas Gregor Date: Wed, 31 Mar 2010 00:15:35 +0000 (+0000) Subject: Drastically simplify the computation of linkage for typeinfo by using X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=031b37140d0864c741618960b5220245a2a086ae;p=clang Drastically simplify the computation of linkage for typeinfo by using the existing (and already well-tested) linkage computation for types, with minor tweaks for dynamic classes and (pointers to) incomplete types. Fixes PR6597. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99968 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 7d284c8852..1caec97fc3 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -327,83 +327,20 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { if (ContainsIncompleteClassType(Ty)) return llvm::GlobalValue::InternalLinkage; - switch (Ty->getTypeClass()) { - default: - // FIXME: We need to add code to handle all types. - assert(false && "Unhandled type!"); - break; - - case Type::Pointer: { - const PointerType *PointerTy = cast(Ty); - - // If the pointee type has internal linkage, then the pointer type needs to - // have it as well. - if (getTypeInfoLinkage(PointerTy->getPointeeType()) == - llvm::GlobalVariable::InternalLinkage) - return llvm::GlobalVariable::InternalLinkage; - - return llvm::GlobalVariable::WeakODRLinkage; - } - - case Type::Enum: { - const EnumType *EnumTy = cast(Ty); - const EnumDecl *ED = EnumTy->getDecl(); - - // If we're in an anonymous namespace, then we always want internal linkage. - if (ED->isInAnonymousNamespace() || !ED->hasLinkage()) - return llvm::GlobalVariable::InternalLinkage; - - return llvm::GlobalValue::WeakODRLinkage; - } - - case Type::Record: { - const RecordType *RecordTy = cast(Ty); - const CXXRecordDecl *RD = cast(RecordTy->getDecl()); - - // If we're in an anonymous namespace, then we always want internal linkage. - if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) - return llvm::GlobalVariable::InternalLinkage; - - // If this class does not have a vtable, we want weak linkage. - if (!RD->isDynamicClass()) - return llvm::GlobalValue::WeakODRLinkage; - - return CodeGenModule::getVtableLinkage(RD); - } - - case Type::Vector: - case Type::ExtVector: - case Type::Builtin: - return llvm::GlobalValue::WeakODRLinkage; - - case Type::FunctionProto: { - const FunctionProtoType *FPT = cast(Ty); + switch (Ty->getLinkage()) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: + return llvm::GlobalValue::InternalLinkage; - // Check the return type. - if (getTypeInfoLinkage(FPT->getResultType()) == - llvm::GlobalValue::InternalLinkage) - return llvm::GlobalValue::InternalLinkage; - - // Check the parameter types. - for (unsigned i = 0; i != FPT->getNumArgs(); ++i) { - if (getTypeInfoLinkage(FPT->getArgType(i)) == - llvm::GlobalValue::InternalLinkage) - return llvm::GlobalValue::InternalLinkage; + case ExternalLinkage: + if (const RecordType *Record = dyn_cast(Ty)) { + const CXXRecordDecl *RD = cast(Record->getDecl()); + if (RD->isDynamicClass()) + return CodeGenModule::getVtableLinkage(RD); } - - return llvm::GlobalValue::WeakODRLinkage; - } - - case Type::ConstantArray: - case Type::IncompleteArray: { - const ArrayType *AT = cast(Ty); - - // Check the element type. - if (getTypeInfoLinkage(AT->getElementType()) == - llvm::GlobalValue::InternalLinkage) - return llvm::GlobalValue::InternalLinkage; - } + return llvm::GlobalValue::WeakODRLinkage; } return llvm::GlobalValue::WeakODRLinkage; @@ -444,8 +381,8 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { switch (Ty->getTypeClass()) { default: assert(0 && "Unhandled type!"); - // GCC treats vector types as fundamental types. case Type::Builtin: + // GCC treats vector types as fundamental types. case Type::Vector: case Type::ExtVector: // abi::__fundamental_type_info. diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp index 799c1d41c7..b9eb5b4ad4 100644 --- a/test/CodeGenCXX/rtti-linkage.cpp +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -92,6 +92,7 @@ const std::type_info &t2() { (void)typeid(D *); (void)typeid(D (*)()); (void)typeid(void (*)(D)); + (void)typeid(void (*)(D&)); // The exception specification is not part of the RTTI descriptor, so it should not have // internal linkage. (void)typeid(void (*)() throw (D));