[clang] [clang] deprecate alias, class templates without arg list after template kw (PR #94789)

2024-06-07 Thread Erick Velez via cfe-commits

evelez7 wrote:

Looks like this heavily affects libcxx, will a `DefaultIgnore` silence the 
diagnostic?

https://github.com/llvm/llvm-project/pull/94789
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)

2024-06-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/94820

Change some parameters in DeclarationFragments.h to be passed by const 
reference. Caught by cppcheck.

Fixes #92756 but doesn't address return value `RT` for `getTopLevelRecords`. 
I'm not sure we'd want a const return of the top records, and returning `RT` by 
reference makes clang complain about returning a temporary object.

>From 98840a10f31705ab684375bf77dcab46ba9009ee Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Fri, 7 Jun 2024 16:23:09 -0700
Subject: [PATCH] [clang][ExtractAPI][NFC] pass params by const reference

---
 clang/include/clang/ExtractAPI/DeclarationFragments.h | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 535da90b98284..7dae4e2f8ac1d 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -199,7 +199,8 @@ class DeclarationFragments {
 return *this;
   }
 
-  DeclarationFragments (std::string NewSpelling, unsigned Position) {
+  DeclarationFragments (const std::string ,
+unsigned Position) {
 Fragments.at(Position).Spelling = NewSpelling;
 return *this;
   }
@@ -240,7 +241,7 @@ class DeclarationFragments {
 
 class AccessControl {
 public:
-  AccessControl(std::string Access) : Access(Access) {}
+  AccessControl(const std::string ) : Access(Access) {}
   AccessControl() : Access("public") {}
 
   const std::string () const { return Access; }
@@ -262,7 +263,7 @@ class FunctionSignature {
 std::string Name;
 DeclarationFragments Fragments;
 
-Parameter(StringRef Name, DeclarationFragments Fragments)
+Parameter(StringRef Name, const DeclarationFragments )
 : Name(Name), Fragments(Fragments) {}
   };
 
@@ -275,7 +276,7 @@ class FunctionSignature {
 return *this;
   }
 
-  void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
+  void setReturnType(const DeclarationFragments ) { ReturnType = RT; }
 
   /// Determine if the FunctionSignature is empty.
   ///

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] deprecate alias, class templates without arg list after template kw (PR #94789)

2024-06-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/94789

Deprecate the use of the template keyword before the qualified name of an alias 
or class template without a template argument list. Introduced in 
[P1787](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html), 
with current wording [here](https://eel.is/c++draft/depr.template.template).

>From 336f2667eecfcfa32afc3695c0dd27a08b302b8e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Thu, 6 Jun 2024 11:13:14 -0700
Subject: [PATCH] [clang] deprecate alias, class templates without arg list
 after template kw

---
 clang/include/clang/Basic/DiagnosticParseKinds.td | 4 
 clang/lib/Parse/ParseTemplate.cpp | 4 
 clang/test/CXX/drs/cwg0xx.cpp | 1 +
 clang/test/CXX/drs/cwg10xx.cpp| 3 ++-
 clang/test/CXX/drs/cwg13xx.cpp| 4 
 clang/test/CXX/drs/cwg17xx.cpp| 1 +
 clang/test/CXX/drs/cwg3xx.cpp | 1 +
 .../test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp  | 1 +
 .../temp.decls/temp.variadic/multi-level-substitution.cpp | 1 +
 clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp   | 2 +-
 clang/test/CXX/temp/temp.param/p15-cxx0x.cpp  | 4 ++--
 clang/test/CXX/temp/temp.res/temp.local/p1.cpp| 4 ++--
 clang/test/PCH/cxx-templates.cpp  | 4 
 clang/test/PCH/cxx-templates.h| 3 ---
 clang/test/SemaCXX/nested-name-spec-locations.cpp | 2 +-
 clang/test/SemaCXX/redeclared-alias-template.cpp  | 2 +-
 clang/test/SemaTemplate/alias-church-numerals.cpp | 3 +--
 clang/test/SemaTemplate/alias-template-template-param.cpp | 3 +--
 clang/test/SemaTemplate/concepts-GH53354.cpp  | 3 +--
 clang/test/SemaTemplate/default-arguments.cpp | 2 +-
 clang/test/SemaTemplate/instantiate-self.cpp  | 2 +-
 .../test/SemaTemplate/instantiate-template-template-parm.cpp  | 2 +-
 clang/test/SemaTemplate/temp-param-subst-linear.cpp   | 3 +--
 23 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index d8c3fee7841f4..661bb6059767b 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -891,6 +891,10 @@ def missing_template_arg_list_after_template_kw : 
Extension<
   "a template argument list is expected after a name prefixed by the template "
   "keyword">, 
InGroup>,
   DefaultError;
+def warn_missing_template_arg_list_after_template_kw_deprecated : Warning<
+  "the use of the keyword template before the qualified name of a class or "
+  "alias template without a template argument list is deprecated">,
+  
InGroup>;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseTemplate.cpp 
b/clang/lib/Parse/ParseTemplate.cpp
index a5130f56600e5..e44a70ffda1af 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1420,6 +1420,10 @@ ParsedTemplateArgument 
Parser::ParseTemplateTemplateArgument() {
   UnqualifiedId Name;
   Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
   ConsumeToken(); // the identifier
+  if (Tok.isNot(tok::less)) {
+Diag(Tok.getLocation(),
+ 
diag::warn_missing_template_arg_list_after_template_kw_deprecated);
+  }
 
   TryConsumeToken(tok::ellipsis, EllipsisLoc);
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index fe3e0cfc1d421..3204327b8e670 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1422,6 +1422,7 @@ namespace cwg96 { // cwg96: sup P1787
 // expected-error@-1 {{a template argument list is expected after a name 
prefixed by the template keyword}}
 A::template S s;
 B b;
+// expected-warning@-1 {{the use of the keyword template before the 
qualified name of a class or alias template without a template argument list is 
deprecated}}
   }
 }
 
diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp
index 58d552942c77c..0db9ab3b3c267 100644
--- a/clang/test/CXX/drs/cwg10xx.cpp
+++ b/clang/test/CXX/drs/cwg10xx.cpp
@@ -40,7 +40,8 @@ namespace cwg1004 { // cwg1004: 5
   // This example (from the standard) is actually ill-formed, because
   // name lookup of "T::template A" names the constructor.
   template class U = T::template A> struct Third { };
-  // expected-error@-1 {{is a constructor name}}
+  // expected-warning@-1 {{the use of the keyword template before the 
qualified name of a class or alias template without a template argument list is 

[clang] [clang] require arg list in type specifiers using template kw (PR #94674)

2024-06-06 Thread Erick Velez via cfe-commits

evelez7 wrote:

I'm also preparing a patch for deprecating the use of template kw without an 
arg list for alias and class templates. Decided to split that up since a lot of 
tests require deprecation messages.

https://github.com/llvm/llvm-project/pull/94674
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require arg list in type specifiers using template kw (PR #94674)

2024-06-06 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/94674

Require a template argument list after a name prefixed by the template keyword 
in nested name specifiers. Addresses [CWG 
96](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96) which was 
superseded by 
[P1787](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html).

Followup to #80801.

>From 9eadf89be9550547ccaa16ebd61307e602466118 Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Tue, 4 Jun 2024 11:39:39 -0700
Subject: [PATCH] [clang] require arg list in type specifiers using template kw

---
 clang/lib/Parse/Parser.cpp | 12 +++-
 clang/test/Parser/cxx2a-concepts-requires-expr.cpp |  2 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 6d0cf7b174e50..71b87147e9a5f 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -2060,9 +2060,19 @@ bool Parser::TryAnnotateTypeOrScopeToken(
   return true;
 }
 
+bool TemplateKWPresent = false;
+if (Tok.is(tok::kw_template)) {
+  ConsumeToken();
+  TemplateKWPresent = true;
+}
+
 TypeResult Ty;
 if (Tok.is(tok::identifier)) {
-  // FIXME: check whether the next token is '<', first!
+  if (TemplateKWPresent && NextToken().isNot(tok::less)) {
+Diag(Tok.getLocation(),
+ diag::missing_template_arg_list_after_template_kw);
+return true;
+  }
   Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
  *Tok.getIdentifierInfo(),
  Tok.getLocation());
diff --git a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp 
b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
index 971591afb08db..5755844a323d2 100644
--- a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
+++ b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp
@@ -83,7 +83,7 @@ bool r23 = requires { typename identity::temp; };
 template
 bool r24 = requires {
 typename identity::template temp;
-typename identity::template temp; // expected-error{{expected an 
identifier or template-id after '::'}}
+typename identity::template temp; // expected-error{{template argument 
list is expected after a name prefixed by the template keyword}}
 };
 
 bool r25 = requires { ; };

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-31 Thread Erick Velez via cfe-commits

https://github.com/evelez7 closed 
https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-31 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From 2c8c5129a9df16c87d9a89ce3864b857c438978e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/8] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/cwg0xx.cpp |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8328be5890dd..92e69ace3c635 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,6 +887,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..719bbc499a19b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 6c600bbc7c3f6..bff529d1339a7 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1418,7 +1418,7 @@ namespace cwg96 { // cwg96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index f42c812a860d0..2196bfb6eaac3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}} expected-error {{a template 
argument list is expected after a name prefixed by the template keyword}}
 
   template
