diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-03-16 18:34:36 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-03-16 18:34:36 +0000 |
commit | b5142bb7af5c70fffd09f05172a1379a35a9c29a (patch) | |
tree | 2d853fec292436890550beaa0f2fd014c5f3fb83 /lib/Lex | |
parent | 60b3e38d421cab497de1c62c06be6a6a5f321edf (diff) |
Add a 'RawPath' parameter to the PPCallbacks interface. This allows
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
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/HeaderMap.cpp | 7 | ||||
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 46 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 32 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 3 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PreprocessingRecord.cpp | 14 |
6 files changed, 68 insertions, 36 deletions
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp index e424f91655..90ed184a57 100644 --- a/lib/Lex/HeaderMap.cpp +++ b/lib/Lex/HeaderMap.cpp @@ -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()); } } diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index b028e339ae..bb4ff60480 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -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. // diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index cea0798f6e..bfb6641a75 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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. diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 858090acb8..62d3dba5cc 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -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; diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 8fd5ec253e..5d6ad6e716 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -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; diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index 3a43ac11e4..b7f6e75c47 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -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()) { |