10 #include "clang/AST/ASTContext.h" 11 #include "clang/Lex/Lexer.h" 21 IgnoreMacros(Options.getLocalOrGlobal(
"IgnoreMacros", true)) {}
26 Finder->addMatcher(typedefDecl(unless(isInstantiated())).bind(
"typedef"),
30 Finder->addMatcher(cxxRecordDecl(unless(isImplicit())).bind(
"struct"),
this);
36 const auto *MatchedCxxRecordDecl =
37 Result.Nodes.getNodeAs<CXXRecordDecl>(
"struct");
38 if (MatchedCxxRecordDecl) {
39 LastCxxDeclRange = MatchedCxxRecordDecl->getSourceRange();
43 const auto *MatchedDecl = Result.Nodes.getNodeAs<TypedefDecl>(
"typedef");
44 if (MatchedDecl->getLocation().isInvalid())
47 SourceLocation StartLoc = MatchedDecl->getBeginLoc();
49 if (StartLoc.isMacroID() && IgnoreMacros)
52 static const char *UseUsingWarning =
"use 'using' instead of 'typedef'";
55 if (MatchedDecl->getUnderlyingType()->isArrayType() || StartLoc.isMacroID()) {
56 diag(StartLoc, UseUsingWarning);
61 printPolicy.SuppressScope =
true;
62 printPolicy.ConstantArraySizeAsWritten =
true;
63 printPolicy.UseVoidForZeroParams =
false;
65 std::string
Type = MatchedDecl->getUnderlyingType().getAsString(printPolicy);
66 std::string
Name = MatchedDecl->getNameAsString();
67 SourceRange ReplaceRange = MatchedDecl->getSourceRange();
73 std::string Using =
"using ";
74 if (ReplaceRange.getBegin().isMacroID() ||
75 ReplaceRange.getBegin() >= LastReplacementEnd) {
78 FirstTypedefType =
Type;
79 FirstTypedefName =
Name;
83 ReplaceRange.setBegin(LastReplacementEnd);
89 if (Type.size() > FirstTypedefType.size() &&
90 Type.substr(0, FirstTypedefType.size()) == FirstTypedefType)
91 Type = FirstTypedefName + Type.substr(FirstTypedefType.size() + 1);
93 if (!ReplaceRange.getEnd().isMacroID())
94 LastReplacementEnd = ReplaceRange.getEnd().getLocWithOffset(Name.size());
96 auto Diag =
diag(ReplaceRange.getBegin(), UseUsingWarning);
99 if (LastCxxDeclRange.isValid() && ReplaceRange.fullyContains(LastCxxDeclRange)) {
108 std::string Replacement = Using + Name +
" = " +
Type;
109 Diag << FixItHint::CreateReplacement(ReplaceRange, Replacement);
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Base class for all clang-tidy checks.
const LangOptions & getLangOpts() const
Returns the language options from the context.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
static constexpr llvm::StringLiteral Name
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.