[ASTImporter] TypeAliasTemplate and PackExpansion importing capability

Patch by: Zoltan Gera!

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

llvm-svn: 318147
This commit is contained in:
Gabor Horvath 2017-11-14 11:30:38 +00:00
parent 21a42bcc0b
commit 7a91c08414
2 changed files with 123 additions and 0 deletions

View File

@ -77,6 +77,7 @@ namespace clang {
QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
QualType VisitElaboratedType(const ElaboratedType *T);
// FIXME: DependentNameType
QualType VisitPackExpansionType(const PackExpansionType *T);
// FIXME: DependentTemplateSpecializationType
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
QualType VisitObjCObjectType(const ObjCObjectType *T);
@ -149,6 +150,7 @@ namespace clang {
Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
Decl *VisitTypedefDecl(TypedefDecl *D);
Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
Decl *VisitLabelDecl(LabelDecl *D);
Decl *VisitEnumDecl(EnumDecl *D);
Decl *VisitRecordDecl(RecordDecl *D);
@ -265,6 +267,7 @@ namespace clang {
Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
@ -767,6 +770,15 @@ QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
ToQualifier, ToNamedType);
}
QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
QualType Pattern = Importer.Import(T->getPattern());
if (Pattern.isNull())
return QualType();
return Importer.getToContext().getPackExpansionType(Pattern,
T->getNumExpansions());
}
QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
ObjCInterfaceDecl *Class
= dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
@ -1487,6 +1499,63 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
return VisitTypedefNameDecl(D, /*IsAlias=*/true);
}
Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
// Import the major distinguishing characteristics of this typedef.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
return nullptr;
if (ToD)
return ToD;
// If this typedef is not in block scope, determine whether we've
// seen a typedef with the same name (that we can merge with) or any
// other entity by that name (which name lookup could conflict with).
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
continue;
if (auto *FoundAlias =
dyn_cast<TypeAliasTemplateDecl>(FoundDecls[I]))
return Importer.Imported(D, FoundAlias);
ConflictingDecls.push_back(FoundDecls[I]);
}
if (!ConflictingDecls.empty()) {
Name = Importer.HandleNameConflict(Name, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
return nullptr;
}
}
TemplateParameterList *Params = ImportTemplateParameterList(
D->getTemplateParameters());
if (!Params)
return nullptr;
NamedDecl *TemplDecl = cast_or_null<NamedDecl>(
Importer.Import(D->getTemplatedDecl()));
if (!TemplDecl)
return nullptr;
TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create(
Importer.getToContext(), DC, Loc, Name, Params, TemplDecl);
ToAlias->setAccess(D->getAccess());
ToAlias->setLexicalDeclContext(LexicalDC);
Importer.Imported(D, ToAlias);
LexicalDC->addDeclInternal(ToAlias);
return ToD;
}
Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
// Import the major distinguishing characteristics of this label.
DeclContext *DC, *LexicalDC;
@ -5180,6 +5249,20 @@ ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
return ToMTE;
}
Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
return nullptr;
Expr *Pattern = Importer.Import(E->getPattern());
if (!Pattern)
return nullptr;
return new (Importer.getToContext()) PackExpansionExpr(
T, Pattern, Importer.Import(E->getEllipsisLoc()),
E->getNumExpansions());
}
Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
QualType T = Importer.Import(CE->getType());
if (T.isNull())

View File

@ -486,5 +486,45 @@ TEST(ImportType, ImportAtomicType) {
}
TEST(ImportType, ImportTypeAliasTemplate) {
MatchVerifier<Decl> Verifier;
EXPECT_TRUE(testImport("template <int K>"
"struct dummy { static const int i = K; };"
"template <int K> using dummy2 = dummy<K>;"
"int declToImport() { return dummy2<3>::i; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionDecl(
hasBody(
compoundStmt(
has(
returnStmt(
has(
implicitCastExpr(
has(
declRefExpr()))))))))));
}
TEST(ImportType, ImportPackExpansion) {
MatchVerifier<Decl> Verifier;
EXPECT_TRUE(testImport("template <typename... Args>"
"struct dummy {"
" dummy(Args... args) {}"
" static const int i = 4;"
"};"
"int declToImport() { return dummy<int>::i; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
functionDecl(
hasBody(
compoundStmt(
has(
returnStmt(
has(
implicitCastExpr(
has(
declRefExpr()))))))))));
}
} // end namespace ast_matchers
} // end namespace clang