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
|