spyffe created this revision. spyffe added reviewers: sepavloff, a.sidorin. spyffe added a subscriber: cfe-commits. spyffe set the repository for this revision to rL LLVM. spyffe added a project: clang-c.
The AST importer currently does not handle injected class names properly (it does not bind their types to the type of the parent as the parser would) and it doesn't handle constructor initializers at all. This patch adds support for both of those, and also forwards the `isImplicit()` and `isReferenced()` flags for *all* declarations as is done for `isUsed()`. Repository: rL LLVM http://reviews.llvm.org/D20118 Files: include/clang/AST/ASTImporter.h lib/AST/ASTImporter.cpp
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<CXXRecordDecl>(DC)); } else { D2CXX = CXXRecordDecl::Create(Importer.getToContext(), D->getTagKind(), @@ -3018,6 +3030,22 @@ D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()); + SmallVector<CXXCtorInitializer *, 4> CtorInitializers; + for (const CXXCtorInitializer *I : FromConstructor->inits()) { + CXXCtorInitializer *ToI =cast_or_null<CXXCtorInitializer>( + 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<CXXConstructorDecl>(ToFunction)->setCtorInitializers(Memory); + llvm::cast<CXXConstructorDecl>(ToFunction)->setNumCtorInitializers( + NumInitializers); + } } else if (isa<CXXDestructorDecl>(D)) { ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), cast<CXXRecordDecl>(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<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 { + 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; } 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits