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() {
443ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  CXSourceLocation Result = { { 0, 0 }, 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() {
553ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  CXSourceRange Result = { { 0, 0 }, 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) {
92153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXSourceLocation Result = { { range.ptr_data[0], 0 }, 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) {
104153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXSourceLocation Result = { { range.ptr_data[1], 0 }, 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) {
1255694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  if (!TU || !file)
1263ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1273ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
128acbe4ba0bec71346e77a2f7360e8920212a07c81Dmitri Gribenko  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
1295694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
1303ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
1313ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  const FileEntry *File = static_cast<const FileEntry *>(file);
1323ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
1333ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (SLoc.isInvalid()) {
134c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    if (Log)
135c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      *Log << llvm::format("(\"%s\", %d, %d) = invalid",
136c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis                           File->getName(), line, column);
1373ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1383ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
1393ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
140c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  CXSourceLocation CXLoc =
141c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
142c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  if (Log)
143c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName(), line, column)
144c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis         << CXLoc;
1453ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
146c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  return CXLoc;
1473ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1483ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1495694feb5ccd6eb862cb600b55753cecc13794471Dmitri GribenkoCXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
1503ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                            CXFile file,
1513ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                            unsigned offset) {
1525694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  if (!TU || !file)
1533ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1543ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1555694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
1563ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1573ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  SourceLocation SLoc
1583ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
1593ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1603ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (SLoc.isInvalid())
1613ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    return clang_getNullLocation();
1623ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1633ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
1643ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1653ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1663ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek} // end extern "C"
1673ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1683ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1693ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// Routines for expanding and manipulating CXSourceLocations, regardless
1703ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek// of their origin.
1713ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek//===----------------------------------------------------------------------===//
1723ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
1733ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekstatic void createNullLocation(CXFile *file, unsigned *line,
1743ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column, unsigned *offset) {
1753ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (file)
1763ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *file = 0;
1773ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (line)
1783ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *line = 0;
1793ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (column)
1803ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *column = 0;
1813ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  if (offset)
1823ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek    *offset = 0;
1833ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  return;
1843ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
1853ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
18651a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenekstatic void createNullLocation(CXString *filename, unsigned *line,
18751a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek                               unsigned *column, unsigned *offset = 0) {
18851a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (filename)
189dc66adb40ee871b4c578ba615f45d82476c7119eDmitri Gribenko    *filename = cxstring::createEmpty();
19051a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (line)
19151a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *line = 0;
19251a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (column)
19351a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *column = 0;
19451a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  if (offset)
19551a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    *offset = 0;
19651a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek  return;
19751a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek}
19851a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek
1993ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekextern "C" {
2003ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2014522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidisint clang_Location_isInSystemHeader(CXSourceLocation location) {
2024522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  const SourceLocation Loc =
2034522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    SourceLocation::getFromRawEncoding(location.int_data);
2044522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  if (Loc.isInvalid())
2054522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    return 0;
2064522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis
2074522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  const SourceManager &SM =
2084522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis    *static_cast<const SourceManager*>(location.ptr_data[0]);
2094522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis  return SM.isInSystemHeader(Loc);
2104522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis}
2114522f63e00fa6f1276b1d29763a9a4f46f46b6a1Argyrios Kyrtzidis
2123ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getExpansionLocation(CXSourceLocation location,
2133ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                CXFile *file,
2143ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *line,
2153ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *column,
2163ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                unsigned *offset) {
2173ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
218153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
219153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXLoadedDiagnostic::decodeLocation(location, file, line, column, offset);
220153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return;
221153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
222153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
223153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
224153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
225153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!location.ptr_data[0] || Loc.isInvalid()) {
226153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(file, line, column, offset);
227153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return;
228153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
229153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
230153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SourceManager &SM =
231153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  *static_cast<const SourceManager*>(location.ptr_data[0]);
232153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
2333ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
234153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // Check that the FileID is invalid on the expansion location.
235153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  // This can manifest in invalid code.
236153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  FileID fileID = SM.getFileID(ExpansionLoc);
237153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  bool Invalid = false;
238153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
239153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (Invalid || !sloc.isFile()) {
240153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(file, line, column, offset);
241b4efaa0a14dd2382aa028c03283b5a7f5345e24dArgyrios Kyrtzidis    return;
2423ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
2433ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
244153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (file)
2453cfa5324ef1c5f75fe5e142bef8050aaf2f03704David Greene    *file = const_cast<FileEntry *>(SM.getFileEntryForSLocEntry(sloc));
246153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (line)
247153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *line = SM.getExpansionLineNumber(ExpansionLoc);
248153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (column)
249153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *column = SM.getExpansionColumnNumber(ExpansionLoc);
250153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (offset)
251153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *offset = SM.getDecomposedLoc(ExpansionLoc).second;
2523ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
2533ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2543ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getPresumedLocation(CXSourceLocation location,
2553ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               CXString *filename,
2563ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *line,
2573ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column) {
2583ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
259153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
260153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    // Other SourceLocation implementations do not support presumed locations
261153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    // at this time.
262153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(filename, line, column);
26351a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    return;
2643ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
265153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
266153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
267153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
268153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!location.ptr_data[0] || Loc.isInvalid())
269153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    createNullLocation(filename, line, column);
270153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  else {
271153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    const SourceManager &SM =
272153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *static_cast<const SourceManager*>(location.ptr_data[0]);
273153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
274153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
275153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (filename)
2760c4394c7f63008fbf4d335710b34f71afab362a3Dmitri Gribenko      *filename = cxstring::createRef(PreLoc.getFilename());
277153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (line)
278153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      *line = PreLoc.getLine();
279153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    if (column)
280153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek      *column = PreLoc.getColumn();
281153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  }
2823ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
2833ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2843ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getInstantiationLocation(CXSourceLocation location,
2853ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    CXFile *file,
2863ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *line,
2873ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *column,
2883ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                                    unsigned *offset) {
2893ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  // Redirect to new API.
2903ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  clang_getExpansionLocation(location, file, line, column, offset);
2913ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
2923ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
2933ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenekvoid clang_getSpellingLocation(CXSourceLocation location,
2943ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               CXFile *file,
2953ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *line,
2963ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *column,
2973ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek                               unsigned *offset) {
2983ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
299153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!isASTUnitSourceLocation(location)) {
300153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    CXLoadedDiagnostic::decodeLocation(location, file, line,
301153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek                                           column, offset);
30251a7d5d7f6bf60c562d825bc271fd4cf696b33b5Ted Kremenek    return;
3033ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek  }
304153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
305153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
306153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
307153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (!location.ptr_data[0] || Loc.isInvalid())
308153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return createNullLocation(file, line, column, offset);
309153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
310153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  const SourceManager &SM =
311153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  *static_cast<const SourceManager*>(location.ptr_data[0]);
3122d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  // FIXME: This should call SourceManager::getSpellingLoc().
3136ee225c8d4381e728c73252ed589f13e9f546defTed Kremenek  SourceLocation SpellLoc = SM.getFileLoc(Loc);
314153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
315153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  FileID FID = LocInfo.first;
316153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  unsigned FileOffset = LocInfo.second;
317153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
318153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (FID.isInvalid())
319153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    return createNullLocation(file, line, column, offset);
320153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek
321153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (file)
3223cfa5324ef1c5f75fe5e142bef8050aaf2f03704David Greene    *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
323153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (line)
324153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *line = SM.getLineNumber(FID, FileOffset);
325153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (column)
326153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *column = SM.getColumnNumber(FID, FileOffset);
327153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek  if (offset)
328153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek    *offset = FileOffset;
3293ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek}
3303ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3312d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidisvoid clang_getFileLocation(CXSourceLocation location,
3322d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           CXFile *file,
3332d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *line,
3342d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *column,
3352d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                           unsigned *offset) {
3362d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3372d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (!isASTUnitSourceLocation(location)) {
3382d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    CXLoadedDiagnostic::decodeLocation(location, file, line,
3392d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis                                           column, offset);
3402d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return;
3412d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  }
3422d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3432d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
3442d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3452d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
3462d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
3473ddef060a94434e6b71b58348e730c4464efbc48Ted Kremenek
3482d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  const SourceManager &SM =
3492d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  *static_cast<const SourceManager*>(location.ptr_data[0]);
3502d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  SourceLocation FileLoc = SM.getFileLoc(Loc);
3512d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(FileLoc);
3522d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  FileID FID = LocInfo.first;
3532d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  unsigned FileOffset = LocInfo.second;
3542d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3552d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (FID.isInvalid())
3562d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    return createNullLocation(file, line, column, offset);
3572d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3582d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (file)
359e4ea879fe73581bc70a9bfbfddc7ca06b5c0768bDmitri Gribenko    *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
3602d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (line)
3612d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *line = SM.getLineNumber(FID, FileOffset);
3622d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (column)
3632d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *column = SM.getColumnNumber(FID, FileOffset);
3642d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis  if (offset)
3652d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis    *offset = FileOffset;
3662d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis}
3672d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis
3682d5c133d3dd95507db63147997109f06e8cfa833Argyrios Kyrtzidis} // end extern "C"
369