Make inline namespace not be transparent after all. The concept simply doesn't fit. Instead, special-case the few places where transparent contexts have the desired behavior for inline namespaces. Fixes a redeclaration issue in inline namespaces.
llvm-svn: 112637
This commit is contained in:
parent
a23e8f7a0f
commit
bd59576541
|
@ -784,6 +784,8 @@ public:
|
|||
return DeclKind == Decl::Namespace;
|
||||
}
|
||||
|
||||
bool isInlineNamespace() const;
|
||||
|
||||
/// \brief Determines whether this context is dependent on a
|
||||
/// template parameter.
|
||||
bool isDependentContext() const;
|
||||
|
@ -802,8 +804,7 @@ public:
|
|||
/// Here, E is a transparent context, so its enumerator (Val1) will
|
||||
/// appear (semantically) that it is in the same context of E.
|
||||
/// Examples of transparent contexts include: enumerations (except for
|
||||
/// C++0x scoped enums), C++ linkage specifications, and C++0x
|
||||
/// inline namespaces.
|
||||
/// C++0x scoped enums), and C++ linkage specifications.
|
||||
bool isTransparentContext() const;
|
||||
|
||||
/// \brief Determine whether this declaration context is equivalent
|
||||
|
@ -829,8 +830,7 @@ public:
|
|||
|
||||
/// getRedeclContext - Retrieve the context in which an entity conflicts with
|
||||
/// other entities of the same name, or where it is a redeclaration if the
|
||||
/// two entities are compatible. This skips through transparent contexts,
|
||||
/// except inline namespaces.
|
||||
/// two entities are compatible. This skips through transparent contexts.
|
||||
DeclContext *getRedeclContext();
|
||||
const DeclContext *getRedeclContext() const {
|
||||
return const_cast<DeclContext *>(this)->getRedeclContext();
|
||||
|
|
|
@ -478,6 +478,11 @@ DeclContext *DeclContext::getLookupParent() {
|
|||
return getParent();
|
||||
}
|
||||
|
||||
bool DeclContext::isInlineNamespace() const {
|
||||
return isNamespace() &&
|
||||
cast<NamespaceDecl>(this)->isInline();
|
||||
}
|
||||
|
||||
bool DeclContext::isDependentContext() const {
|
||||
if (isFileContext())
|
||||
return false;
|
||||
|
@ -509,8 +514,6 @@ bool DeclContext::isTransparentContext() const {
|
|||
return true;
|
||||
else if (DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord)
|
||||
return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
|
||||
else if (DeclKind == Decl::Namespace)
|
||||
return cast<NamespaceDecl>(this)->isInline();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -799,10 +802,10 @@ void DeclContext::buildLookup(DeclContext *DCtx) {
|
|||
I != IEnd; ++I)
|
||||
makeDeclVisibleInContextImpl(I->getInterface());
|
||||
|
||||
// If this declaration is itself a transparent declaration context,
|
||||
// add its members (recursively).
|
||||
// If this declaration is itself a transparent declaration context or
|
||||
// inline namespace, add its members (recursively).
|
||||
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
|
||||
if (InnerCtx->isTransparentContext())
|
||||
if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
|
||||
buildLookup(InnerCtx->getPrimaryContext());
|
||||
}
|
||||
}
|
||||
|
@ -849,8 +852,8 @@ DeclContext::lookup(DeclarationName Name) const {
|
|||
|
||||
DeclContext *DeclContext::getRedeclContext() {
|
||||
DeclContext *Ctx = this;
|
||||
// Skip through transparent contexts, except inline namespaces.
|
||||
while (Ctx->isTransparentContext() && !Ctx->isNamespace())
|
||||
// Skip through transparent contexts.
|
||||
while (Ctx->isTransparentContext())
|
||||
Ctx = Ctx->getParent();
|
||||
return Ctx;
|
||||
}
|
||||
|
@ -904,9 +907,9 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
|
|||
if (LookupPtr || !Recoverable || hasExternalVisibleStorage())
|
||||
makeDeclVisibleInContextImpl(D);
|
||||
|
||||
// If we are a transparent context, insert into our parent context,
|
||||
// too. This operation is recursive.
|
||||
if (isTransparentContext())
|
||||
// If we are a transparent context or inline namespace, insert into our
|
||||
// parent context, too. This operation is recursive.
|
||||
if (isTransparentContext() || isInlineNamespace())
|
||||
getParent()->makeDeclVisibleInContext(D, Recoverable);
|
||||
}
|
||||
|
||||
|
|
|
@ -1619,7 +1619,11 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
|
|||
// We don't use DeclContext::getEnclosingNamespaceContext() as this may
|
||||
// be a locally scoped record.
|
||||
|
||||
while (Ctx->isRecord() || Ctx->isTransparentContext())
|
||||
// We skip out of inline namespaces. The innermost non-inline namespace
|
||||
// contains all names of all its nested inline namespaces anyway, so we can
|
||||
// replace the entire inline namespace tree with its root.
|
||||
while (Ctx->isRecord() || Ctx->isTransparentContext() ||
|
||||
Ctx->isInlineNamespace())
|
||||
Ctx = Ctx->getParent();
|
||||
|
||||
if (Ctx->isFileContext())
|
||||
|
@ -2423,9 +2427,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
|
|||
Visited.add(ND);
|
||||
}
|
||||
|
||||
// Visit transparent contexts inside this context.
|
||||
// Visit transparent contexts and inline namespaces inside this context.
|
||||
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
|
||||
if (InnerCtx->isTransparentContext())
|
||||
if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
|
||||
LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
|
||||
Consumer, Visited);
|
||||
}
|
||||
|
|
|
@ -72,3 +72,26 @@ void foo3() {
|
|||
Distinct d;
|
||||
::over(d);
|
||||
}
|
||||
|
||||
// Don't forget to do correct lookup for redeclarations.
|
||||
namespace redecl { inline namespace n1 {
|
||||
|
||||
template <class Tp> class allocator;
|
||||
|
||||
template <>
|
||||
class allocator<void>
|
||||
{
|
||||
public:
|
||||
typedef const void* const_pointer;
|
||||
};
|
||||
|
||||
template <class Tp>
|
||||
class allocator
|
||||
{
|
||||
public:
|
||||
typedef Tp& reference;
|
||||
|
||||
void allocate(allocator<void>::const_pointer = 0);
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
Loading…
Reference in New Issue