mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-10 18:11:19 +00:00
[Modules] Change private modules rules and warnings
We used to advertise private modules to be declared as submodules (Foo.Private). This has proven to not scale well since private headers might carry several dependencies, introducing unwanted content into the main module and often causing dep cycles. Change the canonical way to name it to Foo_Private, forcing private modules as top level ones, and provide warnings under -Wprivate-module to suggest fixes for other private naming. Update documentation to reflect that. rdar://problem/31173501 llvm-svn: 321337
This commit is contained in:
parent
67885f5d58
commit
2972991969
@ -859,10 +859,12 @@ express this with a single module map file in the library:
|
||||
|
||||
module Foo {
|
||||
header "Foo.h"
|
||||
|
||||
explicit module Private {
|
||||
header "Foo_Private.h"
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
module Foo_Private {
|
||||
header "Foo_Private.h"
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
@ -873,7 +875,7 @@ build machinery.
|
||||
|
||||
Private module map files, which are named ``module.private.modulemap``
|
||||
(or, for backward compatibility, ``module_private.map``), allow one to
|
||||
augment the primary module map file with an additional submodule. For
|
||||
augment the primary module map file with an additional modules. For
|
||||
example, we would split the module map file above into two module map
|
||||
files:
|
||||
|
||||
@ -883,9 +885,9 @@ files:
|
||||
module Foo {
|
||||
header "Foo.h"
|
||||
}
|
||||
|
||||
|
||||
/* module.private.modulemap */
|
||||
explicit module Foo.Private {
|
||||
module Foo_Private {
|
||||
header "Foo_Private.h"
|
||||
}
|
||||
|
||||
@ -899,13 +901,12 @@ boundaries.
|
||||
|
||||
When writing a private module as part of a *framework*, it's recommended that:
|
||||
|
||||
* Headers for this module are present in the ``PrivateHeaders``
|
||||
framework subdirectory.
|
||||
* The private module is defined as a *submodule* of the public framework (if
|
||||
there's one), similar to how ``Foo.Private`` is defined in the example above.
|
||||
* The ``explicit`` keyword should be used to guarantee that its content will
|
||||
only be available when the submodule itself is explicitly named (through a
|
||||
``@import`` for example).
|
||||
* Headers for this module are present in the ``PrivateHeaders`` framework
|
||||
subdirectory.
|
||||
* The private module is defined as a *top level module* with the name of the
|
||||
public framework prefixed, like ``Foo_Private`` above. Clang has extra logic
|
||||
to work with this naming, using ``FooPrivate`` or ``Foo.Private`` (submodule)
|
||||
trigger warnings and might not work as expected.
|
||||
|
||||
Modularizing a Platform
|
||||
=======================
|
||||
|
@ -691,11 +691,15 @@ def err_mmap_expected_feature : Error<"expected a feature name">;
|
||||
def err_mmap_expected_attribute : Error<"expected an attribute name">;
|
||||
def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def warn_mmap_mismatched_top_level_private : Warning<
|
||||
"top-level module '%0' in private module map, expected a submodule of '%1'">,
|
||||
def warn_mmap_mismatched_private_submodule : Warning<
|
||||
"private submodule '%0' in private module map, expected top-level module">,
|
||||
InGroup<PrivateModule>;
|
||||
def note_mmap_rename_top_level_private_as_submodule : Note<
|
||||
"make '%0' a submodule of '%1' to ensure it can be found by name">;
|
||||
def warn_mmap_mismatched_private_module_name : Warning<
|
||||
"expected canonical name for private module '%0'">,
|
||||
InGroup<PrivateModule>;
|
||||
def note_mmap_rename_top_level_private_module : Note<
|
||||
"rename '%0' to ensure it can be found by name">;
|
||||
|
||||
def err_mmap_duplicate_header_attribute : Error<
|
||||
"header attribute '%0' specified multiple times">;
|
||||
def err_mmap_invalid_header_attribute_value : Error<
|
||||
|
@ -209,11 +209,14 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
|
||||
|
||||
// The facility for "private modules" -- adjacent, optional module maps named
|
||||
// module.private.modulemap that are supposed to define private submodules --
|
||||
// is sometimes misused by frameworks that name their associated private
|
||||
// module FooPrivate, rather than as a submodule named Foo.Private as
|
||||
// intended. Here we compensate for such cases by looking in directories named
|
||||
// Foo.framework, when we previously looked and failed to find a
|
||||
// FooPrivate.framework.
|
||||
// may have different flavors of names: FooPrivate, Foo_Private and Foo.Private.
|
||||
//
|
||||
// Foo.Private is now depracated in favor of Foo_Private. Users of FooPrivate
|
||||
// should also rename to Foo_Private. Representing private as submodules
|
||||
// could force building unwanted dependencies into the parent module and cause
|
||||
// dependency cycles.
|
||||
if (!Module && SearchName.consume_back("_Private"))
|
||||
Module = lookupModule(ModuleName, SearchName);
|
||||
if (!Module && SearchName.consume_back("Private"))
|
||||
Module = lookupModule(ModuleName, SearchName);
|
||||
return Module;
|
||||
|
@ -1608,6 +1608,54 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Private modules are canonicalized as Foo_Private. Clang provides extra
|
||||
/// module map search logic to find the appropriate private module when PCH
|
||||
/// is used with implicit module maps. Warn when private modules are written
|
||||
/// in other ways (FooPrivate and Foo.Private), providing notes and fixits.
|
||||
static void diagnosePrivateModules(const ModuleMap &Map,
|
||||
DiagnosticsEngine &Diags,
|
||||
const Module *ActiveModule) {
|
||||
|
||||
auto GenNoteAndFixIt = [&](StringRef BadName, StringRef Canonical,
|
||||
const Module *M) {
|
||||
auto D = Diags.Report(ActiveModule->DefinitionLoc,
|
||||
diag::note_mmap_rename_top_level_private_module);
|
||||
D << BadName << M->Name;
|
||||
D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc, Canonical);
|
||||
};
|
||||
|
||||
for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
|
||||
auto const *M = E->getValue();
|
||||
if (M->Directory != ActiveModule->Directory)
|
||||
continue;
|
||||
|
||||
SmallString<128> FullName(ActiveModule->getFullModuleName());
|
||||
if (!FullName.startswith(M->Name) && !FullName.endswith("Private"))
|
||||
continue;
|
||||
SmallString<128> Canonical(M->Name);
|
||||
Canonical.append("_Private");
|
||||
|
||||
// Foo.Private -> Foo_Private
|
||||
if (ActiveModule->Parent && ActiveModule->Name == "Private" && !M->Parent &&
|
||||
M->Name == ActiveModule->Parent->Name) {
|
||||
Diags.Report(ActiveModule->DefinitionLoc,
|
||||
diag::warn_mmap_mismatched_private_submodule)
|
||||
<< FullName;
|
||||
GenNoteAndFixIt(FullName, Canonical, M);
|
||||
continue;
|
||||
}
|
||||
|
||||
// FooPrivate and whatnots -> Foo_Private
|
||||
if (!ActiveModule->Parent && !M->Parent && M->Name != ActiveModule->Name &&
|
||||
ActiveModule->Name != Canonical) {
|
||||
Diags.Report(ActiveModule->DefinitionLoc,
|
||||
diag::warn_mmap_mismatched_private_module_name)
|
||||
<< ActiveModule->Name;
|
||||
GenNoteAndFixIt(ActiveModule->Name, Canonical, M);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Parse a module declaration.
|
||||
///
|
||||
/// module-declaration:
|
||||
@ -1791,41 +1839,21 @@ void ModuleMapParser::parseModuleDecl() {
|
||||
ActiveModule->NoUndeclaredIncludes = true;
|
||||
ActiveModule->Directory = Directory;
|
||||
|
||||
if (!ActiveModule->Parent) {
|
||||
StringRef MapFileName(ModuleMapFile->getName());
|
||||
if (MapFileName.endswith("module.private.modulemap") ||
|
||||
MapFileName.endswith("module_private.map")) {
|
||||
// Adding a top-level module from a private modulemap is likely a
|
||||
// user error; we check to see if there's another top-level module
|
||||
// defined in the non-private map in the same dir, and if so emit a
|
||||
// warning.
|
||||
for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
|
||||
auto const *M = E->getValue();
|
||||
if (!M->Parent &&
|
||||
M->Directory == ActiveModule->Directory &&
|
||||
M->Name != ActiveModule->Name) {
|
||||
Diags.Report(ActiveModule->DefinitionLoc,
|
||||
diag::warn_mmap_mismatched_top_level_private)
|
||||
<< ActiveModule->Name << M->Name;
|
||||
// The pattern we're defending against here is typically due to
|
||||
// a module named FooPrivate which is supposed to be a submodule
|
||||
// called Foo.Private. Emit a fixit in that case.
|
||||
auto D =
|
||||
Diags.Report(ActiveModule->DefinitionLoc,
|
||||
diag::note_mmap_rename_top_level_private_as_submodule);
|
||||
D << ActiveModule->Name << M->Name;
|
||||
StringRef Bad(ActiveModule->Name);
|
||||
if (Bad.consume_back("Private")) {
|
||||
SmallString<128> Fixed = Bad;
|
||||
Fixed.append(".Private");
|
||||
D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
|
||||
Fixed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Private modules named as FooPrivate, Foo.Private or similar are likely a
|
||||
// user error; provide warnings, notes and fixits to direct users to use
|
||||
// Foo_Private instead.
|
||||
SourceLocation StartLoc =
|
||||
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
|
||||
StringRef MapFileName(ModuleMapFile->getName());
|
||||
if (Map.HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
|
||||
!Diags.isIgnored(diag::warn_mmap_mismatched_private_submodule,
|
||||
StartLoc) &&
|
||||
!Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
|
||||
StartLoc) &&
|
||||
(MapFileName.endswith("module.private.modulemap") ||
|
||||
MapFileName.endswith("module_private.map")))
|
||||
diagnosePrivateModules(Map, Diags, ActiveModule);
|
||||
|
||||
bool Done = false;
|
||||
do {
|
||||
|
@ -0,0 +1 @@
|
||||
extern int APUBLIC;
|
@ -0,0 +1,4 @@
|
||||
framework module A {
|
||||
header "a.h"
|
||||
export *
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
framework module A_Private {
|
||||
header "aprivate.h"
|
||||
export *
|
||||
}
|
@ -0,0 +1 @@
|
||||
extern int APRIVATE;
|
@ -0,0 +1 @@
|
||||
extern int APRIVATE;
|
@ -0,0 +1 @@
|
||||
extern int APUBLIC;
|
@ -0,0 +1 @@
|
||||
extern int APRIVATE;
|
@ -0,0 +1,4 @@
|
||||
framework module A {
|
||||
header "a.h"
|
||||
export *
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
framework module A.Private {
|
||||
header "aprivate.h"
|
||||
export *
|
||||
}
|
@ -0,0 +1 @@
|
||||
extern int APRIVATE;
|
@ -4,7 +4,7 @@
|
||||
// RUN: cp -r %S/Inputs/AddRemovePrivate.framework %t/AddRemovePrivate.framework
|
||||
|
||||
// Build with module.private.modulemap
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -fdisable-module-hash -F %t %s -verify -DP
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -fdisable-module-hash -F %t %s -verify -DP -Wno-private-module
|
||||
// RUN: cp %t.mcp/AddRemovePrivate.pcm %t/with.pcm
|
||||
|
||||
// Build without module.private.modulemap
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
// Build with module.private.modulemap (again)
|
||||
// RUN: cp %S/Inputs/AddRemovePrivate.framework/Modules/module.private.modulemap %t/AddRemovePrivate.framework/Modules/module.private.modulemap
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -fdisable-module-hash -F %t %s -verify -DP
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -fdisable-module-hash -F %t %s -verify -DP -Wno-private-module
|
||||
// RUN: not diff %t.mcp/AddRemovePrivate.pcm %t/without.pcm
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
@ -1,7 +1,7 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify -DERRORS
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -xobjective-c++ %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify -DERRORS
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -xobjective-c++ %s -verify
|
||||
//
|
||||
// Test both with and without the declarations that refer to unimported
|
||||
// entities. For error recovery, those cases implicitly trigger an import.
|
||||
|
@ -1,12 +1,12 @@
|
||||
// RUN: rm -rf %t
|
||||
// Run without global module index
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -fno-modules-global-index -F %S/Inputs %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -fno-modules-global-index -F %S/Inputs %s -verify
|
||||
// RUN: ls %t|not grep modules.idx
|
||||
// Run and create the global module index
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify
|
||||
// RUN: ls %t|grep modules.idx
|
||||
// Run and use the global module index
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify -print-stats 2>&1 | FileCheck %s
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fdisable-module-hash -fmodules -fimplicit-module-maps -F %S/Inputs %s -verify -print-stats 2>&1 | FileCheck %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
@import DependsOnModule;
|
||||
|
35
clang/test/Modules/implicit-private-canonical.m
Normal file
35
clang/test/Modules/implicit-private-canonical.m
Normal file
@ -0,0 +1,35 @@
|
||||
// RUN: rm -rf %t
|
||||
// Build PCH using A, with adjacent private module APrivate, which winds up being implicitly referenced
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -emit-pch -o %t-A.pch %s -Wprivate-module -DNO_AT_IMPORT
|
||||
// Use the PCH with no explicit way to resolve APrivate, still pick it up by automatic second-chance search for "A" with "Private" appended
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -include-pch %t-A.pch %s -fsyntax-only -Wprivate-module -DNO_AT_IMPORT
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -emit-pch -o %t-A.pch %s -Wprivate-module -DUSE_AT_IMPORT_PRIV
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -include-pch %t-A.pch %s -fsyntax-only -Wprivate-module -DUSE_AT_IMPORT_PRIV
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -emit-pch -o %t-A.pch %s -Wprivate-module -DUSE_AT_IMPORT_BOTH
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -include-pch %t-A.pch %s -fsyntax-only -Wprivate-module -DUSE_AT_IMPORT_BOTH
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
#ifdef NO_AT_IMPORT
|
||||
#import "A/aprivate.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_AT_IMPORT_PRIV
|
||||
@import A_Private;
|
||||
#endif
|
||||
|
||||
#ifdef USE_AT_IMPORT_BOTH
|
||||
@import A;
|
||||
@import A_Private;
|
||||
#endif
|
||||
|
||||
const int *y = &APRIVATE;
|
||||
|
||||
#endif
|
@ -1,17 +1,17 @@
|
||||
// RUN: rm -rf %t
|
||||
|
||||
// Build PCH using A, with adjacent private module APrivate, which winds up being implicitly referenced
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -emit-pch -o %t-A.pch %s
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -emit-pch -o %t-A.pch %s -Wprivate-module
|
||||
|
||||
// Use the PCH with no explicit way to resolve APrivate, still pick it up by automatic second-chance search for "A" with "Private" appended
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only -Wprivate-module
|
||||
|
||||
// Check the fixit
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-different-name -include-pch %t-A.pch %s -fsyntax-only -fdiagnostics-parseable-fixits -Wprivate-module %s 2>&1 | FileCheck %s
|
||||
|
||||
// expected-warning@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{top-level module 'APrivate' in private module map, expected a submodule of 'A'}}
|
||||
// expected-note@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{make 'APrivate' a submodule of 'A' to ensure it can be found by name}}
|
||||
// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:18-1:26}:"A.Private"
|
||||
// expected-warning@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{expected canonical name for private module 'APrivate'}}
|
||||
// expected-note@Inputs/implicit-private-with-different-name/A.framework/Modules/module.private.modulemap:1{{rename 'APrivate' to ensure it can be found by name}}
|
||||
// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:18-1:26}:"A_Private"
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
36
clang/test/Modules/implicit-private-with-submodule.m
Normal file
36
clang/test/Modules/implicit-private-with-submodule.m
Normal file
@ -0,0 +1,36 @@
|
||||
// RUN: rm -rf %t
|
||||
// Build PCH using A, with private submodule A.Private
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-submodule -emit-pch -o %t-A.pch %s -DNO_AT_IMPORT
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// Build PCH using A, with private submodule A.Private, check the fixit
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-submodule -emit-pch -o %t-A.pch %s -fdiagnostics-parseable-fixits -DNO_AT_IMPORT 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-submodule -emit-pch -o %t-A.pch %s -DUSE_AT_IMPORT_PRIV
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-with-submodule -emit-pch -o %t-A.pch %s -DUSE_AT_IMPORT_BOTH
|
||||
|
||||
// expected-warning@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{private submodule 'A.Private' in private module map, expected top-level module}}
|
||||
// expected-note@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{rename 'A.Private' to ensure it can be found by name}}
|
||||
// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:20-1:27}:"A_Private"
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
#ifdef NO_AT_IMPORT
|
||||
#import "A/aprivate.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_AT_IMPORT_PRIV
|
||||
@import A.Private;
|
||||
#endif
|
||||
|
||||
#ifdef USE_AT_IMPORT_BOTH
|
||||
@import A;
|
||||
@import A.Private;
|
||||
#endif
|
||||
|
||||
const int *y = &APRIVATE;
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/ModuleMapLocations/Module_ModuleMap -I %S/Inputs/ModuleMapLocations/Both -F %S/Inputs/ModuleMapLocations -I %S/Inputs/ModuleMapLocations -F %S/Inputs -x objective-c -fsyntax-only %s -verify
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/ModuleMapLocations/Module_ModuleMap -I %S/Inputs/ModuleMapLocations/Both -F %S/Inputs/ModuleMapLocations -I %S/Inputs/ModuleMapLocations -F %S/Inputs -x objective-c -fsyntax-only %s -verify -Wno-private-module
|
||||
|
||||
// regular
|
||||
@import module_modulemap;
|
||||
|
@ -8,8 +8,8 @@
|
||||
// Clear out the module cache
|
||||
// RUN: rm -rf %t
|
||||
// Run Clang twice so we end up creating the timestamp file (the second time).
|
||||
// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t %s -verify
|
||||
// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t %s -verify
|
||||
// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -Wno-private-module -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t %s -verify
|
||||
// RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -Wno-private-module -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t %s -verify
|
||||
// RUN: ls %t | grep modules.timestamp
|
||||
// RUN: ls -R %t | grep ^Module.*pcm
|
||||
// RUN: ls -R %t | grep DependsOnModule.*pcm
|
||||
@ -17,7 +17,7 @@
|
||||
// Set the timestamp back more than two days. We should try to prune,
|
||||
// but nothing gets pruned because the module files are new enough.
|
||||
// RUN: touch -m -a -t 201101010000 %t/modules.timestamp
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -Wno-private-module -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: ls %t | grep modules.timestamp
|
||||
// RUN: ls -R %t | grep ^Module.*pcm
|
||||
// RUN: ls -R %t | grep DependsOnModule.*pcm
|
||||
@ -26,7 +26,7 @@
|
||||
// This shouldn't prune anything, because the timestamp has been updated, so
|
||||
// the pruning mechanism won't fire.
|
||||
// RUN: find %t -name DependsOnModule*.pcm | sed -e 's/\\/\//g' | xargs touch -a -t 201101010000
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -F %S/Inputs -Wno-private-module -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: ls %t | grep modules.timestamp
|
||||
// RUN: ls -R %t | grep ^Module.*pcm
|
||||
// RUN: ls -R %t | grep DependsOnModule.*pcm
|
||||
@ -35,7 +35,7 @@
|
||||
// This should trigger pruning, which will remove DependsOnModule but not Module.
|
||||
// RUN: touch -m -a -t 201101010000 %t/modules.timestamp
|
||||
// RUN: find %t -name DependsOnModule*.pcm | sed -e 's/\\/\//g' | xargs touch -a -t 201101010000
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -F %S/Inputs -Wno-private-module -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
|
||||
// RUN: ls %t | grep modules.timestamp
|
||||
// RUN: ls -R %t | grep ^Module.*pcm
|
||||
// RUN: ls -R %t | not grep DependsOnModule.*pcm
|
||||
|
@ -1,8 +1,8 @@
|
||||
// RUN: rm -rf %t.cache
|
||||
// RUN: %clang_cc1 -fsyntax-only %s -fmodules -fmodules-cache-path=%t.cache \
|
||||
// RUN: -fimplicit-module-maps -F%S/Inputs -verify
|
||||
// RUN: -fimplicit-module-maps -Wno-private-module -F%S/Inputs -verify
|
||||
// RUN: %clang_cc1 -fsyntax-only %s -fmodules -fmodules-cache-path=%t.cache \
|
||||
// RUN: -fimplicit-module-maps -F%S/Inputs -DCHANGE_TAGS -verify
|
||||
// RUN: -fimplicit-module-maps -Wno-private-module -F%S/Inputs -DCHANGE_TAGS -verify
|
||||
#include "F/F.h"
|
||||
|
||||
#ifndef CHANGE_TAGS
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify -fcoroutines-ts -DCOROUTINES
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -Wno-private-module -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -Wno-private-module -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify -fcoroutines-ts -DCOROUTINES
|
||||
|
||||
#ifdef COROUTINES
|
||||
@import DependsOnModule.Coroutines;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -fmodule-feature custom_req1
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -fmodule-feature custom_req1
|
||||
|
||||
// expected-error@DependsOnModule.framework/module.map:7 {{module 'DependsOnModule.CXX' requires feature 'cplusplus'}}
|
||||
@import DependsOnModule.CXX; // expected-note {{module imported here}}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs/DependsOnModule.framework %s -verify
|
||||
|
||||
@import DependsOnModule.CXX;
|
||||
// expected-error@module.map:11 {{module 'DependsOnModule.NotCXX' is incompatible with feature 'cplusplus'}}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
// RUN: %clang_cc1 -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
|
||||
@import DependsOnModule;
|
||||
@import SubFramework; // expected-error{{module 'SubFramework' not found}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
// RUN: %clang_cc1 -x objective-c++ -Wauto-import -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
// RUN: %clang_cc1 -x objective-c++ -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
|
||||
|
||||
@import DependsOnModule;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user