else {
const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
- // Debug info for nested types is included in the member list only for
- // CodeView.
- bool IncludeNestedTypes = CGM.getCodeGenOpts().EmitCodeView;
-
// Field number for non-static fields.
unsigned fieldNo = 0;
if (const auto *V = dyn_cast<VarDecl>(I)) {
if (V->hasAttr<NoDebugAttr>())
continue;
+
+ // Skip variable template specializations when emitting CodeView. MSVC
+ // doesn't emit them.
+ if (CGM.getCodeGenOpts().EmitCodeView &&
+ isa<VarTemplateSpecializationDecl>(V))
+ continue;
+
// Reuse the existing static member declaration if one exists
auto MI = StaticDataMemberCache.find(V->getCanonicalDecl());
if (MI != StaticDataMemberCache.end()) {
// Bump field number for next field.
++fieldNo;
- } else if (IncludeNestedTypes) {
+ } else if (CGM.getCodeGenOpts().EmitCodeView) {
+ // Debug info for nested types is included in the member list only for
+ // CodeView.
if (const auto *nestedType = dyn_cast<TypeDecl>(I))
if (!nestedType->isImplicit() &&
nestedType->getDeclContext() == record)
--- /dev/null
+// RUN: %clang_cc1 %s -std=c++14 -triple=i686-pc-windows-msvc -debug-info-kind=limited -gcodeview -emit-llvm -o - | FileCheck %s
+
+// Don't emit static data member debug info for variable templates.
+// PR38004
+
+struct TestImplicit {
+ template <typename T>
+ static const __SIZE_TYPE__ size_var = sizeof(T);
+};
+int instantiate_test1() { return TestImplicit::size_var<int> + TestImplicit::size_var<TestImplicit>; }
+TestImplicit gv1;
+
+// CHECK: ![[empty:[0-9]+]] = !{}
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestImplicit",
+// CHECK-SAME: elements: ![[empty]]
+
+template <typename T> bool vtpl;
+struct TestSpecialization {
+ template <typename T, typename U> static const auto sdm = vtpl<T>;
+ template <> static const auto sdm<int, int> = false;
+} gv2;
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestSpecialization",
+// CHECK-SAME: elements: ![[empty]]
+
+template <class> bool a;
+template <typename> struct b;
+struct TestPartial {
+ template <typename... e> static auto d = a<e...>;
+ template <typename... e> static auto d<b<e...>> = d<e...>;
+} c;
+
+// CHECK: ![[A:[^ ]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TestPartial",
+// CHECK-SAME: elements: ![[empty]]