blob: ba7425bf88c65cc9b340dfe9d5d5096e43981703 [file] [log] [blame]
//===--- SourceLocationUtilities.h - Source location helper functions -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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