CIndex: Stop hiding magic end bit in CXSourceRange locations where clients can't

see it. Instead, translate the locations up-front when we create a
CXSourceRange.
 - This is part of a move to make CXSourceRange a pure half-open range, which is
   a more natural API for clients to deal with. More cleanups to follow.

llvm-svn: 96144
This commit is contained in:
Daniel Dunbar 2010-02-14 01:47:29 +00:00
parent 3e255dae88
commit 474b207716
2 changed files with 54 additions and 36 deletions

View File

@ -146,6 +146,51 @@ static RangeComparisonResult RangeCompare(SourceManager &SM,
return RangeOverlap;
}
/// \brief Translate a Clang source range into a CIndex source range.
///
/// Clang internally represents ranges where the end location points to the
/// start of the token at the end. However, for external clients it is more
/// useful to have a CXSourceRange be a proper half-open interval. This routine
/// does the appropriate translation.
CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
const LangOptions &LangOpts,
SourceRange R) {
// FIXME: This is largely copy-paste from
// TextDiagnosticPrinter::HighlightRange. When it is clear that this is what
// we want the two routines should be refactored.
// We want the last character in this location, so we will adjust the
// instantiation location accordingly.
// If the location is from a macro instantiation, get the end of the
// instantiation range.
SourceLocation EndLoc = R.getEnd();
SourceLocation InstLoc = SM.getInstantiationLoc(EndLoc);
if (EndLoc.isMacroID())
InstLoc = SM.getInstantiationRange(EndLoc).second;
// Measure the length token we're pointing at, so we can adjust the physical
// location in the file to point at the last character.
//
// FIXME: This won't cope with trigraphs or escaped newlines well. For that,
// we actually need a preprocessor, which isn't currently available
// here. Eventually, we'll switch the pointer data of
// CXSourceLocation/CXSourceRange to a translation unit (CXXUnit), so that the
// preprocessor will be available here. At that point, we can use
// Preprocessor::getLocForEndOfToken().
if (InstLoc.isValid()) {
unsigned Length = Lexer::MeasureTokenLength(InstLoc, SM, LangOpts);
// FIXME: Temporarily represent as closed range to preserve API
// compatibility.
if (Length) --Length;
EndLoc = EndLoc.getFileLocWithOffset(Length);
}
CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
R.getBegin().getRawEncoding(),
EndLoc.getRawEncoding() };
return Result;
}
//===----------------------------------------------------------------------===//
// Cursor visitor.
@ -1195,35 +1240,8 @@ void clang_getInstantiationLocation(CXSourceLocation location,
return;
}
// FIXME: This is largely copy-paste from
///TextDiagnosticPrinter::HighlightRange. When it is clear that this is
// what we want the two routines should be refactored.
const SourceManager &SM = *Ptr.getPointer();
SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
if (Ptr.getInt()) {
// We want the last character in this location, so we will adjust
// the instantiation location accordingly.
// If the location is from a macro instantiation, get the end of
// the instantiation range.
if (Loc.isMacroID())
InstLoc = SM.getInstantiationRange(Loc).second;
// Measure the length token we're pointing at, so we can adjust
// the physical location in the file to point at the last
// character.
// FIXME: This won't cope with trigraphs or escaped newlines
// well. For that, we actually need a preprocessor, which isn't
// currently available here. Eventually, we'll switch the pointer
// data of CXSourceLocation/CXSourceRange to a translation unit
// (CXXUnit), so that the preprocessor will be available here. At
// that point, we can use Preprocessor::getLocForEndOfToken().
unsigned Length = Lexer::MeasureTokenLength(InstLoc, SM,
*static_cast<LangOptions *>(location.ptr_data[1]));
if (Length > 0)
InstLoc = InstLoc.getFileLocWithOffset(Length - 1);
}
if (file)
*file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc));

View File

@ -1,4 +1,4 @@
//===- CXSourceLocation.h - Routines for manipulating CXSourceLocations ---===//
//===- CXSourceLocation.h - CXSourceLocations Utilities ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -49,14 +49,14 @@ static inline CXSourceLocation translateSourceLocation(ASTContext &Context,
}
/// \brief Translate a Clang source range into a CIndex source range.
static inline CXSourceRange translateSourceRange(const SourceManager &SM,
const LangOptions &LangOpts,
SourceRange R) {
CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
R.getBegin().getRawEncoding(),
R.getEnd().getRawEncoding() };
return Result;
}
///
/// Clang internally represents ranges where the end location points to the
/// start of the token at the end. However, for external clients it is more
/// useful to have a CXSourceRange be a proper half-open interval. This routine
/// does the appropriate translation.
CXSourceRange translateSourceRange(const SourceManager &SM,
const LangOptions &LangOpts,
SourceRange R);
/// \brief Translate a Clang source range into a CIndex source range.
static inline CXSourceRange translateSourceRange(ASTContext &Context,