Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -273,6 +273,8 @@ Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); + Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE); + Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -5464,6 +5466,80 @@ MemberNameInfo, ResInfo); } +Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr( + CXXUnresolvedConstructExpr *CE) { + + unsigned NumArgs = CE->arg_size(); + + llvm::SmallVector ToArgs(NumArgs); + + for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) { + Expr *FromArg = CE->getArg(ai); + Expr *ToArg = Importer.Import(FromArg); + if (!ToArg) + return nullptr; + ToArgs[ai] = ToArg; + } + + Expr **ToArgs_Copied = new (Importer.getToContext()) Expr *[NumArgs]; + + for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) + ToArgs_Copied[ai] = ToArgs[ai]; + + return CXXUnresolvedConstructExpr::Create( + Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()), + Importer.Import(CE->getLParenLoc()), + llvm::makeArrayRef(ToArgs_Copied, NumArgs), + Importer.Import(CE->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { + CXXRecordDecl *NamingClass = + cast_or_null(Importer.Import(E->getNamingClass())); + if (E->getNamingClass() && !NamingClass) + return nullptr; + + 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); + + 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()) { + for (const auto &FromLoc : E->template_arguments()) { + bool Error = false; + TemplateArgumentLoc ToTALoc = ImportTemplateArgumentLoc(FromLoc, Error); + if (Error) + return nullptr; + ToTAInfo.addArgument(ToTALoc); + } + ResInfo = &ToTAInfo; + } + + if (ResInfo || E->getTemplateKeywordLoc().isValid()) + return UnresolvedLookupExpr::Create( + Importer.getToContext(), NamingClass, + Importer.Import(E->getQualifierLoc()), + Importer.Import(E->getTemplateKeywordLoc()), NameInfo, E->requiresADL(), + ResInfo, ToDecls.begin(), ToDecls.end()); + + return UnresolvedLookupExpr::Create( + Importer.getToContext(), NamingClass, + Importer.Import(E->getQualifierLoc()), NameInfo, E->requiresADL(), + E->isOverloaded(), 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 @@ -457,7 +457,6 @@ vaArgExpr())))))))); } - TEST(ImportType, ImportAtomicType) { MatchVerifier Verifier; EXPECT_TRUE(testImport("void declToImport() { typedef _Atomic(int) a_int; }", @@ -502,5 +501,39 @@ has(cxxDependentScopeMemberExpr())))))))); } +TEST(ImportExpr, ImportUnresolvedLookupExpr) { + MatchVerifier Verifier; + EXPECT_TRUE(testImport("template int foo();" + "template void declToImport() {" + " ::foo;" + " ::template foo;" + "}", + Lang_CXX, "", Lang_CXX, Verifier, + functionTemplateDecl(has(functionDecl(has( + compoundStmt(has(unresolvedLookupExpr())))))))); +} + +TEST(ImportExpr, ImportCXXUnresolvedConstructExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("template class C { T t; };" + "template void declToImport() {" + "C d;" + "d.t = T()" + "}", + Lang_CXX, "", Lang_CXX, Verifier, + functionTemplateDecl(has(functionDecl(has(compoundStmt(has( + binaryOperator(has(cxxUnresolvedConstructExpr())))))))))); + EXPECT_TRUE( + testImport("template class C { T t; };" + "template void declToImport() {" + "C d;" + "(&d)->t = T()" + "}", + Lang_CXX, "", Lang_CXX, Verifier, + functionTemplateDecl(has(functionDecl(has(compoundStmt(has( + binaryOperator(has(cxxUnresolvedConstructExpr())))))))))); +} + } // end namespace ast_matchers } // end namespace clang