Author: spyffe Date: Mon Mar 28 16:43:01 2016 New Revision: 264669 URL: http://llvm.org/viewvc/llvm-project?rev=264669&view=rev Log: Improvements to the ASTImporter to support LLDB top-level Clang expressions.
The testcase for this is in LLDB, adeed by r264662. This patch adds support for a variety of new expression types to the AST importer, mostly related to C++. It also adds support for importing lambdas correctly, and adds support for importing the attributes attached to any Decl. Finally, the patch adds a new templated function to ASTNodeImporter that imports arbitrary arrays of importable things into a bump-allocated array attached to getToContext(). This is a pattern we see at many places in ASTNodeImporter; rather than do it slightly differently at each point, this function does it one way. <rdar://problem/22864976> Modified: cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=264669&r1=264668&r2=264669&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Mar 28 16:43:01 2016 @@ -224,8 +224,36 @@ namespace clang { Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); + Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); + Expr *VisitCXXThisExpr(CXXThisExpr *E); + Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); + Expr *VisitInitListExpr(InitListExpr *E); + + template <typename T, typename Iter> bool ImportArray(Iter B, Iter E, llvm::ArrayRef<T*> &ToArray) { + size_t NumElements = E - B; + SmallVector<T *, 1> ImportedElements(NumElements); + ASTImporter &_Importer = Importer; + + bool Failed = false; + std::transform(B, E, ImportedElements.begin(), + [&_Importer, &Failed](T *Element) -> T* { + T *ToElement = _Importer.Import(Element); + if (Element && !ToElement) + Failed = true; + return ToElement; + }); + + if (Failed) + return false; + + T **CopiedElements = new (Importer.getToContext()) T*[NumElements]; + std::copy(ImportedElements.begin(), ImportedElements.end(), &CopiedElements[0]); + ToArray = llvm::ArrayRef<T*>(CopiedElements, NumElements); + + return true; + } }; } using namespace clang; @@ -2683,11 +2711,26 @@ Decl *ASTNodeImporter::VisitRecordDecl(R RecordDecl *D2 = AdoptDecl; SourceLocation StartLoc = Importer.Import(D->getLocStart()); if (!D2) { - if (isa<CXXRecordDecl>(D)) { - CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), - D->getTagKind(), - DC, StartLoc, Loc, - Name.getAsIdentifierInfo()); + CXXRecordDecl *D2CXX = nullptr; + if (CXXRecordDecl *DCXX = llvm::dyn_cast<CXXRecordDecl>(D)) { + if (DCXX->isLambda()) { + TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo()); + D2CXX = CXXRecordDecl::CreateLambda(Importer.getToContext(), + DC, TInfo, Loc, + DCXX->isDependentLambda(), + DCXX->isGenericLambda(), + DCXX->getLambdaCaptureDefault()); + Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl()); + if (DCXX->getLambdaContextDecl() && !CDecl) + return nullptr; + D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), + CDecl); + } else { + D2CXX = CXXRecordDecl::Create(Importer.getToContext(), + D->getTagKind(), + DC, StartLoc, Loc, + Name.getAsIdentifierInfo()); + } D2 = D2CXX; D2->setAccess(D->getAccess()); } else { @@ -4653,16 +4696,11 @@ Stmt *ASTNodeImporter::VisitNullStmt(Nul } Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) { - SmallVector<Stmt *, 4> ToStmts(S->size()); - auto &_Importer = this->Importer; - std::transform(S->body_begin(), S->body_end(), ToStmts.begin(), - [&_Importer](Stmt *CS) -> Stmt * { - return _Importer.Import(CS); - }); - for (Stmt *ToS : ToStmts) { - if (!ToS) - return nullptr; - } + llvm::ArrayRef<Stmt *> ToStmts; + + if (!ImportArray(S->body_begin(), S->body_end(), ToStmts)) + return nullptr; + SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc()); SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc()); return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(), @@ -5290,17 +5328,10 @@ Expr *ASTNodeImporter::VisitCXXConstruct if (!ToCCD && E->getConstructor()) return nullptr; - size_t NumArgs = E->getNumArgs(); - SmallVector<Expr *, 1> ToArgs(NumArgs); - ASTImporter &_Importer = Importer; - std::transform(E->arg_begin(), E->arg_end(), ToArgs.begin(), - [&_Importer](Expr *AE) -> Expr * { - return _Importer.Import(AE); - }); - for (Expr *ToA : ToArgs) { - if (!ToA) - return nullptr; - } + ArrayRef<Expr *> ToArgs; + + if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs)) + return nullptr; return CXXConstructExpr::Create(Importer.getToContext(), T, Importer.Import(E->getLocation()), @@ -5313,6 +5344,44 @@ Expr *ASTNodeImporter::VisitCXXConstruct Importer.Import(E->getParenOrBraceRange())); } +Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *ToFn = Importer.Import(E->getCallee()); + if (!ToFn) + return nullptr; + + ArrayRef<Expr *> ToArgs; + + if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs)) + return nullptr; + + return new (Importer.getToContext()) CXXMemberCallExpr(Importer.getToContext(), ToFn, + ToArgs, T, E->getValueKind(), + Importer.Import(E->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit()); +} + +Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + return new (Importer.getToContext()) + CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation())); +} + + Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5381,6 +5450,28 @@ Expr *ASTNodeImporter::VisitCallExpr(Cal Importer.Import(E->getRParenLoc())); } +Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + ArrayRef<Expr *> ToInits; + + if (!ImportArray(E->inits().begin(), E->inits().end(), ToInits)) + return nullptr; + + InitListExpr *ToE = new (Importer.getToContext()) + InitListExpr(Importer.getToContext(), + Importer.Import(E->getLBraceLoc()), + ToInits, + Importer.Import(E->getRBraceLoc())); + + if (ToE) + ToE->setType(T); + + return ToE; +} + ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport) @@ -5949,6 +6040,13 @@ void ASTImporter::CompleteDecl (Decl *D) } Decl *ASTImporter::Imported(Decl *From, Decl *To) { + if (From->hasAttrs()) { + for (Attr *FromAttr : From->getAttrs()) + To->addAttr(FromAttr->clone(To->getASTContext())); + } + if (From->isUsed()) { + To->setIsUsed(); + } ImportedDecls[From] = To; return To; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits