[ASTImporter] Support importing UnresolvedMemberExpr, DependentNameType, DependentScopeDeclRefExpr

The visit callback implementations for the 3 C++ AST Node added to the ASTImporter.

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

llvm-svn: 331630
This commit is contained in:
Peter Szecsi 2018-05-07 12:08:27 +00:00
parent f3ae50fca2
commit ce7f318f21
2 changed files with 141 additions and 1 deletions

View File

@ -121,7 +121,7 @@ namespace clang {
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 @@ namespace clang {
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 @@ QualType ASTNodeImporter::VisitDependentTemplateSpecializationType(
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<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
@ -6187,6 +6208,29 @@ Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
cast_or_null<NamedDecl>(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 @@ Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
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<NamedDecl>(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())

View File

@ -1709,5 +1709,60 @@ TEST(ImportDecl, ImportEnumSequential) {
"main.c", enumDecl(), VerificationMatcher);
}
const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr>
dependentScopeDeclRefExpr;
TEST(ImportExpr, DependentScopeDeclRefExpr) {
MatchVerifier<Decl> Verifier;
testImport("template <typename T> struct S { static T foo; };"
"template <typename T> void declToImport() {"
" (void) S<T>::foo;"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionTemplateDecl(has(functionDecl(has(compoundStmt(
has(cStyleCastExpr(has(dependentScopeDeclRefExpr())))))))));
testImport("template <typename T> struct S {"
"template<typename S> static void foo(){};"
"};"
"template <typename T> void declToImport() {"
" S<T>::template foo<T>();"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionTemplateDecl(has(functionDecl(has(compoundStmt(
has(callExpr(has(dependentScopeDeclRefExpr())))))))));
}
const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType>
dependentNameType;
TEST(ImportExpr, DependentNameType) {
MatchVerifier<Decl> Verifier;
testImport("template <typename T> struct declToImport {"
" typedef typename T::type dependent_name;"
"};",
Lang_CXX11, "", Lang_CXX11, Verifier,
classTemplateDecl(has(
cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
}
const internal::VariadicDynCastAllOfMatcher<Expr, UnresolvedMemberExpr>
unresolvedMemberExpr;
TEST(ImportExpr, UnresolvedMemberExpr) {
MatchVerifier<Decl> Verifier;
testImport("struct S { template <typename T> void mem(); };"
"template <typename U> void declToImport() {"
" S s;"
" s.mem<U>();"
"}"
"void instantiate() { declToImport<int>(); }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionTemplateDecl(has(functionDecl(has(
compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
}
} // end namespace ast_matchers
} // end namespace clang