Simplify check for nullary function.
http://reviews.llvm.org/D7639
Files:
clang-tidy/readability/CMakeLists.txt
clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tidy/readability/RedundantVoidArg.cpp
clang-tidy/readability/RedundantVoidArg.h
test/clang-tidy/readability-redundant-void-arg.c
test/clang-tidy/readability-redundant-void-arg.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -8,6 +8,7 @@
NamespaceCommentCheck.cpp
ReadabilityTidyModule.cpp
RedundantSmartptrGet.cpp
+ RedundantVoidArg.cpp
ShrinkToFitCheck.cpp
LINK_LIBS
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -15,6 +15,7 @@
#include "ElseAfterReturnCheck.h"
#include "FunctionSize.h"
#include "RedundantSmartptrGet.h"
+#include "RedundantVoidArg.h"
#include "ShrinkToFitCheck.h"
namespace clang {
@@ -34,16 +35,17 @@
"readability-function-size");
CheckFactories.registerCheck<RedundantSmartptrGet>(
"readability-redundant-smartptr-get");
- CheckFactories.registerCheck<ShrinkToFitCheck>(
- "readability-shrink-to-fit");
+ CheckFactories.registerCheck<RedundantVoidArg>(
+ "readability-redundant-void-arg");
+ CheckFactories.registerCheck<ShrinkToFitCheck>("readability-shrink-to-fit");
}
};
} // namespace readability
// Register the MiscTidyModule using this statically initialized variable.
static ClangTidyModuleRegistry::Add<readability::ReadabilityModule>
-X("readability-module", "Adds readability-related checks.");
+ X("readability-module", "Adds readability-related checks.");
// This anchor is used to force the linker to link in the generated object file
// and thus register the MiscModule.
Index: clang-tidy/readability/RedundantVoidArg.cpp
===================================================================
--- /dev/null
+++ clang-tidy/readability/RedundantVoidArg.cpp
@@ -0,0 +1,307 @@
+//===- RedundantVoidArg.cpp - clang-tidy ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RedundantVoidArg.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+namespace {
+
+// Returns the source text for a source range
+StringRef getText(const MatchFinder::MatchResult &Result, SourceRange Range) {
+ return Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
+ *Result.SourceManager,
+ Result.Context->getLangOpts());
+}
+
+// Returns the source text for a pair of source locations.
+StringRef getText(const MatchFinder::MatchResult &Result, SourceLocation Begin,
+ SourceLocation End) {
+ return getText(Result, SourceRange(Begin, End));
+}
+
+// Returns the text that makes up 'node' in the source.
+// Returns an empty string if the text cannot be found.
+template <typename T>
+StringRef getText(const MatchFinder::MatchResult &Result, const T &Node) {
+ return getText(Result, Node.getSourceRange());
+}
+
+// Determine if the given QualType is a nullary function or pointer to same.
+bool protoTypeHasNoParms(QualType QT) {
+ if (const auto PT = QT->getAs<PointerType>()) {
+ QT = PT->getPointeeType();
+ }
+ if (const auto *MPT = QT->getAs<MemberPointerType>()) {
+ QT = MPT->getPointeeType();
+ }
+ if (const auto FP = QT->getAs<FunctionProtoType>()) {
+ return FP->getNumParams() == 0;
+ }
+ return false;
+}
+
+const char FunctionId[] = "function";
+const char TypedefId[] = "typedef";
+const char FieldId[] = "field";
+const char VarId[] = "var";
+const char NamedCastId[] = "named-cast";
+const char CStyleCastId[] = "c-style-cast";
+const char ExplicitCastId[] = "explicit-cast";
+const char FunctionalCastId[] = "fn-cast";
+const char LambdaId[] = "lambda";
+
+} // namespace
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void RedundantVoidArg::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0),
+ unless(isImplicit()),
+ unless(isExternC())).bind(FunctionId),
+ this);
+ Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId),
+ this);
+ auto ParenFunctionType = parenType(innerType(functionType()));
+ auto PointerToFunctionType = pointee(ParenFunctionType);
+ auto FunctionOrMemberPointer =
+ anyOf(hasType(pointerType(PointerToFunctionType)),
+ hasType(memberPointerType(PointerToFunctionType)));
+ Finder->addMatcher(
+ fieldDecl(isExpansionInMainFile(), FunctionOrMemberPointer).bind(FieldId),
+ this);
+ Finder->addMatcher(
+ varDecl(isExpansionInMainFile(), FunctionOrMemberPointer).bind(VarId),
+ this);
+ auto CastDestinationIsFunction =
+ hasDestinationType(pointsTo(ParenFunctionType));
+ Finder->addMatcher(
+ cStyleCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+ .bind(CStyleCastId),
+ this);
+ Finder->addMatcher(
+ staticCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+ .bind(NamedCastId),
+ this);
+ Finder->addMatcher(
+ reinterpretCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+ .bind(NamedCastId),
+ this);
+ Finder->addMatcher(constCastExpr(isExpansionInMainFile(),
+ CastDestinationIsFunction).bind(NamedCastId),
+ this);
+ Finder->addMatcher(
+ functionalCastExpr(isExpansionInMainFile(), CastDestinationIsFunction)
+ .bind(FunctionalCastId),
+ this);
+ Finder->addMatcher(lambdaExpr(isExpansionInMainFile()).bind(LambdaId), this);
+}
+
+void RedundantVoidArg::check(const MatchFinder::MatchResult &Result) {
+ if (!Result.Context->getLangOpts().CPlusPlus) {
+ return;
+ }
+
+ auto &Nodes = Result.Nodes;
+ if (auto Function = Nodes.getNodeAs<FunctionDecl>(FunctionId)) {
+ processFunctionDecl(Result, Function);
+ } else if (auto Typedef = Nodes.getNodeAs<TypedefDecl>(TypedefId)) {
+ processTypedefDecl(Result, Typedef);
+ } else if (auto Member = Nodes.getNodeAs<FieldDecl>(FieldId)) {
+ processFieldDecl(Result, Member);
+ } else if (auto Var = Nodes.getNodeAs<VarDecl>(VarId)) {
+ processVarDecl(Result, Var);
+ } else if (auto NamedCast = Nodes.getNodeAs<CXXNamedCastExpr>(NamedCastId)) {
+ processNamedCastExpr(Result, NamedCast);
+ } else if (auto CStyleCast = Nodes.getNodeAs<CStyleCastExpr>(CStyleCastId)) {
+ processCStyleCastExpr(Result, CStyleCast);
+ } else if (auto FunctionalCast =
+ Nodes.getNodeAs<CXXFunctionalCastExpr>(FunctionalCastId)) {
+ processFunctionalCast(Result, FunctionalCast);
+ } else if (auto ExplicitCast =
+ Nodes.getNodeAs<ExplicitCastExpr>(ExplicitCastId)) {
+ processExplicitCastExpr(Result, ExplicitCast);
+ } else if (auto Lambda = Nodes.getNodeAs<LambdaExpr>(LambdaId)) {
+ processLambdaExpr(Result, Lambda);
+ }
+}
+
+void
+RedundantVoidArg::processFunctionDecl(const MatchFinder::MatchResult &Result,
+ const FunctionDecl *const Function) {
+ SourceLocation Start = Function->getLocStart();
+ if (Function->isThisDeclarationADefinition()) {
+ SourceLocation BeforeBody =
+ Function->getBody()->getLocStart().getLocWithOffset(-1);
+ std::string DeclText = getText(Result, Start, BeforeBody);
+ removeVoidArgumentTokens(Result, Start, DeclText, "function definition");
+ } else {
+ std::string Text = getText(Result, *Function);
+ removeVoidArgumentTokens(Result, Start, Text, "function declaration");
+ }
+}
+
+void RedundantVoidArg::removeVoidArgumentTokens(
+ const MatchFinder::MatchResult &Result, SourceLocation StartLoc,
+ const std::string &DeclText, StringRef GrammarLocation) {
+ clang::Lexer PrototypeLexer(StartLoc, Result.Context->getLangOpts(),
+ DeclText.data(), DeclText.data(),
+ DeclText.data() + DeclText.size());
+ enum TokenState {
+ NothingYet,
+ SawLeftParen,
+ SawVoid,
+ };
+ TokenState State = NothingYet;
+ Token VoidToken;
+ Token ProtoToken;
+ std::string Diagnostic =
+ ("redundant void argument list in " + GrammarLocation).str();
+ while (!PrototypeLexer.LexFromRawLexer(ProtoToken)) {
+ switch (State) {
+ case NothingYet:
+ if (ProtoToken.is(tok::TokenKind::l_paren)) {
+ State = SawLeftParen;
+ }
+ break;
+ case SawLeftParen:
+ if (ProtoToken.is(tok::TokenKind::raw_identifier) &&
+ ProtoToken.getRawIdentifier() == "void") {
+ State = SawVoid;
+ VoidToken = ProtoToken;
+ } else {
+ State = NothingYet;
+ }
+ break;
+ case SawVoid:
+ State = NothingYet;
+ if (ProtoToken.is(tok::TokenKind::r_paren)) {
+ removeVoidToken(VoidToken, Diagnostic);
+ } else if (ProtoToken.is(tok::TokenKind::l_paren)) {
+ State = SawLeftParen;
+ }
+ break;
+ }
+ }
+ if (State == SawVoid && ProtoToken.is(tok::TokenKind::r_paren)) {
+ removeVoidToken(VoidToken, Diagnostic);
+ }
+}
+
+void RedundantVoidArg::removeVoidToken(Token VoidToken,
+ const StringRef Diagnostic) {
+ SourceLocation VoidLoc(VoidToken.getLocation());
+ const auto VoidRange = SourceRange(VoidLoc, VoidLoc.getLocWithOffset(3));
+ diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidRange);
+}
+
+void
+RedundantVoidArg::processTypedefDecl(const MatchFinder::MatchResult &Result,
+ const TypedefDecl *const Typedef) {
+ if (protoTypeHasNoParms(Typedef->getUnderlyingType())) {
+ StringRef Text = getText(Result, *Typedef);
+ removeVoidArgumentTokens(Result, Typedef->getLocStart(), Text.str(),
+ "typedef");
+ }
+}
+
+void RedundantVoidArg::processFieldDecl(const MatchFinder::MatchResult &Result,
+ const FieldDecl *const Member) {
+ if (protoTypeHasNoParms(Member->getType())) {
+ StringRef Text = getText(Result, *Member);
+ removeVoidArgumentTokens(Result, Member->getLocStart(), Text.str(),
+ "field declaration");
+ }
+}
+
+void RedundantVoidArg::processVarDecl(const MatchFinder::MatchResult &Result,
+ const VarDecl *const Var) {
+ if (protoTypeHasNoParms(Var->getType())) {
+ SourceLocation Begin = Var->getLocStart();
+ if (Var->hasInit()) {
+ SourceLocation InitStart =
+ Result.SourceManager->getExpansionLoc(Var->getInit()->getLocStart())
+ .getLocWithOffset(-1);
+ StringRef Text = getText(Result, Begin, InitStart);
+ removeVoidArgumentTokens(Result, Begin, Text.str(),
+ "variable declaration with initializer");
+ } else {
+ StringRef Text = getText(Result, *Var);
+ removeVoidArgumentTokens(Result, Begin, Text.str(),
+ "variable declaration");
+ }
+ }
+}
+
+void RedundantVoidArg::processNamedCastExpr(
+ const MatchFinder::MatchResult &Result,
+ const CXXNamedCastExpr *const NamedCast) {
+ if (protoTypeHasNoParms(NamedCast->getTypeAsWritten())) {
+ SourceRange AngleBrackets = NamedCast->getAngleBrackets();
+ SourceLocation Begin = AngleBrackets.getBegin().getLocWithOffset(1);
+ SourceLocation End = AngleBrackets.getEnd().getLocWithOffset(-1);
+ StringRef TemplateArgument = getText(Result, Begin, End);
+ removeVoidArgumentTokens(Result, Begin, TemplateArgument.str(),
+ "named cast");
+ }
+}
+
+void RedundantVoidArg::processCStyleCastExpr(
+ const MatchFinder::MatchResult &Result,
+ const CStyleCastExpr *const CStyleCast) {
+ if (protoTypeHasNoParms(CStyleCast->getTypeAsWritten())) {
+ SourceLocation Begin = CStyleCast->getLParenLoc().getLocWithOffset(1);
+ SourceLocation End = CStyleCast->getRParenLoc().getLocWithOffset(-1);
+ StringRef ExprText = getText(Result, Begin, End);
+ removeVoidArgumentTokens(Result, Begin, ExprText.str(), "C style cast");
+ }
+}
+
+void RedundantVoidArg::processFunctionalCast(
+ const MatchFinder::MatchResult &Result,
+ const CXXFunctionalCastExpr *const FunctionalCast) {
+ if (protoTypeHasNoParms(FunctionalCast->getTypeAsWritten())) {
+ SourceLocation Begin = FunctionalCast->getLocStart();
+ StringRef ExprText = getText(
+ Result, Begin, FunctionalCast->getLParenLoc().getLocWithOffset(-1));
+ removeVoidArgumentTokens(Result, Begin, ExprText.str(), "functional cast");
+ }
+}
+
+void RedundantVoidArg::processExplicitCastExpr(
+ const MatchFinder::MatchResult &Result,
+ const ExplicitCastExpr *const ExplicitCast) {
+ if (protoTypeHasNoParms(ExplicitCast->getTypeAsWritten())) {
+ StringRef ExprText = getText(Result, *ExplicitCast);
+ removeVoidArgumentTokens(Result, ExplicitCast->getLocStart(),
+ ExprText.str(), "explicit cast");
+ }
+}
+
+void RedundantVoidArg::processLambdaExpr(const MatchFinder::MatchResult &Result,
+ const LambdaExpr *const Lambda) {
+ if (Lambda->getLambdaClass()->getLambdaCallOperator()->getNumParams() == 0 &&
+ Lambda->hasExplicitParameters()) {
+ SourceLocation Begin =
+ Lambda->getIntroducerRange().getEnd().getLocWithOffset(1);
+ SourceLocation End = Lambda->getBody()->getLocStart().getLocWithOffset(-1);
+ StringRef LambdaProtoText = getText(Result, Begin, End);
+ removeVoidArgumentTokens(Result, Begin, LambdaProtoText.str(),
+ "lambda expression");
+ }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/RedundantVoidArg.h
===================================================================
--- /dev/null
+++ clang-tidy/readability/RedundantVoidArg.h
@@ -0,0 +1,79 @@
+//===--- RedundantVoidArg.h - clang-tidy ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_VOID_ARG_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_VOID_ARG_H
+
+#include "../ClangTidy.h"
+#include "clang/Lex/Token.h"
+
+#include <string>
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// \brief Find and remove redundant void argument lists.
+///
+/// Examples:
+/// int foo(void); ==> int foo();
+class RedundantVoidArg : public ClangTidyCheck {
+public:
+ RedundantVoidArg(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+
+ 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 processTypedefDecl(const ast_matchers::MatchFinder::MatchResult &Result,
+ const TypedefDecl *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
+ processCStyleCastExpr(const ast_matchers::MatchFinder::MatchResult &Result,
+ const CStyleCastExpr *CStyleCast);
+
+ void
+ processFunctionalCast(const ast_matchers::MatchFinder::MatchResult &Result,
+ const CXXFunctionalCastExpr *FunctionalCast);
+
+ 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,
+ SourceLocation StartLoc, const std::string &DeclText,
+ StringRef GrammarLocation);
+
+ void removeVoidToken(Token VoidToken, const StringRef Diagnostic);
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_VOID_ARG_H
Index: test/clang-tidy/readability-redundant-void-arg.c
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-redundant-void-arg.c
@@ -0,0 +1,128 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-remove-void-arg %t -- -x c
+// REQUIRES: shell
+
+#include <stdio.h>
+
+extern int i;
+
+int foo2()
+{
+ return 0;
+}
+
+int j = 1;
+
+int foo(void)
+// CHECK-FIXES: {{^}}int foo(void){{$}}
+{
+ return 0;
+}
+
+typedef unsigned int my_uint;
+
+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-FIXES: {{^}}int (*returns_fn_void_int(void))(void);{{$}}
+
+typedef int (*returns_fn_void_int_t(void))(void);
+// CHECK-FIXES: {{^}}typedef int (*returns_fn_void_int_t(void))(void);{{$}}
+
+int (*returns_fn_void_int(void))(void)
+// CHECK-FIXES: {{^}}int (*returns_fn_void_int(void))(void){{$}}
+{
+ return NULL;
+}
+
+// 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-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void(void))(void))(void);{{$}}
+
+typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);
+// CHECK-FIXES: {{^}}typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);{{$}}
+
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void)
+// CHECK-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void(void))(void))(void){{$}}
+{
+ return NULL;
+}
+
+void bar()
+{
+ int i;
+ int *pi = NULL;
+ void *pv = (void *) pi;
+ float f;
+ float *fi;
+ double d;
+ double *pd;
+}
+
+void (*f1)(void);
+// CHECK-FIXES: {{^}}void (*f1)(void);{{$}}
+
+void (*f2)(void) = NULL;
+// CHECK-FIXES: {{^}}void (*f2)(void) = NULL;{{$}}
+
+void (*f3)(void) = bar;
+// CHECK-FIXES: {{^}}void (*f3)(void) = bar;{{$}}
+
+void (*fa)();
+
+void (*fb)() = NULL;
+
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);
+// CHECK-FIXES: {{^}}typedef void (function_ptr)(void);{{$}}
+
+typedef void (function_ptr2)
+ (
+ void
+ );
+// CHECK-FIXES: {{^}}typedef void (function_ptr2){{$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ void$}}
+// CHECK-FIXES-NEXT: {{^ \);$}}
+
+typedef
+void
+(
+*
+(
+*
+returns_fn_returns_fn_void_void_t2
+(
+void
+)
+)
+(
+void
+)
+)
+(
+void
+)
+;
+// CHECK-FIXES: {{^typedef$}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^returns_fn_returns_fn_void_void_t2$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^;$}}
Index: test/clang-tidy/readability-redundant-void-arg.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-redundant-void-arg.cpp
@@ -0,0 +1,426 @@
+// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-redundant-void-arg %t
+// REQUIRES: shell
+
+#include <iostream>
+
+int foo();
+
+void bar();
+
+void bar2();
+
+extern "C" void ecfoo(void);
+
+extern "C" void ecfoo(void)
+{
+}
+
+extern int i;
+
+int j = 1;
+
+int foo(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [readability-redundant-void-arg]
+// CHECK-FIXES: {{^}}int foo(){{$}}
+{
+ return 0;
+}
+
+typedef unsigned int my_uint;
+
+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-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-FIXES: {{^}}typedef int (*returns_fn_void_int_t())();{{$}}
+
+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-FIXES: {{^}}int (*returns_fn_void_int())(){{$}}
+{
+ return nullptr;
+}
+
+// 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-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-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-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void())())(){{$}}
+{
+ return nullptr;
+}
+
+void bar(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void bar(){{$}}
+{
+}
+
+void op_fn(int i)
+{
+}
+
+class gronk
+{
+public:
+ gronk();
+ ~gronk();
+
+ void foo();
+ void bar();
+ void bar2
+ ();
+ void operation(int i) { }
+
+private:
+ int m_i;
+ int *m_pi;
+ float m_f;
+ float *m_pf;
+ double m_d;
+ double *m_pd;
+
+ void (*f1)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^ }}void (*f1)();{{$}}
+
+ void (*op)(int i);
+
+ void (gronk::*p1)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p1)();{{$}}
+
+ int (gronk::*p_mi);
+
+ void (gronk::*p2)(int);
+
+ void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: {{.*}} in function declaration
+ // CHECK-MESSAGES: :[[@LINE-2]]:53: warning: {{.*}} in function declaration
+ // CHECK-MESSAGES: :[[@LINE-3]]:60: warning: {{.*}} in function declaration
+ // 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]]:60: warning: {{.*}} in field declaration
+ // CHECK-MESSAGES: :[[@LINE-2]]:67: warning: {{.*}} in field declaration
+ // CHECK-MESSAGES: :[[@LINE-3]]:74: warning: {{.*}} in field declaration
+ // CHECK-FIXES: {{^}} void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)())())();{{$}}
+};
+
+int i;
+int *pi;
+void *pv = (void *) pi;
+float f;
+float *fi;
+double d;
+double *pd;
+
+void (*f1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (*f1)();{{$}}
+
+void (*f2)(void) = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2)() = nullptr;{{$}}
+
+void (*f2b)(void)(nullptr);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2b)()(nullptr);{{$}}
+
+void (*f2c)(void){nullptr};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2c)(){nullptr};{{$}}
+
+void (*f2d)(void) = NULL;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2d)() = NULL;{{$}}
+
+void (*f2e)(void)(NULL);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2e)()(NULL);{{$}}
+
+void (*f2f)(void){NULL};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2f)(){NULL};{{$}}
+
+void (*f3)(void) = bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f3)() = bar;{{$}}
+
+void (*o1)(int i);
+void (*o2)(int i) = nullptr;
+void (*o3)(int i)(nullptr);
+void (*o4)(int i){nullptr};
+void (*o5)(int i) = NULL;
+void (*o6)(int i)(NULL);
+void (*o7)(int i){NULL};
+void (*o8)(int i) = op_fn;
+
+void (*fa)();
+
+void (*fb)() = nullptr;
+
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (function_ptr)();{{$}}
+
+typedef void (function_ptr2)
+ (
+ void
+ );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^typedef void \(function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \);$}}
+
+typedef
+void
+(
+*
+(
+*
+returns_fn_returns_fn_void_void_t2
+(
+void
+)
+)
+(
+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-FIXES: {{^typedef$}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^returns_fn_returns_fn_void_void_t2$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT: {{[^ ]}}
+// CHECK-FIXES: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^;$}}
+
+
+void (gronk::*p1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (gronk::*p1)();{{$}}
+
+void (gronk::*p2)(void) = &gronk::foo;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (gronk::*p2)() = &gronk::foo;{{$}}
+
+typedef void (gronk::*member_function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (gronk::*member_function_ptr)();{{$}}
+
+typedef void (gronk::*member_function_ptr2)
+ (
+ void
+ );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^typedef void \(gronk::\*member_function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \);$}}
+
+void gronk::foo()
+{
+ void (*f1)(void) = &::bar;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-FIXES: {{^ }}void (*f1)() = &::bar;{{$}}
+
+ void (*f2)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (*f2)();{{$}}
+
+ void (*f3)
+ (
+ void
+ );
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (*f3){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \);$}}
+}
+
+void gronk::bar(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void gronk::bar(){{$}}
+{
+ void (gronk::*p3)(void) = &gronk::foo;
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}} in variable declaration with initializer
+ // CHECK-FIXES: {{^ }}void (gronk::*p3)() = &gronk::foo;{{$}}
+
+ void (gronk::*p4)(void);
+ // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p4)();{{$}}
+
+ void (gronk::*p5)
+ (
+ void
+ );
+ // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}void (gronk::*p5){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NExT: {{^ $}}
+ // CHECK-FIXES-NExT: {{^ \);$}}
+}
+
+void gronk::bar2
+ (
+ void
+ )
+// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^void gronk::bar2$}}
+// CHECK-FIXES-NEXT: {{^ \($}}
+// CHECK-FIXES-NEXT: {{^ $}}
+// CHECK-FIXES-NEXT: {{^ \)$}}
+{
+}
+
+gronk::gronk(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::gronk(){{$}}
+ : f1(nullptr),
+ p1(nullptr)
+{
+}
+
+gronk::~gronk(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::~gronk(){{$}}
+{
+}
+
+class nutter
+{
+public:
+ nutter();
+};
+
+nutter::nutter(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}nutter::nutter(){{$}}
+{
+ void (*f3)(void) = static_cast<void (*)(void)>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:45: warning: {{.*}} in named cast
+ // CHECK-FIXES: void (*f3)() = static_cast<void (*)()>(0);{{$}}
+
+ void (*f4)(void) = (void (*)(void)) 0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in C style cast
+ // CHECK-FIXES: void (*f4)() = (void (*)()) 0;{{$}}
+
+ void (*f5)(void) = reinterpret_cast<void (*)(void)>(0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-2]]:50: warning: {{.*}} in named cast
+ // CHECK-FIXES: void (*f5)() = reinterpret_cast<void (*)()>(0);{{$}}
+
+ void (*f6)(void) = static_cast<void (*)
+ (
+ void
+ )>(0);
+ // CHECK-MESSAGES: :[[@LINE-4]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: {{.*}} in named cast
+ // CHECK-FIXES: {{^ }}void (*f6)() = static_cast<void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ }})>(0);{{$}}
+
+ void (*f7)(void) = (void (*)
+ (
+ void
+ )) 0;
+ // CHECK-MESSAGES: :[[@LINE-4]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: {{.*}} in C style cast
+ // CHECK-FIXES: {{^ }}void (*f7)() = (void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \)\) 0;$}}
+
+ void (*f8)(void) = reinterpret_cast<void (*)
+ (
+ void
+ )>(0);
+ // CHECK-MESSAGES: :[[@LINE-4]]:16: warning: {{.*}} in variable declaration with initializer
+ // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: {{.*}} in named cast
+ // CHECK-FIXES: {{^ }}void (*f8)() = reinterpret_cast<void (*){{$}}
+ // CHECK-FIXES-NEXT: {{^ \($}}
+ // CHECK-FIXES-NEXT: {{^ $}}
+ // CHECK-FIXES-NEXT: {{^ \)>\(0\);$}}
+
+ void (*o1)(int) = static_cast<void (*)(int)>(0);
+ void (*o2)(int) = (void (*)(int)) 0;
+ void (*o3)(int) = reinterpret_cast<void (*)(int)>(0);
+}
+
+class generator
+{
+public:
+ int operator()(void) { return 1; }
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}} in function definition
+ // CHECK-FIXES: {{^ }}int operator()() { return 1; }{{$}}
+};
+
+void test_lambda_functions()
+{
+ auto lamb_duh = [](void (*fn)(void)) { (*fn)(); };
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: {{.*}} in variable declaration
+ // CHECK-FIXES: {{^ }}auto lamb_duh = [](void (*fn)()) { (*fn)(); };{{$}}
+
+ auto lambda_generator = [](void) { return 1; };
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} in lambda expression
+ // CHECK-FIXES: {{^ }}auto lambda_generator = []() { return 1; };{{$}}
+
+ auto gen2 = []() { return 1; };
+
+ auto gen3 = []{ return 1; };
+
+ auto void_returner = [](void) -> void (*)(void) { return f1; };
+ // CHECK-MESSAGES: [[@LINE-1]]:29: warning: {{.*}} in lambda expression
+ // CHECK-MESSAGES: [[@LINE-2]]:47: warning: {{.*}} in lambda expression
+ // CHECK-FIXES: {{^ }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits