From 6d74b50085f7b47b394a691378680e7e24410d87 Mon Sep 17 00:00:00 2001 From: Gabor Horvath Date: Tue, 14 Nov 2017 11:30:38 +0000 Subject: [PATCH] [ASTImporter] TypeAliasTemplate and PackExpansion importing capability Patch by: Zoltan Gera! Differential Revision: https://reviews.llvm.org/D39247 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318147 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTImporter.cpp | 83 +++++++++++++++++++++++++++++++ unittests/AST/ASTImporterTest.cpp | 40 +++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index c92647770e..3ca13eb2ef 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -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(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 ConflictingDecls; + unsigned IDNS = Decl::IDNS_Ordinary; + SmallVector 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(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( + 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()) diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp index aea5bfa39e..7b41c5d579 100644 --- a/unittests/AST/ASTImporterTest.cpp +++ b/unittests/AST/ASTImporterTest.cpp @@ -486,5 +486,45 @@ TEST(ImportType, ImportAtomicType) { } +TEST(ImportType, ImportTypeAliasTemplate) { + MatchVerifier Verifier; + EXPECT_TRUE(testImport("template " + "struct dummy { static const int i = K; };" + "template using dummy2 = dummy;" + "int declToImport() { return dummy2<3>::i; }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionDecl( + hasBody( + compoundStmt( + has( + returnStmt( + has( + implicitCastExpr( + has( + declRefExpr())))))))))); +} + + +TEST(ImportType, ImportPackExpansion) { + MatchVerifier Verifier; + EXPECT_TRUE(testImport("template " + "struct dummy {" + " dummy(Args... args) {}" + " static const int i = 4;" + "};" + "int declToImport() { return dummy::i; }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionDecl( + hasBody( + compoundStmt( + has( + returnStmt( + has( + implicitCastExpr( + has( + declRefExpr())))))))))); +} + + } // end namespace ast_matchers } // end namespace clang -- 2.40.0