clang  19.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 
16 #include "clang/AST/ASTContext.h"
18 #include "clang/Basic/TokenKinds.h"
19 #include <optional>
20 
21 namespace clang {
22 namespace 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.
26 CharSourceRange 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.
33 template <typename T>
35  ASTContext &Context) {
36  return maybeExtendRange(CharSourceRange::getTokenRange(Node.getSourceRange()),
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.
52 StringRef getText(CharSourceRange Range, const ASTContext &Context);
53 
54 /// Returns the source-code text corresponding to \p Node.
55 template <typename T>
56 StringRef 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
83 template <typename T>
84 StringRef 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.
91 llvm::Error validateEditRange(const CharSourceRange &Range,
92  const SourceManager &SM);
93 
94 /// Determines whether \p Range is one that can be read from. If
95 /// `AllowSystemHeaders` is false, a range that falls within a system header
96 /// fails validation.
97 llvm::Error validateRange(const CharSourceRange &Range, const SourceManager &SM,
98  bool AllowSystemHeaders);
99 
100 /// Attempts to resolve the given range to one that can be edited by a rewrite;
101 /// generally, one that starts and ends within a particular file. If a value is
102 /// returned, it satisfies \c validateEditRange.
103 ///
104 /// If \c IncludeMacroExpansion is true, a limited set of cases involving source
105 /// locations in macro expansions is supported. For example, if we're looking to
106 /// rewrite the int literal 3 to 6, and we have the following definition:
107 /// #define DO_NOTHING(x) x
108 /// then
109 /// foo(DO_NOTHING(3))
110 /// will be rewritten to
111 /// foo(6)
112 std::optional<CharSourceRange>
113 getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
114  const LangOptions &LangOpts,
115  bool IncludeMacroExpansion = true);
116 inline std::optional<CharSourceRange>
117 getFileRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context,
118  bool IncludeMacroExpansion = true) {
119  return getFileRangeForEdit(EditRange, Context.getSourceManager(),
120  Context.getLangOpts(), IncludeMacroExpansion);
121 }
122 
123 /// Attempts to resolve the given range to one that starts and ends in a
124 /// particular file.
125 ///
126 /// If \c IncludeMacroExpansion is true, a limited set of cases involving source
127 /// locations in macro expansions is supported. For example, if we're looking to
128 /// get the range of the int literal 3, and we have the following definition:
129 /// #define DO_NOTHING(x) x
130 /// foo(DO_NOTHING(3))
131 /// the returned range will hold the source text `DO_NOTHING(3)`.
132 std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
133  const SourceManager &SM,
134  const LangOptions &LangOpts,
135  bool IncludeMacroExpansion);
136 inline std::optional<CharSourceRange>
137 getFileRange(const CharSourceRange &EditRange, const ASTContext &Context,
138  bool IncludeMacroExpansion) {
139  return getFileRange(EditRange, Context.getSourceManager(),
140  Context.getLangOpts(), IncludeMacroExpansion);
141 }
142 
143 } // namespace tooling
144 } // namespace clang
145 #endif // LLVM_CLANG_TOOLING_TRANSFORMER_SOURCECODE_H
Defines the clang::ASTContext interface.
DynTypedNode Node
#define SM(sm)
Definition: Cuda.cpp:83
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:185
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
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:174
llvm::Error validateRange(const CharSourceRange &Range, const SourceManager &SM, bool AllowSystemHeaders)
Determines whether Range is one that can be read from.
Definition: SourceCode.cpp:53
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:185
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:412
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T