summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKadir Cetinkaya <kadircet@google.com>2019-10-01 14:08:51 +0000
committerKadir Cetinkaya <kadircet@google.com>2019-10-01 14:08:51 +0000
commitfd019ed54e36179d0b69d93822164ec2e5689e36 (patch)
treeadd4df2268e7c8e4ac3496a9584fd9649b5496f2
parentb67c3b6cf0f039503d35ad91c1ababebe56e036f (diff)
downloadbcm5719-llvm-fd019ed54e36179d0b69d93822164ec2e5689e36.tar.gz
bcm5719-llvm-fd019ed54e36179d0b69d93822164ec2e5689e36.zip
[clang] Make handling of unnamed template params similar to function params
Summary: Clang uses the location identifier should be inserted for declarator decls when a decl is unnamed. But for type template and template template paramaters it uses the location of "typename/class" keyword, which makes it hard for tooling to insert/change parameter names. This change tries to unify these two cases by making template parameter parsing and sourcerange operations similar to function params/declarator decls. Reviewers: ilya-biryukov Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68143 llvm-svn: 373340
-rw-r--r--clang/lib/AST/DeclTemplate.cpp8
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp13
-rw-r--r--clang/test/AST/ast-dump-decl.cpp4
-rw-r--r--clang/test/AST/ast-dump-record-definition-data-json.cpp30
-rw-r--r--clang/test/AST/ast-dump-template-decls-json.cpp8
-rw-r--r--clang/test/AST/ast-dump-template-decls.cpp4
-rw-r--r--clang/test/ASTMerge/class-template/test.cpp6
-rw-r--r--clang/test/Index/index-templates.cpp2
9 files changed, 32 insertions, 51 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 40c39c845db..c03ae22fb5d 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -510,8 +510,12 @@ SourceRange TemplateTypeParmDecl::getSourceRange() const {
if (hasDefaultArgument() && !defaultArgumentWasInherited())
return SourceRange(getBeginLoc(),
getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
- else
- return TypeDecl::getSourceRange();
+ // TypeDecl::getSourceRange returns a range containing name location, which is
+ // wrong for unnamed template parameters. e.g:
+ // it will return <[[typename>]] instead of <[[typename]]>
+ else if (getDeclName().isEmpty())
+ return SourceRange(getBeginLoc());
+ return TypeDecl::getSourceRange();
}
unsigned TemplateTypeParmDecl::getDepth() const {
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 9bb5b6eac37..928bc5aa25b 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -630,11 +630,11 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
}
// Grab the template parameter name (if given)
- SourceLocation NameLoc;
+ SourceLocation NameLoc = Tok.getLocation();
IdentifierInfo *ParamName = nullptr;
if (Tok.is(tok::identifier)) {
ParamName = Tok.getIdentifierInfo();
- NameLoc = ConsumeToken();
+ ConsumeToken();
} else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
tok::greatergreater)) {
// Unnamed template parameter. Don't have to do anything here, just
@@ -727,11 +727,11 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
: diag::ext_variadic_templates);
// Get the identifier, if given.
- SourceLocation NameLoc;
+ SourceLocation NameLoc = Tok.getLocation();
IdentifierInfo *ParamName = nullptr;
if (Tok.is(tok::identifier)) {
ParamName = Tok.getIdentifierInfo();
- NameLoc = ConsumeToken();
+ ConsumeToken();
} else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
tok::greatergreater)) {
// Unnamed template parameter. Don't have to do anything here, just
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5633582d679..199103e36fe 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1005,15 +1005,10 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
assert(S->isTemplateParamScope() &&
"Template type parameter not in template parameter scope!");
- SourceLocation Loc = ParamNameLoc;
- if (!ParamName)
- Loc = KeyLoc;
-
bool IsParameterPack = EllipsisLoc.isValid();
- TemplateTypeParmDecl *Param
- = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
- KeyLoc, Loc, Depth, Position, ParamName,
- Typename, IsParameterPack);
+ TemplateTypeParmDecl *Param = TemplateTypeParmDecl::Create(
+ Context, Context.getTranslationUnitDecl(), KeyLoc, ParamNameLoc, Depth,
+ Position, ParamName, Typename, IsParameterPack);
Param->setAccess(AS_public);
if (Param->isParameterPack())
@@ -1044,7 +1039,7 @@ NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
assert(DefaultTInfo && "expected source information for type");
// Check for unexpanded parameter packs.
- if (DiagnoseUnexpandedParameterPack(Loc, DefaultTInfo,
+ if (DiagnoseUnexpandedParameterPack(ParamNameLoc, DefaultTInfo,
UPPC_DefaultArgument))
return Param;
diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index 0d8fadc01ed..529733475a2 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -413,13 +413,13 @@ namespace testClassTemplateDecl {
// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:275:3, col:68> col:68 TestTemplateTemplateDefaultType
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:42> col:37 depth 0 index 0 TT
-// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:21 typename depth 1 index 0
+// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0
// CHECK-NEXT: | `-TemplateArgument <col:42> template TestClassTemplate
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:61, col:68> col:68 struct TestTemplateTemplateDefaultType
// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:276:3, col:82> col:48 TestTemplateTemplateDefaultType
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:37> col:37 depth 0 index 0 TT
-// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:21 typename depth 1 index 0
+// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0
// CHECK-NEXT: | `-TemplateArgument <line:275:42> template TestClassTemplate
// CHECK-NEXT: | `-inherited from TemplateTemplateParm 0x{{.+}} 'TT'
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:276:41, col:82> col:48 struct TestTemplateTemplateDefaultType definition
diff --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp
index 4ad938683e5..9de52868bdc 100644
--- a/clang/test/AST/ast-dump-record-definition-data-json.cpp
+++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp
@@ -395,14 +395,8 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: }
+// CHECK-NEXT: "begin": {},
+// CHECK-NEXT: "end": {}
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "tagUsed": "class",
@@ -497,14 +491,8 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: }
+// CHECK-NEXT: "begin": {},
+// CHECK-NEXT: "end": {}
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "tagUsed": "class",
@@ -563,14 +551,8 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "col": 29,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: }
+// CHECK-NEXT: "begin": {},
+// CHECK-NEXT: "end": {}
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "tagUsed": "class",
diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp
index 21574af2c4a..fc9aeca5b27 100644
--- a/clang/test/AST/ast-dump-template-decls-json.cpp
+++ b/clang/test/AST/ast-dump-template-decls-json.cpp
@@ -656,8 +656,8 @@ void V<Ty>::f() {}
// CHECK-NEXT: "id": "0x{{.*}}",
// CHECK-NEXT: "kind": "TemplateTypeParmDecl",
// CHECK-NEXT: "loc": {
-// CHECK-NEXT: "col": 33,
-// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: "col": 41,
+// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
@@ -1099,8 +1099,8 @@ void V<Ty>::f() {}
// CHECK-NEXT: "kind": "TemplateTypeParmDecl",
// CHECK-NEXT: "loc": {
// CHECK-NEXT: "line": 27,
-// CHECK-NEXT: "col": 11,
-// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: "col": 20,
+// CHECK-NEXT: "tokLen": 1
// CHECK-NEXT: },
// CHECK-NEXT: "range": {
// CHECK-NEXT: "begin": {
diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp
index a1f355b4da0..2fa50d8f549 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -26,7 +26,7 @@ template <typename Ty, template<typename> typename Uy>
// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+4]]:18> col:6 d
// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:20> col:20 referenced typename depth 0 index 0 Ty
// CHECK-NEXT: TemplateTemplateParmDecl 0x{{[^ ]*}} <col:24, col:52> col:52 depth 0 index 1 Uy
-// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:33> col:33 typename depth 1 index 0
+// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <col:33> col:41 typename depth 1 index 0
void d(Ty, Uy<Ty>);
template <class Ty>
@@ -47,7 +47,7 @@ void g(Ty);
template <typename = void>
// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:8> col:6 h
-// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:22> col:11 typename depth 0 index 0
+// CHECK-NEXT: TemplateTypeParmDecl 0x{{[^ ]*}} <line:[[@LINE-2]]:11, col:22> col:20 typename depth 0 index 0
// CHECK-NEXT: TemplateArgument type 'void'
void h();
diff --git a/clang/test/ASTMerge/class-template/test.cpp b/clang/test/ASTMerge/class-template/test.cpp
index 27761f6983a..671064786d7 100644
--- a/clang/test/ASTMerge/class-template/test.cpp
+++ b/clang/test/ASTMerge/class-template/test.cpp
@@ -9,13 +9,13 @@ static_assert(sizeof(X0<int>().getValue(1)) == sizeof(int));
// CHECK: class-template2.cpp:9:15: note: declared here with type 'long'
// CHECK: class-template1.cpp:12:14: warning: template parameter has different kinds in different translation units
-// CHECK: class-template2.cpp:12:10: note: template parameter declared here
+// CHECK: class-template2.cpp:12:18: note: template parameter declared here
// CHECK: class-template1.cpp:18:23: warning: non-type template parameter declared with incompatible types in different translation units ('long' vs. 'int')
// CHECK: class-template2.cpp:18:23: note: declared here with type 'int'
-// CHECK: class-template1.cpp:21:10: warning: template parameter has different kinds in different translation units
-// CHECK: class-template2.cpp:21:10: note: template parameter declared here
+// CHECK: class-template1.cpp:21:18: warning: template parameter has different kinds in different translation units
+// CHECK: class-template2.cpp:21:31: note: template parameter declared here
// CHECK: class-template2.cpp:27:20: warning: external variable 'x0r' declared with incompatible types in different translation units ('X0<double> *' vs. 'X0<float> *')
// CHECK: class-template1.cpp:26:19: note: declared here with type 'X0<float> *'
diff --git a/clang/test/Index/index-templates.cpp b/clang/test/Index/index-templates.cpp
index 424a638ffbb..b06ea7fed7a 100644
--- a/clang/test/Index/index-templates.cpp
+++ b/clang/test/Index/index-templates.cpp
@@ -155,7 +155,7 @@ using alias = T;
// CHECK-LOAD: index-templates.cpp:36:44: DeclRefExpr=OneDimension:35:16 Extent=[36:44 - 36:56]
// CHECK-LOAD: index-templates.cpp:40:8: ClassTemplate=storage:40:8 (Definition) Extent=[39:1 - 40:19]
// CHECK-LOAD: index-templates.cpp:39:45: TemplateTemplateParameter=DataStructure:39:45 (Definition) Extent=[39:10 - 39:66]
-// CHECK-LOAD: index-templates.cpp:39:19: TemplateTypeParameter=:39:19 (Definition) Extent=[39:19 - 39:27]
+// CHECK-LOAD: index-templates.cpp:39:27: TemplateTypeParameter=:39:27 (Definition) Extent=[39:19 - 39:27]
// CHECK-LOAD: index-templates.cpp:39:37: NonTypeTemplateParameter=:39:37 (Definition) Extent=[39:29 - 39:37]
// CHECK-LOAD: index-templates.cpp:39:61: TemplateRef=array:37:8 Extent=[39:61 - 39:66]
// CHECK-LOAD: index-templates.cpp:42:18: TypedefDecl=Unsigned:42:18 (Definition) Extent=[42:1 - 42:26]
OpenPOWER on IntegriCloud