Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -121,7 +121,7 @@ QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T); QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); QualType VisitElaboratedType(const ElaboratedType *T); - // FIXME: DependentNameType + QualType VisitDependentNameType(const DependentNameType *T); QualType VisitPackExpansionType(const PackExpansionType *T); QualType VisitDependentTemplateSpecializationType( const DependentTemplateSpecializationType *T); @@ -347,8 +347,10 @@ Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); + Expr *VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE); Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); + Expr *VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -938,6 +940,25 @@ T->getKeyword(), Qualifier, Name, ToPack); } +QualType ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) { + NestedNameSpecifier *NNS = Importer.Import(T->getQualifier()); + if (!NNS && T->getQualifier()) + return QualType(); + + IdentifierInfo *Name = Importer.Import(T->getIdentifier()); + if (!Name && T->getIdentifier()) + return QualType(); + + QualType Canon = (T == T->getCanonicalTypeInternal().getTypePtr()) + ? QualType() + : Importer.Import(T->getCanonicalTypeInternal()); + if (!Canon.isNull()) + Canon = Canon.getCanonicalType(); + + return Importer.getToContext().getDependentNameType(T->getKeyword(), NNS, + Name, Canon); +} + QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { auto *Class = dyn_cast_or_null(Importer.Import(T->getDecl())); @@ -6187,6 +6208,29 @@ cast_or_null(ToFQ), MemberNameInfo, ResInfo); } +Expr * +ASTNodeImporter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + DeclarationName Name = Importer.Import(E->getDeclName()); + if (!E->getDeclName().isEmpty() && Name.isEmpty()) + return nullptr; + + DeclarationNameInfo NameInfo(Name, Importer.Import(E->getExprLoc())); + ImportDeclarationNameLoc(E->getNameInfo(), NameInfo); + + TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()), + Importer.Import(E->getRAngleLoc())); + TemplateArgumentListInfo *ResInfo = nullptr; + if (E->hasExplicitTemplateArgs()) { + if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) + return nullptr; + ResInfo = &ToTAInfo; + } + + return DependentScopeDeclRefExpr::Create( + Importer.getToContext(), Importer.Import(E->getQualifierLoc()), + Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo); +} + Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr( CXXUnresolvedConstructExpr *CE) { unsigned NumArgs = CE->arg_size(); @@ -6244,6 +6288,47 @@ E->isOverloaded(), ToDecls.begin(), ToDecls.end()); } +Expr *ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { + DeclarationName Name = Importer.Import(E->getName()); + if (!E->getName().isEmpty() && Name.isEmpty()) + return nullptr; + DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc())); + // Import additional name location/type info. + ImportDeclarationNameLoc(E->getNameInfo(), NameInfo); + + QualType BaseType = Importer.Import(E->getType()); + if (!E->getType().isNull() && BaseType.isNull()) + return nullptr; + + UnresolvedSet<8> ToDecls; + for (Decl *D : E->decls()) { + if (NamedDecl *To = cast_or_null(Importer.Import(D))) + ToDecls.addDecl(To); + else + return nullptr; + } + + TemplateArgumentListInfo ToTAInfo; + TemplateArgumentListInfo *ResInfo = nullptr; + if (E->hasExplicitTemplateArgs()) { + if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) + return nullptr; + ResInfo = &ToTAInfo; + } + + Expr *BaseE = E->isImplicitAccess() ? nullptr : Importer.Import(E->getBase()); + if (!BaseE && !E->isImplicitAccess() && E->getBase()) { + return nullptr; + } + + return UnresolvedMemberExpr::Create( + Importer.getToContext(), E->hasUnresolvedUsing(), BaseE, BaseType, + E->isArrow(), Importer.Import(E->getOperatorLoc()), + Importer.Import(E->getQualifierLoc()), + Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo, + ToDecls.begin(), ToDecls.end()); +} + Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1709,5 +1709,60 @@ "main.c", enumDecl(), VerificationMatcher); } +const internal::VariadicDynCastAllOfMatcher + dependentScopeDeclRefExpr; + +TEST(ImportExpr, DependentScopeDeclRefExpr) { + MatchVerifier Verifier; + testImport("template struct S { static T foo; };" + "template void declToImport() {" + " (void) S::foo;" + "}" + "void instantiate() { declToImport(); }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionTemplateDecl(has(functionDecl(has(compoundStmt( + has(cStyleCastExpr(has(dependentScopeDeclRefExpr()))))))))); + + testImport("template struct S {" + "template static void foo(){};" + "};" + "template void declToImport() {" + " S::template foo();" + "}" + "void instantiate() { declToImport(); }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionTemplateDecl(has(functionDecl(has(compoundStmt( + has(callExpr(has(dependentScopeDeclRefExpr()))))))))); +} + +const internal::VariadicDynCastAllOfMatcher + dependentNameType; + +TEST(ImportExpr, DependentNameType) { + MatchVerifier Verifier; + testImport("template struct declToImport {" + " typedef typename T::type dependent_name;" + "};", + Lang_CXX11, "", Lang_CXX11, Verifier, + classTemplateDecl(has( + cxxRecordDecl(has(typedefDecl(has(dependentNameType()))))))); +} + +const internal::VariadicDynCastAllOfMatcher + unresolvedMemberExpr; + +TEST(ImportExpr, UnresolvedMemberExpr) { + MatchVerifier Verifier; + testImport("struct S { template void mem(); };" + "template void declToImport() {" + " S s;" + " s.mem();" + "}" + "void instantiate() { declToImport(); }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionTemplateDecl(has(functionDecl(has( + compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); +} + } // end namespace ast_matchers } // end namespace clang