From 779448684662c1fb97d2daec6fbf769ca2515a6d Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 2 Mar 2014 05:58:18 +0000 Subject: Add [extern_c] attribute for modules, allowing a C module to be imported within an extern "C" block in C++ code. llvm-svn: 202615 --- clang/lib/Sema/SemaDecl.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema/SemaDecl.cpp') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 69dd4905cb5..abcd886da6b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12957,6 +12957,36 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, return New; } +static void checkModuleImportContext(Sema &S, Module *M, + SourceLocation ImportLoc, + DeclContext *DC) { + if (auto *LSD = dyn_cast(DC)) { + switch (LSD->getLanguage()) { + case LinkageSpecDecl::lang_c: + if (!M->IsExternC) { + S.Diag(ImportLoc, diag::err_module_import_in_extern_c) + << M->getFullModuleName(); + S.Diag(LSD->getLocStart(), diag::note_module_import_in_extern_c); + return; + } + break; + case LinkageSpecDecl::lang_cxx: + break; + } + DC = LSD->getParent(); + } + + while (isa(DC)) + DC = DC->getParent(); + if (!isa(DC)) { + S.Diag(ImportLoc, diag::err_module_import_not_at_top_level) + << M->getFullModuleName() << DC; + S.Diag(cast(DC)->getLocStart(), + diag::note_module_import_not_at_top_level) + << DC; + } +} + DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, ModuleIdPath Path) { @@ -12965,7 +12995,9 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, /*IsIncludeDirective=*/false); if (!Mod) return true; - + + checkModuleImportContext(*this, Mod, ImportLoc, CurContext); + SmallVector IdentifierLocs; Module *ModCheck = Mod; for (unsigned I = 0, N = Path.size(); I != N; ++I) { @@ -12987,6 +13019,8 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, } void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + // FIXME: Should we synthesize an ImportDecl here? PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc, /*Complain=*/true); -- cgit v1.2.3