File: SourceLocationUtilities.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (173 lines) | stat: -rw-r--r-- 7,277 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//===--- SourceLocationUtilities.h - Source location helper functions -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H
#define LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H

#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"

namespace clang {

class Stmt;
class LangOptions;

namespace tooling {

inline bool isPairOfFileLocations(SourceLocation Start, SourceLocation End) {
  return Start.isValid() && Start.isFileID() && End.isValid() && End.isFileID();
}

/// Return true if the Point is within Start and End.
inline bool isPointWithin(SourceLocation Location, SourceLocation Start,
                          SourceLocation End, const SourceManager &SM) {
  return Location == Start || Location == End ||
         (SM.isBeforeInTranslationUnit(Start, Location) &&
          SM.isBeforeInTranslationUnit(Location, End));
}

/// Return true if the two given ranges overlap with each other.
inline bool areRangesOverlapping(SourceRange R1, SourceRange R2,
                                 const SourceManager &SM) {
  return isPointWithin(R1.getBegin(), R2.getBegin(), R2.getEnd(), SM) ||
         isPointWithin(R2.getBegin(), R1.getBegin(), R1.getEnd(), SM);
}

/// \brief Return the source location that can be considered the last location
/// of the source construct before its body.
///
/// The returned location is determined using the following rules:
///
/// 1) If the source construct has a compound body that starts on the same line,
///    then this function will return the location of the opening '{'.
///
///    if (condition) {
///                   ^
///
/// 2) If the source construct's body is not a compound statement that starts
///    on the same line, then this function will return the location just before
///    the starting location of the body.
///
///    if (condition) foo()
///                  ^
///
/// 3) Otherwise, this function will return the last location on the line prior
///    to the the line on which the body starts.
///
///    if (condition)
///                  ^
///      foo()
///
/// \param HeaderEnd The last known location of the pre-body portion of the
/// source construct. For example, for an if statement, HeaderEnd should
/// be the ending location of its conditional expression.
SourceLocation findLastLocationOfSourceConstruct(SourceLocation HeaderEnd,
                                                 const Stmt *Body,
                                                 const SourceManager &SM);

/// \brief Return the source location that can be considered the first location
/// of the source construct prior to the previous portion of its body.
///
/// The returned location is determined using the following rules:
///
/// 1) If the source construct's body is a compound statement that ends
///    on the same line, then this function will return the location of the
///    closing '}'.
///
///    } else if (condition)
///    ^
///
/// 2) Otherwise, this function will return the starting location of the source
///    construct.
///
///      foo();
///    else if (condition)
///    ^
///
///    }
///    else if (condition)
///    ^
///
/// \param HeaderStart The first known location of the post-body portion of the
/// source construct. For example, for an if statement, HeaderStart should
/// be the starting location of the if keyword.
SourceLocation findFirstLocationOfSourceConstruct(SourceLocation HeaderStart,
                                                  const Stmt *PreviousBody,
                                                  const SourceManager &SM);

/// Return true if the given \p Location is within any range.
bool isLocationInAnyRange(SourceLocation Location, ArrayRef<SourceRange> Ranges,
                          const SourceManager &SM);

/// Return the precise end location for the given token.
SourceLocation getPreciseTokenLocEnd(SourceLocation Loc,
                                     const SourceManager &SM,
                                     const LangOptions &LangOpts);

/// \brief Find the source location right after the location of the next ')'.
///
/// If the token that's located after \p LastKnownLoc isn't ')', then this
/// function returns an invalid source location.
SourceLocation findClosingParenLocEnd(SourceLocation LastKnownLoc,
                                      const SourceManager &SM,
                                      const LangOptions &LangOpts);

/// Return the range of the next token if it has the given kind.
SourceRange getRangeOfNextToken(SourceLocation Loc, tok::TokenKind Kind,
                                const SourceManager &SM,
                                const LangOptions &LangOpts);

/// Return the end location of the body when \p S is a compound statement or an
/// invalid location when \p S is an empty compound statement. Otherwise,
/// return the end location of the given statement \p S.
SourceLocation findLastNonCompoundLocation(const Stmt *S);

/// Return true if the two locations are on the same line and aren't
///  macro locations.
bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
                   const SourceManager &SM);

/// Return the last location of the line which contains the given spellling
/// location \p SpellingLoc unless that line has other tokens after the given
/// location.
SourceLocation
getLastLineLocationUnlessItHasOtherTokens(SourceLocation SpellingLoc,
                                          const SourceManager &SM,
                                          const LangOptions &LangOpts);

/// Return true if the token at the given location is a semicolon.
bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager &SM,
                           const LangOptions &LangOpts);

/// Shrink the given range by ignoring leading whitespace and trailing
/// whitespace and semicolons.
///
/// Returns an invalid source range if the source range consists of whitespace
/// or semicolons only.
SourceRange trimSelectionRange(SourceRange Range, const SourceManager &SM,
                               const LangOptions &LangOpts);

/// Return the source location of the conjoined comment(s) that precede the
/// given location \p Loc, or the same location if there's no comment before
/// \p Loc.
SourceLocation getLocationOfPrecedingComment(SourceLocation Loc,
                                             const SourceManager &SM,
                                             const LangOptions &LangOpts);

/// Return the source location of the token that comes before the token at the
/// given location.
SourceLocation getLocationOfPrecedingToken(SourceLocation Loc,
                                           const SourceManager &SM,
                                           const LangOptions &LangOpts);

} // end namespace tooling
} // end namespace clang

#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H