Author: rsmith Date: Fri Jan 5 17:07:05 2018 New Revision: 321921 URL: http://llvm.org/viewvc/llvm-project?rev=321921&view=rev Log: Serialize the IDNS for a UsingShadowDecl rather than recomputing it.
Attempting to recompute it are doomed to fail because the IDNS of a declaration is not necessarily preserved across serialization and deserialization (in turn because whether a friend declaration is visible depends on whether some prior non-friend declaration exists). Added: cfe/trunk/test/Modules/using-decl-friend-2.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Modified: cfe/trunk/include/clang/AST/DeclCXX.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=321921&r1=321920&r2=321921&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/DeclCXX.h (original) +++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jan 5 17:07:05 2018 @@ -3129,10 +3129,14 @@ public: /// \brief Sets the underlying declaration which has been brought into the /// local scope. - void setTargetDecl(NamedDecl* ND) { + void setTargetDecl(NamedDecl *ND) { assert(ND && "Target decl is null!"); Underlying = ND; - IdentifierNamespace = ND->getIdentifierNamespace(); + // A UsingShadowDecl is never a friend or local extern declaration, even + // if it is a shadow declaration for one. + IdentifierNamespace = + ND->getIdentifierNamespace() & + ~(IDNS_OrdinaryFriend | IDNS_TagFriend | IDNS_LocalExtern); } /// \brief Gets the using declaration to which this declaration is tied. Modified: cfe/trunk/lib/AST/DeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=321921&r1=321920&r2=321921&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclCXX.cpp (original) +++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Jan 5 17:07:05 2018 @@ -2387,10 +2387,10 @@ UsingShadowDecl::UsingShadowDecl(Kind K, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) : NamedDecl(K, DC, Loc, Using ? Using->getDeclName() : DeclarationName()), - redeclarable_base(C), Underlying(Target), + redeclarable_base(C), Underlying(), UsingOrNextShadow(cast<NamedDecl>(Using)) { if (Target) - IdentifierNamespace = Target->getIdentifierNamespace(); + setTargetDecl(Target); setImplicit(); } Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=321921&r1=321920&r2=321921&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Jan 5 17:07:05 2018 @@ -1500,7 +1500,8 @@ void ASTDeclReader::VisitUsingPackDecl(U void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); VisitNamedDecl(D); - D->setTargetDecl(ReadDeclAs<NamedDecl>()); + D->Underlying = ReadDeclAs<NamedDecl>(); + D->IdentifierNamespace = Record.readInt(); D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(); UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(); if (Pattern) Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=321921&r1=321920&r2=321921&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Jan 5 17:07:05 2018 @@ -1192,6 +1192,7 @@ void ASTDeclWriter::VisitUsingShadowDecl VisitRedeclarable(D); VisitNamedDecl(D); Record.AddDeclRef(D->getTargetDecl()); + Record.push_back(D->getIdentifierNamespace()); Record.AddDeclRef(D->UsingOrNextShadow); Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D)); Code = serialization::DECL_USING_SHADOW; Added: cfe/trunk/test/Modules/using-decl-friend-2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/using-decl-friend-2.cpp?rev=321921&view=auto ============================================================================== --- cfe/trunk/test/Modules/using-decl-friend-2.cpp (added) +++ cfe/trunk/test/Modules/using-decl-friend-2.cpp Fri Jan 5 17:07:05 2018 @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fmodules %s -verify +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +namespace N { class X; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +namespace N { class Friendly { friend class X; }; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build C +module C {} +#pragma clang module contents +#pragma clang module begin C +#pragma clang module import A +void use_X(N::X *p); +#pragma clang module import B +// UsingShadowDecl names the friend declaration +using N::X; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import B +namespace N { class AlsoFriendly { friend class X; }; } +#pragma clang module import A +#pragma clang module import C +// The friend declaration from N::Friendly is now the first in the redecl +// chain, so is not ordinarily visible. We need the IDNS of the UsingShadowDecl +// to still consider it to be visible, though. +X *p; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits