forked from OSchip/llvm-project
AST, Sema, Serialization: add CUDAKernelCallExpr and related semantic actions
llvm-svn: 125217
This commit is contained in:
parent
9e2c81f00a
commit
41f8546233
|
@ -116,6 +116,35 @@ public:
|
|||
static bool classof(const CXXMemberCallExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// CUDAKernelCallExpr - Represents a call to a CUDA kernel function.
|
||||
class CUDAKernelCallExpr : public CallExpr {
|
||||
private:
|
||||
enum { CONFIG, END_PREARG };
|
||||
|
||||
public:
|
||||
CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config,
|
||||
Expr **args, unsigned numargs, QualType t,
|
||||
ExprValueKind VK, SourceLocation RP)
|
||||
: CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, numargs, t, VK,
|
||||
RP) {
|
||||
setConfig(Config);
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == CUDAKernelCallExprClass;
|
||||
}
|
||||
static bool classof(const CUDAKernelCallExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// CXXNamedCastExpr - Abstract class common to all of the C++ "named"
|
||||
/// casts, @c static_cast, @c dynamic_cast, @c reinterpret_cast, or @c
|
||||
/// const_cast.
|
||||
|
|
|
@ -1846,6 +1846,7 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
|
|||
|
||||
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
|
||||
DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
|
||||
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
|
||||
|
||||
// These operators (all of them) do not need any action except
|
||||
// iterating over the children.
|
||||
|
|
|
@ -125,6 +125,9 @@ def ObjCIvarRefExpr : DStmt<Expr>;
|
|||
def ObjCPropertyRefExpr : DStmt<Expr>;
|
||||
def ObjCIsaExpr : DStmt<Expr>;
|
||||
|
||||
// CUDA Expressions.
|
||||
def CUDAKernelCallExpr : DStmt<CallExpr>;
|
||||
|
||||
// Clang Extensions.
|
||||
def ShuffleVectorExpr : DStmt<Expr>;
|
||||
def BlockExpr : DStmt<Expr>;
|
||||
|
|
|
@ -1177,7 +1177,8 @@ public:
|
|||
UnresolvedLookupExpr *ULE,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc);
|
||||
SourceLocation RParenLoc,
|
||||
Expr *ExecConfig);
|
||||
|
||||
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
||||
unsigned Opc,
|
||||
|
@ -1913,11 +1914,16 @@ public:
|
|||
/// This provides the location of the left/right parens and a list of comma
|
||||
/// locations.
|
||||
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
||||
MultiExprArg Args, SourceLocation RParenLoc);
|
||||
MultiExprArg Args, SourceLocation RParenLoc,
|
||||
Expr *ExecConfig = 0);
|
||||
ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc);
|
||||
SourceLocation RParenLoc,
|
||||
Expr *ExecConfig = 0);
|
||||
|
||||
ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
|
||||
MultiExprArg ExecConfig, SourceLocation GGGLoc);
|
||||
|
||||
ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
|
||||
ParsedType Ty, SourceLocation RParenLoc,
|
||||
|
|
|
@ -949,7 +949,11 @@ namespace clang {
|
|||
|
||||
EXPR_PACK_EXPANSION, // PackExpansionExpr
|
||||
EXPR_SIZEOF_PACK, // SizeOfPackExpr
|
||||
EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK // SubstNonTypeTemplateParmPackExpr
|
||||
EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK,// SubstNonTypeTemplateParmPackExpr
|
||||
|
||||
// CUDA
|
||||
|
||||
EXPR_CUDA_KERNEL_CALL // CUDAKernelCallExpr
|
||||
};
|
||||
|
||||
/// \brief The kinds of designators that can occur in a
|
||||
|
|
|
@ -238,6 +238,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
|||
case Expr::CallExprClass:
|
||||
case Expr::CXXOperatorCallExprClass:
|
||||
case Expr::CXXMemberCallExprClass:
|
||||
case Expr::CUDAKernelCallExprClass:
|
||||
return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType());
|
||||
|
||||
// __builtin_choose_expr is equivalent to the chosen expression.
|
||||
|
|
|
@ -2599,6 +2599,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
|||
case Expr::AddrLabelExprClass:
|
||||
case Expr::StmtExprClass:
|
||||
case Expr::CXXMemberCallExprClass:
|
||||
case Expr::CUDAKernelCallExprClass:
|
||||
case Expr::CXXDynamicCastExprClass:
|
||||
case Expr::CXXTypeidExprClass:
|
||||
case Expr::CXXUuidofExprClass:
|
||||
|
|
|
@ -1732,7 +1732,8 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
|
|||
case Expr::BinaryTypeTraitExprClass:
|
||||
case Expr::VAArgExprClass:
|
||||
case Expr::CXXUuidofExprClass:
|
||||
case Expr::CXXNoexceptExprClass: {
|
||||
case Expr::CXXNoexceptExprClass:
|
||||
case Expr::CUDAKernelCallExprClass: {
|
||||
// As bad as this diagnostic is, it's better than crashing.
|
||||
Diagnostic &Diags = Context.getDiags();
|
||||
unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
|
||||
|
|
|
@ -961,6 +961,15 @@ void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
|
|||
VisitCallExpr(cast<CallExpr>(Node));
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
|
||||
PrintExpr(Node->getCallee());
|
||||
OS << "<<<";
|
||||
PrintCallArgs(Node->getConfig());
|
||||
OS << ">>>(";
|
||||
PrintCallArgs(Node);
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
|
||||
OS << Node->getCastName() << '<';
|
||||
OS << Node->getTypeAsWritten().getAsString(Policy) << ">(";
|
||||
|
|
|
@ -644,6 +644,10 @@ void StmtProfiler::VisitCXXMemberCallExpr(CXXMemberCallExpr *S) {
|
|||
VisitCallExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *S) {
|
||||
VisitCallExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCXXNamedCastExpr(CXXNamedCastExpr *S) {
|
||||
VisitExplicitCastExpr(S);
|
||||
}
|
||||
|
|
|
@ -4362,7 +4362,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
/// locations.
|
||||
ExprResult
|
||||
Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
||||
MultiExprArg args, SourceLocation RParenLoc) {
|
||||
MultiExprArg args, SourceLocation RParenLoc,
|
||||
Expr *ExecConfig) {
|
||||
unsigned NumArgs = args.size();
|
||||
|
||||
// Since this might be a postfix expression, get rid of ParenListExprs.
|
||||
|
@ -4399,10 +4400,17 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
|||
else if (Expr::hasAnyTypeDependentArguments(Args, NumArgs))
|
||||
Dependent = true;
|
||||
|
||||
if (Dependent)
|
||||
return Owned(new (Context) CallExpr(Context, Fn, Args, NumArgs,
|
||||
Context.DependentTy, VK_RValue,
|
||||
RParenLoc));
|
||||
if (Dependent) {
|
||||
if (ExecConfig) {
|
||||
return Owned(new (Context) CUDAKernelCallExpr(
|
||||
Context, Fn, cast<CallExpr>(ExecConfig), Args, NumArgs,
|
||||
Context.DependentTy, VK_RValue, RParenLoc));
|
||||
} else {
|
||||
return Owned(new (Context) CallExpr(Context, Fn, Args, NumArgs,
|
||||
Context.DependentTy, VK_RValue,
|
||||
RParenLoc));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether this is a call to an object (C++ [over.call.object]).
|
||||
if (Fn->getType()->isRecordType())
|
||||
|
@ -4495,7 +4503,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
|||
if (isa<UnresolvedLookupExpr>(NakedFn)) {
|
||||
UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(NakedFn);
|
||||
return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, Args, NumArgs,
|
||||
RParenLoc);
|
||||
RParenLoc, ExecConfig);
|
||||
}
|
||||
|
||||
NamedDecl *NDecl = 0;
|
||||
|
@ -4506,7 +4514,23 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
|
|||
if (isa<DeclRefExpr>(NakedFn))
|
||||
NDecl = cast<DeclRefExpr>(NakedFn)->getDecl();
|
||||
|
||||
return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, Args, NumArgs, RParenLoc);
|
||||
return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, Args, NumArgs, RParenLoc,
|
||||
ExecConfig);
|
||||
}
|
||||
|
||||
ExprResult
|
||||
Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
|
||||
MultiExprArg execConfig, SourceLocation GGGLoc) {
|
||||
FunctionDecl *ConfigDecl = Context.getcudaConfigureCallDecl();
|
||||
if (!ConfigDecl)
|
||||
return ExprError(Diag(LLLLoc, diag::err_undeclared_var_use)
|
||||
<< "cudaConfigureCall");
|
||||
QualType ConfigQTy = ConfigDecl->getType();
|
||||
|
||||
DeclRefExpr *ConfigDR = new (Context) DeclRefExpr(
|
||||
ConfigDecl, ConfigQTy, VK_LValue, LLLLoc);
|
||||
|
||||
return ActOnCallExpr(S, ConfigDR, LLLLoc, execConfig, GGGLoc, 0);
|
||||
}
|
||||
|
||||
/// BuildResolvedCallExpr - Build a call to a resolved expression,
|
||||
|
@ -4519,7 +4543,8 @@ ExprResult
|
|||
Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc) {
|
||||
SourceLocation RParenLoc,
|
||||
Expr *Config) {
|
||||
FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl);
|
||||
|
||||
// Promote the function operand.
|
||||
|
@ -4527,11 +4552,21 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
|
|||
|
||||
// Make the call expr early, before semantic checks. This guarantees cleanup
|
||||
// of arguments and function on error.
|
||||
CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
|
||||
Args, NumArgs,
|
||||
Context.BoolTy,
|
||||
VK_RValue,
|
||||
RParenLoc);
|
||||
CallExpr *TheCall;
|
||||
if (Config) {
|
||||
TheCall = new (Context) CUDAKernelCallExpr(Context, Fn,
|
||||
cast<CallExpr>(Config),
|
||||
Args, NumArgs,
|
||||
Context.BoolTy,
|
||||
VK_RValue,
|
||||
RParenLoc);
|
||||
} else {
|
||||
TheCall = new (Context) CallExpr(Context, Fn,
|
||||
Args, NumArgs,
|
||||
Context.BoolTy,
|
||||
VK_RValue,
|
||||
RParenLoc);
|
||||
}
|
||||
|
||||
const FunctionType *FuncT;
|
||||
if (!Fn->getType()->isBlockPointerType()) {
|
||||
|
|
|
@ -7426,7 +7426,8 @@ ExprResult
|
|||
Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
|
||||
SourceLocation LParenLoc,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc) {
|
||||
SourceLocation RParenLoc,
|
||||
Expr *ExecConfig) {
|
||||
#ifndef NDEBUG
|
||||
if (ULE->requiresADL()) {
|
||||
// To do ADL, we must have found an unqualified name.
|
||||
|
@ -7466,8 +7467,8 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
|
|||
DiagnoseUseOfDecl(FDecl? FDecl : Best->FoundDecl.getDecl(),
|
||||
ULE->getNameLoc());
|
||||
Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
|
||||
return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
|
||||
RParenLoc);
|
||||
return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc,
|
||||
ExecConfig);
|
||||
}
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
|
|
|
@ -1348,9 +1348,10 @@ public:
|
|||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
|
||||
MultiExprArg Args,
|
||||
SourceLocation RParenLoc) {
|
||||
SourceLocation RParenLoc,
|
||||
Expr *ExecConfig = 0) {
|
||||
return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
|
||||
move(Args), RParenLoc);
|
||||
move(Args), RParenLoc, ExecConfig);
|
||||
}
|
||||
|
||||
/// \brief Build a new member access expression.
|
||||
|
@ -5919,6 +5920,39 @@ TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
|||
return getDerived().TransformCallExpr(E);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
||||
// Transform the callee.
|
||||
ExprResult Callee = getDerived().TransformExpr(E->getCallee());
|
||||
if (Callee.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
// Transform exec config.
|
||||
ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
|
||||
if (EC.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
// Transform arguments.
|
||||
bool ArgChanged = false;
|
||||
ASTOwningVector<Expr*> Args(SemaRef);
|
||||
if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
|
||||
&ArgChanged))
|
||||
return ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
Callee.get() == E->getCallee() &&
|
||||
!ArgChanged)
|
||||
return SemaRef.Owned(E);
|
||||
|
||||
// FIXME: Wrong source location information for the '('.
|
||||
SourceLocation FakeLParenLoc
|
||||
= ((Expr *)Callee.get())->getSourceRange().getBegin();
|
||||
return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
|
||||
move_arg(Args),
|
||||
E->getRParenLoc(), EC.get());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
||||
|
|
|
@ -182,6 +182,9 @@ namespace clang {
|
|||
void VisitSubstNonTypeTemplateParmPackExpr(
|
||||
SubstNonTypeTemplateParmPackExpr *E);
|
||||
void VisitOpaqueValueExpr(OpaqueValueExpr *E);
|
||||
|
||||
// CUDA Expressions
|
||||
void VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1323,6 +1326,15 @@ void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|||
E->Loc = ReadSourceLocation(Record, Idx);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CUDA Expressions and Statements
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
||||
VisitCallExpr(E);
|
||||
E->setConfig(cast<CallExpr>(Reader.ReadSubExpr()));
|
||||
}
|
||||
|
||||
Stmt *ASTReader::ReadStmt(PerFileData &F) {
|
||||
switch (ReadingKind) {
|
||||
case Read_Decl:
|
||||
|
@ -1872,6 +1884,10 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) {
|
|||
case EXPR_OPAQUE_VALUE:
|
||||
S = new (Context) OpaqueValueExpr(Empty);
|
||||
break;
|
||||
|
||||
case EXPR_CUDA_KERNEL_CALL:
|
||||
S = new (Context) CUDAKernelCallExpr(*Context, Empty);
|
||||
break;
|
||||
}
|
||||
|
||||
// We hit a STMT_STOP, so we're done with this expression.
|
||||
|
|
|
@ -691,6 +691,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
|
|||
RECORD(EXPR_PACK_EXPANSION);
|
||||
RECORD(EXPR_SIZEOF_PACK);
|
||||
RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
|
||||
RECORD(EXPR_CUDA_KERNEL_CALL);
|
||||
#undef RECORD
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ namespace clang {
|
|||
void VisitSubstNonTypeTemplateParmPackExpr(
|
||||
SubstNonTypeTemplateParmPackExpr *E);
|
||||
void VisitOpaqueValueExpr(OpaqueValueExpr *E);
|
||||
|
||||
// CUDA Expressions
|
||||
void VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1324,6 +1327,16 @@ void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|||
Code = serialization::EXPR_OPAQUE_VALUE;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CUDA Expressions and Statements.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
||||
VisitCallExpr(E);
|
||||
Writer.AddStmt(E->getConfig());
|
||||
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ASTWriter Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -894,6 +894,7 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
|
|||
case Stmt::PredefinedExprClass:
|
||||
case Stmt::ShuffleVectorExprClass:
|
||||
case Stmt::VAArgExprClass:
|
||||
case Stmt::CUDAKernelCallExprClass:
|
||||
// Fall through.
|
||||
|
||||
// Cases we intentionally don't evaluate, since they don't need
|
||||
|
|
|
@ -187,6 +187,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
|
|||
case Stmt::CallExprClass:
|
||||
case Stmt::CXXOperatorCallExprClass:
|
||||
case Stmt::CXXMemberCallExprClass:
|
||||
case Stmt::CUDAKernelCallExprClass:
|
||||
case Stmt::CXXConstructExprClass:
|
||||
case Stmt::CXXTemporaryObjectExprClass:
|
||||
// FIXME: CXXUnresolvedConstructExpr
|
||||
|
|
Loading…
Reference in New Issue