Skip to content

Commit c2445d4

Browse files
committed
[clang] Diagnose config_macros before building modules
Before this patch, if a module fails to build because of a missing config_macro, the user will never see the config macro warning. This patch diagnoses this before building, and each subsequent time a module is imported. rdar://123921931
1 parent 463fb9f commit c2445d4

File tree

4 files changed

+63
-23
lines changed

4 files changed

+63
-23
lines changed

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,6 +1591,14 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
15911591
}
15921592
}
15931593

1594+
static void checkConfigMacros(Preprocessor &PP, Module *M,
1595+
SourceLocation ImportLoc) {
1596+
clang::Module *TopModule = M->getTopLevelModule();
1597+
for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
1598+
checkConfigMacro(PP, TopModule->ConfigMacros[I], M, ImportLoc);
1599+
}
1600+
}
1601+
15941602
/// Write a new timestamp file with the given path.
15951603
static void writeTimestampFile(StringRef TimestampFile) {
15961604
std::error_code EC;
@@ -1829,6 +1837,13 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
18291837
Module *M =
18301838
HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
18311839

1840+
// Check for any configuration macros that have changed. This is done
1841+
// immediately before potentially building a module in case this module
1842+
// depends on having one of its configuration macros defined to successfully
1843+
// build. If this is not done the user will never see the warning.
1844+
if (M)
1845+
checkConfigMacros(getPreprocessor(), M, ImportLoc);
1846+
18321847
// Select the source and filename for loading the named module.
18331848
std::string ModuleFilename;
18341849
ModuleSource Source =
@@ -2006,6 +2021,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
20062021
if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
20072022
// Use the cached result, which may be nullptr.
20082023
Module = *MaybeModule;
2024+
// Config macros are already checked before building a module, but they need
2025+
// to be checked at each import location in case any of the config macros
2026+
// have a new value at the current `ImportLoc`.
2027+
if (Module)
2028+
checkConfigMacros(getPreprocessor(), Module, ImportLoc);
20092029
} else if (ModuleName == getLangOpts().CurrentModule) {
20102030
// This is the module we're building.
20112031
Module = PP->getHeaderSearchInfo().lookupModule(
@@ -2146,18 +2166,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
21462166
TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc);
21472167
}
21482168

2149-
// Check for any configuration macros that have changed.
2150-
clang::Module *TopModule = Module->getTopLevelModule();
2151-
for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
2152-
checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
2153-
Module, ImportLoc);
2154-
}
2155-
21562169
// Resolve any remaining module using export_as for this one.
21572170
getPreprocessor()
21582171
.getHeaderSearchInfo()
21592172
.getModuleMap()
2160-
.resolveLinkAsDependencies(TopModule);
2173+
.resolveLinkAsDependencies(Module->getTopLevelModule());
21612174

21622175
LastModuleImportLoc = ImportLoc;
21632176
LastModuleImportResult = ModuleLoadResult(Module);

clang/test/Modules/Inputs/config.h

Lines changed: 0 additions & 7 deletions
This file was deleted.

clang/test/Modules/Inputs/module.modulemap

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,6 @@ module cxx_decls_merged {
260260
header "cxx-decls-merged.h"
261261
}
262262

263-
module config {
264-
header "config.h"
265-
config_macros [exhaustive] WANT_FOO, WANT_BAR
266-
}
267-
268263
module diag_flags {
269264
header "diag_flags.h"
270265
}

clang/test/Modules/config_macros.m

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %t/module.modulemap
4+
// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %t -DWANT_FOO=1 %t/config.m -verify
5+
// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %t -DTEST_ERROR %t/config_error.m -verify
6+
7+
//--- module.modulemap
8+
9+
module config {
10+
header "config.h"
11+
config_macros [exhaustive] WANT_FOO, WANT_BAR
12+
}
13+
14+
module config_error {
15+
header "config_error.h"
16+
config_macros SOME_VALUE
17+
}
18+
19+
//--- config.h
20+
21+
#ifdef WANT_FOO
22+
int* foo(void);
23+
#endif
24+
25+
#ifdef WANT_BAR
26+
char *bar(void);
27+
#endif
28+
29+
//--- config_error.h
30+
31+
struct my_thing {
32+
char buf[SOME_VALUE];
33+
};
34+
35+
//--- config.m
36+
137
@import config;
238

339
int *test_foo(void) {
@@ -22,7 +58,10 @@
2258
#define WANT_BAR 1 // expected-note{{macro was defined here}}
2359
@import config; // expected-warning{{definition of configuration macro 'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on the command line to configure the module}}
2460

25-
// RUN: rm -rf %t
26-
// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.modulemap
27-
// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
61+
//--- config_error.m
2862

63+
#ifdef TEST_ERROR
64+
#define SOME_VALUE 5 // expected-note{{macro was defined here}}
65+
@import config_error; // expected-error{{could not build module}} \
66+
// expected-warning{{definition of configuration macro 'SOME_VALUE' has no effect on the import of 'config_error';}}
67+
#endif

0 commit comments

Comments
 (0)