forked from OSchip/llvm-project
166 lines
6.0 KiB
C++
166 lines
6.0 KiB
C++
//===--- RenamerClangTidyCheck.h - clang-tidy -------------------*- C++ -*-===//
|
|
//
|
|
// 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_RENAMERCLANGTIDYCHECK_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
|
|
|
|
#include "../ClangTidyCheck.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/DenseSet.h"
|
|
#include "llvm/ADT/FunctionExtras.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
namespace clang {
|
|
|
|
class MacroInfo;
|
|
|
|
namespace tidy {
|
|
|
|
/// Base class for clang-tidy checks that want to flag declarations and/or
|
|
/// macros for renaming based on customizable criteria.
|
|
class RenamerClangTidyCheck : public ClangTidyCheck {
|
|
public:
|
|
RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context);
|
|
~RenamerClangTidyCheck();
|
|
|
|
/// Derived classes should not implement any matching logic themselves; this
|
|
/// class will do the matching and call the derived class'
|
|
/// getDeclFailureInfo() and getMacroFailureInfo() for determining whether a
|
|
/// given identifier passes or fails the check.
|
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
|
|
void
|
|
check(const ast_matchers::MatchFinder::MatchResult &Result) override final;
|
|
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
|
Preprocessor *ModuleExpanderPP) override final;
|
|
void onEndOfTranslationUnit() override final;
|
|
|
|
/// Derived classes that override this function should call this method from
|
|
/// the overridden method.
|
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
|
|
|
/// This enum will be used in %select of the diagnostic message.
|
|
/// Each value below IgnoreFailureThreshold should have an error message.
|
|
enum class ShouldFixStatus {
|
|
ShouldFix,
|
|
|
|
/// The fixup will conflict with a language keyword,
|
|
/// so we can't fix it automatically.
|
|
ConflictsWithKeyword,
|
|
|
|
/// The fixup will conflict with a macro
|
|
/// definition, so we can't fix it
|
|
/// automatically.
|
|
ConflictsWithMacroDefinition,
|
|
|
|
/// The fixup results in an identifier that is not a valid c/c++ identifier.
|
|
FixInvalidIdentifier,
|
|
|
|
/// Values pass this threshold will be ignored completely
|
|
/// i.e no message, no fixup.
|
|
IgnoreFailureThreshold,
|
|
|
|
/// If the identifier was used or declared within a macro we
|
|
/// won't offer a fixup for safety reasons.
|
|
InsideMacro,
|
|
};
|
|
|
|
/// Information describing a failed check
|
|
struct FailureInfo {
|
|
std::string KindName; // Tag or misc info to be used as derived classes need
|
|
std::string Fixup; // The name that will be proposed as a fix-it hint
|
|
};
|
|
|
|
/// Holds an identifier name check failure, tracking the kind of the
|
|
/// identifier, its possible fixup and the starting locations of all the
|
|
/// identifier usages.
|
|
struct NamingCheckFailure {
|
|
FailureInfo Info;
|
|
|
|
/// Whether the failure should be fixed or not.
|
|
///
|
|
/// e.g.: if the identifier was used or declared within a macro we won't
|
|
/// offer a fixup for safety reasons.
|
|
bool shouldFix() const {
|
|
return FixStatus == ShouldFixStatus::ShouldFix && !Info.Fixup.empty();
|
|
}
|
|
|
|
bool shouldNotify() const {
|
|
return FixStatus < ShouldFixStatus::IgnoreFailureThreshold;
|
|
}
|
|
|
|
ShouldFixStatus FixStatus = ShouldFixStatus::ShouldFix;
|
|
|
|
/// A set of all the identifier usages starting SourceLocation.
|
|
llvm::DenseSet<SourceLocation> RawUsageLocs;
|
|
|
|
NamingCheckFailure() = default;
|
|
};
|
|
|
|
using NamingCheckId = std::pair<SourceLocation, std::string>;
|
|
|
|
using NamingCheckFailureMap =
|
|
llvm::DenseMap<NamingCheckId, NamingCheckFailure>;
|
|
|
|
/// Check Macros for style violations.
|
|
void checkMacro(SourceManager &SourceMgr, const Token &MacroNameTok,
|
|
const MacroInfo *MI);
|
|
|
|
/// Add a usage of a macro if it already has a violation.
|
|
void expandMacro(const Token &MacroNameTok, const MacroInfo *MI);
|
|
|
|
void addUsage(const RenamerClangTidyCheck::NamingCheckId &Decl,
|
|
SourceRange Range, SourceManager *SourceMgr = nullptr);
|
|
|
|
/// Convenience method when the usage to be added is a NamedDecl.
|
|
void addUsage(const NamedDecl *Decl, SourceRange Range,
|
|
SourceManager *SourceMgr = nullptr);
|
|
|
|
protected:
|
|
/// Overridden by derived classes, returns information about if and how a Decl
|
|
/// failed the check. A 'None' result means the Decl did not fail the check.
|
|
virtual llvm::Optional<FailureInfo>
|
|
getDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const = 0;
|
|
|
|
/// Overridden by derived classes, returns information about if and how a
|
|
/// macro failed the check. A 'None' result means the macro did not fail the
|
|
/// check.
|
|
virtual llvm::Optional<FailureInfo>
|
|
getMacroFailureInfo(const Token &MacroNameTok,
|
|
const SourceManager &SM) const = 0;
|
|
|
|
/// Represents customized diagnostic text and how arguments should be applied.
|
|
/// Example usage:
|
|
///
|
|
/// return DiagInfo{"my %1 very %2 special %3 text",
|
|
/// [=](DiagnosticBuilder &diag) {
|
|
/// diag << arg1 << arg2 << arg3;
|
|
/// }};
|
|
struct DiagInfo {
|
|
std::string Text;
|
|
llvm::unique_function<void(DiagnosticBuilder &)> ApplyArgs;
|
|
};
|
|
|
|
/// Overridden by derived classes, returns a description of the diagnostic
|
|
/// that should be emitted for the given failure. The base class will then
|
|
/// further customize the diagnostic by adding info about whether the fix-it
|
|
/// can be automatically applied or not.
|
|
virtual DiagInfo getDiagInfo(const NamingCheckId &ID,
|
|
const NamingCheckFailure &Failure) const = 0;
|
|
|
|
private:
|
|
NamingCheckFailureMap NamingCheckFailures;
|
|
const bool AggressiveDependentMemberLookup;
|
|
};
|
|
|
|
} // namespace tidy
|
|
} // namespace clang
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_RENAMERCLANGTIDYCHECK_H
|