[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