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;

41 C = C->getNextSibling())

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.