Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,37 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#include "AvoidNSErrorInitCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace objc {
void AvoidNSErrorInitCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(objcMessageExpr(hasSelector("init"),
hasReceiverType(asString("NSError *")))
.bind("nserrorInit"),
this);
}
void AvoidNSErrorInitCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MatchedExpr =
Result.Nodes.getNodeAs<ObjCMessageExpr>("nserrorInit");
diag(MatchedExpr->getLocStart(),
"use errorWithDomain:code:userInfo: or initWithDomain:code:userInfo: to "
"create a new NSError");
}
} // namespace objc
} // namespace tidy
} // namespace clang

View File

@@ -0,0 +1,36 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_AVOIDNSERRORINITCHECK_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace objc {
/// Finds usages of [NSSError init]. It is not the proper way of creating
/// NSError. errorWithDomain:code:userInfo: should be used instead.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/objc-avoid-nserror-init.html
class AvoidNSErrorInitCheck : public ClangTidyCheck {
public:
AvoidNSErrorInitCheck(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_AVOIDNSERRORINITCHECK_H

View File

@@ -0,0 +1,37 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#include "AvoidSpinlockCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace objc {
void AvoidSpinlockCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(callee((functionDecl(hasAnyName(
"OSSpinlockLock", "OSSpinlockUnlock", "OSSpinlockTry")))))
.bind("spinlock"),
this);
}
void AvoidSpinlockCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MatchedExpr = Result.Nodes.getNodeAs<CallExpr>("spinlock");
diag(MatchedExpr->getLocStart(),
"use os_unfair_lock_lock() or dispatch queue APIs instead of the "
"deprecated OSSpinLock");
}
} // namespace objc
} // namespace tidy
} // namespace clang

View File

@@ -0,0 +1,36 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#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"
namespace clang {
namespace tidy {
namespace objc {
/// Finds usages of OSSpinlock, which is deprecated due to potential livelock
/// problems.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/objc-avoid-spinlock.html
class AvoidSpinlockCheck : public ClangTidyCheck {
public:
AvoidSpinlockCheck(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_AVOID_SPINLOCK_H

View File

@@ -0,0 +1,17 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyObjCModule
AvoidNSErrorInitCheck.cpp
AvoidSpinlockCheck.cpp
ForbiddenSubclassingCheck.cpp
ObjCTidyModule.cpp
PropertyDeclarationCheck.cpp
LINK_LIBS
clangAST
clangASTMatchers
clangBasic
clangLex
clangTidy
clangTidyUtils
)

View File

@@ -0,0 +1,118 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#include "ForbiddenSubclassingCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "../utils/OptionsUtils.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace objc {
namespace {
constexpr char DefaultForbiddenSuperClassNames[] =
"ABNewPersonViewController;"
"ABPeoplePickerNavigationController;"
"ABPersonViewController;"
"ABUnknownPersonViewController;"
"NSHashTable;"
"NSMapTable;"
"NSPointerArray;"
"NSPointerFunctions;"
"NSTimer;"
"UIActionSheet;"
"UIAlertView;"
"UIImagePickerController;"
"UITextInputMode;"
"UIWebView";
/// \brief Matches Objective-C classes that directly or indirectly
/// have a superclass matching \c Base.
///
/// Note that a class is not considered to be a subclass of itself.
///
/// Example matches Y, Z
/// (matcher = objcInterfaceDecl(hasName("X")))
/// \code
/// @interface X
/// @end
/// @interface Y : X // directly derived
/// @end
/// @interface Z : Y // indirectly derived
/// @end
/// \endcode
AST_MATCHER_P(ObjCInterfaceDecl, isSubclassOf,
ast_matchers::internal::Matcher<ObjCInterfaceDecl>, Base) {
for (const auto *SuperClass = Node.getSuperClass();
SuperClass != nullptr;
SuperClass = SuperClass->getSuperClass()) {
if (Base.matches(*SuperClass, Finder, Builder)) {
return true;
}
}
return false;
}
} // namespace
ForbiddenSubclassingCheck::ForbiddenSubclassingCheck(
StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
ForbiddenSuperClassNames(
utils::options::parseStringList(
Options.get("ClassNames", DefaultForbiddenSuperClassNames))) {
}
void ForbiddenSubclassingCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
objcInterfaceDecl(
isSubclassOf(
objcInterfaceDecl(
hasAnyName(
std::vector<StringRef>(
ForbiddenSuperClassNames.begin(),
ForbiddenSuperClassNames.end())))
.bind("superclass")))
.bind("subclass"),
this);
}
void ForbiddenSubclassingCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *SubClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
"subclass");
assert(SubClass != nullptr);
const auto *SuperClass = Result.Nodes.getNodeAs<ObjCInterfaceDecl>(
"superclass");
assert(SuperClass != nullptr);
diag(SubClass->getLocation(),
"Objective-C interface %0 subclasses %1, which is not "
"intended to be subclassed")
<< SubClass
<< SuperClass;
}
void ForbiddenSubclassingCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(
Opts,
"ForbiddenSuperClassNames",
utils::options::serializeStringList(ForbiddenSuperClassNames));
}
} // namespace objc
} // namespace tidy
} // namespace clang

