diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-14 02:00:47 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-14 02:00:47 +0000 |
| commit | 32952e1e42ce69c232b37b26173ef301a2318f38 (patch) | |
| tree | 4a227dc92a8f5be29cf2dcd8e5375319e9e7acd7 /clang/lib | |
| parent | 5bbe3df63f4788b42ead0344d431ecd9656d7ced (diff) | |
| download | bcm5719-llvm-32952e1e42ce69c232b37b26173ef301a2318f38.tar.gz bcm5719-llvm-32952e1e42ce69c232b37b26173ef301a2318f38.zip | |
[modules] Merging for class-scope using-declarations.
llvm-svn: 219657
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 68 |
2 files changed, 75 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index a07f7765fcb..274105d532a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4293,25 +4293,26 @@ static bool isInstantiationOf(EnumDecl *Pattern, static bool isInstantiationOf(UsingShadowDecl *Pattern, UsingShadowDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUsingShadowDecl(Instance) == Pattern; + return declaresSameEntity(C.getInstantiatedFromUsingShadowDecl(Instance), + Pattern); } static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUsingDecl(Instance) == Pattern; + return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern); } static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern, UsingDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUsingDecl(Instance) == Pattern; + return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern); } static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern, UsingDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUsingDecl(Instance) == Pattern; + return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern); } static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, @@ -4377,8 +4378,8 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) { if (!Field->getDeclName()) { // This is an unnamed field. - return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) == - cast<FieldDecl>(D); + return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field), + cast<FieldDecl>(D)); } } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 51d930073dc..a3b773f6fc5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1224,6 +1224,7 @@ void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { D->setTypename(Record[Idx++]); if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx)) Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern); + mergeMergeable(D); } void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { @@ -1251,6 +1252,7 @@ void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { D->setUsingLoc(ReadSourceLocation(Record, Idx)); D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx); + mergeMergeable(D); } void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( @@ -1258,6 +1260,7 @@ void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( VisitTypeDecl(D); D->TypenameLocation = ReadSourceLocation(Record, Idx); D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); + mergeMergeable(D); } void ASTDeclReader::ReadCXXDefinitionData( @@ -2341,6 +2344,53 @@ static bool isSameTemplateParameter(const NamedDecl *X, TY->getTemplateParameters()); } +static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) { + if (auto *NS = X->getAsNamespace()) + return NS; + if (auto *NAS = X->getAsNamespaceAlias()) + return NAS->getNamespace(); + return nullptr; +} + +static bool isSameQualifier(const NestedNameSpecifier *X, + const NestedNameSpecifier *Y) { + if (auto *NSX = getNamespace(X)) { + auto *NSY = getNamespace(Y); + if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl()) + return false; + } else if (X->getKind() != Y->getKind()) + return false; + + // FIXME: For namespaces and types, we're permitted to check that the entity + // is named via the same tokens. We should probably do so. + switch (X->getKind()) { + case NestedNameSpecifier::Identifier: + if (X->getAsIdentifier() != Y->getAsIdentifier()) + return false; + break; + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: + // We've already checked that we named the same namespace. + break; + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + if (X->getAsType()->getCanonicalTypeInternal() != + Y->getAsType()->getCanonicalTypeInternal()) + return false; + break; + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Super: + return true; + } + + // Recurse into earlier portion of NNS, if any. + auto *PX = X->getPrefix(); + auto *PY = Y->getPrefix(); + if (PX && PY) + return isSameQualifier(PX, PY); + return !PX && !PY; +} + /// \brief Determine whether two template parameter lists are similar enough /// that they may be used in declarations of the same template. static bool isSameTemplateParameterList(const TemplateParameterList *X, @@ -2448,6 +2498,24 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return USX->getTargetDecl() == USY->getTargetDecl(); } + // Using declarations with the same qualifier match. (We already know that + // the name matches.) + if (auto *UX = dyn_cast<UsingDecl>(X)) { + auto *UY = cast<UsingDecl>(Y); + return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && + UX->hasTypename() == UY->hasTypename() && + UX->isAccessDeclaration() == UY->isAccessDeclaration(); + } + if (auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { + auto *UY = cast<UnresolvedUsingValueDecl>(Y); + return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && + UX->isAccessDeclaration() == UY->isAccessDeclaration(); + } + if (auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) + return isSameQualifier( + UX->getQualifier(), + cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); + // Namespace alias definitions with the same target match. if (auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { auto *NAY = cast<NamespaceAliasDecl>(Y); |

