forked from OSchip/llvm-project
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:
parent
d8efd89b20
commit
f1b382e87d
|
@ -719,6 +719,32 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
|
||||||
return BlockLiteralGeneric;
|
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) {
|
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
|
||||||
// Typedefs are derived from some other type. If we have a typedef of a
|
// Typedefs are derived from some other type. If we have a typedef of a
|
||||||
// typedef, make sure to emit the whole chain.
|
// typedef, make sure to emit the whole chain.
|
||||||
|
@ -1932,9 +1958,12 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
|
||||||
switch (T->getTypeClass()) {
|
switch (T->getTypeClass()) {
|
||||||
default:
|
default:
|
||||||
return C.getQualifiedType(T.getTypePtr(), Quals);
|
return C.getQualifiedType(T.getTypePtr(), Quals);
|
||||||
case Type::TemplateSpecialization:
|
case Type::TemplateSpecialization: {
|
||||||
T = cast<TemplateSpecializationType>(T)->desugar();
|
const auto *Spec = cast<TemplateSpecializationType>(T);
|
||||||
break;
|
if (Spec->isTypeAlias())
|
||||||
|
return C.getQualifiedType(T.getTypePtr(), Quals);
|
||||||
|
T = Spec->desugar();
|
||||||
|
break; }
|
||||||
case Type::TypeOfExpr:
|
case Type::TypeOfExpr:
|
||||||
T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
|
T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
|
||||||
break;
|
break;
|
||||||
|
@ -2191,8 +2220,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
|
||||||
case Type::Atomic:
|
case Type::Atomic:
|
||||||
return CreateType(cast<AtomicType>(Ty), Unit);
|
return CreateType(cast<AtomicType>(Ty), Unit);
|
||||||
|
|
||||||
case Type::Attributed:
|
|
||||||
case Type::TemplateSpecialization:
|
case Type::TemplateSpecialization:
|
||||||
|
return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
|
||||||
|
|
||||||
|
case Type::Attributed:
|
||||||
case Type::Elaborated:
|
case Type::Elaborated:
|
||||||
case Type::Paren:
|
case Type::Paren:
|
||||||
case Type::SubstTemplateTypeParm:
|
case Type::SubstTemplateTypeParm:
|
||||||
|
|
|
@ -109,6 +109,7 @@ class CGDebugInfo {
|
||||||
llvm::DIType CreateType(const ComplexType *Ty);
|
llvm::DIType CreateType(const ComplexType *Ty);
|
||||||
llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
|
llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
|
||||||
llvm::DIType CreateType(const TypedefType *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::DIType CreateType(const ObjCObjectPointerType *Ty,
|
||||||
llvm::DIFile F);
|
llvm::DIFile F);
|
||||||
llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
|
llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue