summaryrefslogtreecommitdiffstats
path: root/clang-tidy/objc
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tidy/objc')
-rw-r--r--clang-tidy/objc/AvoidNSErrorInitCheck.cpp7
-rw-r--r--clang-tidy/objc/AvoidNSErrorInitCheck.h9
-rw-r--r--clang-tidy/objc/AvoidSpinlockCheck.cpp7
-rw-r--r--clang-tidy/objc/AvoidSpinlockCheck.h9
-rw-r--r--clang-tidy/objc/CMakeLists.txt1
-rw-r--r--clang-tidy/objc/ForbiddenSubclassingCheck.cpp7
-rw-r--r--clang-tidy/objc/ForbiddenSubclassingCheck.h9
-rw-r--r--clang-tidy/objc/ObjCTidyModule.cpp10
-rw-r--r--clang-tidy/objc/PropertyDeclarationCheck.cpp40
-rw-r--r--clang-tidy/objc/PropertyDeclarationCheck.h20
-rw-r--r--clang-tidy/objc/SuperSelfCheck.cpp127
-rw-r--r--clang-tidy/objc/SuperSelfCheck.h36
12 files changed, 209 insertions, 73 deletions
diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
index d5e2027a..eb18dcd2 100644
--- a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
+++ b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp
@@ -1,9 +1,8 @@
//===--- AvoidNSErrorInitCheck.cpp - clang-tidy----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.h b/clang-tidy/objc/AvoidNSErrorInitCheck.h
index 379b8a2a..030a532e 100644
--- a/clang-tidy/objc/AvoidNSErrorInitCheck.h
+++ b/clang-tidy/objc/AvoidNSErrorInitCheck.h
@@ -1,16 +1,15 @@
//===--- AvoidNSErrorInitCheck.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.
+// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
namespace clang {
namespace tidy {
diff --git a/clang-tidy/objc/AvoidSpinlockCheck.cpp b/clang-tidy/objc/AvoidSpinlockCheck.cpp
index 319d9456..ac3d2b28 100644
--- a/clang-tidy/objc/AvoidSpinlockCheck.cpp
+++ b/clang-tidy/objc/AvoidSpinlockCheck.cpp
@@ -1,9 +1,8 @@
//===--- AvoidSpinlockCheck.cpp - clang-tidy-------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/clang-tidy/objc/AvoidSpinlockCheck.h b/clang-tidy/objc/AvoidSpinlockCheck.h
index d9dbf8cb..dd409625 100644
--- a/clang-tidy/objc/AvoidSpinlockCheck.h
+++ b/clang-tidy/objc/AvoidSpinlockCheck.h
@@ -1,16 +1,15 @@
//===--- AvoidSpinlockCheck.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.
+// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOID_SPINLOCK_H
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
namespace clang {
namespace tidy {
diff --git a/clang-tidy/objc/CMakeLists.txt b/clang-tidy/objc/CMakeLists.txt
index 4063bba1..4eeb1484 100644
--- a/clang-tidy/objc/CMakeLists.txt
+++ b/clang-tidy/objc/CMakeLists.txt
@@ -6,6 +6,7 @@ add_clang_library(clangTidyObjCModule
ForbiddenSubclassingCheck.cpp
ObjCTidyModule.cpp
PropertyDeclarationCheck.cpp
+ SuperSelfCheck.cpp
LINK_LIBS
clangAST
diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
index 0599b21d..6b8e7951 100644
--- a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
+++ b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp
@@ -1,9 +1,8 @@
//===--- ForbiddenSubclassingCheck.cpp - clang-tidy -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.h b/clang-tidy/objc/ForbiddenSubclassingCheck.h
index 6c7e08b3..c05ba084 100644
--- a/clang-tidy/objc/ForbiddenSubclassingCheck.h
+++ b/clang-tidy/objc/ForbiddenSubclassingCheck.h
@@ -1,16 +1,15 @@
//===--- ForbiddenSubclassingCheck.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.
+// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H
-#include "../ClangTidy.h"
+#include "../ClangTidyCheck.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
diff --git a/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tidy/objc/ObjCTidyModule.cpp
index 19152c21..636e2c02 100644
--- a/clang-tidy/objc/ObjCTidyModule.cpp
+++ b/clang-tidy/objc/ObjCTidyModule.cpp
@@ -1,9 +1,8 @@
//===--- ObjCTidyModule.cpp - clang-tidy --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
@@ -14,6 +13,7 @@
#include "AvoidSpinlockCheck.h"
#include "ForbiddenSubclassingCheck.h"
#include "PropertyDeclarationCheck.h"
+#include "SuperSelfCheck.h"
using namespace clang::ast_matchers;
@@ -32,6 +32,8 @@ public:
"objc-forbidden-subclassing");
CheckFactories.registerCheck<PropertyDeclarationCheck>(
"objc-property-declaration");
+ CheckFactories.registerCheck<SuperSelfCheck>(
+ "objc-super-self");
}
};
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp
index 94b82f00..094c193c 100644
--- a/clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -1,9 +1,8 @@
//===--- PropertyDeclarationCheck.cpp - clang-tidy-------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
@@ -81,7 +80,8 @@ std::string validPropertyNameRegex(bool UsedInMatcher) {
}
bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) {
- auto RegexExp = llvm::Regex("^[a-zA-Z]+_[a-zA-Z0-9][a-zA-Z0-9_]+$");
+ auto RegexExp =
+ llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$");
return RegexExp.match(PropertyName);
}
@@ -92,31 +92,21 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) {
if (Prefix.lower() != Prefix) {
return false;
}
- auto RegexExp =
- llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
+ auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false)));
return RegexExp.match(PropertyName.substr(Start + 1));
}
} // namespace
-PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name,
- ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context),
- SpecialAcronyms(
- utils::options::parseStringList(Options.get("Acronyms", ""))),
- IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)),
- EscapedAcronyms() {}
-
void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
// this check should only be applied to ObjC sources.
if (!getLangOpts().ObjC) return;
- Finder->addMatcher(
- objcPropertyDecl(
- // the property name should be in Lower Camel Case like
- // 'lowerCamelCase'
- unless(matchesName(validPropertyNameRegex(true))))
- .bind("property"),
- this);
+ Finder->addMatcher(objcPropertyDecl(
+ // the property name should be in Lower Camel Case like
+ // 'lowerCamelCase'
+ unless(matchesName(validPropertyNameRegex(true))))
+ .bind("property"),
+ this);
}
void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
@@ -146,12 +136,6 @@ void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
<< generateFixItHint(MatchedDecl, StandardProperty);
}
-void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
- Options.store(Opts, "Acronyms",
- utils::options::serializeStringList(SpecialAcronyms));
- Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms);
-}
-
} // namespace objc
} // namespace tidy
} // namespace clang
diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h
index b2683bae..769f0c4c 100644
--- a/clang-tidy/objc/PropertyDeclarationCheck.h
+++ b/clang-tidy/objc/PropertyDeclarationCheck.h
@@ -1,18 +1,15 @@
//===--- PropertyDeclarationCheck.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.
+// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H
-#include "../ClangTidy.h"
-#include <string>
-#include <vector>
+#include "../ClangTidyCheck.h"
namespace clang {
namespace tidy {
@@ -28,15 +25,10 @@ namespace objc {
/// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html
class PropertyDeclarationCheck : public ClangTidyCheck {
public:
- PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context);
+ PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
- void storeOptions(ClangTidyOptions::OptionMap &Options) override;
-
-private:
- const std::vector<std::string> SpecialAcronyms;
- const bool IncludeDefaultAcronyms;
- std::vector<std::string> EscapedAcronyms;
};
} // namespace objc
diff --git a/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tidy/objc/SuperSelfCheck.cpp
new file mode 100644
index 00000000..7aafd66a
--- /dev/null
+++ b/clang-tidy/objc/SuperSelfCheck.cpp
@@ -0,0 +1,127 @@
+//===--- SuperSelfCheck.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 "SuperSelfCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+namespace {
+
+/// \brief Matches Objective-C methods in the initializer family.
+///
+/// Example matches -init and -initWithInt:.
+/// (matcher = objcMethodDecl(isInitializer()))
+/// \code
+/// @interface Foo
+/// - (instancetype)init;
+/// - (instancetype)initWithInt:(int)i;
+/// + (instancetype)init;
+/// - (void)bar;
+/// @end
+/// \endcode
+AST_MATCHER(ObjCMethodDecl, isInitializer) {
+ return Node.getMethodFamily() == OMF_init;
+}
+
+/// \brief Matches Objective-C implementations of classes that directly or
+/// indirectly have a superclass matching \c InterfaceDecl.
+///
+/// Note that a class is not considered to be a subclass of itself.
+///
+/// Example matches implementation declarations for Y and Z.
+/// (matcher = objcInterfaceDecl(isSubclassOf(hasName("X"))))
+/// \code
+/// @interface X
+/// @end
+/// @interface Y : X
+/// @end
+/// @implementation Y // directly derived
+/// @end
+/// @interface Z : Y
+/// @end
+/// @implementation Z // indirectly derived
+/// @end
+/// \endcode
+AST_MATCHER_P(ObjCImplementationDecl, isSubclassOf,
+ ast_matchers::internal::Matcher<ObjCInterfaceDecl>,
+ InterfaceDecl) {
+ // Check if any of the superclasses of the class match.
+ for (const ObjCInterfaceDecl *SuperClass =
+ Node.getClassInterface()->getSuperClass();
+ SuperClass != nullptr; SuperClass = SuperClass->getSuperClass()) {
+ if (InterfaceDecl.matches(*SuperClass, Finder, Builder))
+ return true;
+ }
+
+ // No matches found.
+ return false;
+}
+
+/// \brief Matches Objective-C message expressions where the receiver is the
+/// super instance.
+///
+/// Example matches the invocations of -banana and -orange.
+/// (matcher = objcMessageExpr(isMessagingSuperInstance()))
+/// \code
+/// - (void)banana {
+/// [self apple]
+/// [super banana];
+/// [super orange];
+/// }
+/// \endcode
+AST_MATCHER(ObjCMessageExpr, isMessagingSuperInstance) {
+ return Node.getReceiverKind() == ObjCMessageExpr::SuperInstance;
+}
+
+} // namespace
+
+void SuperSelfCheck::registerMatchers(MatchFinder *Finder) {
+ // This check should only be applied to Objective-C sources.
+ if (!getLangOpts().ObjC)
+ return;
+
+ Finder->addMatcher(
+ objcMessageExpr(
+ hasSelector("self"), isMessagingSuperInstance(),
+ hasAncestor(objcMethodDecl(isInitializer(),
+ hasDeclContext(objcImplementationDecl(
+ isSubclassOf(hasName("NSObject")))))))
+ .bind("message"),
+ this);
+}
+
+void SuperSelfCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *Message = Result.Nodes.getNodeAs<ObjCMessageExpr>("message");
+
+ auto Diag = diag(Message->getExprLoc(), "suspicious invocation of %0 in "
+ "initializer; did you mean to "
+ "invoke a superclass initializer?")
+ << Message->getMethodDecl();
+
+ SourceLocation ReceiverLoc = Message->getReceiverRange().getBegin();
+ if (ReceiverLoc.isMacroID() || ReceiverLoc.isInvalid())
+ return;
+
+ SourceLocation SelectorLoc = Message->getSelectorStartLoc();
+ if (SelectorLoc.isMacroID() || SelectorLoc.isInvalid())
+ return;
+
+ Diag << FixItHint::CreateReplacement(Message->getSourceRange(),
+ StringRef("[super init]"));
+}
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/objc/SuperSelfCheck.h b/clang-tidy/objc/SuperSelfCheck.h
new file mode 100644
index 00000000..ed5d1cd0
--- /dev/null
+++ b/clang-tidy/objc/SuperSelfCheck.h
@@ -0,0 +1,36 @@
+//===--- SuperSelfCheck.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_OBJC_SUPERSELFCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+/// Finds invocations of -self on super instances in initializers of subclasses
+/// of NSObject and recommends calling a superclass initializer instead.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/objc-super-self.html
+class SuperSelfCheck : public ClangTidyCheck {
+public:
+ SuperSelfCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_SUPERSELFCHECK_H