aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorMichael Spencer <bigcheesegs@gmail.com>2024-03-05 10:15:21 -0800
committerGitHub <noreply@github.com>2024-03-05 10:15:21 -0800
commitee044d5e651787c5d73b37b2cbb7ca6444bb0502 (patch)
treeeeab8a836a4e6adb7ae8279724d1d7bcf203afad /clang/lib/Frontend/CompilerInstance.cpp
parentcaad3794f081321e7c9f370ebe69f297fc13097e (diff)
downloadllvm-ee044d5e651787c5d73b37b2cbb7ca6444bb0502.zip
llvm-ee044d5e651787c5d73b37b2cbb7ca6444bb0502.tar.gz
llvm-ee044d5e651787c5d73b37b2cbb7ca6444bb0502.tar.bz2
[clang] Diagnose config_macros before building modules (#83641)
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
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 444ffff..ec4e682 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1591,6 +1591,14 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
}
}
+static void checkConfigMacros(Preprocessor &PP, Module *M,
+ SourceLocation ImportLoc) {
+ clang::Module *TopModule = M->getTopLevelModule();
+ for (const StringRef ConMacro : TopModule->ConfigMacros) {
+ checkConfigMacro(PP, ConMacro, M, ImportLoc);
+ }
+}
+
/// Write a new timestamp file with the given path.
static void writeTimestampFile(StringRef TimestampFile) {
std::error_code EC;
@@ -1829,6 +1837,13 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
Module *M =
HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);
+ // Check for any configuration macros that have changed. This is done
+ // immediately before potentially building a module in case this module
+ // depends on having one of its configuration macros defined to successfully
+ // build. If this is not done the user will never see the warning.
+ if (M)
+ checkConfigMacros(getPreprocessor(), M, ImportLoc);
+
// Select the source and filename for loading the named module.
std::string ModuleFilename;
ModuleSource Source =
@@ -2006,12 +2021,23 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
// Use the cached result, which may be nullptr.
Module = *MaybeModule;
+ // Config macros are already checked before building a module, but they need
+ // to be checked at each import location in case any of the config macros
+ // have a new value at the current `ImportLoc`.
+ if (Module)
+ checkConfigMacros(getPreprocessor(), Module, ImportLoc);
} else if (ModuleName == getLangOpts().CurrentModule) {
// This is the module we're building.
Module = PP->getHeaderSearchInfo().lookupModule(
ModuleName, ImportLoc, /*AllowSearch*/ true,
/*AllowExtraModuleMapSearch*/ !IsInclusionDirective);
+ // Config macros do not need to be checked here for two reasons.
+ // * This will always be textual inclusion, and thus the config macros
+ // actually do impact the content of the header.
+ // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this
+ // function as the `#include` or `#import` is textual.
+
MM.cacheModuleLoad(*Path[0].first, Module);
} else {
ModuleLoadResult Result = findOrCompileModuleAndReadAST(
@@ -2146,18 +2172,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc);
}
- // Check for any configuration macros that have changed.
- clang::Module *TopModule = Module->getTopLevelModule();
- for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) {
- checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I],
- Module, ImportLoc);
- }
-
// Resolve any remaining module using export_as for this one.
getPreprocessor()
.getHeaderSearchInfo()
.getModuleMap()
- .resolveLinkAsDependencies(TopModule);
+ .resolveLinkAsDependencies(Module->getTopLevelModule());
LastModuleImportLoc = ImportLoc;
LastModuleImportResult = ModuleLoadResult(Module);