[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)
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
[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] Add test case for #141990 (PR #142209)
https://github.com/evelez7 approved this pull request. https://github.com/llvm/llvm-project/pull/142209 ___ 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 FileCheck for conversion function HTML test (PR #141976)
evelez7 wrote: CI passed besides the Linux test. Identical to what was discussed in #138065 https://github.com/llvm/llvm-project/pull/141976 ___ 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 FileCheck for conversion function HTML test (PR #141976)
https://github.com/evelez7 unassigned https://github.com/llvm/llvm-project/pull/141976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Reenable time trace support (PR #141139)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/141139 >From 7f346f476e89bc97c5d1780ef9f12246ebc4f86d Mon Sep 17 00:00:00 2001 From: Paul Kirth Date: Wed, 21 May 2025 09:50:32 -0700 Subject: [PATCH] [clang-doc] Reenable time trace support This patch re-enables -ftime-trace support in clang-doc. Initial support in #97644 was reverted, and never relanded. This patch adds back the command line option, and leverages the RAII tracing infrastructure more thoroughly. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 8 + .../clang-doc/HTMLMustacheGenerator.cpp | 32 +- clang-tools-extra/clang-doc/Mapper.cpp| 84 +++-- .../clang-doc/Representation.cpp | 6 +- clang-tools-extra/clang-doc/Representation.h | 5 +- .../clang-doc/tool/ClangDocMain.cpp | 303 ++ 6 files changed, 266 insertions(+), 172 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..546dd0254ec01 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -9,6 +9,7 @@ #include "BitcodeReader.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/Support/Error.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include @@ -672,6 +673,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { template <> llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { + llvm::TimeTraceScope("Reducing infos", "readRecord"); Record R; llvm::StringRef Blob; llvm::Expected MaybeRecID = Stream.readRecord(ID, R, &Blob); @@ -683,6 +685,7 @@ llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { // Read a block of records into a single info. template llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { + llvm::TimeTraceScope("Reducing infos", "readBlock"); if (llvm::Error Err = Stream.EnterSubBlock(ID)) return Err; @@ -713,6 +716,7 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { template llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { + llvm::TimeTraceScope("Reducing infos", "readSubBlock"); switch (ID) { // Blocks can only have certain types of sub blocks. case BI_COMMENT_BLOCK_ID: { @@ -819,6 +823,7 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { ClangDocBitcodeReader::Cursor ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) { + llvm::TimeTraceScope("Reducing infos", "skipUntilRecordOrBlock"); BlockOrRecordID = 0; while (!Stream.AtEndOfStream()) { @@ -880,6 +885,7 @@ llvm::Error ClangDocBitcodeReader::validateStream() { } llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() { + llvm::TimeTraceScope("Reducing infos", "readBlockInfoBlock"); Expected> MaybeBlockInfo = Stream.ReadBlockInfoBlock(); if (!MaybeBlockInfo) @@ -895,6 +901,7 @@ llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() { template llvm::Expected> ClangDocBitcodeReader::createInfo(unsigned ID) { + llvm::TimeTraceScope("Reducing infos", "createInfo"); std::unique_ptr I = std::make_unique(); if (auto Err = readBlock(ID, static_cast(I.get( return std::move(Err); @@ -903,6 +910,7 @@ ClangDocBitcodeReader::createInfo(unsigned ID) { llvm::Expected> ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { + llvm::TimeTraceScope("Reducing infos", "readBlockToInfo"); switch (ID) { case BI_NAMESPACE_BLOCK_ID: return createInfo(ID); diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp index 65dc2e93582e8..8b7e4896c9fde 100644 --- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mustache.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TimeProfiler.h" using namespace llvm; using namespace llvm::json; @@ -125,13 +126,18 @@ static Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) { Error MustacheHTMLGenerator::generateDocs( StringRef RootDir, StringMap> Infos, const clang::doc::ClangDocContext &CDCtx) { - if (auto Err = setupTemplateFiles(CDCtx)) -return Err; + { +llvm::TimeTraceScope TS("Setup Templates"); +if (auto Err = setupTemplateFiles(CDCtx)) + return Err; + } + // Track which directories we already tried to create. StringSet<> CreatedDirs; // Collect all output by file name and create the necessary directories. StringMap> FileToInfos; for (const auto &Group : Infos) { +llvm::TimeTraceScope TS("setup directories"); doc::Info *Info = Group.getValue().get(); SmallString<128> Path; @@ -148,15 +154,19 @@ Error MustacheHTMLGenerator::generateDocs( FileToInfos[Path].p
[clang-tools-extra] [clang-doc] fix FileCheck for conversion function HTML test (PR #141976)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/141976 The HTML FileCheck was missing the RUN command. Fixing that revealed an error in the HTML check. >From 38fa68d1e35cdffe4199e0cafde62edba54956ef Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Wed, 28 May 2025 10:04:06 -0700 Subject: [PATCH] [clang-doc] fix FileCheck not running for conversion HTML test Forgot to add RUN for the test which revealed a problem with the test. --- clang-tools-extra/test/clang-doc/conversion_function.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/test/clang-doc/conversion_function.cpp b/clang-tools-extra/test/clang-doc/conversion_function.cpp index bf97d85661346..0200a578219ee 100644 --- a/clang-tools-extra/test/clang-doc/conversion_function.cpp +++ b/clang-tools-extra/test/clang-doc/conversion_function.cpp @@ -4,7 +4,7 @@ // 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 +// RUN: FileCheck %s < %t/GlobalNamespace/MyStruct.html --check-prefix=CHECK-HTML template struct MyStruct { @@ -14,5 +14,5 @@ struct MyStruct { // Output correct conversion names. // CHECK-YAML: Name:'operator T' -// CHECK-HTML: 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] Reenable time trace support (PR #141139)
evelez7 wrote: Sorry about that I was trying to get the PR changes via Github CLI... https://github.com/llvm/llvm-project/pull/141139 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Reenable time trace support (PR #141139)
https://github.com/evelez7 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/141139 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Reenable time trace support (PR #141139)
@@ -13,7 +13,9 @@ #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Support/Error.h" evelez7 wrote: Error is already included via TimeProfiler.h https://github.com/llvm/llvm-project/pull/141139 ___ 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 FileCheck for conversion function HTML test (PR #141976)
https://github.com/evelez7 closed https://github.com/llvm/llvm-project/pull/141976 ___ 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 a JSON generator (PR #142483)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/142483 >From cf68952c0cf4dfeda65c78c6d2326426bbf2d693 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Mon, 2 Jun 2025 12:53:36 -0700 Subject: [PATCH] [clang-doc] add a JSON generator --- clang-tools-extra/clang-doc/CMakeLists.txt| 1 + clang-tools-extra/clang-doc/Generators.cpp| 2 + clang-tools-extra/clang-doc/Generators.h | 1 + clang-tools-extra/clang-doc/JSONGenerator.cpp | 316 ++ .../clang-doc/tool/ClangDocMain.cpp | 8 +- .../test/clang-doc/json/class.cpp | 183 ++ 6 files changed, 509 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/clang-doc/JSONGenerator.cpp create mode 100644 clang-tools-extra/test/clang-doc/json/class.cpp diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt index 79563c41435eb..5989e5fe60cf3 100644 --- a/clang-tools-extra/clang-doc/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangDoc STATIC Serialize.cpp YAMLGenerator.cpp HTMLMustacheGenerator.cpp + JSONGenerator.cpp DEPENDS omp_gen diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp index a3c2773412cff..3fb5b63c403a7 100644 --- a/clang-tools-extra/clang-doc/Generators.cpp +++ b/clang-tools-extra/clang-doc/Generators.cpp @@ -105,5 +105,7 @@ static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest = HTMLGeneratorAnchorSource; static int LLVM_ATTRIBUTE_UNUSED MHTMLGeneratorAnchorDest = MHTMLGeneratorAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED JSONGeneratorAnchorDest = +JSONGeneratorAnchorSource; } // namespace doc } // namespace clang diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h index aee04b9d58d9d..92d3006e6002d 100644 --- a/clang-tools-extra/clang-doc/Generators.h +++ b/clang-tools-extra/clang-doc/Generators.h @@ -58,6 +58,7 @@ extern volatile int YAMLGeneratorAnchorSource; extern volatile int MDGeneratorAnchorSource; extern volatile int HTMLGeneratorAnchorSource; extern volatile int MHTMLGeneratorAnchorSource; +extern volatile int JSONGeneratorAnchorSource; } // namespace doc } // namespace clang diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp new file mode 100644 index 0..499ca4dd05e6e --- /dev/null +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -0,0 +1,316 @@ +#include "Generators.h" +#include "llvm/Support/JSON.h" + +using namespace llvm; +using namespace llvm::json; + +static llvm::ExitOnError ExitOnErr; + +namespace clang { +namespace doc { + +class JSONGenerator : public Generator { +public: + static const char *Format; + + Error generateDocs(StringRef RootDir, + llvm::StringMap> Infos, + const ClangDocContext &CDCtx) override; + Error createResources(ClangDocContext &CDCtx) override; + Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) override; +}; + +const char *JSONGenerator::Format = "json"; + +static json::Object serializeLocation(const Location &Loc, + std::optional RepositoryUrl) { + Object LocationObj = Object(); + LocationObj["LineNumber"] = Loc.StartLineNumber; + LocationObj["Filename"] = Loc.Filename; + + if (!Loc.IsFileInRootDir || !RepositoryUrl) +return LocationObj; + SmallString<128> FileURL(*RepositoryUrl); + sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename); + FileURL += "#" + std::to_string(Loc.StartLineNumber); + LocationObj["FileURL"] = FileURL; + return LocationObj; +} + +static json::Value serializeComment(const CommentInfo &Comment) { + assert((Comment.Kind == "BlockCommandComment" || + Comment.Kind == "FullComment" || Comment.Kind == "ParagraphComment" || + Comment.Kind == "TextComment") && + "Unknown Comment type in CommentInfo."); + + Object Obj = Object(); + json::Value Child = Object(); + + // TextComment has no children, so return it. + if (Comment.Kind == "TextComment") { +Obj["TextComment"] = Comment.Text; +return Obj; + } + + // BlockCommandComment needs to generate a Command key. + if (Comment.Kind == "BlockCommandComment") +Child.getAsObject()->insert({"Command", Comment.Name}); + + // Use the same handling for everything else. + // Only valid for: + // - BlockCommandComment + // - FullComment + // - ParagraphComment + json::Value ChildArr = Array(); + auto &CARef = *ChildArr.getAsArray(); + CARef.reserve(Comment.Children.size()); + for (const auto &C : Comment.Children) +CARef.emplace_back(serializeComment(*C)); + Child.getAsObject()->insert({"Children", ChildArr}); + Obj.insert({Comment.Kind, Child}); + return Obj; +} + +static void serializeCommonAttri
[clang-tools-extra] [clang-doc] add a JSON generator (PR #142483)
evelez7 wrote: I think this patch is mostly ready in terms of functionality, but we should decide if the emitted files should follow the HTML or YAML style of creation. Right now, since I just ripped the Mustache generator code, it creates folders for each namespace and emits the nested entities there. This actually represents a problem for template specializations because the code tries to write another JSON object (the specialization) to the same file as the base template, which is invalid. With YAML, each entity is emitted in a file that uses the entity's USR as a name. All files are emitted to the output directory without any folders. That conveniently solves the above template problem, but also results in ugly file names that are potentially bad for multi-file testing (right now, we use regex to find a USR file name to test YAML). I'd say the HTML layout is nice, but then we'd need to decide what to call the specializations' files or whether to just include them as an object inside the base template's file. https://github.com/llvm/llvm-project/pull/142483 ___ 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 a JSON generator (PR #142483)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/142483 None >From 497637bbc1c5b20fb60357fbbfda55514a8681c2 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Mon, 2 Jun 2025 12:53:36 -0700 Subject: [PATCH] [clang-doc] add a JSON generator --- clang-tools-extra/clang-doc/CMakeLists.txt| 1 + clang-tools-extra/clang-doc/Generators.cpp| 2 + clang-tools-extra/clang-doc/Generators.h | 1 + clang-tools-extra/clang-doc/JSONGenerator.cpp | 258 ++ .../clang-doc/tool/ClangDocMain.cpp | 8 +- .../test/clang-doc/json/class.cpp | 120 6 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/clang-doc/JSONGenerator.cpp create mode 100644 clang-tools-extra/test/clang-doc/json/class.cpp diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt index 79563c41435eb..5989e5fe60cf3 100644 --- a/clang-tools-extra/clang-doc/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangDoc STATIC Serialize.cpp YAMLGenerator.cpp HTMLMustacheGenerator.cpp + JSONGenerator.cpp DEPENDS omp_gen diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp index a3c2773412cff..3fb5b63c403a7 100644 --- a/clang-tools-extra/clang-doc/Generators.cpp +++ b/clang-tools-extra/clang-doc/Generators.cpp @@ -105,5 +105,7 @@ static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest = HTMLGeneratorAnchorSource; static int LLVM_ATTRIBUTE_UNUSED MHTMLGeneratorAnchorDest = MHTMLGeneratorAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED JSONGeneratorAnchorDest = +JSONGeneratorAnchorSource; } // namespace doc } // namespace clang diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h index aee04b9d58d9d..92d3006e6002d 100644 --- a/clang-tools-extra/clang-doc/Generators.h +++ b/clang-tools-extra/clang-doc/Generators.h @@ -58,6 +58,7 @@ extern volatile int YAMLGeneratorAnchorSource; extern volatile int MDGeneratorAnchorSource; extern volatile int HTMLGeneratorAnchorSource; extern volatile int MHTMLGeneratorAnchorSource; +extern volatile int JSONGeneratorAnchorSource; } // namespace doc } // namespace clang diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp new file mode 100644 index 0..70a56afd83659 --- /dev/null +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -0,0 +1,258 @@ +#include "Generators.h" +#include "Representation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" +#include + +using namespace llvm; +using namespace llvm::json; + +static llvm::ExitOnError ExitOnErr; + +namespace clang { +namespace doc { + +class JSONGenerator : public Generator { +public: + static const char *Format; + + Error generateDocs(StringRef RootDir, + llvm::StringMap> Infos, + const ClangDocContext &CDCtx) override; + Error createResources(ClangDocContext &CDCtx) override; + Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) override; +}; + +const char *JSONGenerator::Format = "json"; + +static json::Object serializeLocation(const Location &Loc, + std::optional RepositoryUrl) { + Object LocationObj = Object(); + LocationObj["LineNumber"] = Loc.StartLineNumber; + LocationObj["Filename"] = Loc.Filename; + + if (!Loc.IsFileInRootDir || !RepositoryUrl) +return LocationObj; + SmallString<128> FileURL(*RepositoryUrl); + sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename); + FileURL += "#" + std::to_string(Loc.StartLineNumber); + LocationObj["FileURL"] = FileURL; + return LocationObj; +} + +static json::Value serializeComment(const CommentInfo &Comment) { + assert((Comment.Kind == "BlockCommandComment" || + Comment.Kind == "FullComment" || Comment.Kind == "ParagraphComment" || + Comment.Kind == "TextComment") && + "Unknown Comment type in CommentInfo."); + + Object Obj = Object(); + json::Value Child = Object(); + + // TextComment has no children, so return it. + if (Comment.Kind == "TextComment") { +Obj["TextComment"] = Comment.Text; +return Obj; + } + + // BlockCommandComment needs to generate a Command key. + if (Comment.Kind == "BlockCommandComment") +Child.getAsObject()->insert({"Command", Comment.Name}); + + // Use the same handling for everything else. + // Only valid for: + // - BlockCommandComment + // - FullComment + // - ParagraphComment + json::Value ChildArr = Array(); + auto &CARef = *ChildArr.getAsArray(); + CARef.reserve(Comment.Children.size()); + for (const auto &C : Comment.Children) +CARef.emplace_back(serializeComment(*C)); + Child.getAsObject()->insert({"
[clang-tools-extra] [clang-doc] add a JSON generator (PR #142483)
evelez7 wrote: * **#142483** https://app.graphite.dev/github/pr/llvm/llvm-project/142483?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/142483?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/142483 ___ 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 a JSON generator (PR #142483)
https://github.com/evelez7 edited https://github.com/llvm/llvm-project/pull/142483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] mangle specialization file names (PR #144617)
https://github.com/evelez7 ready_for_review https://github.com/llvm/llvm-project/pull/144617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] mangle specialization file names (PR #144617)
@@ -909,6 +910,13 @@ emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc, RI->Template.emplace(); RI->Template->Specialization.emplace(); auto &Specialization = *RI->Template->Specialization; +auto *Mangler = ItaniumMangleContext::create( +D->getASTContext(), D->getASTContext().getDiagnostics()); +std::string MangledName; +llvm::raw_string_ostream Stream(MangledName); +Mangler->mangleCXXVTT(dyn_cast(D), Stream); +Specialization.MangledName.emplace(MangledName); +delete Mangler; evelez7 wrote: It'd be nice to keep this mangler somewhere so that it's not allocated/deleted constantly. If it was kept in the Clang-Doc Context, it'd have to be passed specifically to this emitInfo which would break the pattern we have. https://github.com/llvm/llvm-project/pull/144617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] document global variables (PR #145070)
@@ -25,7 +24,7 @@ typedef int MyTypedef; // CHECK-NEXT: { // CHECK-NEXT:"Location": { // CHECK-NEXT: "Filename": "{{.*}}namespace.cpp", -// CHECK-NEXT: "LineNumber": 15 +// CHECK-NEXT: "LineNumber": 14 evelez7 wrote: After our offline discussion, I think having one test to correctly check line numbers would be a pretty good compromise. https://github.com/llvm/llvm-project/pull/145070 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] mangle template specialization file names (PR #144617)
https://github.com/evelez7 edited https://github.com/llvm/llvm-project/pull/144617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] mangle template specialization file names (PR #144617)
evelez7 wrote: After our offline discussion, I think I'm going to close this PR in favor of implementing mangling for all names. https://github.com/llvm/llvm-project/pull/144617 ___ 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 global variables (PR #145069)
evelez7 wrote: ### Merge activity * **Jun 21, 6:55 PM UTC**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/145069). https://github.com/llvm/llvm-project/pull/145069 ___ 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 global variables (PR #145069)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/145069 >From 890d6f93bdef75e4b4d52835bd5ac14b52fb23e8 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Thu, 19 Jun 2025 21:25:13 -0700 Subject: [PATCH] [clang-doc] Precommit test for global variables --- .../test/clang-doc/json/namespace.cpp | 20 ++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp b/clang-tools-extra/test/clang-doc/json/namespace.cpp index 928864be1feb0..248d47351bd38 100644 --- a/clang-tools-extra/test/clang-doc/json/namespace.cpp +++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp @@ -103,5 +103,23 @@ typedef int MyTypedef; // CHECK-NEXT: } // CHECK-NEXT:], // CHECK-NEXT:"USR": "" -// CHECK-NOT: "Variables": [ +// CHECK-NOT:"Variables": [ +// CHECK-NOT: { +// CHECK-NOT:"IsStatic": true, +// CHECK-NOT:"Location": { +// CHECK-NOT: "Filename": "{{.*}}namespace.cpp", +// CHECK-NOT: "LineNumber": 13 +// CHECK-NOT:}, +// CHECK-NOT:"Name": "Global", +// CHECK-NOT:"Type": { +// COM:FIXME: IsBuiltIn emits as its default value +// CHECK-NOT: "IsBuiltIn": false, +// CHECK-NOT: "IsTemplate": false, +// CHECK-NOT: "Name": "int", +// CHECK-NOT: "QualName": "int", +// CHECK-NOT: "USR": "" +// CHECK-NOT:}, +// CHECK-NOT:"USR": "{{[0-9A-F]*}}" +// CHECK-NOT: } +// CHECK-NOT:] // CHECK-NEXT: } ___ 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 global variables (PR #145069)
https://github.com/evelez7 edited https://github.com/llvm/llvm-project/pull/145069 ___ 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 support for concepts (PR #144430)
evelez7 wrote: ### Merge activity * **Jun 21, 12:38 AM UTC**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/144430). https://github.com/llvm/llvm-project/pull/144430 ___ 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 support for concepts (PR #144430)
https://github.com/evelez7 closed https://github.com/llvm/llvm-project/pull/144430 ___ 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 concept tests (PR #144160)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/144160 >From 9c18fd3f486b48fd883fc6ba0c6a23255d0659f6 Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Fri, 13 Jun 2025 14:16:17 -0700 Subject: [PATCH] [clang-doc] Precommit concept tests --- .../test/clang-doc/json/class-requires.cpp| 34 .../test/clang-doc/json/concept.cpp | 37 + .../test/clang-doc/json/function-requires.cpp | 79 +++ 3 files changed, 150 insertions(+) create mode 100644 clang-tools-extra/test/clang-doc/json/class-requires.cpp create mode 100644 clang-tools-extra/test/clang-doc/json/concept.cpp create mode 100644 clang-tools-extra/test/clang-doc/json/function-requires.cpp diff --git a/clang-tools-extra/test/clang-doc/json/class-requires.cpp b/clang-tools-extra/test/clang-doc/json/class-requires.cpp new file mode 100644 index 0..af108a402b403 --- /dev/null +++ b/clang-tools-extra/test/clang-doc/json/class-requires.cpp @@ -0,0 +1,34 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.json + +template +concept Addable = requires(T a, T b) { + { a + b }; +}; + +template +requires Addable +struct MyClass; + +// CHECK: "Name": "MyClass", +// CHECK-NEXT: "Namespace": [ +// CHECK-NEXT:"GlobalNamespace" +// CHECK-NEXT: ], +// CHECK-NEXT: "Path": "GlobalNamespace", +// CHECK-NEXT: "TagType": "struct", +// CHECK-NEXT: "Template": { +// CHECK-NOT: "Constraints": [ +// CHECK-NOT: { +// CHECK-NOT: "Expression": "Addable", +// CHECK-NOT: "Name": "Addable", +// CHECK-NOT: "Path": "", +// CHECK-NOT: "QualName": "Addable", +// CHECK-NOT: "USR": "{{[0-9A-F]*}}" +// CHECK-NOT: } +// CHECK-NOT: ], +// CHECK-NEXT:"Parameters": [ +// CHECK-NEXT: "typename T" +// CHECK-NEXT:] +// CHECK-NEXT: }, +// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" diff --git a/clang-tools-extra/test/clang-doc/json/concept.cpp b/clang-tools-extra/test/clang-doc/json/concept.cpp new file mode 100644 index 0..624f71c6bf9b3 --- /dev/null +++ b/clang-tools-extra/test/clang-doc/json/concept.cpp @@ -0,0 +1,37 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s + +// Requires that T suports post and pre-incrementing. +template +concept Incrementable = requires(T x) { + ++x; + x++; +}; + +// CHECK: { +// CHECK-NOT:"Concepts": [ +// CHECK-NOT: { +// CHECK-NOT:"ConstraintExpression": "requires (T x) { ++x; x++; }", +// CHECK-NOT:"Description": [ +// CHECK-NOT: { +// CHECK-NOT:"FullComment": { +// CHECK-NOT: "Children": [ +// CHECK-NOT:{ +// CHECK-NOT: "ParagraphComment": { +// CHECK-NOT:"Children": [ +// CHECK-NOT: { +// CHECK-NOT:"TextComment": " Requires that T suports post and pre-incrementing." +// CHECK-NOT:], +// CHECK-NOT:"IsType": true, +// CHECK-NOT:"Name": "Incrementable", +// CHECK-NOT:"Template": { +// CHECK-NOT: "Parameters": [ +// CHECK-NOT:"typename T" +// CHECK-NOT: ] +// CHECK-NOT:}, +// CHECK-NOT:"USR": "{{[0-9A-F]*}}" +// CHECK-NOT: } +// CHECK-NOT:], +// CHECK:"Name": "", +// CHECK:"USR": "" +// CHECK: } diff --git a/clang-tools-extra/test/clang-doc/json/function-requires.cpp b/clang-tools-extra/test/clang-doc/json/function-requires.cpp new file mode 100644 index 0..aa62464d07b4b --- /dev/null +++ b/clang-tools-extra/test/clang-doc/json/function-requires.cpp @@ -0,0 +1,79 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/index.json + +template +concept Incrementable = requires(T x) { + ++x; + x++; +}; + +template void increment(T t) requires Incrementable; + +template Incrementable auto incrementTwo(T t); + +// CHECK: "Functions": [ +// CHECK-NEXT:{ +// CHECK-NEXT: "IsStatic": false, +// CHECK-NEXT: "Name": "increment", +// CHECK-NEXT: "Params": [ +// CHECK-NEXT:{ +// CHECK-NEXT: "Name": "t", +// CHECK-NEXT: "Type": "T" +// CHECK-NEXT:} +// CHECK-NEXT: ], +// CHECK-NEXT: "ReturnType": { +// CHECK-NEXT:"IsBuiltIn": false, +// CHECK-NEXT:"IsTemplate": false, +// CHECK-NEXT:"Name": "void", +// CHECK-NEXT:"QualName": "void", +// CHECK-NEXT:"USR": "" +// CHECK-NEXT: }, +// CHECK-NEXT: "Template": { +// CHECK-NOT: "Constraints": [ +// CHECK-NOT: { +// CHECK-NOT:
[clang-tools-extra] [clang-doc] refactor JSONGenerator array usage (PR #145595)
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/145595 >From df4ddc4f8bdaaf7cf47865f2c9c98622ca4941fa Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 24 Jun 2025 11:19:06 -0700 Subject: [PATCH] [clang-doc] refactor JSONGenerator array usage Improve code reuse by calling serializeArray in more generic cases instead of creating and reserving arrays on their own. --- clang-tools-extra/clang-doc/JSONGenerator.cpp | 230 +++--- 1 file changed, 83 insertions(+), 147 deletions(-) diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp index 91f5ba4080619..c8b9aee7af8c9 100644 --- a/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -22,19 +22,27 @@ class JSONGenerator : public Generator { const char *JSONGenerator::Format = "json"; -static void serializeInfo(const TypedefInfo &I, json::Object &Obj, - std::optional RepositoryUrl); -static void serializeInfo(const EnumInfo &I, json::Object &Obj, - std::optional RepositoryUrl); static void serializeInfo(const ConstraintInfo &I, Object &Obj); +static void serializeInfo(const RecordInfo &I, Object &Obj, + std::optional RepositoryUrl); + +static void serializeReference(const Reference &Ref, Object &ReferenceObj); + +template +static void serializeArray(const Container &Records, Object &Obj, + const std::string &Key, + SerializationFunc SerializeInfo); // Convenience lambda to pass to serializeArray. // If a serializeInfo needs a RepositoryUrl, create a local lambda that captures // the optional. -static auto SerializeInfoLambda = [](const ConstraintInfo &Info, - Object &Object) { +static auto SerializeInfoLambda = [](const auto &Info, Object &Object) { serializeInfo(Info, Object); }; +static auto SerializeReferenceLambda = [](const Reference &Ref, + Object &Object) { + serializeReference(Ref, Object); +}; static json::Object serializeLocation(const Location &Loc, std::optional RepositoryUrl) { @@ -198,67 +206,28 @@ static void serializeReference(const Reference &Ref, Object &ReferenceObj) { ReferenceObj["USR"] = toHex(toStringRef(Ref.USR)); } -static void serializeReference(const SmallVector &References, - Object &Obj, std::string Key) { - json::Value ReferencesArray = Array(); - json::Array &ReferencesArrayRef = *ReferencesArray.getAsArray(); - ReferencesArrayRef.reserve(References.size()); - for (const auto &Reference : References) { -json::Value ReferenceVal = Object(); -auto &ReferenceObj = *ReferenceVal.getAsObject(); -serializeReference(Reference, ReferenceObj); -ReferencesArrayRef.push_back(ReferenceVal); - } - Obj[Key] = ReferencesArray; -} - // Although namespaces and records both have ScopeChildren, they serialize them // differently. Only enums, records, and typedefs are handled here. static void serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj, std::optional RepositoryUrl) { - if (!Children.Enums.empty()) { -json::Value EnumsArray = Array(); -auto &EnumsArrayRef = *EnumsArray.getAsArray(); -EnumsArrayRef.reserve(Children.Enums.size()); -for (const auto &Enum : Children.Enums) { - json::Value EnumVal = Object(); - auto &EnumObj = *EnumVal.getAsObject(); - serializeInfo(Enum, EnumObj, RepositoryUrl); - EnumsArrayRef.push_back(EnumVal); -} -Obj["Enums"] = EnumsArray; - } + static auto SerializeInfo = [RepositoryUrl](const auto &Info, + Object &Object) { +serializeInfo(Info, Object, RepositoryUrl); + }; - if (!Children.Typedefs.empty()) { -json::Value TypedefsArray = Array(); -auto &TypedefsArrayRef = *TypedefsArray.getAsArray(); -TypedefsArrayRef.reserve(Children.Typedefs.size()); -for (const auto &Typedef : Children.Typedefs) { - json::Value TypedefVal = Object(); - auto &TypedefObj = *TypedefVal.getAsObject(); - serializeInfo(Typedef, TypedefObj, RepositoryUrl); - TypedefsArrayRef.push_back(TypedefVal); -} -Obj["Typedefs"] = TypedefsArray; - } + if (!Children.Enums.empty()) +serializeArray(Children.Enums, Obj, "Enums", SerializeInfo); - if (!Children.Records.empty()) { -json::Value RecordsArray = Array(); -auto &RecordsArrayRef = *RecordsArray.getAsArray(); -RecordsArrayRef.reserve(Children.Records.size()); -for (const auto &Record : Children.Records) { - json::Value RecordVal = Object(); - auto &RecordObj = *RecordVal.getAsObject(); - serializeReference(Record, RecordObj); - RecordsArrayRef.push_back(Re
[clang-tools-extra] [clang-doc] Precommit concept tests (PR #144160)
@@ -0,0 +1,37 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --extra-arg -std=c++20 --output=%t --format=json --executor=standalone %s evelez7 wrote: FileCheck is omitted here because since nothing is mapped, no file is created. https://github.com/llvm/llvm-project/pull/144160 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] remove default label on some switches (PR #143919)
evelez7 wrote: ### Merge activity * **Jun 13, 11:33 PM UTC**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/143919). https://github.com/llvm/llvm-project/pull/143919 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] remove default label on some switches (PR #143919)
https://github.com/evelez7 closed https://github.com/llvm/llvm-project/pull/143919 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] mangle specialization file names (PR #144617)
https://github.com/evelez7 created https://github.com/llvm/llvm-project/pull/144617 None >From bd5747e542e23078a98a830da191e5f1f72bd85b Mon Sep 17 00:00:00 2001 From: Erick Velez Date: Tue, 17 Jun 2025 15:11:02 -0700 Subject: [PATCH] [clang-doc] mangle specialization file names --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 + clang-tools-extra/clang-doc/BitcodeWriter.cpp | 7 ++- clang-tools-extra/clang-doc/BitcodeWriter.h | 1 + clang-tools-extra/clang-doc/JSONGenerator.cpp | 9 - clang-tools-extra/clang-doc/Representation.h | 3 +++ clang-tools-extra/clang-doc/Serialize.cpp | 8 .../json/specialization-mangled-name.cpp | 15 +++ 7 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/json/specialization-mangled-name.cpp diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 35058abab0663..9227cf2bf51a2 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -83,6 +83,13 @@ static llvm::Error decodeRecord(const Record &R, std::optional &Field, return llvm::Error::success(); } +static llvm::Error decodeRecord(const Record &R, +std::optional> &Field, +llvm::StringRef Blob) { + Field.emplace(Blob); + return llvm::Error::success(); +} + static llvm::Error decodeRecord(const Record &R, InfoType &Field, llvm::StringRef Blob) { switch (auto IT = static_cast(R[0])) { @@ -379,6 +386,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, TemplateSpecializationInfo *I) { if (ID == TEMPLATE_SPECIALIZATION_OF) return decodeRecord(R, I->SpecializationOf, Blob); + if (ID == TEMPLATE_SPECIALIZATION_MANGLED_NAME) +return decodeRecord(R, I->MangledName, Blob); return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid field for TemplateParamInfo"); } diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f8a6859169b01..e2c58731fbc67 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -202,6 +202,8 @@ static const llvm::IndexedMap {TEMPLATE_PARAM_CONTENTS, {"Contents", &genStringAbbrev}}, {TEMPLATE_SPECIALIZATION_OF, {"SpecializationOf", &genSymbolIdAbbrev}}, + {TEMPLATE_SPECIALIZATION_MANGLED_NAME, + {"MangledName", &genStringAbbrev}}, {TYPEDEF_USR, {"USR", &genSymbolIdAbbrev}}, {TYPEDEF_NAME, {"Name", &genStringAbbrev}}, {TYPEDEF_DEFLOCATION, {"DefLocation", &genLocationAbbrev}}, @@ -263,7 +265,8 @@ static const std::vector>> // Template Blocks. {BI_TEMPLATE_BLOCK_ID, {}}, {BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}}, -{BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}}; +{BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, + {TEMPLATE_SPECIALIZATION_OF, TEMPLATE_SPECIALIZATION_MANGLED_NAME}}}; // AbbreviationMap @@ -638,6 +641,8 @@ void ClangDocBitcodeWriter::emitBlock(const TemplateInfo &T) { void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) { StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID); emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF); + if (T.MangledName) +emitRecord(T.MangledName->str(), TEMPLATE_SPECIALIZATION_MANGLED_NAME); for (const auto &P : T.Params) emitBlock(P); } diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h b/clang-tools-extra/clang-doc/BitcodeWriter.h index e33a1aece883c..c0b879af59194 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.h +++ b/clang-tools-extra/clang-doc/BitcodeWriter.h @@ -131,6 +131,7 @@ enum RecordId { REFERENCE_FIELD, TEMPLATE_PARAM_CONTENTS, TEMPLATE_SPECIALIZATION_OF, + TEMPLATE_SPECIALIZATION_MANGLED_NAME, TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DEFLOCATION, diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp index 0f7cbafcf5135..ca56e669038b4 100644 --- a/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -491,7 +491,14 @@ Error JSONGenerator::generateDocs( CreatedDirs.insert(Path); } -sys::path::append(Path, Info->getFileBaseName() + ".json"); +SmallString<16> FileBaseName = Info->getFileBaseName(); +if (Info->IT == InfoType::IT_record) { + if (auto Template = static_cast(Info)->Template; + Template && Template->Specialization && + Template->Specialization->MangledName) +FileBaseName = Template->Specialization->MangledName.value(); +} +sys::path::append(P