szepet created this revision.
This patch adds support for importing two different kind of C++ AST Node.
Note: This solution is based on
https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp#L7605
.
https://reviews.llvm.org/D38694
Files:
lib/AST/ASTImporter.cpp
unittests/AST/ASTImporterTest.cpp
Index: unittests/AST/ASTImporterTest.cpp
===================================================================
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -457,7 +457,6 @@
vaArgExpr()))))))));
}
-
TEST(ImportType, ImportAtomicType) {
MatchVerifier<Decl> Verifier;
EXPECT_TRUE(testImport("void declToImport() { typedef _Atomic(int) a_int; }",
@@ -502,5 +501,39 @@
has(cxxDependentScopeMemberExpr()))))))));
}
+TEST(ImportExpr, ImportUnresolvedLookupExpr) {
+ MatchVerifier<Decl> Verifier;
+ EXPECT_TRUE(testImport("template<typename T> int foo();"
+ "template <typename T> void declToImport() {"
+ " ::foo<T>;"
+ " ::template foo<T>;"
+ "}",
+ Lang_CXX, "", Lang_CXX, Verifier,
+ functionTemplateDecl(has(functionDecl(has(
+ compoundStmt(has(unresolvedLookupExpr()))))))));
+}
+
+TEST(ImportExpr, ImportCXXUnresolvedConstructExpr) {
+ MatchVerifier<Decl> Verifier;
+ EXPECT_TRUE(
+ testImport("template <typename T> class C { T t; };"
+ "template <typename T> void declToImport() {"
+ "C<T> d;"
+ "d.t = T()"
+ "}",
+ Lang_CXX, "", Lang_CXX, Verifier,
+ functionTemplateDecl(has(functionDecl(has(compoundStmt(has(
+ binaryOperator(has(cxxUnresolvedConstructExpr()))))))))));
+ EXPECT_TRUE(
+ testImport("template <typename T> class C { T t; };"
+ "template <typename T> void declToImport() {"
+ "C<T> 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
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<Expr *, 2> 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<CXXRecordDecl>(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<NamedDecl>(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())
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits