From 87b1f6d1901036602bcbccaeea341d175e7f900d Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 24 Aug 2013 08:21:10 +0000 Subject: [PATCH] DebugInfo: Emit info for constant expressions in template arguments Summary: This allows us to handle the general case where a non-type template argument evaluates to a constant expression which isn't integral or a declaration. This fixes PR16939. Reviewers: dblaikie, rsmith Reviewed By: dblaikie CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1453 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189165 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 12 +++++++++++- test/CodeGenCXX/debug-info-template.cpp | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 73b93ab339..c22ca886ef 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1297,8 +1297,18 @@ CollectTemplateParams(const TemplateParameterList *TPList, CollectTemplateParams(NULL, TA.getPackAsArray(), Unit)); TemplateParams.push_back(TVP); } break; + case TemplateArgument::Expression: { + const Expr *E = TA.getAsExpr(); + QualType T = E->getType(); + llvm::Value *V = CGM.EmitConstantExpr(E, T); + assert(V && "Expression in template argument isn't constant"); + llvm::DIType TTy = getOrCreateType(T, Unit); + llvm::DITemplateValueParameter TVP = + DBuilder.createTemplateValueParameter(TheCU, Name, TTy, + V->stripPointerCasts()); + TemplateParams.push_back(TVP); + } break; // And the following should never occur: - case TemplateArgument::Expression: case TemplateArgument::TemplateExpansion: case TemplateArgument::Null: llvm_unreachable( diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp index 596178d4e3..0f7230cc67 100644 --- a/test/CodeGenCXX/debug-info-template.cpp +++ b/test/CodeGenCXX/debug-info-template.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s +// RUN: %clang -S -emit-llvm -fms-extensions -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s // CHECK: [[EMPTY:![0-9]*]] = metadata !{i32 0} @@ -69,6 +69,12 @@ // CHECK: [[TCNARG5]] = {{.*}}metadata !"b", metadata [[MEMFUNPTR]], i8 0, {{.*}} ; [ DW_TAG_template_value_parameter ] // CHECK: [[TCNARG6]] = {{.*}}metadata !"f", metadata [[FUNPTR]], i8 0, {{.*}} ; [ DW_TAG_template_value_parameter ] // CHECK: [[TCNARG8]] = {{.*}}metadata !"Is", null, metadata [[EMPTY]], {{.*}} ; [ DW_TAG_GNU_template_parameter_pack ] +// CHECK: metadata [[TGIARGS:![0-9]*]]} ; [ DW_TAG_structure_type ] [tmpl_guid<&__uuidof(uuid)>] +// CHECK: [[TGIARGS]] = metadata !{metadata [[TGIARG1:![0-9]*]]} +// CHECK: [[TGIARG1]] = {{.*}}metadata !"", metadata [[CONST_GUID_PTR:![0-9]*]], { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab, {{.*}} ; [ DW_TAG_template_value_parameter ] +// CHECK: [[CONST_GUID_PTR]] = {{.*}}, metadata [[CONST_GUID:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ] +// CHECK: [[CONST_GUID]] = {{.*}}, metadata [[GUID:![0-9]*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from _GUID] +// CHECK: [[GUID]] = {{.*}} ; [ DW_TAG_structure_type ] [_GUID] [line 100, size 0, align 0, offset 0] [decl] struct foo { char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero) int e; @@ -90,3 +96,11 @@ struct tmpl_impl { TC::nested tci; TC tcn; + +struct _GUID; +template <_GUID *> +struct tmpl_guid { +}; + +struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ab}")) uuid; +tmpl_guid<&__uuidof(uuid)> tgi; -- 2.40.0