From f1b382e87df86b5fee84c9aeb2d7b6fad6862514 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sun, 6 Apr 2014 17:14:06 +0000 Subject: [PATCH] DebugInfo: Support type alias templates We already got the type alias correct (though I've included a test case here) since Clang represents that like any other typedef - but type alias templates weren't being handled. llvm-svn: 205691 --- clang/lib/CodeGen/CGDebugInfo.cpp | 39 +++++++++++++++++++--- clang/lib/CodeGen/CGDebugInfo.h | 1 + clang/test/CodeGenCXX/debug-info-alias.cpp | 28 ++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-alias.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c8fe9120800a..33fbb8d5437c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -719,6 +719,32 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, return BlockLiteralGeneric; } +llvm::DIType CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Unit) { + assert(Ty->isTypeAlias()); + llvm::DIType Src = getOrCreateType(Ty->getAliasedType(), Unit); + assert(Src); + + SmallString<128> NS; + llvm::raw_svector_ostream OS(NS); + Ty->getTemplateName().print(OS, CGM.getContext().getPrintingPolicy(), /*qualified*/ false); + + TemplateSpecializationType::PrintTemplateArgumentList( + OS, Ty->getArgs(), Ty->getNumArgs(), + CGM.getContext().getPrintingPolicy()); + + TypeAliasDecl *AliasDecl = + cast(Ty->getTemplateName().getAsTemplateDecl()) + ->getTemplatedDecl(); + + SourceLocation Loc = AliasDecl->getLocation(); + llvm::DIFile File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); + + llvm::DIDescriptor Ctxt = getContextDescriptor(cast(AliasDecl->getDeclContext())); + + return DBuilder.createTypedef(Src, internString(OS.str()), File, Line, Ctxt); +} + llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) { // Typedefs are derived from some other type. If we have a typedef of a // typedef, make sure to emit the whole chain. @@ -1932,9 +1958,12 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) { switch (T->getTypeClass()) { default: return C.getQualifiedType(T.getTypePtr(), Quals); - case Type::TemplateSpecialization: - T = cast(T)->desugar(); - break; + case Type::TemplateSpecialization: { + const auto *Spec = cast(T); + if (Spec->isTypeAlias()) + return C.getQualifiedType(T.getTypePtr(), Quals); + T = Spec->desugar(); + break; } case Type::TypeOfExpr: T = cast(T)->getUnderlyingExpr()->getType(); break; @@ -2191,8 +2220,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { case Type::Atomic: return CreateType(cast(Ty), Unit); - case Type::Attributed: case Type::TemplateSpecialization: + return CreateType(cast(Ty), Unit); + + case Type::Attributed: case Type::Elaborated: case Type::Paren: case Type::SubstTemplateTypeParm: diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 52784daf6300..ea2998b1cb70 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -109,6 +109,7 @@ class CGDebugInfo { llvm::DIType CreateType(const ComplexType *Ty); llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg); llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg); + llvm::DIType CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Fg); llvm::DIType CreateType(const ObjCObjectPointerType *Ty, llvm::DIFile F); llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F); diff --git a/clang/test/CodeGenCXX/debug-info-alias.cpp b/clang/test/CodeGenCXX/debug-info-alias.cpp new file mode 100644 index 000000000000..e354ef0a7381 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-alias.cpp @@ -0,0 +1,28 @@ +// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s + +template +struct foo { +}; +namespace x { +// splitting these over multiple lines to make sure the right token is used for +// the location +template +using +# 42 +bar += foo; +} + +// CHECK: metadata [[BINT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bi] +// CHECK: [[BINT]] = {{.*}} ; [ DW_TAG_typedef ] [bar] [line 42 +x::bar bi; +// CHECK: metadata [[BFLOAT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bf] +// CHECK: [[BFLOAT]] = {{.*}} ; [ DW_TAG_typedef ] [bar] [line 42 +x::bar bf; + +using +// metadata [[NARF:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [n] +narf // [[NARF]] = {{.*}} ; [ DW_TAG_typedef ] [narf] [line [[@LINE]] += int; +narf n; +