clang-tools  10.0.0
CollectMacros.h
Go to the documentation of this file.
1 //===--- CollectMacros.h -----------------------------------------*- C++-*-===//
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 
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H
11 
12 #include "AST.h"
13 #include "Protocol.h"
14 #include "SourceCode.h"
15 #include "index/SymbolID.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Lex/PPCallbacks.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include <string>
20 
21 namespace clang {
22 namespace clangd {
23 
25  llvm::StringSet<> Names;
26  // Instead of storing SourceLocation, we have to store the token range because
27  // SourceManager from preamble is not available when we build the AST.
28  llvm::DenseMap<SymbolID, std::vector<Range>> MacroRefs;
29  // Somtimes it is not possible to compute the SymbolID for the Macro, e.g. a
30  // reference to an undefined macro. Store them separately, e.g. for semantic
31  // highlighting.
32  std::vector<Range> UnknownMacros;
33  // Ranges skipped by the preprocessor due to being inactive.
34  std::vector<Range> SkippedRanges;
35 };
36 
37 /// Collects macro references (e.g. definitions, expansions) in the main file.
38 /// It is used to:
39 /// - collect macros in the preamble section of the main file (in Preamble.cpp)
40 /// - collect macros after the preamble of the main file (in ParsedAST.cpp)
42 public:
43  explicit CollectMainFileMacros(const SourceManager &SM,
44  const LangOptions &LangOpts,
45  MainFileMacros &Out)
46  : SM(SM), LangOpts(LangOpts), Out(Out) {}
47 
48  void FileChanged(SourceLocation Loc, FileChangeReason,
49  SrcMgr::CharacteristicKind, FileID) override {
50  InMainFile = isInsideMainFile(Loc, SM);
51  }
52 
53  void MacroDefined(const Token &MacroName, const MacroDirective *MD) override {
54  add(MacroName, MD->getMacroInfo());
55  }
56 
57  void MacroExpands(const Token &MacroName, const MacroDefinition &MD,
58  SourceRange Range, const MacroArgs *Args) override {
59  add(MacroName, MD.getMacroInfo());
60  }
61 
62  void MacroUndefined(const clang::Token &MacroName,
63  const clang::MacroDefinition &MD,
64  const clang::MacroDirective *Undef) override {
65  add(MacroName, MD.getMacroInfo());
66  }
67 
68  void Ifdef(SourceLocation Loc, const Token &MacroName,
69  const MacroDefinition &MD) override {
70  add(MacroName, MD.getMacroInfo());
71  }
72 
73  void Ifndef(SourceLocation Loc, const Token &MacroName,
74  const MacroDefinition &MD) override {
75  add(MacroName, MD.getMacroInfo());
76  }
77 
78  void Defined(const Token &MacroName, const MacroDefinition &MD,
79  SourceRange Range) override {
80  add(MacroName, MD.getMacroInfo());
81  }
82 
83  void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override {
84  if (!InMainFile)
85  return;
86  Position Begin = sourceLocToPosition(SM, R.getBegin());
87  Position End = sourceLocToPosition(SM, R.getEnd());
88  Out.SkippedRanges.push_back(Range{Begin, End});
89  }
90 
91 private:
92  void add(const Token &MacroNameTok, const MacroInfo *MI) {
93  if (!InMainFile)
94  return;
95  auto Loc = MacroNameTok.getLocation();
96  if (Loc.isMacroID())
97  return;
98 
99  if (auto Range = getTokenRange(SM, LangOpts, Loc)) {
100  auto Name = MacroNameTok.getIdentifierInfo()->getName();
101  Out.Names.insert(Name);
102  if (auto SID = getSymbolID(Name, MI, SM))
103  Out.MacroRefs[*SID].push_back(*Range);
104  else
105  Out.UnknownMacros.push_back(*Range);
106  }
107  }
108  const SourceManager &SM;
109  const LangOptions &LangOpts;
110  bool InMainFile = true;
111  MainFileMacros &Out;
112 };
113 
114 } // namespace clangd
115 } // namespace clang
116 
117 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTEDMACROS_H
SourceLocation Loc
&#39;#&#39; location in the include directive
std::vector< Range > SkippedRanges
Definition: CollectMacros.h:34
void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override
Definition: CollectMacros.h:83
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
Definition: AST.cpp:286
Collects macro references (e.g.
Definition: CollectMacros.h:41
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Definition: SourceCode.cpp:534
void Ifdef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
Definition: CollectMacros.h:68
void Defined(const Token &MacroName, const MacroDefinition &MD, SourceRange Range) override
Definition: CollectMacros.h:78
void Ifndef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
Definition: CollectMacros.h:73
std::vector< Range > UnknownMacros
Definition: CollectMacros.h:32
llvm::DenseMap< SymbolID, std::vector< Range > > MacroRefs
Definition: CollectMacros.h:28
void MacroUndefined(const clang::Token &MacroName, const clang::MacroDefinition &MD, const clang::MacroDirective *Undef) override
Definition: CollectMacros.h:62
void FileChanged(SourceLocation Loc, FileChangeReason, SrcMgr::CharacteristicKind, FileID) override
Definition: CollectMacros.h:48
void MacroDefined(const Token &MacroName, const MacroDirective *MD) override
Definition: CollectMacros.h:53
static constexpr llvm::StringLiteral Name
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
Definition: SourceCode.cpp:227
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:200
void MacroExpands(const Token &MacroName, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
Definition: CollectMacros.h:57
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
CollectMainFileMacros(const SourceManager &SM, const LangOptions &LangOpts, MainFileMacros &Out)
Definition: CollectMacros.h:43