forked from OSchip/llvm-project
[libclang] Move implementation of functions for manipulation CXSourceLocations and CXSourceRanges into a separate file.
llvm-svn: 143370
This commit is contained in:
parent
05df460269
commit
4c4f08d555
|
@ -2752,232 +2752,6 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
|
|||
|
||||
} // end: extern "C"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CXSourceLocation and CXSourceRange Operations.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extern "C" {
|
||||
CXSourceLocation clang_getNullLocation() {
|
||||
CXSourceLocation Result = { { 0, 0 }, 0 };
|
||||
return Result;
|
||||
}
|
||||
|
||||
unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
|
||||
return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
|
||||
loc1.ptr_data[1] == loc2.ptr_data[1] &&
|
||||
loc1.int_data == loc2.int_data);
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getLocation(CXTranslationUnit tu,
|
||||
CXFile file,
|
||||
unsigned line,
|
||||
unsigned column) {
|
||||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
bool Logging = ::getenv("LIBCLANG_LOGGING");
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
const FileEntry *File = static_cast<const FileEntry *>(file);
|
||||
SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
|
||||
if (SLoc.isInvalid()) {
|
||||
if (Logging)
|
||||
llvm::errs() << "clang_getLocation(\"" << File->getName()
|
||||
<< "\", " << line << ", " << column << ") = invalid\n";
|
||||
return clang_getNullLocation();
|
||||
}
|
||||
|
||||
if (Logging)
|
||||
llvm::errs() << "clang_getLocation(\"" << File->getName()
|
||||
<< "\", " << line << ", " << column << ") = "
|
||||
<< SLoc.getRawEncoding() << "\n";
|
||||
|
||||
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
|
||||
CXFile file,
|
||||
unsigned offset) {
|
||||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
SourceLocation SLoc
|
||||
= CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
|
||||
if (SLoc.isInvalid()) return clang_getNullLocation();
|
||||
|
||||
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
|
||||
}
|
||||
|
||||
CXSourceRange clang_getNullRange() {
|
||||
CXSourceRange Result = { { 0, 0 }, 0, 0 };
|
||||
return Result;
|
||||
}
|
||||
|
||||
CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
|
||||
if (begin.ptr_data[0] != end.ptr_data[0] ||
|
||||
begin.ptr_data[1] != end.ptr_data[1])
|
||||
return clang_getNullRange();
|
||||
|
||||
CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
|
||||
begin.int_data, end.int_data };
|
||||
return Result;
|
||||
}
|
||||
|
||||
unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2)
|
||||
{
|
||||
return range1.ptr_data[0] == range2.ptr_data[0]
|
||||
&& range1.ptr_data[1] == range2.ptr_data[1]
|
||||
&& range1.begin_int_data == range2.begin_int_data
|
||||
&& range1.end_int_data == range2.end_int_data;
|
||||
}
|
||||
|
||||
int clang_Range_isNull(CXSourceRange range) {
|
||||
return clang_equalRanges(range, clang_getNullRange());
|
||||
}
|
||||
|
||||
} // end: extern "C"
|
||||
|
||||
static void createNullLocation(CXFile *file, unsigned *line,
|
||||
unsigned *column, unsigned *offset) {
|
||||
if (file)
|
||||
*file = 0;
|
||||
if (line)
|
||||
*line = 0;
|
||||
if (column)
|
||||
*column = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void clang_getExpansionLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid()) {
|
||||
createNullLocation(file, line, column, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
|
||||
|
||||
// Check that the FileID is invalid on the expansion location.
|
||||
// This can manifest in invalid code.
|
||||
FileID fileID = SM.getFileID(ExpansionLoc);
|
||||
bool Invalid = false;
|
||||
const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
|
||||
if (Invalid || !sloc.isFile()) {
|
||||
createNullLocation(file, line, column, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file)
|
||||
*file = (void *)SM.getFileEntryForSLocEntry(sloc);
|
||||
if (line)
|
||||
*line = SM.getExpansionLineNumber(ExpansionLoc);
|
||||
if (column)
|
||||
*column = SM.getExpansionColumnNumber(ExpansionLoc);
|
||||
if (offset)
|
||||
*offset = SM.getDecomposedLoc(ExpansionLoc).second;
|
||||
}
|
||||
|
||||
void clang_getPresumedLocation(CXSourceLocation location,
|
||||
CXString *filename,
|
||||
unsigned *line,
|
||||
unsigned *column) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid()) {
|
||||
if (filename)
|
||||
*filename = createCXString("");
|
||||
if (line)
|
||||
*line = 0;
|
||||
if (column)
|
||||
*column = 0;
|
||||
}
|
||||
else {
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
|
||||
|
||||
if (filename)
|
||||
*filename = createCXString(PreLoc.getFilename());
|
||||
if (line)
|
||||
*line = PreLoc.getLine();
|
||||
if (column)
|
||||
*column = PreLoc.getColumn();
|
||||
}
|
||||
}
|
||||
|
||||
void clang_getInstantiationLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
// Redirect to new API.
|
||||
clang_getExpansionLocation(location, file, line, column, offset);
|
||||
}
|
||||
|
||||
void clang_getSpellingLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid())
|
||||
return createNullLocation(file, line, column, offset);
|
||||
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
SourceLocation SpellLoc = Loc;
|
||||
if (SpellLoc.isMacroID()) {
|
||||
SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
|
||||
if (SimpleSpellingLoc.isFileID() &&
|
||||
SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
|
||||
SpellLoc = SimpleSpellingLoc;
|
||||
else
|
||||
SpellLoc = SM.getExpansionLoc(SpellLoc);
|
||||
}
|
||||
|
||||
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
|
||||
FileID FID = LocInfo.first;
|
||||
unsigned FileOffset = LocInfo.second;
|
||||
|
||||
if (FID.isInvalid())
|
||||
return createNullLocation(file, line, column, offset);
|
||||
|
||||
if (file)
|
||||
*file = (void *)SM.getFileEntryForID(FID);
|
||||
if (line)
|
||||
*line = SM.getLineNumber(FID, FileOffset);
|
||||
if (column)
|
||||
*column = SM.getColumnNumber(FID, FileOffset);
|
||||
if (offset)
|
||||
*offset = FileOffset;
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getRangeStart(CXSourceRange range) {
|
||||
CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
|
||||
range.begin_int_data };
|
||||
return Result;
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
|
||||
CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
|
||||
range.end_int_data };
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // end: extern "C"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CXFile Operations.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -29,6 +29,7 @@ set(SOURCES
|
|||
CIndexer.h
|
||||
CXCursor.cpp
|
||||
CXCursor.h
|
||||
CXSourceLocation.cpp
|
||||
CXSourceLocation.h
|
||||
CXStoredDiagnostic.cpp
|
||||
CXString.cpp
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
//===- CXSourceLocation.cpp - CXSourceLocations APIs ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines routines for manipulating CXSourceLocations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
|
||||
#include "CIndexer.h"
|
||||
#include "CXString.h"
|
||||
#include "CXSourceLocation.h"
|
||||
#include "CXTranslationUnit.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Basic construction and comparison of CXSourceLocations and CXSourceRanges.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extern "C" {
|
||||
|
||||
CXSourceLocation clang_getNullLocation() {
|
||||
CXSourceLocation Result = { { 0, 0 }, 0 };
|
||||
return Result;
|
||||
}
|
||||
|
||||
unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
|
||||
return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
|
||||
loc1.ptr_data[1] == loc2.ptr_data[1] &&
|
||||
loc1.int_data == loc2.int_data);
|
||||
}
|
||||
|
||||
CXSourceRange clang_getNullRange() {
|
||||
CXSourceRange Result = { { 0, 0 }, 0, 0 };
|
||||
return Result;
|
||||
}
|
||||
|
||||
CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
|
||||
if (begin.ptr_data[0] != end.ptr_data[0] ||
|
||||
begin.ptr_data[1] != end.ptr_data[1])
|
||||
return clang_getNullRange();
|
||||
|
||||
CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
|
||||
begin.int_data, end.int_data };
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2) {
|
||||
return range1.ptr_data[0] == range2.ptr_data[0]
|
||||
&& range1.ptr_data[1] == range2.ptr_data[1]
|
||||
&& range1.begin_int_data == range2.begin_int_data
|
||||
&& range1.end_int_data == range2.end_int_data;
|
||||
}
|
||||
|
||||
int clang_Range_isNull(CXSourceRange range) {
|
||||
return clang_equalRanges(range, clang_getNullRange());
|
||||
}
|
||||
|
||||
|
||||
CXSourceLocation clang_getRangeStart(CXSourceRange range) {
|
||||
CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
|
||||
range.begin_int_data };
|
||||
return Result;
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
|
||||
CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
|
||||
range.end_int_data };
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // end extern "C"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Getting CXSourceLocations and CXSourceRanges from a translation unit.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extern "C" {
|
||||
|
||||
CXSourceLocation clang_getLocation(CXTranslationUnit tu,
|
||||
CXFile file,
|
||||
unsigned line,
|
||||
unsigned column) {
|
||||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
bool Logging = ::getenv("LIBCLANG_LOGGING");
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
const FileEntry *File = static_cast<const FileEntry *>(file);
|
||||
SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
|
||||
if (SLoc.isInvalid()) {
|
||||
if (Logging)
|
||||
llvm::errs() << "clang_getLocation(\"" << File->getName()
|
||||
<< "\", " << line << ", " << column << ") = invalid\n";
|
||||
return clang_getNullLocation();
|
||||
}
|
||||
|
||||
if (Logging)
|
||||
llvm::errs() << "clang_getLocation(\"" << File->getName()
|
||||
<< "\", " << line << ", " << column << ") = "
|
||||
<< SLoc.getRawEncoding() << "\n";
|
||||
|
||||
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
|
||||
}
|
||||
|
||||
CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
|
||||
CXFile file,
|
||||
unsigned offset) {
|
||||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
|
||||
SourceLocation SLoc
|
||||
= CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
|
||||
|
||||
if (SLoc.isInvalid())
|
||||
return clang_getNullLocation();
|
||||
|
||||
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
|
||||
}
|
||||
|
||||
} // end extern "C"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Routines for expanding and manipulating CXSourceLocations, regardless
|
||||
// of their origin.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
static void createNullLocation(CXFile *file, unsigned *line,
|
||||
unsigned *column, unsigned *offset) {
|
||||
if (file)
|
||||
*file = 0;
|
||||
if (line)
|
||||
*line = 0;
|
||||
if (column)
|
||||
*column = 0;
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void clang_getExpansionLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid()) {
|
||||
createNullLocation(file, line, column, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
|
||||
|
||||
// Check that the FileID is invalid on the expansion location.
|
||||
// This can manifest in invalid code.
|
||||
FileID fileID = SM.getFileID(ExpansionLoc);
|
||||
bool Invalid = false;
|
||||
const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
|
||||
if (Invalid || !sloc.isFile()) {
|
||||
createNullLocation(file, line, column, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (file)
|
||||
*file = (void *)SM.getFileEntryForSLocEntry(sloc);
|
||||
if (line)
|
||||
*line = SM.getExpansionLineNumber(ExpansionLoc);
|
||||
if (column)
|
||||
*column = SM.getExpansionColumnNumber(ExpansionLoc);
|
||||
if (offset)
|
||||
*offset = SM.getDecomposedLoc(ExpansionLoc).second;
|
||||
}
|
||||
|
||||
void clang_getPresumedLocation(CXSourceLocation location,
|
||||
CXString *filename,
|
||||
unsigned *line,
|
||||
unsigned *column) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid()) {
|
||||
if (filename)
|
||||
*filename = createCXString("");
|
||||
if (line)
|
||||
*line = 0;
|
||||
if (column)
|
||||
*column = 0;
|
||||
}
|
||||
else {
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
|
||||
|
||||
if (filename)
|
||||
*filename = createCXString(PreLoc.getFilename());
|
||||
if (line)
|
||||
*line = PreLoc.getLine();
|
||||
if (column)
|
||||
*column = PreLoc.getColumn();
|
||||
}
|
||||
}
|
||||
|
||||
void clang_getInstantiationLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
// Redirect to new API.
|
||||
clang_getExpansionLocation(location, file, line, column, offset);
|
||||
}
|
||||
|
||||
void clang_getSpellingLocation(CXSourceLocation location,
|
||||
CXFile *file,
|
||||
unsigned *line,
|
||||
unsigned *column,
|
||||
unsigned *offset) {
|
||||
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
|
||||
|
||||
if (!location.ptr_data[0] || Loc.isInvalid())
|
||||
return createNullLocation(file, line, column, offset);
|
||||
|
||||
const SourceManager &SM =
|
||||
*static_cast<const SourceManager*>(location.ptr_data[0]);
|
||||
SourceLocation SpellLoc = Loc;
|
||||
if (SpellLoc.isMacroID()) {
|
||||
SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
|
||||
if (SimpleSpellingLoc.isFileID() &&
|
||||
SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
|
||||
SpellLoc = SimpleSpellingLoc;
|
||||
else
|
||||
SpellLoc = SM.getExpansionLoc(SpellLoc);
|
||||
}
|
||||
|
||||
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
|
||||
FileID FID = LocInfo.first;
|
||||
unsigned FileOffset = LocInfo.second;
|
||||
|
||||
if (FID.isInvalid())
|
||||
return createNullLocation(file, line, column, offset);
|
||||
|
||||
if (file)
|
||||
*file = (void *)SM.getFileEntryForID(FID);
|
||||
if (line)
|
||||
*line = SM.getLineNumber(FID, FileOffset);
|
||||
if (column)
|
||||
*column = SM.getColumnNumber(FID, FileOffset);
|
||||
if (offset)
|
||||
*offset = FileOffset;
|
||||
}
|
||||
|
||||
} // end extern "C"
|
||||
|
Loading…
Reference in New Issue