Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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"
17
#include "clang/Basic/SourceLocation.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>
34
CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
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`.
49
CharSourceRange getAssociatedRange(const Decl &D, ASTContext &Context);
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
/// 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)
106
std::optional<CharSourceRange>
107
getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
108
                    const LangOptions &LangOpts,
109
                    bool IncludeMacroExpansion = true);
110
inline std::optional<CharSourceRange>
111
getFileRangeForEdit(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)`.
126
std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
127
                                            const SourceManager &SM,
128
                                            const LangOptions &LangOpts,
129
                                            bool IncludeMacroExpansion);
130
inline std::optional<CharSourceRange>
131
getFileRange(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