r250137 - [modules] Allow the error on importing a C++ module within an extern "C"

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 17:39:41 PDT 2015


Author: rsmith
Date: Mon Oct 12 19:39:40 2015
New Revision: 250137

URL: http://llvm.org/viewvc/llvm-project?rev=250137&view=rev
Log:
[modules] Allow the error on importing a C++ module within an extern "C"
context (but otherwise at the top level) to be disabled, to support use of C++
standard library implementations that (legitimately) mark their <blah.h>
headers as being C++ headers from C libraries that wrap things in 'extern "C"'
a bit too enthusiastically.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Modules/extern_c.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=250137&r1=250136&r2=250137&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 12 19:39:40 2015
@@ -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<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=250137&r1=250136&r2=250137&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Oct 12 19:39:40 2015
@@ -14424,15 +14424,13 @@ Decl *Sema::ActOnFileScopeAsmDecl(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(Sem
 
   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);
   }
 }
 

Modified: cfe/trunk/test/Modules/extern_c.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/extern_c.cpp?rev=250137&r1=250136&r2=250137&view=diff
==============================================================================
--- cfe/trunk/test/Modules/extern_c.cpp (original)
+++ cfe/trunk/test/Modules/extern_c.cpp Mon Oct 12 19:39:40 2015
@@ -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 at -3 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
-// expected-note at -17 {{extern "C" language linkage specification begins here}}
-#elif defined(NAMESPACE)
-// expected-error-re at -6 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
-// expected-note at -24 {{namespace 'M' begins here}}
+#if defined(NAMESPACE)
+// expected-error-re at -3 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
+// expected-note at -21 {{namespace 'M' begins here}}
+#elif defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER) && !defined(NO_EXTERN_C_ERROR)
+// expected-error at -6 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
+// expected-note at -20 {{extern "C" language linkage specification begins here}}
 #endif
 
 #ifdef EXTERN_CXX




More information about the cfe-commits mailing list