r307115 - [modules ts] Declarations from a module interface unit are only visible outside
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 4 18:42:07 PDT 2017
Author: rsmith
Date: Tue Jul 4 18:42:07 2017
New Revision: 307115
URL: http://llvm.org/viewvc/llvm-project?rev=307115&view=rev
Log:
[modules ts] Declarations from a module interface unit are only visible outside
the module if declared in an export block.
Added:
cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/
cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cpp
cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cppm
cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/other.cpp
Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
cfe/trunk/test/SemaCXX/modules-ts.cppm
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Tue Jul 4 18:42:07 2017
@@ -749,7 +749,7 @@ public:
/// Set that this declaration is globally visible, even if it came from a
/// module that is not visible.
void setVisibleDespiteOwningModule() {
- if (hasOwningModule())
+ if (getModuleOwnershipKind() == ModuleOwnershipKind::VisibleWhenImported)
setModuleOwnershipKind(ModuleOwnershipKind::Visible);
}
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jul 4 18:42:07 2017
@@ -1266,6 +1266,7 @@ public:
void emitAndClearUnusedLocalTypedefWarnings();
+ void ActOnStartOfTranslationUnit();
void ActOnEndOfTranslationUnit();
void CheckDelegatingCtorCycles();
@@ -1541,6 +1542,7 @@ public:
llvm::SmallVectorImpl<Module *> *Modules);
bool hasVisibleMergedDefinition(NamedDecl *Def);
+ bool hasMergedDefinitionInCurrentModule(NamedDecl *Def);
/// Determine if \p D and \p Suggested have a structurally compatible
/// layout as described in C11 6.2.7/1.
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Jul 4 18:42:07 2017
@@ -283,7 +283,7 @@ void Decl::setLexicalDeclContext(DeclCon
setLocalOwningModule(cast<Decl>(DC)->getOwningModule());
}
- assert((!hasOwningModule() || getOwningModule()) &&
+ assert((!hasOwningModule() || getOwningModule() || isModulePrivate()) &&
"hidden declaration has no owning module");
}
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Jul 4 18:42:07 2017
@@ -526,6 +526,8 @@ void Parser::LateTemplateParserCleanupCa
}
bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
+ Actions.ActOnStartOfTranslationUnit();
+
// C11 6.9p1 says translation units must have at least one top-level
// declaration. C++ doesn't have this restriction. We also don't want to
// complain if we have a precompiled header, although technically if the PCH
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Jul 4 18:42:07 2017
@@ -705,6 +705,18 @@ void Sema::emitAndClearUnusedLocalTypede
UnusedLocalTypedefNameCandidates.clear();
}
+/// This is called before the very first declaration in the translation unit
+/// is parsed. Note that the ASTContext may have already injected some
+/// declarations.
+void Sema::ActOnStartOfTranslationUnit() {
+ if (getLangOpts().ModulesTS) {
+ // We start in the global module; all those declarations are implicitly
+ // module-private (though they do not have module linkage).
+ Context.getTranslationUnitDecl()->setModuleOwnershipKind(
+ Decl::ModuleOwnershipKind::ModulePrivate);
+ }
+}
+
/// ActOnEndOfTranslationUnit - This is called at the very end of the
/// translation unit when EOF is reached and all but the top-level scope is
/// popped.
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jul 4 18:42:07 2017
@@ -16054,8 +16054,6 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
return nullptr;
}
- // FIXME: Create a ModuleDecl and return it.
-
// FIXME: Most of this work should be done by the preprocessor rather than
// here, in order to support macro import.
@@ -16069,6 +16067,8 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
ModuleName += Piece.first->getName();
}
+ // FIXME: If we've already seen a module-declaration, report an error.
+
// If a module name was explicitly specified on the command line, it must be
// correct.
if (!getLangOpts().CurrentModule.empty() &&
@@ -16081,6 +16081,7 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+ Module *Mod;
switch (MDK) {
case ModuleDeclKind::Module: {
@@ -16099,12 +16100,9 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
}
// Create a Module for the module that we're defining.
- Module *Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
+ Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
assert(Mod && "module creation should not fail");
-
- // Enter the semantic scope of the module.
- ActOnModuleBegin(ModuleLoc, Mod);
- return nullptr;
+ break;
}
case ModuleDeclKind::Partition:
@@ -16114,14 +16112,26 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDe
case ModuleDeclKind::Implementation:
std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
PP.getIdentifierInfo(ModuleName), Path[0].second);
-
- DeclResult Import = ActOnModuleImport(ModuleLoc, ModuleLoc, ModuleNameLoc);
- if (Import.isInvalid())
+ Mod = getModuleLoader().loadModule(ModuleLoc, Path, Module::AllVisible,
+ /*IsIncludeDirective=*/false);
+ if (!Mod)
return nullptr;
- return ConvertDeclToDeclGroup(Import.get());
+ break;
}
- llvm_unreachable("unexpected module decl kind");
+ // Enter the semantic scope of the module.
+ ModuleScopes.push_back({});
+ ModuleScopes.back().Module = Mod;
+ ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
+ VisibleModules.setVisible(Mod, ModuleLoc);
+
+ // From now on, we have an owning module for all declarations we see.
+ // However, those declarations are module-private unless explicitly
+ // exported.
+ Context.getTranslationUnitDecl()->setLocalOwningModule(Mod);
+
+ // FIXME: Create a ModuleDecl.
+ return nullptr;
}
DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
@@ -16310,6 +16320,7 @@ Decl *Sema::ActOnStartExportDecl(Scope *
CurContext->addDecl(D);
PushDeclContext(S, D);
+ D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
return D;
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Jul 4 18:42:07 2017
@@ -1395,6 +1395,13 @@ bool Sema::hasVisibleMergedDefinition(Na
return false;
}
+bool Sema::hasMergedDefinitionInCurrentModule(NamedDecl *Def) {
+ for (Module *Merged : Context.getModulesWithMergedDefinition(Def))
+ if (Merged->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ return true;
+ return false;
+}
+
template<typename ParmDecl>
static bool
hasVisibleDefaultArgument(Sema &S, const ParmDecl *D,
@@ -1495,16 +1502,25 @@ bool LookupResult::isVisibleSlow(Sema &S
assert(D->isHidden() && "should not call this: not in slow case");
Module *DeclModule = SemaRef.getOwningModule(D);
- assert(DeclModule && "hidden decl not from a module");
+ if (!DeclModule) {
+ // A module-private declaration with no owning module means this is in the
+ // global module in the C++ Modules TS. This is visible within the same
+ // translation unit only.
+ // FIXME: Don't assume that "same translation unit" means the same thing
+ // as "not from an AST file".
+ assert(D->isModulePrivate() && "hidden decl has no module");
+ return !D->isFromASTFile();
+ }
// If the owning module is visible, and the decl is not module private,
// then the decl is visible too. (Module private is ignored within the same
// top-level module.)
- // FIXME: Check the owning module for module-private declarations rather than
- // assuming "same AST file" is the same thing as "same module".
- if ((!D->isFromASTFile() || !D->isModulePrivate()) &&
- (SemaRef.isModuleVisible(DeclModule) ||
- SemaRef.hasVisibleMergedDefinition(D)))
+ if (D->isModulePrivate()
+ ? DeclModule->getTopLevelModuleName() ==
+ SemaRef.getLangOpts().CurrentModule ||
+ SemaRef.hasMergedDefinitionInCurrentModule(D)
+ : SemaRef.isModuleVisible(DeclModule) ||
+ SemaRef.hasVisibleMergedDefinition(D))
return true;
// If this declaration is not at namespace scope nor module-private,
Added: cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cpp?rev=307115&view=auto
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cpp (added)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cpp Tue Jul 4 18:42:07 2017
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts %S/module.cppm -emit-module-interface -o %t
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -fmodule-file=%t %s -verify
+// expected-no-diagnostics
+module M;
+
+// FIXME: Use of internal linkage entities should be rejected.
+void use_from_module_impl() {
+ external_linkage_fn();
+ module_linkage_fn();
+ internal_linkage_fn();
+ (void)external_linkage_class{};
+ (void)module_linkage_class{};
+ (void)internal_linkage_class{};
+ (void)external_linkage_var;
+ (void)module_linkage_var;
+ (void)internal_linkage_var;
+}
Added: cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cppm?rev=307115&view=auto
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cppm (added)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/module.cppm Tue Jul 4 18:42:07 2017
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts %s -verify
+// expected-no-diagnostics
+export module M;
+
+export int external_linkage_var;
+int module_linkage_var;
+static int internal_linkage_var;
+
+export void external_linkage_fn() {}
+void module_linkage_fn() {}
+static void internal_linkage_fn() {}
+
+export struct external_linkage_class {};
+struct module_linkage_class {};
+namespace {
+ struct internal_linkage_class {};
+}
+
+void use() {
+ external_linkage_fn();
+ module_linkage_fn();
+ internal_linkage_fn();
+ (void)external_linkage_class{};
+ (void)module_linkage_class{};
+ (void)internal_linkage_class{};
+ (void)external_linkage_var;
+ (void)module_linkage_var;
+ (void)internal_linkage_var;
+}
Added: cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/other.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/other.cpp?rev=307115&view=auto
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/other.cpp (added)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.link/p2/other.cpp Tue Jul 4 18:42:07 2017
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts %S/module.cppm -emit-module-interface -o %t
+// RUN: %clang_cc1 -std=c++1z -fmodules-ts -fmodule-file=%t %s -verify
+import M;
+
+void use_from_module_impl() {
+ external_linkage_fn();
+ module_linkage_fn(); // expected-error {{undeclared identifier}}
+ internal_linkage_fn(); // expected-error {{undeclared identifier}}
+ (void)external_linkage_class{};
+ (void)module_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}}
+ (void)internal_linkage_class{}; // expected-error {{undeclared identifier}} expected-error 0+{{}}
+ // expected-note at module.cppm:9 {{here}}
+ (void)external_linkage_var;
+ (void)module_linkage_var; // expected-error {{undeclared identifier}}
+ (void)internal_linkage_var; // expected-error {{undeclared identifier}}
+}
Modified: cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp (original)
+++ cfe/trunk/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.import/p1.cpp Tue Jul 4 18:42:07 2017
@@ -1,7 +1,7 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
-// RUN: echo 'export module x; int a, b;' > %t/x.cppm
-// RUN: echo 'export module x.y; int c;' > %t/x.y.cppm
+// RUN: echo 'export module x; export int a, b;' > %t/x.cppm
+// RUN: echo 'export module x.y; export int c;' > %t/x.y.cppm
//
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface %t/x.cppm -o %t/x.pcm
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -emit-module-interface -fmodule-file=%t/x.pcm %t/x.y.cppm -o %t/x.y.pcm
Modified: cfe/trunk/test/SemaCXX/modules-ts.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/modules-ts.cppm?rev=307115&r1=307114&r2=307115&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/modules-ts.cppm (original)
+++ cfe/trunk/test/SemaCXX/modules-ts.cppm Tue Jul 4 18:42:07 2017
@@ -13,7 +13,13 @@ export module foo;
// expected-note at modules-ts.cppm:* {{loaded from}}
#endif
-static int m; // ok, internal linkage, so no redefinition error
+static int m;
+#if TEST == 2 // FIXME: 'm' has internal linkage, so there should be no error here
+// expected-error at -2 {{redefinition of '}}
+// expected-note at -3 {{unguarded header; consider using #ifdef guards or #pragma once}}
+// FIXME: We should drop the "header from" in this diagnostic.
+// expected-note-re at modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site in header from module 'foo'}}
+#endif
int n;
#if TEST >= 2
// expected-error at -2 {{redefinition of '}}
More information about the cfe-commits
mailing list