Forgot to svn add the test file.
Hi doug.gregor,
http://llvm-reviews.chandlerc.com/D963
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D963?vs=2516&id=2546#toc
Files:
docs/Modules.rst
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Sema/SemaCodeComplete.cpp
lib/Lex/Preprocessor.cpp
lib/Lex/PPDirectives.cpp
test/Modules/maps-only.cpp
include/clang/Lex/HeaderSearchOptions.h
include/clang/Driver/Options.td
Index: docs/Modules.rst
===================================================================
--- docs/Modules.rst
+++ docs/Modules.rst
@@ -149,6 +149,8 @@
To actually see any benefits from modules, one first has to introduce module maps for the underlying C standard library and the libraries and headers on which it depends. The section `Modularizing a Platform`_ describes the steps one must take to write these module maps.
+One can use module maps without modules to check the integrity of the use of header files. To do this, use the ``-fmodule-maps`` option instead of the ``-fmodules`` option.
+
Compilation model
-----------------
The binary representation of modules is automatically generated by the compiler on an as-needed basis. When a module is imported (e.g., by an ``#include`` of one of the module's headers), the compiler will spawn a second instance of itself [#]_, with a fresh preprocessing context [#]_, to parse just the headers in that module. The resulting Abstract Syntax Tree (AST) is then persisted into the binary representation of the module that is then loaded into translation unit where the module import was encountered.
@@ -165,6 +167,9 @@
``-fcxx-modules``
Enable the modules feature for C++ (EXPERIMENTAL and VERY BROKEN).
+``-fmodule-maps``
+ Enable interpretation of module maps (EXPERIMENTAL). This option is implied by ``-fmodules``.
+
``-fmodules-cache-path=<directory>``
Specify the path to the modules cache. If not provided, Clang will select a system-appropriate default.
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3012,6 +3012,13 @@
}
}
+ // -fmodule-maps enables module map processing (off by default) for header
+ // checking. It is implied by -fmodules.
+ if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps,
+ false)) {
+ CmdArgs.push_back("-fmodule-maps");
+ }
+
// If a module path was provided, pass it along. Otherwise, use a temporary
// directory.
if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -868,6 +868,8 @@
Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path);
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
+ // -fmodules implies -fmodule-maps
+ Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules);
Opts.ModuleCachePruneInterval =
getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60);
Opts.ModuleCachePruneAfter =
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -3188,7 +3188,7 @@
? CXAvailability_Available
: CXAvailability_NotAvailable));
}
- } else {
+ } else if (getLangOpts().Modules) {
// Load the named module.
Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
Module::AllVisible,
Index: lib/Lex/Preprocessor.cpp
===================================================================
--- lib/Lex/Preprocessor.cpp
+++ lib/Lex/Preprocessor.cpp
@@ -734,7 +734,7 @@
}
// If we have a non-empty module path, load the named module.
- if (!ModuleImportPath.empty()) {
+ if (!ModuleImportPath.empty() && getLangOpts().Modules) {
Module *Imported = TheModuleLoader.loadModule(ModuleImportLoc,
ModuleImportPath,
Module::MacrosVisible,
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/LiteralSupport.h"
@@ -1421,7 +1422,7 @@
const FileEntry *File = LookupFile(
FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL,
- getLangOpts().Modules? &SuggestedModule : 0);
+ HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : 0);
if (Callbacks) {
if (!File) {
@@ -1435,13 +1436,14 @@
// Try the lookup again, skipping the cache.
File = LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
- 0, 0, getLangOpts().Modules? &SuggestedModule : 0,
+ 0, 0, HeaderInfo.getHeaderSearchOpts().ModuleMaps ?
+ &SuggestedModule : 0,
/*SkipCache*/true);
}
}
}
- if (!SuggestedModule) {
+ if (!SuggestedModule || !getLangOpts().Modules) {
// Notify the callback object that we've seen an inclusion directive.
Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
FilenameRange, File,
@@ -1459,7 +1461,8 @@
File = LookupFile(FilenameLoc, Filename, false, LookupFrom, CurDir,
Callbacks ? &SearchPath : 0,
Callbacks ? &RelativePath : 0,
- getLangOpts().Modules ? &SuggestedModule : 0);
+ HeaderInfo.getHeaderSearchOpts().ModuleMaps ?
+ &SuggestedModule : 0);
if (File) {
SourceRange Range(FilenameTok.getLocation(), CharEnd);
Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
@@ -1477,7 +1480,7 @@
// If we are supposed to import a module rather than including the header,
// do so now.
- if (SuggestedModule) {
+ if (SuggestedModule && getLangOpts().Modules) {
// Compute the module access path corresponding to this module.
// FIXME: Should we have a second loadModule() overload to avoid this
// extra lookup step?
Index: test/Modules/maps-only.cpp
===================================================================
--- test/Modules/maps-only.cpp
+++ test/Modules/maps-only.cpp
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t/NOLOAD
+// RUN: mkdir -p %t/NOLOAD
+// RUN: chmod -rwx %t/NOLOAD
+// RUN: %clang_cc1 -fmodules-cache-path=%t/NOLOAD -fmodule-maps -I %S/Inputs/private0 -I %S/Inputs/private1 -I %S/Inputs/private2 %s -verify
+
+#include "common.h"
+#include "public1.h"
+#include "private1.h" // expected-error {{use of private header from outside its module}}
+#include "public2.h"
+#include "private2.h" // expected-error {{use of private header from outside its module}}
+
+struct use_this1 client_variable1;
+struct use_this2 client_variable2;
+struct mitts_off1 client_variable3;
+struct mitts_off2 client_variable4;
Index: include/clang/Lex/HeaderSearchOptions.h
===================================================================
--- include/clang/Lex/HeaderSearchOptions.h
+++ include/clang/Lex/HeaderSearchOptions.h
@@ -95,6 +95,9 @@
/// Note: Only used for testing!
unsigned DisableModuleHash : 1;
+ /// \brief Interpret module maps. This option is implied by full modules.
+ unsigned ModuleMaps : 1;
+
/// \brief The interval (in seconds) between pruning operations.
///
/// This operation is expensive, because it requires Clang to walk through
@@ -134,7 +137,7 @@
public:
HeaderSearchOptions(StringRef _Sysroot = "/")
- : Sysroot(_Sysroot), DisableModuleHash(0),
+ : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0),
ModuleCachePruneInterval(7*24*60*60),
ModuleCachePruneAfter(31*24*60*60),
UseBuiltinIncludes(true),
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -545,6 +545,9 @@
HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">;
def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>,
HelpText<"Enable the 'modules' language feature">;
+def fmodule_maps : Flag <["-"], "fmodule-maps">, Group<f_Group>,
+ Flags<[NoForward,CC1Option]>,
+ HelpText<"Read module maps to understand the structure of library headers">;
def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
@@ -601,6 +604,8 @@
def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
Flags<[CC1Option]>, HelpText<"Disallow merging of constants">;
def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>, Flags<[NoForward]>;
+def fno_module_maps : Flag <["-"], "fno-module-maps">, Group<f_Group>,
+ Flags<[NoForward]>;
def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>;
def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>;
def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits