diff options
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 70 |
4 files changed, 85 insertions, 19 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 38a09a0dac3..05ba3c0265a 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -911,6 +911,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { // taking it as an input instead of hard-coding llvm::errs. raw_ostream &OS = llvm::errs(); + if (!Act.PrepareToExecute(*this)) + return false; + // Create the target instance. setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getInvocation().TargetOpts)); @@ -1615,22 +1618,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) { // Determine what file we're searching from. - // FIXME: Should we be deciding whether this is a submodule (here and - // below) based on -fmodules-ts or should we pass a flag and make the - // caller decide? - std::string ModuleName; - if (getLangOpts().ModulesTS) { - // FIXME: Same code as Sema::ActOnModuleDecl() so there is probably a - // better place/way to do this. - for (auto &Piece : Path) { - if (!ModuleName.empty()) - ModuleName += "."; - ModuleName += Piece.first->getName(); - } - } - else - ModuleName = Path[0].first->getName(); - + StringRef ModuleName = Path[0].first->getName(); SourceLocation ModuleNameLoc = Path[0].second; // If we've already handled this import, just return the cached result. @@ -1859,7 +1847,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // Verify that the rest of the module path actually corresponds to // a submodule. bool MapPrivateSubModToTopLevel = false; - if (!getLangOpts().ModulesTS && Path.size() > 1) { + if (Path.size() > 1) { for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(Name); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index b11581ddf79..55745b19633 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1454,6 +1454,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::GenerateModule; break; case OPT_emit_module_interface: Opts.ProgramAction = frontend::GenerateModuleInterface; break; + case OPT_emit_header_module: + Opts.ProgramAction = frontend::GenerateHeaderModule; break; case OPT_emit_pch: Opts.ProgramAction = frontend::GeneratePCH; break; case OPT_emit_pth: @@ -2830,6 +2832,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::FixIt: case frontend::GenerateModule: case frontend::GenerateModuleInterface: + case frontend::GenerateHeaderModule: case frontend::GeneratePCH: case frontend::GeneratePTH: case frontend::ParseSyntaxOnly: diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index ddb522ae05f..10f1d1ef611 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -523,7 +523,6 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, setCurrentInput(Input); setCompilerInstance(&CI); - StringRef InputFile = Input.getFile(); bool HasBegunSourceFile = false; bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled && usesPreprocessorOnly(); @@ -541,6 +540,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, &Diags->getDiagnosticOptions())); ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false); + // FIXME: What if the input is a memory buffer? + StringRef InputFile = Input.getFile(); + std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); @@ -604,6 +606,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics()); + // FIXME: What if the input is a memory buffer? + StringRef InputFile = Input.getFile(); + std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( InputFile, CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(), CI.getCodeGenOpts().DebugTypeExtRefs); @@ -791,7 +796,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // For preprocessed files, check if the first line specifies the original // source file name with a linemarker. - std::string PresumedInputFile = InputFile; + std::string PresumedInputFile = getCurrentFileOrBufferName(); if (Input.isPreprocessed()) ReadOriginalFileName(CI, PresumedInputFile); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 40008bf3cdd..d0d83076f1d 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -242,6 +242,76 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); } +bool GenerateHeaderModuleAction::PrepareToExecuteAction( + CompilerInstance &CI) { + if (!CI.getLangOpts().Modules && !CI.getLangOpts().ModulesTS) { + CI.getDiagnostics().Report(diag::err_header_module_requires_modules); + return false; + } + + auto &Inputs = CI.getFrontendOpts().Inputs; + if (Inputs.empty()) + return GenerateModuleAction::BeginInvocation(CI); + + auto Kind = Inputs[0].getKind(); + + // Convert the header file inputs into a single module input buffer. + SmallString<256> HeaderContents; + ModuleHeaders.reserve(Inputs.size()); + for (const FrontendInputFile &FIF : Inputs) { + // FIXME: We should support re-compiling from an AST file. + if (FIF.getKind().getFormat() != InputKind::Source || !FIF.isFile()) { + CI.getDiagnostics().Report(diag::err_module_header_file_not_found) + << (FIF.isFile() ? FIF.getFile() + : FIF.getBuffer()->getBufferIdentifier()); + return true; + } + + HeaderContents += "#include \""; + HeaderContents += FIF.getFile(); + HeaderContents += "\"\n"; + ModuleHeaders.push_back(FIF.getFile()); + } + Buffer = llvm::MemoryBuffer::getMemBufferCopy( + HeaderContents, Module::getModuleInputBufferName()); + + // Set that buffer up as our "real" input. + Inputs.clear(); + Inputs.push_back(FrontendInputFile(Buffer.get(), Kind, /*IsSystem*/false)); + + return GenerateModuleAction::PrepareToExecuteAction(CI); +} + +bool GenerateHeaderModuleAction::BeginSourceFileAction( + CompilerInstance &CI) { + CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderModule); + + // Synthesize a Module object for the given headers. + auto &HS = CI.getPreprocessor().getHeaderSearchInfo(); + SmallVector<Module::Header, 16> Headers; + for (StringRef Name : ModuleHeaders) { + const DirectoryLookup *CurDir = nullptr; + const FileEntry *FE = HS.LookupFile( + Name, SourceLocation(), /*Angled*/ false, nullptr, CurDir, + None, nullptr, nullptr, nullptr, nullptr, nullptr); + if (!FE) { + CI.getDiagnostics().Report(diag::err_module_header_file_not_found) + << Name; + continue; + } + Headers.push_back({Name, FE}); + } + HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers); + + return GenerateModuleAction::BeginSourceFileAction(CI); +} + +std::unique_ptr<raw_pwrite_stream> +GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI, + StringRef InFile) { + return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm"); +} + SyntaxOnlyAction::~SyntaxOnlyAction() { } |