jhen updated this revision to Diff 44538. jhen added a comment. - Handle unexpanded parameter packs
The changes for instantiation dependence also fix a bug with unexpanded parameter packs, so add a unit test for unexpanded parameter packs as well. http://reviews.llvm.org/D15858 Files: include/clang/AST/Expr.h include/clang/AST/ExprCXX.h lib/AST/Expr.cpp test/SemaCUDA/cxx11-kernel-call.cu test/SemaCUDA/kernel-call.cu
Index: test/SemaCUDA/kernel-call.cu =================================================================== --- test/SemaCUDA/kernel-call.cu +++ test/SemaCUDA/kernel-call.cu @@ -23,4 +23,6 @@ int (*fp)(int) = h2; fp<<<1, 1>>>(42); // expected-error {{must have void return type}} + + g1<<<undeclared, 1>>>(42); // expected-error {{use of undeclared identifier 'undeclared'}} } Index: test/SemaCUDA/cxx11-kernel-call.cu =================================================================== --- /dev/null +++ test/SemaCUDA/cxx11-kernel-call.cu @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +#include "Inputs/cuda.h" + +__global__ void k1() {} + +template<int ...Dimensions> void k1Wrapper() { + void (*f)() = [] { k1<<<Dimensions, Dimensions>>>(); }; // expected-error {{initializer contains unexpanded parameter pack 'Dimensions'}} +} Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -1138,38 +1138,38 @@ // Postfix Operators. //===----------------------------------------------------------------------===// -CallExpr::CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, - unsigned NumPreArgs, ArrayRef<Expr*> args, QualType t, +CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : Expr(SC, t, VK, OK_Ordinary, - fn->isTypeDependent(), - fn->isValueDependent(), - fn->isInstantiationDependent(), - fn->containsUnexpandedParameterPack()), - NumArgs(args.size()) { - - SubExprs = new (C) Stmt*[args.size()+PREARGS_START+NumPreArgs]; + : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), + fn->isValueDependent(), fn->isInstantiationDependent(), + fn->containsUnexpandedParameterPack()), + NumArgs(args.size()) { + + unsigned NumPreArgs = preargs.size(); + SubExprs = new (C) Stmt *[args.size()+PREARGS_START+NumPreArgs]; SubExprs[FN] = fn; + for (unsigned i = 0; i != NumPreArgs; ++i) { + updateDependenciesFromArg(preargs[i]); + SubExprs[i+PREARGS_START] = preargs[i]; + } for (unsigned i = 0; i != args.size(); ++i) { - if (args[i]->isTypeDependent()) - ExprBits.TypeDependent = true; - if (args[i]->isValueDependent()) - ExprBits.ValueDependent = true; - if (args[i]->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (args[i]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; - + updateDependenciesFromArg(args[i]); SubExprs[i+PREARGS_START+NumPreArgs] = args[i]; } CallExprBits.NumPreArgs = NumPreArgs; RParenLoc = rparenloc; } +CallExpr::CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> args, QualType t, ExprValueKind VK, + SourceLocation rparenloc) + : CallExpr(C, SC, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) {} + CallExpr::CallExpr(const ASTContext &C, Expr *fn, ArrayRef<Expr *> args, QualType t, ExprValueKind VK, SourceLocation rparenloc) - : CallExpr(C, CallExprClass, fn, /*NumPreArgs=*/0, args, t, VK, rparenloc) { + : CallExpr(C, CallExprClass, fn, ArrayRef<Expr *>(), args, t, VK, rparenloc) { } CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty) @@ -1179,10 +1179,21 @@ EmptyShell Empty) : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) { // FIXME: Why do we allocate this? - SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs]; + SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs](); CallExprBits.NumPreArgs = NumPreArgs; } +void CallExpr::updateDependenciesFromArg(Expr *Arg) { + if (Arg->isTypeDependent()) + ExprBits.TypeDependent = true; + if (Arg->isValueDependent()) + ExprBits.ValueDependent = true; + if (Arg->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (Arg->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; +} + Decl *CallExpr::getCalleeDecl() { Expr *CEE = getCallee()->IgnoreParenImpCasts(); Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -66,8 +66,7 @@ CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation operatorloc, bool fpContractable) - : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK, - operatorloc), + : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), Operator(Op), FPContractable(fpContractable) { Range = getSourceRangeImpl(); } @@ -125,7 +124,7 @@ public: CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -160,18 +159,29 @@ CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) { - setConfig(Config); - } + : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {} CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { } const CallExpr *getConfig() const { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } - void setConfig(CallExpr *E) { setPreArg(CONFIG, E); } + + /// \brief Sets the kernel configuration expression. + /// + /// Note that this method cannot be called if config has already been set to a + /// non-null value. + void setConfig(CallExpr *E) { + assert(!getConfig() && + "Cannot call setConfig if config is not null"); + setPreArg(CONFIG, E); + setInstantiationDependent(isInstantiationDependent() || + E->isInstantiationDependent()); + setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || + E->containsUnexpandedParameterPack()); + } static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; @@ -398,7 +408,7 @@ UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), + : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), UDSuffixLoc(SuffixLoc) {} explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2136,11 +2136,15 @@ unsigned NumArgs; SourceLocation RParenLoc; + void updateDependenciesFromArg(Expr *Arg); + protected: // These versions of the constructor are for derived classes. - CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, - ArrayRef<Expr*> args, QualType t, ExprValueKind VK, - SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t, + ExprValueKind VK, SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args, + QualType t, ExprValueKind VK, SourceLocation rparenloc); CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits