From: Anders Carlsson Date: Sat, 14 Nov 2009 21:08:12 +0000 (+0000) Subject: Canonicalize the type before trying to create a debug type. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b6117a7727565be9fcaf709706c7d720bf191ad;p=clang Canonicalize the type before trying to create a debug type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88808 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 99bd0198bb..64748dc8f3 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -795,6 +795,29 @@ llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty, Ty, Ty->getPointeeType(), Unit); } +static QualType CanonicalizeTypeForDebugInfo(QualType T) { + switch (T->getTypeClass()) { + default: + return T; + case Type::TemplateSpecialization: + return cast(T)->desugar(); + case Type::TypeOfExpr: { + TypeOfExprType *Ty = cast(T); + return CanonicalizeTypeForDebugInfo(Ty->getUnderlyingExpr()->getType()); + } + case Type::TypeOf: + return cast(T)->getUnderlyingType(); + case Type::Decltype: + return cast(T)->getUnderlyingType(); + case Type::QualifiedName: + return cast(T)->getNamedType(); + case Type::SubstTemplateTypeParm: + return cast(T)->getReplacementType(); + case Type::Elaborated: + return cast(T)->getUnderlyingType(); + } +} + /// getOrCreateType - Get the type from the cache or create a new /// one if necessary. llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, @@ -802,6 +825,9 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, if (Ty.isNull()) return llvm::DIType(); + // Canonicalize the type. + Ty = CanonicalizeTypeForDebugInfo(Ty); + // Check for existing entry. std::map::iterator it = TypeCache.find(Ty.getAsOpaquePtr()); @@ -859,36 +885,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, case Type::FunctionProto: case Type::FunctionNoProto: return CreateType(cast(Ty), Unit); - case Type::Elaborated: - return getOrCreateType(cast(Ty)->getUnderlyingType(), - Unit); - case Type::ConstantArray: case Type::VariableArray: case Type::IncompleteArray: return CreateType(cast(Ty), Unit); - case Type::TypeOfExpr: - return getOrCreateType(cast(Ty)->getUnderlyingExpr() - ->getType(), Unit); - case Type::TypeOf: - return getOrCreateType(cast(Ty)->getUnderlyingType(), Unit); - case Type::Decltype: - return getOrCreateType(cast(Ty)->getUnderlyingType(), Unit); - - case Type::QualifiedName: { - const QualifiedNameType *T = cast(Ty); - return CreateTypeNode(T->getNamedType(), Unit); - } - - case Type::SubstTemplateTypeParm: { - const SubstTemplateTypeParmType *T = cast(Ty); - return CreateTypeNode(T->getReplacementType(), Unit); - } - - case Type::TemplateSpecialization: { - const TemplateSpecializationType *T = cast(Ty); - return CreateTypeNode(T->desugar(), Unit); - } case Type::LValueReference: return CreateType(cast(Ty), Unit); diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp index ac9aee4cb2..b89435a990 100644 --- a/test/CodeGenCXX/debug-info.cpp +++ b/test/CodeGenCXX/debug-info.cpp @@ -6,3 +6,8 @@ template struct Identity { void f(Identity::Type a) {} void f(Identity a) {} void f(int& a) { } + +template struct A { + A *next; +}; +void f(A) { }