[Modules TS] Avoid computing the linkage of the enclosing DeclContext for a declaration in the global module.

This works around a language issue where adding a typedef name for linkage
purposes changes the linkage of an already-defined class after it becomes
complete.

llvm-svn: 315256
This commit is contained in:
Richard Smith 2017-10-10 00:49:38 +00:00
parent e6a0242ebc
commit a0b68be6cf
4 changed files with 24 additions and 4 deletions

View File

@ -740,7 +740,10 @@ public:
/// Get the module that owns this declaration for linkage purposes.
/// There only ever is such a module under the C++ Modules TS.
Module *getOwningModuleForLinkage() const;
///
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
/// all declarations in a global module fragment are unowned.
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
/// \brief Determine whether this declaration might be hidden from name
/// lookup. Note that the declaration might be visible even if this returns

View File

@ -3051,8 +3051,11 @@ public:
RedeclarationKind forRedeclarationInCurContext() {
// A declaration with an owning module for linkage can never link against
// anything that is not visible.
if (cast<Decl>(CurContext)->getOwningModuleForLinkage())
// anything that is not visible. We don't need to check linkage here; if
// the context has internal linkage, redeclaration lookup won't find things
// from other TUs, and we can't safely compute linkage yet in general.
if (cast<Decl>(CurContext)
->getOwningModuleForLinkage(/*IgnoreLinkage*/true))
return ForVisibleRedeclaration;
return ForExternalRedeclaration;
}

View File

@ -1395,7 +1395,7 @@ LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
: NamedDecl::VisibilityForValue));
}
Module *Decl::getOwningModuleForLinkage() const {
Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
Module *M = getOwningModule();
if (!M)
return nullptr;
@ -1413,6 +1413,8 @@ Module *Decl::getOwningModuleForLinkage() const {
// for linkage purposes. But internal linkage declarations in the global
// module fragment of a particular module are owned by that module for
// linkage purposes.
if (IgnoreLinkage)
return nullptr;
bool InternalLinkage;
if (auto *ND = dyn_cast<NamedDecl>(this))
InternalLinkage = !ND->hasExternalFormalLinkage();

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s
typedef struct {
int c;
union {
int n;
char c[4];
} v;
} mbstate;
export module M;
export using ::mbstate;