summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp2
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp2
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp81
-rw-r--r--clang/lib/Frontend/FrontendOptions.cpp2
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp5
-rw-r--r--clang/lib/Lex/ModuleMap.cpp21
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp2
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp2
-rw-r--r--clang/lib/Lex/Preprocessor.cpp19
-rw-r--r--clang/lib/Parse/ParseAST.cpp22
-rw-r--r--clang/lib/Parse/Parser.cpp21
-rw-r--r--clang/lib/Sema/SemaDecl.cpp88
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--clang/lib/Serialization/GeneratePCH.cpp7
15 files changed, 194 insertions, 85 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index f66ff140aab..3acd64587b1 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -2825,7 +2825,7 @@ const FileEntry *ASTUnit::getPCHFile() {
}
bool ASTUnit::isModuleFile() {
- return isMainFileAST() && ASTFileLangOpts.CompilingModule;
+ return isMainFileAST() && ASTFileLangOpts.isCompilingModule();
}
void ASTUnit::PreambleData::countLines() const {
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 89907f11719..627134e8dd1 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1026,7 +1026,7 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
// Construct a module-generating action. Passing through the module map is
// safe because the FileManager is shared between the compiler instances.
- GenerateModuleAction CreateModuleAction(
+ GenerateModuleFromModuleMapAction CreateModuleAction(
ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem);
ImportingInstance.getDiagnostics().Report(ImportLoc,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 97c37defa10..3154291d26f 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1116,6 +1116,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::FixIt; break;
case OPT_emit_module:
Opts.ProgramAction = frontend::GenerateModule; break;
+ case OPT_emit_module_interface:
+ Opts.ProgramAction = frontend::GenerateModuleInterface; break;
case OPT_emit_pch:
Opts.ProgramAction = frontend::GeneratePCH; break;
case OPT_emit_pth:
@@ -2259,6 +2261,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
case frontend::EmitObj:
case frontend::FixIt:
case frontend::GenerateModule:
+ case frontend::GenerateModuleInterface:
case frontend::GeneratePCH:
case frontend::GeneratePTH:
case frontend::ParseSyntaxOnly:
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index d73d46984cc..eb91940cbbf 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -130,13 +130,13 @@ 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;
@@ -151,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());
@@ -266,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 =
@@ -279,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))
@@ -381,10 +390,8 @@ 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()) {
@@ -398,16 +405,28 @@ GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI,
// 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() {
diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp
index 9ede674e47e..6a82084aff1 100644
--- a/clang/lib/Frontend/FrontendOptions.cpp
+++ b/clang/lib/Frontend/FrontendOptions.cpp
@@ -25,6 +25,8 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) {
.Case("mii", IK_PreprocessedObjCXX)
.Cases("C", "cc", "cp", IK_CXX)
.Cases("cpp", "CPP", "c++", "cxx", "hpp", IK_CXX)
+ .Case("cppm", IK_CXX)
+ .Case("iim", IK_PreprocessedCXX)
.Case("cl", IK_OpenCL)
.Case("cu", IK_CUDA)
.Cases("ll", "bc", IK_LLVM_IR)
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 13cb52aa1e3..187a6e76245 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -52,7 +52,10 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
case EmitCodeGenOnly: return llvm::make_unique<EmitCodeGenOnlyAction>();
case EmitObj: return llvm::make_unique<EmitObjAction>();
case FixIt: return llvm::make_unique<FixItAction>();
- case GenerateModule: return llvm::make_unique<GenerateModuleAction>();
+ case GenerateModule:
+ return llvm::make_unique<GenerateModuleFromModuleMapAction>();
+ case GenerateModuleInterface:
+ return llvm::make_unique<GenerateModuleInterfaceAction>();
case GeneratePCH: return llvm::make_unique<GeneratePCHAction>();
case GeneratePTH: return llvm::make_unique<GeneratePTHAction>();
case InitOnly: return llvm::make_unique<InitOnlyAction>();
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 3e3215dee82..50eb6f82c27 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -558,6 +558,25 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
return std::make_pair(Result, true);
}
+Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
+ StringRef Name) {
+ assert(LangOpts.CurrentModule == Name && "module name mismatch");
+ assert(!Modules[Name] && "redefining existing module");
+
+ auto *Result =
+ new Module(Name, Loc, nullptr, /*IsFramework*/ false,
+ /*IsExplicit*/ false, NumCreatedModules++);
+ Modules[Name] = SourceModule = Result;
+
+ // Mark the main source file as being within the newly-created module so that
+ // declarations and macros are properly visibility-restricted to it.
+ auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+ assert(MainFile && "no input file for module interface");
+ Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
+
+ return Result;
+}
+
/// \brief For a framework module, infer the framework against which we
/// should link.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
@@ -805,7 +824,7 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
bool isCompilingModuleHeader =
- LangOpts.CompilingModule && Mod->getTopLevelModule() == SourceModule;
+ LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index e2eceafd983..33d690de8b2 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -685,7 +685,7 @@ bool Preprocessor::needModuleMacros() const {
return true;
// Otherwise, we only need module macros if we're actually compiling a module
// interface.
- return getLangOpts().CompilingModule;
+ return getLangOpts().isCompilingModule();
}
void Preprocessor::LeaveSubmodule() {
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index a201838e815..3566c3429fe 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1795,7 +1795,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
[this](Token &Tok, bool &HasLexedNextToken) -> int {
IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
diag::err_expected_id_building_module);
- return getLangOpts().CompilingModule && II &&
+ return getLangOpts().isCompilingModule() && II &&
(II->getName() == getLangOpts().CurrentModule);
});
} else if (II == Ident__MODULE__) {
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 096a6107a95..1f28b3b268d 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -480,7 +480,7 @@ void Preprocessor::CreateString(StringRef Str, Token &Tok,
}
Module *Preprocessor::getCurrentModule() {
- if (!getLangOpts().CompilingModule)
+ if (!getLangOpts().isCompilingModule())
return nullptr;
return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule);
@@ -795,6 +795,23 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty()) {
+ // Under the Modules TS, the dot is just part of the module name, and not
+ // a real hierarachy separator. Flatten such module names now.
+ //
+ // FIXME: Is this the right level to be performing this transformation?
+ std::string FlatModuleName;
+ if (getLangOpts().ModulesTS) {
+ for (auto &Piece : ModuleImportPath) {
+ if (!FlatModuleName.empty())
+ FlatModuleName += ".";
+ FlatModuleName += Piece.first->getName();
+ }
+ SourceLocation FirstPathLoc = ModuleImportPath[0].second;
+ ModuleImportPath.clear();
+ ModuleImportPath.push_back(
+ std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));
+ }
+
Module *Imported = nullptr;
if (getLangOpts().Modules) {
Imported = TheModuleLoader.loadModule(ModuleImportLoc,
diff --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp
index bab3dbefb0d..d018d4c08ed 100644
--- a/clang/lib/Parse/ParseAST.cpp
+++ b/clang/lib/Parse/ParseAST.cpp
@@ -138,26 +138,18 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
S.getPreprocessor().EnterMainSourceFile();
P.Initialize();
- // C11 6.9p1 says translation units must have at least one top-level
- // declaration. C++ doesn't have this restriction. We also don't want to
- // complain if we have a precompiled header, although technically if the PCH
- // is empty we should still emit the (pedantic) diagnostic.
Parser::DeclGroupPtrTy ADecl;
ExternalASTSource *External = S.getASTContext().getExternalSource();
if (External)
External->StartTranslationUnit(Consumer);
- if (P.ParseFirstTopLevelDecl(ADecl)) {
- if (!External && !S.getLangOpts().CPlusPlus)
- P.Diag(diag::ext_empty_translation_unit);
- } else {
- do {
- // If we got a null return and something *was* parsed, ignore it. This
- // is due to a top-level semicolon, an action override, or a parse error
- // skipping something.
- if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
- return;
- } while (!P.ParseTopLevelDecl(ADecl));
+ for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF;
+ AtEOF = P.ParseTopLevelDecl(ADecl)) {
+ // If we got a null return and something *was* parsed, ignore it. This
+ // is due to a top-level semicolon, an action override, or a parse error
+ // skipping something.
+ if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
+ return;
}
// Process any TopLevelDecls generated by #pragma weak.
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index a391363ff38..e58e3f7c20e 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -544,11 +544,21 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
if (Tok.is(tok::kw_module)) {
Result = ParseModuleDecl();
return false;
+ } else if (getLangOpts().getCompilingModule() ==
+ LangOptions::CMK_ModuleInterface) {
+ Diag(Tok, diag::err_expected_module_interface_decl);
}
- // FIXME: If we're parsing a module interface and we don't have a module
- // declaration here, diagnose.
- return ParseTopLevelDecl(Result);
+ // C11 6.9p1 says translation units must have at least one top-level
+ // declaration. C++ doesn't have this restriction. We also don't want to
+ // complain if we have a precompiled header, although technically if the PCH
+ // is empty we should still emit the (pedantic) diagnostic.
+ bool NoTopLevelDecls = ParseTopLevelDecl(Result);
+ if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&
+ !getLangOpts().CPlusPlus)
+ Diag(diag::ext_empty_translation_unit);
+
+ return NoTopLevelDecls;
}
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
@@ -820,6 +830,11 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParseMicrosoftIfExistsExternalDeclaration();
return nullptr;
+ case tok::kw_module:
+ Diag(Tok, diag::err_unexpected_module_decl);
+ SkipUntil(tok::semi);
+ return nullptr;
+
default:
dont_know:
// We can't tell whether this is a function-definition or declaration yet.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9122030e16d..c756d1f6ab6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15180,48 +15180,84 @@ void Sema::diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc) {
Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation ModuleLoc,
ModuleDeclKind MDK,
ModuleIdPath Path) {
- // We should see 'module implementation' if and only if we are not compiling
- // a module interface.
- if (getLangOpts().CompilingModule ==
- (MDK == ModuleDeclKind::Implementation)) {
+ // 'module implementation' requires that we are not compiling a module of any
+ // kind. 'module' and 'module partition' require that we are compiling a
+ // module inteface (not a module map).
+ auto CMK = getLangOpts().getCompilingModule();
+ if (MDK == ModuleDeclKind::Implementation
+ ? CMK != LangOptions::CMK_None
+ : CMK != LangOptions::CMK_ModuleInterface) {
Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
<< (unsigned)MDK;
return nullptr;
}
// FIXME: Create a ModuleDecl and return it.
- // FIXME: Teach the lexer to handle this declaration too.
+
+ // FIXME: Most of this work should be done by the preprocessor rather than
+ // here, in case we look ahead across something where the current
+ // module matters (eg a #include).
+
+ // The dots in a module name in the Modules TS are a lie. Unlike Clang's
+ // hierarchical module map modules, the dots here are just another character
+ // that can appear in a module name. Flatten down to the actual module name.
+ std::string ModuleName;
+ for (auto &Piece : Path) {
+ if (!ModuleName.empty())
+ ModuleName += ".";
+ ModuleName += Piece.first->getName();
+ }
+
+ // If a module name was explicitly specified on the command line, it must be
+ // correct.
+ if (!getLangOpts().CurrentModule.empty() &&
+ getLangOpts().CurrentModule != ModuleName) {
+ Diag(Path.front().second, diag::err_current_module_name_mismatch)
+ << SourceRange(Path.front().second, Path.back().second)
+ << getLangOpts().CurrentModule;
+ return nullptr;
+ }
+ const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
+
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
switch (MDK) {
- case ModuleDeclKind::Module:
+ case ModuleDeclKind::Module: {
// FIXME: Check we're not in a submodule.
- // FIXME: Set CurrentModule and create a corresponding Module object.
+
+ // We can't have imported a definition of this module or parsed a module
+ // map defining it already.
+ if (auto *M = Map.findModule(ModuleName)) {
+ Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
+ if (M->DefinitionLoc.isValid())
+ Diag(M->DefinitionLoc, diag::note_prev_module_definition);
+ else if (const auto *FE = M->getASTFile())
+ Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
+ << FE->getName();
+ return nullptr;
+ }
+
+ // Create a Module for the module that we're defining.
+ Module *Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
+ assert(Mod && "module creation should not fail");
+
+ // Enter the semantic scope of the module.
+ ActOnModuleBegin(ModuleLoc, Mod);
return nullptr;
+ }
case ModuleDeclKind::Partition:
// FIXME: Check we are in a submodule of the named module.
return nullptr;
case ModuleDeclKind::Implementation:
- DeclResult Import = ActOnModuleImport(ModuleLoc, ModuleLoc, Path);
+ std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
+ PP.getIdentifierInfo(ModuleName), Path[0].second);
+
+ DeclResult Import = ActOnModuleImport(ModuleLoc, ModuleLoc, ModuleNameLoc);
if (Import.isInvalid())
return nullptr;
- ImportDecl *ID = cast<ImportDecl>(Import.get());
-
- // The current module is whatever we just loaded.
- //
- // FIXME: We should probably do this from the lexer rather than waiting
- // until now, in case we look ahead across something where the current
- // module matters (eg a #include).
- auto Name = ID->getImportedModule()->getTopLevelModuleName();
- if (!getLangOpts().CurrentModule.empty() &&
- getLangOpts().CurrentModule != Name) {
- Diag(Path.front().second, diag::err_current_module_name_mismatch)
- << SourceRange(Path.front().second, Path.back().second)
- << getLangOpts().CurrentModule;
- }
- const_cast<LangOptions&>(getLangOpts()).CurrentModule = Name;
- return ConvertDeclToDeclGroup(ID);
+ return ConvertDeclToDeclGroup(Import.get());
}
llvm_unreachable("unexpected module decl kind");
@@ -15246,8 +15282,8 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
// Import-from-implementation is valid in the Modules TS. FIXME: Should we
// warn on a redundant import of the current module?
if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
- (getLangOpts().CompilingModule || !getLangOpts().ModulesTS))
- Diag(ImportLoc, getLangOpts().CompilingModule
+ (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS))
+ Diag(ImportLoc, getLangOpts().isCompilingModule()
? diag::err_module_self_import
: diag::err_module_import_in_implementation)
<< Mod->getFullModuleName() << getLangOpts().CurrentModule;
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 9750d53743b..3237cd00521 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -3217,7 +3217,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List,
ObjCMethodList *ListWithSameDeclaration = nullptr;
for (; List; Previous = List, List = List->getNext()) {
// If we are building a module, keep all of the methods.
- if (getLangOpts().CompilingModule)
+ if (getLangOpts().isCompilingModule())
continue;
bool SameDeclaration = MatchTwoMethodDeclarations(Method,
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index b2d79a20871..e1765dafd96 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -46,10 +46,13 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
return;
Module *Module = nullptr;
- if (PP.getLangOpts().CompilingModule) {
+ if (PP.getLangOpts().isCompilingModule()) {
Module = PP.getHeaderSearchInfo().lookupModule(
PP.getLangOpts().CurrentModule, /*AllowSearch*/ false);
- assert(Module && "emitting module but current module doesn't exist");
+ if (!Module) {
+ assert(hasErrors && "emitting module but current module doesn't exist");
+ return;
+ }
}
// Emit the PCH file to the Buffer.
OpenPOWER on IntegriCloud