forked from OSchip/llvm-project
[ASTImporter] Add support to import some AST nodes:
* CXXOperatorCallExpr * SizeOfPackExpr * DependentTemplateSpecializationType * DependentSizedArray * CXXTypeidExpr * Fix importing CXXTemporaryObjectExpr Some of the changes are based on https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp Differential Revision: https://reviews.llvm.org/D42335 llvm-svn: 323589
This commit is contained in:
parent
1ae296da36
commit
c78d99a84b
|
@ -52,7 +52,7 @@ namespace clang {
|
|||
QualType VisitConstantArrayType(const ConstantArrayType *T);
|
||||
QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
|
||||
QualType VisitVariableArrayType(const VariableArrayType *T);
|
||||
// FIXME: DependentSizedArrayType
|
||||
QualType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
|
||||
// FIXME: DependentSizedExtVectorType
|
||||
QualType VisitVectorType(const VectorType *T);
|
||||
QualType VisitExtVectorType(const ExtVectorType *T);
|
||||
|
@ -78,7 +78,8 @@ namespace clang {
|
|||
QualType VisitElaboratedType(const ElaboratedType *T);
|
||||
// FIXME: DependentNameType
|
||||
QualType VisitPackExpansionType(const PackExpansionType *T);
|
||||
// FIXME: DependentTemplateSpecializationType
|
||||
QualType VisitDependentTemplateSpecializationType(
|
||||
const DependentTemplateSpecializationType *T);
|
||||
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
|
||||
QualType VisitObjCObjectType(const ObjCObjectType *T);
|
||||
QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
|
||||
|
@ -294,6 +295,7 @@ namespace clang {
|
|||
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
|
||||
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
|
||||
Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
|
||||
Expr *VisitSizeOfPackExpr(SizeOfPackExpr *E);
|
||||
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
|
||||
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
|
||||
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
|
||||
|
@ -315,6 +317,7 @@ namespace clang {
|
|||
Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
|
||||
Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
|
||||
Expr *VisitTypeTraitExpr(TypeTraitExpr *E);
|
||||
Expr *VisitCXXTypeidExpr(CXXTypeidExpr *E);
|
||||
|
||||
|
||||
template<typename IIter, typename OIter>
|
||||
|
@ -527,6 +530,24 @@ QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
|
|||
Brackets);
|
||||
}
|
||||
|
||||
QualType ASTNodeImporter::VisitDependentSizedArrayType(
|
||||
const DependentSizedArrayType *T) {
|
||||
QualType ToElementType = Importer.Import(T->getElementType());
|
||||
if (ToElementType.isNull())
|
||||
return QualType();
|
||||
|
||||
// SizeExpr may be null if size is not specified directly.
|
||||
// For example, 'int a[]'.
|
||||
Expr *Size = Importer.Import(T->getSizeExpr());
|
||||
if (!Size && T->getSizeExpr())
|
||||
return QualType();
|
||||
|
||||
SourceRange Brackets = Importer.Import(T->getBracketsRange());
|
||||
return Importer.getToContext().getDependentSizedArrayType(
|
||||
ToElementType, Size, T->getSizeModifier(), T->getIndexTypeCVRQualifiers(),
|
||||
Brackets);
|
||||
}
|
||||
|
||||
QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
|
||||
QualType ToElementType = Importer.Import(T->getElementType());
|
||||
if (ToElementType.isNull())
|
||||
|
@ -827,6 +848,25 @@ QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
|
|||
T->getNumExpansions());
|
||||
}
|
||||
|
||||
QualType ASTNodeImporter::VisitDependentTemplateSpecializationType(
|
||||
const DependentTemplateSpecializationType *T) {
|
||||
NestedNameSpecifier *Qualifier = Importer.Import(T->getQualifier());
|
||||
if (!Qualifier && T->getQualifier())
|
||||
return QualType();
|
||||
|
||||
IdentifierInfo *Name = Importer.Import(T->getIdentifier());
|
||||
if (!Name && T->getIdentifier())
|
||||
return QualType();
|
||||
|
||||
SmallVector<TemplateArgument, 2> ToPack;
|
||||
ToPack.reserve(T->getNumArgs());
|
||||
if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToPack))
|
||||
return QualType();
|
||||
|
||||
return Importer.getToContext().getDependentTemplateSpecializationType(
|
||||
T->getKeyword(), Qualifier, Name, ToPack);
|
||||
}
|
||||
|
||||
QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
|
||||
ObjCInterfaceDecl *Class
|
||||
= dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
|
||||
|
@ -5709,6 +5749,11 @@ Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
|
|||
if (T.isNull())
|
||||
return nullptr;
|
||||
|
||||
|
||||
TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo());
|
||||
if (!TInfo)
|
||||
return nullptr;
|
||||
|
||||
SmallVector<Expr *, 8> Args(CE->getNumArgs());
|
||||
if (ImportContainerChecked(CE->arguments(), Args))
|
||||
return nullptr;
|
||||
|
@ -5718,18 +5763,11 @@ Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
|
|||
if (!Ctor)
|
||||
return nullptr;
|
||||
|
||||
return CXXTemporaryObjectExpr::Create(
|
||||
Importer.getToContext(), T,
|
||||
Importer.Import(CE->getLocStart()),
|
||||
Ctor,
|
||||
CE->isElidable(),
|
||||
Args,
|
||||
CE->hadMultipleCandidates(),
|
||||
CE->isListInitialization(),
|
||||
CE->isStdInitListInitialization(),
|
||||
CE->requiresZeroInitialization(),
|
||||
CE->getConstructionKind(),
|
||||
Importer.Import(CE->getParenOrBraceRange()));
|
||||
return new (Importer.getToContext()) CXXTemporaryObjectExpr(
|
||||
Importer.getToContext(), Ctor, T, TInfo, Args,
|
||||
Importer.Import(CE->getParenOrBraceRange()), CE->hadMultipleCandidates(),
|
||||
CE->isListInitialization(), CE->isStdInitListInitialization(),
|
||||
CE->requiresZeroInitialization());
|
||||
}
|
||||
|
||||
Expr *
|
||||
|
@ -5769,6 +5807,31 @@ Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|||
E->getNumExpansions());
|
||||
}
|
||||
|
||||
Expr *ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
||||
auto *Pack = cast_or_null<NamedDecl>(Importer.Import(E->getPack()));
|
||||
if (!Pack)
|
||||
return nullptr;
|
||||
|
||||
Optional<unsigned> Length;
|
||||
|
||||
if (!E->isValueDependent())
|
||||
Length = E->getPackLength();
|
||||
|
||||
SmallVector<TemplateArgument, 8> PartialArguments;
|
||||
if (E->isPartiallySubstituted()) {
|
||||
if (ImportTemplateArguments(E->getPartialArguments().data(),
|
||||
E->getPartialArguments().size(),
|
||||
PartialArguments))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return SizeOfPackExpr::Create(
|
||||
Importer.getToContext(), Importer.Import(E->getOperatorLoc()), Pack,
|
||||
Importer.Import(E->getPackLoc()), Importer.Import(E->getRParenLoc()),
|
||||
Length, PartialArguments);
|
||||
}
|
||||
|
||||
|
||||
Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
|
||||
QualType T = Importer.Import(CE->getType());
|
||||
if (T.isNull())
|
||||
|
@ -6093,16 +6156,9 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
|
|||
return nullptr;
|
||||
|
||||
unsigned NumArgs = E->getNumArgs();
|
||||
|
||||
llvm::SmallVector<Expr *, 2> ToArgs(NumArgs);
|
||||
|
||||
for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) {
|
||||
Expr *FromArg = E->getArg(ai);
|
||||
Expr *ToArg = Importer.Import(FromArg);
|
||||
if (!ToArg)
|
||||
return nullptr;
|
||||
ToArgs[ai] = ToArg;
|
||||
}
|
||||
if (ImportContainerChecked(E->arguments(), ToArgs))
|
||||
return nullptr;
|
||||
|
||||
Expr **ToArgs_Copied = new (Importer.getToContext())
|
||||
Expr*[NumArgs];
|
||||
|
@ -6110,6 +6166,13 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
|
|||
for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai)
|
||||
ToArgs_Copied[ai] = ToArgs[ai];
|
||||
|
||||
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
|
||||
return new (Importer.getToContext()) CXXOperatorCallExpr(
|
||||
Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, T,
|
||||
OCE->getValueKind(), Importer.Import(OCE->getRParenLoc()),
|
||||
OCE->getFPFeatures());
|
||||
}
|
||||
|
||||
return new (Importer.getToContext())
|
||||
CallExpr(Importer.getToContext(), ToCallee,
|
||||
llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(),
|
||||
|
@ -6336,6 +6399,28 @@ Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
|||
E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue);
|
||||
}
|
||||
|
||||
Expr *ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
||||
QualType ToType = Importer.Import(E->getType());
|
||||
if (ToType.isNull())
|
||||
return nullptr;
|
||||
|
||||
if (E->isTypeOperand()) {
|
||||
TypeSourceInfo *TSI = Importer.Import(E->getTypeOperandSourceInfo());
|
||||
if (!TSI)
|
||||
return nullptr;
|
||||
|
||||
return new (Importer.getToContext())
|
||||
CXXTypeidExpr(ToType, TSI, Importer.Import(E->getSourceRange()));
|
||||
}
|
||||
|
||||
Expr *Op = Importer.Import(E->getExprOperand());
|
||||
if (!Op)
|
||||
return nullptr;
|
||||
|
||||
return new (Importer.getToContext())
|
||||
CXXTypeidExpr(ToType, Op, Importer.Import(E->getSourceRange()));
|
||||
}
|
||||
|
||||
void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
|
||||
CXXMethodDecl *FromMethod) {
|
||||
for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
|
||||
|
|
|
@ -484,6 +484,16 @@ TEST(ImportExpr, ImportVAArgExpr) {
|
|||
vaArgExpr())))))));
|
||||
}
|
||||
|
||||
TEST(ImportExpr, CXXTemporaryObjectExpr) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("struct C {};"
|
||||
"void declToImport() { C c = C(); }",
|
||||
Lang_CXX, "", Lang_CXX, Verifier,
|
||||
functionDecl(hasBody(compoundStmt(has(
|
||||
declStmt(has(varDecl(has(exprWithCleanups(has(cxxConstructExpr(
|
||||
has(materializeTemporaryExpr(has(implicitCastExpr(
|
||||
has(cxxTemporaryObjectExpr())))))))))))))))));
|
||||
}
|
||||
|
||||
TEST(ImportType, ImportAtomicType) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
|
@ -568,6 +578,50 @@ TEST(ImportType, ImportPackExpansion) {
|
|||
declRefExpr())))))))));
|
||||
}
|
||||
|
||||
const internal::VariadicDynCastAllOfMatcher<Type,
|
||||
DependentTemplateSpecializationType>
|
||||
dependentTemplateSpecializationType;
|
||||
|
||||
TEST(ImportType, ImportDependentTemplateSpecialization) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("template<typename T>"
|
||||
"struct A;"
|
||||
"template<typename T>"
|
||||
"struct declToImport {"
|
||||
" typename A<T>::template B<T> a;"
|
||||
"};",
|
||||
Lang_CXX, "", Lang_CXX, Verifier,
|
||||
classTemplateDecl(has(cxxRecordDecl(has(
|
||||
fieldDecl(hasType(dependentTemplateSpecializationType())))))));
|
||||
}
|
||||
|
||||
const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
|
||||
sizeOfPackExpr;
|
||||
|
||||
TEST(ImportExpr, ImportSizeOfPackExpr) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("template <typename... Ts>"
|
||||
"void declToImport() {"
|
||||
" const int i = sizeof...(Ts);"
|
||||
"};"
|
||||
"void g() { declToImport<int>(); }",
|
||||
Lang_CXX11, "", Lang_CXX11, Verifier,
|
||||
functionTemplateDecl(has(functionDecl(
|
||||
hasBody(compoundStmt(has(declStmt(has(varDecl(hasInitializer(
|
||||
implicitCastExpr(has(sizeOfPackExpr())))))))))))));
|
||||
testImport(
|
||||
"template <typename... Ts>"
|
||||
"using X = int[sizeof...(Ts)];"
|
||||
"template <typename... Us>"
|
||||
"struct Y {"
|
||||
" X<Us..., int, double, int, Us...> f;"
|
||||
"};"
|
||||
"Y<float, int> declToImport;",
|
||||
Lang_CXX11, "", Lang_CXX11, Verifier,
|
||||
varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType(
|
||||
hasUnqualifiedDesugaredType(constantArrayType(hasSize(7))))))))));
|
||||
}
|
||||
|
||||
/// \brief Matches __builtin_types_compatible_p:
|
||||
/// GNU extension to check equivalent types
|
||||
/// Given
|
||||
|
@ -590,6 +644,24 @@ TEST(ImportExpr, ImportTypeTraitExpr) {
|
|||
typeTraitExpr(hasType(asString("int"))))))));
|
||||
}
|
||||
|
||||
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr;
|
||||
|
||||
TEST(ImportExpr, ImportCXXTypeidExpr) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport(
|
||||
"namespace std { class type_info {}; }"
|
||||
"void declToImport() {"
|
||||
" int x;"
|
||||
" auto a = typeid(int); auto b = typeid(x);"
|
||||
"}",
|
||||
Lang_CXX11, "", Lang_CXX11, Verifier,
|
||||
functionDecl(
|
||||
hasDescendant(varDecl(
|
||||
hasName("a"), hasInitializer(hasDescendant(cxxTypeidExpr())))),
|
||||
hasDescendant(varDecl(
|
||||
hasName("b"), hasInitializer(hasDescendant(cxxTypeidExpr()))))));
|
||||
}
|
||||
|
||||
TEST(ImportExpr, ImportTypeTraitExprValDep) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("template<typename T> struct declToImport {"
|
||||
|
@ -712,5 +784,25 @@ TEST(ImportDecl, ImportTemplatedDeclForTemplate) {
|
|||
unless(has(cxxRecordDecl(hasName("declToImport"))))))));
|
||||
}
|
||||
|
||||
TEST(ImportExpr, CXXOperatorCallExpr) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("class declToImport {"
|
||||
" void f() { *this = declToImport(); }"
|
||||
"};",
|
||||
Lang_CXX, "", Lang_CXX, Verifier,
|
||||
cxxRecordDecl(has(cxxMethodDecl(hasBody(compoundStmt(
|
||||
has(exprWithCleanups(has(cxxOperatorCallExpr())))))))));
|
||||
}
|
||||
|
||||
TEST(ImportExpr, DependentSizedArrayType) {
|
||||
MatchVerifier<Decl> Verifier;
|
||||
testImport("template<typename T, int Size> class declToImport {"
|
||||
" T data[Size];"
|
||||
"};",
|
||||
Lang_CXX, "", Lang_CXX, Verifier,
|
||||
classTemplateDecl(has(cxxRecordDecl(
|
||||
has(fieldDecl(hasType(dependentSizedArrayType())))))));
|
||||
}
|
||||
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
|
|
Loading…
Reference in New Issue