diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp | 219 |
1 files changed, 116 insertions, 103 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp index cf856fc..eccb94c 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp @@ -111,8 +111,8 @@ static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, if (DiagOpts->DiagnosticLogFile != "-") { // Create the output stream. llvm::raw_fd_ostream *FileOS( - new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), - ErrorInfo, llvm::raw_fd_ostream::F_Append)); + new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo, + llvm::sys::fs::F_Append)); if (!ErrorInfo.empty()) { Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) << DiagOpts->DiagnosticLogFile << ErrorInfo; @@ -138,8 +138,8 @@ static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, std::string ErrorInfo; OwningPtr<llvm::raw_fd_ostream> OS; OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, - llvm::raw_fd_ostream::F_Binary)); - + llvm::sys::fs::F_Binary)); + if (!ErrorInfo.empty()) { Diags.Report(diag::warn_fe_serialized_diag_failure) << OutputFile << ErrorInfo; @@ -218,7 +218,7 @@ void CompilerInstance::createPreprocessor() { // Create the Preprocessor. HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), - getFileManager(), + getSourceManager(), getDiagnostics(), getLangOpts(), &getTarget()); @@ -259,7 +259,7 @@ void CompilerInstance::createPreprocessor() { AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, getHeaderSearchOpts().Sysroot); - + // Handle generating header include information, if requested. if (DepOpts.ShowHeaderIncludes) AttachHeaderIncludeGen(*PP); @@ -270,6 +270,11 @@ void CompilerInstance::createPreprocessor() { AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, /*ShowDepth=*/false); } + + if (DepOpts.PrintShowIncludes) { + AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"", + /*ShowDepth=*/true, /*MSStyle=*/true); + } } // ASTContext @@ -384,7 +389,7 @@ void CompilerInstance::createCodeCompletionConsumer() { } if (CompletionConsumer->isOutputBinary() && - llvm::sys::Program::ChangeStdoutToBinary()) { + llvm::sys::ChangeStdoutToBinary()) { getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); setCodeCompletionConsumer(0); } @@ -445,7 +450,7 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) { } } } else if (!it->Filename.empty() && EraseFiles) - llvm::sys::Path(it->Filename).eraseFromDisk(); + llvm::sys::fs::remove(it->Filename); } OutputFiles.clear(); @@ -509,9 +514,8 @@ CompilerInstance::createOutputFile(StringRef OutputPath, } else if (InFile == "-") { OutFile = "-"; } else if (!Extension.empty()) { - llvm::sys::Path Path(InFile); - Path.eraseSuffix(); - Path.appendSuffix(Extension); + SmallString<128> Path(InFile); + llvm::sys::path::replace_extension(Path, Extension); OutFile = Path.str(); } else { OutFile = "-"; @@ -520,47 +524,64 @@ CompilerInstance::createOutputFile(StringRef OutputPath, OwningPtr<llvm::raw_fd_ostream> OS; std::string OSFile; - if (UseTemporary && OutFile != "-") { - // Only create the temporary if the parent directory exists (or create - // missing directories is true) and we can actually write to OutPath, - // otherwise we want to fail early. - SmallString<256> AbsPath(OutputPath); - llvm::sys::fs::make_absolute(AbsPath); - llvm::sys::Path OutPath(AbsPath); - bool ParentExists = false; - if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()), - ParentExists)) - ParentExists = false; - bool Exists; - if ((CreateMissingDirectories || ParentExists) && - ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) || - (OutPath.isRegularFile() && OutPath.canWrite()))) { - // Create a temporary file. - SmallString<128> TempPath; - TempPath = OutFile; - TempPath += "-%%%%%%%%"; - int fd; - if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, - /*makeAbsolute=*/false, 0664) - == llvm::errc::success) { - OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); - OSFile = TempFile = TempPath.str(); + if (UseTemporary) { + if (OutFile == "-") + UseTemporary = false; + else { + llvm::sys::fs::file_status Status; + llvm::sys::fs::status(OutputPath, Status); + if (llvm::sys::fs::exists(Status)) { + // Fail early if we can't write to the final destination. + if (!llvm::sys::fs::can_write(OutputPath)) + return 0; + + // Don't use a temporary if the output is a special file. This handles + // things like '-o /dev/null' + if (!llvm::sys::fs::is_regular_file(Status)) + UseTemporary = false; } } } + if (UseTemporary) { + // Create a temporary file. + SmallString<128> TempPath; + TempPath = OutFile; + TempPath += "-%%%%%%%%"; + int fd; + llvm::error_code EC = + llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); + + if (CreateMissingDirectories && + EC == llvm::errc::no_such_file_or_directory) { + StringRef Parent = llvm::sys::path::parent_path(OutputPath); + EC = llvm::sys::fs::create_directories(Parent); + if (!EC) { + EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); + } + } + + if (!EC) { + OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); + OSFile = TempFile = TempPath.str(); + } + // If we failed to create the temporary, fallback to writing to the file + // directly. This handles the corner case where we cannot write to the + // directory, but can write to the file. + } + if (!OS) { OSFile = OutFile; - OS.reset( - new llvm::raw_fd_ostream(OSFile.c_str(), Error, - (Binary ? llvm::raw_fd_ostream::F_Binary : 0))); + OS.reset(new llvm::raw_fd_ostream( + OSFile.c_str(), Error, + (Binary ? llvm::sys::fs::F_Binary : llvm::sys::fs::F_None))); if (!Error.empty()) return 0; } // Make sure the out stream file gets removed if we crash. if (RemoveFileOnSignal) - llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile)); + llvm::sys::RemoveFileOnSignal(OSFile); if (ResultPathName) *ResultPathName = OutFile; @@ -597,7 +618,7 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, // 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, /*OpenFile=*/true); if (!File) { Diags.Report(diag::err_fe_error_reading) << InputFile; return false; @@ -605,26 +626,27 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, // The natural SourceManager infrastructure can't currently handle named // pipes, but we would at least like to accept them for the main - // file. Detect them here, read them with the more generic MemoryBuffer - // function, and simply override their contents as we do for STDIN. + // file. Detect them here, read them with the volatile flag so FileMgr will + // pick up the correct size, and simply override their contents as we do for + // STDIN. if (File->isNamedPipe()) { - OwningPtr<llvm::MemoryBuffer> MB; - if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) { - Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message(); + std::string ErrorStr; + if (llvm::MemoryBuffer *MB = + FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) { + // Create a new virtual file that will have the correct size. + File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); + SourceMgr.overrideFileContents(File, MB); + } else { + Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr; return false; } - - // Create a new virtual file that will have the correct size. - File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); - SourceMgr.overrideFileContents(File, MB.take()); } SourceMgr.createMainFileID(File, Kind); } else { OwningPtr<llvm::MemoryBuffer> SB; - if (llvm::MemoryBuffer::getSTDIN(SB)) { - // FIXME: Give ec.message() in this diag. - Diags.Report(diag::err_fe_error_reading_stdin); + if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) { + Diags.Report(diag::err_fe_error_reading_stdin) << ec.message(); return false; } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), @@ -764,6 +786,11 @@ static void compileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName) { + // FIXME: have LockFileManager return an error_code so that we can + // avoid the mkdir when the directory already exists. + StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); + llvm::sys::fs::create_directories(Dir); + llvm::LockFileManager Locked(ModuleFileName); switch (Locked) { case llvm::LockFileManager::LFS_Error: @@ -824,33 +851,6 @@ static void compileModule(CompilerInstance &ImportingInstance, FrontendOpts.Inputs.clear(); InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); - // Get or create the module map that we'll use to build this module. - SmallString<128> TempModuleMapFileName; - if (const FileEntry *ModuleMapFile - = ModMap.getContainingModuleMapFile(Module)) { - // Use the module map where this module resides. - FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(), - IK)); - } else { - // Create a temporary module map file. - TempModuleMapFileName = Module->Name; - TempModuleMapFileName += "-%%%%%%%%.map"; - int FD; - if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD, - TempModuleMapFileName, - /*makeAbsolute=*/true) - != llvm::errc::success) { - ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file) - << TempModuleMapFileName; - return; - } - // Print the module map to this file. - llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true); - Module->print(OS); - FrontendOpts.Inputs.push_back( - FrontendInputFile(TempModuleMapFileName.str().str(), IK)); - } - // Don't free the remapped file buffers; they are owned by our caller. PPOpts.RetainRemappedFileBuffers = true; @@ -877,9 +877,29 @@ static void compileModule(CompilerInstance &ImportingInstance, SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); + // Get or create the module map that we'll use to build this module. + std::string InferredModuleMapContent; + if (const FileEntry *ModuleMapFile = + ModMap.getContainingModuleMapFile(Module)) { + // Use the module map where this module resides. + FrontendOpts.Inputs.push_back( + FrontendInputFile(ModuleMapFile->getName(), IK)); + } else { + llvm::raw_string_ostream OS(InferredModuleMapContent); + Module->print(OS); + OS.flush(); + FrontendOpts.Inputs.push_back( + FrontendInputFile("__inferred_module.map", IK)); + + const llvm::MemoryBuffer *ModuleMapBuffer = + llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); + ModuleMapFile = Instance.getFileManager().getVirtualFile( + "__inferred_module.map", InferredModuleMapContent.size(), 0); + SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer); + } // Construct a module-generating action. - GenerateModuleAction CreateModuleAction; + GenerateModuleAction CreateModuleAction(Module->IsSystem); // Execute the action to actually build the module in-place. Use a separate // thread so that we get a stack large enough. @@ -894,8 +914,6 @@ static void compileModule(CompilerInstance &ImportingInstance, // be nice to do this with RemoveFileOnSignal when we can. However, that // doesn't make sense for all clients, so clean this up manually. Instance.clearOutputFiles(/*EraseFiles=*/true); - if (!TempModuleMapFileName.empty()) - llvm::sys::Path(TempModuleMapFileName).eraseFromDisk(); // We've rebuilt a module. If we're allowed to generate or update the global // module index, record that fact in the importing compiler instance. @@ -994,7 +1012,7 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, static void writeTimestampFile(StringRef TimestampFile) { std::string ErrorInfo; llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo, - llvm::raw_fd_ostream::F_Binary); + llvm::sys::fs::F_Binary); } /// \brief Prune the module cache of modules that haven't been accessed in @@ -1035,8 +1053,7 @@ static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { Dir(ModuleCachePathNative.str(), EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { // If we don't have a directory, there's nothing to look into. - bool IsDirectory; - if (llvm::sys::fs::is_directory(Dir->path(), IsDirectory) || !IsDirectory) + if (!llvm::sys::fs::is_directory(Dir->path())) continue; // Walk all of the files within this directory. @@ -1086,23 +1103,23 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) { + // Determine what file we're searching from. + StringRef ModuleName = Path[0].first->getName(); + SourceLocation ModuleNameLoc = Path[0].second; + // If we've already handled this import, just return the cached result. // This one-element cache is important to eliminate redundant diagnostics // when both the preprocessor and parser see the same import declaration. if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. - if (LastModuleImportResult) + if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, ImportLoc, /*Complain=*/false); return LastModuleImportResult; } - - // Determine what file we're searching from. - StringRef ModuleName = Path[0].first->getName(); - SourceLocation ModuleNameLoc = Path[0].second; clang::Module *Module = 0; - + // If we don't already have information on this module, load the module now. llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known = KnownModules.find(Path[0].first); @@ -1164,15 +1181,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, case ASTReader::Success: break; - case ASTReader::OutOfDate: { - // The module file is out-of-date. Remove it, then rebuild it. - bool Existed; - llvm::sys::fs::remove(ModuleFileName, Existed); - } - // Fall through to build the module again. - + case ASTReader::OutOfDate: case ASTReader::Missing: { - // The module file is (now) missing. Build it. + // The module file is missing or out-of-date. Build it. // If we don't have a module, we don't know how to build the module file. // Complain and return. @@ -1247,12 +1258,14 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: + ModuleLoader::HadFatalFailure = true; // FIXME: The ASTReader will already have complained, but can we showhorn // that diagnostic information into a more useful form? KnownModules[Path[0].first] = 0; return ModuleLoadResult(); case ASTReader::Failure: + ModuleLoader::HadFatalFailure = true; // Already complained, but note now that we failed. KnownModules[Path[0].first] = 0; ModuleBuildFailed = true; @@ -1346,11 +1359,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } // Check whether this module is available. - StringRef Feature; - if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { + clang::Module::Requirement Requirement; + if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement)) { getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) << Module->getFullModuleName() - << Feature + << Requirement.second << Requirement.first << SourceRange(Path.front().second, Path.back().second); LastModuleImportLoc = ImportLoc; LastModuleImportResult = ModuleLoadResult(); |