DeclUnloader: reset the anonymous namespace in the enclosing DC
From SemaDeclCXX.cpp: ``` C++ [namespace.unnamed]p1. An unnamed-namespace-definition behaves as if it were replaced by namespace unique { /* empty body */ } using namespace unique; namespace unique { namespace-body } where all occurrences of 'unique' in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program. ``` Thus, the first declaration of an unnamed namespace creates an implicit UsingDirectiveDecl that makes the names available in the parent DC. If we are reverting such first declaration, make sure we reset the anonymous namespace for the parent DeclContext so that the implicit UsingDirectiveDecl is created again when parsing the next anonymous namespace. Fixes issue #7483.
This commit is contained in:
parent
b651b2bdb4
commit
2ec73dd62a
@ -733,6 +733,22 @@ bool DeclUnloader::VisitRedeclarable(clang::Redeclarable<T>* R, DeclContext* DC)
|
||||
}
|
||||
|
||||
bool DeclUnloader::VisitNamespaceDecl(NamespaceDecl* NSD) {
|
||||
// The first declaration of an unnamed namespace, creates an implicit
|
||||
// UsingDirectiveDecl that makes the names available in the parent DC (see
|
||||
// `Sema::ActOnStartNamespaceDef()`).
|
||||
// If we are reverting such first declaration, make sure we reset the
|
||||
// anonymous namespace for the parent DeclContext so that the
|
||||
// implicit UsingDirectiveDecl is created again when parsing the next
|
||||
// anonymous namespace.
|
||||
if (NSD->isAnonymousNamespace() && NSD->isFirstDecl()) {
|
||||
auto Parent = NSD->getParent();
|
||||
if (auto TU = dyn_cast<TranslationUnitDecl>(Parent)) {
|
||||
TU->setAnonymousNamespace(nullptr);
|
||||
} else if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
|
||||
NS->setAnonymousNamespace(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// NamespaceDecl: NamedDecl, DeclContext, Redeclarable
|
||||
bool Successful = VisitDeclContext(NSD);
|
||||
Successful &= VisitRedeclarable(NSD, NSD->getDeclContext());
|
||||
|
@ -23,3 +23,8 @@ macro() // CHECK: version 1
|
||||
.L macro2.h
|
||||
macro() // CHECK: 2.version 2
|
||||
//CHECK: (int) 2
|
||||
|
||||
.x unnamedns.h
|
||||
//CHECK: 13
|
||||
.x unnamedns.h
|
||||
//CHECK-NEXT: 13
|
||||
|
7
test/CodeUnloading/unnamedns.h
Normal file
7
test/CodeUnloading/unnamedns.h
Normal file
@ -0,0 +1,7 @@
|
||||
namespace {
|
||||
int h = 12;
|
||||
}
|
||||
|
||||
void unnamedns() {
|
||||
printf("%d\n", ++h);
|
||||
}
|
Loading…
Reference in New Issue
Block a user