Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[Implicit Modules] Add -cc1 option -fmodules-strict-context-hash whic…
Browse files Browse the repository at this point in the history
…h includes search paths and diagnostics.

Differential Revision: https://reviews.llvm.org/D68528

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375322 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Bigcheese committed Oct 19, 2019
1 parent a27ae54 commit 56ddb2a
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 1 deletion.
10 changes: 10 additions & 0 deletions docs/Modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,16 @@ Command-line parameters
``-fprebuilt-module-path=<directory>``
Specify the path to the prebuilt modules. If specified, we will look for modules in this directory for a given top-level module name. We don't need a module map for loading prebuilt modules in this directory and the compiler will not try to rebuild these modules. This can be specified multiple times.

-cc1 Options
^^^^^^^^^^^^

``-fmodules-strict-context-hash``
Enables hashing of all compiler options that could impact the semantics of a
module in an implicit build. This includes things such as header search paths
and diagnostics. Using this option may lead to an excessive number of modules
being built if the command line arguments are not homogeneous across your
build.

Module Semantics
================

Expand Down
3 changes: 3 additions & 0 deletions include/clang/Driver/CC1Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,9 @@ def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
HelpText<"Disable the module hash">;
def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
HelpText<"Enable hashing the content of a module file">;
def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">,
HelpText<"Enable hashing of all compiler options that could impact the "
"semantics of a module in an implicit build">;
def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
HelpText<"Add directory to the C SYSTEM include search path">;
def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
Expand Down
20 changes: 19 additions & 1 deletion include/clang/Lex/HeaderSearchOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
#include <cstdint>
Expand Down Expand Up @@ -206,6 +207,13 @@ class HeaderSearchOptions {

unsigned ModulesHashContent : 1;

/// Whether we should include all things that could impact the module in the
/// hash.
///
/// This includes things like the full header search path, and enabled
/// diagnostics.
unsigned ModulesStrictContextHash : 1;

HeaderSearchOptions(StringRef _Sysroot = "/")
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
Expand All @@ -214,7 +222,8 @@ class HeaderSearchOptions {
ModulesValidateOncePerBuildSession(false),
ModulesValidateSystemHeaders(false),
ValidateASTInputFilesContent(false), UseDebugInfo(false),
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
ModulesStrictContextHash(false) {}

/// AddPath - Add the \p Path path to the specified \p Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
Expand All @@ -238,6 +247,15 @@ class HeaderSearchOptions {
}
};

inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
}

inline llvm::hash_code
hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader);
}

} // namespace clang

#endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
20 changes: 20 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2067,6 +2067,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
Opts.AddPrebuiltModulePath(A->getValue());
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash);
Opts.ModulesValidateDiagnosticOptions =
!Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
Expand Down Expand Up @@ -3546,6 +3547,7 @@ std::string CompilerInvocation::getModuleHash() const {
using llvm::hash_code;
using llvm::hash_value;
using llvm::hash_combine;
using llvm::hash_combine_range;

// Start the signature with the compiler version.
// FIXME: We'd rather use something more cryptographically sound than
Expand Down Expand Up @@ -3600,6 +3602,24 @@ std::string CompilerInvocation::getModuleHash() const {
hsOpts.ModulesValidateDiagnosticOptions);
code = hash_combine(code, hsOpts.ResourceDir);

if (hsOpts.ModulesStrictContextHash) {
hash_code SHPC = hash_combine_range(hsOpts.SystemHeaderPrefixes.begin(),
hsOpts.SystemHeaderPrefixes.end());
hash_code UEC = hash_combine_range(hsOpts.UserEntries.begin(),
hsOpts.UserEntries.end());
code = hash_combine(code, hsOpts.SystemHeaderPrefixes.size(), SHPC,
hsOpts.UserEntries.size(), UEC);

const DiagnosticOptions &diagOpts = getDiagnosticOpts();
#define DIAGOPT(Name, Bits, Default) \
code = hash_combine(code, diagOpts.Name);
#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
code = hash_combine(code, diagOpts.get##Name());
#include "clang/Basic/DiagnosticOptions.def"
#undef DIAGOPT
#undef ENUM_DIAGOPT
}

// Extend the signature with the user build path.
code = hash_combine(code, hsOpts.ModuleUserBuildPath);

Expand Down
33 changes: 33 additions & 0 deletions test/Modules/context-hash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -internal-isystem \
// RUN: %S/Inputs/System/usr/include -fmodules -fimplicit-module-maps \
// RUN: -fmodules-cache-path=%t %s -Rmodule-build 2> %t1
// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -internal-isystem \
// RUN: %S/Inputs/System/usr/include -internal-isystem %S -fmodules \
// RUN: -fimplicit-module-maps -fmodules-cache-path=%t %s -Rmodule-build 2> \
// RUN: %t2
// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -internal-isystem \
// RUN: %S/Inputs/System/usr/include -internal-isystem %S -fmodules \
// RUN: -fimplicit-module-maps -fmodules-cache-path=%t %s \
// RUN: -fmodules-strict-context-hash -Rmodule-build 2> %t3
// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -Weverything -internal-isystem \
// RUN: %S/Inputs/System/usr/include -fmodules -fmodules-strict-context-hash \
// RUN: -fimplicit-module-maps -fmodules-cache-path=%t %s -Rmodule-build 2> \
// RUN: %t4
// RUN: echo %t | cat - %t1 %t2 %t3 %t4 | FileCheck %s

// This test verifies that only strict hashing includes search paths and
// diagnostics in the module context hash.

#include <stdio.h>

// CHECK: [[PREFIX:(.*[/\\])+[a-zA-Z0-9.-]+]]
// CHECK: building module 'cstd' as '[[PREFIX]]{{[/\\]}}[[CONTEXT_HASH:[A-Z0-9]+]]{{[/\\]}}cstd-[[AST_HASH:[A-Z0-9]+]].pcm'
// CHECK: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}}cstd-[[AST_HASH]].pcm'
// CHECK-NOT: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}}
// CHECK: cstd-[[AST_HASH]].pcm'
// CHECK-NOT: building module 'cstd' as '{{.*[/\\]}}[[CONTEXT_HASH]]{{[/\\]}}
// CHECK: cstd-[[AST_HASH]].pcm'

0 comments on commit 56ddb2a

Please sign in to comment.