diff --git a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp index 831c8565eb74d..f27016a9dc4ea 100644 --- a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -7,281 +7,45 @@ //===----------------------------------------------------------------------===// #include "RedundantVoidArgCheck.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Lex/Lexer.h" +#include "../utils/LexerUtils.h" +#include "clang/ASTMatchers/ASTMatchers.h" using namespace clang::ast_matchers; namespace clang::tidy::modernize { -// Determine if the given QualType is a nullary function or pointer to same. -static bool protoTypeHasNoParms(QualType QT) { - if (const auto *PT = QT->getAs()) - QT = PT->getPointeeType(); - if (auto *MPT = QT->getAs()) - QT = MPT->getPointeeType(); - if (const auto *FP = QT->getAs()) - return FP->getNumParams() == 0; - return false; -} - -static const char FunctionId[] = "function"; -static const char TypedefId[] = "typedef"; -static const char FieldId[] = "field"; -static const char VarId[] = "var"; -static const char NamedCastId[] = "named-cast"; -static const char CStyleCastId[] = "c-style-cast"; -static const char ExplicitCastId[] = "explicit-cast"; -static const char LambdaId[] = "lambda"; - void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()), - unless(isInstantiated()), unless(isExternC())) - .bind(FunctionId), - this); - Finder->addMatcher(typedefNameDecl(unless(isImplicit())).bind(TypedefId), - this); - auto ParenFunctionType = parenType(innerType(functionType())); - auto PointerToFunctionType = pointee(ParenFunctionType); - auto FunctionOrMemberPointer = - anyOf(hasType(pointerType(PointerToFunctionType)), - hasType(memberPointerType(PointerToFunctionType))); - Finder->addMatcher(fieldDecl(FunctionOrMemberPointer).bind(FieldId), this); - Finder->addMatcher(varDecl(FunctionOrMemberPointer).bind(VarId), this); - auto CastDestinationIsFunction = - hasDestinationType(pointsTo(ParenFunctionType)); - Finder->addMatcher( - cStyleCastExpr(CastDestinationIsFunction).bind(CStyleCastId), this); Finder->addMatcher( - cxxStaticCastExpr(CastDestinationIsFunction).bind(NamedCastId), this); - Finder->addMatcher( - cxxReinterpretCastExpr(CastDestinationIsFunction).bind(NamedCastId), + traverse(TK_IgnoreUnlessSpelledInSource, + functionTypeLoc(unless(hasParent(functionDecl(isExternC())))) + .bind("fn")), this); Finder->addMatcher( - cxxConstCastExpr(CastDestinationIsFunction).bind(NamedCastId), this); - Finder->addMatcher(lambdaExpr().bind(LambdaId), this); + traverse(TK_IgnoreUnlessSpelledInSource, lambdaExpr().bind("fn")), this); } void RedundantVoidArgCheck::check(const MatchFinder::MatchResult &Result) { - const BoundNodes &Nodes = Result.Nodes; - if (const auto *Function = Nodes.getNodeAs(FunctionId)) - processFunctionDecl(Result, Function); - else if (const auto *TypedefName = - Nodes.getNodeAs(TypedefId)) - processTypedefNameDecl(Result, TypedefName); - else if (const auto *Member = Nodes.getNodeAs(FieldId)) - processFieldDecl(Result, Member); - else if (const auto *Var = Nodes.getNodeAs(VarId)) - processVarDecl(Result, Var); - else if (const auto *NamedCast = - Nodes.getNodeAs(NamedCastId)) - processNamedCastExpr(Result, NamedCast); - else if (const auto *CStyleCast = - Nodes.getNodeAs(CStyleCastId)) - processExplicitCastExpr(Result, CStyleCast); - else if (const auto *ExplicitCast = - Nodes.getNodeAs(ExplicitCastId)) - processExplicitCastExpr(Result, ExplicitCast); - else if (const auto *Lambda = Nodes.getNodeAs(LambdaId)) - processLambdaExpr(Result, Lambda); -} - -void RedundantVoidArgCheck::processFunctionDecl( - const MatchFinder::MatchResult &Result, const FunctionDecl *Function) { - const auto *Method = dyn_cast(Function); - const SourceLocation Start = Method && Method->getParent()->isLambda() - ? Method->getBeginLoc() - : Function->getLocation(); - SourceLocation End = Function->getEndLoc(); - if (Function->isThisDeclarationADefinition()) { - if (const Stmt *Body = Function->getBody()) { - End = Body->getBeginLoc(); - if (End.isMacroID() && - Result.SourceManager->isAtStartOfImmediateMacroExpansion(End)) - End = Result.SourceManager->getExpansionLoc(End); - End = End.getLocWithOffset(-1); - } - removeVoidArgumentTokens(Result, SourceRange(Start, End), - "function definition"); - } else - removeVoidArgumentTokens(Result, SourceRange(Start, End), - "function declaration"); -} - -static bool isMacroIdentifier(const IdentifierTable &Idents, - const Token &ProtoToken) { - if (!ProtoToken.is(tok::TokenKind::raw_identifier)) - return false; - - const IdentifierTable::iterator It = - Idents.find(ProtoToken.getRawIdentifier()); - if (It == Idents.end()) - return false; - - return It->second->hadMacroDefinition(); -} - -void RedundantVoidArgCheck::removeVoidArgumentTokens( - const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range, - StringRef GrammarLocation) { - const CharSourceRange CharRange = - Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Range), - *Result.SourceManager, getLangOpts()); - - std::string DeclText = - Lexer::getSourceText(CharRange, *Result.SourceManager, getLangOpts()) - .str(); - Lexer PrototypeLexer(CharRange.getBegin(), getLangOpts(), DeclText.data(), - DeclText.data(), DeclText.data() + DeclText.size()); - enum class TokenState { - Start, - MacroId, - MacroLeftParen, - MacroArguments, - LeftParen, - Void, - }; - TokenState State = TokenState::Start; - Token VoidToken; - Token ProtoToken; - const IdentifierTable &Idents = Result.Context->Idents; - int MacroLevel = 0; - const std::string Diagnostic = - ("redundant void argument list in " + GrammarLocation).str(); - - while (!PrototypeLexer.LexFromRawLexer(ProtoToken)) { - switch (State) { - case TokenState::Start: - if (ProtoToken.is(tok::TokenKind::l_paren)) - State = TokenState::LeftParen; - else if (isMacroIdentifier(Idents, ProtoToken)) - State = TokenState::MacroId; - break; - case TokenState::MacroId: - if (ProtoToken.is(tok::TokenKind::l_paren)) - State = TokenState::MacroLeftParen; - else - State = TokenState::Start; - break; - case TokenState::MacroLeftParen: - ++MacroLevel; - if (ProtoToken.is(tok::TokenKind::raw_identifier)) { - if (isMacroIdentifier(Idents, ProtoToken)) - State = TokenState::MacroId; - else - State = TokenState::MacroArguments; - } else if (ProtoToken.is(tok::TokenKind::r_paren)) { - --MacroLevel; - if (MacroLevel == 0) - State = TokenState::Start; - else - State = TokenState::MacroId; - } else - State = TokenState::MacroArguments; - break; - case TokenState::MacroArguments: - if (isMacroIdentifier(Idents, ProtoToken)) - State = TokenState::MacroLeftParen; - else if (ProtoToken.is(tok::TokenKind::r_paren)) { - --MacroLevel; - if (MacroLevel == 0) - State = TokenState::Start; - } - break; - case TokenState::LeftParen: - if (ProtoToken.is(tok::TokenKind::raw_identifier)) { - if (isMacroIdentifier(Idents, ProtoToken)) - State = TokenState::MacroId; - else if (ProtoToken.getRawIdentifier() == "void") { - State = TokenState::Void; - VoidToken = ProtoToken; - } - } else if (ProtoToken.is(tok::TokenKind::l_paren)) - State = TokenState::LeftParen; - else - State = TokenState::Start; - break; - case TokenState::Void: - State = TokenState::Start; - if (ProtoToken.is(tok::TokenKind::r_paren)) - removeVoidToken(VoidToken, Diagnostic); - else if (ProtoToken.is(tok::TokenKind::l_paren)) - State = TokenState::LeftParen; - break; - } - } - - if (State == TokenState::Void && ProtoToken.is(tok::TokenKind::r_paren)) - removeVoidToken(VoidToken, Diagnostic); -} - -void RedundantVoidArgCheck::removeVoidToken(Token VoidToken, - StringRef Diagnostic) { - const SourceLocation VoidLoc = VoidToken.getLocation(); - diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidLoc); -} - -void RedundantVoidArgCheck::processTypedefNameDecl( - const MatchFinder::MatchResult &Result, - const TypedefNameDecl *TypedefName) { - if (protoTypeHasNoParms(TypedefName->getUnderlyingType())) - removeVoidArgumentTokens(Result, TypedefName->getSourceRange(), - isa(TypedefName) ? "typedef" - : "type alias"); -} - -void RedundantVoidArgCheck::processFieldDecl( - const MatchFinder::MatchResult &Result, const FieldDecl *Member) { - if (protoTypeHasNoParms(Member->getType())) - removeVoidArgumentTokens(Result, Member->getSourceRange(), - "field declaration"); -} - -void RedundantVoidArgCheck::processVarDecl( - const MatchFinder::MatchResult &Result, const VarDecl *Var) { - if (protoTypeHasNoParms(Var->getType())) { - const SourceLocation Begin = Var->getBeginLoc(); - if (Var->hasInit()) { - const SourceLocation InitStart = - Result.SourceManager->getExpansionLoc(Var->getInit()->getBeginLoc()) - .getLocWithOffset(-1); - removeVoidArgumentTokens(Result, SourceRange(Begin, InitStart), - "variable declaration with initializer"); - } else - removeVoidArgumentTokens(Result, Var->getSourceRange(), - "variable declaration"); - } -} - -void RedundantVoidArgCheck::processNamedCastExpr( - const MatchFinder::MatchResult &Result, const CXXNamedCastExpr *NamedCast) { - if (protoTypeHasNoParms(NamedCast->getTypeAsWritten())) - removeVoidArgumentTokens( - Result, - NamedCast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange(), - "named cast"); -} - -void RedundantVoidArgCheck::processExplicitCastExpr( - const MatchFinder::MatchResult &Result, - const ExplicitCastExpr *ExplicitCast) { - if (protoTypeHasNoParms(ExplicitCast->getTypeAsWritten())) - removeVoidArgumentTokens(Result, ExplicitCast->getSourceRange(), - "cast expression"); -} - -void RedundantVoidArgCheck::processLambdaExpr( - const MatchFinder::MatchResult &Result, const LambdaExpr *Lambda) { - if (Lambda->getLambdaClass()->getLambdaCallOperator()->getNumParams() == 0 && - Lambda->hasExplicitParameters()) { - const SourceManager *SM = Result.SourceManager; - const TypeLoc TL = - Lambda->getLambdaClass()->getLambdaTypeInfo()->getTypeLoc(); - removeVoidArgumentTokens(Result, - {SM->getSpellingLoc(TL.getBeginLoc()), - SM->getSpellingLoc(TL.getEndLoc())}, - "lambda expression"); - } + const FunctionTypeLoc TL = [&] { + if (const auto *TL = Result.Nodes.getNodeAs("fn")) + return *TL; + return Result.Nodes.getNodeAs("fn") + ->getCallOperator() + ->getFunctionTypeLoc(); + }(); + + if (TL.getNumParams() != 0) + return; + + const std::optional Tok = utils::lexer::findNextTokenSkippingComments( + Result.SourceManager->getSpellingLoc(TL.getLParenLoc()), + *Result.SourceManager, getLangOpts()); + + if (!Tok || Tok->isNot(tok::raw_identifier) || + Tok->getRawIdentifier() != "void") + return; + + diag(Tok->getLocation(), "redundant void argument list") + << FixItHint::CreateRemoval(Tok->getLocation()); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h index d6edd9950ddae..77ebdc84be7e9 100644 --- a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.h @@ -10,9 +10,6 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_REDUNDANTVOIDARGCHECK_H #include "../ClangTidyCheck.h" -#include "clang/Lex/Token.h" - -#include namespace clang::tidy::modernize { @@ -38,37 +35,6 @@ class RedundantVoidArgCheck : public ClangTidyCheck { void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - -private: - void processFunctionDecl(const ast_matchers::MatchFinder::MatchResult &Result, - const FunctionDecl *Function); - - void - processTypedefNameDecl(const ast_matchers::MatchFinder::MatchResult &Result, - const TypedefNameDecl *Typedef); - - void processFieldDecl(const ast_matchers::MatchFinder::MatchResult &Result, - const FieldDecl *Member); - - void processVarDecl(const ast_matchers::MatchFinder::MatchResult &Result, - const VarDecl *Var); - - void - processNamedCastExpr(const ast_matchers::MatchFinder::MatchResult &Result, - const CXXNamedCastExpr *NamedCast); - - void - processExplicitCastExpr(const ast_matchers::MatchFinder::MatchResult &Result, - const ExplicitCastExpr *ExplicitCast); - - void processLambdaExpr(const ast_matchers::MatchFinder::MatchResult &Result, - const LambdaExpr *Lambda); - - void - removeVoidArgumentTokens(const ast_matchers::MatchFinder::MatchResult &Result, - SourceRange Range, StringRef GrammarLocation); - - void removeVoidToken(Token VoidToken, StringRef Diagnostic); }; } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg-delayed.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg-delayed.cpp index 4e05ada1d2992..b5916146ac8d8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg-delayed.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg-delayed.cpp @@ -1,7 +1,7 @@ // RUN: %check_clang_tidy %s modernize-redundant-void-arg %t -- -- -fdelayed-template-parsing int foo(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int foo() { return 0; } @@ -9,7 +9,7 @@ int foo(void) { template struct MyFoo { int foo(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int foo() { return 0; } @@ -21,7 +21,7 @@ template struct MyBar { // This declaration isn't instantiated and won't be parsed 'delayed-template-parsing'. int foo(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int foo() { return 0; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp index 631149761e5e8..09dc2bb5c1775 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/redundant-void-arg.cpp @@ -18,7 +18,7 @@ extern int i; int j = 1; int foo(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int foo() { return 0; } @@ -30,24 +30,24 @@ typedef void my_void; // A function taking void and returning a pointer to function taking void // and returning int. int (*returns_fn_void_int(void))(void); -// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function declaration -// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function declaration +// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int (*returns_fn_void_int())(); typedef int (*returns_fn_void_int_t(void))(void); -// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: {{.*}} in typedef -// CHECK-MESSAGES: :[[@LINE-2]]:44: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:44: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: typedef int (*returns_fn_void_int_t())(); // Should work for type aliases as well as typedef. using returns_fn_void_int_t2 = int (*(void))(void); -// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: {{.*}} in type alias -// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: {{.*}} in type alias +// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: using returns_fn_void_int_t2 = int (*())(); int (*returns_fn_void_int(void))(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function definition -// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: int (*returns_fn_void_int())() { return nullptr; } @@ -55,27 +55,27 @@ int (*returns_fn_void_int(void))(void) { // A function taking void and returning a pointer to a function taking void // and returning a pointer to a function taking void and returning void. void (*(*returns_fn_returns_fn_void_void(void))(void))(void); -// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function declaration -// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function declaration -// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function declaration +// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*(*returns_fn_returns_fn_void_void())())(); typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void); -// CHECK-MESSAGES: :[[@LINE-1]]:52: warning: {{.*}} in typedef -// CHECK-MESSAGES: :[[@LINE-2]]:59: warning: {{.*}} in typedef -// CHECK-MESSAGES: :[[@LINE-3]]:66: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-1]]:52: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:59: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-3]]:66: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: typedef void (*(*returns_fn_returns_fn_void_void_t())())(); void (*(*returns_fn_returns_fn_void_void(void))(void))(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function definition -// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function definition -// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*(*returns_fn_returns_fn_void_void())())() { return nullptr; } void bar(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void bar() { } @@ -102,13 +102,13 @@ class gronk { double *m_pd; void (*f1)(void); - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in field declaration + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f1)(); void (*op)(int i); void (gronk::*p1)(void); - // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in field declaration + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (gronk::*p1)(); int (gronk::*p_mi); @@ -116,15 +116,15 @@ class gronk { void (gronk::*p2)(int); void (*(*returns_fn_returns_fn_void_void(void))(void))(void); - // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in function declaration - // CHECK-MESSAGES: :[[@LINE-2]]:51: warning: {{.*}} in function declaration - // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: {{.*}} in function declaration + // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-2]]:51: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*(*returns_fn_returns_fn_void_void())())(); void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)(void))(void))(void); - // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: {{.*}} in field declaration - // CHECK-MESSAGES: :[[@LINE-2]]:65: warning: {{.*}} in field declaration - // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: {{.*}} in field declaration + // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-2]]:65: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)())())(); }; @@ -137,35 +137,35 @@ double d; double *pd; void (*f1)(void); -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f1)(); void (*f2)(void) = nullptr; -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2)() = nullptr; void (*f2b)(void)(nullptr); -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2b)()(nullptr); void (*f2c)(void){nullptr}; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2c)(){nullptr}; void (*f2d)(void) = NULL; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2d)() = NULL; void (*f2e)(void)(NULL); -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2e)()(NULL); void (*f2f)(void){NULL}; -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2f)(){NULL}; void (*f3)(void) = bar; -// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f3)() = bar; void (*o1)(int i); @@ -184,7 +184,7 @@ void (*fb)() = nullptr; void (*fc)() = bar; typedef void (function_ptr)(void); -// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: typedef void (function_ptr)(); // intentionally not LLVM style to check preservation of whitespace @@ -192,7 +192,7 @@ typedef void (function_ptr2) ( void ); -// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^typedef void \(function_ptr2\)$}} // CHECK-FIXES-NEXT: {{^ \($}} // CHECK-FIXES-NEXT: {{^ $}} @@ -219,9 +219,9 @@ void void ) ; -// CHECK-MESSAGES: :[[@LINE-11]]:1: warning: {{.*}} in typedef -// CHECK-MESSAGES: :[[@LINE-8]]:1: warning: {{.*}} in typedef -// CHECK-MESSAGES: :[[@LINE-5]]:1: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-11]]:1: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-8]]:1: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-5]]:1: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^typedef$}} // CHECK-FIXES-NEXT: {{^void$}} // CHECK-FIXES-NEXT: {{^\($}} @@ -244,15 +244,15 @@ void // clang-format on void (gronk::*p1)(void); -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (gronk::*p1)(); void (gronk::*p2)(void) = &gronk::foo; -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration with initializer +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (gronk::*p2)() = &gronk::foo; typedef void (gronk::*member_function_ptr)(void); -// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: typedef void (gronk::*member_function_ptr)(); // intentionally not LLVM style to check preservation of whitespace @@ -260,7 +260,7 @@ typedef void (gronk::*member_function_ptr2) ( void ); -// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^typedef void \(gronk::\*member_function_ptr2\)$}} // CHECK-FIXES-NEXT: {{^ \($}} // CHECK-FIXES-NEXT: {{^ $}} @@ -268,11 +268,11 @@ typedef void (gronk::*member_function_ptr2) void gronk::foo() { void (*f1)(void) = &::bar; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f1)() = &::bar; void (*f2)(void); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f2)(); // intentionally not LLVM style to check preservation of whitespace @@ -280,7 +280,7 @@ void gronk::foo() { ( void ); - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^ }}void (*f3){{$}} // CHECK-FIXES-NEXT: {{^ \($}} // CHECK-FIXES-NEXT: {{^ $}} @@ -288,14 +288,14 @@ void gronk::foo() { } void gronk::bar(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void gronk::bar() { void (gronk::*p3)(void) = &gronk::foo; - // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration with initializer + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (gronk::*p3)() = &gronk::foo; void (gronk::*p4)(void); - // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (gronk::*p4)(); // intentionally not LLVM style to check preservation of whitespace @@ -303,11 +303,11 @@ void gronk::bar(void) { ( void ); - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^ }}void (gronk::*p5){{$}} // CHECK-FIXES-NEXT: {{^ \($}} - // CHECK-FIXES-NExT: {{^ $}} - // CHECK-FIXES-NExT: {{^ \);$}} + // CHECK-FIXES-NEXT: {{^ $}} + // CHECK-FIXES-NEXT: {{^ \);$}} } // intentionally not LLVM style to check preservation of whitespace @@ -315,7 +315,7 @@ void gronk::bar2 ( void ) -// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^void gronk::bar2$}} // CHECK-FIXES-NEXT: {{^ \($}} // CHECK-FIXES-NEXT: {{^ $}} @@ -324,14 +324,14 @@ void gronk::bar2 } gronk::gronk(void) -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: gronk::gronk() : f1(nullptr), p1(nullptr) { } gronk::~gronk(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: gronk::~gronk() { } @@ -341,21 +341,21 @@ class nutter { }; nutter::nutter(void) { -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: nutter::nutter() { void (*f3)(void) = static_cast(0); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer - // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: {{.*}} in named cast + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f3)() = static_cast(0); void (*f4)(void) = (void (*)(void)) 0; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer - // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: {{.*}} in cast expression + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f4)() = (void (*)()) 0; void (*f5)(void) = reinterpret_cast(0); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer - // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: {{.*}} in named cast + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void (*f5)() = reinterpret_cast(0); // intentionally not LLVM style to check preservation of whitespace @@ -363,8 +363,8 @@ nutter::nutter(void) { ( void )>(0); - // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer - // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast + // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^ }}void (*f6)() = static_cast(0); - // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer - // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast + // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: {{^ }}void (*f8)() = reinterpret_cast void (*)(void) { return f1; }; - // CHECK-MESSAGES: [[@LINE-1]]:27: warning: {{.*}} in lambda expression - // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression + // CHECK-MESSAGES: [[@LINE-1]]:27: warning: redundant void argument list [modernize-redundant-void-arg] + // CHECK-MESSAGES: [[@LINE-2]]:45: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: auto void_returner = []() -> void (*)() { return f1; }; } #define M(x) x M(void inmacro(void) {}) -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: M(void inmacro() {}) #define F(A, B) \ @@ -436,6 +436,11 @@ M(void inmacro(void) {}) F_##A##_##B(void); \ }; \ F_##A##_##B::F_##A##_##B(void) +// CHECK-MESSAGES: :[[@LINE-3]]:17: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-FIXES: F_##A##_##B(); {{\\}} + +// CHECK-MESSAGES: :[[@LINE-4]]:28: warning: redundant void argument list [modernize-redundant-void-arg] +// CHECK-FIXES: F_##A##_##B::F_##A##_##B() F(Foo, Bar) { @@ -443,7 +448,7 @@ F(Foo, Bar) { struct DefinitionWithNoBody { DefinitionWithNoBody(void) = delete; - // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: DefinitionWithNoBody() = delete; }; @@ -451,55 +456,55 @@ struct DefinitionWithNoBody { #define BODY {} #define LAMBDA1 [](void){} -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: #define LAMBDA1 [](){} #define LAMBDA2 [](void)BODY -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: #define LAMBDA2 []()BODY #define LAMBDA3(captures, args, body) captures args body #define WRAP(...) __VA_ARGS__ #define LAMBDA4 (void)LAMBDA3([],(void),BODY) -// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: #define LAMBDA4 (void)LAMBDA3([],(),BODY) #define LAMBDA5 []() -> void (*)(void) {return BODY;} -// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: #define LAMBDA5 []() -> void (*)() {return BODY;} void lambda_expression_with_macro_test(){ (void)LAMBDA1; (void)LAMBDA2; (void)LAMBDA3([], (void), BODY); - // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: (void)LAMBDA3([], (), BODY); LAMBDA4; LAMBDA5; WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP((void)), WRAP(BODY))))); - // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP(()), WRAP(BODY))))); (void)WRAP([](void) {}); - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: (void)WRAP([]() {}); [](void) BODY; - // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: []() BODY; } namespace qqq { void foo() BODY void bar(void) BODY; -// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void bar() BODY; } struct S_1 { void g_1(void) const { - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void g_1() const { int a; (void)a; @@ -514,7 +519,7 @@ struct S_1 { template struct S_2 { void g_1(void) const { - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void g_1() const { int a; (void)a; @@ -530,7 +535,7 @@ template struct S_3 { template void g_1(void) const { - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void g_1() const { int a; (void)a; @@ -544,7 +549,7 @@ struct S_3 { template void g_3(void) { - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition [modernize-redundant-void-arg] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: void g_3() { int a; (void)a; @@ -560,33 +565,33 @@ void f_testTemplate() { #define return_t(T) T extern return_t(void) func(void); -// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: redundant void argument list in function declaration +// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: extern return_t(void) func(); return_t(void) func(void) { - // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list in function definition + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: return_t(void) func() { int a; (void)a; } extern return_t(void) func(return_t(void) (*fp)(void)); -// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: redundant void argument list in variable declaration +// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: extern return_t(void) func(return_t(void) (*fp)()); return_t(void) func(return_t(void) (*fp)(void)) { - // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: redundant void argument list in variable declaration + // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: return_t(void) func(return_t(void) (*fp)()) { int a; (void)a; } extern return_t(return_t(void)) func2(return_t(return_t(void)) (*fp)(void)); -// CHECK-MESSAGES: :[[@LINE-1]]:70: warning: redundant void argument list in variable declaration +// CHECK-MESSAGES: :[[@LINE-1]]:70: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: extern return_t(return_t(void)) func2(return_t(return_t(void)) (*fp)()); return_t(return_t(void)) func2(return_t(return_t(void)) (*fp)(void)) { - // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: redundant void argument list in variable declaration + // CHECK-MESSAGES: :[[@LINE-1]]:63: warning: redundant void argument list [modernize-redundant-void-arg] // CHECK-FIXES: return_t(return_t(void)) func2(return_t(return_t(void)) (*fp)()) { int a; (void)a; diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index e3ec26207d2bc..9b427de23ac2b 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7016,6 +7016,19 @@ AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher, extern const internal::VariadicDynCastAllOfMatcher arrayTypeLoc; +/// Matches `FunctionTypeLoc`s. +/// +/// Given +/// \code +/// void f(int); +/// double g(char, float) {} +/// char (*fn_ptr)(); +/// \endcode +/// functionTypeLoc() +/// matches "void (int)", "double (char, float)", and "char ()". +extern const internal::VariadicDynCastAllOfMatcher + functionTypeLoc; + /// Matches template specialization `TypeLoc`s. /// /// Given diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index a556ffca96903..2c55c78d614b4 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -808,6 +808,8 @@ const internal::VariadicDynCastAllOfMatcher const internal::VariadicDynCastAllOfMatcher referenceTypeLoc; const internal::VariadicDynCastAllOfMatcher arrayTypeLoc; +const internal::VariadicDynCastAllOfMatcher + functionTypeLoc; const internal::VariadicDynCastAllOfMatcher templateSpecializationTypeLoc;