[cfe-commits] r112637 - in /cfe/trunk: include/clang/AST/DeclBase.h lib/AST/DeclBase.cpp lib/Sema/SemaLookup.cpp test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Tue Aug 31 13:53:31 PDT 2010
Author: cornedbee
Date: Tue Aug 31 15:53:31 2010
New Revision: 112637
URL: http://llvm.org/viewvc/llvm-project?rev=112637&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=112637&r1=112636&r2=112637&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Tue Aug 31 15:53:31 2010
@@ -784,6 +784,8 @@
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 @@
/// 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 @@
/// 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();
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=112637&r1=112636&r2=112637&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Aug 31 15:53:31 2010
@@ -478,6 +478,11 @@
return getParent();
}
+bool DeclContext::isInlineNamespace() const {
+ return isNamespace() &&
+ cast<NamespaceDecl>(this)->isInline();
+}
+
bool DeclContext::isDependentContext() const {
if (isFileContext())
return false;
@@ -509,8 +514,6 @@
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 @@
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 *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 @@
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);
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=112637&r1=112636&r2=112637&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Aug 31 15:53:31 2010
@@ -1619,7 +1619,11 @@
// 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 @@
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);
}
Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp?rev=112637&r1=112636&r2=112637&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp Tue Aug 31 15:53:31 2010
@@ -72,3 +72,26 @@
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);
+ };
+
+} }
More information about the cfe-commits
mailing list