]> granicus.if.org Git - clang/commitdiff
Add a 'RawPath' parameter to the PPCallbacks interface. This allows
authorChandler Carruth <chandlerc@gmail.com>
Wed, 16 Mar 2011 18:34:36 +0000 (18:34 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 16 Mar 2011 18:34:36 +0000 (18:34 +0000)
clients to observe the exact path through which an #included file was
located. This is very useful when trying to record and replay inclusion
operations without it beind influenced by the aggressive caching done
inside the FileManager to avoid redundant system calls and filesystem
operations.

The work to compute and return this is only done in the presence of
callbacks, so it should have no effect on normal compilation.

Patch by Manuel Klimek.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127742 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/clang/Lex/DirectoryLookup.h
include/clang/Lex/HeaderMap.h
include/clang/Lex/HeaderSearch.h
include/clang/Lex/PPCallbacks.h
include/clang/Lex/PreprocessingRecord.h
include/clang/Lex/Preprocessor.h
lib/Lex/HeaderMap.cpp
lib/Lex/HeaderSearch.cpp
lib/Lex/PPDirectives.cpp
lib/Lex/PPMacroExpansion.cpp
lib/Lex/Pragma.cpp
lib/Lex/PreprocessingRecord.cpp

index 64687a18e2b633a4f623fc74273566c590d63355..1ee19266f3092ce08570342b23679275a1f7a124 100644 (file)
@@ -18,6 +18,7 @@
 
 namespace llvm {
   class StringRef;
+  template <typename T> class SmallVectorImpl;
 }
 namespace clang {
 class HeaderMap;
@@ -121,11 +122,17 @@ public:
 
   /// LookupFile - Lookup the specified file in this search path, returning it
   /// if it exists or returning null if not.
-  const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS) const;
+  /// If RawPath is not NULL and the file is found, RawPath will be set to the
+  /// raw path at which the file was found in the file system. For example,
+  /// for a search path ".." and a filename "../file.h" this would be
+  /// "../../file.h".
+  const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS,
+                              llvm::SmallVectorImpl<char> *RawPath) const;
 
 private:
-  const FileEntry *DoFrameworkLookup(llvm::StringRef Filename,
-                                     HeaderSearch &HS) const;
+  const FileEntry *DoFrameworkLookup(
+      llvm::StringRef Filename, HeaderSearch &HS,
+      llvm::SmallVectorImpl<char> *RawPath) const;
 
 };
 
index 8a5c83ecf4951f2e67347c2aa7427b37fcaa14ce..54c7eb47c85956e4baf6d4b38cc6f41ac4e1b828 100644 (file)
@@ -17,6 +17,7 @@
 namespace llvm {
   class MemoryBuffer;
   class StringRef;
+  template <typename T> class SmallVectorImpl;
 }
 namespace clang {
   class FileEntry;
@@ -47,7 +48,12 @@ public:
 
   /// LookupFile - Check to see if the specified relative filename is located in
   /// this HeaderMap.  If so, open it and return its FileEntry.
-  const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) const;
+  /// If RawPath is not NULL and the file is found, RawPath will be set to the
+  /// raw path at which the file was found in the file system. For example,
+  /// for a search path ".." and a filename "../file.h" this would be
+  /// "../../file.h".
+  const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM,
+                              llvm::SmallVectorImpl<char> *RawPath) const;
 
   /// getFileName - Return the filename of the headermap.
   const char *getFileName() const;
index ed84ebc1442ce85e03817e9b00b8cf0cc82ef46a..a63386bd6b5136bb225696baaaad1ffb528cdd66 100644 (file)
@@ -192,15 +192,18 @@ public:
   const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled,
                               const DirectoryLookup *FromDir,
                               const DirectoryLookup *&CurDir,
-                              const FileEntry *CurFileEnt);
+                              const FileEntry *CurFileEnt,
+                              llvm::SmallVectorImpl<char> *RawPath);
 
   /// LookupSubframeworkHeader - Look up a subframework for the specified
   /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
   /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
   /// is a subframework within Carbon.framework.  If so, return the FileEntry
   /// for the designated file, otherwise return null.
-  const FileEntry *LookupSubframeworkHeader(llvm::StringRef Filename,
-                                            const FileEntry *RelativeFileEnt);
+  const FileEntry *LookupSubframeworkHeader(
+      llvm::StringRef Filename,
+      const FileEntry *RelativeFileEnt,
+      llvm::SmallVectorImpl<char> *RawPath);
 
   /// LookupFrameworkCache - Look up the specified framework name in our
   /// framework cache, returning the DirectoryEntry it is in if we know,
