Author: spyffe Date: Mon May 16 15:48:03 2016 New Revision: 269693 URL: http://llvm.org/viewvc/llvm-project?rev=269693&view=rev Log: Added support to the ASTImporter for C++ constructor initializers. Also added named casts and propagation of "implicit" to fix the LLDB testsuite. This is a fixed commit of r269546, which was reverted by r269575.
Thanks to Aleksei Sidorin for review and advice. Added: cfe/trunk/test/ASTMerge/Inputs/init-ctors-classes.cpp cfe/trunk/test/ASTMerge/init-ctors.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=269693&r1=269692&r2=269693&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTImporter.h (original) +++ cfe/trunk/include/clang/AST/ASTImporter.h Mon May 16 15:48:03 2016 @@ -23,6 +23,7 @@ namespace clang { class ASTContext; + class CXXCtorInitializer; class Decl; class DeclContext; class DiagnosticsEngine; @@ -204,6 +205,14 @@ namespace clang { /// \returns the equivalent file ID in the source manager of the "to" /// context. FileID Import(FileID); + + /// \brief Import the given C++ constructor initializer from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent initializer in the "to" context. + CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); + + /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=269693&r1=269692&r2=269693&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon May 16 15:48:03 2016 @@ -252,6 +252,8 @@ namespace clang { Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); Expr *VisitInitListExpr(InitListExpr *E); + Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); + Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); template<typename IIter, typename OIter> void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) { @@ -3029,6 +3031,22 @@ Decl *ASTNodeImporter::VisitFunctionDecl D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()); + if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) { + SmallVector<CXXCtorInitializer *, 4> CtorInitializers; + for (CXXCtorInitializer *I : FromConstructor->inits()) { + CXXCtorInitializer *ToI = + cast_or_null<CXXCtorInitializer>(Importer.Import(I)); + if (!ToI && I) + return nullptr; + CtorInitializers.push_back(ToI); + } + CXXCtorInitializer **Memory = + new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; + std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); + CXXConstructorDecl *ToCtor = llvm::cast<CXXConstructorDecl>(ToFunction); + ToCtor->setCtorInitializers(Memory); + ToCtor->setNumCtorInitializers(NumInitializers); + } } else if (isa<CXXDestructorDecl>(D)) { ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), cast<CXXRecordDecl>(DC), @@ -5779,12 +5797,12 @@ Expr *ASTNodeImporter::VisitCXXConstruct return nullptr; NamedDecl *ToFound = - dyn_cast<NamedDecl>(Importer.Import(E->getFoundDecl())); + dyn_cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl())); if (!ToFound) return nullptr; CXXConstructorDecl *ToCCD = - dyn_cast<CXXConstructorDecl>(Importer.Import(E->getConstructor())); + dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor())); if (!ToCCD) return nullptr; @@ -5955,6 +5973,50 @@ Expr *ASTNodeImporter::VisitInitListExpr return To; } +Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { + FieldDecl *ToField = llvm::dyn_cast_or_null<FieldDecl>( + Importer.Import(DIE->getField())); + if (!ToField && DIE->getField()) + return nullptr; + + return CXXDefaultInitExpr::Create( + Importer.getToContext(), Importer.Import(DIE->getLocStart()), ToField); +} + +Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { + QualType ToType = Importer.Import(E->getType()); + if (ToType.isNull() && !E->getType().isNull()) + return nullptr; + ExprValueKind VK = E->getValueKind(); + CastKind CK = E->getCastKind(); + Expr *ToOp = Importer.Import(E->getSubExpr()); + if (!ToOp && E->getSubExpr()) + return nullptr; + CXXCastPath BasePath; + if (ImportCastPath(E, BasePath)) + return nullptr; + TypeSourceInfo *ToWritten = Importer.Import(E->getTypeInfoAsWritten()); + SourceLocation ToOperatorLoc = Importer.Import(E->getOperatorLoc()); + SourceLocation ToRParenLoc = Importer.Import(E->getRParenLoc()); + SourceRange ToAngleBrackets = Importer.Import(E->getAngleBrackets()); + + if (isa<CXXStaticCastExpr>(E)) { + return CXXStaticCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else if (isa<CXXDynamicCastExpr>(E)) { + return CXXDynamicCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else if (isa<CXXReinterpretCastExpr>(E)) { + return CXXReinterpretCastExpr::Create( + Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath, + ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets); + } else { + return nullptr; + } +} + ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport) @@ -6360,6 +6422,72 @@ FileID ASTImporter::Import(FileID FromID return ToID; } +CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) { + Expr *ToExpr = Import(From->getInit()); + if (!ToExpr && From->getInit()) + return nullptr; + + if (From->isBaseInitializer()) { + TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); + if (!ToTInfo && From->getTypeSourceInfo()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToTInfo, From->isBaseVirtual(), Import(From->getLParenLoc()), + ToExpr, Import(From->getRParenLoc()), + From->isPackExpansion() ? Import(From->getEllipsisLoc()) + : SourceLocation()); + } else if (From->isMemberInitializer()) { + FieldDecl *ToField = + llvm::cast_or_null<FieldDecl>(Import(From->getMember())); + if (!ToField && From->getMember()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); + } else if (From->isIndirectMemberInitializer()) { + IndirectFieldDecl *ToIField = llvm::cast_or_null<IndirectFieldDecl>( + Import(From->getIndirectMember())); + if (!ToIField && From->getIndirectMember()) + return nullptr; + + return new (ToContext) CXXCtorInitializer( + ToContext, ToIField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc())); + } else if (From->isDelegatingInitializer()) { + TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo()); + if (!ToTInfo && From->getTypeSourceInfo()) + return nullptr; + + return new (ToContext) + CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()), + ToExpr, Import(From->getRParenLoc())); + } else if (unsigned NumArrayIndices = From->getNumArrayIndices()) { + FieldDecl *ToField = + llvm::cast_or_null<FieldDecl>(Import(From->getMember())); + if (!ToField && From->getMember()) + return nullptr; + + SmallVector<VarDecl *, 4> ToAIs(NumArrayIndices); + + for (unsigned AII = 0; AII < NumArrayIndices; ++AII) { + VarDecl *ToArrayIndex = + dyn_cast_or_null<VarDecl>(Import(From->getArrayIndex(AII))); + if (!ToArrayIndex && From->getArrayIndex(AII)) + return nullptr; + } + + return CXXCtorInitializer::Create( + ToContext, ToField, Import(From->getMemberLocation()), + Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()), + ToAIs.data(), NumArrayIndices); + } else { + return nullptr; + } +} + + void ASTImporter::ImportDefinition(Decl *From) { Decl *To = Import(From); if (!To) @@ -6535,6 +6663,9 @@ Decl *ASTImporter::Imported(Decl *From, if (From->isUsed()) { To->setIsUsed(); } + if (From->isImplicit()) { + To->setImplicit(); + } ImportedDecls[From] = To; return To; } Added: cfe/trunk/test/ASTMerge/Inputs/init-ctors-classes.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/init-ctors-classes.cpp?rev=269693&view=auto ============================================================================== --- cfe/trunk/test/ASTMerge/Inputs/init-ctors-classes.cpp (added) +++ cfe/trunk/test/ASTMerge/Inputs/init-ctors-classes.cpp Mon May 16 15:48:03 2016 @@ -0,0 +1,19 @@ +class A_base +{ +public: + int x; + A_base() : x(0) { + } + A_base(int _x) : x(static_cast<int>(_x)) { + } +}; + +class A : public A_base +{ +public: + int y; + struct { int z; }; + int array[2]; + A(int _x) : A_base(_x), y(0), z(1), array{{2},{3}} { + } +}; Added: cfe/trunk/test/ASTMerge/init-ctors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/init-ctors.cpp?rev=269693&view=auto ============================================================================== --- cfe/trunk/test/ASTMerge/init-ctors.cpp (added) +++ cfe/trunk/test/ASTMerge/init-ctors.cpp Mon May 16 15:48:03 2016 @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/init-ctors-classes.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class B { + int method_1() { + A a(0); + return a.x; + } +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits