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); @@ -282,6 +283,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); @@ -514,6 +516,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()) @@ -814,6 +834,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())); @@ -5572,6 +5611,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; @@ -5581,18 +5625,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 * @@ -5632,6 +5669,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()) @@ -5958,16 +6020,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]; @@ -5975,6 +6030,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(), Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -480,6 +480,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; @@ -564,6 +574,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 @@ -691,5 +745,25 @@ binaryOperator(has(cxxUnresolvedConstructExpr()))))))))); } +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