clang 17.0.0git
SourceCode.h
Go to the documentation of this file.
1//===--- SourceCode.h - Source code manipulation routines -------*- 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// This file provides functions that simplify extraction of source code.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
14#define LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
15
19#include <optional>
20
21namespace clang {
22namespace tooling {
23
24/// Extends \p Range to include the token \p Terminator, if it immediately
25/// follows the end of the range. Otherwise, returns \p Range unchanged.
26CharSourceRange maybeExtendRange(CharSourceRange Range,
27 tok::TokenKind Terminator,
28 ASTContext &Context);
29
30/// Returns the source range spanning the node, extended to include \p Next, if
31/// it immediately follows \p Node. Otherwise, returns the normal range of \p
32/// Node. See comments on `getExtendedText()` for examples.
33template <typename T>
35 ASTContext &Context) {
37 Next, Context);
38}
39
40/// Returns the logical source range of the node extended to include associated
41/// comments and whitespace before and after the node, and associated
42/// terminators. The returned range consists of file locations, if valid file
43/// locations can be found for the associated content; otherwise, an invalid
44/// range is returned.
45///
46/// Note that parsing comments is disabled by default. In order to select a
47/// range containing associated comments, you may need to invoke the tool with
48/// `-fparse-all-comments`.
50
51/// Returns the source-code text in the specified range.
52StringRef getText(CharSourceRange Range, const ASTContext &Context);
53
54/// Returns the source-code text corresponding to \p Node.
55template <typename T>
56StringRef getText(const T &Node, const ASTContext &Context) {
57 return getText(CharSourceRange::getTokenRange(Node.getSourceRange()),
58 Context);
59}
60
61/// Returns the source text of the node, extended to include \p Next, if it
62/// immediately follows the node. Otherwise, returns the text of just \p Node.
63///
64/// For example, given statements S1 and S2 below:
65/// \code
66/// {
67/// // S1:
68/// if (!x) return foo();
69/// // S2:
70/// if (!x) { return 3; }
71/// }
72/// \endcode
73/// then
74/// \code
75/// getText(S1, Context) = "if (!x) return foo()"
76/// getExtendedText(S1, tok::TokenKind::semi, Context)
77/// = "if (!x) return foo();"
78/// getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context)
79/// = "return foo();"
80/// getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context)
81/// = getText(S2, Context) = "{ return 3; }"
82/// \endcode
83template <typename T>
84StringRef getExtendedText(const T &Node, tok::TokenKind Next,
85 ASTContext &Context) {
86 return getText(getExtendedRange(Node, Next, Context), Context);
87}
88
89/// Determines whether \p Range is one that can be edited by a rewrite;
90/// generally, one that starts and ends within a particular file.
91llvm::Error validateEditRange(const CharSourceRange &Range,
92 const SourceManager &SM);
93
94/// Attempts to resolve the given range to one that can be edited by a rewrite;
95/// generally, one that starts and ends within a particular file. If a value is
96/// returned, it satisfies \c validateEditRange.
97///
98/// If \c IncludeMacroExpansion is true, a limited set of cases involving source
99/// locations in macro expansions is supported. For example, if we're looking to
100/// rewrite the int literal 3 to 6, and we have the following definition:
101/// #define DO_NOTHING(x) x
102/// then
103/// foo(DO_NOTHING(3))
104/// will be rewritten to
105/// foo(6)
106std::optional<CharSourceRange>
107getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
108 const LangOptions &LangOpts,
109 bool IncludeMacroExpansion = true);
110inline std::optional<CharSourceRange>
111getFileRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context,
112 bool IncludeMacroExpansion = true) {
113 return getFileRangeForEdit(EditRange, Context.getSourceManager(),
114 Context.getLangOpts(), IncludeMacroExpansion);
115}
116
117/// Attempts to resolve the given range to one that starts and ends in a
118/// particular file.
119///
120/// If \c IncludeMacroExpansion is true, a limited set of cases involving source
121/// locations in macro expansions is supported. For example, if we're looking to
122/// get the range of the int literal 3, and we have the following definition:
123/// #define DO_NOTHING(x) x
124/// foo(DO_NOTHING(3))
125/// the returned range will hold the source text `DO_NOTHING(3)`.
126std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
127 const SourceManager &SM,
128 const LangOptions &LangOpts,
129 bool IncludeMacroExpansion);
130inline std::optional<CharSourceRange>
131getFileRange(const CharSourceRange &EditRange, const ASTContext &Context,
132 bool IncludeMacroExpansion) {
133 return getFileRange(EditRange, Context.getSourceManager(),
134 Context.getLangOpts(), IncludeMacroExpansion);
135}
136
137} // namespace tooling
138} // namespace clang
139#endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
Defines the clang::ASTContext interface.
DynTypedNode Node
#define SM(sm)
Definition: Cuda.cpp:78
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TokenKind enum and support functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
This class handles loading and caching of source files into memory.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next, ASTContext &Context)
Returns the source range spanning the node, extended to include Next, if it immediately follows Node.
Definition: SourceCode.h:34
StringRef getExtendedText(const T &Node, tok::TokenKind Next, ASTContext &Context)
Returns the source text of the node, extended to include Next, if it immediately follows the node.
Definition: SourceCode.h:84
std::optional< CharSourceRange > getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion=true)
Attempts to resolve the given range to one that can be edited by a rewrite; generally,...
Definition: SourceCode.cpp:125
llvm::Error validateEditRange(const CharSourceRange &Range, const SourceManager &SM)
Determines whether Range is one that can be edited by a rewrite; generally, one that starts and ends ...
Definition: SourceCode.cpp:84
std::optional< CharSourceRange > getFileRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
Attempts to resolve the given range to one that starts and ends in a particular file.
Definition: SourceCode.cpp:136
CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Terminator, ASTContext &Context)
Extends Range to include the token Terminator, if it immediately follows the end of the range.
Definition: SourceCode.cpp:37
StringRef getText(CharSourceRange Range, const ASTContext &Context)
Returns the source-code text in the specified range.
Definition: SourceCode.cpp:31
CharSourceRange getAssociatedRange(const Decl &D, ASTContext &Context)
Returns the logical source range of the node extended to include associated comments and whitespace b...
Definition: SourceCode.cpp:363