Skip to content

Commit

Permalink
[clang][DebugInfo] Simplify logic to determine DW_AT_default_value fo…
Browse files Browse the repository at this point in the history
…r template parameters

DWARFv5 added support for labelling template parameters with
DW_AT_default_value to indicate whether the particular instantiation
defaulted parameter. The current implementation only supports a limited
set of possible cases. Namely for non-value-dependent integral template
parameters and simple type template parameters.

Useful cases that don't work are:
1. Type template parameters with defaults that are
   themselves templates. E.g.,
```
template<typename T1, typename T2 = Foo<T1>> class C1;
template<typename T = Foo<int>> class C2;
etc.
```
2. Template template parameters

`clang::isSubstitutedDefaultArgument` already implement the required logic
to determine whether a template argument is defaulted. This patch re-uses
this logic for DWARF CodeGen.

Differential Revision: https://reviews.llvm.org/D139988
  • Loading branch information
Michael137 committed Dec 16, 2022
1 parent 1706f34 commit 8d3843b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 23 deletions.
26 changes: 7 additions & 19 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Expand Up @@ -1999,35 +1999,23 @@ CGDebugInfo::CollectTemplateParams(Optional<TemplateArgs> OArgs,
const TemplateArgument &TA = Args.Args[i];
StringRef Name;
bool defaultParameter = false;
if (Args.TList)
if (Args.TList) {
Name = Args.TList->getParam(i)->getName();

NamedDecl const *ND = Args.TList->getParam(i);
defaultParameter = clang::isSubstitutedDefaultArgument(
CGM.getContext(), TA, ND, Args.Args, Args.TList->getDepth());
}

switch (TA.getKind()) {
case TemplateArgument::Type: {
llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit);

if (Args.TList)
if (auto *templateType =
dyn_cast_or_null<TemplateTypeParmDecl>(Args.TList->getParam(i)))
if (templateType->hasDefaultArgument())
defaultParameter =
templateType->getDefaultArgument() == TA.getAsType();

TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
TheCU, Name, TTy, defaultParameter));

} break;
case TemplateArgument::Integral: {
llvm::DIType *TTy = getOrCreateType(TA.getIntegralType(), Unit);
if (Args.TList)
if (auto *templateType = dyn_cast_or_null<NonTypeTemplateParmDecl>(
Args.TList->getParam(i)))
if (templateType->hasDefaultArgument() &&
!templateType->getDefaultArgument()->isValueDependent())
defaultParameter = llvm::APSInt::isSameValue(
templateType->getDefaultArgument()->EvaluateKnownConstInt(
CGM.getContext()),
TA.getAsIntegral());

TemplateParams.push_back(DBuilder.createTemplateValueParameter(
TheCU, Name, TTy, defaultParameter,
llvm::ConstantInt::get(CGM.getLLVMContext(), TA.getAsIntegral())));
Expand Down
15 changes: 11 additions & 4 deletions clang/test/CodeGenCXX/debug-info-template-parameter.cpp
Expand Up @@ -7,26 +7,33 @@

// CHECK: DILocalVariable(name: "f1", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]]
// CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F1_TYPE:[0-9]+]]
// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]]}
// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]], ![[FIFTH:[0-9]+]]}
// CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}})
// CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, value: i32 6)
// PRE17: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, value: i8 0)
// CXX17: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, value: i1 false)
// CHECK: [[FIFTH]] = !DITemplateTypeParameter(name: "d", type: !{{[0-9]*}})

// CHECK: DILocalVariable(name: "f2", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]]
// CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F2_TYPE:[0-9]+]]
// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]]}
// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]], ![[FIFTH:[0-9]+]]}
// CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}, defaulted: true)
// CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, defaulted: true, value: i32 3)
// PRE17: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, defaulted: true, value: i8 1)
// CXX17: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, defaulted: true, value: i1 true)
// CHECK: [[FIFTH]] = !DITemplateTypeParameter(name: "d", type: !{{[0-9]*}}, defaulted: true)

template <typename T = char, int i = 3, bool b = true, int x = sizeof(T)>
template <typename T>
class bar {
};

template <typename T = char, int i = 3, bool b = true, int x = sizeof(T),
typename d = bar<T>>
class foo {
};

int main() {
foo<int, 6, false, 3> f1;
foo<int, 6, false, 3, double> f1;
foo<> f2;
return 0;
}

0 comments on commit 8d3843b

Please sign in to comment.