-  int () { return 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-30 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From 2c8c5129a9df16c87d9a89ce3864b857c438978e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/7] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/cwg0xx.cpp |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8328be5890dd..92e69ace3c635 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,6 +887,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..719bbc499a19b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 6c600bbc7c3f6..bff529d1339a7 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1418,7 +1418,7 @@ namespace cwg96 { // cwg96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index f42c812a860d0..2196bfb6eaac3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}} expected-error {{a template 
argument list is expected after a name prefixed by the template keyword}}
 
   template
-  int () { return 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-30 Thread Erick Velez via cfe-commits


@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||

evelez7 wrote:

Yeah this case isn't covered here. The error fires before reaching this method. 
I can try to diagnose it for this patch if needed, or I can do a followup patch.

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-30 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From 2c8c5129a9df16c87d9a89ce3864b857c438978e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/6] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/cwg0xx.cpp |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8328be5890dd..92e69ace3c635 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,6 +887,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..719bbc499a19b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 6c600bbc7c3f6..bff529d1339a7 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1418,7 +1418,7 @@ namespace cwg96 { // cwg96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index f42c812a860d0..2196bfb6eaac3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}} expected-error {{a template 
argument list is expected after a name prefixed by the template keyword}}
 
   template
-  int () { return 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-30 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From 2c8c5129a9df16c87d9a89ce3864b857c438978e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/5] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/cwg0xx.cpp |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8328be5890dd..92e69ace3c635 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,6 +887,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..719bbc499a19b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 6c600bbc7c3f6..bff529d1339a7 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1418,7 +1418,7 @@ namespace cwg96 { // cwg96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index f42c812a860d0..2196bfb6eaac3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}} expected-error {{a template 
argument list is expected after a name prefixed by the template keyword}}
 
   template
-  int () { return 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-30 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From 2c8c5129a9df16c87d9a89ce3864b857c438978e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/4] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/cwg0xx.cpp |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8328be5890dd..92e69ace3c635 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -887,6 +887,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index e149b1a0fb5ef..719bbc499a19b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -3026,13 +3027,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 6c600bbc7c3f6..bff529d1339a7 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -1418,7 +1418,7 @@ namespace cwg96 { // cwg96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index f42c812a860d0..2196bfb6eaac3 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 
'A::template n' requires template arguments}} expected-error {{a template 
argument list is expected after a name prefixed by the template keyword}}
 
   template
-  int () { return 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-05-23 Thread Erick Velez via cfe-commits

evelez7 wrote:

ping @Endilll 

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)

2024-05-23 Thread Erick Velez via cfe-commits

https://github.com/evelez7 approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/93205
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-04-02 Thread Erick Velez via cfe-commits

https://github.com/evelez7 closed 
https://github.com/llvm/llvm-project/pull/77716
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-03-26 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/77716

>From f0f25f2eb4f654c9a9f04c92deea9df2da6fc64c Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Wed, 10 Jan 2024 18:28:19 -0800
Subject: [PATCH] [clang][ExtractAPI] improve template argument name deduction

The names of template arguments in partial specializations or parameters used as
types might be mangled according to index and depth. Instead of looping
through parameter lists to find matches like we do now, they can be
deduced via their QualTypes or as written from the AST.
---
 .../clang/ExtractAPI/DeclarationFragments.h   | 19 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 51 ---
 2 files changed, 14 insertions(+), 56 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index b85a5d21d61217..8a3a22d9a594c6 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -27,8 +27,6 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
 #include 
 
 namespace clang {
@@ -315,13 +313,9 @@ class DeclarationFragmentsBuilder {
   static DeclarationFragments
   getFragmentsForTemplateParameters(ArrayRef);
 
-  static std::string
-  getNameForTemplateArgument(const ArrayRef, std::string);
-
-  static DeclarationFragments
-  getFragmentsForTemplateArguments(const ArrayRef,
-   ASTContext &,
-   const std::optional>);
+  static DeclarationFragments getFragmentsForTemplateArguments(
+  const ArrayRef, ASTContext &,
+  const std::optional>);
 
   static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
 
@@ -430,12 +424,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const 
FunctionT *Function) {
   if (isa(Function) &&
   dyn_cast(Function)->getDescribedFunctionTemplate() &&
   StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
-std::string ProperArgName =
-getNameForTemplateArgument(dyn_cast(Function)
-   ->getDescribedFunctionTemplate()
-   ->getTemplateParameters()
-   ->asArray(),
-   ReturnType.begin()->Spelling);
+std::string ProperArgName = Function->getReturnType().getAsString();
 ReturnType.begin()->Spelling.swap(ProperArgName);
   }
   ReturnType.append(std::move(After));
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 80a0a498dc4001..22b98e07c2c890 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -14,14 +14,11 @@
 #include "clang/ExtractAPI/DeclarationFragments.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/QualTypeNames.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringSwitch.h"
-#include 
 
 using namespace clang::extractapi;
 using namespace llvm;
@@ -535,9 +532,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
   getFragmentsForType(T, Var->getASTContext(), After);
   if (StringRef(ArgumentFragment.begin()->Spelling)
   .starts_with("type-parameter")) {
-std::string ProperArgName = getNameForTemplateArgument(
-Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(),
-ArgumentFragment.begin()->Spelling);
+std::string ProperArgName = T.getAsString();
 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
   }
   Fragments.append(std::move(ArgumentFragment))
@@ -570,12 +565,7 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const 
ParmVarDecl *Param) {
 
   if (StringRef(TypeFragments.begin()->Spelling)
   .starts_with("type-parameter")) {
-std::string ProperArgName = getNameForTemplateArgument(
-dyn_cast(Param->getDeclContext())
-->getDescribedFunctionTemplate()
-->getTemplateParameters()
-->asArray(),
-TypeFragments.begin()->Spelling);
+std::string ProperArgName = Param->getOriginalType().getAsString();
 TypeFragments.begin()->Spelling.swap(ProperArgName);
   }
 
@@ -668,11 +658,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const 
FunctionDecl *Func) {
   getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
   if (StringRef(ReturnValueFragment.begin()->Spelling)
   .starts_with("type-parameter")) {
-std::string ProperArgName =
-

[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-03-26 Thread Erick Velez via cfe-commits


@@ -1127,7 +1096,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
   .append("<", DeclarationFragments::FragmentKind::Text)
   .append(getFragmentsForTemplateArguments(
   Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
-  Decl->getTemplateParameters()->asArray()))
+  Decl->getTemplateArgsAsWritten()->arguments()))

evelez7 wrote:

In this patch `getFragmentsForTemplateArguments`, which is being called here, 
is changed to accept `ArrayRef` (which is what the changed 
line returns) instead of `ArrayRef` because of the nasty loop that 
was deleted in `DeclarationFragments.cpp:962`. A `TemplateArgumentLoc` gives us 
the name of the specialization's type argument directly, instead of comparing 
with the declaration's template parameters.

https://github.com/llvm/llvm-project/pull/77716
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-03-26 Thread Erick Velez via cfe-commits

evelez7 wrote:

ping

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-08 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From fd07c0a15eb45c3e7eb400026ea7702ae909a11e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/4] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/dr0xx.cpp  |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a30ab27566ec3e..159600f3e26dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..b3a1a6f6cf80d0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 5959f0a0c8dd65..127d45be5bda97 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d512..37dbe0b212eb6a 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}} expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 
   template
-  int () { return T::template n; } // 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From fd07c0a15eb45c3e7eb400026ea7702ae909a11e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/3] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/dr0xx.cpp  |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a30ab27566ec3e..159600f3e26dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..b3a1a6f6cf80d0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 5959f0a0c8dd65..127d45be5bda97 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d512..37dbe0b212eb6a 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}} expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 
   template
-  int () { return T::template n; } // 

[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-02-07 Thread Erick Velez via cfe-commits

evelez7 wrote:

ping

https://github.com/llvm/llvm-project/pull/77716
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-07 Thread Erick Velez via cfe-commits

evelez7 wrote:

I was wondering why the Windows CI was failing but seems to be bugged according 
to Discourse. Newest commit changes the error to a pedantic warning that 
defaults to an error.

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/80801

>From fd07c0a15eb45c3e7eb400026ea7702ae909a11e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH 1/2] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/dr0xx.cpp  |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a30ab27566ec3e..159600f3e26dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..b3a1a6f6cf80d0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 5959f0a0c8dd65..127d45be5bda97 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d512..37dbe0b212eb6a 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}}
+  int  = A::template n; // expected-error {{use of variable template 'n' 
requires template arguments}} expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 
   template
-  int () { return T::template n; } // 

