From: Ted Kremenek Date: Mon, 31 Oct 2011 22:05:42 +0000 (+0000) Subject: [libclang] Move implementation of functions for manipulation CXSourceLocations and... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3ddef060a94434e6b71b58348e730c4464efbc48;p=clang [libclang] Move implementation of functions for manipulation CXSourceLocations and CXSourceRanges into a separate file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143370 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 8981226cbb..f028aa6124 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -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(tu->TUData); - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - const FileEntry *File = static_cast(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(tu->TUData); - SourceLocation SLoc - = CXXUnit->getLocation(static_cast(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(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(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(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 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. //===----------------------------------------------------------------------===// diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index 6f62d236ee..e4a5527112 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -29,6 +29,7 @@ set(SOURCES CIndexer.h CXCursor.cpp CXCursor.h + CXSourceLocation.cpp CXSourceLocation.h CXStoredDiagnostic.cpp CXString.cpp diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp new file mode 100644 index 0000000000..74087be7f3 --- /dev/null +++ b/tools/libclang/CXSourceLocation.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(tu->TUData); + ASTUnit::ConcurrencyCheck Check(*CXXUnit); + const FileEntry *File = static_cast(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(tu->TUData); + + SourceLocation SLoc + = CXXUnit->getLocation(static_cast(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(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(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(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 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" +