summaryrefslogtreecommitdiff
path: root/lib/Frontend/FrontendActions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/FrontendActions.cpp')
-rw-r--r--lib/Frontend/FrontendActions.cpp116
1 files changed, 76 insertions, 40 deletions
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index b1e806add8cc..eb91940cbbfc 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -11,19 +11,18 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTConsumers.h"
-#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Pragma.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Parser.h"
+#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <system_error>
@@ -92,7 +91,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, nullptr, Sysroot,
+ CI.getPreprocessor(), OutputFile, Sysroot,
Buffer, CI.getFrontendOpts().ModuleFileExtensions,
/*AllowASTWithErrors*/false,
/*IncludeTimestamps*/
@@ -131,18 +130,18 @@ GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
std::unique_ptr<ASTConsumer>
GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
- std::string Sysroot;
- std::string OutputFile;
- std::unique_ptr<raw_pwrite_stream> OS =
- ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
+ std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
if (!OS)
return nullptr;
+ std::string OutputFile = CI.getFrontendOpts().OutputFile;
+ std::string Sysroot;
+
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, Module, Sysroot,
+ CI.getPreprocessor(), OutputFile, Sysroot,
Buffer, CI.getFrontendOpts().ModuleFileExtensions,
/*AllowASTWithErrors=*/false,
/*IncludeTimestamps=*/
@@ -152,6 +151,23 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
}
+bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) {
+ // Set up embedding for any specified files. Do this before we load any
+ // source files, including the primary module map for the compilation.
+ for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
+ if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
+ CI.getSourceManager().setFileIsTransient(FE);
+ else
+ CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
+ }
+ if (CI.getFrontendOpts().ModulesEmbedAllFiles)
+ CI.getSourceManager().setAllFilesAreTransient(true);
+
+ return true;
+}
+
+
static SmallVectorImpl<char> &
operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
Includes.append(RHS.begin(), RHS.end());
@@ -267,9 +283,12 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
return std::error_code();
}
-bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
- StringRef Filename) {
- CI.getLangOpts().CompilingModule = true;
+bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
+ CompilerInstance &CI, StringRef Filename) {
+ CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
+
+ if (!GenerateModuleAction::BeginSourceFileAction(CI, Filename))
+ return false;
// Find the module map file.
const FileEntry *ModuleMap =
@@ -280,17 +299,6 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
return false;
}
- // Set up embedding for any specified files. Do this before we load any
- // source files, including the primary module map for the compilation.
- for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
- if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
- CI.getSourceManager().setFileIsTransient(FE);
- else
- CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
- }
- if (CI.getFrontendOpts().ModulesEmbedAllFiles)
- CI.getSourceManager().setAllFilesAreTransient(true);
-
// Parse the module map file.
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
if (HS.loadModuleMapFile(ModuleMap, IsSystem))
@@ -382,32 +390,43 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
}
std::unique_ptr<raw_pwrite_stream>
-GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI,
- StringRef InFile,
- std::string &Sysroot,
- std::string &OutputFile) {
+GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
+ StringRef InFile) {
// If no output file was provided, figure out where this module would go
// in the module cache.
if (CI.getFrontendOpts().OutputFile.empty()) {
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
CI.getFrontendOpts().OutputFile =
HS.getModuleFileName(CI.getLangOpts().CurrentModule,
- ModuleMapForUniquing->getName());
+ ModuleMapForUniquing->getName(),
+ /*UsePrebuiltPath=*/false);
}
// We use createOutputFile here because this is exposed via libclang, and we
// must disable the RemoveFileOnSignal behavior.
// We use a temporary to avoid race conditions.
- std::unique_ptr<raw_pwrite_stream> OS =
- CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
- /*RemoveFileOnSignal=*/false, InFile,
- /*Extension=*/"", /*useTemporary=*/true,
- /*CreateMissingDirectories=*/true);
- if (!OS)
- return nullptr;
+ return CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
+ /*RemoveFileOnSignal=*/false, InFile,
+ /*Extension=*/"", /*useTemporary=*/true,
+ /*CreateMissingDirectories=*/true);
+}
- OutputFile = CI.getFrontendOpts().OutputFile;
- return OS;
+bool GenerateModuleInterfaceAction::BeginSourceFileAction(CompilerInstance &CI,
+ StringRef Filename) {
+ if (!CI.getLangOpts().ModulesTS) {
+ CI.getDiagnostics().Report(diag::err_module_interface_requires_modules_ts);
+ return false;
+ }
+
+ CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
+
+ return GenerateModuleAction::BeginSourceFileAction(CI, Filename);
+}
+
+std::unique_ptr<raw_pwrite_stream>
+GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
+ StringRef InFile) {
+ return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
}
SyntaxOnlyAction::~SyntaxOnlyAction() {
@@ -597,6 +616,13 @@ namespace {
};
}
+bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) {
+ // The Object file reader also supports raw ast files and there is no point in
+ // being strict about the module file format in -module-file-info mode.
+ CI.getHeaderSearchOpts().ModuleFormat = "obj";
+ return true;
+}
+
void DumpModuleInfoAction::ExecuteAction() {
// Set up the output file.
std::unique_ptr<llvm::raw_fd_ostream> OutFile;
@@ -609,11 +635,21 @@ void DumpModuleInfoAction::ExecuteAction() {
llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
Out << "Information for module file '" << getCurrentFile() << "':\n";
+ auto &FileMgr = getCompilerInstance().getFileManager();
+ auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
+ StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
+ bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' &&
+ Magic[2] == 'C' && Magic[3] == 'H');
+ Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
+
+ Preprocessor &PP = getCompilerInstance().getPreprocessor();
DumpModuleInfoListener Listener(Out);
+ HeaderSearchOptions &HSOpts =
+ PP.getHeaderSearchInfo().getHeaderSearchOpts();
ASTReader::readASTFileControlBlock(
- getCurrentFile(), getCompilerInstance().getFileManager(),
- getCompilerInstance().getPCHContainerReader(),
- /*FindModuleFileExtensions=*/true, Listener);
+ getCurrentFile(), FileMgr, getCompilerInstance().getPCHContainerReader(),
+ /*FindModuleFileExtensions=*/true, Listener,
+ HSOpts.ModulesValidateDiagnosticOptions);
}
//===----------------------------------------------------------------------===//