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
This commit is contained in:
David Blaikie 2014-04-06 17:14:06 +00:00
parent d8efd89b20
commit f1b382e87d
3 changed files with 64 additions and 4 deletions

View File

@ -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<TypeAliasTemplateDecl>(Ty->getTemplateName().getAsTemplateDecl())
->getTemplatedDecl();
SourceLocation Loc = AliasDecl->getLocation();
llvm::DIFile File = getOrCreateFile(Loc);
unsigned Line = getLineNumber(Loc);
llvm::DIDescriptor Ctxt = getContextDescriptor(cast<Decl>(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<TemplateSpecializationType>(T)->desugar();
break;
case Type::TemplateSpecialization: {
const auto *Spec = cast<TemplateSpecializationType>(T);
if (Spec->isTypeAlias())
return C.getQualifiedType(T.getTypePtr(), Quals);
T = Spec->desugar();
break; }
case Type::TypeOfExpr:
T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
break;
@ -2191,8 +2220,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
case Type::Atomic:
return CreateType(cast<AtomicType>(Ty), Unit);
case Type::Attributed:
case Type::TemplateSpecialization:
return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
case Type::Attributed:
case Type::Elaborated:
case Type::Paren:
case Type::SubstTemplateTypeParm:

View File

@ -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);

View File

@ -0,0 +1,28 @@
// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
template<typename T>
struct foo {
};
namespace x {
// splitting these over multiple lines to make sure the right token is used for
// the location
template<typename T>
using
# 42
bar
= foo<T*>;
}
// CHECK: metadata [[BINT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bi]
// CHECK: [[BINT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<int>] [line 42
x::bar<int> bi;
// CHECK: metadata [[BFLOAT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bf]
// CHECK: [[BFLOAT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<float>] [line 42
x::bar<float> 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;