[cfe-commits] r91493 - in /cfe/trunk: include/clang/AST/Decl.h lib/Sema/SemaDeclCXX.cpp test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
John McCall
rjmccall at apple.com
Tue Dec 15 18:06:49 PST 2009
Author: rjmccall
Date: Tue Dec 15 20:06:49 2009
New Revision: 91493
URL: http://llvm.org/viewvc/llvm-project?rev=91493&view=rev
Log:
Successive anonymous namespaces name the same scope. I misinterpreted the
standard the last time. Fixes PR5766.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=91493&r1=91492&r2=91493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Dec 15 20:06:49 2009
@@ -85,13 +85,20 @@
class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx;
+ /// The (most recently entered) anonymous namespace for this
+ /// translation unit, if one has been created.
+ NamespaceDecl *AnonymousNamespace;
+
explicit TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, 0, SourceLocation()),
DeclContext(TranslationUnit),
- Ctx(ctx) {}
+ Ctx(ctx), AnonymousNamespace(0) {}
public:
ASTContext &getASTContext() const { return Ctx; }
+ NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; }
+ void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; }
+
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
@@ -247,10 +254,15 @@
// OrigNamespace of the first namespace decl points to itself.
NamespaceDecl *OrigNamespace, *NextNamespace;
+ // The (most recently entered) anonymous namespace inside this
+ // namespace.
+ NamespaceDecl *AnonymousNamespace;
+
NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
: NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace) {
OrigNamespace = this;
NextNamespace = 0;
+ AnonymousNamespace = 0;
}
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
@@ -278,6 +290,16 @@
}
void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
+ NamespaceDecl *getAnonymousNamespace() const {
+ return AnonymousNamespace;
+ }
+
+ void setAnonymousNamespace(NamespaceDecl *D) {
+ assert(D->isAnonymousNamespace());
+ assert(D->getParent() == this);
+ AnonymousNamespace = D;
+ }
+
virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
const NamespaceDecl *getCanonicalDecl() const { return OrigNamespace; }
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=91493&r1=91492&r2=91493&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Dec 15 20:06:49 2009
@@ -2748,6 +2748,28 @@
PushOnScopeChains(Namespc, DeclRegionScope);
} else {
// Anonymous namespaces.
+ assert(Namespc->isAnonymousNamespace());
+ CurContext->addDecl(Namespc);
+
+ // Link the anonymous namespace into its parent.
+ NamespaceDecl *PrevDecl;
+ DeclContext *Parent = CurContext->getLookupContext();
+ if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) {
+ PrevDecl = TU->getAnonymousNamespace();
+ TU->setAnonymousNamespace(Namespc);
+ } else {
+ NamespaceDecl *ND = cast<NamespaceDecl>(Parent);
+ PrevDecl = ND->getAnonymousNamespace();
+ ND->setAnonymousNamespace(Namespc);
+ }
+
+ // Link the anonymous namespace with its previous declaration.
+ if (PrevDecl) {
+ assert(PrevDecl->isAnonymousNamespace());
+ assert(!PrevDecl->getNextNamespace());
+ Namespc->setOriginalNamespace(PrevDecl->getOriginalNamespace());
+ PrevDecl->setNextNamespace(Namespc);
+ }
// C++ [namespace.unnamed]p1. An unnamed-namespace-definition
// behaves as if it were replaced by
@@ -2765,20 +2787,19 @@
// declarations semantically contained within an anonymous
// namespace internal linkage.
- assert(Namespc->isAnonymousNamespace());
- CurContext->addDecl(Namespc);
-
- UsingDirectiveDecl* UD
- = UsingDirectiveDecl::Create(Context, CurContext,
- /* 'using' */ LBrace,
- /* 'namespace' */ SourceLocation(),
- /* qualifier */ SourceRange(),
- /* NNS */ NULL,
- /* identifier */ SourceLocation(),
- Namespc,
- /* Ancestor */ CurContext);
- UD->setImplicit();
- CurContext->addDecl(UD);
+ if (!PrevDecl) {
+ UsingDirectiveDecl* UD
+ = UsingDirectiveDecl::Create(Context, CurContext,
+ /* 'using' */ LBrace,
+ /* 'namespace' */ SourceLocation(),
+ /* qualifier */ SourceRange(),
+ /* NNS */ NULL,
+ /* identifier */ SourceLocation(),
+ Namespc,
+ /* Ancestor */ CurContext);
+ UD->setImplicit();
+ CurContext->addDecl(UD);
+ }
}
// Although we could have an invalid decl (i.e. the namespace name is a
Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp?rev=91493&r1=91492&r2=91493&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp Tue Dec 15 20:06:49 2009
@@ -1,7 +1,6 @@
// RUN: %clang_cc1 -emit-llvm-only -verify %s
// This lame little test was ripped straight from the standard.
-
namespace {
int i; // expected-note {{candidate}}
}
@@ -22,3 +21,22 @@
A::i++;
j++;
}
+
+
+// Test that all anonymous namespaces in a translation unit are
+// considered the same context.
+namespace {
+ class Test3 {}; // expected-note {{previous definition}}
+}
+namespace {
+ class Test3 {}; // expected-error {{redefinition of 'Test3'}}
+}
+
+namespace test4 {
+ namespace {
+ class Test4 {}; // expected-note {{previous definition}}
+ }
+ namespace {
+ class Test4 {}; // expected-error {{redefinition of 'Test4'}}
+ }
+}
More information about the cfe-commits
mailing list