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
24 struct MainFileMacros {
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)
41 class CollectMainFileMacros : public PPCallbacks {
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
Loc
SourceLocation Loc
&#39;#&#39; location in the include directive
Definition: IncludeOrderCheck.cpp:37
clang::clangd::MainFileMacros::SkippedRanges
std::vector< Range > SkippedRanges
Definition: CollectMacros.h:34
AST.h
clang::clangd::CollectMainFileMacros::SourceRangeSkipped
void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override
Definition: CollectMacros.h:83
clang::clangd::getSymbolID
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
Definition: AST.cpp:286
clang::clangd::CollectMainFileMacros
Collects macro references (e.g.
Definition: CollectMacros.h:41
SourceCode.h
clang::clangd::isInsideMainFile
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
Definition: SourceCode.cpp:534
Protocol.h
clang::clangd::Position
Definition: Protocol.h:127
clang::clangd::CollectMainFileMacros::Ifdef
void Ifdef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
Definition: CollectMacros.h:68
clang::clangd::CollectMainFileMacros::Defined
void Defined(const Token &MacroName, const MacroDefinition &MD, SourceRange Range) override
Definition: CollectMacros.h:78
clang::clangd::MainFileMacros
Definition: CollectMacros.h:24
clang::clangd::CollectMainFileMacros::Ifndef
void Ifndef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
Definition: CollectMacros.h:73
clang::clangd::MainFileMacros::UnknownMacros
std::vector< Range > UnknownMacros
Definition: CollectMacros.h:32
clang::clangd::MainFileMacros::MacroRefs
llvm::DenseMap< SymbolID, std::vector< Range > > MacroRefs
Definition: CollectMacros.h:28
clang::clangd::Range
Definition: Protocol.h:156
clang::clangd::CollectMainFileMacros::MacroUndefined
void MacroUndefined(const clang::Token &MacroName, const clang::MacroDefinition &MD, const clang::MacroDirective *Undef) override
Definition: CollectMacros.h:62
clang::clangd::CollectMainFileMacros::FileChanged
void FileChanged(SourceLocation Loc, FileChangeReason, SrcMgr::CharacteristicKind, FileID) override
Definition: CollectMacros.h:48
clang::clangd::CollectMainFileMacros::MacroDefined
void MacroDefined(const Token &MacroName, const MacroDirective *MD) override
Definition: CollectMacros.h:53
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:27
clang::clangd::getTokenRange
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
Definition: SourceCode.cpp:227
clang::clangd::sourceLocToPosition
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
Definition: SourceCode.cpp:200
PPCallbacks
clang::clangd::CollectMainFileMacros::MacroExpands
void MacroExpands(const Token &MacroName, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
Definition: CollectMacros.h:57
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::doc::MD
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
clang::clangd::CollectMainFileMacros::CollectMainFileMacros
CollectMainFileMacros(const SourceManager &SM, const LangOptions &LangOpts, MainFileMacros &Out)
Definition: CollectMacros.h:43
clang::clangd::MainFileMacros::Names
llvm::StringSet Names
Definition: CollectMacros.h:25
SymbolID.h