[clang] [clang][ExtractAPI] Add support for blocks in declaration fragments (PR #73369)
@@ -24,6 +26,40 @@ using namespace clang::extractapi; using namespace llvm; +namespace { + +void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo, + clang::FunctionTypeLoc &Block, + clang::FunctionProtoTypeLoc &BlockProto) { + 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] Add support for blocks in declaration fragments (PR #73369)
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)
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)
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)
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)
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 C unions in non C++ parsing mode (PR #77451)
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] improve template argument name deduction (PR #77716)
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) { getFragmentsForTy
[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)
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 = -getNameForTemplateArgument(Func->getDescribedFuncti
[clang] [clang] require template arg list after template kw (PR #80801)
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][ExtractAPI] improve template argument name deduction (PR #77716)
@@ -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][ExtractAPI] improve template argument name deduction (PR #77716)
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 = -getNameForTemplateArgument(Func->getDescribedFunct
[clang] [clang][ExtractAPI] improve template argument name deduction (PR #77716)
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] require template arg list after template kw (PR #80801)
@@ -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)
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)
@@ -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)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}} + int &r = 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 &f() { return T::template n; } // expe
[clang] [clang] require template arg list after template kw (PR #80801)
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][ExtractAPI] improve template argument name deduction (PR #77716)
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)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}} + int &r = 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 &f() { return T::template n; } // expe
[clang] [clang] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}} + int &r = 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 &f() { return T::template n; } // expe
[clang] [clang] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of va
[clang] 7ba37f4 - [clang][ExtractAPI] Add support for C++ class templates and concepts
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 &getParameters() const { +return Parameters; + } + + const llvm::SmallVector &getConstraints() 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,
[clang] 8d8c898 - [clang][ExtractAPI] Add support for C++ variable templates
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 &getParameters() 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 &Comment, + 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 &Comment, + 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 &Comment, 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 *Reco
[clang] 80b787e - [clang][ExtractAPI] Add support for C++ global function templates
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 &Comment, + 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 &Comment, + 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 &Comment, 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
[clang] d8e9c5d - [clang][ExtractAPI] Visit method templates with better scheme
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 &Comment, + 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 &Comment, + 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 &Record) : 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,
[clang] 634b2fd - [clang][ExtractAPI] Add support for C++ member templates
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 &Comment, + 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 &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + AccessControl Access, Template Template, bool IsFromSystemHeader); + CXXClassRecord * addCXXClass(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, @@ -1482,6 +1512,9 @@ class APISet { getCXXMethodTemplateSpecializations() const { return CXXMethodTemplateSpecializations; } + const RecordMap &getCXXFieldTemplates() const { +return CXXFieldTemplates; + } const RecordMap &getConcepts() const { return Concepts; } const RecordMap &getClassTemplates() 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( - De
[clang] 3bb4855 - [clang][ExtractAPI] Refactor C++ method and field visitation
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 &Comment, @@ -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 &Comment, 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 &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + FunctionSignature Signature, AccessControl Access, + bool IsFromSystemHeader); + + CXXMethodRecord *addCXXStaticMethod( + APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + FunctionSignature Signature, AccessControl Access, + bool IsFromSystemHeader); CXXMethodRecord *addCXXSpecialMethod( - CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, + APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, 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 &getCXXMethodTemplates() const { return CXXMethodTemplates; } + const RecordMap &getCXXInstanceMethods() const { +return CXXInstanceMethods; + } + const RecordMap &getCXXStaticMethods() const { +return CXXStaticMethods; +
[clang] 08f034f - [clang][ExtractAPI] Add support for namespaces
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 &Comment, 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 &Comment, 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 &Comment, 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 &Comment, -DeclarationFragments Declaration, -DeclarationFragments SubHeading, -bool IsFromSystemHeader) + ClassTemplateSpecializationRecord( + StringRef USR, StringRef Name, PresumedLoc Loc, + AvailabilitySet Availabilities, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + AccessControl Access, bool IsFromSystemHeader) : CXXClassRecord(USR, Name, Loc, std::move(Availabil
[clang] e817445 - [clang][ExtractAPI] Fix bool spelling coming from the macro definition.
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 &replace(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", + "sp
[clang] 422bcd1 - [clang][ExtractAPI] Add semicolons to vars and fields and to test reference JSON
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":
[clang] [clang][ExtractAPI] Remove test with system header (PR #65646)
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)
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)
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)
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)
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)
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] require arg list in type specifiers using template kw (PR #94674)
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 arg list in type specifiers using template kw (PR #94674)
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] deprecate alias, class templates without arg list after template kw (PR #94789)
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 dep
[clang] [clang][ExtractAPI][NFC] pass params by const reference (PR #94820)
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 &replace(std::string NewSpelling, unsigned Position) { + DeclarationFragments &replace(const std::string &NewSpelling, +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(Access) {} AccessControl() : Access("public") {} const std::string &getAccess() const { return Access; } @@ -262,7 +263,7 @@ class FunctionSignature { std::string Name; DeclarationFragments Fragments; -Parameter(StringRef Name, DeclarationFragments Fragments) +Parameter(StringRef Name, const DeclarationFragments &Fragments) : Name(Name), Fragments(Fragments) {} }; @@ -275,7 +276,7 @@ class FunctionSignature { return *this; } - void setReturnType(DeclarationFragments RT) { ReturnType = RT; } + void setReturnType(const DeclarationFragments &RT) { 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)
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] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} + int &r = 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 &f() { return T:
[clang] [clang] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} + int &r = 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 &f() { return T:
[clang] [clang] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} + int &r = 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 &f() { return T:
[clang] [clang] require template arg list after template kw (PR #80801)
@@ -2995,13 +2996,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, 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)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} + int &r = 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 &f() { return T:
[clang] [clang] require template arg list after template kw (PR #80801)
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 &SS, 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 &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} + int &r = 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 &f() { return T:
[clang] [clang] require template arg list after template kw (PR #80801)
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][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)
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] require template arg list after template kw (PR #80801)
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] require arg list in type specifiers using template kw (PR #94674)
https://github.com/evelez7 closed 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][ExtractAPI] Fix up casting from CXXClassRecord (PR #110983)
https://github.com/evelez7 approved this pull request. https://github.com/llvm/llvm-project/pull/110983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][ExtractAPI] emit correct spelling for type aliases (PR #134007)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/134007 Previously, C++11 type aliases were serialized using "typedef" regardless of the source spelling. This checks if the TypedefNameDecl is actually a TypeAliasDecl and corrects the spelling. >From 28879073b9d59dffa13f9523b4c9ec677b3a7b9c Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 1 Apr 2025 16:20:44 -0700 Subject: [PATCH] [clang][ExtractAPI] emit correct spelling for type aliases Previously, C++11 type aliases were serialized using "typedef" regardless of the source spelling. This checks if the TypedefNameDecl is actually a TypeAliasDecl and corrects the spelling. --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 26 ++--- clang/test/ExtractAPI/type-alias.cpp | 56 +++ 2 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 clang/test/ExtractAPI/type-alias.cpp diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index d7eebcbc3c2f9..80174e30ffd1a 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -1584,13 +1584,25 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( const TypedefNameDecl *Decl) { DeclarationFragments Fragments, After; - Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) - .appendSpace() - .append(getFragmentsForType(Decl->getUnderlyingType(), - Decl->getASTContext(), After)) - .append(std::move(After)) - .appendSpace() - .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); + if (!isa(Decl)) +Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) +.appendSpace() +.append(getFragmentsForType(Decl->getUnderlyingType(), +Decl->getASTContext(), After)) +.append(std::move(After)) +.appendSpace() +.append(Decl->getName(), +DeclarationFragments::FragmentKind::Identifier); + else +Fragments.append("using", DeclarationFragments::FragmentKind::Keyword) +.appendSpace() +.append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier) +.appendSpace() +.append("=", DeclarationFragments::FragmentKind::Text) +.appendSpace() +.append(getFragmentsForType(Decl->getUnderlyingType(), +Decl->getASTContext(), After)) +.append(std::move(After)); return Fragments.appendSemicolon(); } diff --git a/clang/test/ExtractAPI/type-alias.cpp b/clang/test/ExtractAPI/type-alias.cpp new file mode 100644 index 0..246e8fbb92156 --- /dev/null +++ b/clang/test/ExtractAPI/type-alias.cpp @@ -0,0 +1,56 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=TypeAlias -triple arm64-apple-macosx -x c++-header %s -o %t/type-alias.symbols.json -verify + +// RUN: FileCheck %s --input-file %t/type-alias.symbols.json --check-prefix MYALIAS +using MyAlias = int; +//MYALIAS-LABEL "!testLabel": "c:@MYALIAS" +//MYALIAS: "accessLevel": "public", +//MYALIAS: "declarationFragments": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "keyword", +//MYALIAS-NEXT: "spelling": "using" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " = " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "typeIdentifier", +//MYALIAS-NEXT: "preciseIdentifier": "c:I", +//MYALIAS-NEXT: "spelling": "int" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": ";" +//MYALIAS-NEXT:} +//MYALIAS: "kind": { +//MYALIAS-NEXT: "displayName": "Type Alias", +//MYALIAS-NEXT: "identifier": "c++.typealias" +//MYALIAS: names": { +//MYALIAS-NEXT:"navigator": [ +//MYALIAS-NEXT: { +//MYALIAS-NEXT:"kind": "identifier", +//MYALIAS-NEXT:"spelling": "MyAlias" +//MYALIAS-NEXT: } +//MYALIAS-NEXT:], +//MYALIAS-NEXT: "subHeading": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:} +//MYALIAS-NEXT:], +//MYALIAS-NEXT:"title": "MyAlias" +//MYALIAS: "pathComponents": [ +//MYALIAS-NEXT:"MyAlias" +//MYALIAS-NEXT: ] + +// expected-no-diagnostics \ No newline at end of file
[clang] [clang][ExtractAPI] emit correct spelling for type aliases (PR #134007)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/134007 >From 28879073b9d59dffa13f9523b4c9ec677b3a7b9c Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 1 Apr 2025 16:20:44 -0700 Subject: [PATCH 1/2] [clang][ExtractAPI] emit correct spelling for type aliases Previously, C++11 type aliases were serialized using "typedef" regardless of the source spelling. This checks if the TypedefNameDecl is actually a TypeAliasDecl and corrects the spelling. --- clang/lib/ExtractAPI/DeclarationFragments.cpp | 26 ++--- clang/test/ExtractAPI/type-alias.cpp | 56 +++ 2 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 clang/test/ExtractAPI/type-alias.cpp diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index d7eebcbc3c2f9..80174e30ffd1a 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -1584,13 +1584,25 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( const TypedefNameDecl *Decl) { DeclarationFragments Fragments, After; - Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) - .appendSpace() - .append(getFragmentsForType(Decl->getUnderlyingType(), - Decl->getASTContext(), After)) - .append(std::move(After)) - .appendSpace() - .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); + if (!isa(Decl)) +Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) +.appendSpace() +.append(getFragmentsForType(Decl->getUnderlyingType(), +Decl->getASTContext(), After)) +.append(std::move(After)) +.appendSpace() +.append(Decl->getName(), +DeclarationFragments::FragmentKind::Identifier); + else +Fragments.append("using", DeclarationFragments::FragmentKind::Keyword) +.appendSpace() +.append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier) +.appendSpace() +.append("=", DeclarationFragments::FragmentKind::Text) +.appendSpace() +.append(getFragmentsForType(Decl->getUnderlyingType(), +Decl->getASTContext(), After)) +.append(std::move(After)); return Fragments.appendSemicolon(); } diff --git a/clang/test/ExtractAPI/type-alias.cpp b/clang/test/ExtractAPI/type-alias.cpp new file mode 100644 index 0..246e8fbb92156 --- /dev/null +++ b/clang/test/ExtractAPI/type-alias.cpp @@ -0,0 +1,56 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=TypeAlias -triple arm64-apple-macosx -x c++-header %s -o %t/type-alias.symbols.json -verify + +// RUN: FileCheck %s --input-file %t/type-alias.symbols.json --check-prefix MYALIAS +using MyAlias = int; +//MYALIAS-LABEL "!testLabel": "c:@MYALIAS" +//MYALIAS: "accessLevel": "public", +//MYALIAS: "declarationFragments": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "keyword", +//MYALIAS-NEXT: "spelling": "using" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " = " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "typeIdentifier", +//MYALIAS-NEXT: "preciseIdentifier": "c:I", +//MYALIAS-NEXT: "spelling": "int" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": ";" +//MYALIAS-NEXT:} +//MYALIAS: "kind": { +//MYALIAS-NEXT: "displayName": "Type Alias", +//MYALIAS-NEXT: "identifier": "c++.typealias" +//MYALIAS: names": { +//MYALIAS-NEXT:"navigator": [ +//MYALIAS-NEXT: { +//MYALIAS-NEXT:"kind": "identifier", +//MYALIAS-NEXT:"spelling": "MyAlias" +//MYALIAS-NEXT: } +//MYALIAS-NEXT:], +//MYALIAS-NEXT: "subHeading": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:} +//MYALIAS-NEXT:], +//MYALIAS-NEXT:"title": "MyAlias" +//MYALIAS: "pathComponents": [ +//MYALIAS-NEXT:"MyAlias" +//MYALIAS-NEXT: ] + +// expected-no-diagnostics \ No newline at end of file >From 61e7db6a233258e538c7ef6cb9fb9077d8bec4f4 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 1 Apr 2025 21:54:51 -0700 Subject: [PATCH 2/2] add newline to test --- clang/test/ExtractAPI/type-alias.cpp | 2 +- 1
[clang] [clang][ExtractAPI] emit correct spelling for type aliases (PR #134007)
@@ -0,0 +1,56 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=TypeAlias -triple arm64-apple-macosx -x c++-header %s -o %t/type-alias.symbols.json -verify + +// RUN: FileCheck %s --input-file %t/type-alias.symbols.json --check-prefix MYALIAS +using MyAlias = int; +//MYALIAS-LABEL "!testLabel": "c:@MYALIAS" +//MYALIAS: "accessLevel": "public", +//MYALIAS: "declarationFragments": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "keyword", +//MYALIAS-NEXT: "spelling": "using" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": " = " +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "typeIdentifier", +//MYALIAS-NEXT: "preciseIdentifier": "c:I", +//MYALIAS-NEXT: "spelling": "int" +//MYALIAS-NEXT:}, +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "text", +//MYALIAS-NEXT: "spelling": ";" +//MYALIAS-NEXT:} +//MYALIAS: "kind": { +//MYALIAS-NEXT: "displayName": "Type Alias", +//MYALIAS-NEXT: "identifier": "c++.typealias" +//MYALIAS: names": { +//MYALIAS-NEXT:"navigator": [ +//MYALIAS-NEXT: { +//MYALIAS-NEXT:"kind": "identifier", +//MYALIAS-NEXT:"spelling": "MyAlias" +//MYALIAS-NEXT: } +//MYALIAS-NEXT:], +//MYALIAS-NEXT: "subHeading": [ +//MYALIAS-NEXT:{ +//MYALIAS-NEXT: "kind": "identifier", +//MYALIAS-NEXT: "spelling": "MyAlias" +//MYALIAS-NEXT:} +//MYALIAS-NEXT:], +//MYALIAS-NEXT:"title": "MyAlias" +//MYALIAS: "pathComponents": [ +//MYALIAS-NEXT:"MyAlias" +//MYALIAS-NEXT: ] + +// expected-no-diagnostics evelez7 wrote: Thanks! https://github.com/llvm/llvm-project/pull/134007 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
https://github.com/evelez7 approved this pull request. https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
@@ -40,3 +51,4 @@ target_link_libraries(ClangDocTests clangDoc LLVMTestingSupport ) + evelez7 wrote: extra newline https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
@@ -0,0 +1,61 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Utils.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace llvm; + +SmallString<128> appendPathNative(StringRef Base, StringRef Path) { + SmallString<128> Default; + sys::path::native(Base, Default); + sys::path::append(Default, Path); + return Default; +} + +SmallString<128> appendPathPosix(StringRef Base, StringRef Path) { + SmallString<128> Default; + sys::path::native(Base, Default, sys::path::Style::posix); + sys::path::append(Default, Path); + return Default; +} + +void getMustacheHtmlFiles(StringRef AssetsPath, + clang::doc::ClangDocContext &CDCtx) { + assert(!AssetsPath.empty()); + assert(sys::fs::is_directory(AssetsPath)); + + SmallString<128> DefaultStylesheet = + appendPathPosix(AssetsPath, "clang-doc-mustache.css"); + SmallString<128> NamespaceTemplate = + appendPathPosix(AssetsPath, "namespace-template.mustache"); + SmallString<128> ClassTemplate = + appendPathPosix(AssetsPath, "class-template.mustache"); + SmallString<128> EnumTemplate = + appendPathPosix(AssetsPath, "enum-template.mustache"); + SmallString<128> FunctionTemplate = + appendPathPosix(AssetsPath, "function-template.mustache"); + SmallString<128> CommentTemplate = + appendPathPosix(AssetsPath, "comments-template.mustache"); + SmallString<128> IndexJS = appendPathPosix(AssetsPath, "mustache-index.js"); + + CDCtx.JsScripts.insert(CDCtx.JsScripts.begin(), IndexJS.c_str()); + CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(), + DefaultStylesheet.str().str()); evelez7 wrote: ```suggestion DefaultStylesheet.c_str()); ``` We don't retrieve the `StringRef` first for any other `SmallString` here https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
@@ -74,7 +75,51 @@ static std::unique_ptr NamespaceTemplate = nullptr; static std::unique_ptr RecordTemplate = nullptr; +static Error +setupTemplate(std::unique_ptr &Template, + StringRef TemplatePath, + std::vector> Partials) { + auto T = MustacheTemplateFile::createMustacheFile(TemplatePath); + if (Error Err = T.takeError()) +return Err; + Template = std::move(T.get()); + for (const auto [Name, FileName] : Partials) { +if (auto Err = Template->registerPartialFile(Name, FileName)) + return Err; + } + return Error::success(); +} + static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { + // Template files need to use the native path when they're opened, + // but have to be used in Posix style when used in HTML. + auto ConvertToNative = [](std::string &&Path) -> std::string { +SmallString<128> PathBuf(Path); +llvm::sys::path::native(PathBuf); +return PathBuf.str().str(); + }; + + std::string NamespaceFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("namespace-template")); + std::string ClassFilePath = + ConvertToNative(CDCtx.MustacheTemplates.lookup("class-template")); + std::string CommentFilePath = evelez7 wrote: possible mega-nit: This is also referred to as `CommentTemplate` in Utils.cpp but its key is plural ("comments-template"). Then the first type is plural below in the pair ("Comments"). It's the only one like this. https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Add helpers for Template config (PR #138062)
@@ -6,4 +6,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangDocSupport STATIC File.cpp - ) \ No newline at end of file + Utils.cpp + ) + evelez7 wrote: nit: extra newline https://github.com/llvm/llvm-project/pull/138062 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/140856 >From e25581d28ecda89fe4e550da71e668b6ae749804 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 20 May 2025 23:26:02 -0700 Subject: [PATCH 1/2] [clang-doc] fix conversion names of dependent types Fixes #59812 The names of conversion functions of template type parameters were being emitted as "type-parameter-N-M". Now we check if the conversion type is a TemplateTypeParmType and reconstruct the source name. --- clang-tools-extra/clang-doc/Serialize.cpp | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 18db427b5239e..585a46112d43d 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -525,7 +525,13 @@ template static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace) { I.USR = getUSRForDecl(D); - I.Name = D->getNameAsString(); + auto ConversionDecl = dyn_cast_or_null(D); + if (ConversionDecl && ConversionDecl->getConversionType() +.getTypePtr() +->isTemplateTypeParmType()) +I.Name = "operator " + ConversionDecl->getConversionType().getAsString(); + else +I.Name = D->getNameAsString(); populateParentNamespaces(I.Namespace, D, IsInAnonymousNamespace); if (C) { I.Description.emplace_back(); >From a4d5ad45cad45f21505fdd8e88e2706dc3343e88 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Thu, 22 May 2025 14:14:26 -0700 Subject: [PATCH 2/2] address review feedback --- clang-tools-extra/clang-doc/Serialize.cpp | 4 ++-- .../test/clang-doc/conversion_function.cpp | 17 + 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/conversion_function.cpp diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 585a46112d43d..fe4ef9c50cc12 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -525,8 +525,8 @@ template static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace) { I.USR = getUSRForDecl(D); - auto ConversionDecl = dyn_cast_or_null(D); - if (ConversionDecl && ConversionDecl->getConversionType() + if (auto ConversionDecl = dyn_cast_or_null(D); + ConversionDecl && ConversionDecl->getConversionType() .getTypePtr() ->isTemplateTypeParmType()) I.Name = "operator " + ConversionDecl->getConversionType().getAsString(); diff --git a/clang-tools-extra/test/clang-doc/conversion_function.cpp b/clang-tools-extra/test/clang-doc/conversion_function.cpp new file mode 100644 index 0..fee86b356011e --- /dev/null +++ b/clang-tools-extra/test/clang-doc/conversion_function.cpp @@ -0,0 +1,17 @@ +// RUN: rm -rf %t && mkdir -p %t + +// RUN: clang-doc --output=%t --executor=standalone %s +// RUN: find %t/ -regex ".*/[0-9A-F]*.yaml" -exec cat {} ";" | FileCheck %s --check-prefix=CHECK-YAML + +// RUN: clang-doc --format=html --output=%t --executor=standalone %s +// FileCheck %s --check-prefix=CHECK-HTML + +template +struct MyStruct { + operator T(); +}; + +// CHECK-YAML: Name:'operator T' + +// CHECK-HTML: operator T +// CHECK-HTML: public T operator T ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Precommit test for correct conversion function names (PR #141168)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/141168 None >From 4c7294576a85fee8a373b407b39eeb0b35af4923 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Thu, 22 May 2025 17:31:37 -0700 Subject: [PATCH] [clang-doc] Precommit test for conversion function names --- .../test/clang-doc/conversion_function.cpp | 18 ++ 1 file changed, 18 insertions(+) create mode 100644 clang-tools-extra/test/clang-doc/conversion_function.cpp diff --git a/clang-tools-extra/test/clang-doc/conversion_function.cpp b/clang-tools-extra/test/clang-doc/conversion_function.cpp new file mode 100644 index 0..ad321a45b1ed5 --- /dev/null +++ b/clang-tools-extra/test/clang-doc/conversion_function.cpp @@ -0,0 +1,18 @@ +// RUN: rm -rf %t && mkdir -p %t + +// RUN: clang-doc --output=%t --executor=standalone %s +// RUN: find %t/ -regex ".*/[0-9A-F]*.yaml" -exec cat {} ";" | FileCheck %s --check-prefix=CHECK-YAML + +// RUN: clang-doc --format=html --output=%t --executor=standalone %s +// FileCheck %s --check-prefix=CHECK-HTML + +template +struct MyStruct { + operator T(); +}; + +// Output incorrect conversion names. +// CHECK-YAML-NOT: Name:'operator T' + +// CHECK-HTML-NOT: operator T +// CHECK-HTML-NOT: public T operator T() ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/140856 >From b1a07c3dd19f2aa15abc286fdde0a2cb439dd7b7 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Thu, 22 May 2025 17:08:59 -0700 Subject: [PATCH] separate test from code change --- clang-tools-extra/clang-doc/Serialize.cpp | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 18db427b5239e..fe4ef9c50cc12 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -525,7 +525,13 @@ template static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace) { I.USR = getUSRForDecl(D); - I.Name = D->getNameAsString(); + if (auto ConversionDecl = dyn_cast_or_null(D); + ConversionDecl && ConversionDecl->getConversionType() +.getTypePtr() +->isTemplateTypeParmType()) +I.Name = "operator " + ConversionDecl->getConversionType().getAsString(); + else +I.Name = D->getNameAsString(); populateParentNamespaces(I.Namespace, D, IsInAnonymousNamespace); if (C) { I.Description.emplace_back(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Avoid reading files in unit tests (PR #141269)
https://github.com/evelez7 approved this pull request. https://github.com/llvm/llvm-project/pull/141269 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
https://github.com/evelez7 closed https://github.com/llvm/llvm-project/pull/140856 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
evelez7 wrote: > would you mind pre-committing the test so its easy to see what's changing in > the output with this patch? Could you explain what this means please? Do you mean reorganizing the PR so that the first commit is the test and then the second is the code change? https://github.com/llvm/llvm-project/pull/140856 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Precommit test for correct conversion function names (PR #141168)
https://github.com/evelez7 closed https://github.com/llvm/llvm-project/pull/141168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
evelez7 wrote: Should note that #59812 also mentions the `requires` clause being omitted but that should be addressed by a different issue/patch because that will be applicable to all function types. https://github.com/llvm/llvm-project/pull/140856 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] fix names of conversions for template parameters (PR #140856)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/140856 Fixes #59812 The names of conversion functions of template type parameters were being emitted as "type-parameter-N-M". Now we check if the conversion type is a TemplateTypeParmType and reconstruct the source name. >From e25581d28ecda89fe4e550da71e668b6ae749804 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 20 May 2025 23:26:02 -0700 Subject: [PATCH] [clang-doc] fix conversion names of dependent types Fixes #59812 The names of conversion functions of template type parameters were being emitted as "type-parameter-N-M". Now we check if the conversion type is a TemplateTypeParmType and reconstruct the source name. --- clang-tools-extra/clang-doc/Serialize.cpp | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 18db427b5239e..585a46112d43d 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -525,7 +525,13 @@ template static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace) { I.USR = getUSRForDecl(D); - I.Name = D->getNameAsString(); + auto ConversionDecl = dyn_cast_or_null(D); + if (ConversionDecl && ConversionDecl->getConversionType() +.getTypePtr() +->isTemplateTypeParmType()) +I.Name = "operator " + ConversionDecl->getConversionType().getAsString(); + else +I.Name = D->getNameAsString(); populateParentNamespaces(I.Namespace, D, IsInAnonymousNamespace); if (C) { I.Description.emplace_back(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits