aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorJan Svoboda <jan_svoboda@apple.com>2023-01-19 17:02:42 -0800
committerJan Svoboda <jan_svoboda@apple.com>2023-01-20 13:37:36 -0800
commitc3efd52770ca964ba46287298c1d2f7697fd446c (patch)
treeba336fee3953bfb00a7c8bbacb6764b85a415770 /clang/lib
parent743fbcb79d9af759377df5f5929ffdd38ff52b09 (diff)
downloadllvm-c3efd52770ca964ba46287298c1d2f7697fd446c.zip
llvm-c3efd52770ca964ba46287298c1d2f7697fd446c.tar.gz
llvm-c3efd52770ca964ba46287298c1d2f7697fd446c.tar.bz2
[clang][modules] Disallow importing private framework in the implementation
Whenever we are compiling implementation of a framework (with the `-fmodule-name=FW` option), we never translate `#import <FW/Header.h>` to an import, regardless of whether "Header.h" belongs to "FW" or "FW_Private". For the same reasons, we also disallow `@import FW`. However, we still allow `@import FW_Private`. This patch disallows that a well, to be consistent with the rest of the rules. Reviewed By: benlangmuir Differential Revision: https://reviews.llvm.org/D142167
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Module.cpp20
-rw-r--r--clang/lib/Lex/PPDirectives.cpp32
-rw-r--r--clang/lib/Sema/SemaModule.cpp2
3 files changed, 26 insertions, 28 deletions
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index aa82a99..9c4c834 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -148,6 +148,26 @@ bool Module::isUnimportable(const LangOptions &LangOpts,
llvm_unreachable("could not find a reason why module is unimportable");
}
+// The -fmodule-name option tells the compiler to textually include headers in
+// the specified module, meaning Clang won't build the specified module. This
+// is useful in a number of situations, for instance, when building a library
+// that vends a module map, one might want to avoid hitting intermediate build
+// products containing the module map or avoid finding the system installed
+// modulemap for that library.
+bool Module::isForBuilding(const LangOptions &LangOpts) const {
+ StringRef TopLevelName = getTopLevelModuleName();
+ StringRef CurrentModule = LangOpts.CurrentModule;
+
+ // When building framework Foo, we want to make sure that Foo *and*
+ // Foo_Private are textually included and no modules are built for both.
+ if (getTopLevelModule()->IsFramework &&
+ CurrentModule == LangOpts.ModuleName &&
+ !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
+ TopLevelName = TopLevelName.drop_back(8);
+
+ return TopLevelName == CurrentModule;
+}
+
bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Requirement &Req,
UnresolvedHeaderDirective &MissingHeader,
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 41b38b6..f08d5fe 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -109,25 +109,6 @@ enum PPElifDiag {
PED_Elifndef
};
-// The -fmodule-name option tells the compiler to textually include headers in
-// the specified module, meaning clang won't build the specified module. This is
-// useful in a number of situations, for instance, when building a library that
-// vends a module map, one might want to avoid hitting intermediate build
-// products containimg the module map or avoid finding the system installed
-// modulemap for that library.
-static bool isForModuleBuilding(Module *M, StringRef CurrentModule,
- StringRef ModuleName) {
- StringRef TopLevelName = M->getTopLevelModuleName();
-
- // When building framework Foo, we wanna make sure that Foo *and* Foo_Private
- // are textually included and no modules are built for both.
- if (M->getTopLevelModule()->IsFramework && CurrentModule == ModuleName &&
- !CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
- TopLevelName = TopLevelName.drop_back(8);
-
- return TopLevelName == CurrentModule;
-}
-
static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II) {
const LangOptions &Lang = PP.getLangOpts();
if (isReservedInAllContexts(II->isReserved(Lang))) {
@@ -2219,14 +2200,13 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
alreadyIncluded(*File))
Action = IncludeLimitReached;
- bool MaybeTranslateInclude = Action == Enter && File && SuggestedModule &&
- !isForModuleBuilding(SuggestedModule.getModule(),
- getLangOpts().CurrentModule,
- getLangOpts().ModuleName);
-
// FIXME: We do not have a good way to disambiguate C++ clang modules from
// C++ standard modules (other than use/non-use of Header Units).
Module *SM = SuggestedModule.getModule();
+
+ bool MaybeTranslateInclude =
+ Action == Enter && File && SM && !SM->isForBuilding(getLangOpts());
+
// Maybe a usable Header Unit
bool UsableHeaderUnit = false;
if (getLangOpts().CPlusPlusModules && SM && SM->isHeaderUnit()) {
@@ -2556,9 +2536,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
// that behaves the same as the header would behave in a compilation using
// that PCH, which means we should enter the submodule. We need to teach
// the AST serialization layer to deal with the resulting AST.
- if (getLangOpts().CompilingPCH &&
- isForModuleBuilding(SM, getLangOpts().CurrentModule,
- getLangOpts().ModuleName))
+ if (getLangOpts().CompilingPCH && SM->isForBuilding(getLangOpts()))
return {ImportAction::None};
assert(!CurLexerSubmodule && "should not have marked this as a module yet");
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 8fa31ea..823a4e9 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -541,7 +541,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
// of the same top-level module. Until we do, make it an error rather than
// silently ignoring the import.
// FIXME: Should we warn on a redundant import of the current module?
- if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
+ if (Mod->isForBuilding(getLangOpts()) &&
(getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
Diag(ImportLoc, getLangOpts().isCompilingModule()
? diag::err_module_self_import