View File

@@ -0,0 +1,42 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#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 "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
namespace clang {
namespace tidy {
namespace objc {
/// Finds Objective-C classes which have a superclass which is
/// documented to not support subclassing.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/objc-forbidden-subclassing.html
class ForbiddenSubclassingCheck : public ClangTidyCheck {
public:
ForbiddenSubclassingCheck(StringRef Name, ClangTidyContext *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> ForbiddenSuperClassNames;
};
} // namespace objc
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_FORBIDDEN_SUBCLASSING_CHECK_H

View File

@@ -0,0 +1,50 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "AvoidNSErrorInitCheck.h"
#include "AvoidSpinlockCheck.h"
#include "ForbiddenSubclassingCheck.h"
#include "PropertyDeclarationCheck.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace objc {
class ObjCModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<AvoidNSErrorInitCheck>(
"objc-avoid-nserror-init");
CheckFactories.registerCheck<AvoidSpinlockCheck>(
"objc-avoid-spinlock");
CheckFactories.registerCheck<ForbiddenSubclassingCheck>(
"objc-forbidden-subclassing");
CheckFactories.registerCheck<PropertyDeclarationCheck>(
"objc-property-declaration");
}
};
// Register the ObjCTidyModule using this statically initialized variable.
static ClangTidyModuleRegistry::Add<ObjCModule> X(
"objc-module",
"Adds Objective-C lint checks.");
} // namespace objc
// This anchor is used to force the linker to link in the generated object file
// and thus register the ObjCModule.
volatile int ObjCModuleAnchorSource = 0;
} // namespace tidy
} // namespace clang

View File

@@ -0,0 +1,115 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#include "PropertyDeclarationCheck.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Regex.h"
#include <algorithm>
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace objc {
namespace {
/// The acronyms are from
/// https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/APIAbbreviations.html#//apple_ref/doc/uid/20001285-BCIHCGAE
constexpr char DefaultSpecialAcronyms[] =
"ASCII;"
"PDF;"
"XML;"
"HTML;"
"URL;"
"RTF;"
"HTTP;"
"TIFF;"
"JPG;"
"PNG;"
"GIF;"
"LZW;"
"ROM;"
"RGB;"
"CMYK;"
"MIDI;"
"FTP";
/// For now we will only fix 'CamelCase' property to
/// 'camelCase'. For other cases the users need to
/// come up with a proper name by their own.
/// FIXME: provide fix for snake_case to snakeCase
FixItHint generateFixItHint(const ObjCPropertyDecl *Decl) {
if (isupper(Decl->getName()[0])) {
auto NewName = Decl->getName().str();
NewName[0] = tolower(NewName[0]);
return FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())),
llvm::StringRef(NewName));
}
return FixItHint();
}
std::string validPropertyNameRegex(const std::vector<std::string> &Prefixes) {
std::vector<std::string> EscapedPrefixes;
EscapedPrefixes.reserve(Prefixes.size());
// In case someone defines a custom prefix which includes a regex
// special character, escape all the prefixes.
std::transform(Prefixes.begin(), Prefixes.end(),
std::back_inserter(EscapedPrefixes), [](const std::string& s) {
return llvm::Regex::escape(s); });
// Allow any of these names:
// foo
// fooBar
// url
// urlString
// URL
// URLString
return std::string("::((") +
llvm::join(EscapedPrefixes.begin(), EscapedPrefixes.end(), "|") +
")[A-Z]?)?[a-z]+[a-z0-9]*([A-Z][a-z0-9]+)*$";
}
} // namespace
PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
SpecialAcronyms(utils::options::parseStringList(
Options.get("Acronyms", DefaultSpecialAcronyms))) {}
void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
objcPropertyDecl(
// the property name should be in Lower Camel Case like
// 'lowerCamelCase'
unless(matchesName(validPropertyNameRegex(SpecialAcronyms))))
.bind("property"),
this);
}
void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MatchedDecl =
Result.Nodes.getNodeAs<ObjCPropertyDecl>("property");
assert(MatchedDecl->getName().size() > 0);
diag(MatchedDecl->getLocation(),
"property name '%0' should use lowerCamelCase style, according to "
"the Apple Coding Guidelines")
<< MatchedDecl->getName() << generateFixItHint(MatchedDecl);
}
void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "Acronyms",
utils::options::serializeStringList(SpecialAcronyms));
}
} // namespace objc
} // namespace tidy
} // namespace clang

View File

@@ -0,0 +1,44 @@
//===--- 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.
//
//===----------------------------------------------------------------------===//
#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>
namespace clang {
namespace tidy {
namespace objc {
/// Finds Objective-C property declarations which
/// are not in Lower Camel Case.
///
/// The format of property should look like:
/// @property(nonatomic) NSString *lowerCamelCase;
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html
class PropertyDeclarationCheck : public ClangTidyCheck {
public:
PropertyDeclarationCheck(StringRef Name, ClangTidyContext *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;
};
} // namespace objc
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H