aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-03-13 13:58:24 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-03-13 14:11:53 +0300
commit11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch)
treefabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/tools/libclang/CXSourceLocation.cpp
parent9685917341315774aad5733b1793b1e533a88bbb (diff)
downloadydb-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.cpp374
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;
+}