]> granicus.if.org Git - clang/commitdiff
Introduce SourceManager::getLocation() to get a source location out of a "file:line...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 20 Jun 2009 08:09:57 +0000 (08:09 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 20 Jun 2009 08:09:57 +0000 (08:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73823 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/SourceManager.h
lib/Basic/SourceManager.cpp

index 57ae9a45114dded140a477d0cc974c7aa55d7ed1..bcfb83b8942cba60f0c0ad52de92b7220968fcb6 100644 (file)
@@ -68,7 +68,12 @@ namespace SrcMgr {
     /// NumLines - The number of lines in this ContentCache.  This is only valid
     /// if SourceLineCache is non-null.
     unsigned NumLines;
-    
+
+    /// FirstFID - First FileID that was created for this ContentCache.
+    /// Represents the first source inclusion of the file associated with this
+    /// ContentCache.
+    mutable FileID FirstFID;
+
     /// getBuffer - Returns the memory buffer for the associated content.
     const llvm::MemoryBuffer *getBuffer() const;
     
@@ -624,6 +629,13 @@ public:
   //===--------------------------------------------------------------------===//
   // Other miscellaneous methods.
   //===--------------------------------------------------------------------===//
+
+  /// \brief Get the source location for the given file:line:col triplet.
+  ///
+  /// If the source file is included multiple times, the source location will
+  /// be based upon the first inclusion.
+  SourceLocation getLocation(const FileEntry *SourceFile,
+                             unsigned Line, unsigned Col) const;
   
   // Iterators over FileInfos.
   typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
index ed5eb46c2847f49913fdc57642981ddee203d1bd..867e1bdf553189b43a20a02c18c2562a6cf48397 100644 (file)
@@ -358,7 +358,10 @@ FileID SourceManager::createFileID(const ContentCache *File,
     SLocEntryTable[PreallocatedID] 
       = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter));
     SLocEntryLoaded[PreallocatedID] = true;
-    return LastFileIDLookup = FileID::get(PreallocatedID);
+    FileID FID = FileID::get(PreallocatedID);
+    if (File->FirstFID.isInvalid())
+      File->FirstFID = FID;
+    return LastFileIDLookup = FID;
   }
 
   SLocEntryTable.push_back(SLocEntry::get(NextOffset, 
@@ -914,6 +917,43 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
 // Other miscellaneous methods.
 //===----------------------------------------------------------------------===//
 
+/// \brief Get the source location for the given file:line:col triplet.
+///
+/// If the source file is included multiple times, the source location will
+/// be based upon the first inclusion.
+SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
+                                          unsigned Line, unsigned Col) const {
+  assert(SourceFile && "Null source file!");
+  assert(Line && Col && "Line and column should start from 1!");
+
+  fileinfo_iterator FI = FileInfos.find(SourceFile);
+  if (FI == FileInfos.end())
+    return SourceLocation();
+  ContentCache *Content = FI->second;
+  
+  // If this is the first use of line information for this buffer, compute the
+  /// SourceLineCache for it on demand.
+  if (Content->SourceLineCache == 0)
+    ComputeLineNumbers(Content, ContentCacheAlloc);
+
+  if (Line > Content->NumLines)
+    return SourceLocation();
+  
+  unsigned FilePos = Content->SourceLineCache[Line - 1];
+  const char *BufStart = Content->getBuffer()->getBufferStart();
+  const char *BufEnd = Content->getBuffer()->getBufferEnd();
+  const char *p = BufStart;
+
+  // Check that the given column is valid.
+  while (p < BufEnd && *p != '\n' && *p != '\r')
+    ++p;
+  if (Col > p-BufStart)
+    return SourceLocation();
+  
+  return getLocForStartOfFile(Content->FirstFID).
+            getFileLocWithOffset(FilePos + Col - 1);
+}
+
 
 /// PrintStats - Print statistics to stderr.
 ///