Index: include/clang/AST/ASTImporter.h =================================================================== --- include/clang/AST/ASTImporter.h +++ include/clang/AST/ASTImporter.h @@ -23,6 +23,7 @@ namespace clang { class ASTContext; + class CXXCtorInitializer; class Decl; class DeclContext; class DiagnosticsEngine; @@ -204,6 +205,12 @@ /// \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(const CXXCtorInitializer *FromInit); /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2820,6 +2820,18 @@ return nullptr; D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), CDecl); + } else if (DCXX->isInjectedClassName()) { + // We have to be careful to do a similar dance to the one in + // Sema::ActOnStartCXXMemberDeclarations + CXXRecordDecl * const PrevDecl = nullptr; + const bool DelayTypeCreation = true; + D2CXX = CXXRecordDecl::Create(Importer.getToContext(), + D->getTagKind(), + DC, StartLoc, Loc, + Name.getAsIdentifierInfo(), + PrevDecl, DelayTypeCreation); + Importer.getToContext().getTypeDeclType( + D2CXX, llvm::dyn_cast(DC)); } else { D2CXX = CXXRecordDecl::Create(Importer.getToContext(), D->getTagKind(), @@ -3018,6 +3030,22 @@ D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()); + SmallVector CtorInitializers; + for (const CXXCtorInitializer *I : FromConstructor->inits()) { + CXXCtorInitializer *ToI =cast_or_null( + Importer.Import(I)); + if (!ToI && I) + return nullptr; + CtorInitializers.push_back(ToI); + } + if (unsigned NumInitializers = CtorInitializers.size()) { + CXXCtorInitializer **Memory = new (Importer.getToContext()) + CXXCtorInitializer*[NumInitializers]; + std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); + llvm::cast(ToFunction)->setCtorInitializers(Memory); + llvm::cast(ToFunction)->setNumCtorInitializers( + NumInitializers); + } } else if (isa(D)) { ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), cast(DC), @@ -6344,6 +6372,58 @@ return ToID; } +CXXCtorInitializer *ASTImporter::Import(const 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(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(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 { + return nullptr; + } +} + void ASTImporter::ImportDefinition(Decl *From) { Decl *To = Import(From); if (!To) @@ -6514,6 +6594,12 @@ if (From->isUsed()) { To->setIsUsed(); } + if (From->isImplicit()) { + To->setImplicit(); + } + if (From->isReferenced()) { + To->setReferenced(); + } ImportedDecls[From] = To; return To; }