13ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===- CXSourceLocation.cpp - CXSourceLocations APIs ------------*- C++ -*-===//
23ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//
33ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//                     The LLVM Compiler Infrastructure
43ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//
53ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// This file is distributed under the University of Illinois Open Source
63ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// License. See LICENSE.TXT for details.
73ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//
83ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
93ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//
103ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// This file defines routines for manipulating CXSourceLocations.
113ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//
123ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
133ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
143ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek#include "clang/Frontend/ASTUnit.h"
153ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek#include "CIndexer.h"
16b1ba0efc3d1dc1daa5d82c40bc504e1f368c4fa0Chandler Carruth#include "CLog.h"
17f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CXLoadedDiagnostic.h"
183ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek#include "CXSourceLocation.h"
19f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "CXString.h"
203ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek#include "CXTranslationUnit.h"
21acbe4ba0bec71346e77a2f7360e8920212a07c81Dmitri Gribenko#include "llvm/Support/Compiler.h"
22c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis#include "llvm/Support/Format.h"
233ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
243ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekusing namespace clang;
25c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidisusing namespace clang::cxindex;
263ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
273ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
2851a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek// Internal predicates on CXSourceLocations.
2951a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek//===----------------------------------------------------------------------===//
3051a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek
3151a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenekstatic bool isASTUnitSourceLocation(const CXSourceLocation &L) {
3251a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  // If the lowest bit is clear then the first ptr_data entry is a SourceManager
3351a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  // pointer, or the CXSourceLocation is a null location.
3451a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  return ((uintptr_t)L.ptr_data[0] & 0x1) == 0;
3551a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek}
3651a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek
3751a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek//===----------------------------------------------------------------------===//
383ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// Basic construction and comparison of CXSourceLocations and CXSourceRanges.
393ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
403ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
413ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekextern "C" {
423ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
433ddef060a94434e6b71b58348e730c4464efbc48Ted KremenekCXSourceLocation clang_getNullLocation() {
44c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  CXSourceLocation Result = { { nullptr, nullptr }, 0 };
453ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return Result;
463ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
473ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
483ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekunsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
493ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return (loc1.ptr_data[0] == loc2.ptr_data[0] &&
503ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek          loc1.ptr_data[1] == loc2.ptr_data[1] &&
513ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek          loc1.int_data == loc2.int_data);
523ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
533ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
543ddef060a94434e6b71b58348e730c4464efbc48Ted KremenekCXSourceRange clang_getNullRange() {
55c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  CXSourceRange Result = { { nullptr, nullptr }, 0, 0 };
563ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return Result;
573ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
583ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
593ddef060a94434e6b71b58348e730c4464efbc48Ted KremenekCXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
60153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(begin)) {
61153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (isASTUnitSourceLocation(end))
62153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      return clang_getNullRange();
63153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXSourceRange Result = { { begin.ptr_data[0], end.ptr_data[0] }, 0, 0 };
64153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return Result;
65153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
66153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
673ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (begin.ptr_data[0] != end.ptr_data[0] ||
683ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek      begin.ptr_data[1] != end.ptr_data[1])
693ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullRange();
703ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
713ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] },
723ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                           begin.int_data, end.int_data };
733ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
743ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return Result;
753ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
763ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
773ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekunsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2) {
783ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return range1.ptr_data[0] == range2.ptr_data[0]
793ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    && range1.ptr_data[1] == range2.ptr_data[1]
803ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    && range1.begin_int_data == range2.begin_int_data
813ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    && range1.end_int_data == range2.end_int_data;
823ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
833ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
843ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekint clang_Range_isNull(CXSourceRange range) {
853ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return clang_equalRanges(range, clang_getNullRange());
863ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
873ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
883ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
893ddef060a94434e6b71b58348e730c4464efbc48Ted KremenekCXSourceLocation clang_getRangeStart(CXSourceRange range) {
90153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
91153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if ((uintptr_t)range.ptr_data[0] & 0x1) {
92c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    CXSourceLocation Result = { { range.ptr_data[0], nullptr }, 0 };
93153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return Result;
94153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
95153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
963ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
973ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    range.begin_int_data };
983ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return Result;
993ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1003ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1013ddef060a94434e6b71b58348e730c4464efbc48Ted KremenekCXSourceLocation clang_getRangeEnd(CXSourceRange range) {
102153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
103153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if ((uintptr_t)range.ptr_data[0] & 0x1) {
104c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    CXSourceLocation Result = { { range.ptr_data[1], nullptr }, 0 };
105153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return Result;
106153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
107153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
1083ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
1093ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    range.end_int_data };
1103ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return Result;
1113ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1123ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1133ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek} // end extern "C"
1143ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1153ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1163ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//  Getting CXSourceLocations and CXSourceRanges from a translation unit.
1173ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1183ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1193ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekextern "C" {
1203ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1215694feb5ccd6eb862cb600b55753cecc13794471Dmitri GribenkoCXSourceLocation clang_getLocation(CXTranslationUnit TU,
1223ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                   CXFile file,
1233ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                   unsigned line,
1243ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                   unsigned column) {
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cxtu::isNotUsableTU(TU)) {
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(TU);
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return clang_getNullLocation();
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!file)
1303ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1318644aa9149f40fb00bfd20f0a22a873428f520d3Argyrios Kyrtzidis  if (line == 0 || column == 0)
1328644aa9149f40fb00bfd20f0a22a873428f520d3Argyrios Kyrtzidis    return clang_getNullLocation();
1333ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
134acbe4ba0bec71346e77a2f7360e8920212a07c81Dmitri Gribenko  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
1355694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
1363ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
1373ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  const FileEntry *File = static_cast<const FileEntry *>(file);
1383ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
1393ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (SLoc.isInvalid()) {
140c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    if (Log)
141c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      *Log << llvm::format("(\"%s\", %d, %d) = invalid",
142c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis                           File->getName(), line, column);
1433ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1443ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
1453ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
146c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  CXSourceLocation CXLoc =
147c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
148c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  if (Log)
149c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName(), line, column)
150c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis         << CXLoc;
1513ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
152c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  return CXLoc;
1533ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1543ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1555694feb5ccd6eb862cb600b55753cecc13794471Dmitri GribenkoCXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
1563ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                            CXFile file,
1573ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                            unsigned offset) {
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (cxtu::isNotUsableTU(TU)) {
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    LOG_BAD_TU(TU);
1603ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!file)
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return clang_getNullLocation();
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1655694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
1663ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1673ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  SourceLocation SLoc
1683ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
1693ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1703ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (SLoc.isInvalid())
1713ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1723ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1733ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
1743ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1753ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1763ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek} // end extern "C"
1773ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1783ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1793ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// Routines for expanding and manipulating CXSourceLocations, regardless
1803ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// of their origin.
1813ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1823ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1833ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekstatic void createNullLocation(CXFile *file, unsigned *line,
1843ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column, unsigned *offset) {
1853ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (file)
186c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    *file = nullptr;
1873ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (line)
1883ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *line = 0;
1893ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (column)
1903ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *column = 0;
1913ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (offset)
1923ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *offset = 0;
1933ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return;
1943ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1953ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
19651a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenekstatic void createNullLocation(CXString *filename, unsigned *line,
197c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines                               unsigned *column, unsigned *offset = nullptr) {
19851a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (filename)
199dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    *filename = cxstring::createEmpty();
20051a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (line)
20151a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *line = 0;
20251a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (column)
20351a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *column = 0;
20451a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (offset)
20551a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *offset = 0;
20651a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  return;
20751a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek}
20851a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek
2093ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekextern "C" {
2103ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2114522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidisint clang_Location_isInSystemHeader(CXSourceLocation location) {
2124522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  const SourceLocation Loc =
2134522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    SourceLocation::getFromRawEncoding(location.int_data);
2144522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  if (Loc.isInvalid())
2154522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    return 0;
2164522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis
2174522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  const SourceManager &SM =
2184522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    *static_cast<const SourceManager*>(location.ptr_data[0]);
2194522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  return SM.isInSystemHeader(Loc);
2204522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis}
2214522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis
222ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toitint clang_Location_isFromMainFile(CXSourceLocation location) {
223ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit  const SourceLocation Loc =
224ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit    SourceLocation::getFromRawEncoding(location.int_data);
225ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit  if (Loc.isInvalid())
226ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit    return 0;
227ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit
228ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit  const SourceManager &SM =
229ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit    *static_cast<const SourceManager*>(location.ptr_data[0]);
23024146975f1af8c1b4b14e8545f218129d0e7dfebEli Friedman  return SM.isWrittenInMainFile(Loc);
231ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit}
232ad0d5707463cd7875e1ffd50dacd3f900d185aa1Stefanus Du Toit
2333ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getExpansionLocation(CXSourceLocation location,
2343ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                CXFile *file,
2353ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *line,
2363ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *column,
2373ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *offset) {
2383ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
239153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
240153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
241153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return;
242153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
243153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
244153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
245153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
246153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!location.ptr_data[0] || Loc.isInvalid()) {
247153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(file, line, column, offset);
248153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return;
249153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
250153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
251153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SourceManager &SM =
252153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  *static_cast<const SourceManager*>(location.ptr_data[0]);
253153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
2543ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
255153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // Check that the FileID is invalid on the expansion location.
256153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // This can manifest in invalid code.
257153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  FileID fileID = SM.getFileID(ExpansionLoc);
258153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  bool Invalid = false;
259153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
260153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (Invalid || !sloc.isFile()) {
261153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(file, line, column, offset);
262b4efaa0a14dd2382aa028c03283b5a7f5345e24dArgyrios Kyrtzidis    return;
2633ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
2643ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
265153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (file)
2663cfa5324ef1c5f75fe5e142bef8050aaf2f03704David Greene    *file = const_cast<FileEntry *>(SM.getFileEntryForSLocEntry(sloc));
267153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (line)
268153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *line = SM.getExpansionLineNumber(ExpansionLoc);
269153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (column)
270153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *column = SM.getExpansionColumnNumber(ExpansionLoc);
271153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (offset)
272153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *offset = SM.getDecomposedLoc(ExpansionLoc).second;
2733ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
2743ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2753ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getPresumedLocation(CXSourceLocation location,
2763ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               CXString *filename,
2773ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *line,
2783ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column) {
2792bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov
280153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
281153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    // Other SourceLocation implementations do not support presumed locations
282153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    // at this time.
283153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(filename, line, column);
28451a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    return;
2853ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
286153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
287153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
288153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
2892bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  if (!location.ptr_data[0] || Loc.isInvalid()) {
290153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(filename, line, column);
2912bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov    return;
292153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
2932bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov
2942bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  const SourceManager &SM =
2952bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov      *static_cast<const SourceManager *>(location.ptr_data[0]);
2962bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
2972bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  if (PreLoc.isInvalid()) {
2982bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov    createNullLocation(filename, line, column);
2992bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov    return;
3002bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  }
3012bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov
3022bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  if (filename) *filename = cxstring::createRef(PreLoc.getFilename());
3032bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  if (line) *line = PreLoc.getLine();
3042bb6dad4a44569dd2f86e7500a5ba21680718736Evgeniy Stepanov  if (column) *column = PreLoc.getColumn();
3053ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
3063ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3073ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getInstantiationLocation(CXSourceLocation location,
3083ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    CXFile *file,
3093ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *line,
3103ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *column,
3113ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *offset) {
3123ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  // Redirect to new API.
3133ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  clang_getExpansionLocation(location, file, line, column, offset);
3143ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
3153ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3163ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getSpellingLocation(CXSourceLocation location,
3173ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               CXFile *file,
3183ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *line,
3193ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column,
3203ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *offset) {
3213ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
322153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
323153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXLoadedDiagnostic::decodeLocation(location, file, line,
324153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek                                           column, offset);
32551a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    return;
3263ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
327153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
328153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
329153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
330153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!location.ptr_data[0] || Loc.isInvalid())
331153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return createNullLocation(file, line, column, offset);
332153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
333153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SourceManager &SM =
334153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  *static_cast<const SourceManager*>(location.ptr_data[0]);
3352d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  // FIXME: This should call SourceManager::getSpellingLoc().
3366ee225c8d4381e728c73252ed589f13e9f546defTed Kremenek  SourceLocation SpellLoc = SM.getFileLoc(Loc);
337153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
338153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  FileID FID = LocInfo.first;
339153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  unsigned FileOffset = LocInfo.second;
340153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
341153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (FID.isInvalid())
342153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return createNullLocation(file, line, column, offset);
343153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
344153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (file)
3453cfa5324ef1c5f75fe5e142bef8050aaf2f03704David Greene    *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
346153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (line)
347153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *line = SM.getLineNumber(FID, FileOffset);
348153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (column)
349153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *column = SM.getColumnNumber(FID, FileOffset);
350153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (offset)
351153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *offset = FileOffset;
3523ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
3533ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3542d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidisvoid clang_getFileLocation(CXSourceLocation location,
3552d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           CXFile *file,
3562d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *line,
3572d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *column,
3582d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *offset) {
3592d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3602d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (!isASTUnitSourceLocation(location)) {
3612d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    CXLoadedDiagnostic::decodeLocation(location, file, line,
3622d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                                           column, offset);
3632d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return;
3642d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  }
3652d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3662d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
3672d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3682d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
3692d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
3703ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3712d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  const SourceManager &SM =
3722d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  *static_cast<const SourceManager*>(location.ptr_data[0]);
3732d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  SourceLocation FileLoc = SM.getFileLoc(Loc);
3742d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(FileLoc);
3752d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  FileID FID = LocInfo.first;
3762d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  unsigned FileOffset = LocInfo.second;
3772d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3782d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (FID.isInvalid())
3792d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
3802d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3812d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (file)
382e4ea879fe73581bc70a9bfbfddc7ca06b5c0768bDmitri Gribenko    *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
3832d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (line)
3842d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *line = SM.getLineNumber(FID, FileOffset);
3852d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (column)
3862d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *column = SM.getColumnNumber(FID, FileOffset);
3872d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (offset)
3882d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *offset = FileOffset;
3892d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis}
3902d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3912d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis} // end extern "C"
392