clang-tools 20.0.0git
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_COLLECTMACROS_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTMACROS_H
11
12#include "Protocol.h"
13#include "SourceCode.h"
14#include "index/SymbolID.h"
15#include "clang/Basic/SourceLocation.h"
16#include "clang/Lex/PPCallbacks.h"
17#include "clang/Lex/Preprocessor.h"
18#include "llvm/ADT/DenseMap.h"
19#include <cstddef>
20#include <string>
21
22namespace clang {
23namespace clangd {
24
26 // Half-open range (end offset is exclusive) inside the main file.
28 size_t EndOffset;
29
31 // True if the occurence is used in a conditional directive, e.g. #ifdef MACRO
33
34 Range toRange(const SourceManager &SM) const;
35};
36
38 llvm::StringSet<> Names;
39 llvm::DenseMap<SymbolID, std::vector<MacroOccurrence>> MacroRefs;
40 // Somtimes it is not possible to compute the SymbolID for the Macro, e.g. a
41 // reference to an undefined macro. Store them separately, e.g. for semantic
42 // highlighting.
43 std::vector<MacroOccurrence> UnknownMacros;
44 // Ranges skipped by the preprocessor due to being inactive.
45 std::vector<Range> SkippedRanges;
46};
47
48/// Collects macro references (e.g. definitions, expansions) in the main file.
49/// It is used to:
50/// - collect macros in the preamble section of the main file (in Preamble.cpp)
51/// - collect macros after the preamble of the main file (in ParsedAST.cpp)
53public:
54 explicit CollectMainFileMacros(const Preprocessor &PP, MainFileMacros &Out)
55 : SM(PP.getSourceManager()), PP(PP), Out(Out) {}
56
57 void FileChanged(SourceLocation Loc, FileChangeReason,
58 SrcMgr::CharacteristicKind, FileID) override;
59
60 void MacroDefined(const Token &MacroName, const MacroDirective *MD) override;
61
62 void MacroExpands(const Token &MacroName, const MacroDefinition &MD,
63 SourceRange Range, const MacroArgs *Args) override;
64
65 void MacroUndefined(const clang::Token &MacroName,
66 const clang::MacroDefinition &MD,
67 const clang::MacroDirective *Undef) override;
68
69 void Ifdef(SourceLocation Loc, const Token &MacroName,
70 const MacroDefinition &MD) override;
71 void Ifndef(SourceLocation Loc, const Token &MacroName,
72 const MacroDefinition &MD) override;
73 using PPCallbacks::Elifdef;
74 using PPCallbacks::Elifndef;
75 void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
76 const MacroDefinition &MD) override;
77 void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
78 const MacroDefinition &MD) override;
79
80 void Defined(const Token &MacroName, const MacroDefinition &MD,
81 SourceRange Range) override;
82
83 void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override;
84
85 // Called when the AST build is done to disable further recording
86 // of macros by this class. This is needed because some clang-tidy
87 // checks can trigger PP callbacks by calling directly into the
88 // preprocessor. Such calls are not interleaved with FileChanged()
89 // in the expected way, leading this class to erroneously process
90 // macros that are not in the main file.
91 void doneParse() { InMainFile = false; }
92
93private:
94 void add(const Token &MacroNameTok, const MacroInfo *MI,
95 bool IsDefinition = false, bool InConditionalDirective = false);
96 const SourceManager &SM;
97 const Preprocessor &PP;
98 bool InMainFile = true;
99 MainFileMacros &Out;
100};
101
102/// Represents a `#pragma mark` in the main file.
103///
104/// There can be at most one pragma mark per line.
107 std::string Trivia;
108};
109
110/// Collect all pragma marks from the main file.
111std::unique_ptr<PPCallbacks>
112collectPragmaMarksCallback(const SourceManager &, std::vector<PragmaMark> &Out);
113
114} // namespace clangd
115} // namespace clang
116
117#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_COLLECTMACROS_H
CompiledFragmentImpl & Out
SourceLocation Loc
std::string MacroName
Definition: Preamble.cpp:240
llvm::json::Object Args
Definition: Trace.cpp:138
Collects macro references (e.g.
Definition: CollectMacros.h:52
void MacroDefined(const Token &MacroName, const MacroDirective *MD) override
void FileChanged(SourceLocation Loc, FileChangeReason, SrcMgr::CharacteristicKind, FileID) override
void MacroExpands(const Token &MacroName, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override
CollectMainFileMacros(const Preprocessor &PP, MainFileMacros &Out)
Definition: CollectMacros.h:54
void Elifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
void Defined(const Token &MacroName, const MacroDefinition &MD, SourceRange Range) override
void MacroUndefined(const clang::Token &MacroName, const clang::MacroDefinition &MD, const clang::MacroDirective *Undef) override
void Ifndef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
void SourceRangeSkipped(SourceRange R, SourceLocation EndifLoc) override
void Ifdef(SourceLocation Loc, const Token &MacroName, const MacroDefinition &MD) override
void Elifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) override
std::unique_ptr< PPCallbacks > collectPragmaMarksCallback(const SourceManager &SM, std::vector< PragmaMark > &Out)
Collect all pragma marks from the main file.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Range toRange(const SourceManager &SM) const
std::vector< MacroOccurrence > UnknownMacros
Definition: CollectMacros.h:43
llvm::DenseMap< SymbolID, std::vector< MacroOccurrence > > MacroRefs
Definition: CollectMacros.h:39
std::vector< Range > SkippedRanges
Definition: CollectMacros.h:45
Represents a #pragma mark in the main file.
A single C++ or preprocessor token.
Definition: support/Token.h:50