index b2a80a62985f0ba40742532323748af632ba3c6a..242986dae576c70b22894a924f1623d4f52f5206 100644 (file)
@@ -75,12 +75,17 @@ public:
   ///
   /// \param EndLoc The location of the last token within the inclusion
   /// directive.
+  ///
+  /// \param RawPath Contains the raw path at which the file was found in the
+  /// file system. For example, for a search path ".." and a filename
+  /// "../file.h" this would be "../../file.h".
   virtual void InclusionDirective(SourceLocation HashLoc,
                                   const Token &IncludeTok,
                                   llvm::StringRef FileName,
                                   bool IsAngled,
                                   const FileEntry *File,
-                                  SourceLocation EndLoc) {
+                                  SourceLocation EndLoc,
+                                  const llvm::SmallVectorImpl<char> &RawPath) {
   }
 
   /// EndOfMainFile - This callback is invoked when the end of the main file is
@@ -188,11 +193,12 @@ public:
                                   llvm::StringRef FileName,
                                   bool IsAngled,
                                   const FileEntry *File,
-                                  SourceLocation EndLoc) {
-    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 
-                              EndLoc);
-    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, 
-                               EndLoc);
+                                  SourceLocation EndLoc,
+                                  const llvm::SmallVectorImpl<char> &RawPath) {
+    First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
+                              EndLoc, RawPath);
+    Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
+                               EndLoc, RawPath);
   }
 
   virtual void EndOfMainFile() {
index afd7ae1187cc6a7cdb0549250dbaeff22cf4eba6..f5066d4bfd661436ebe22ffd868211932db24787 100644 (file)
@@ -341,7 +341,8 @@ namespace clang {
                                     llvm::StringRef FileName,
                                     bool IsAngled,
                                     const FileEntry *File,
-                                    SourceLocation EndLoc);
+                                    SourceLocation EndLoc,
+                                    const llvm::SmallVectorImpl<char> &RawPath);
   };
 } // end namespace clang
 
index 42af489d903217190ef31eac6ae640e629629758..5dc13eb4eaeeea151932a4edfefe566f59492f9a 100644 (file)
@@ -832,7 +832,8 @@ public:
   /// for system #include's or not (i.e. using <> instead of "").
   const FileEntry *LookupFile(llvm::StringRef Filename,
                               bool isAngled, const DirectoryLookup *FromDir,
-                              const DirectoryLookup *&CurDir);
+                              const DirectoryLookup *&CurDir,
+                              llvm::SmallVectorImpl<char> *RawPath);
 
   /// GetCurLookup - The DirectoryLookup structure used to find the current
   /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
