summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
-rw-r--r--clang/test/Modules/extern_c.cpp14
3 files changed, 20 insertions, 14 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index ab4cf0e5429..2cc863f4a18 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7803,9 +7803,10 @@ def err_module_unimported_use : Error<
def err_module_unimported_use_multiple : Error<
"%select{declaration|definition|default argument}0 of %1 must be imported "
"from one of the following modules before it is required:%2">;
-def err_module_import_in_extern_c : Error<
+def ext_module_import_in_extern_c : ExtWarn<
"import of C++ module '%0' appears within extern \"C\" language linkage "
- "specification">;
+ "specification">, DefaultError,
+ InGroup<DiagGroup<"module-import-in-extern-c">>;
def note_module_import_in_extern_c : Note<
"extern \"C\" language linkage specification begins here">;
def err_module_import_not_at_top_level_fatal : Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a12ff3a02e9..174b9cf50f2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14424,15 +14424,13 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
static void checkModuleImportContext(Sema &S, Module *M,
SourceLocation ImportLoc,
DeclContext *DC) {
+ SourceLocation ExternCLoc;
+
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;
- }
+ if (ExternCLoc.isInvalid())
+ ExternCLoc = LSD->getLocStart();
break;
case LinkageSpecDecl::lang_cxx:
break;
@@ -14442,11 +14440,16 @@ static void checkModuleImportContext(Sema &S, Module *M,
while (isa<LinkageSpecDecl>(DC))
DC = DC->getParent();
+
if (!isa<TranslationUnitDecl>(DC)) {
S.Diag(ImportLoc, diag::err_module_import_not_at_top_level_fatal)
<< M->getFullModuleName() << DC;
S.Diag(cast<Decl>(DC)->getLocStart(),
diag::note_module_import_not_at_top_level) << DC;
+ } else if (!M->IsExternC && ExternCLoc.isValid()) {
+ S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
+ << M->getFullModuleName();
+ S.Diag(ExternCLoc, diag::note_module_import_in_extern_c);
}
}
diff --git a/clang/test/Modules/extern_c.cpp b/clang/test/Modules/extern_c.cpp
index c9b4b8435fd..c072b7e75ab 100644
--- a/clang/test/Modules/extern_c.cpp
+++ b/clang/test/Modules/extern_c.cpp
@@ -9,6 +9,8 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_CXX
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DEXTERN_CXX
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNAMESPACE
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNO_EXTERN_C_ERROR -Wno-module-import-in-extern-c
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNAMESPACE -DNO_EXTERN_C_ERROR -Wno-module-import-in-extern-c
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs -x c %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs/elsewhere -I %S/Inputs %s -DEXTERN_C -DINDIRECT
@@ -36,12 +38,12 @@ extern "C++" {
#include HEADER
-#if defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER)
-// expected-error@-3 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
-// expected-note@-17 {{extern "C" language linkage specification begins here}}
-#elif defined(NAMESPACE)
-// expected-error-re@-6 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
-// expected-note@-24 {{namespace 'M' begins here}}
+#if defined(NAMESPACE)
+// expected-error-re@-3 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
+// expected-note@-21 {{namespace 'M' begins here}}
+#elif defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER) && !defined(NO_EXTERN_C_ERROR)
+// expected-error@-6 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
+// expected-note@-20 {{extern "C" language linkage specification begins here}}
#endif
#ifdef EXTERN_CXX
OpenPOWER on IntegriCloud