diff options
Diffstat (limited to 'lib/Frontend/FrontendActions.cpp')
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 103 |
1 files changed, 84 insertions, 19 deletions
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 8a8354c7d4c90..a407dfc162bb1 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -92,12 +92,6 @@ ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { } std::unique_ptr<ASTConsumer> -DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { - return CreateDeclContextPrinter(); -} - -std::unique_ptr<ASTConsumer> GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { std::string Sysroot; if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot)) @@ -242,6 +236,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() { } @@ -341,6 +405,8 @@ private: return "PriorTemplateArgumentSubstitution"; case CodeSynthesisContext::DefaultTemplateArgumentChecking: return "DefaultTemplateArgumentChecking"; + case CodeSynthesisContext::ExceptionSpecEvaluation: + return "ExceptionSpecEvaluation"; case CodeSynthesisContext::ExceptionSpecInstantiation: return "ExceptionSpecInstantiation"; case CodeSynthesisContext::DeclaringSpecialMember: @@ -599,6 +665,17 @@ namespace { return true; } + + /// Returns true if this \c ASTReaderListener wants to receive the + /// imports of the AST file via \c visitImport, false otherwise. + bool needsImportVisitation() const override { return true; } + + /// If needsImportVisitation returns \c true, this is called for each + /// AST file imported by this AST file. + void visitImport(StringRef ModuleName, StringRef Filename) override { + Out.indent(2) << "Imports module '" << ModuleName + << "': " << Filename.str() << "\n"; + } #undef DUMP_BOOLEAN }; } @@ -673,16 +750,6 @@ void DumpTokensAction::ExecuteAction() { } while (Tok.isNot(tok::eof)); } -void GeneratePTHAction::ExecuteAction() { - CompilerInstance &CI = getCompilerInstance(); - std::unique_ptr<raw_pwrite_stream> OS = - CI.createDefaultOutputFile(true, getCurrentFile()); - if (!OS) - return; - - CacheTokens(CI.getPreprocessor(), OS.get()); -} - void PreprocessOnlyAction::ExecuteAction() { Preprocessor &PP = getCompilerInstance().getPreprocessor(); @@ -742,7 +809,7 @@ void PrintPreprocessedAction::ExecuteAction() { } std::unique_ptr<raw_ostream> OS = - CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); + CI.createDefaultOutputFile(BinaryMode, getCurrentFileOrBufferName()); if (!OS) return; // If we're preprocessing a module map, start by dumping the contents of the @@ -754,8 +821,6 @@ void PrintPreprocessedAction::ExecuteAction() { OS->write_escaped(Input.getFile()); (*OS) << "\"\n"; } - // FIXME: Include additional information here so that we don't need the - // original source files to exist on disk. getCurrentModule()->print(*OS); (*OS) << "#pragma clang module contents\n"; } |