diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-02 05:58:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-03-02 05:58:18 +0000 |
commit | 779448684662c1fb97d2daec6fbf769ca2515a6d (patch) | |
tree | b19ea3bc584c37388126eadd15a21df44df4a1f6 /clang/lib/Sema/SemaDecl.cpp | |
parent | 293a81c406a4cbc94f03a9989166534064c701e7 (diff) | |
download | bcm5719-llvm-779448684662c1fb97d2daec6fbf769ca2515a6d.tar.gz bcm5719-llvm-779448684662c1fb97d2daec6fbf769ca2515a6d.zip |
Add [extern_c] attribute for modules, allowing a C module to be imported within an extern "C" block in C++ code.
llvm-svn: 202615
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
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<LinkageSpecDecl>(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<LinkageSpecDecl>(DC)) + DC = DC->getParent(); + if (!isa<TranslationUnitDecl>(DC)) { + S.Diag(ImportLoc, diag::err_module_import_not_at_top_level) + << M->getFullModuleName() << DC; + S.Diag(cast<Decl>(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<SourceLocation, 2> 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); |