forked from OSchip/llvm-project
[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:
parent
21a42bcc0b
commit
7a91c08414
|
@ -77,6 +77,7 @@ namespace clang {
|
||||||
QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
|
QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
|
||||||
QualType VisitElaboratedType(const ElaboratedType *T);
|
QualType VisitElaboratedType(const ElaboratedType *T);
|
||||||
// FIXME: DependentNameType
|
// FIXME: DependentNameType
|
||||||
|
QualType VisitPackExpansionType(const PackExpansionType *T);
|
||||||
// FIXME: DependentTemplateSpecializationType
|
// FIXME: DependentTemplateSpecializationType
|
||||||
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
|
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
|
||||||
QualType VisitObjCObjectType(const ObjCObjectType *T);
|
QualType VisitObjCObjectType(const ObjCObjectType *T);
|
||||||
|
@ -149,6 +150,7 @@ namespace clang {
|
||||||
Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
|
Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
|
||||||
Decl *VisitTypedefDecl(TypedefDecl *D);
|
Decl *VisitTypedefDecl(TypedefDecl *D);
|
||||||
Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
|
Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
|
||||||
|
Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
|
||||||
Decl *VisitLabelDecl(LabelDecl *D);
|
Decl *VisitLabelDecl(LabelDecl *D);
|
||||||
Decl *VisitEnumDecl(EnumDecl *D);
|
Decl *VisitEnumDecl(EnumDecl *D);
|
||||||
Decl *VisitRecordDecl(RecordDecl *D);
|
Decl *VisitRecordDecl(RecordDecl *D);
|
||||||
|
@ -265,6 +267,7 @@ namespace clang {
|
||||||
Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
|
Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
|
||||||
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
|
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
|
||||||
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
|
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
|
||||||
|
Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
|
||||||
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
|
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
|
||||||
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
|
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
|
||||||
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
|
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
|
||||||
|
@ -767,6 +770,15 @@ QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
|
||||||
ToQualifier, ToNamedType);
|
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) {
|
QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
|
||||||
ObjCInterfaceDecl *Class
|
ObjCInterfaceDecl *Class
|
||||||
= dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
|
= dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
|
||||||
|
@ -1487,6 +1499,63 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
|
||||||
return VisitTypedefNameDecl(D, /*IsAlias=*/true);
|
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) {
|
Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
|
||||||
// Import the major distinguishing characteristics of this label.
|
// Import the major distinguishing characteristics of this label.
|
||||||
DeclContext *DC, *LexicalDC;
|
DeclContext *DC, *LexicalDC;
|
||||||
|
@ -5180,6 +5249,20 @@ ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
||||||
return ToMTE;
|
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) {
|
Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
|
||||||
QualType T = Importer.Import(CE->getType());
|
QualType T = Importer.Import(CE->getType());
|
||||||
if (T.isNull())
|
if (T.isNull())
|
||||||
|
|
|
@ -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 ast_matchers
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
Loading…
Reference in New Issue