clang-tools  11.0.0
ReplaceDisallowCopyAndAssignMacroCheck.cpp
Go to the documentation of this file.
1 //===--- ReplaceDisallowCopyAndAssignMacroCheck.cpp - clang-tidy ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/Frontend/CompilerInstance.h"
11 #include "clang/Lex/MacroArgs.h"
12 #include "clang/Lex/PPCallbacks.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "llvm/Support/FormatVariadic.h"
15 
16 namespace clang {
17 namespace tidy {
18 namespace modernize {
19 
20 namespace {
21 
22 class ReplaceDisallowCopyAndAssignMacroCallbacks : public PPCallbacks {
23 public:
24  explicit ReplaceDisallowCopyAndAssignMacroCallbacks(
25  ReplaceDisallowCopyAndAssignMacroCheck &Check, Preprocessor &PP)
26  : Check(Check), PP(PP) {}
27 
28  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
29  SourceRange Range, const MacroArgs *Args) override {
30  IdentifierInfo *Info = MacroNameTok.getIdentifierInfo();
31  if (!Info || !Args || Args->getNumMacroArguments() != 1)
32  return;
33  if (Info->getName() != Check.getMacroName())
34  return;
35  // The first argument to the DISALLOW_COPY_AND_ASSIGN macro is exptected to
36  // be the class name.
37  const Token *ClassNameTok = Args->getUnexpArgument(0);
38  if (Args->ArgNeedsPreexpansion(ClassNameTok, PP))
39  // For now we only support simple argument that don't need to be
40  // pre-expanded.
41  return;
42  clang::IdentifierInfo *ClassIdent = ClassNameTok->getIdentifierInfo();
43  if (!ClassIdent)
44  return;
45 
46  std::string Replacement = llvm::formatv(
47  R"cpp({0}(const {0} &) = delete;
48 const {0} &operator=(const {0} &) = delete{1})cpp",
49  ClassIdent->getName(), shouldAppendSemi(Range) ? ";" : "");
50 
51  Check.diag(MacroNameTok.getLocation(),
52  "prefer deleting copy constructor and assignment operator over "
53  "using macro '%0'")
54  << Check.getMacroName()
55  << FixItHint::CreateReplacement(
56  PP.getSourceManager().getExpansionRange(Range), Replacement);
57  }
58 
59 private:
60  /// \returns \c true if the next token after the given \p MacroLoc is \b not a
61  /// semicolon.
62  bool shouldAppendSemi(SourceRange MacroLoc) {
63  llvm::Optional<Token> Next = Lexer::findNextToken(
64  MacroLoc.getEnd(), PP.getSourceManager(), PP.getLangOpts());
65  return !(Next && Next->is(tok::semi));
66  }
67 
68  ReplaceDisallowCopyAndAssignMacroCheck &Check;
69  Preprocessor &PP;
70 };
71 } // namespace
72 
74  StringRef Name, ClangTidyContext *Context)
75  : ClangTidyCheck(Name, Context),
76  MacroName(Options.get("MacroName", "DISALLOW_COPY_AND_ASSIGN")) {}
77 
79  const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
80  PP->addPPCallbacks(
81  ::std::make_unique<ReplaceDisallowCopyAndAssignMacroCallbacks>(
82  *this, *ModuleExpanderPP));
83 }
84 
87  Options.store(Opts, "MacroName", MacroName);
88 }
89 
90 } // namespace modernize
91 } // namespace tidy
92 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
clang::doc::MD
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
ReplaceDisallowCopyAndAssignMacroCheck.h
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:114
clang::tidy::modernize::ReplaceDisallowCopyAndAssignMacroCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
Definition: ReplaceDisallowCopyAndAssignMacroCheck.cpp:85
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:471
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:76
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:27
clang::tidy::modernize::ReplaceDisallowCopyAndAssignMacroCheck::registerPPCallbacks
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override
Override this to register PPCallbacks in the preprocessor.
Definition: ReplaceDisallowCopyAndAssignMacroCheck.cpp:78
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:120
PPCallbacks
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::ClangTidyCheck::OptionsView::store
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Definition: ClangTidyCheck.cpp:152
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:111
clang::tidy::modernize::ReplaceDisallowCopyAndAssignMacroCheck::ReplaceDisallowCopyAndAssignMacroCheck
ReplaceDisallowCopyAndAssignMacroCheck(StringRef Name, ClangTidyContext *Context)
Definition: ReplaceDisallowCopyAndAssignMacroCheck.cpp:73