diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 8 | ||||
-rw-r--r-- | lib/Basic/FileManager.cpp | 60 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 7 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 17 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/ASTMerge.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 33 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 32 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 28 | ||||
-rw-r--r-- | lib/Frontend/FrontendAction.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/InitHeaderSearch.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 12 | ||||
-rw-r--r-- | lib/Lex/HeaderMap.cpp | 10 | ||||
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 30 | ||||
-rw-r--r-- | lib/Lex/PTHLexer.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 17 |
18 files changed, 212 insertions, 75 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index a8cb1c5bed..7747e617e3 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -2980,9 +2980,12 @@ Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { ASTImporter::ASTImporter(Diagnostic &Diags, ASTContext &ToContext, FileManager &ToFileManager, - ASTContext &FromContext, FileManager &FromFileManager) + const FileSystemOptions &ToFileSystemOpts, + ASTContext &FromContext, FileManager &FromFileManager, + const FileSystemOptions &FromFileSystemOpts) : ToContext(ToContext), FromContext(FromContext), ToFileManager(ToFileManager), FromFileManager(FromFileManager), + ToFileSystemOpts(ToFileSystemOpts), FromFileSystemOpts(FromFileSystemOpts), Diags(Diags) { ImportedDecls[FromContext.getTranslationUnitDecl()] = ToContext.getTranslationUnitDecl(); @@ -3153,7 +3156,8 @@ FileID ASTImporter::Import(FileID FromID) { // disk again // FIXME: We definitely want to re-use the existing MemoryBuffer, rather // than mmap the files several times. - const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName()); + const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName(), + ToFileSystemOpts); ToID = ToSM.createFileID(Entry, ToIncludeLoc, FromSLoc.getFile().getFileCharacteristic()); } else { diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp index 565f8a61de..247ba1b752 100644 --- a/lib/Basic/FileManager.cpp +++ b/lib/Basic/FileManager.cpp @@ -18,8 +18,10 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Path.h" #include "llvm/Config/config.h" @@ -197,7 +199,8 @@ void FileManager::removeStatCache(StatSysCallCache *statCache) { /// \brief Retrieve the directory that the given file name resides in. static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, const char *NameStart, - const char *NameEnd) { + const char *NameEnd, + const FileSystemOptions &FileSystemOpts) { // Figure out what directory it is in. If the string contains a / in it, // strip off everything after it. // FIXME: this logic should be in sys::Path. @@ -211,18 +214,19 @@ static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, if (SlashPos < NameStart) { // Use the current directory if file has no path component. const char *Name = "."; - return FileMgr.getDirectory(Name, Name+1); + return FileMgr.getDirectory(Name, Name+1, FileSystemOpts); } else if (SlashPos == NameEnd-1) return 0; // If filename ends with a /, it's a directory. else - return FileMgr.getDirectory(NameStart, SlashPos); + return FileMgr.getDirectory(NameStart, SlashPos, FileSystemOpts); } /// getDirectory - Lookup, cache, and verify the specified directory. This /// returns null if the directory doesn't exist. /// const DirectoryEntry *FileManager::getDirectory(const char *NameStart, - const char *NameEnd) { + const char *NameEnd, + const FileSystemOptions &FileSystemOpts) { // stat doesn't like trailing separators (at least on Windows). if (((NameEnd - NameStart) > 1) && ((*(NameEnd - 1) == '/') || (*(NameEnd - 1) == '\\'))) @@ -248,7 +252,7 @@ const DirectoryEntry *FileManager::getDirectory(const char *NameStart, // Check to see if the directory exists. struct stat StatBuf; - if (stat_cached(InterndDirName, &StatBuf) || // Error stat'ing. + if (stat_cached(InterndDirName, &StatBuf, FileSystemOpts) || // Error stat'ing. !S_ISDIR(StatBuf.st_mode)) // Not a directory? return 0; @@ -274,7 +278,8 @@ const DirectoryEntry *FileManager::getDirectory(const char *NameStart, /// if the file doesn't exist. /// const FileEntry *FileManager::getFile(const char *NameStart, - const char *NameEnd) { + const char *NameEnd, + const FileSystemOptions &FileSystemOpts) { ++NumFileLookups; // See if there is already an entry in the map. @@ -297,7 +302,7 @@ const FileEntry *FileManager::getFile(const char *NameStart, const char *InterndFileName = NamedFileEnt.getKeyData(); const DirectoryEntry *DirInfo - = getDirectoryFromFile(*this, NameStart, NameEnd); + = getDirectoryFromFile(*this, NameStart, NameEnd, FileSystemOpts); if (DirInfo == 0) // Directory doesn't exist, file can't exist. return 0; @@ -307,7 +312,7 @@ const FileEntry *FileManager::getFile(const char *NameStart, // Nope, there isn't. Check to see if the file exists. struct stat StatBuf; //llvm::errs() << "STATING: " << Filename; - if (stat_cached(InterndFileName, &StatBuf) || // Error stat'ing. + if (stat_cached(InterndFileName, &StatBuf, FileSystemOpts) || // Error stat'ing. S_ISDIR(StatBuf.st_mode)) { // A directory? // If this file doesn't exist, we leave a null in FileEntries for this path. //llvm::errs() << ": Not existing\n"; @@ -336,7 +341,8 @@ const FileEntry *FileManager::getFile(const char *NameStart, const FileEntry * FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size, - time_t ModificationTime) { + time_t ModificationTime, + const FileSystemOptions &FileSystemOpts) { const char *NameStart = Filename.begin(), *NameEnd = Filename.end(); ++NumFileLookups; @@ -356,7 +362,7 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size, NamedFileEnt.setValue(NON_EXISTENT_FILE); const DirectoryEntry *DirInfo - = getDirectoryFromFile(*this, NameStart, NameEnd); + = getDirectoryFromFile(*this, NameStart, NameEnd, FileSystemOpts); if (DirInfo == 0) // Directory doesn't exist, file can't exist. return 0; @@ -374,7 +380,7 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size, // newly-created file entry. const char *InterndFileName = NamedFileEnt.getKeyData(); struct stat StatBuf; - if (!stat_cached(InterndFileName, &StatBuf) && + if (!stat_cached(InterndFileName, &StatBuf, FileSystemOpts) && !S_ISDIR(StatBuf.st_mode)) { llvm::sys::Path FilePath(InterndFileName); FilePath.makeAbsolute(); @@ -384,6 +390,38 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size, return UFE; } +llvm::MemoryBuffer *FileManager::getBufferForFile(const char *FilenameStart, + const char *FilenameEnd, + const FileSystemOptions &FileSystemOpts, + std::string *ErrorStr, + int64_t FileSize, + struct stat *FileInfo) { + llvm::sys::Path FilePath(llvm::StringRef(FilenameStart, + FilenameEnd-FilenameStart)); + FixupRelativePath(FilePath, FileSystemOpts); + + return llvm::MemoryBuffer::getFile(FilePath.c_str(), ErrorStr, + FileSize, FileInfo); +} + +int FileManager::stat_cached(const char* path, struct stat* buf, + const FileSystemOptions &FileSystemOpts) { + llvm::sys::Path FilePath(path); + FixupRelativePath(FilePath, FileSystemOpts); + + return StatCache.get() ? StatCache->stat(FilePath.c_str(), buf) + : stat(FilePath.c_str(), buf); +} + +void FileManager::FixupRelativePath(llvm::sys::Path &path, + const FileSystemOptions &FSOpts) { + if (!FSOpts.WorkingDir.empty() && !path.isAbsolute()) { + llvm::sys::Path NewPath(FSOpts.WorkingDir); + NewPath.appendComponent(path.str()); + path = NewPath; + } +} + void FileManager::PrintStats() const { llvm::errs() << "\n*** File Manager Stats:\n"; llvm::errs() << UniqueFiles.size() << " files found, " diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 7127e80018..97af0d6fe3 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -73,9 +73,10 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag, if (!Buffer.getPointer() && Entry) { std::string ErrorStr; struct stat FileInfo; - Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr, - Entry->getSize(), &FileInfo)); - + Buffer.setPointer(SM.getFileManager().getBufferForFile(Entry, + SM.getFileSystemOpts(), + &ErrorStr, &FileInfo)); + // If we were unable to open the file, then we are in an inconsistent // situation where the content cache referenced a file which no longer // exists. Most likely, we were using a stat cache with an invalid entry but diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 1355206065..c7a7434837 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -753,10 +753,19 @@ void Driver::BuildActions(const ToolChain &TC, const ArgList &Args, } // Check that the file exists, if enabled. - if (CheckInputsExist && memcmp(Value, "-", 2) != 0 && - !llvm::sys::Path(Value).exists()) - Diag(clang::diag::err_drv_no_such_file) << A->getValue(Args); - else + if (CheckInputsExist && memcmp(Value, "-", 2) != 0) { + llvm::sys::Path Path(Value); + if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) + if (!Path.isAbsolute()) { + Path = WorkDir->getValue(Args); + Path.appendComponent(Value); + } + + if (!Path.exists()) + Diag(clang::diag::err_drv_no_such_file) << Path.str(); + else + Inputs.push_back(std::make_pair(Ty, A)); + } else Inputs.push_back(std::make_pair(Ty, A)); } else if (A->getOption().isLinkerInput()) { diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 7ba1dc8be7..744b0ae661 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1073,6 +1073,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-resource-dir"); CmdArgs.push_back(D.ResourceDir.c_str()); + Args.AddLastArg(CmdArgs, options::OPT_working_directory); + // Add preprocessing options like -I, -D, etc. if we are using the // preprocessor. // diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp index b46212feda..f270846343 100644 --- a/lib/Frontend/ASTMerge.cpp +++ b/lib/Frontend/ASTMerge.cpp @@ -40,7 +40,8 @@ void ASTMergeAction::ExecuteAction() { &CI.getASTContext()); llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics()); for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) { - ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, false); + ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags, + CI.getFileSystemOpts(), false); if (!Unit) continue; @@ -53,8 +54,10 @@ void ASTMergeAction::ExecuteAction() { ASTImporter Importer(CI.getDiagnostics(), CI.getASTContext(), CI.getFileManager(), + CI.getFileSystemOpts(), Unit->getASTContext(), - Unit->getFileManager()); + Unit->getFileManager(), + Unit->getFileSystemOpts()); TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl(); for (DeclContext::decl_iterator D = TU->decls_begin(), diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index b07ed12f75..bbee11ba7c 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -449,8 +449,17 @@ const std::string &ASTUnit::getASTFileName() { return static_cast<ASTReader *>(Ctx->getExternalSource())->getFileName(); } +llvm::MemoryBuffer *ASTUnit::getBufferForFile(llvm::StringRef Filename, + std::string *ErrorStr, + int64_t FileSize, + struct stat *FileInfo) { + return FileMgr->getBufferForFile(Filename, FileSystemOpts, + ErrorStr, FileSize, FileInfo); +} + ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls, RemappedFile *RemappedFiles, unsigned NumRemappedFiles, @@ -467,9 +476,13 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, AST->CaptureDiagnostics = CaptureDiagnostics; AST->OnlyLocalDecls = OnlyLocalDecls; AST->Diagnostics = Diags; + AST->FileSystemOpts = FileSystemOpts; AST->FileMgr.reset(new FileManager); - AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics())); - AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); + AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics(), + AST->getFileManager(), + AST->getFileSystemOpts())); + AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager(), + AST->getFileSystemOpts())); // If requested, capture diagnostics in the ASTUnit. CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(), @@ -480,7 +493,8 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, const FileEntry *FromFile = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, RemappedFiles[I].second->getBufferSize(), - 0); + 0, + AST->getFileSystemOpts()); if (!FromFile) { AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) << RemappedFiles[I].first; @@ -505,7 +519,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, llvm::OwningPtr<ASTReader> Reader; Reader.reset(new ASTReader(AST->getSourceManager(), AST->getFileManager(), - AST->getDiagnostics())); + AST->getFileSystemOpts(), AST->getDiagnostics())); Reader->setListener(new ASTInfoCollector(LangInfo, HeaderInfo, TargetTriple, Predefines, Counter)); @@ -732,7 +746,8 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { // Configure the various subsystems. // FIXME: Should we retain the previous file manager? FileMgr.reset(new FileManager); - SourceMgr.reset(new SourceManager(getDiagnostics())); + FileSystemOpts = Clang.getFileSystemOpts(); + SourceMgr.reset(new SourceManager(getDiagnostics(), *FileMgr, FileSystemOpts)); TheSema.reset(); Ctx.reset(); PP.reset(); @@ -908,7 +923,7 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, CreatedBuffer = false; } - Buffer = llvm::MemoryBuffer::getFile(M->second); + Buffer = getBufferForFile(M->second); if (!Buffer) return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); @@ -941,7 +956,7 @@ ASTUnit::ComputePreamble(CompilerInvocation &Invocation, // If the main source file was not remapped, load it now. if (!Buffer) { - Buffer = llvm::MemoryBuffer::getFile(FrontendOpts.Inputs[0].second); + Buffer = getBufferForFile(FrontendOpts.Inputs[0].second); if (!Buffer) return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); @@ -1240,7 +1255,9 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( Clang.setFileManager(new FileManager); // Create the source manager. - Clang.setSourceManager(new SourceManager(getDiagnostics())); + Clang.setSourceManager(new SourceManager(getDiagnostics(), + Clang.getFileManager(), + Clang.getFileSystemOpts())); llvm::OwningPtr<PrecompilePreambleAction> Act; Act.reset(new PrecompilePreambleAction(*this)); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 95d417f633..c5e5d7f90a 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -148,8 +148,9 @@ void CompilerInstance::createFileManager() { // Source Manager -void CompilerInstance::createSourceManager() { - SourceMgr.reset(new SourceManager(getDiagnostics())); +void CompilerInstance::createSourceManager(FileManager &FileMgr, + const FileSystemOptions &FSOpts) { + SourceMgr.reset(new SourceManager(getDiagnostics(), FileMgr, FSOpts)); } // Preprocessor @@ -158,8 +159,8 @@ void CompilerInstance::createPreprocessor() { PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(), getPreprocessorOpts(), getHeaderSearchOpts(), getDependencyOutputOpts(), getTarget(), - getFrontendOpts(), getSourceManager(), - getFileManager())); + getFrontendOpts(), getFileSystemOpts(), + getSourceManager(), getFileManager())); } Preprocessor * @@ -170,15 +171,16 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, const DependencyOutputOptions &DepOpts, const TargetInfo &Target, const FrontendOptions &FEOpts, + const FileSystemOptions &FSOpts, SourceManager &SourceMgr, FileManager &FileMgr) { // Create a PTH manager if we are using some form of a token cache. PTHManager *PTHMgr = 0; if (!PPOpts.TokenCache.empty()) - PTHMgr = PTHManager::Create(PPOpts.TokenCache, Diags); + PTHMgr = PTHManager::Create(PPOpts.TokenCache, FileMgr, FSOpts, Diags); // Create the Preprocessor. - HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr); + HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr, FSOpts); Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target, SourceMgr, *HeaderInfo, PTHMgr, /*OwnsHeaderSearch=*/true); @@ -194,7 +196,7 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, if (PPOpts.DetailedRecord) PP->createPreprocessingRecord(); - InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts); + InitializePreprocessor(*PP, FSOpts, PPOpts, HSOpts, FEOpts); // Handle generating dependencies, if requested. if (!DepOpts.OutputFile.empty()) @@ -271,7 +273,8 @@ static bool EnableCodeCompletion(Preprocessor &PP, unsigned Column) { // Tell the source manager to chop off the given file at a specific // line and column. - const FileEntry *Entry = PP.getFileManager().getFile(Filename); + const FileEntry *Entry = PP.getFileManager().getFile(Filename, + PP.getFileSystemOpts()); if (!Entry) { PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) << Filename; @@ -352,7 +355,11 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) { TempPath.eraseFromDisk(); else { std::string Error; - if (TempPath.renamePathOnDisk(llvm::sys::Path(it->Filename), &Error)) { + llvm::sys::Path NewOutFile(it->Filename); + // If '-working-directory' was passed, the output filename should be + // relative to that. + FileManager::FixupRelativePath(NewOutFile, getFileSystemOpts()); + if (TempPath.renamePathOnDisk(NewOutFile, &Error)) { getDiagnostics().Report(diag::err_fe_unable_to_rename_temp) << it->TempFilename << it->Filename << Error; TempPath.eraseFromDisk(); @@ -457,17 +464,19 @@ CompilerInstance::createOutputFile(llvm::StringRef OutputPath, bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile) { return InitializeSourceManager(InputFile, getDiagnostics(), getFileManager(), + getFileSystemOpts(), getSourceManager(), getFrontendOpts()); } bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, Diagnostic &Diags, FileManager &FileMgr, + const FileSystemOptions &FSOpts, SourceManager &SourceMgr, const FrontendOptions &Opts) { // Figure out where to get and map in the main file. if (InputFile != "-") { - const FileEntry *File = FileMgr.getFile(InputFile); + const FileEntry *File = FileMgr.getFile(InputFile, FSOpts); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; @@ -480,7 +489,8 @@ bool CompilerInstance::InitializeSourceManager(llvm::StringRef InputFile, return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), - SB->getBufferSize(), 0); + SB->getBufferSize(), 0, + FSOpts); SourceMgr.createMainFileID(File); SourceMgr.overrideFileContents(File, SB); } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 561555ad1f..b20520bbee 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -10,6 +10,7 @@ #include "clang/Frontend/CompilerInvocation.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/Version.h" +#include "clang/Basic/FileManager.h" #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/CC1Options.h" @@ -351,6 +352,14 @@ static const char *getActionName(frontend::ActionKind Kind) { return 0; } +static void FileSystemOptsToArgs(const FileSystemOptions &Opts, + std::vector<std::string> &Res) { + if (!Opts.WorkingDir.empty()) { + Res.push_back("-working-directory"); + Res.push_back(Opts.WorkingDir); + } +} + static void FrontendOptsToArgs(const FrontendOptions &Opts, std::vector<std::string> &Res) { if (Opts.DisableFree) @@ -743,6 +752,7 @@ void CompilerInvocation::toArgs(std::vector<std::string> &Res) { CodeGenOptsToArgs(getCodeGenOpts(), Res); DependencyOutputOptsToArgs(getDependencyOutputOpts(), Res); DiagnosticOptsToArgs(getDiagnosticOpts(), Res); + FileSystemOptsToArgs(getFileSystemOpts(), Res); FrontendOptsToArgs(getFrontendOpts(), Res); HeaderSearchOptsToArgs(getHeaderSearchOpts(), Res); LangOptsToArgs(getLangOpts(), Res); @@ -979,6 +989,10 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.Warnings = Args.getAllArgValues(OPT_W); } +static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) { + Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory); +} + static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) { using namespace cc1options; @@ -1402,6 +1416,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, + FileManager &FileMgr, + const FileSystemOptions &FSOpts, Diagnostic &Diags) { using namespace cc1options; Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch); @@ -1456,7 +1472,8 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, // PCH is handled specially, we need to extra the original include path. if (A->getOption().matches(OPT_include_pch)) { std::string OriginalFile = - ASTReader::getOriginalSourceFile(A->getValue(Args), Diags); + ASTReader::getOriginalSourceFile(A->getValue(Args), FileMgr, FSOpts, + Diags); if (OriginalFile.empty()) continue; @@ -1535,11 +1552,18 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, Diags); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args); ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags); + ParseFileSystemArgs(Res.getFileSystemOpts(), *Args); InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags); ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args); if (DashX != IK_AST && DashX != IK_LLVM_IR) ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags); - ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, Diags); + // FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of + // PCH file and find the original header name. Remove the need to do that in + // ParsePreprocessorArgs and remove the FileManager & FileSystemOptions + // parameters from the function and the "FileManager.h" #include. + FileManager FileMgr; + ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, + FileMgr, Res.getFileSystemOpts(), Diags); ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args); ParseTargetArgs(Res.getTargetOpts(), *Args); } diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp index 48f115fd3e..cfa0b6dbd3 100644 --- a/lib/Frontend/FrontendAction.cpp +++ b/lib/Frontend/FrontendAction.cpp @@ -103,7 +103,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, llvm::IntrusiveRefCntPtr<Diagnostic> Diags(&CI.getDiagnostics()); std::string Error; - ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags); + ASTUnit *AST = ASTUnit::LoadFromASTFile(Filename, Diags, + CI.getFileSystemOpts()); if (!AST) goto failure; @@ -132,7 +133,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!CI.hasFileManager()) CI.createFileManager(); if (!CI.hasSourceManager()) - CI.createSourceManager(); + CI.createSourceManager(CI.getFileManager(), CI.getFileSystemOpts()); // IR files bypass the rest of initialization. if (InputKind == IK_LLVM_IR) { diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 5bc6506e1f..9ef1ca64d7 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -207,7 +207,10 @@ void PrintPreambleAction::ExecuteAction() { return; } - llvm::MemoryBuffer *Buffer = llvm::MemoryBuffer::getFile(getCurrentFile()); + CompilerInstance &CI = getCompilerInstance(); + llvm::MemoryBuffer *Buffer + = CI.getFileManager().getBufferForFile(getCurrentFile(), + CI.getFileSystemOpts()); if (Buffer) { unsigned Preamble = Lexer::ComputePreamble(Buffer).first; llvm::outs().write(Buffer->getBufferStart(), Preamble); diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 97157b3615..e47381e39d 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -99,6 +99,7 @@ void InitHeaderSearch::AddPath(const llvm::Twine &Path, bool IgnoreSysRoot) { assert(!Path.isTriviallyEmpty() && "can't handle empty path here"); FileManager &FM = Headers.getFileMgr(); + const FileSystemOptions &FSOpts = Headers.getFileSystemOpts(); // Compute the actual path, taking into consideration -isysroot. llvm::SmallString<256> MappedPathStr; @@ -125,7 +126,7 @@ void InitHeaderSearch::AddPath(const llvm::Twine &Path, // If the directory exists, add it. - if (const DirectoryEntry *DE = FM.getDirectory(MappedPath.str())) { + if (const DirectoryEntry *DE = FM.getDirectory(MappedPath.str(), FSOpts)) { IncludeGroup[Group].push_back(DirectoryLookup(DE, Type, isUserSupplied, isFramework)); return; @@ -134,7 +135,7 @@ void InitHeaderSearch::AddPath(const llvm::Twine &Path, // Check to see if this is an apple-style headermap (which are not allowed to // be frameworks). if (!isFramework) { - if (const FileEntry *FE = FM.getFile(MappedPath.str())) { + if (const FileEntry *FE = FM.getFile(MappedPath.str(), FSOpts)) { if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) { // It is a headermap, add it to the search path. IncludeGroup[Group].push_back(DirectoryLookup(HM, Type,isUserSupplied)); diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 181f671025..7275733bbb 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -478,6 +478,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, static void InitializeFileRemapping(Diagnostic &Diags, SourceManager &SourceMgr, FileManager &FileMgr, + const FileSystemOptions &FSOpts, const PreprocessorOptions &InitOpts) { // Remap files in the source manager (with buffers). for (PreprocessorOptions::const_remapped_file_buffer_iterator @@ -488,7 +489,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, // Create the file entry for the file that we're mapping from. const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first, Remap->second->getBufferSize(), - 0); + 0, FSOpts); if (!FromFile) { Diags.Report(diag::err_fe_remap_missing_from_file) << Remap->first; @@ -510,7 +511,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, Remap != RemapEnd; ++Remap) { // Find the file that we're mapping to. - const FileEntry *ToFile = FileMgr.getFile(Remap->second); + const FileEntry *ToFile = FileMgr.getFile(Remap->second, FSOpts); if (!ToFile) { Diags.Report(diag::err_fe_remap_missing_to_file) << Remap->first << Remap->second; @@ -520,7 +521,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, // Create the file entry for the file that we're mapping from. const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first, ToFile->getSize(), - 0); + 0, FSOpts); if (!FromFile) { Diags.Report(diag::err_fe_remap_missing_from_file) << Remap->first; @@ -530,7 +531,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, // Load the contents of the file we're mapping to. std::string ErrorStr; const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr); + = FileMgr.getBufferForFile(ToFile->getName(), FSOpts, &ErrorStr); if (!Buffer) { Diags.Report(diag::err_fe_error_opening) << Remap->second << ErrorStr; @@ -547,6 +548,7 @@ static void InitializeFileRemapping(Diagnostic &Diags, /// environment ready to process a single file. This returns true on error. /// void clang::InitializePreprocessor(Preprocessor &PP, + const FileSystemOptions &FSOpts, const PreprocessorOptions &InitOpts, const HeaderSearchOptions &HSOpts, const FrontendOptions &FEOpts) { @@ -556,7 +558,7 @@ void clang::InitializePreprocessor(Preprocessor &PP, MacroBuilder Builder(Predefines); InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(), - PP.getFileManager(), InitOpts); + PP.getFileManager(), FSOpts, InitOpts); // Emit line markers for various builtin sections of the file. We don't do // this in asm preprocessor mode, because "# 4" is not a line marker directive diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp index 4010d613ac..5d9b218a7d 100644 --- a/lib/Lex/HeaderMap.cpp +++ b/lib/Lex/HeaderMap.cpp @@ -75,13 +75,14 @@ static inline unsigned HashHMapKey(llvm::StringRef Str) { /// map. If it doesn't look like a HeaderMap, it gives up and returns null. /// If it looks like a HeaderMap but is obviously corrupted, it puts a reason /// into the string error argument and returns null. -const HeaderMap *HeaderMap::Create(const FileEntry *FE) { +const HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM, + const |