[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-06 Thread Erick Velez via cfe-commits


@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;

evelez7 wrote:

> This should be a pedantic warning (maybe defaulting to an error) Otherwise we 
> might break existing (non conforming) code

I've done this by adding this as a warning to the Pedantic diagnostic group, 
but I've had to increment the number in `test/Misc/warning-flags.c:91`, and 
there's a rather stern warning about not adding to `-Wpedantic`. Would this be 
ok?

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-06 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-06 Thread Erick Velez via cfe-commits


@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?

evelez7 wrote:

The use of 'template' before an alias template is 
[deprecated](https://eel.is/c++draft/depr.template.template), along with before 
a class template. I wasn't sure how to interpret this for clang, they aren't 
errors yet?

https://github.com/llvm/llvm-project/pull/80801
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] require template arg list after template kw (PR #80801)

2024-02-05 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/80801

Require a template argument list after an identifier prefixed by the template 
keyword. Introduced by [CWG 
96](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96). Current 
wording of [temp.names] introduced in 
[P1787R6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1787r6.html).

Fixes #53095

>From fd07c0a15eb45c3e7eb400026ea7702ae909a11e Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Mon, 5 Feb 2024 21:26:07 -0800
Subject: [PATCH] [clang] require template arg list after template kw

Require a template argument list after an identifier prefixed by the
template keyword. Introduced by CWG 96.

Fixes #53095
---
 .../clang/Basic/DiagnosticParseKinds.td   |  3 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 23 
 clang/test/CXX/drs/dr0xx.cpp  |  2 +-
 .../cxx1y-variable-templates_in_class.cpp |  6 ++--
 .../test/SemaCXX/template-specialization.cpp  |  2 +-
 clang/test/SemaTemplate/dependent-names.cpp   |  6 ++--
 clang/test/SemaTemplate/template-id-expr.cpp  | 36 +--
 .../SemaTemplate/template-id-printing.cpp | 13 ---
 8 files changed, 46 insertions(+), 45 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a30ab27566ec3e..159600f3e26dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -868,6 +868,9 @@ def err_requires_expr_in_simple_requirement : Error<
   "requires expression in requirement body; did "
   "you intend to place it in a nested requirement? (add another 'requires' "
   "before the expression)">;
+def err_missing_template_arg_list_after_template_kw : Error<
+  "a template argument list is expected after a name prefixed by the template "
+  "keyword">;
 
 def err_missing_dependent_template_keyword : Error<
   "use 'template' keyword to treat '%0' as a dependent template name">;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..b3a1a6f6cf80d0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec , 
ParsedType ObjectType,
   SS, ObjectType, ObjectHadErrors,
   TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,
   EnteringContext, Result, TemplateSpecified);
-else if (TemplateSpecified &&
- Actions.ActOnTemplateName(
- getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,
- EnteringContext, Template,
- /*AllowInjectedClassName*/ true) == TNK_Non_template)
-  return true;
 
+if (TemplateSpecified) {
+  TemplateNameKind TNK =
+  Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,
+ObjectType, EnteringContext, Template,
+/*AllowInjectedClassName*/ true);
+  if (TNK == TNK_Non_template)
+return true;
+
+  // C++ [template.names]p6
+  // A name prefixed by the keyword template shall be followed by a 
template
+  // argument list or refer to a class template or an alias template.
+  if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name 
||
+   TNK == TNK_Var_template) &&
+  !Tok.is(tok::less))
+Diag(IdLoc, diag::err_missing_template_arg_list_after_template_kw);
+}
 return false;
   }
 
diff --git a/clang/test/CXX/drs/dr0xx.cpp b/clang/test/CXX/drs/dr0xx.cpp
index 5959f0a0c8dd65..127d45be5bda97 100644
--- a/clang/test/CXX/drs/dr0xx.cpp
+++ b/clang/test/CXX/drs/dr0xx.cpp
@@ -1414,7 +1414,7 @@ namespace dr96 { // dr96: no
 // FIXME: This is ill-formed, because 'f' is not a template-id and does not
 // name a class template.
 // FIXME: What about alias templates?
-int k2 = a.template f(1);
+int k2 = a.template f(1); // expected-error {{a template argument list is 
expected after a name prefixed by the template keyword}}
 A::template S s;
 B b;
   }
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d512..37dbe0b212eb6a 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
   struct A {
 template static int n; // expected-note 2{{here}}
   };
-  int  = A::template n; // expected-error {{use of 

[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-01-11 Thread Erick Velez via cfe-commits

https://github.com/evelez7 updated 
https://github.com/llvm/llvm-project/pull/77716

>From c6373dcc5f8c647f483266954fd95a6f7b5df44c Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Wed, 10 Jan 2024 18:28:19 -0800
Subject: [PATCH] [clang][ExtractAPI] improve template argument name deduction

The names of template arguments in partial specializations or parameters used as
types might be mangled according to index and depth. Instead of looping
through parameter lists to find matches like we do now, they can be
deduced via their QualTypes or as written from the AST.
---
 .../clang/ExtractAPI/DeclarationFragments.h   | 19 ++-
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 51 ---
 2 files changed, 14 insertions(+), 56 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index d719196b9a43ec..84b4fc5a54377f 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -27,8 +27,6 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
 #include 
 
 namespace clang {
@@ -314,13 +312,9 @@ class DeclarationFragmentsBuilder {
   static DeclarationFragments
   getFragmentsForTemplateParameters(ArrayRef);
 
-  static std::string
-  getNameForTemplateArgument(const ArrayRef, std::string);
-
-  static DeclarationFragments
-  getFragmentsForTemplateArguments(const ArrayRef,
-   ASTContext &,
-   const std::optional>);
+  static DeclarationFragments getFragmentsForTemplateArguments(
+  const ArrayRef, ASTContext &,
+  const std::optional>);
 
   static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
 
@@ -430,12 +424,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const 
FunctionT *Function) {
   dyn_cast(Function)->getDescribedFunctionTemplate() &&
   ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
   0) {
-std::string ProperArgName =
-getNameForTemplateArgument(dyn_cast(Function)
-   ->getDescribedFunctionTemplate()
-   ->getTemplateParameters()
-   ->asArray(),
-   ReturnType.begin()->Spelling);
+std::string ProperArgName = Function->getReturnType().getAsString();
 ReturnType.begin()->Spelling.swap(ProperArgName);
   }
   ReturnType.append(std::move(After));
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index eb6eea0aaf5465..9f45d2eaeb8875 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -14,14 +14,11 @@
 #include "clang/ExtractAPI/DeclarationFragments.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/QualTypeNames.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringSwitch.h"
-#include 
 
 using namespace clang::extractapi;
 using namespace llvm;
@@ -535,9 +532,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
   getFragmentsForType(T, Var->getASTContext(), After);
   if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
   "type-parameter") == 0) {
-std::string ProperArgName = getNameForTemplateArgument(
-Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(),
-ArgumentFragment.begin()->Spelling);
+std::string ProperArgName = T.getAsString();
 ArgumentFragment.begin()->Spelling.swap(ProperArgName);
   }
   Fragments.append(std::move(ArgumentFragment))
@@ -570,12 +565,7 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const 
ParmVarDecl *Param) {
 
   if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") 
==
   0) {
-std::string ProperArgName = getNameForTemplateArgument(
-dyn_cast(Param->getDeclContext())
-->getDescribedFunctionTemplate()
-->getTemplateParameters()
-->asArray(),
-TypeFragments.begin()->Spelling);
+std::string ProperArgName = Param->getOriginalType().getAsString();
 TypeFragments.begin()->Spelling.swap(ProperArgName);
   }
 
@@ -668,11 +658,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const 
FunctionDecl *Func) {
   getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
   if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare(
   "type-parameter") == 0) {
-std::string ProperArgName =
-

[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)

2024-01-10 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/77716

The names of template arguments in partial specializations or parameters used 
as types might be mangled according to index and depth. Instead of looping 
through parameter lists to find matches like we do now, they can be deduced via 
their QualTypes or as written from the AST.

>From ac995ade6d9e4e0ebf4e897594ccfa5c4f5e4b60 Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Wed, 10 Jan 2024 18:28:19 -0800
Subject: [PATCH] [clang][ExtractAPI] improve template argument name deduction

The names of template arguments in partial specializations or parameters used as
types might be mangled according to index and depth. Instead of looping
through parameter lists to find matches like we do now, they can be
deduced via their QualTypes or as written from the AST.
---
 .../clang/ExtractAPI/DeclarationFragments.h   | 22 +++
 clang/lib/ExtractAPI/DeclarationFragments.cpp | 58 +--
 .../class_template_partial_spec.cpp   |  3 +-
 .../global_var_template_partial_spec.cpp  |  3 +-
 4 files changed, 25 insertions(+), 61 deletions(-)

diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index d719196b9a43ec..5af4a01fa6bb9c 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -27,8 +27,6 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/MacroInfo.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
 #include 
 
 namespace clang {
@@ -67,6 +65,9 @@ class DeclarationFragments {
 /// parameters.
 GenericParameter,
 
+/// Argument for partial template specialization.
+GenericArgument,
+
 /// External parameters in Objective-C methods.
 /// For example, \c forKey in
 /// \code{.m}
@@ -314,13 +315,9 @@ class DeclarationFragmentsBuilder {
   static DeclarationFragments
   getFragmentsForTemplateParameters(ArrayRef);
 
-  static std::string
-  getNameForTemplateArgument(const ArrayRef, std::string);
-
-  static DeclarationFragments
-  getFragmentsForTemplateArguments(const ArrayRef,
-   ASTContext &,
-   const std::optional>);
+  static DeclarationFragments getFragmentsForTemplateArguments(
+  const ArrayRef, ASTContext &,
+  const std::optional>);
 
   static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
 
@@ -430,12 +427,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const 
FunctionT *Function) {
   dyn_cast(Function)->getDescribedFunctionTemplate() &&
   ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
   0) {
-std::string ProperArgName =
-getNameForTemplateArgument(dyn_cast(Function)
-   ->getDescribedFunctionTemplate()
-   ->getTemplateParameters()
-   ->asArray(),
-   ReturnType.begin()->Spelling);
+std::string ProperArgName = Function->getReturnType().getAsString();
 ReturnType.begin()->Spelling.swap(ProperArgName);
   }
   ReturnType.append(std::move(After));
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index eb6eea0aaf5465..2c82aeab6083ba 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -14,14 +14,11 @@
 #include "clang/ExtractAPI/DeclarationFragments.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/QualTypeNames.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Basic/OperatorKinds.h"
 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/StringSwitch.h"
-#include 
 
 using namespace clang::extractapi;
 using namespace llvm;
@@ -102,6 +99,8 @@ StringRef DeclarationFragments::getFragmentKindString(
 return "internalParam";
   case DeclarationFragments::FragmentKind::Text:
 return "text";
+  case DeclarationFragments::FragmentKind::GenericArgument:
+return "genericArgument";
   }
 
   llvm_unreachable("Unhandled FragmentKind");
@@ -122,6 +121,8 @@ DeclarationFragments::parseFragmentKindFromString(StringRef 
S) {
   .Case("internalParam", DeclarationFragments::FragmentKind::InternalParam)
   .Case("externalParam", DeclarationFragments::FragmentKind::ExternalParam)
   .Case("text", DeclarationFragments::FragmentKind::Text)
+  .Case("genericArgument",
+DeclarationFragments::FragmentKind::GenericArgument)
   .Default(DeclarationFragments::FragmentKind::None);
 }
 
@@ -535,9 +536,7 @@ 
DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
   

[clang] [clang][ExtractAPI] Add support C unions in non C++ parsing mode (PR #77451)

2024-01-09 Thread Erick Velez via cfe-commits

https://github.com/evelez7 approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/77451
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 approved this pull request.


https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 deleted 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 requested changes to this pull request.

LGTM except for while loop

https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)

2023-11-27 Thread Erick Velez via cfe-commits


@@ -24,6 +26,40 @@
 using namespace clang::extractapi;
 using namespace llvm;
 
+namespace {
+
+void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo,
+ clang::FunctionTypeLoc ,
+ clang::FunctionProtoTypeLoc ) {
+  if (!TSInfo)
+return;
+
+  clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+  while (true) {
+// Look through qualified types
+if (auto QualifiedTL = TL.getAs()) {
+  TL = QualifiedTL.getUnqualifiedLoc();
+  continue;
+}
+
+if (auto AttrTL = TL.getAs()) {
+  TL = AttrTL.getModifiedLoc();
+  continue;
+}
+
+// Try to get the function prototype behind the block pointer type,
+// then we're done.
+if (auto BlockPtr = TL.getAs()) {
+  TL = BlockPtr.getPointeeLoc().IgnoreParens();
+  Block = TL.getAs();
+  BlockProto = TL.getAs();
+}
+break;

evelez7 wrote:

Wouldn't this while just break on the first iteration?

https://github.com/llvm/llvm-project/pull/73369
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 closed 
https://github.com/llvm/llvm-project/pull/65646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

evelez7 wrote:

Nevermind: https://reviews.llvm.org/D158474#inline-1544258

https://github.com/llvm/llvm-project/pull/65646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 edited 
https://github.com/llvm/llvm-project/pull/65646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 review_requested 
https://github.com/llvm/llvm-project/pull/65646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 created 
https://github.com/llvm/llvm-project/pull/65646:

Issue raised here: https://reviews.llvm.org/D158474#inline-1543925

We can still test that `bool` is properly serialized using the `bool.cpp` test.

>From 966ff8288a16f710c5220b152cb7ce0fa735a2ee Mon Sep 17 00:00:00 2001
From: Erick Velez 
Date: Thu, 7 Sep 2023 10:27:36 -0700
Subject: [PATCH] [clang][ExtractAPI] Remove test with system header

---
 clang/test/ExtractAPI/bool.c | 204 ---
 1 file changed, 204 deletions(-)
 delete mode 100644 clang/test/ExtractAPI/bool.c

diff --git a/clang/test/ExtractAPI/bool.c b/clang/test/ExtractAPI/bool.c
deleted file mode 100644
index fc013792c67991..00
--- a/clang/test/ExtractAPI/bool.c
+++ /dev/null
@@ -1,204 +0,0 @@
-// RUN: rm -rf %t
-// RUN: split-file %s %t
-// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
-// RUN: %t/reference.output.json.in >> %t/reference.output.json
-// RUN: %clang -extract-api -target arm64-apple-macosx \
-// RUN: %t/input.h -o %t/output.json
-
-// Generator version is not consistent across test runs, normalize it.
-// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
-// RUN: %t/output.json >> %t/output-normalized.json
-// RUN: diff %t/reference.output.json %t/output-normalized.json
-
-//--- input.h
-#include 
-bool Foo;
-
-bool IsFoo(bool Bar);
-/// expected-no-diagnostics
-
-//--- reference.output.json.in
-{
-  "metadata": {
-"formatVersion": {
-  "major": 0,
-  "minor": 5,
-  "patch": 3
-},
-"generator": "?"
-  },
-  "module": {
-"name": "",
-"platform": {
-  "architecture": "arm64",
-  "operatingSystem": {
-"minimumVersion": {
-  "major": 11,
-  "minor": 0,
-  "patch": 0
-},
-"name": "macosx"
-  },
-  "vendor": "apple"
-}
-  },
-  "relationships": [],
-  "symbols": [
-{
-  "accessLevel": "public",
-  "declarationFragments": [
-{
-  "kind": "typeIdentifier",
-  "preciseIdentifier": "c:b",
-  "spelling": "bool"
-},
-{
-  "kind": "text",
-  "spelling": " "
-},
-{
-  "kind": "identifier",
-  "spelling": "Foo"
-},
-{
-  "kind": "text",
-  "spelling": ";"
-}
-  ],
-  "identifier": {
-"interfaceLanguage": "c",
-"precise": "c:@Foo"
-  },
-  "kind": {
-"displayName": "Global Variable",
-"identifier": "c.var"
-  },
-  "location": {
-"position": {
-  "character": 6,
-  "line": 2
-},
-"uri": "file://INPUT_DIR/input.h"
-  },
-  "names": {
-"navigator": [
-  {
-"kind": "identifier",
-"spelling": "Foo"
-  }
-],
-"subHeading": [
-  {
-"kind": "identifier",
-"spelling": "Foo"
-  }
-],
-"title": "Foo"
-  },
-  "pathComponents": [
-"Foo"
-  ]
-},
-{
-  "accessLevel": "public",
-  "declarationFragments": [
-{
-  "kind": "typeIdentifier",
-  "preciseIdentifier": "c:b",
-  "spelling": "bool"
-},
-{
-  "kind": "text",
-  "spelling": " "
-},
-{
-  "kind": "identifier",
-  "spelling": "IsFoo"
-},
-{
-  "kind": "text",
-  "spelling": "("
-},
-{
-  "kind": "typeIdentifier",
-  "preciseIdentifier": "c:b",
-  "spelling": "bool"
-},
-{
-  "kind": "text",
-  "spelling": " "
-},
-{
-  "kind": "internalParam",
-  "spelling": "Bar"
-},
-{
-  "kind": "text",
-  "spelling": ");"
-}
-  ],
-  "functionSignature": {
-"parameters": [
-  {
-"declarationFragments": [
-  {
-"kind": "typeIdentifier",
-"preciseIdentifier": "c:b",
-"spelling": "bool"
-  },
-  {
-"kind": "text",
-"spelling": " "
-  },
-  {
-"kind": "internalParam",
-"spelling": "Bar"
-  }
-],
-"name": "Bar"
-  }
-],
-"returns": [
-  {
-"kind": "typeIdentifier",
-"preciseIdentifier": "c:b",
-"spelling": "bool"
-  }
-]
-  },
-  "identifier": {
-"interfaceLanguage": "c",
-"precise": "c:@F@IsFoo"
-  },
-  "kind": {
-"displayName": "Function",
-"identifier": "c.func"
-  },
-  "location": {
-"position": {
-  "character": 6,
-  "line": 4
-},
-"uri": "file://INPUT_DIR/input.h"
-  },
-  

[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)

2023-09-07 Thread Erick Velez via cfe-commits

https://github.com/evelez7 review_requested 
https://github.com/llvm/llvm-project/pull/65646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e817445 - [clang][ExtractAPI] Fix bool spelling coming from the macro definition.

2023-08-22 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-22T15:00:14-07:00
New Revision: e81744563a53b1ed0aaa2cefda885287974a9e21

URL: 
https://github.com/llvm/llvm-project/commit/e81744563a53b1ed0aaa2cefda885287974a9e21
DIFF: 
https://github.com/llvm/llvm-project/commit/e81744563a53b1ed0aaa2cefda885287974a9e21.diff

LOG: [clang][ExtractAPI] Fix bool spelling coming from the macro definition.

getFragmentsForType resulted in a bool typeIdentifier fragment to be spelled 
"_Bool".
This fixes the spelling to be "bool" and checks it in C and C++.

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/bool.c
clang/test/ExtractAPI/bool.cpp

Modified: 
clang/include/clang/ExtractAPI/DeclarationFragments.h
clang/lib/ExtractAPI/DeclarationFragments.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h 
b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 3c05f43e829c60..316d83df13e935 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -170,6 +170,11 @@ class DeclarationFragments {
 return *this;
   }
 
+  DeclarationFragments (std::string NewSpelling, unsigned Position) {
+Fragments.at(Position).Spelling = NewSpelling;
+return *this;
+  }
+
   /// Append a text Fragment of a space character.
   ///
   /// \returns a reference to the DeclarationFragments object itself after

diff  --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index f1fff6bf513df6..3c15d5073b01eb 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -397,6 +397,9 @@ DeclarationFragments 
DeclarationFragmentsBuilder::getFragmentsForType(
   DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals),
TypeFragments =
getFragmentsForType(SQT.Ty, Context, After);
+  if (QT.getAsString() == "_Bool")
+TypeFragments.replace("bool", 0);
+
   if (QualsFragments.getFragments().empty())
 return TypeFragments;
 

diff  --git a/clang/test/ExtractAPI/bool.c b/clang/test/ExtractAPI/bool.c
new file mode 100644
index 00..fc013792c67991
--- /dev/null
+++ b/clang/test/ExtractAPI/bool.c
@@ -0,0 +1,204 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
+// RUN: %t/reference.output.json.in >> %t/reference.output.json
+// RUN: %clang -extract-api -target arm64-apple-macosx \
+// RUN: %t/input.h -o %t/output.json
+
+// Generator version is not consistent across test runs, normalize it.
+// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
+// RUN: %t/output.json >> %t/output-normalized.json
+// RUN: 
diff  %t/reference.output.json %t/output-normalized.json
+
+//--- input.h
+#include 
+bool Foo;
+
+bool IsFoo(bool Bar);
+/// expected-no-diagnostics
+
+//--- reference.output.json.in
+{
+  "metadata": {
+"formatVersion": {
+  "major": 0,
+  "minor": 5,
+  "patch": 3
+},
+"generator": "?"
+  },
+  "module": {
+"name": "",
+"platform": {
+  "architecture": "arm64",
+  "operatingSystem": {
+"minimumVersion": {
+  "major": 11,
+  "minor": 0,
+  "patch": 0
+},
+"name": "macosx"
+  },
+  "vendor": "apple"
+}
+  },
+  "relationships": [],
+  "symbols": [
+{
+  "accessLevel": "public",
+  "declarationFragments": [
+{
+  "kind": "typeIdentifier",
+  "preciseIdentifier": "c:b",
+  "spelling": "bool"
+},
+{
+  "kind": "text",
+  "spelling": " "
+},
+{
+  "kind": "identifier",
+  "spelling": "Foo"
+},
+{
+  "kind": "text",
+  "spelling": ";"
+}
+  ],
+  "identifier": {
+"interfaceLanguage": "c",
+"precise": "c:@Foo"
+  },
+  "kind": {
+"displayName": "Global Variable",
+"identifier": "c.var"
+  },
+  "location": {
+"position": {
+  "character": 6,
+  "line": 2
+},
+"uri": "file://INPUT_DIR/input.h"
+  },
+  "names": {
+"navigator": [
+  {
+"kind": "identifier",
+"spelling": "Foo"
+  }
+],
+"subHeading": [
+  {
+"kind": "identifier",
+"spelling": "Foo"
+  }
+],
+"title": "Foo"
+  },
+  "pathComponents": [
+"Foo"
+  ]
+},
+{
+  "accessLevel": "public",
+  "declarationFragments": [
+{
+  "kind": "typeIdentifier",
+  "preciseIdentifier": "c:b",
+  "spelling": "bool"
+},
+{
+  "kind": "text",
+  

[clang] 08f034f - [clang][ExtractAPI] Add support for namespaces

2023-08-22 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-22T09:56:34-07:00
New Revision: 08f034f952fa67fc379df4caee2904de466a69f9

URL: 
https://github.com/llvm/llvm-project/commit/08f034f952fa67fc379df4caee2904de466a69f9
DIFF: 
https://github.com/llvm/llvm-project/commit/08f034f952fa67fc379df4caee2904de466a69f9.diff

LOG: [clang][ExtractAPI] Add support for namespaces

Serialize namespaces, nested namespaces, and class relationships inside them.

Depends on D157076

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/namespace.cpp
clang/test/ExtractAPI/nested_namespaces.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/DeclarationFragments.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 7b2d28f738e260..b4c0e0ad39cdf2 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -157,6 +157,7 @@ struct APIRecord {
   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
   enum RecordKind {
 RK_Unknown,
+RK_Namespace,
 RK_GlobalFunction,
 RK_GlobalFunctionTemplate,
 RK_GlobalFunctionTemplateSpecialization,
@@ -271,6 +272,20 @@ struct APIRecord {
   virtual ~APIRecord() = 0;
 };
 
+struct NamespaceRecord : APIRecord {
+  NamespaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, LinkageInfo Linkage,
+  const DocComment , DeclarationFragments Declaration,
+  DeclarationFragments SubHeading, bool IsFromSystemHeader)
+  : APIRecord(RK_Namespace, USR, Name, Loc, std::move(Availabilities),
+  Linkage, Comment, Declaration, SubHeading,
+  IsFromSystemHeader) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_Namespace;
+  }
+};
+
 /// This holds information associated with global functions.
 struct GlobalFunctionRecord : APIRecord {
   FunctionSignature Signature;
@@ -904,15 +919,17 @@ struct CXXClassRecord : APIRecord {
   SmallVector> Fields;
   SmallVector> Methods;
   SmallVector Bases;
+  AccessControl Access;
 
   CXXClassRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
  AvailabilitySet Availabilities, const DocComment ,
  DeclarationFragments Declaration,
  DeclarationFragments SubHeading, RecordKind Kind,
- bool IsFromSystemHeader)
+ AccessControl Access, bool IsFromSystemHeader)
   : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
   LinkageInfo::none(), Comment, Declaration, SubHeading,
-  IsFromSystemHeader) {}
+  IsFromSystemHeader),
+Access(Access) {}
 
   static bool classof(const APIRecord *Record) {
 return (Record->getKind() == RK_CXXClass);
@@ -929,9 +946,9 @@ struct ClassTemplateRecord : CXXClassRecord {
   AvailabilitySet Availabilities, const DocComment 
,
   DeclarationFragments Declaration,
   DeclarationFragments SubHeading, Template Template,
-  bool IsFromSystemHeader)
+  AccessControl Access, bool IsFromSystemHeader)
   : CXXClassRecord(USR, Name, Loc, std::move(Availabilities), Comment,
-   Declaration, SubHeading, RK_ClassTemplate,
+   Declaration, SubHeading, RK_ClassTemplate, Access,
IsFromSystemHeader),
 Templ(Template) {}
 
@@ -941,16 +958,14 @@ struct ClassTemplateRecord : CXXClassRecord {
 };
 
 struct ClassTemplateSpecializationRecord : CXXClassRecord {
-  ClassTemplateSpecializationRecord(StringRef USR, StringRef Name,
-PresumedLoc Loc,
-AvailabilitySet Availabilities,
-const DocComment ,
-DeclarationFragments Declaration,
-DeclarationFragments SubHeading,
-bool IsFromSystemHeader)
+  ClassTemplateSpecializationRecord(
+  StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, const DocComment ,
+  DeclarationFragments Declaration, DeclarationFragments SubHeading,
+  AccessControl Access, bool IsFromSystemHeader)
   : CXXClassRecord(USR, Name, Loc, std::move(Availabilities), Comment,
   

[clang] 3bb4855 - [clang][ExtractAPI] Refactor C++ method and field visitation

2023-08-21 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-21T10:38:01-07:00
New Revision: 3bb485530869d3ea43458b24df5a2d5302553bf9

URL: 
https://github.com/llvm/llvm-project/commit/3bb485530869d3ea43458b24df5a2d5302553bf9
DIFF: 
https://github.com/llvm/llvm-project/commit/3bb485530869d3ea43458b24df5a2d5302553bf9.diff

LOG: [clang][ExtractAPI] Refactor C++ method and field visitation

Refactor visitation for C++ record children by following the Visitor's CRTP.
Expand VisitCXXField, VisitCXXMethod for non-templates and introduce 
VisitCXXConstructor, VisitCXXDestructor.
Handle relationships by finding the parent's Record via USR from DeclContext.

Depends on D158029

Reviewed By: dang

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

Added: 


Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
clang/test/ExtractAPI/constructor_destructor.cpp
clang/test/ExtractAPI/methods.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index b855f460b9c7c1..7b2d28f738e260 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -1117,7 +1117,9 @@ struct has_function_signature
 template <>
 struct has_function_signature : public std::true_type 
{};
 template <>
-struct has_function_signature : public std::true_type {};
+struct has_function_signature : public std::true_type 
{};
+template <>
+struct has_function_signature : public std::true_type 
{};
 template <>
 struct has_function_signature : public std::true_type 
{
 };
@@ -1126,7 +1128,8 @@ struct 
has_function_signature
 : public std::true_type {};
 
 template  struct has_access : public std::false_type {};
-template <> struct has_access : public std::true_type {};
+template <> struct has_access : public std::true_type 
{};
+template <> struct has_access : public std::true_type 
{};
 template <> struct has_access : public std::true_type {};
 template <>
 struct has_access : public std::true_type {};
@@ -1267,7 +1270,7 @@ class APISet {
  DeclarationFragments SubHeading, SymbolReference Context,
  AccessControl Access, bool IsFromSystemHeaderg);
 
-  CXXFieldRecord *addCXXField(CXXClassRecord *CXXClass, StringRef Name,
+  CXXFieldRecord *addCXXField(APIRecord *CXXClass, StringRef Name,
   StringRef USR, PresumedLoc Loc,
   AvailabilitySet Availabilities,
   const DocComment ,
@@ -1322,18 +1325,25 @@ class APISet {
   DeclarationFragments SubHeading, Template Template,
   bool IsFromSystemHeader);
 
-  CXXMethodRecord *
-  addCXXMethod(CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR,
-   PresumedLoc Loc, AvailabilitySet Availability,
-   const DocComment , DeclarationFragments Declaration,
-   DeclarationFragments SubHeading, FunctionSignature Signature,
-   bool IsStatic, AccessControl Access, bool IsFromSystemHeader);
+  CXXMethodRecord *addCXXInstanceMethod(
+  APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+  AvailabilitySet Availability, const DocComment ,
+  DeclarationFragments Declaration, DeclarationFragments SubHeading,
+  FunctionSignature Signature, AccessControl Access,
+  bool IsFromSystemHeader);
+
+  CXXMethodRecord *addCXXStaticMethod(
+  APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+  AvailabilitySet Availability, const DocComment ,
+  DeclarationFragments Declaration, DeclarationFragments SubHeading,
+  FunctionSignature Signature, AccessControl Access,
+  bool IsFromSystemHeader);
 
   CXXMethodRecord *addCXXSpecialMethod(
-  CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR,
-  PresumedLoc Loc, AvailabilitySet Availability, const DocComment ,
+  APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+  AvailabilitySet Availability, const DocComment ,
   DeclarationFragments Declaration, DeclarationFragments SubHeading,
-  FunctionSignature Signature, bool IsConstructor, AccessControl Access,
+  FunctionSignature Signature, AccessControl Access,
   bool IsFromSystemHeader);
 
   CXXMethodTemplateRecord *addCXXMethodTemplate(
@@ -1508,6 +1518,13 @@ class APISet {
   const RecordMap () const {
 return CXXMethodTemplates;
   }
+  const RecordMap () const {
+return CXXInstanceMethods;
+  }
+  const RecordMap () const {
+return CXXStaticMethods;
+  }
+  const RecordMap () const { return CXXFields; }
   const RecordMap &
   

[clang] 634b2fd - [clang][ExtractAPI] Add support for C++ member templates

2023-08-21 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-21T10:17:58-07:00
New Revision: 634b2fd2cac251e2d645dadc6b00a2b2b80a08d0

URL: 
https://github.com/llvm/llvm-project/commit/634b2fd2cac251e2d645dadc6b00a2b2b80a08d0
DIFF: 
https://github.com/llvm/llvm-project/commit/634b2fd2cac251e2d645dadc6b00a2b2b80a08d0.diff

LOG: [clang][ExtractAPI] Add support for C++ member templates

Visit and serialize C++ fields by checking if a var template's context is a 
CXXRecordDecl in VisitVarTemplateDecl.

Depends on D158027

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/field_template.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index cd20de6674f708..b855f460b9c7c1 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -171,6 +171,7 @@ struct APIRecord {
 RK_Union,
 RK_StaticField,
 RK_CXXField,
+RK_CXXFieldTemplate,
 RK_CXXClass,
 RK_ClassTemplate,
 RK_ClassTemplateSpecialization,
@@ -530,6 +531,25 @@ struct CXXFieldRecord : APIRecord {
   virtual void anchor();
 };
 
+struct CXXFieldTemplateRecord : CXXFieldRecord {
+  Template Templ;
+
+  CXXFieldTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilitySet Availabilities,
+ const DocComment ,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, AccessControl Access,
+ Template Template, bool IsFromSystemHeader)
+  : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Loc,
+   std::move(Availabilities), Comment, Declaration,
+   SubHeading, Access, IsFromSystemHeader),
+Templ(Template) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_CXXFieldTemplate;
+  }
+};
+
 struct CXXMethodRecord : APIRecord {
   FunctionSignature Signature;
   AccessControl Access;
@@ -1113,6 +1133,8 @@ struct has_access : public 
std::true_type {};
 template <>
 struct has_access
 : public std::true_type {};
+template <>
+struct has_access : public std::true_type {};
 
 template  struct has_template : public std::false_type {};
 template <> struct has_template : public std::true_type 
{};
@@ -1127,6 +1149,8 @@ struct 
has_template
 : public std::true_type {};
 template <>
 struct has_template : public std::true_type {};
+template <>
+struct has_template : public std::true_type {};
 
 template <>
 struct has_template : public std::true_type {};
@@ -1251,6 +1275,12 @@ class APISet {
   DeclarationFragments SubHeading,
   AccessControl Access, bool IsFromSystemHeader);
 
+  CXXFieldTemplateRecord *addCXXFieldTemplate(
+  APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+  AvailabilitySet Availability, const DocComment ,
+  DeclarationFragments Declaration, DeclarationFragments SubHeading,
+  AccessControl Access, Template Template, bool IsFromSystemHeader);
+
   CXXClassRecord *
   addCXXClass(StringRef Name, StringRef USR, PresumedLoc Loc,
   AvailabilitySet Availability, const DocComment ,
@@ -1482,6 +1512,9 @@ class APISet {
   getCXXMethodTemplateSpecializations() const {
 return CXXMethodTemplateSpecializations;
   }
+  const RecordMap () const {
+return CXXFieldTemplates;
+  }
   const RecordMap () const { return Concepts; }
   const RecordMap () const {
 return ClassTemplates;
@@ -1564,6 +1597,7 @@ class APISet {
   RecordMap CXXMethodTemplates;
   RecordMap
   CXXMethodTemplateSpecializations;
+  RecordMap CXXFieldTemplates;
   RecordMap ClassTemplates;
   RecordMap ClassTemplateSpecializations;
   RecordMap

diff  --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h 
b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 5dfffb3e8fd60a..dbe7f78cd33430 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -697,20 +697,29 @@ bool ExtractAPIVisitorBase::VisitVarTemplateDecl(
 Context.getDiagnostics());
 
   // Build declaration fragments and sub-heading for the variable.
-  DeclarationFragments Declaration =
-  DeclarationFragmentsBuilder::getFragmentsForVarTemplate(
-  Decl->getTemplatedDecl());
+  DeclarationFragments Declaration;
+  

[clang] d8e9c5d - [clang][ExtractAPI] Visit method templates with better scheme

2023-08-21 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-21T09:05:57-07:00
New Revision: d8e9c5d9cab51f0ec21d4953014f41fe4dc603d9

URL: 
https://github.com/llvm/llvm-project/commit/d8e9c5d9cab51f0ec21d4953014f41fe4dc603d9
DIFF: 
https://github.com/llvm/llvm-project/commit/d8e9c5d9cab51f0ec21d4953014f41fe4dc603d9.diff

LOG: [clang][ExtractAPI] Visit method templates with better scheme

Visit and serialize method templates and template specializations. Introduces a 
new scheme of visiting child Decls via VisitCXXMethodDecl which will be 
followed in future patches for Fields and non-template methods.

Depends on D157579

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/method_template.cpp
clang/test/ExtractAPI/method_template_spec.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 7fc6447e93b961..cd20de6674f708 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -180,6 +180,8 @@ struct APIRecord {
 RK_CXXInstanceMethod,
 RK_CXXConstructorMethod,
 RK_CXXDestructorMethod,
+RK_CXXMethodTemplate,
+RK_CXXMethodTemplateSpecialization,
 RK_ObjCInstanceProperty,
 RK_ObjCClassProperty,
 RK_ObjCIvar,
@@ -623,6 +625,42 @@ struct CXXInstanceMethodRecord : CXXMethodRecord {
   virtual void anchor();
 };
 
+struct CXXMethodTemplateRecord : CXXMethodRecord {
+  Template Templ;
+
+  CXXMethodTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities,
+  const DocComment ,
+  DeclarationFragments Declaration,
+  DeclarationFragments SubHeading,
+  FunctionSignature Signature, AccessControl Access,
+  Template Template, bool IsFromSystemHeader)
+  : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Loc,
+std::move(Availabilities), Comment, Declaration,
+SubHeading, Signature, Access, IsFromSystemHeader),
+Templ(Template) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_CXXMethodTemplate;
+  }
+};
+
+struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
+  CXXMethodTemplateSpecializationRecord(
+  StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, const DocComment ,
+  DeclarationFragments Declaration, DeclarationFragments SubHeading,
+  FunctionSignature Signature, AccessControl Access,
+  bool IsFromSystemHeader)
+  : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Loc,
+std::move(Availabilities), Comment, Declaration,
+SubHeading, Signature, Access, IsFromSystemHeader) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_CXXMethodTemplateSpecialization;
+  }
+};
+
 /// This holds information associated with Objective-C properties.
 struct ObjCPropertyRecord : APIRecord {
   /// The attributes associated with an Objective-C property.
@@ -794,6 +832,8 @@ struct SymbolReference {
   : Name(Name), USR(USR), Source(Source) {}
   SymbolReference(const APIRecord )
   : Name(Record.Name), USR(Record.USR) {}
+  SymbolReference(const APIRecord *Record)
+  : Name(Record->Name), USR(Record->USR) {}
 
   /// Determine if this SymbolReference is empty.
   ///
@@ -1058,10 +1098,21 @@ template <>
 struct has_function_signature : public std::true_type 
{};
 template <>
 struct has_function_signature : public std::true_type {};
+template <>
+struct has_function_signature : public std::true_type 
{
+};
+template <>
+struct has_function_signature
+: public std::true_type {};
 
 template  struct has_access : public std::false_type {};
 template <> struct has_access : public std::true_type {};
 template <> struct has_access : public std::true_type {};
+template <>
+struct has_access : public std::true_type {};
+template <>
+struct has_access
+: public std::true_type {};
 
 template  struct has_template : public std::false_type {};
 template <> struct has_template : public std::true_type 
{};
@@ -1074,6 +1125,8 @@ struct has_template : 
public std::true_type {};
 template <>
 struct has_template
 : public std::true_type {};
+template <>
+struct has_template : public std::true_type {};
 
 template <>
 struct has_template : public std::true_type {};
@@ -1253,6 +1306,20 @@ class 

[clang] 80b787e - [clang][ExtractAPI] Add support for C++ global function templates

2023-08-18 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-18T17:42:05-07:00
New Revision: 80b787e803292119f30da2e1e95acff5beea61db

URL: 
https://github.com/llvm/llvm-project/commit/80b787e803292119f30da2e1e95acff5beea61db
DIFF: 
https://github.com/llvm/llvm-project/commit/80b787e803292119f30da2e1e95acff5beea61db.diff

LOG: [clang][ExtractAPI] Add support for C++ global function templates

Add records, serialization for global function templates and their 
specializations

Depends on D157350

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/global_func_template.cpp
clang/test/ExtractAPI/global_func_template_spec.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/DeclarationFragments.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 7846ad14127fe4..7fc6447e93b961 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -158,6 +158,8 @@ struct APIRecord {
   enum RecordKind {
 RK_Unknown,
 RK_GlobalFunction,
+RK_GlobalFunctionTemplate,
+RK_GlobalFunctionTemplateSpecialization,
 RK_GlobalVariable,
 RK_GlobalVariableTemplate,
 RK_GlobalVariableTemplateSpecialization,
@@ -281,6 +283,16 @@ struct GlobalFunctionRecord : APIRecord {
   IsFromSystemHeader),
 Signature(Signature) {}
 
+  GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
+   PresumedLoc Loc, AvailabilitySet Availabilities,
+   LinkageInfo Linkage, const DocComment ,
+   DeclarationFragments Declaration,
+   DeclarationFragments SubHeading,
+   FunctionSignature Signature, bool IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
+  Comment, Declaration, SubHeading, IsFromSystemHeader),
+Signature(Signature) {}
+
   static bool classof(const APIRecord *Record) {
 return Record->getKind() == RK_GlobalFunction;
   }
@@ -289,6 +301,44 @@ struct GlobalFunctionRecord : APIRecord {
   virtual void anchor();
 };
 
+struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
+  Template Templ;
+
+  GlobalFunctionTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+   AvailabilitySet Availabilities,
+   LinkageInfo Linkage, const DocComment ,
+   DeclarationFragments Declaration,
+   DeclarationFragments SubHeading,
+   FunctionSignature Signature, Template Template,
+   bool IsFromSystemHeader)
+  : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Loc,
+ std::move(Availabilities), Linkage, Comment,
+ Declaration, SubHeading, Signature,
+ IsFromSystemHeader),
+Templ(Template) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_GlobalFunctionTemplate;
+  }
+};
+
+struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
+  GlobalFunctionTemplateSpecializationRecord(
+  StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, LinkageInfo Linkage,
+  const DocComment , DeclarationFragments Declaration,
+  DeclarationFragments SubHeading, FunctionSignature Signature,
+  bool IsFromSystemHeader)
+  : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, 
Name,
+ Loc, std::move(Availabilities), Linkage, Comment,
+ Declaration, SubHeading, Signature,
+ IsFromSystemHeader) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_GlobalFunctionTemplateSpecialization;
+  }
+};
+
 /// This holds information associated with global functions.
 struct GlobalVariableRecord : APIRecord {
   GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
@@ -1025,6 +1075,15 @@ template <>
 struct has_template
 : public std::true_type {};
 
+template <>
+struct has_template : public std::true_type {};
+template <>
+struct has_function_signature
+: public std::true_type {};
+template <>
+struct has_function_signature
+: public std::true_type {};
+
 /// APISet holds the set of API records collected from given 

[clang] 8d8c898 - [clang][ExtractAPI] Add support for C++ variable templates

2023-08-18 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-18T13:57:02-07:00
New Revision: 8d8c8981cac0e548f0fca1268d6e501431564f66

URL: 
https://github.com/llvm/llvm-project/commit/8d8c8981cac0e548f0fca1268d6e501431564f66
DIFF: 
https://github.com/llvm/llvm-project/commit/8d8c8981cac0e548f0fca1268d6e501431564f66.diff

LOG: [clang][ExtractAPI] Add support for C++ variable templates

Serialize global C++ variable templates and specializations.

Depends on D157076

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/global_var_template.cpp
clang/test/ExtractAPI/global_var_template_partial_spec.cpp
clang/test/ExtractAPI/global_var_template_spec.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/DeclarationFragments.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index 83ff982be559b9..7846ad14127fe4 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -99,6 +99,24 @@ class Template {
 }
   }
 
+  Template(const VarTemplatePartialSpecializationDecl *Decl) {
+for (auto *const Parameter : *Decl->getTemplateParameters()) {
+  const auto *Param = dyn_cast(Parameter);
+  if (!Param) // some params are null
+continue;
+  std::string Type;
+  if (Param->hasTypeConstraint())
+Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+  else if (Param->wasDeclaredWithTypename())
+Type = "typename";
+  else
+Type = "class";
+
+  addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+   Param->getDepth(), Param->isParameterPack());
+}
+  }
+
   const llvm::SmallVector () const {
 return Parameters;
   }
@@ -141,6 +159,9 @@ struct APIRecord {
 RK_Unknown,
 RK_GlobalFunction,
 RK_GlobalVariable,
+RK_GlobalVariableTemplate,
+RK_GlobalVariableTemplateSpecialization,
+RK_GlobalVariableTemplatePartialSpecialization,
 RK_EnumConstant,
 RK_Enum,
 RK_StructField,
@@ -279,6 +300,14 @@ struct GlobalVariableRecord : APIRecord {
   Linkage, Comment, Declaration, SubHeading,
   IsFromSystemHeader) {}
 
+  GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
+   PresumedLoc Loc, AvailabilitySet Availabilities,
+   LinkageInfo Linkage, const DocComment ,
+   DeclarationFragments Declaration,
+   DeclarationFragments SubHeading, bool 
IsFromSystemHeader)
+  : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage,
+  Comment, Declaration, SubHeading, IsFromSystemHeader) {}
+
   static bool classof(const APIRecord *Record) {
 return Record->getKind() == RK_GlobalVariable;
   }
@@ -287,6 +316,61 @@ struct GlobalVariableRecord : APIRecord {
   virtual void anchor();
 };
 
+struct GlobalVariableTemplateRecord : GlobalVariableRecord {
+  Template Templ;
+
+  GlobalVariableTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+   AvailabilitySet Availabilities,
+   LinkageInfo Linkage, const DocComment ,
+   DeclarationFragments Declaration,
+   DeclarationFragments SubHeading,
+   class Template Template, bool 
IsFromSystemHeader)
+  : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Loc,
+ std::move(Availabilities), Linkage, Comment,
+ Declaration, SubHeading, IsFromSystemHeader),
+Templ(Template) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() == RK_GlobalVariableTemplate;
+  }
+};
+
+struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
+  GlobalVariableTemplateSpecializationRecord(
+  StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, LinkageInfo Linkage,
+  const DocComment , DeclarationFragments Declaration,
+  DeclarationFragments SubHeading, bool IsFromSystemHeader)
+  : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, 
Name,
+ Loc, std::move(Availabilities), Linkage, Comment,
+ Declaration, SubHeading, IsFromSystemHeader) {}
+
+  static bool classof(const APIRecord *Record) {
+return Record->getKind() 

[clang] 7ba37f4 - [clang][ExtractAPI] Add support for C++ class templates and concepts

2023-08-18 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-08-18T13:40:22-07:00
New Revision: 7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5

URL: 
https://github.com/llvm/llvm-project/commit/7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5
DIFF: 
https://github.com/llvm/llvm-project/commit/7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5.diff

LOG: [clang][ExtractAPI] Add support for C++ class templates and concepts

Add has_template template, DeclarationFragmentBuilder functions, and tests for 
class templates, specializations/partial specs, and concepts.

Depends on D157007

Reviewed By: dang

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

Added: 
clang/test/ExtractAPI/class_template.cpp
clang/test/ExtractAPI/class_template_param_inheritance.cpp
clang/test/ExtractAPI/class_template_partial_spec.cpp
clang/test/ExtractAPI/class_template_spec.cpp
clang/test/ExtractAPI/concept.cpp

Modified: 
clang/include/clang/ExtractAPI/API.h
clang/include/clang/ExtractAPI/DeclarationFragments.h
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
clang/lib/ExtractAPI/API.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp

Removed: 




diff  --git a/clang/include/clang/ExtractAPI/API.h 
b/clang/include/clang/ExtractAPI/API.h
index a965f49c8e91b2..83ff982be559b9 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -36,6 +36,86 @@
 namespace clang {
 namespace extractapi {
 
+class Template {
+  struct TemplateParameter {
+// "class", "typename", or concept name
+std::string Type;
+std::string Name;
+unsigned int Index;
+unsigned int Depth;
+bool IsParameterPack;
+
+TemplateParameter(std::string Type, std::string Name, unsigned int Index,
+  unsigned int Depth, bool IsParameterPack)
+: Type(Type), Name(Name), Index(Index), Depth(Depth),
+  IsParameterPack(IsParameterPack) {}
+  };
+
+  struct TemplateConstraint {
+// type name of the constraint, if it has one
+std::string Type;
+std::string Kind;
+std::string LHS, RHS;
+  };
+  llvm::SmallVector Parameters;
+  llvm::SmallVector Constraints;
+
+public:
+  Template() = default;
+
+  Template(const TemplateDecl *Decl) {
+for (auto *const Parameter : *Decl->getTemplateParameters()) {
+  const auto *Param = dyn_cast(Parameter);
+  if (!Param) // some params are null
+continue;
+  std::string Type;
+  if (Param->hasTypeConstraint())
+Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+  else if (Param->wasDeclaredWithTypename())
+Type = "typename";
+  else
+Type = "class";
+
+  addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+   Param->getDepth(), Param->isParameterPack());
+}
+  }
+
+  Template(const ClassTemplatePartialSpecializationDecl *Decl) {
+for (auto *const Parameter : *Decl->getTemplateParameters()) {
+  const auto *Param = dyn_cast(Parameter);
+  if (!Param) // some params are null
+continue;
+  std::string Type;
+  if (Param->hasTypeConstraint())
+Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+  else if (Param->wasDeclaredWithTypename())
+Type = "typename";
+  else
+Type = "class";
+
+  addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+   Param->getDepth(), Param->isParameterPack());
+}
+  }
+
+  const llvm::SmallVector () const {
+return Parameters;
+  }
+
+  const llvm::SmallVector () const {
+return Constraints;
+  }
+
+  void addTemplateParameter(std::string Type, std::string Name,
+unsigned int Index, unsigned int Depth,
+bool IsParameterPack) {
+Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
+  }
+
+  bool empty() const { return Parameters.empty() && Constraints.empty(); }
+};
+
 /// DocComment is a vector of RawComment::CommentLine.
 ///
 /// Each line represents one line of striped documentation comment,
@@ -69,6 +149,10 @@ struct APIRecord {
 RK_StaticField,
 RK_CXXField,
 RK_CXXClass,
+RK_ClassTemplate,
+RK_ClassTemplateSpecialization,
+RK_ClassTemplatePartialSpecialization,
+RK_Concept,
 RK_CXXStaticMethod,
 RK_CXXInstanceMethod,
 RK_CXXConstructorMethod,
@@ -644,6 +728,75 @@ struct CXXClassRecord : APIRecord {
   virtual void anchor();
 };
 
+struct ClassTemplateRecord : CXXClassRecord {
+  Template Templ;
+
+  ClassTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+  AvailabilitySet Availabilities, const DocComment 
,
+   

[clang] 422bcd1 - [clang][ExtractAPI] Add semicolons to vars and fields and to test reference JSON

2023-08-01 Thread Erick Velez via cfe-commits

Author: Erick Velez
Date: 2023-07-31T23:29:04-07:00
New Revision: 422bcd10c48bac9042ed9f33f3d17eb81ebfd21a

URL: 
https://github.com/llvm/llvm-project/commit/422bcd10c48bac9042ed9f33f3d17eb81ebfd21a
DIFF: 
https://github.com/llvm/llvm-project/commit/422bcd10c48bac9042ed9f33f3d17eb81ebfd21a.diff

LOG: [clang][ExtractAPI] Add semicolons to vars and fields and to test 
reference JSON

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

Added: 


Modified: 
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/test/ExtractAPI/anonymous_record_no_typedef.c
clang/test/ExtractAPI/global_record.c
clang/test/ExtractAPI/global_record_multifile.c
clang/test/ExtractAPI/known_files_only.c
clang/test/ExtractAPI/language.c
clang/test/ExtractAPI/objc_interface.m
clang/test/ExtractAPI/relative_include.m
clang/test/ExtractAPI/struct.c
clang/test/ExtractAPI/typedef_struct_enum.c
clang/test/ExtractAPI/underscored.c

Removed: 




diff  --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp 
b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 1e52f221c7982d..20335768ac30b0 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -389,7 +389,8 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const 
VarDecl *Var) {
   return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
   .appendSpace()
   .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
-  .append(std::move(After));
+  .append(std::move(After))
+  .append(";", DeclarationFragments::FragmentKind::Text);
 }
 
 DeclarationFragments
@@ -495,7 +496,8 @@ DeclarationFragmentsBuilder::getFragmentsForField(const 
FieldDecl *Field) {
   return getFragmentsForType(Field->getType(), Field->getASTContext(), After)
   .appendSpace()
   .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier)
-  .append(std::move(After));
+  .append(std::move(After))
+  .append(";", DeclarationFragments::FragmentKind::Text);
 }
 
 DeclarationFragments

diff  --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c 
b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
index 880a42c30ceb8d..0890e3cbdb6d08 100644
--- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c
+++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
@@ -316,6 +316,10 @@ struct Vehicle {
 {
   "kind": "identifier",
   "spelling": "type"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {
@@ -367,6 +371,10 @@ struct Vehicle {
 {
   "kind": "identifier",
   "spelling": "information"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {

diff  --git a/clang/test/ExtractAPI/global_record.c 
b/clang/test/ExtractAPI/global_record.c
index 7ca89875d66ae5..c287c791d947e6 100644
--- a/clang/test/ExtractAPI/global_record.c
+++ b/clang/test/ExtractAPI/global_record.c
@@ -68,6 +68,10 @@ char unavailable __attribute__((unavailable));
 {
   "kind": "identifier",
   "spelling": "num"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {

diff  --git a/clang/test/ExtractAPI/global_record_multifile.c 
b/clang/test/ExtractAPI/global_record_multifile.c
index b1e9f9ed21d425..fd4022fada6a04 100644
--- a/clang/test/ExtractAPI/global_record_multifile.c
+++ b/clang/test/ExtractAPI/global_record_multifile.c
@@ -70,6 +70,10 @@ char unavailable __attribute__((unavailable));
 {
   "kind": "identifier",
   "spelling": "num"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {

diff  --git a/clang/test/ExtractAPI/known_files_only.c 
b/clang/test/ExtractAPI/known_files_only.c
index ddb6e577823a85..1e51139c0cae4b 100644
--- a/clang/test/ExtractAPI/known_files_only.c
+++ b/clang/test/ExtractAPI/known_files_only.c
@@ -66,6 +66,10 @@ struct Foo { int a; };
 {
   "kind": "identifier",
   "spelling": "num"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {

diff  --git a/clang/test/ExtractAPI/language.c 
b/clang/test/ExtractAPI/language.c
index b9f69b272a44c3..3a434d475134f8 100644
--- a/clang/test/ExtractAPI/language.c
+++ b/clang/test/ExtractAPI/language.c
@@ -70,6 +70,10 @@ char objc;
 {
   "kind": "identifier",
   "spelling": "c"
+},
+{
+  "kind": "text",
+  "spelling": ";"
 }
   ],
   "identifier": {
@@ -150,6 +154,10 @@ char objc;
 {
   "kind": "identifier",
   "spelling": "objc"
+},
+{
+  "kind":