[ASTImporter] Support importing CXXUnresolvedConstructExpr and UnresolvedLookupExpr

* Note: This solution is based on
  https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp#L7605.

Patch by Peter Szecsi!

Differential Revision: https://reviews.llvm.org/D38694

llvm-svn: 322091
This commit is contained in:
Aleksei Sidorin 2018-01-09 16:40:40 +00:00
parent 72b0bb1405
commit e267a0f342
2 changed files with 96 additions and 0 deletions

View File

@ -287,6 +287,8 @@ namespace clang {
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);
@ -5887,6 +5889,65 @@ Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
}
Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
CXXUnresolvedConstructExpr *CE) {
unsigned NumArgs = CE->arg_size();
llvm::SmallVector<Expr *, 8> ToArgs(NumArgs);
if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin()))
return nullptr;
return CXXUnresolvedConstructExpr::Create(
Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()),
Importer.Import(CE->getLParenLoc()), llvm::makeArrayRef(ToArgs),
Importer.Import(CE->getRParenLoc()));
}
Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
CXXRecordDecl *NamingClass =
cast_or_null<CXXRecordDecl>(Importer.Import(E->getNamingClass()));
if (E->getNamingClass() && !NamingClass)
return nullptr;
DeclarationName Name = Importer.Import(E->getName());
if (E->getName() && !Name)
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<NamedDecl>(Importer.Import(D)))
ToDecls.addDecl(To);
else
return nullptr;
}
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;
}
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())

View File

@ -656,5 +656,40 @@ TEST(ImportDecl, ImportUsingShadowDecl) {
namespaceDecl(has(usingShadowDecl())));
}
TEST(ImportExpr, ImportUnresolvedLookupExpr) {
MatchVerifier<Decl> Verifier;
testImport("template<typename T> int foo();"
"template <typename T> void declToImport() {"
" ::foo<T>;"
" ::template foo<T>;"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX, "", Lang_CXX, Verifier,
functionTemplateDecl(has(functionDecl(has(
compoundStmt(has(unresolvedLookupExpr())))))));
}
TEST(ImportExpr, ImportCXXUnresolvedConstructExpr) {
MatchVerifier<Decl> Verifier;
testImport("template <typename T> class C { T t; };"
"template <typename T> void declToImport() {"
" C<T> d;"
" d.t = T();"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX, "", Lang_CXX, Verifier,
functionTemplateDecl(has(functionDecl(has(compoundStmt(has(
binaryOperator(has(cxxUnresolvedConstructExpr())))))))));
testImport("template <typename T> class C { T t; };"
"template <typename T> void declToImport() {"
" C<T> d;"
" (&d)->t = T();"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX, "", Lang_CXX, Verifier,
functionTemplateDecl(has(functionDecl(has(compoundStmt(has(
binaryOperator(has(cxxUnresolvedConstructExpr())))))))));
}
} // end namespace ast_matchers
} // end namespace clang