index e424f91655152a3549c5eaea9d3144177ae78b4e..90ed184a570a739ea8fa91e5c2d676486cb38f21 100644 (file)
@@ -199,8 +199,9 @@ void HeaderMap::dump() const {
 
 /// LookupFile - Check to see if the specified relative filename is located in
 /// this HeaderMap.  If so, open it and return its FileEntry.
-const FileEntry *HeaderMap::LookupFile(llvm::StringRef Filename,
-                                       FileManager &FM) const {
+const FileEntry *HeaderMap::LookupFile(
+    llvm::StringRef Filename, FileManager &FM,
+    llvm::SmallVectorImpl<char> *RawPath) const {
   const HMapHeader &Hdr = getHeader();
   unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
 
@@ -223,6 +224,8 @@ const FileEntry *HeaderMap::LookupFile(llvm::StringRef Filename,
     llvm::SmallString<1024> DestPath;
     DestPath += getString(B.Prefix);
     DestPath += getString(B.Suffix);
+    if (RawPath != NULL)
+      *RawPath = DestPath;
     return FM.getFile(DestPath.str());
   }
 }
index b028e339ae9194d7c886affdec47356ff24cbb14..bb4ff60480fe29f15ab63a624a90c2947a03cbda 100644 (file)
@@ -114,8 +114,9 @@ const char *DirectoryLookup::getName() const {
 
 /// LookupFile - Lookup the specified file in this search path, returning it
 /// if it exists or returning null if not.
-const FileEntry *DirectoryLookup::LookupFile(llvm::StringRef Filename,
-                                             HeaderSearch &HS) const {
+const FileEntry *DirectoryLookup::LookupFile(
+    llvm::StringRef Filename,
+    HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const {
   llvm::SmallString<1024> TmpDir;
   if (isNormalDir()) {
     // Concatenate the requested file onto the directory.
@@ -123,21 +124,24 @@ const FileEntry *DirectoryLookup::LookupFile(llvm::StringRef Filename,
     TmpDir += getDir()->getName();
     TmpDir.push_back('/');
     TmpDir.append(Filename.begin(), Filename.end());
+    if (RawPath != NULL)
+      *RawPath = TmpDir;
     return HS.getFileMgr().getFile(TmpDir.str());
   }
 
   if (isFramework())
-    return DoFrameworkLookup(Filename, HS);
+    return DoFrameworkLookup(Filename, HS, RawPath);
 
   assert(isHeaderMap() && "Unknown directory lookup");
-  return getHeaderMap()->LookupFile(Filename, HS.getFileMgr());
+  return getHeaderMap()->LookupFile(Filename, HS.getFileMgr(), RawPath);
 }
 
 
 /// DoFrameworkLookup - Do a lookup of the specified file in the current
 /// DirectoryLookup, which is a framework directory.
-const FileEntry *DirectoryLookup::DoFrameworkLookup(llvm::StringRef Filename,
-                                                    HeaderSearch &HS) const {
+const FileEntry *DirectoryLookup::DoFrameworkLookup(
+    llvm::StringRef Filename,
+    HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const {
   FileManager &FileMgr = HS.getFileMgr();
 
   // Framework names must have a '/' in the filename.
@@ -188,13 +192,18 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(llvm::StringRef Filename,
 
   FrameworkName += "Headers/";
   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
-  if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str()))
+  if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str())) {
+    if (RawPath != NULL)
+      *RawPath = FrameworkName;
     return FE;
+  }
 
   // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
   const char *Private = "Private";
   FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
                        Private+strlen(Private));
+  if (RawPath != NULL)
+    *RawPath = FrameworkName;
   return FileMgr.getFile(FrameworkName.str());
 }
 
@@ -209,11 +218,13 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(llvm::StringRef Filename,
 /// for system #include's or not (i.e. using <> instead of "").  CurFileEnt, if
 /// non-null, indicates where the #including file is, in case a relative search
 /// is needed.
-const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
-                                          bool isAngled,
-                                          const DirectoryLookup *FromDir,
-                                          const DirectoryLookup *&CurDir,
-                                          const FileEntry *CurFileEnt) {
+const FileEntry *HeaderSearch::LookupFile(
+    llvm::StringRef Filename,
+    bool isAngled,
+    const DirectoryLookup *FromDir,
+    const DirectoryLookup *&CurDir,
+    const FileEntry *CurFileEnt,
+    llvm::SmallVectorImpl<char> *RawPath) {
   // If 'Filename' is absolute, check to see if it exists and no searching.
   if (llvm::sys::path::is_absolute(Filename)) {
     CurDir = 0;
@@ -221,6 +232,8 @@ const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
     // If this was an #include_next "/absolute/file", fail.
     if (FromDir) return 0;
 
+    if (RawPath != NULL)
+      llvm::Twine(Filename).toVector(*RawPath);
     // Otherwise, just return the file.
     return FileMgr.getFile(Filename);
   }
@@ -246,6 +259,8 @@ const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
       // of evaluation.
       unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
       getFileInfo(FE).DirInfo = DirInfo;
+      if (RawPath != NULL)
+        *RawPath = TmpDir;
       return FE;
     }
   }
@@ -283,7 +298,7 @@ const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     const FileEntry *FE =
-      SearchDirs[i].LookupFile(Filename, *this);
+      SearchDirs[i].LookupFile(Filename, *this, RawPath);
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];
@@ -308,7 +323,8 @@ const FileEntry *HeaderSearch::LookupFile(llvm::StringRef Filename,
 /// for the designated file, otherwise return null.
 const FileEntry *HeaderSearch::
 LookupSubframeworkHeader(llvm::StringRef Filename,
-                         const FileEntry *ContextFileEnt) {
+                         const FileEntry *ContextFileEnt,
+                         llvm::SmallVectorImpl<char> *RawPath) {
   assert(ContextFileEnt && "No context file?");
 
   // Framework names must have a '/' in the filename.  Find it.
@@ -369,6 +385,8 @@ LookupSubframeworkHeader(llvm::StringRef Filename,
     if (!(FE = FileMgr.getFile(HeadersFilename.str())))
       return 0;
   }
+  if (RawPath != NULL)
+    *RawPath = HeadersFilename;
 
   // This file is a system header or C++ unfriendly if the old file is.
   //
index cea0798f6e514758c918b83b6acd1f5dd3d0d7b2..bfb6641a758d4a9a073799e38ca9b2690b9e5cc5 100644 (file)
@@ -469,10 +469,12 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() {
 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
 /// return null on failure.  isAngled indicates whether the file reference is
 /// for system #include's or not (i.e. using <> instead of "").
-const FileEntry *Preprocessor::LookupFile(llvm::StringRef Filename,
-                                          bool isAngled,
-                                          const DirectoryLookup *FromDir,
-                                          const DirectoryLookup *&CurDir) {
+const FileEntry *Preprocessor::LookupFile(
+    llvm::StringRef Filename,
+    bool isAngled,
+    const DirectoryLookup *FromDir,
+    const DirectoryLookup *&CurDir,
+    llvm::SmallVectorImpl<char> *RawPath) {
   // If the header lookup mechanism may be relative to the current file, pass in
   // info about where the current file is.
   const FileEntry *CurFileEnt = 0;
@@ -494,8 +496,8 @@ const FileEntry *Preprocessor::LookupFile(llvm::StringRef Filename,
 
   // Do a standard file entry lookup.
   CurDir = CurDirLookup;
-  const FileEntry *FE =
-    HeaderInfo.LookupFile(Filename, isAngled, FromDir, CurDir, CurFileEnt);
+  const FileEntry *FE = HeaderInfo.LookupFile(
+      Filename, isAngled, FromDir, CurDir, CurFileEnt, RawPath);
   if (FE) return FE;
 
   // Otherwise, see if this is a subframework header.  If so, this is relative
@@ -503,7 +505,8 @@ const FileEntry *Preprocessor::LookupFile(llvm::StringRef Filename,
   // headers on the #include stack and pass them to HeaderInfo.
   if (IsFileLexer()) {
     if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
-      if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
+      if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
+                                                    RawPath)))
         return FE;
   }
 
@@ -512,7 +515,8 @@ const FileEntry *Preprocessor::LookupFile(llvm::StringRef Filename,
     if (IsFileLexer(ISEntry)) {
       if ((CurFileEnt =
            SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
-        if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt)))
+        if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
+                                                      RawPath)))
           return FE;
     }
   }
@@ -1167,7 +1171,11 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
 
   // Search include directories.
   const DirectoryLookup *CurDir;
-  const FileEntry *File = LookupFile(Filename, isAngled, LookupFrom, CurDir);
+  llvm::SmallString<1024> RawPath;
+  // We get the raw path only if we have 'Callbacks' to which we later pass
+  // the path.
+  const FileEntry *File = LookupFile(
+      Filename, isAngled, LookupFrom, CurDir, Callbacks ? &RawPath : NULL);
   if (File == 0) {
     Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
     return;
@@ -1175,9 +1183,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
 
   // Notify the callback object that we've seen an inclusion directive.
   if (Callbacks)
-    Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File, 
-                                  End);
-  
+    Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File,
+                                  End, RawPath);
+
   // The #included file will be considered to be a system header if either it is
   // in a system include directory, or if the #includer is a system include
   // header.
index 858090acb843bbcfc2cdb0f7cf2a45383bab260e..62d3dba5cc6fc869a9e6193c9fd8fc7c0119d3cb 100644 (file)
@@ -662,7 +662,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
 
   // Search include directories.
   const DirectoryLookup *CurDir;
-  const FileEntry *File = PP.LookupFile(Filename, isAngled, LookupFrom, CurDir);
+  const FileEntry *File =
+      PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL);
 
   // Get the result value.  Result = true means the file exists.
   bool Result = File != 0;
index 8fd5ec253edd2fbf7072b1f9e2644c7567c3ecfd..5d6ad6e7161168ef267f51cb9a0fda30e5901c15 100644 (file)
@@ -368,7 +368,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
 
   // Search include directories for this file.
   const DirectoryLookup *CurDir;
-  const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir);
+  const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL);
   if (File == 0) {
     Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
     return;
index 3a43ac11e4e02e3aa1d3e102e89bfe9a8a5973f9..b7f6e75c47c7f43473104e1dba8f29ac4808ecbb 100644 (file)
@@ -146,12 +146,14 @@ void PreprocessingRecord::MacroUndefined(const Token &Id,
     MacroDefinitions.erase(Pos);
 }
 
-void PreprocessingRecord::InclusionDirective(SourceLocation HashLoc,
-                                             const clang::Token &IncludeTok, 
-                                             llvm::StringRef FileName, 
-                                             bool IsAngled, 
-                                             const FileEntry *File,
-                                           clang::SourceLocation EndLoc) {
+void PreprocessingRecord::InclusionDirective(
+    SourceLocation HashLoc,
+    const clang::Token &IncludeTok,
+    llvm::StringRef FileName,
+    bool IsAngled,
+    const FileEntry *File,
+    clang::SourceLocation EndLoc,
+    const llvm::SmallVectorImpl<char> &RawPath) {
   InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
   
   switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {