diff options
Diffstat (limited to 'lib/Sema/TreeTransform.h')
-rw-r--r-- | lib/Sema/TreeTransform.h | 691 |
1 files changed, 538 insertions, 153 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 89e23ef..4351c25 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -24,6 +24,7 @@ #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenMP.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Designator.h" #include "clang/Sema/Lookup.h" @@ -141,7 +142,11 @@ public: /// /// Subclasses may override this function to specify when the transformation /// should rebuild all AST nodes. - bool AlwaysRebuild() { return false; } + /// + /// We must always rebuild all AST nodes when performing variadic template + /// pack expansion, in order to avoid violating the AST invariant that each + /// statement node appears at most once in its containing declaration. + bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; } /// \brief Returns the location of the entity being transformed, if that /// information was not available elsewhere in the AST. @@ -313,6 +318,16 @@ public: /// \returns the transformed statement. StmtResult TransformStmt(Stmt *S); + /// \brief Transform the given statement. + /// + /// By default, this routine transforms a statement by delegating to the + /// appropriate TransformOMPXXXClause function to transform a specific kind + /// of clause. Subclasses may override this function to transform statements + /// using some other mechanism. + /// + /// \returns the transformed OpenMP clause. + OMPClause *TransformOMPClause(OMPClause *S); + /// \brief Transform the given expression. /// /// By default, this routine transforms an expression by delegating to the @@ -533,8 +548,7 @@ public: CXXRecordDecl *ThisContext, unsigned ThisTypeQuals); - StmtResult - TransformSEHHandler(Stmt *Handler); + StmtResult TransformSEHHandler(Stmt *Handler); QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB, @@ -579,21 +593,37 @@ public: StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E); - + + typedef std::pair<ExprResult, QualType> InitCaptureInfoTy; /// \brief Transform the captures and body of a lambda expression. - ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator); + ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator, + ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes); + + TemplateParameterList *TransformTemplateParameterList( + TemplateParameterList *TPL) { + return TPL; + } ExprResult TransformAddressOfOperand(Expr *E); ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, bool IsAddressOfOperand); +// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous +// amount of stack usage with clang. #define STMT(Node, Parent) \ + LLVM_ATTRIBUTE_NOINLINE \ StmtResult Transform##Node(Node *S); #define EXPR(Node, Parent) \ + LLVM_ATTRIBUTE_NOINLINE \ ExprResult Transform##Node(Node *E); #define ABSTRACT_STMT(Stmt) #include "clang/AST/StmtNodes.inc" +#define OPENMP_CLAUSE(Name, Class) \ + LLVM_ATTRIBUTE_NOINLINE \ + OMPClause *Transform ## Class(Class *S); +#include "clang/Basic/OpenMPKinds.def" + /// \brief Build a new pointer type given its pointee type. /// /// By default, performs semantic analysis when building the pointer type. @@ -767,7 +797,8 @@ public: // Note, IsDependent is always false here: we implicitly convert an 'auto' // which has been deduced to a dependent type into an undeduced 'auto', so // that we'll retry deduction after the transformation. - return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto); + return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto, + /*IsDependent*/ false); } /// \brief Build a new template specialization type. @@ -1163,10 +1194,9 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls, - SourceLocation StartLoc, - SourceLocation EndLoc) { - Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls, NumDecls); + StmtResult RebuildDeclStmt(llvm::MutableArrayRef<Decl *> Decls, + SourceLocation StartLoc, SourceLocation EndLoc) { + Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls); return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc); } @@ -1256,6 +1286,63 @@ public: return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); } + /// \brief Build a new OpenMP parallel directive. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + StmtResult RebuildOMPParallelDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPParallelDirective(Clauses, AStmt, + StartLoc, EndLoc); + } + + /// \brief Build a new OpenMP 'default' clause. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind, + SourceLocation KindKwLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc, + StartLoc, LParenLoc, EndLoc); + } + + /// \brief Build a new OpenMP 'private' clause. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, + EndLoc); + } + + /// \brief Build a new OpenMP 'firstprivate' clause. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, + EndLoc); + } + + OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, + EndLoc); + } + /// \brief Rebuild the operand to an Objective-C \@synchronized statement. /// /// By default, performs semantic analysis to build the new statement. @@ -1333,9 +1420,8 @@ public: /// /// By default, performs semantic analysis to build the new statement. /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, - Stmt *TryBlock, - MultiStmtArg Handlers) { + StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, + ArrayRef<Stmt *> Handlers) { return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers); } @@ -1392,22 +1478,18 @@ public: return getSema().FinishCXXForRangeStmt(ForRange, Body); } - StmtResult RebuildSEHTryStmt(bool IsCXXTry, - SourceLocation TryLoc, - Stmt *TryBlock, - Stmt *Handler) { - return getSema().ActOnSEHTryBlock(IsCXXTry,TryLoc,TryBlock,Handler); + StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, + Stmt *TryBlock, Stmt *Handler) { + return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler); } - StmtResult RebuildSEHExceptStmt(SourceLocation Loc, - Expr *FilterExpr, + StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block) { - return getSema().ActOnSEHExceptBlock(Loc,FilterExpr,Block); + return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block); } - StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, - Stmt *Block) { - return getSema().ActOnSEHFinallyBlock(Loc,Block); + StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) { + return getSema().ActOnSEHFinallyBlock(Loc, Block); } /// \brief Build a new expression that references a declaration. @@ -1767,12 +1849,10 @@ public: SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - TypeSourceInfo **Types, - Expr **Exprs, - unsigned NumAssocs) { + ArrayRef<TypeSourceInfo *> Types, + ArrayRef<Expr *> Exprs) { return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, - ControllingExpr, Types, Exprs, - NumAssocs); + ControllingExpr, Types, Exprs); } /// \brief Build a new overloaded operator call expression. @@ -2485,6 +2565,14 @@ public: return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take())); } + /// \brief Build a new convert vector expression. + ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, + Expr *SrcExpr, TypeSourceInfo *DstTInfo, + SourceLocation RParenLoc) { + return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo, + BuiltinLoc, RParenLoc); + } + /// \brief Build a new template argument pack expansion. /// /// By default, performs semantic analysis to build a new pack expansion @@ -2603,6 +2691,23 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { return SemaRef.Owned(S); } +template<typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) { + if (!S) + return S; + + switch (S->getClauseKind()) { + default: break; + // Transform individual clause nodes +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_ ## Name : \ + return getDerived().Transform ## Class(cast<Class>(S)); +#include "clang/Basic/OpenMPKinds.def" + } + + return S; +} + template<typename Derived> ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) { @@ -2632,12 +2737,19 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) Init = ExprTemp->getSubExpr(); + if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) + Init = MTE->GetTemporaryExpr(); + while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) Init = Binder->getSubExpr(); if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) Init = ICE->getSubExprAsWritten(); + if (CXXStdInitializerListExpr *ILE = + dyn_cast<CXXStdInitializerListExpr>(Init)) + return TransformInitializer(ILE->getSubExpr(), CXXDirectInit); + // If this is not a direct-initializer, we only need to reconstruct // InitListExprs. Other forms of copy-initialization will be a no-op if // the initializer is already the right type. @@ -2675,7 +2787,7 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, Construct->getType()); // Build a ParenListExpr to represent anything else. - SourceRange Parens = Construct->getParenRange(); + SourceRange Parens = Construct->getParenOrBraceRange(); return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs, Parens.getEnd()); } @@ -3228,8 +3340,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, SourceLocation Ellipsis; Optional<unsigned> OrigNumExpansions; TemplateArgumentLoc Pattern - = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions, - getSema().Context); + = getSema().getTemplateArgumentPackExpansionPattern( + In, Ellipsis, OrigNumExpansions); SmallVector<UnexpandedParameterPack, 2> Unexpanded; getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); @@ -3421,12 +3533,13 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, Qs.removeObjCLifetime(); Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs); - Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto()); + Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto(), + AutoTy->isDependentType()); TLB.TypeWasModifiedSafely(Result); } else { // Otherwise, complain about the addition of a qualifier to an // already-qualified type. - SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange(); + SourceRange R = T.getUnqualifiedLoc().getSourceRange(); SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant) << Result << R; @@ -3581,6 +3694,22 @@ QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, } template<typename Derived> +QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, + DecayedTypeLoc TL) { + QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc()); + if (OriginalType.isNull()) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || + OriginalType != TL.getOriginalLoc().getType()) + Result = SemaRef.Context.getDecayedType(OriginalType); + TLB.push<DecayedTypeLoc>(Result); + // Nothing to set for DecayedTypeLoc. + return Result; +} + +template<typename Derived> QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB, PointerTypeLoc TL) { QualType PointeeType @@ -5582,8 +5711,7 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { if (!getDerived().AlwaysRebuild() && !DeclChanged) return SemaRef.Owned(S); - return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(), - S->getStartLoc(), S->getEndLoc()); + return getDerived().RebuildDeclStmt(Decls, S->getStartLoc(), S->getEndLoc()); } template<typename Derived> @@ -5877,23 +6005,19 @@ TreeTransform<Derived>::TransformObjCForCollectionStmt( Body.get()); } - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { // Transform the exception declaration, if any. VarDecl *Var = 0; - if (S->getExceptionDecl()) { - VarDecl *ExceptionDecl = S->getExceptionDecl(); - TypeSourceInfo *T = getDerived().TransformType( - ExceptionDecl->getTypeSourceInfo()); + if (VarDecl *ExceptionDecl = S->getExceptionDecl()) { + TypeSourceInfo *T = + getDerived().TransformType(ExceptionDecl->getTypeSourceInfo()); if (!T) return StmtError(); - Var = getDerived().RebuildExceptionDecl(ExceptionDecl, T, - ExceptionDecl->getInnerLocStart(), - ExceptionDecl->getLocation(), - ExceptionDecl->getIdentifier()); + Var = getDerived().RebuildExceptionDecl( + ExceptionDecl, T, ExceptionDecl->getInnerLocStart(), + ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); if (!Var || Var->isInvalidDecl()) return StmtError(); } @@ -5903,31 +6027,25 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { if (Handler.isInvalid()) return StmtError(); - if (!getDerived().AlwaysRebuild() && - !Var && + if (!getDerived().AlwaysRebuild() && !Var && Handler.get() == S->getHandlerBlock()) return SemaRef.Owned(S); - return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), - Var, - Handler.get()); + return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get()); } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { // Transform the try block itself. - StmtResult TryBlock - = getDerived().TransformCompoundStmt(S->getTryBlock()); + StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); if (TryBlock.isInvalid()) return StmtError(); // Transform the handlers. bool HandlerChanged = false; - SmallVector<Stmt*, 8> Handlers; + SmallVector<Stmt *, 8> Handlers; for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) { - StmtResult Handler - = getDerived().TransformCXXCatchStmt(S->getHandler(I)); + StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I)); if (Handler.isInvalid()) return StmtError(); @@ -5935,8 +6053,7 @@ TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { Handlers.push_back(Handler.takeAs<Stmt>()); } - if (!getDerived().AlwaysRebuild() && - TryBlock.get() == S->getTryBlock() && + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && !HandlerChanged) return SemaRef.Owned(S); @@ -6108,57 +6225,166 @@ TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) { QualifierLoc, E->getMemberLoc()); } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { - StmtResult TryBlock; // = getDerived().TransformCompoundStmt(S->getTryBlock()); - if(TryBlock.isInvalid()) return StmtError(); +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { + StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); + if (TryBlock.isInvalid()) + return StmtError(); StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler()); - if(!getDerived().AlwaysRebuild() && - TryBlock.get() == S->getTryBlock() && - Handler.get() == S->getHandler()) + if (Handler.isInvalid()) + return StmtError(); + + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && + Handler.get() == S->getHandler()) return SemaRef.Owned(S); - return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), - S->getTryLoc(), - TryBlock.take(), - Handler.take()); + return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), + TryBlock.take(), Handler.take()); } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) { - StmtResult Block; // = getDerived().TransformCompoundStatement(S->getBlock()); - if(Block.isInvalid()) return StmtError(); +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) { + StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); + if (Block.isInvalid()) + return StmtError(); - return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), - Block.take()); + return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.take()); } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) { +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) { ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr()); - if(FilterExpr.isInvalid()) return StmtError(); + if (FilterExpr.isInvalid()) + return StmtError(); - StmtResult Block; // = getDerived().TransformCompoundStatement(S->getBlock()); - if(Block.isInvalid()) return StmtError(); + StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); + if (Block.isInvalid()) + return StmtError(); - return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), - FilterExpr.take(), + return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.take(), Block.take()); } -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { - if(isa<SEHFinallyStmt>(Handler)) +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { + if (isa<SEHFinallyStmt>(Handler)) return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler)); else return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler)); } +template<typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) { + DeclarationNameInfo DirName; + getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, 0); + + // Transform the clauses + llvm::SmallVector<OMPClause *, 16> TClauses; + ArrayRef<OMPClause *> Clauses = D->clauses(); + TClauses.reserve(Clauses.size()); + for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) { + if (*I) { + OMPClause *Clause = getDerived().TransformOMPClause(*I); + if (!Clause) { + getSema().EndOpenMPDSABlock(0); + return StmtError(); + } + TClauses.push_back(Clause); + } + else { + TClauses.push_back(0); + } + } + if (!D->getAssociatedStmt()) { + getSema().EndOpenMPDSABlock(0); + return StmtError(); + } + StmtResult AssociatedStmt = + getDerived().TransformStmt(D->getAssociatedStmt()); + if (AssociatedStmt.isInvalid()) { + getSema().EndOpenMPDSABlock(0); + return StmtError(); + } + + StmtResult Res = getDerived().RebuildOMPParallelDirective(TClauses, + AssociatedStmt.take(), + D->getLocStart(), + D->getLocEnd()); + getSema().EndOpenMPDSABlock(Res.get()); + return Res; +} + +template<typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) { + return getDerived().RebuildOMPDefaultClause(C->getDefaultKind(), + C->getDefaultKindKwLoc(), + C->getLocStart(), + C->getLParenLoc(), + C->getLocEnd()); +} + +template<typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); + if (EVar.isInvalid()) + return 0; + Vars.push_back(EVar.take()); + } + return getDerived().RebuildOMPPrivateClause(Vars, + C->getLocStart(), + C->getLParenLoc(), + C->getLocEnd()); +} + +template<typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPFirstprivateClause( + OMPFirstprivateClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); + if (EVar.isInvalid()) + return 0; + Vars.push_back(EVar.take()); + } + return getDerived().RebuildOMPFirstprivateClause(Vars, + C->getLocStart(), + C->getLParenLoc(), + C->getLocEnd()); +} + +template<typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (OMPSharedClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); + if (EVar.isInvalid()) + return 0; + Vars.push_back(EVar.take()); + } + return getDerived().RebuildOMPSharedClause(Vars, + C->getLocStart(), + C->getLParenLoc(), + C->getLocEnd()); +} + //===----------------------------------------------------------------------===// // Expression transformation //===----------------------------------------------------------------------===// @@ -6289,9 +6515,8 @@ TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) { E->getDefaultLoc(), E->getRParenLoc(), ControllingExpr.release(), - AssocTypes.data(), - AssocExprs.data(), - E->getNumAssocs()); + AssocTypes, + AssocExprs); } template<typename Derived> @@ -6323,7 +6548,11 @@ TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) { template<typename Derived> ExprResult TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) { - ExprResult SubExpr = TransformAddressOfOperand(E->getSubExpr()); + ExprResult SubExpr; + if (E->getOpcode() == UO_AddrOf) + SubExpr = TransformAddressOfOperand(E->getSubExpr()); + else + SubExpr = TransformExpr(E->getSubExpr()); if (SubExpr.isInvalid()) return ExprError(); @@ -7165,7 +7394,7 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr( return SemaRef.Owned(E); return getDerived().RebuildCXXFunctionalCastExpr(Type, - /*FIXME:*/E->getSubExpr()->getLocStart(), + E->getLParenLoc(), SubExpr.get(), E->getRParenLoc()); } @@ -7261,18 +7490,7 @@ TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr( template<typename Derived> ExprResult TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) { - DeclContext *DC = getSema().getFunctionLevelDeclContext(); - QualType T; - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) - T = MD->getThisType(getSema().Context); - else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) { - T = getSema().Context.getPointerType( - getSema().Context.getRecordType(Record)); - } else { - assert(SemaRef.Context.getDiagnostics().hasErrorOccurred() && - "this in the wrong scope?"); - return ExprError(); - } + QualType T = getSema().getCurrentThisType(); if (!getDerived().AlwaysRebuild() && T == E->getType()) { // Make sure that we capture 'this'. @@ -7602,8 +7820,10 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( // This can happen because of dependent hiding. if (isa<UsingShadowDecl>(*I)) continue; - else + else { + R.clear(); return ExprError(); + } } // Expand using declarations. @@ -7638,8 +7858,10 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( Old->getNameLoc(), Old->getNamingClass())); - if (!NamingClass) + if (!NamingClass) { + R.clear(); return ExprError(); + } R.setNamingClass(NamingClass); } @@ -7657,8 +7879,10 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( if (Old->hasExplicitTemplateArgs() && getDerived().TransformTemplateArguments(Old->getTemplateArgs(), Old->getNumTemplateArgs(), - TransArgs)) + TransArgs)) { + R.clear(); return ExprError(); + } return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, Old->requiresADL(), &TransArgs); @@ -7785,6 +8009,19 @@ TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) { if (To.isNull()) return ExprError(); + if (To->containsUnexpandedParameterPack()) { + To = getDerived().RebuildPackExpansionType(To, + PatternTL.getSourceRange(), + ExpansionTL.getEllipsisLoc(), + NumExpansions); + if (To.isNull()) + return ExprError(); + + PackExpansionTypeLoc ToExpansionTL + = TLB.push<PackExpansionTypeLoc>(To); + ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); + } + Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); } @@ -7883,6 +8120,7 @@ ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( DependentScopeDeclRefExpr *E, bool IsAddressOfOperand) { + assert(E->getQualifierLoc()); NestedNameSpecifierLoc QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); if (!QualifierLoc) @@ -7974,7 +8212,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { E->isListInitialization(), E->requiresZeroInitialization(), E->getConstructionKind(), - E->getParenRange()); + E->getParenOrBraceRange()); } /// \brief Transform a C++ temporary-binding expression. @@ -8039,57 +8277,157 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr( template<typename Derived> ExprResult TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { - // Transform the type of the lambda parameters and start the definition of - // the lambda itself. - TypeSourceInfo *MethodTy - = TransformType(E->getCallOperator()->getTypeSourceInfo()); - if (!MethodTy) + + // Transform any init-capture expressions before entering the scope of the + // lambda body, because they are not semantically within that scope. + SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes; + InitCaptureExprsAndTypes.resize(E->explicit_capture_end() - + E->explicit_capture_begin()); + + for (LambdaExpr::capture_iterator C = E->capture_begin(), + CEnd = E->capture_end(); + C != CEnd; ++C) { + if (!C->isInitCapture()) + continue; + EnterExpressionEvaluationContext EEEC(getSema(), + Sema::PotentiallyEvaluated); + ExprResult NewExprInitResult = getDerived().TransformInitializer( + C->getCapturedVar()->getInit(), + C->getCapturedVar()->getInitStyle() == VarDecl::CallInit); + + if (NewExprInitResult.isInvalid()) + return ExprError(); + Expr *NewExprInit = NewExprInitResult.get(); + + VarDecl *OldVD = C->getCapturedVar(); + QualType NewInitCaptureType = + getSema().performLambdaInitCaptureInitialization(C->getLocation(), + OldVD->getType()->isReferenceType(), OldVD->getIdentifier(), + NewExprInit); + NewExprInitResult = NewExprInit; + InitCaptureExprsAndTypes[C - E->capture_begin()] = + std::make_pair(NewExprInitResult, NewInitCaptureType); + + } + + LambdaScopeInfo *LSI = getSema().PushLambdaScope(); + // Transform the template parameters, and add them to the current + // instantiation scope. The null case is handled correctly. + LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList( + E->getTemplateParameterList()); + + // Check to see if the TypeSourceInfo of the call operator needs to + // be transformed, and if so do the transformation in the + // CurrentInstantiationScope. + + TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); + FunctionProtoTypeLoc OldCallOpFPTL = + OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); + TypeSourceInfo *NewCallOpTSI = 0; + + const bool CallOpWasAlreadyTransformed = + getDerived().AlreadyTransformed(OldCallOpTSI->getType()); + + // Use the Old Call Operator's TypeSourceInfo if it is already transformed. + if (CallOpWasAlreadyTransformed) + NewCallOpTSI = OldCallOpTSI; + else { + // Transform the TypeSourceInfo of the Original Lambda's Call Operator. + // The transformation MUST be done in the CurrentInstantiationScope since + // it introduces a mapping of the original to the newly created + // transformed parameters. + + TypeLocBuilder NewCallOpTLBuilder; + QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder, + OldCallOpFPTL, + 0, 0); + NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, + NewCallOpType); + } + // Extract the ParmVarDecls from the NewCallOpTSI and add them to + // the vector below - this will be used to synthesize the + // NewCallOperator. Additionally, add the parameters of the untransformed + // lambda call operator to the CurrentInstantiationScope. + SmallVector<ParmVarDecl *, 4> Params; + { + FunctionProtoTypeLoc NewCallOpFPTL = + NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>(); + ParmVarDecl **NewParamDeclArray = NewCallOpFPTL.getParmArray(); + const unsigned NewNumArgs = NewCallOpFPTL.getNumArgs(); + + for (unsigned I = 0; I < NewNumArgs; ++I) { + // If this call operator's type does not require transformation, + // the parameters do not get added to the current instantiation scope, + // - so ADD them! This allows the following to compile when the enclosing + // template is specialized and the entire lambda expression has to be + // transformed. + // template<class T> void foo(T t) { + // auto L = [](auto a) { + // auto M = [](char b) { <-- note: non-generic lambda + // auto N = [](auto c) { + // int x = sizeof(a); + // x = sizeof(b); <-- specifically this line + // x = sizeof(c); + // }; + // }; + // }; + // } + // foo('a') + if (CallOpWasAlreadyTransformed) + getDerived().transformedLocalDecl(NewParamDeclArray[I], + NewParamDeclArray[I]); + // Add to Params array, so these parameters can be used to create + // the newly transformed call operator. + Params.push_back(NewParamDeclArray[I]); + } + } + + if (!NewCallOpTSI) return ExprError(); // Create the local class that will describe the lambda. CXXRecordDecl *Class = getSema().createLambdaClosureType(E->getIntroducerRange(), - MethodTy, - /*KnownDependent=*/false); - getDerived().transformedLocalDecl(E->getLambdaClass(), Class); + NewCallOpTSI, + /*KnownDependent=*/false, + E->getCaptureDefault()); - // Transform lambda parameters. - SmallVector<QualType, 4> ParamTypes; - SmallVector<ParmVarDecl *, 4> Params; - if (getDerived().TransformFunctionTypeParams(E->getLocStart(), - E->getCallOperator()->param_begin(), - E->getCallOperator()->param_size(), - 0, ParamTypes, &Params)) - return ExprError(); + getDerived().transformedLocalDecl(E->getLambdaClass(), Class); // Build the call operator. - CXXMethodDecl *CallOperator + CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(Class, E->getIntroducerRange(), - MethodTy, + NewCallOpTSI, E->getCallOperator()->getLocEnd(), Params); - getDerived().transformAttrs(E->getCallOperator(), CallOperator); + LSI->CallOperator = NewCallOperator; + + getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); - return getDerived().TransformLambdaScope(E, CallOperator); + return getDerived().TransformLambdaScope(E, NewCallOperator, + InitCaptureExprsAndTypes); } template<typename Derived> ExprResult TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E, - CXXMethodDecl *CallOperator) { + CXXMethodDecl *CallOperator, + ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) { + bool Invalid = false; + // Introduce the context of the call operator. Sema::ContextRAII SavedContext(getSema(), CallOperator); + LambdaScopeInfo *const LSI = getSema().getCurLambda(); // Enter the scope of the lambda. - sema::LambdaScopeInfo *LSI - = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(), + getSema().buildLambdaScope(LSI, CallOperator, E->getIntroducerRange(), E->getCaptureDefault(), + E->getCaptureDefaultLoc(), E->hasExplicitParameters(), E->hasExplicitResultType(), E->isMutable()); // Transform captures. - bool Invalid = false; bool FinishedExplicitCaptures = false; for (LambdaExpr::capture_iterator C = E->capture_begin(), CEnd = E->capture_end(); @@ -8107,6 +8445,32 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E, continue; } + // Rebuild init-captures, including the implied field declaration. + if (C->isInitCapture()) { + + InitCaptureInfoTy InitExprTypePair = + InitCaptureExprsAndTypes[C - E->capture_begin()]; + ExprResult Init = InitExprTypePair.first; + QualType InitQualType = InitExprTypePair.second; + if (Init.isInvalid() || InitQualType.isNull()) { + Invalid = true; + continue; + } + VarDecl *OldVD = C->getCapturedVar(); + VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl( + OldVD->getLocation(), InitExprTypePair.second, + OldVD->getIdentifier(), Init.get()); + if (!NewVD) + Invalid = true; + else { + getDerived().transformedLocalDecl(OldVD, NewVD); + } + getSema().buildInitCaptureField(LSI, NewVD); + continue; + } + + assert(C->capturesVariable() && "unexpected kind of lambda capture"); + // Determine the capture kind for Sema. Sema::TryCaptureKind Kind = C->isImplicit()? Sema::TryCapture_Implicit @@ -8123,8 +8487,10 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E, C->getLocation(), Unexpanded, ShouldExpand, RetainExpansion, - NumExpansions)) - return ExprError(); + NumExpansions)) { + Invalid = true; + continue; + } if (ShouldExpand) { // The transform has determined that we should perform an expansion; @@ -8519,6 +8885,13 @@ TreeTransform<Derived>::TransformMaterializeTemporaryExpr( template<typename Derived> ExprResult +TreeTransform<Derived>::TransformCXXStdInitializerListExpr( + CXXStdInitializerListExpr *E) { + return getDerived().TransformExpr(E->getSubExpr()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { return SemaRef.MaybeBindToTemporary(E); } @@ -8919,6 +9292,27 @@ TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) { + ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); + if (SrcExpr.isInvalid()) + return ExprError(); + + TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); + if (!Type) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && + Type == E->getTypeSourceInfo() && + SrcExpr.get() == E->getSrcExpr()) + return SemaRef.Owned(E); + + return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(), + SrcExpr.get(), Type, + E->getRParenLoc()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { BlockDecl *oldBlock = E->getBlockDecl(); @@ -8945,15 +9339,6 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { QualType exprResultType = getDerived().TransformType(exprFunctionType->getResultType()); - // Don't allow returning a objc interface by value. - if (exprResultType->isObjCObjectType()) { - getSema().Diag(E->getCaretLocation(), - diag::err_object_cannot_be_passed_returned_by_value) - << 0 << exprResultType; - getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); - return ExprError(); - } - QualType functionType = getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, exprFunctionType->getExtProtoInfo()); @@ -9080,7 +9465,7 @@ TreeTransform<Derived>::RebuildArrayType(QualType ElementType, SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy, SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty }; - const unsigned NumTypes = sizeof(Types) / sizeof(QualType); + const unsigned NumTypes = llvm::array_lengthof(Types); QualType SizeType; for (unsigned I = 0; I != NumTypes; ++I) if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) { @@ -9196,7 +9581,7 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) { TypeDecl *Ty; if (isa<UsingDecl>(D)) { UsingDecl *Using = cast<UsingDecl>(D); - assert(Using->isTypeName() && + assert(Using->hasTypename() && "UnresolvedUsingTypenameDecl transformed to non-typename using"); // A valid resolved using typename decl points to exactly one type decl. @@ -9295,7 +9680,7 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); - return Template.template getAsVal<TemplateName>(); + return Template.get(); } template<typename Derived> |