diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 81 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendOptions.cpp | 2 | ||||
-rw-r--r-- | clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Parse/ParseAST.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 88 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/GeneratePCH.cpp | 7 |
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. |