149 lines · cpp
1// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown_unknown -std=c++17 %s -o - -w -debug-info-kind=limited -gsimple-template-names=mangled \2// RUN: | FileCheck %s3// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown_unknown -std=c++17 %s -o - -w -debug-info-kind=limited -gsimple-template-names=simple \4// RUN: | FileCheck %s --implicit-check-not=_STN --check-prefix=SIMPLE5// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown_unknown -std=c++17 %s -o - -w -debug-info-kind=limited \6// RUN: | FileCheck %s --implicit-check-not=_STN --check-prefix=FULL7// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown_unknown -std=c++17 %s -o - -w -debug-info-kind=line-tables-only -gsimple-template-names=mangled -fdebug-info-for-profiling \8// RUN: | FileCheck %s --implicit-check-not=_STN --check-prefix=FULL9 10template <typename... T>11void f1() {}12template <typename T, T V>13void f2() {}14template <typename... T>15struct t1 {};16extern int x;17int x;18struct t2 {19 template <typename T = float>20 operator t1<int>() { __builtin_unreachable(); }21};22template <template <typename...> class T>23void f3() {}24namespace {25enum LocalEnum { LocalEnum1 };26}27template<typename T, T ... ts>28struct t3 { };29struct t4 {30 t3<LocalEnum, LocalEnum1> m1;31};32 33t4 v1;34enum { UnnamedEnum1 };35template<decltype(UnnamedEnum1)>36void f4() {37}38// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "t3<(anonymous namespace)::LocalEnum, ((anonymous namespace)::LocalEnum)0>"39void f() {40 // Basic examples of simplifiable/rebuildable names41 f1<>();42 // CHECK: !DISubprogram(name: "_STN|f1|<>",43 // SIMPLE: !DISubprogram(name: "f1",44 // FULL: !DISubprogram(name: "f1<>",45 f1<int>();46 // CHECK: !DISubprogram(name: "_STN|f1|<int>",47 f1<void()>();48 // CHECK: !DISubprogram(name: "_STN|f1|<void ()>",49 f2<int, 42>();50 // CHECK: !DISubprogram(name: "_STN|f2|<int, 42>",51 52 // Check that even though the nested name can't be rebuilt, it'll carry its53 // full name and the outer name can be rebuilt from that.54 f1<t1<void() noexcept>>();55 // CHECK: !DISubprogram(name: "_STN|f1|<t1<void () noexcept> >",56 57 // Vector array types are encoded in DWARF but the decoding in llvm-dwarfdump58 // isn't implemented yet.59 f1<__attribute__((__vector_size__((sizeof(int) * 2)))) int>();60 // CHECK: !DISubprogram(name: "f1<__attribute__((__vector_size__(2 * sizeof(int)))) int>",61 62 // noexcept is part of function types in C++17 onwards, but not encoded in63 // DWARF64 f1<void() noexcept>();65 // CHECK: !DISubprogram(name: "f1<void () noexcept>",66 67 // Unnamed entities (lambdas, structs/classes, enums) can't be fully rebuilt68 // since we don't emit the column number. Also lambdas and unnamed classes are69 // ambiguous with each other - there's no DWARF that designates a lambda as70 // anything other than another unnamed class/struct.71 auto Lambda = [] {};72 f1<decltype(Lambda)>();73 // CHECK: !DISubprogram(name: "f1<(lambda at {{.*}}simple-template-names.cpp:[[# @LINE - 2]]:17)>",74 f1<t1<t1<decltype(Lambda)>>>();75 // CHECK: !DISubprogram(name: "f1<t1<t1<(lambda at {{.*}}> > >",76 struct {77 } unnamed_struct;78 f1<decltype(unnamed_struct)>();79 // CHECK: !DISubprogram(name: "f1<(unnamed struct at {{.*}}simple-template-names.cpp:[[# @LINE - 3]]:3)>",80 f1<void (decltype(unnamed_struct))>();81 // CHECK: !DISubprogram(name: "f1<void ((unnamed struct at {{.*}}simple-template-names.cpp:[[# @LINE - 5]]:3))>",82 enum {} unnamed_enum;83 f1<decltype(unnamed_enum)>();84 // CHECK: !DISubprogram(name: "f1<(unnamed enum at {{.*}}simple-template-names.cpp:[[# @LINE - 2]]:3)>",85 86 // Declarations can't readily be reversed as the value in the DWARF only87 // contains the address of the value - we'd have to do symbol lookup to find88 // the name of that value (& rely on it not having been stripped out, etc).89 f2<int *, &x>();90 // CHECK: !DISubprogram(name: "f2<int *, &x>",91 92 // We could probably handle \/ this case, but since it's a small subset of93 // pointer typed non-type-template parameters which can't be handled it94 // doesn't seem high priority.95 f2<decltype(nullptr), nullptr>();96 // CHECK: !DISubprogram(name: "f2<std::nullptr_t, nullptr>",97 98 // These larger constants are encoded as data blocks which makes them a bit99 // harder to re-render. I think they might be missing sign information, or at100 // maybe it's just a question of doing APInt things to render such large101 // values. Punting on this for now.102 f2<__int128, ((__int128)9223372036854775807) * 2>();103 // CHECK: !DISubprogram(name: "f2<__int128, (__int128)18446744073709551614>",104 105 t2().operator t1<int>();106 // FIXME: This should be something like "operator t1<int><float>"107 // CHECK: !DISubprogram(name: "operator t1<float>",108 109 // Function pointer non-type-template parameters currently don't get any DWARF110 // value (GCC doesn't provide one either) and even if there was a value, if111 // it's like variable/pointer non-type template parameters, it couldn't be112 // rebuilt anyway (see the note above for details on that) so we don't have to113 // worry about seeing conversion operators as parameters to other templates.114 115 f3<t1>();116 // CHECK: !DISubprogram(name: "_STN|f3|<t1>",117 118 f1<_BitInt(3)>();119 // CHECK: !DISubprogram(name: "_STN|f1|<_BitInt(3)>",120 121 f1<const unsigned _BitInt(5)>();122 // CHECK: !DISubprogram(name: "_STN|f1|<const unsigned _BitInt(5)>",123 124 f1<_BitInt(120)>();125 // CHECK: !DISubprogram(name: "_STN|f1|<_BitInt(120)>",126 127 f1<const unsigned _BitInt(120)>();128 // CHECK: !DISubprogram(name: "_STN|f1|<const unsigned _BitInt(120)>",129 130 f2<_BitInt(2), 1>();131 // CHECK: !DISubprogram(name: "_STN|f2|<_BitInt(2), (_BitInt(2))1>",132 133 f2<_BitInt(64), 12>();134 // CHECK: !DISubprogram(name: "_STN|f2|<_BitInt(64), (_BitInt(64))12>",135 136 // FIXME: make block forms reconstitutable137 f2<_BitInt(65), 1>();138// CHECK: !DISubprogram(name: "f2<_BitInt(65), (_BitInt(65))1>",139 140 // Add a parameter just so this differs from other attributed function types141 // that don't mangle differently.142 int fnrt() __attribute__((noreturn));143 f1<decltype(fnrt)>();144 // CHECK: !DISubprogram(name: "f1<int () __attribute__((noreturn))>",145 146 f4<UnnamedEnum1>();147 // CHECK: !DISubprogram(name: "f4<((unnamed enum at {{.*}}))0>"148}149