Teach SourceManager::getLocation() how to cope with a source file
whose inode has changed since the file was first created and that is
being seen through a different path name (e.g., due to symlinks or
relative path elements), such that its FileEntry pointer doesn't match
a known FileEntry pointer. Since this requires a system call (to
stat()), we only perform this deeper checking if we can't find the
file by comparing FileEntry pointers.

Also, add a micro-optimization where we don't bother to compute line
numbers when given the location (1, 1). This improves the
efficiency of clang_getLocationForOffset().
 


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124800 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index ec0f54f..32e0039 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2483,12 +2483,22 @@
   if (!tu || !file)
     return clang_getNullLocation();
   
+  bool Logging = ::getenv("LIBCLANG_LOGGING");
   ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+  const FileEntry *File = static_cast<const FileEntry *>(file);
   SourceLocation SLoc
-    = CXXUnit->getSourceManager().getLocation(
-                                        static_cast<const FileEntry *>(file),
-                                              line, column);
-  if (SLoc.isInvalid()) return clang_getNullLocation();
+    = CXXUnit->getSourceManager().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);
 }