From 0acee6e0d722ba41026bf01bdd7b5f7ebbfc32b0 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 14 Nov 2009 21:08:12 +0000 Subject: [PATCH] Canonicalize the type before trying to create a debug type. llvm-svn: 88808 --- clang/lib/CodeGen/CGDebugInfo.cpp | 52 ++++++++++++++-------------- clang/test/CodeGenCXX/debug-info.cpp | 5 +++ 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 99bd0198bbc2..64748dc8f34b 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/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/clang/test/CodeGenCXX/debug-info.cpp b/clang/test/CodeGenCXX/debug-info.cpp index ac9aee4cb2f4..b89435a99044 100644 --- a/clang/test/CodeGenCXX/debug-info.cpp +++ b/clang/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) { }