diff options
author | Gabor Marton <gabor.marton@ericsson.com> | 2019-07-02 07:36:39 +0000 |
---|---|---|
committer | Gabor Marton <gabor.marton@ericsson.com> | 2019-07-02 07:36:39 +0000 |
commit | 4f883f1c39f99bda828a67fc3a18d5fd52a43998 (patch) | |
tree | a12e9cd8806e03a7f3c9e43a70b5bde94f8ddc1f /clang/lib/AST/ASTStructuralEquivalence.cpp | |
parent | 000ef2c2ae0752ae97a99db8dabada7ca2f480f3 (diff) | |
download | bcm5719-llvm-4f883f1c39f99bda828a67fc3a18d5fd52a43998.tar.gz bcm5719-llvm-4f883f1c39f99bda828a67fc3a18d5fd52a43998.zip |
[ASTImporter] Structural eq: handle DependentScopeDeclRefExpr
Summary:
Structural equivalence did not handle dependent template args properly
when the arg contained a DependentScopeDeclRefExpr.
Reviewers: a_sidorin, a.sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62329
llvm-svn: 364889
Diffstat (limited to 'clang/lib/AST/ASTStructuralEquivalence.cpp')
-rw-r--r-- | clang/lib/AST/ASTStructuralEquivalence.cpp | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 5ba318955f2..744b30f8533 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -73,6 +73,7 @@ #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" @@ -100,6 +101,59 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, const TemplateArgument &Arg1, const TemplateArgument &Arg2); +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + NestedNameSpecifier *NNS1, + NestedNameSpecifier *NNS2); +static bool IsStructurallyEquivalent(const IdentifierInfo *Name1, + const IdentifierInfo *Name2); + +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const DeclarationName Name1, + const DeclarationName Name2) { + if (Name1.getNameKind() != Name2.getNameKind()) + return false; + + switch (Name1.getNameKind()) { + + case DeclarationName::Identifier: + return IsStructurallyEquivalent(Name1.getAsIdentifierInfo(), + Name2.getAsIdentifierInfo()); + + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + return IsStructurallyEquivalent(Context, Name1.getCXXNameType(), + Name2.getCXXNameType()); + + case DeclarationName::CXXDeductionGuideName: { + if (!IsStructurallyEquivalent( + Context, Name1.getCXXDeductionGuideTemplate()->getDeclName(), + Name2.getCXXDeductionGuideTemplate()->getDeclName())) + return false; + return IsStructurallyEquivalent(Context, + Name1.getCXXDeductionGuideTemplate(), + Name2.getCXXDeductionGuideTemplate()); + } + + case DeclarationName::CXXOperatorName: + return Name1.getCXXOverloadedOperator() == Name2.getCXXOverloadedOperator(); + + case DeclarationName::CXXLiteralOperatorName: + return IsStructurallyEquivalent(Name1.getCXXLiteralIdentifier(), + Name2.getCXXLiteralIdentifier()); + + case DeclarationName::CXXUsingDirective: + return true; // FIXME When do we consider two using directives equal? + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + return true; // FIXME + } + + llvm_unreachable("Unhandled kind of DeclarationName"); + return true; +} /// Determine structural equivalence of two expressions. static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, @@ -107,7 +161,26 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, if (!E1 || !E2) return E1 == E2; - // FIXME: Actually perform a structural comparison! + if (auto *DE1 = dyn_cast<DependentScopeDeclRefExpr>(E1)) { + auto *DE2 = dyn_cast<DependentScopeDeclRefExpr>(E2); + if (!DE2) + return false; + if (!IsStructurallyEquivalent(Context, DE1->getDeclName(), + DE2->getDeclName())) + return false; + return IsStructurallyEquivalent(Context, DE1->getQualifier(), + DE2->getQualifier()); + } else if (auto CastE1 = dyn_cast<ImplicitCastExpr>(E1)) { + auto *CastE2 = dyn_cast<ImplicitCastExpr>(E2); + if (!CastE2) + return false; + if (!IsStructurallyEquivalent(Context, CastE1->getType(), + CastE2->getType())) + return false; + return IsStructurallyEquivalent(Context, CastE1->getSubExpr(), + CastE2->getSubExpr()); + } + // FIXME: Handle other kind of expressions! return true; } |