r193219 - Make UsingShadowDecls redeclarable. This fixes some visibility problems with
Richard Smith
richard-llvm at metafoo.co.uk
Tue Oct 22 19:17:46 PDT 2013
Author: rsmith
Date: Tue Oct 22 21:17:46 2013
New Revision: 193219
URL: http://llvm.org/viewvc/llvm-project?rev=193219&view=rev
Log:
Make UsingShadowDecls redeclarable. This fixes some visibility problems with
modules.
With this fixed, I no longer see any test regressions in the libc++ test suite
when enabling a single-module module.map for libc++ (other than issues with my
system headers).
Added:
cfe/trunk/test/Modules/Inputs/using-decl-a.h
cfe/trunk/test/Modules/Inputs/using-decl-b.h
cfe/trunk/test/Modules/using-decl.cpp
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTCommon.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
cfe/trunk/test/Modules/Inputs/module.map
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Oct 22 21:17:46 2013
@@ -2676,7 +2676,7 @@ public:
/// // Also creates a UsingShadowDecl for A::foo() in B
/// }
/// \endcode
-class UsingShadowDecl : public NamedDecl {
+class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
virtual void anchor();
/// The referenced declaration.
@@ -2699,6 +2699,17 @@ class UsingShadowDecl : public NamedDecl
setImplicit();
}
+ typedef Redeclarable<UsingShadowDecl> redeclarable_base;
+ virtual UsingShadowDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
+ }
+ virtual UsingShadowDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual UsingShadowDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
+
public:
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
@@ -2707,7 +2718,20 @@ public:
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
+
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
+
+ virtual UsingShadowDecl *getCanonicalDecl() {
+ return getFirstDecl();
+ }
+ virtual const UsingShadowDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
/// \brief Gets the underlying declaration which has been brought into the
/// local scope.
NamedDecl *getTargetDecl() const { return Underlying; }
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Oct 22 21:17:46 2013
@@ -3640,9 +3640,11 @@ public:
void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
- const LookupResult &PreviousDecls);
+ const LookupResult &PreviousDecls,
+ UsingShadowDecl *&PrevShadow);
UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
- NamedDecl *Target);
+ NamedDecl *Target,
+ UsingShadowDecl *PrevDecl);
bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
bool HasTypenameKeyword,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Oct 22 21:17:46 2013
@@ -7073,20 +7073,15 @@ Decl *Sema::ActOnUsingDeclaration(Scope
/// \brief Determine whether a using declaration considers the given
/// declarations as "equivalent", e.g., if they are redeclarations of
/// the same entity or are both typedefs of the same type.
-static bool
-IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2,
- bool &SuppressRedeclaration) {
- if (D1->getCanonicalDecl() == D2->getCanonicalDecl()) {
- SuppressRedeclaration = false;
+static bool
+IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2) {
+ if (D1->getCanonicalDecl() == D2->getCanonicalDecl())
return true;
- }
if (TypedefNameDecl *TD1 = dyn_cast<TypedefNameDecl>(D1))
- if (TypedefNameDecl *TD2 = dyn_cast<TypedefNameDecl>(D2)) {
- SuppressRedeclaration = true;
+ if (TypedefNameDecl *TD2 = dyn_cast<TypedefNameDecl>(D2))
return Context.hasSameType(TD1->getUnderlyingType(),
TD2->getUnderlyingType());
- }
return false;
}
@@ -7095,7 +7090,8 @@ IsEquivalentForUsingDecl(ASTContext &Con
/// Determines whether to create a using shadow decl for a particular
/// decl, given the set of decls existing prior to this using lookup.
bool Sema::CheckUsingShadowDecl(UsingDecl *Using, NamedDecl *Orig,
- const LookupResult &Previous) {
+ const LookupResult &Previous,
+ UsingShadowDecl *&PrevShadow) {
// Diagnose finding a decl which is not from a base class of the
// current class. We do this now because there are cases where this
// function will silently decide not to build a shadow decl, which
@@ -7155,16 +7151,22 @@ bool Sema::CheckUsingShadowDecl(UsingDec
// FIXME: but we might be increasing its access, in which case we
// should redeclare it.
NamedDecl *NonTag = 0, *Tag = 0;
+ bool FoundEquivalentDecl = false;
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
- bool Result;
- if (IsEquivalentForUsingDecl(Context, D, Target, Result))
- return Result;
+ if (IsEquivalentForUsingDecl(Context, D, Target)) {
+ if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(*I))
+ PrevShadow = Shadow;
+ FoundEquivalentDecl = true;
+ }
(isa<TagDecl>(D) ? Tag : NonTag) = D;
}
+ if (FoundEquivalentDecl)
+ return false;
+
if (Target->isFunctionOrFunctionTemplate()) {
FunctionDecl *FD;
if (isa<FunctionTemplateDecl>(Target))
@@ -7223,7 +7225,8 @@ bool Sema::CheckUsingShadowDecl(UsingDec
/// Builds a shadow declaration corresponding to a 'using' declaration.
UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S,
UsingDecl *UD,
- NamedDecl *Orig) {
+ NamedDecl *Orig,
+ UsingShadowDecl *PrevDecl) {
// If we resolved to another shadow declaration, just coalesce them.
NamedDecl *Target = Orig;
@@ -7231,16 +7234,18 @@ UsingShadowDecl *Sema::BuildUsingShadowD
Target = cast<UsingShadowDecl>(Target)->getTargetDecl();
assert(!isa<UsingShadowDecl>(Target) && "nested shadow declaration");
}
-
+
UsingShadowDecl *Shadow
= UsingShadowDecl::Create(Context, CurContext,
UD->getLocation(), UD, Target);
UD->addShadowDecl(Shadow);
-
+
Shadow->setAccess(UD->getAccess());
if (Orig->isInvalidDecl() || UD->isInvalidDecl())
Shadow->setInvalidDecl();
-
+
+ Shadow->setPreviousDecl(PrevDecl);
+
if (S)
PushOnScopeChains(Shadow, S);
else
@@ -7504,8 +7509,9 @@ NamedDecl *Sema::BuildUsingDeclaration(S
}
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
- if (!CheckUsingShadowDecl(UD, *I, Previous))
- BuildUsingShadowDecl(S, UD, *I);
+ UsingShadowDecl *PrevDecl = 0;
+ if (!CheckUsingShadowDecl(UD, *I, Previous, PrevDecl))
+ BuildUsingShadowDecl(S, UD, *I, PrevDecl);
}
return UD;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Oct 22 21:17:46 2013
@@ -2152,19 +2152,22 @@ Decl *TemplateDeclInstantiator::VisitUsi
I != E; ++I) {
UsingShadowDecl *Shadow = *I;
NamedDecl *InstTarget =
- cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl(
- Shadow->getLocation(),
- Shadow->getTargetDecl(),
- TemplateArgs));
+ cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl(
+ Shadow->getLocation(), Shadow->getTargetDecl(), TemplateArgs));
if (!InstTarget)
return 0;
- if (CheckRedeclaration &&
- SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev))
- continue;
+ UsingShadowDecl *PrevDecl = 0;
+ if (CheckRedeclaration) {
+ if (SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev, PrevDecl))
+ continue;
+ } else if (UsingShadowDecl *OldPrev = Shadow->getPreviousDecl()) {
+ PrevDecl = cast_or_null<UsingShadowDecl>(SemaRef.FindInstantiatedDecl(
+ Shadow->getLocation(), OldPrev, TemplateArgs));
+ }
- UsingShadowDecl *InstShadow
- = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0, NewUD, InstTarget);
+ UsingShadowDecl *InstShadow =
+ SemaRef.BuildUsingShadowDecl(/*Scope*/0, NewUD, InstTarget, PrevDecl);
SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow);
if (isFunctionScope)
Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Tue Oct 22 21:17:46 2013
@@ -165,6 +165,7 @@ bool serialization::isRedeclarableDeclKi
case Decl::CXXConstructor:
case Decl::CXXDestructor:
case Decl::CXXConversion:
+ case Decl::UsingShadow:
case Decl::Var:
case Decl::FunctionTemplate:
case Decl::ClassTemplate:
@@ -192,7 +193,6 @@ bool serialization::isRedeclarableDeclKi
case Decl::NonTypeTemplateParm:
case Decl::TemplateTemplateParm:
case Decl::Using:
- case Decl::UsingShadow:
case Decl::ObjCMethod:
case Decl::ObjCCategory:
case Decl::ObjCCategoryImpl:
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Oct 22 21:17:46 2013
@@ -1134,12 +1134,14 @@ void ASTDeclReader::VisitUsingDecl(Using
}
void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ RedeclarableResult Redecl = VisitRedeclarable(D);
VisitNamedDecl(D);
D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx));
D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx);
UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx);
if (Pattern)
Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
+ mergeRedeclarable(D, Redecl);
}
void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
@@ -2151,6 +2153,12 @@ static bool isSameEntity(NamedDecl *X, N
// FIXME: Also check the value is odr-equivalent.
return true;
+ // Using shadow declarations with the same target match.
+ if (UsingShadowDecl *USX = dyn_cast<UsingShadowDecl>(X)) {
+ UsingShadowDecl *USY = cast<UsingShadowDecl>(Y);
+ return USX->getTargetDecl() == USY->getTargetDecl();
+ }
+
// FIXME: Many other cases to implement.
return false;
}
@@ -2258,6 +2266,8 @@ void ASTDeclReader::attachPreviousDecl(D
VD->RedeclLink.setNext(cast<VarDecl>(previous));
} else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
+ } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
+ USD->RedeclLink.setNext(cast<UsingShadowDecl>(previous));
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
} else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
@@ -2285,7 +2295,7 @@ void ASTDeclReader::attachLatestDecl(Dec
TD->RedeclLink
= Redeclarable<TagDecl>::LatestDeclLink(cast<TagDecl>(Latest));
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- FD->RedeclLink
+ FD->RedeclLink
= Redeclarable<FunctionDecl>::LatestDeclLink(cast<FunctionDecl>(Latest));
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
VD->RedeclLink
@@ -2294,6 +2304,10 @@ void ASTDeclReader::attachLatestDecl(Dec
TD->RedeclLink
= Redeclarable<TypedefNameDecl>::LatestDeclLink(
cast<TypedefNameDecl>(Latest));
+ } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
+ USD->RedeclLink
+ = Redeclarable<UsingShadowDecl>::LatestDeclLink(
+ cast<UsingShadowDecl>(Latest));
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
ID->RedeclLink
= Redeclarable<ObjCInterfaceDecl>::LatestDeclLink(
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Oct 22 21:17:46 2013
@@ -938,6 +938,7 @@ void ASTDeclWriter::VisitUsingDecl(Using
}
void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ VisitRedeclarable(D);
VisitNamedDecl(D);
Writer.AddDeclRef(D->getTargetDecl(), Record);
Writer.AddDeclRef(D->UsingOrNextShadow, Record);
Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=193219&r1=193218&r2=193219&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Tue Oct 22 21:17:46 2013
@@ -258,3 +258,8 @@ module warning {
module initializer_list {
header "initializer_list"
}
+
+module using_decl {
+ module a { header "using-decl-a.h" export * }
+ module b { header "using-decl-b.h" export * }
+}
Added: cfe/trunk/test/Modules/Inputs/using-decl-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/using-decl-a.h?rev=193219&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/using-decl-a.h (added)
+++ cfe/trunk/test/Modules/Inputs/using-decl-a.h Tue Oct 22 21:17:46 2013
@@ -0,0 +1,10 @@
+typedef int using_decl_type;
+int using_decl_var;
+
+namespace UsingDecl {
+ using ::using_decl_type;
+ using ::using_decl_var;
+
+ namespace A { typedef int inner; }
+ using A::inner;
+}
Added: cfe/trunk/test/Modules/Inputs/using-decl-b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/using-decl-b.h?rev=193219&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/using-decl-b.h (added)
+++ cfe/trunk/test/Modules/Inputs/using-decl-b.h Tue Oct 22 21:17:46 2013
@@ -0,0 +1,11 @@
+namespace UsingDecl {
+ namespace B { typedef int inner; }
+ using B::inner;
+}
+
+#include "using-decl-a.h"
+
+namespace UsingDecl {
+ using ::using_decl_type;
+ using ::using_decl_var;
+}
Added: cfe/trunk/test/Modules/using-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/using-decl.cpp?rev=193219&view=auto
==============================================================================
--- cfe/trunk/test/Modules/using-decl.cpp (added)
+++ cfe/trunk/test/Modules/using-decl.cpp Tue Oct 22 21:17:46 2013
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify
+
+ at import using_decl.a;
+
+// expected-no-diagnostics
+UsingDecl::using_decl_type x = UsingDecl::using_decl_var;
+UsingDecl::inner y = x;
More information about the cfe-commits
mailing list