]> granicus.if.org Git - clang/commitdiff
[Modules][ObjC] Warn on the use of '@import' in framework headers
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Wed, 27 Jun 2018 20:29:36 +0000 (20:29 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Wed, 27 Jun 2018 20:29:36 +0000 (20:29 +0000)
Using @import in framework headers inhibit the use of such headers
when not using modules, this is specially bad for headers that end
up in the SDK (or any other system framework). Add a warning to give
users some indication that this is discouraged.

rdar://problem/39192894

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335780 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/Parser.cpp
test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h [new file with mode: 0644]
test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap [new file with mode: 0644]
test/Modules/Inputs/at-import-in-framework-header/module.modulemap [new file with mode: 0644]
test/Modules/at-import-in-framework-header.m [new file with mode: 0644]
test/VFS/umbrella-mismatch.m

index 56384db1246de90338251c7dde2c57404ae0e654..a7fe5032dffdd5a41d672da2c20bcb6fdea7ccc2 100644 (file)
@@ -34,6 +34,7 @@ def AutoImport : DiagGroup<"auto-import">;
 def FrameworkHdrQuotedInclude : DiagGroup<"quoted-include-in-framework-header">;
 def FrameworkIncludePrivateFromPublic :
   DiagGroup<"framework-include-private-from-public">;
+def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">;
 def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
 def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">;
 def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">;
index ee9ca7118b18203ce2822d572aaff5fd1349ea2e..c2a1f095f17d7b2e8bab193f73fdcfb341ca53ac 100644 (file)
@@ -248,6 +248,11 @@ def err_unexpected_at : Error<"unexpected '@' in program">;
 def err_atimport : Error<
 "use of '@import' when modules are disabled">;
 
+def warn_atimport_in_framework_header : Warning<
+  "use of '@import' in framework header is discouraged, "
+  "including this header requires -fmodules">,
+  InGroup<FrameworkHdrAtImport>;
+
 def err_invalid_reference_qualifier_application : Error<
   "'%0' qualifier may not be applied to a reference">;
 def err_illegal_decl_reference_to_reference : Error<
index d9255109d72974604a7b999299f1e49686431dea..d1c35352ae4b8fbeeff3cf89550b70437d05baf7 100644 (file)
@@ -20,6 +20,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
+#include "llvm/Support/Path.h"
 using namespace clang;
 
 
@@ -2123,6 +2124,7 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
   assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import)
                             : Tok.isObjCAtKeyword(tok::objc_import)) &&
          "Improper start to module import");
+  bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
   SourceLocation ImportLoc = ConsumeToken();
   SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc;
   
@@ -2146,6 +2148,16 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
   if (Import.isInvalid())
     return nullptr;
 
+  // Using '@import' in framework headers requires modules to be enabled so that
+  // the header is parseable. Emit a warning to make the user aware.
+  if (IsObjCAtImport && AtLoc.isValid()) {
+    auto &SrcMgr = PP.getSourceManager();
+    auto *FE = SrcMgr.getFileEntryForID(SrcMgr.getFileID(AtLoc));
+    if (FE && llvm::sys::path::parent_path(FE->getDir()->getName())
+                  .endswith(".framework"))
+      Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);
+  }
+
   return Import.get();
 }
 
diff --git a/test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h
new file mode 100644 (file)
index 0000000..6949a87
--- /dev/null
@@ -0,0 +1,2 @@
+@import B;
+int foo();
diff --git a/test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap
new file mode 100644 (file)
index 0000000..126cf26
--- /dev/null
@@ -0,0 +1,4 @@
+// at-import-in-framework-header/A.framework/Modules/module.modulemap
+framework module A {
+  header "A.h"
+}
diff --git a/test/Modules/Inputs/at-import-in-framework-header/module.modulemap b/test/Modules/Inputs/at-import-in-framework-header/module.modulemap
new file mode 100644 (file)
index 0000000..a38d668
--- /dev/null
@@ -0,0 +1,2 @@
+// at-import-in-framework-header/module.modulemap
+module B {}
diff --git a/test/Modules/at-import-in-framework-header.m b/test/Modules/at-import-in-framework-header.m
new file mode 100644 (file)
index 0000000..fe36638
--- /dev/null
@@ -0,0 +1,17 @@
+// REQUIRES: shell
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \
+// RUN:   -F%S/Inputs/at-import-in-framework-header -I%S/Inputs/at-import-in-framework-header \
+// RUN:   -Watimport-in-framework-header -fsyntax-only %s \
+// RUN:   2>%t/stderr
+// RUN: FileCheck --input-file=%t/stderr %s
+
+// CHECK: use of '@import' in framework header is discouraged
+
+#import <A/A.h>
+
+int bar() { return foo(); }
+
index fc5180241619097d491ae7e7db0e5f138fe45da0..8167a21f485bb4533f1cced13f945af24e96c3ea 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
 // RUN: sed -e "s;INPUT_DIR;%/S/Inputs;g" -e "s;OUT_DIR;%/S/Inputs;g" %S/Inputs/vfsoverlay.yaml > %t.yaml
 
-// RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -F %S/Inputs -fsyntax-only %s -verify
-// RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs -fsyntax-only %s -verify
+// RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -ivfsoverlay %t.yaml -F %S/Inputs -fsyntax-only %s -Wno-atimport-in-framework-header -verify
+// RUN: %clang_cc1 -Werror -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs -fsyntax-only %s -Wno-atimport-in-framework-header -verify
 // expected-no-diagnostics
 @import UsesFoo;