diff options
-rw-r--r-- | include/clang/Lex/DirectoryLookup.h | 21 | ||||
-rw-r--r-- | include/clang/Lex/HeaderMap.h | 3 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 33 | ||||
-rw-r--r-- | include/clang/Lex/PPCallbacks.h | 24 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessingRecord.h | 3 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 3 | ||||
-rw-r--r-- | lib/Lex/HeaderMap.cpp | 5 | ||||
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 102 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 20 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PreprocessingRecord.cpp | 3 |
12 files changed, 161 insertions, 60 deletions
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index 1ee19266f3..1ee6953a12 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -122,17 +122,26 @@ public: /// LookupFile - Lookup the specified file in this search path, returning it /// if it exists or returning null if not. - /// 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". + /// + /// \param Filename The file to look up relative to the search paths. + /// + /// \param HS The header search instance to search with. + /// + /// \param SearchPath If not NULL, will be set to the search path relative + /// to which the file was found. + /// + /// \param RelativePath If not NULL, will be set to the path relative to + /// SearchPath at which the file was found. This only differs from the + /// Filename for framework includes. const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS, - llvm::SmallVectorImpl<char> *RawPath) const; + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) const; private: const FileEntry *DoFrameworkLookup( llvm::StringRef Filename, HeaderSearch &HS, - llvm::SmallVectorImpl<char> *RawPath) const; + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) const; }; diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 54c7eb47c8..e333840b6a 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -52,8 +52,7 @@ public: /// 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; + const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) const; /// getFileName - Return the filename of the headermap. const char *getFileName() const; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 3ba780438f..fec4dad1e7 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -182,18 +182,32 @@ public: } /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, - /// return null on failure. isAngled indicates whether the file reference is - /// a <> reference. If successful, this returns 'UsedDir', the - /// DirectoryLookup member the file was found in, or null if not applicable. - /// If CurDir is non-null, the file was found in the specified directory - /// search location. This is used to implement #include_next. CurFileEnt, if - /// non-null, indicates where the #including file is, in case a relative - /// search is needed. + /// return null on failure. + /// + /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member + /// the file was found in, or null if not applicable. + /// + /// \param isAngled indicates whether the file reference is a <> reference. + /// + /// \param CurDir If non-null, the file was found in the specified directory + /// search location. This is used to implement #include_next. + /// + /// \param CurFileEnt If non-null, indicates where the #including file is, in + /// case a relative search is needed. + /// + /// \param SearchPath If non-null, will be set to the search path relative + /// to which the file was found. If the include path is absolute, SearchPath + /// will be set to an empty string. + /// + /// \param RelativePath If non-null, will be set to the path relative to + /// SearchPath at which the file was found. This only differs from the + /// Filename for framework includes. const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt, - llvm::SmallVectorImpl<char> *RawPath); + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath); /// LookupSubframeworkHeader - Look up a subframework for the specified /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from @@ -203,7 +217,8 @@ public: const FileEntry *LookupSubframeworkHeader( llvm::StringRef Filename, const FileEntry *RelativeFileEnt, - llvm::SmallVectorImpl<char> *RawPath); + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath); /// LookupFrameworkCache - Look up the specified framework name in our /// framework cache, returning the DirectoryEntry it is in if we know, diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 242986dae5..fd07a29f8e 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -76,16 +76,25 @@ 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". + /// \param SearchPath Contains the search path which was used to find the file + /// in the file system. If the file was found via an absolute include path, + /// SearchPath will be empty. For framework includes, the SearchPath and + /// RelativePath will be split up. For example, if an include of "Some/Some.h" + /// is found via the framework path + /// "path/to/Frameworks/Some.framework/Headers/Some.h", SearchPath will be + /// "path/to/Frameworks/Some.framework/Headers" and RelativePath will be + /// "Some.h". + /// + /// \param RelativePath The path relative to SearchPath, at which the include + /// file was found. This is equal to FileName except for framework includes. virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, llvm::StringRef FileName, bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - const llvm::SmallVectorImpl<char> &RawPath) { + llvm::StringRef SearchPath, + llvm::StringRef RelativePath) { } /// EndOfMainFile - This callback is invoked when the end of the main file is @@ -194,11 +203,12 @@ public: bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - const llvm::SmallVectorImpl<char> &RawPath) { + llvm::StringRef SearchPath, + llvm::StringRef RelativePath) { First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, - EndLoc, RawPath); + EndLoc, SearchPath, RelativePath); Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File, - EndLoc, RawPath); + EndLoc, SearchPath, RelativePath); } virtual void EndOfMainFile() { diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index f5066d4bfd..7be845549d 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -342,7 +342,8 @@ namespace clang { bool IsAngled, const FileEntry *File, SourceLocation EndLoc, - const llvm::SmallVectorImpl<char> &RawPath); + llvm::StringRef SearchPath, + llvm::StringRef RelativePath); }; } // end namespace clang diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 04b3e3224f..af3631de52 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -834,7 +834,8 @@ public: const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, - llvm::SmallVectorImpl<char> *RawPath); + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath); /// GetCurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp index 90ed184a57..e102a6da60 100644 --- a/lib/Lex/HeaderMap.cpp +++ b/lib/Lex/HeaderMap.cpp @@ -200,8 +200,7 @@ 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, - llvm::SmallVectorImpl<char> *RawPath) const { + llvm::StringRef Filename, FileManager &FM) const { const HMapHeader &Hdr = getHeader(); unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets); @@ -224,8 +223,6 @@ const FileEntry *HeaderMap::LookupFile( 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 db91ba4e78..1fe0240f43 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -116,7 +116,9 @@ const char *DirectoryLookup::getName() const { /// if it exists or returning null if not. const FileEntry *DirectoryLookup::LookupFile( llvm::StringRef Filename, - HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const { + HeaderSearch &HS, + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) const { llvm::SmallString<1024> TmpDir; if (isNormalDir()) { // Concatenate the requested file onto the directory. @@ -124,16 +126,36 @@ const FileEntry *DirectoryLookup::LookupFile( TmpDir += getDir()->getName(); TmpDir.push_back('/'); TmpDir.append(Filename.begin(), Filename.end()); - if (RawPath != NULL) - *RawPath = TmpDir; + if (SearchPath != NULL) { + llvm::StringRef SearchPathRef(getDir()->getName()); + SearchPath->clear(); + SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); + } + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin(), Filename.end()); + } return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); } if (isFramework()) - return DoFrameworkLookup(Filename, HS, RawPath); + return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath); assert(isHeaderMap() && "Unknown directory lookup"); - return getHeaderMap()->LookupFile(Filename, HS.getFileMgr(), RawPath); + const FileEntry * const Result = getHeaderMap()->LookupFile( + Filename, HS.getFileMgr()); + if (Result) { + if (SearchPath != NULL) { + llvm::StringRef SearchPathRef(getDir()->getName()); + SearchPath->clear(); + SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); + } + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin(), Filename.end()); + } + } + return Result; } @@ -141,7 +163,9 @@ const FileEntry *DirectoryLookup::LookupFile( /// DirectoryLookup, which is a framework directory. const FileEntry *DirectoryLookup::DoFrameworkLookup( llvm::StringRef Filename, - HeaderSearch &HS, llvm::SmallVectorImpl<char> *RawPath) const { + HeaderSearch &HS, + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) const { FileManager &FileMgr = HS.getFileMgr(); // Framework names must have a '/' in the filename. @@ -187,15 +211,25 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( FrameworkDirCache = getFrameworkDir(); } + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); + } + // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" unsigned OrigSize = FrameworkName.size(); FrameworkName += "Headers/"; + + if (SearchPath != NULL) { + SearchPath->clear(); + // Without trailing '/'. + SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); + } + FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/true)) { - if (RawPath != NULL) - *RawPath = FrameworkName; return FE; } @@ -203,8 +237,10 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( const char *Private = "Private"; FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, Private+strlen(Private)); - if (RawPath != NULL) - *RawPath = FrameworkName; + if (SearchPath != NULL) + SearchPath->insert(SearchPath->begin()+OrigSize, Private, + Private+strlen(Private)); + return FileMgr.getFile(FrameworkName.str(), /*openFile=*/true); } @@ -225,7 +261,8 @@ const FileEntry *HeaderSearch::LookupFile( const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt, - llvm::SmallVectorImpl<char> *RawPath) { + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) { // If 'Filename' is absolute, check to see if it exists and no searching. if (llvm::sys::path::is_absolute(Filename)) { CurDir = 0; @@ -233,8 +270,12 @@ const FileEntry *HeaderSearch::LookupFile( // If this was an #include_next "/absolute/file", fail. if (FromDir) return 0; - if (RawPath != NULL) - llvm::Twine(Filename).toVector(*RawPath); + if (SearchPath != NULL) + SearchPath->clear(); + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin(), Filename.end()); + } // Otherwise, just return the file. return FileMgr.getFile(Filename, /*openFile=*/true); } @@ -260,8 +301,15 @@ const FileEntry *HeaderSearch::LookupFile( // of evaluation. unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo; getFileInfo(FE).DirInfo = DirInfo; - if (RawPath != NULL) - *RawPath = TmpDir; + if (SearchPath != NULL) { + llvm::StringRef SearchPathRef(CurFileEnt->getDir()->getName()); + SearchPath->clear(); + SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); + } + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin(), Filename.end()); + } return FE; } } @@ -299,7 +347,7 @@ const FileEntry *HeaderSearch::LookupFile( // 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, RawPath); + SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath); if (!FE) continue; CurDir = &SearchDirs[i]; @@ -325,7 +373,8 @@ const FileEntry *HeaderSearch::LookupFile( const FileEntry *HeaderSearch:: LookupSubframeworkHeader(llvm::StringRef Filename, const FileEntry *ContextFileEnt, - llvm::SmallVectorImpl<char> *RawPath) { + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) { assert(ContextFileEnt && "No context file?"); // Framework names must have a '/' in the filename. Find it. @@ -373,21 +422,36 @@ LookupSubframeworkHeader(llvm::StringRef Filename, const FileEntry *FE = 0; + if (RelativePath != NULL) { + RelativePath->clear(); + RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); + } + // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" llvm::SmallString<1024> HeadersFilename(FrameworkName); HeadersFilename += "Headers/"; + if (SearchPath != NULL) { + SearchPath->clear(); + // Without trailing '/'. + SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); + } + HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" HeadersFilename = FrameworkName; HeadersFilename += "PrivateHeaders/"; + if (SearchPath != NULL) { + SearchPath->clear(); + // Without trailing '/'. + SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); + } + HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 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 ac4f8e0b8f..af3fa6e2ad 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -474,7 +474,8 @@ const FileEntry *Preprocessor::LookupFile( bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, - llvm::SmallVectorImpl<char> *RawPath) { + llvm::SmallVectorImpl<char> *SearchPath, + llvm::SmallVectorImpl<char> *RelativePath) { // 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; @@ -497,7 +498,8 @@ const FileEntry *Preprocessor::LookupFile( // Do a standard file entry lookup. CurDir = CurDirLookup; const FileEntry *FE = HeaderInfo.LookupFile( - Filename, isAngled, FromDir, CurDir, CurFileEnt, RawPath); + Filename, isAngled, FromDir, CurDir, CurFileEnt, + SearchPath, RelativePath); if (FE) return FE; // Otherwise, see if this is a subframework header. If so, this is relative @@ -506,7 +508,7 @@ const FileEntry *Preprocessor::LookupFile( if (IsFileLexer()) { if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt, - RawPath))) + SearchPath, RelativePath))) return FE; } @@ -515,8 +517,8 @@ const FileEntry *Preprocessor::LookupFile( if (IsFileLexer(ISEntry)) { if ((CurFileEnt = SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID()))) - if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt, - RawPath))) + if ((FE = HeaderInfo.LookupSubframeworkHeader( + Filename, CurFileEnt, SearchPath, RelativePath))) return FE; } } @@ -1171,11 +1173,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // Search include directories. const DirectoryLookup *CurDir; - llvm::SmallString<1024> RawPath; + llvm::SmallString<1024> SearchPath; + llvm::SmallString<1024> RelativePath; // 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); + Filename, isAngled, LookupFrom, CurDir, + Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL); if (File == 0) { Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; return; @@ -1184,7 +1188,7 @@ 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, RawPath); + End, SearchPath, RelativePath); // 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 diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 0e38e39c26..29f9cd6e32 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -668,7 +668,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, // Search include directories. const DirectoryLookup *CurDir; const FileEntry *File = - PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL); + PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, 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 5d6ad6e716..0c180918dc 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, NULL); + const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, 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 b7f6e75c47..9555611dc5 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -153,7 +153,8 @@ void PreprocessingRecord::InclusionDirective( bool IsAngled, const FileEntry *File, clang::SourceLocation EndLoc, - const llvm::SmallVectorImpl<char> &RawPath) { + llvm::StringRef SearchPath, + llvm::StringRef RelativePath) { InclusionDirective::InclusionKind Kind = InclusionDirective::Include; switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { |