diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp')
-rw-r--r-- | contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp b/contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp new file mode 100644 index 0000000000..39c2194f7d --- /dev/null +++ b/contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp @@ -0,0 +1,374 @@ +//===- CXSourceLocation.cpp - CXSourceLocations APIs ------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines routines for manipulating CXSourceLocations. +// +//===----------------------------------------------------------------------===// + +#include "CXSourceLocation.h" +#include "CIndexer.h" +#include "CLog.h" +#include "CXLoadedDiagnostic.h" +#include "CXString.h" +#include "CXTranslationUnit.h" +#include "clang/Basic/FileManager.h" +#include "clang/Frontend/ASTUnit.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Format.h" + +using namespace clang; +using namespace clang::cxindex; + +//===----------------------------------------------------------------------===// +// Internal predicates on CXSourceLocations. +//===----------------------------------------------------------------------===// + +static bool isASTUnitSourceLocation(const CXSourceLocation &L) { + // If the lowest bit is clear then the first ptr_data entry is a SourceManager + // pointer, or the CXSourceLocation is a null location. + return ((uintptr_t)L.ptr_data[0] & 0x1) == 0; +} + +//===----------------------------------------------------------------------===// +// Basic construction and comparison of CXSourceLocations and CXSourceRanges. +//===----------------------------------------------------------------------===// + +CXSourceLocation clang_getNullLocation() { + CXSourceLocation Result = { { nullptr, nullptr }, 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 = { { nullptr, nullptr }, 0, 0 }; + return Result; +} + +CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { + if (!isASTUnitSourceLocation(begin)) { + if (isASTUnitSourceLocation(end)) + return clang_getNullRange(); + CXSourceRange Result = { { begin.ptr_data[0], end.ptr_data[0] }, 0, 0 }; + return Result; + } + + 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) { + // Special decoding for CXSourceLocations for CXLoadedDiagnostics. + if ((uintptr_t)range.ptr_data[0] & 0x1) { + CXSourceLocation Result = { { range.ptr_data[0], nullptr }, 0 }; + return Result; + } + + CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, + range.begin_int_data }; + return Result; +} + +CXSourceLocation clang_getRangeEnd(CXSourceRange range) { + // Special decoding for CXSourceLocations for CXLoadedDiagnostics. + if ((uintptr_t)range.ptr_data[0] & 0x1) { + CXSourceLocation Result = { { range.ptr_data[1], nullptr }, 0 }; + return Result; + } + + CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, + range.end_int_data }; + return Result; +} + +//===----------------------------------------------------------------------===// +// Getting CXSourceLocations and CXSourceRanges from a translation unit. +//===----------------------------------------------------------------------===// + +CXSourceLocation clang_getLocation(CXTranslationUnit TU, + CXFile file, + unsigned line, + unsigned column) { + if (cxtu::isNotUsableTU(TU)) { + LOG_BAD_TU(TU); + return clang_getNullLocation(); + } + if (!file) + return clang_getNullLocation(); + if (line == 0 || column == 0) + return clang_getNullLocation(); + + LogRef Log = Logger::make(__func__); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); + ASTUnit::ConcurrencyCheck Check(*CXXUnit); + const FileEntry *File = static_cast<const FileEntry *>(file); + SourceLocation SLoc = CXXUnit->getLocation(File, line, column); + if (SLoc.isInvalid()) { + if (Log) + *Log << llvm::format("(\"%s\", %d, %d) = invalid", + File->getName().str().c_str(), line, column); + return clang_getNullLocation(); + } + + CXSourceLocation CXLoc = + cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); + if (Log) + *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName().str().c_str(), + line, column) + << CXLoc; + + return CXLoc; +} + +CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU, + CXFile file, + unsigned offset) { + if (cxtu::isNotUsableTU(TU)) { + LOG_BAD_TU(TU); + return clang_getNullLocation(); + } + if (!file) + return clang_getNullLocation(); + + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); + + SourceLocation SLoc + = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset); + + if (SLoc.isInvalid()) + return clang_getNullLocation(); + + return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); +} + +//===----------------------------------------------------------------------===// +// Routines for expanding and manipulating CXSourceLocations, regardless +// of their origin. +//===----------------------------------------------------------------------===// + +static void createNullLocation(CXFile *file, unsigned *line, + unsigned *column, unsigned *offset) { + if (file) + *file = nullptr; + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; +} + +static void createNullLocation(CXString *filename, unsigned *line, + unsigned *column, unsigned *offset = nullptr) { + if (filename) + *filename = cxstring::createEmpty(); + if (line) + *line = 0; + if (column) + *column = 0; + if (offset) + *offset = 0; +} + +int clang_Location_isInSystemHeader(CXSourceLocation location) { + const SourceLocation Loc = + SourceLocation::getFromRawEncoding(location.int_data); + if (Loc.isInvalid()) + return 0; + + const SourceManager &SM = + *static_cast<const SourceManager*>(location.ptr_data[0]); + return SM.isInSystemHeader(Loc); +} + +int clang_Location_isFromMainFile(CXSourceLocation location) { + const SourceLocation Loc = + SourceLocation::getFromRawEncoding(location.int_data); + if (Loc.isInvalid()) + return 0; + + const SourceManager &SM = + *static_cast<const SourceManager*>(location.ptr_data[0]); + return SM.isWrittenInMainFile(Loc); +} + +void clang_getExpansionLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset) { + if (!isASTUnitSourceLocation(location)) { + CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset); + return; + } + + 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 = const_cast<FileEntry *>(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) { + if (!isASTUnitSourceLocation(location)) { + // Other SourceLocation implementations do not support presumed locations + // at this time. + createNullLocation(filename, line, column); + return; + } + + SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); + + if (!location.ptr_data[0] || Loc.isInvalid()) { + createNullLocation(filename, line, column); + return; + } + + const SourceManager &SM = + *static_cast<const SourceManager *>(location.ptr_data[0]); + PresumedLoc PreLoc = SM.getPresumedLoc(Loc); + if (PreLoc.isInvalid()) { + createNullLocation(filename, line, column); + return; + } + + if (filename) *filename = cxstring::createRef(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) { + if (!isASTUnitSourceLocation(location)) { + CXLoadedDiagnostic::decodeLocation(location, file, line, + column, offset); + return; + } + + 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]); + // FIXME: This should call SourceManager::getSpellingLoc(). + SourceLocation SpellLoc = SM.getFileLoc(Loc); + 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 = const_cast<FileEntry *>(SM.getFileEntryForID(FID)); + if (line) + *line = SM.getLineNumber(FID, FileOffset); + if (column) + *column = SM.getColumnNumber(FID, FileOffset); + if (offset) + *offset = FileOffset; +} + +void clang_getFileLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column, + unsigned *offset) { + if (!isASTUnitSourceLocation(location)) { + CXLoadedDiagnostic::decodeLocation(location, file, line, + column, offset); + return; + } + + 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 FileLoc = SM.getFileLoc(Loc); + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(FileLoc); + FileID FID = LocInfo.first; + unsigned FileOffset = LocInfo.second; + + if (FID.isInvalid()) + return createNullLocation(file, line, column, offset); + + if (file) + *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID)); + if (line) + *line = SM.getLineNumber(FID, FileOffset); + if (column) + *column = SM.getColumnNumber(FID, FileOffset); + if (offset) + *offset = FileOffset; +} |