clang: lib/Tooling/Syntax/ComputeReplacements.cpp Source File (original) (raw)
1
2
3
4
5
6
7
13#include "llvm/Support/Error.h"
14
15using namespace clang;
16
17namespace {
19 bool )>;
20
21void enumerateTokenSpans(const syntax::Tree *Root,
23 ProcessTokensFn Callback) {
25 Enumerator(const syntax::TokenBufferTokenManager &STM,
26 ProcessTokensFn Callback)
28 Callback(Callback) {}
29
30 void run(const syntax::Tree *Root) {
31 process(Root);
32
33 if (SpanBegin)
34 Callback(llvm::ArrayRef(SpanBegin, SpanEnd), SpanIsOriginal);
35 }
36
37 private:
38 void process(const syntax::Node *N) {
39 if (auto *T = dyn_castsyntax::Tree(N)) {
40 for (const auto *C = T->getFirstChild(); C != nullptr;
42 process(C);
43 return;
44 }
45
47 if (SpanEnd == STM.getToken(L->getTokenKey()) &&
48 SpanIsOriginal == L->isOriginal()) {
49
50 ++SpanEnd;
51 return;
52 }
53
54 if (SpanBegin)
55 Callback(llvm::ArrayRef(SpanBegin, SpanEnd), SpanIsOriginal);
56
57 SpanBegin = STM.getToken(L->getTokenKey());
58 SpanEnd = SpanBegin + 1;
59 SpanIsOriginal = L->isOriginal();
60 }
61
62 const syntax::TokenBufferTokenManager &STM;
63 const syntax::Token *SpanBegin;
64 const syntax::Token *SpanEnd;
65 bool SpanIsOriginal;
66 ProcessTokensFn Callback;
67 };
68
69 return Enumerator(STM, Callback).run(Root);
70}
71
76
77
78 assert(Buffer.expandedTokens().begin() <= Expanded.begin());
79 assert(Expanded.end() < Buffer.expandedTokens().end());
80
81 if (Expanded.empty())
82
84 SM, SM.getExpansionLoc(Expanded.begin()->location()), 0);
85
86 auto Spelled = Buffer.spelledForExpanded(Expanded);
87 assert(Spelled && "could not find spelled tokens for expanded");
89}
90}
91
94 const syntax::TranslationUnit &TU) {
97
99
100 std::string Replacement;
102 if (ReplacedRange.empty() && Replacement.empty())
103 return;
105 SM, rangeOfExpanded(TBTM, ReplacedRange).toCharRange(SM),
106 Replacement)));
107 Replacement = "";
108 };
109 const syntax::Token *NextOriginal = Buffer.expandedTokens().begin();
110 enumerateTokenSpans(
112 if (!IsOriginal) {
113 Replacement +=
115 return;
116 }
117 assert(NextOriginal <= Tokens.begin());
118
119 if (NextOriginal != Tokens.begin()) {
120
122 } else {
123
125 }
126 NextOriginal = Tokens.end();
127 });
128
129
131 llvm::ArrayRef(NextOriginal, Buffer.expandedTokens().drop_back().end()));
132
133 return Replacements;
134}
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
A TokenBuffer-powered token manager.
const syntax::Token * getToken(Key I) const
const TokenBuffer & tokenBuffer() const
SourceManager & sourceManager()
A token coming directly from a file or from a macro invocation.
FileRange range(const SourceManager &SM) const
Gets a range of this token.
A node that has children and represents a syntactic language construct.
tooling::Replacements computeReplacements(const TokenBufferTokenManager &TBTM, const syntax::TranslationUnit &TU)
Computes textual replacements required to mimic the tree modifications made to the syntax tree.
Definition ComputeReplacements.cpp:93
Stencil run(MatchConsumer< std::string > C)
Wraps a MatchConsumer in a Stencil, so that it can be used in a Stencil.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Enumerator
Enumerator value with fixed underlying type.
A half-open character range inside a particular file, the start offset is included and the end offset...
llvm::StringRef text(const SourceManager &SM) const
Gets the substring that this FileRange refers to.