aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/Frontend/CompilerInstance.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp98
1 files changed, 56 insertions, 42 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 2cd7efd862ec..ecc1c4cf51c1 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -12,6 +12,7 @@
#include "clang/AST/Decl.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/SourceManager.h"
@@ -25,6 +26,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/LogDiagnosticPrinter.h"
+#include "clang/Frontend/SARIFDiagnosticPrinter.h"
#include "clang/Frontend/SerializedDiagnosticPrinter.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
@@ -39,6 +41,7 @@
#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Errc.h"
@@ -52,6 +55,7 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
#include <time.h>
#include <utility>
@@ -115,9 +119,9 @@ bool CompilerInstance::createTarget() {
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);
if (getFrontendOpts().AuxTargetCPU)
- TO->CPU = getFrontendOpts().AuxTargetCPU.value();
+ TO->CPU = *getFrontendOpts().AuxTargetCPU;
if (getFrontendOpts().AuxTargetFeatures)
- TO->FeaturesAsWritten = getFrontendOpts().AuxTargetFeatures.value();
+ TO->FeaturesAsWritten = *getFrontendOpts().AuxTargetFeatures;
TO->HostTriple = getTarget().getTriple().str();
setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
}
@@ -249,7 +253,8 @@ static void collectIncludePCH(CompilerInstance &CI,
// used here since we're not interested in validating the PCH at this time,
// but only to check whether this is a file containing an AST.
if (!ASTReader::readASTFileControlBlock(
- Dir->path(), FileMgr, CI.getPCHContainerReader(),
+ Dir->path(), FileMgr, CI.getModuleCache(),
+ CI.getPCHContainerReader(),
/*FindModuleFileExtensions=*/false, Validator,
/*ValidateDiagnosticOptions=*/false))
MDC->addFile(Dir->path());
@@ -346,6 +351,8 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
// implementing -verify.
if (Client) {
Diags->setClient(Client, ShouldOwnClient);
+ } else if (Opts->getFormat() == DiagnosticOptions::SARIF) {
+ Diags->setClient(new SARIFDiagnosticPrinter(llvm::errs(), Opts));
} else
Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));
@@ -419,7 +426,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags,
// Remap files in the source manager (with other files).
for (const auto &RF : InitOpts.RemappedFiles) {
// Find the file that we're mapping to.
- auto ToFile = FileMgr.getFile(RF.second);
+ OptionalFileEntryRef ToFile = FileMgr.getOptionalFileRef(RF.second);
if (!ToFile) {
Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
continue;
@@ -427,7 +434,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags,
// Create the file entry for the file that we're mapping from.
const FileEntry *FromFile =
- FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
+ FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
if (!FromFile) {
Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
continue;
@@ -777,12 +784,7 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) {
continue;
}
- // If '-working-directory' was passed, the output filename should be
- // relative to that.
- SmallString<128> NewOutFile(OF.Filename);
- FileMgr->FixupRelativePath(NewOutFile);
-
- llvm::Error E = OF.File->keep(NewOutFile);
+ llvm::Error E = OF.File->keep(OF.Filename);
if (!E)
continue;
@@ -803,7 +805,7 @@ std::unique_ptr<raw_pwrite_stream> CompilerInstance::createDefaultOutputFile(
bool Binary, StringRef InFile, StringRef Extension, bool RemoveFileOnSignal,
bool CreateMissingDirectories, bool ForceUseTemporary) {
StringRef OutputPath = getFrontendOpts().OutputFile;
- Optional<SmallString<128>> PathStorage;
+ std::optional<SmallString<128>> PathStorage;
if (OutputPath.empty()) {
if (InFile == "-" || Extension.empty()) {
OutputPath = "-";
@@ -845,8 +847,17 @@ CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary,
assert((!CreateMissingDirectories || UseTemporary) &&
"CreateMissingDirectories is only allowed when using temporary files");
+ // If '-working-directory' was passed, the output filename should be
+ // relative to that.
+ std::optional<SmallString<128>> AbsPath;
+ if (OutputPath != "-" && !llvm::sys::path::is_absolute(OutputPath)) {
+ AbsPath.emplace(OutputPath);
+ FileMgr->FixupRelativePath(*AbsPath);
+ OutputPath = *AbsPath;
+ }
+
std::unique_ptr<llvm::raw_fd_ostream> OS;
- Optional<StringRef> OSFile;
+ std::optional<StringRef> OSFile;
if (UseTemporary) {
if (OutputPath == "-")
@@ -868,7 +879,7 @@ CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary,
}
}
- Optional<llvm::sys::fs::TempFile> Temp;
+ std::optional<llvm::sys::fs::TempFile> Temp;
if (UseTemporary) {
// Create a temporary file.
// Insert -%%%%%%%% before the extension (if any), and because some tools
@@ -1015,9 +1026,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
// Validate/process some options.
if (getHeaderSearchOpts().Verbose)
- OS << "clang -cc1 version " CLANG_VERSION_STRING
- << " based upon " << BACKEND_PACKAGE_STRING
- << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
+ OS << "clang -cc1 version " CLANG_VERSION_STRING << " based upon LLVM "
+ << LLVM_VERSION_STRING << " default target "
+ << llvm::sys::getDefaultTargetTriple() << "\n";
if (getCodeGenOpts().TimePasses)
createFrontendTimer();
@@ -1150,8 +1161,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
// For any options that aren't intended to affect how a module is built,
// reset them to their default values.
- Invocation->getLangOpts()->resetNonModularOptions();
- PPOpts.resetNonModularOptions();
+ Invocation->resetNonModularOptions();
// Remove any macro definitions that are explicitly ignored by the module.
// They aren't supposed to affect how the module is built anyway.
@@ -1213,11 +1223,16 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
ImportingInstance.getDiagnosticClient()),
/*ShouldOwnClient=*/true);
- // Note that this module is part of the module build stack, so that we
- // can detect cycles in the module graph.
- Instance.setFileManager(&ImportingInstance.getFileManager());
+ if (FrontendOpts.ModulesShareFileManager) {
+ Instance.setFileManager(&ImportingInstance.getFileManager());
+ } else {
+ Instance.createFileManager(&ImportingInstance.getVirtualFileSystem());
+ }
Instance.createSourceManager(Instance.getFileManager());
SourceManager &SourceMgr = Instance.getSourceManager();
+
+ // Note that this module is part of the module build stack, so that we
+ // can detect cycles in the module graph.
SourceMgr.setModuleBuildStack(
ImportingInstance.getSourceManager().getModuleBuildStack());
SourceMgr.pushModuleBuildStack(ModuleName,
@@ -1266,19 +1281,17 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
}
-static const FileEntry *getPublicModuleMap(const FileEntry *File,
- FileManager &FileMgr) {
- StringRef Filename = llvm::sys::path::filename(File->getName());
- SmallString<128> PublicFilename(File->getDir()->getName());
+static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,
+ FileManager &FileMgr) {
+ StringRef Filename = llvm::sys::path::filename(File.getName());
+ SmallString<128> PublicFilename(File.getDir().getName());
if (Filename == "module_private.map")
llvm::sys::path::append(PublicFilename, "module.map");
else if (Filename == "module.private.modulemap")
llvm::sys::path::append(PublicFilename, "module.modulemap");
else
- return nullptr;
- if (auto FE = FileMgr.getFile(PublicFilename))
- return *FE;
- return nullptr;
+ return std::nullopt;
+ return FileMgr.getOptionalFileRef(PublicFilename);
}
/// Compile a module file for the given module in a separate compiler instance,
@@ -1294,21 +1307,22 @@ static bool compileModule(CompilerInstance &ImportingInstance,
ModuleMap &ModMap
= ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
bool Result;
- if (const FileEntry *ModuleMapFile =
+ if (OptionalFileEntryRef ModuleMapFile =
ModMap.getContainingModuleMapFile(Module)) {
// Canonicalize compilation to start with the public module map. This is
// vital for submodules declarations in the private module maps to be
// correctly parsed when depending on a top level module in the public one.
- if (const FileEntry *PublicMMFile = getPublicModuleMap(
- ModuleMapFile, ImportingInstance.getFileManager()))
+ if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap(
+ *ModuleMapFile, ImportingInstance.getFileManager()))
ModuleMapFile = PublicMMFile;
+ StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested();
+
// Use the module map where this module resides.
Result = compileModuleImpl(
ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
- FrontendInputFile(ModuleMapFile->getName(), IK, +Module->IsSystem),
- ModMap.getModuleMapFileForUniquing(Module)->getName(),
- ModuleFileName);
+ FrontendInputFile(ModuleMapFilePath, IK, +Module->IsSystem),
+ ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName);
} else {
// FIXME: We only need to fake up an input file here as a way of
// transporting the module's directory to the module map parser. We should
@@ -1330,7 +1344,7 @@ static bool compileModule(CompilerInstance &ImportingInstance,
[&](CompilerInstance &Instance) {
std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
- ModuleMapFile = Instance.getFileManager().getVirtualFile(
+ const FileEntry *ModuleMapFile = Instance.getFileManager().getVirtualFile(
FakeModuleMapFile, InferredModuleMapContent.size(), 0);
Instance.getSourceManager().overrideFileContents(
ModuleMapFile, std::move(ModuleMapBuffer));
@@ -1432,7 +1446,7 @@ static bool compileModuleAndReadASTBehindLock(
<< Module->Name << Locked.getErrorMessage();
// Clear out any potential leftover.
Locked.unsafeRemoveLockFile();
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case llvm::LockFileManager::LFS_Owned:
// We're responsible for building the module ourselves.
return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,
@@ -1870,7 +1884,7 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
diag::warn_module_config_mismatch)
<< ModuleFilename;
// Fall through to error out.
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case ASTReader::VersionMismatch:
case ASTReader::HadErrors:
ModuleLoader::HadFatalFailure = true;
@@ -2005,8 +2019,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// match Foo_Private and emit a warning asking for the user to write
// @import Foo_Private instead. FIXME: remove this when existing clients
// migrate off of Foo.Private syntax.
- if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" &&
- Module == Module->getTopLevelModule()) {
+ if (!Sub && Name == "Private" && Module == Module->getTopLevelModule()) {
SmallString<128> PrivateModule(Module->Name);
PrivateModule.append("_Private");
@@ -2020,6 +2033,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective);
if (Sub) {
MapPrivateSubModToTopLevel = true;
+ PP->markClangModuleAsAffecting(Module);
if (!getDiagnostics().isIgnored(
diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
getDiagnostics().Report(Path[I].second,
@@ -2091,7 +2105,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
<< Module->getFullModuleName()
<< SourceRange(Path.front().second, Path.back().second);
- return ModuleLoadResult::MissingExpected;
+ return ModuleLoadResult(Module, ModuleLoadResult::MissingExpected);
}
// Check whether this module is available.