diff --git a/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp index fc1098c98589..8680f71cda7f 100644 --- a/clang/lib/CodeGen/CGRTTI.cpp +++ b/clang/lib/CodeGen/CGRTTI.cpp @@ -367,11 +367,11 @@ public: case Type::MemberPointer: case Type::FunctionProto: case Type::FunctionNoProto: - return BuildTypeInfo(Ty); - case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: + return BuildTypeInfo(Ty); + case Type::Vector: case Type::ExtVector: return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE"); @@ -598,7 +598,15 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { if (ContainsIncompleteClassType(Ty)) return llvm::GlobalValue::InternalLinkage; - if (const PointerType *PointerTy = dyn_cast(Ty)) { + 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()) == @@ -606,9 +614,11 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { return llvm::GlobalVariable::InternalLinkage; return llvm::GlobalVariable::WeakODRLinkage; + break; } - - if (const RecordType *RecordTy = dyn_cast(Ty)) { + + 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. @@ -630,31 +640,39 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { return llvm::GlobalValue::ExternalLinkage; } - if (Ty->getTypeClass() == Type::Builtin) { + case Type::Builtin: return llvm::GlobalValue::WeakODRLinkage; - } - if (const FunctionType *FT = dyn_cast(Ty)) { - if (getTypeInfoLinkage(FT->getResultType()) - == llvm::GlobalValue::InternalLinkage) + case Type::FunctionProto: { + const FunctionProtoType *FPT = cast(Ty); + + // Check the return type. + if (getTypeInfoLinkage(FPT->getResultType()) == + llvm::GlobalValue::InternalLinkage) return llvm::GlobalValue::InternalLinkage; - - if (const FunctionProtoType *FPT = dyn_cast(Ty)) { - for (unsigned i = 0; i < FPT->getNumArgs(); ++i) - if (getTypeInfoLinkage(FPT->getArgType(i)) - == llvm::GlobalValue::InternalLinkage) - return llvm::GlobalValue::InternalLinkage; - for (unsigned i = 0; i < FPT->getNumExceptions(); ++i) - if (getTypeInfoLinkage(FPT->getExceptionType(i)) - == 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; } - + 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; + } + + } - // FIXME: We need to add code to handle all types. - assert(false && "Unhandled type!"); return llvm::GlobalValue::WeakODRLinkage; } @@ -663,7 +681,19 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { switch (Ty->getTypeClass()) { default: assert(0 && "Unhandled type!"); - + + case Type::ConstantArray: + case Type::IncompleteArray: + // abi::__array_type_info + VtableName = "_ZTVN10__cxxabiv117__array_type_infoE"; + break; + + case Type::FunctionNoProto: + case Type::FunctionProto: + // abi::__function_type_info + VtableName = "_ZTVN10__cxxabiv120__function_type_infoE"; + break; + case Type::Record: { const CXXRecordDecl *RD = cast(cast(Ty)->getDecl()); @@ -678,15 +708,11 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { // abi::__pointer_type_info VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE"; break; + case Type::MemberPointer: // abi::__pointer_to_member_type_info VtableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE"; break; - - case Type::FunctionNoProto: - case Type::FunctionProto: - // abi::__function_type_info - VtableName = "_ZTVN10__cxxabiv120__function_type_infoE"; } llvm::Constant *Vtable = @@ -734,6 +760,12 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) { assert(false && "Builtin type info must be in the standard library!"); break; + case Type::ConstantArray: + case Type::IncompleteArray: + // Itanium C++ ABI 2.9.5p4: + // abi::__array_type_info adds no data members to std::type_info; + break; + case Type::FunctionNoProto: case Type::FunctionProto: // Itanium C++ ABI 2.9.5p4: