Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -52,7 +52,7 @@ 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 @@ 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 @@ 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 @@ Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E); Expr *VisitTypeTraitExpr(TypeTraitExpr *E); + Expr *VisitCXXTypeidExpr(CXXTypeidExpr *E); template @@ -527,6 +530,24 @@ 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 @@ 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 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(Importer.Import(T->getDecl())); @@ -5709,6 +5749,11 @@ if (T.isNull()) return nullptr; + + TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo()); + if (!TInfo) + return nullptr; + SmallVector Args(CE->getNumArgs()); if (ImportContainerChecked(CE->arguments(), Args)) return nullptr; @@ -5718,18 +5763,11 @@ 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 @@ E->getNumExpansions()); } +Expr *ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { + auto *Pack = cast_or_null(Importer.Import(E->getPack())); + if (!Pack) + return nullptr; + + Optional Length; + + if (!E->isValueDependent()) + Length = E->getPackLength(); + + SmallVector 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 @@ return nullptr; unsigned NumArgs = E->getNumArgs(); - llvm::SmallVector 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 @@ for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) ToArgs_Copied[ai] = ToArgs[ai]; + if (const auto *OCE = dyn_cast(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 @@ 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()) Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -484,6 +484,16 @@ vaArgExpr()))))))); } +TEST(ImportExpr, CXXTemporaryObjectExpr) { + MatchVerifier 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 Verifier; @@ -568,6 +578,50 @@ declRefExpr()))))))))); } +const internal::VariadicDynCastAllOfMatcher + dependentTemplateSpecializationType; + +TEST(ImportType, ImportDependentTemplateSpecialization) { + MatchVerifier Verifier; + testImport("template" + "struct A;" + "template" + "struct declToImport {" + " typename A::template B a;" + "};", + Lang_CXX, "", Lang_CXX, Verifier, + classTemplateDecl(has(cxxRecordDecl(has( + fieldDecl(hasType(dependentTemplateSpecializationType()))))))); +} + +const internal::VariadicDynCastAllOfMatcher + sizeOfPackExpr; + +TEST(ImportExpr, ImportSizeOfPackExpr) { + MatchVerifier Verifier; + testImport("template " + "void declToImport() {" + " const int i = sizeof...(Ts);" + "};" + "void g() { declToImport(); }", + Lang_CXX11, "", Lang_CXX11, Verifier, + functionTemplateDecl(has(functionDecl( + hasBody(compoundStmt(has(declStmt(has(varDecl(hasInitializer( + implicitCastExpr(has(sizeOfPackExpr()))))))))))))); + testImport( + "template " + "using X = int[sizeof...(Ts)];" + "template " + "struct Y {" + " X f;" + "};" + "Y 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 @@ typeTraitExpr(hasType(asString("int")))))))); } +const internal::VariadicDynCastAllOfMatcher cxxTypeidExpr; + +TEST(ImportExpr, ImportCXXTypeidExpr) { + MatchVerifier 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 Verifier; testImport("template struct declToImport {" @@ -712,5 +784,25 @@ unless(has(cxxRecordDecl(hasName("declToImport")))))))); } +TEST(ImportExpr, CXXOperatorCallExpr) { + MatchVerifier 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 Verifier; + testImport("template class declToImport {" + " T data[Size];" + "};", + Lang_CXX, "", Lang_CXX, Verifier, + classTemplateDecl(has(cxxRecordDecl( + has(fieldDecl(hasType(dependentSizedArrayType()))))))); +} + } // end namespace ast_matchers } // end namespace clang