[clang] source range of variable template specialization should include initializer
authorTomasz Kamiński <tomasz.kamiński@sonarsource.com>
Mon, 27 Mar 2023 08:13:20 +0000 (10:13 +0200)
committerTomasz Kamiński <tomasz.kamiński@sonarsource.com>
Mon, 27 Mar 2023 10:22:06 +0000 (12:22 +0200)
This patch adjust the getSourceRange() for the
VarTemplateSpecializationDecl and VarTemplatePartialSpecializationDecl,
such that the initializer is included if present:
```
template<typename T>
T temp = 1;

template<> double temp<double> = 1;
```
This patch makes it consistent with the behavior of
non-template variables with initializers and restores
behavior that was present before https://reviews.llvm.org/D139705.

n case, when the initializer is not present we still
include the template arguments in the source range,
which was required for fixing zero-initialization fix-it.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D146733

clang/docs/ReleaseNotes.rst
clang/include/clang/AST/DeclTemplate.h
clang/lib/AST/DeclTemplate.cpp
clang/test/AST/ast-dump-template-decls.cpp

index 5ea223e..385f7db 100644 (file)
@@ -230,6 +230,11 @@ Bug Fixes in This Version
   antecipation of `CWG2563 <https://cplusplus.github.io/CWG/issues/2563.html>_`.
 - Fix highlighting issue with ``_Complex`` and initialization list with more than
   2 items. (`#61518 <https://github.com/llvm/llvm-project/issues/61518>`_)
+- Fix  ``getSourceRange`` on  ``VarTemplateSpecializationDecl`` and
+  ``VarTemplatePartialSpecializationDecl``, which represents variable with
+  the initializer, so it behaves consistently with other ``VarDecls`` and ends
+  on the last token of initializer, instead of right angle bracket of
+  the template argument list.
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index ae2542f..f2a1e16 100644 (file)
@@ -2926,13 +2926,7 @@ public:
     return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
   }
 
-  SourceRange getSourceRange() const override LLVM_READONLY {
-    if (isExplicitSpecialization()) {
-      if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
-        return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
-    }
-    return VarDecl::getSourceRange();
-  }
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
     Profile(ID, TemplateArgs->asArray(), getASTContext());
@@ -3091,13 +3085,7 @@ public:
     return First->InstantiatedFromMember.setInt(true);
   }
 
-  SourceRange getSourceRange() const override LLVM_READONLY {
-    if (isExplicitSpecialization()) {
-      if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
-        return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
-    }
-    return VarDecl::getSourceRange();
-  }
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
     Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
index 531be70..77dfd58 100644 (file)
@@ -1402,6 +1402,15 @@ void VarTemplateSpecializationDecl::setTemplateArgsInfo(
       ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
 }
 
+SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
+  if (isExplicitSpecialization() && !hasInit()) {
+    if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
+      return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
+  }
+  return VarDecl::getSourceRange();
+}
+
+
 //===----------------------------------------------------------------------===//
 // VarTemplatePartialSpecializationDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -1447,6 +1456,14 @@ VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
 }
 
+SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
+  if (isExplicitSpecialization() && !hasInit()) {
+    if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
+      return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
+  }
+  return VarDecl::getSourceRange();
+}
+
 static TemplateParameterList *
 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
   // typename T
index fe367ae..847a437 100644 (file)
@@ -197,9 +197,7 @@ int unTempl<int>;
 
 template<>
 float unTempl<float> = 1;
-// FIXME (#61680) - serializing and loading AST should not affect reported source range
-// DIRECT:     VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:20> col:7 unTempl 'float' cinit
-// SERIALIZED: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 unTempl 'float' cinit
+// CHECK:      VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 unTempl 'float' cinit
 // CHECK-NEXT: |-TemplateArgument type 'float'
 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
 // CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <col:24> 'float' <IntegralToFloating>
@@ -245,9 +243,7 @@ int binTempl<int, int>;
 
 template<>
 float binTempl<float, float> = 1;
-// FIXME (#61680) - serializing and loading AST should not affect reported source range
-// DIRECT:    VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:28> col:7 binTempl 'float' cinit
-// SERIALIZED: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:32> col:7 binTempl 'float' cinit
+// CHECK:     VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:32> col:7 binTempl 'float' cinit
 // CHECK-NEXT: |-TemplateArgument type 'float'
 // CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
 // CHECK-NEXT: |-TemplateArgument type 'float'