//===--- SemaCUDA.cpp - Semantic Analysis for CUDA constructs -------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// \file /// \brief This file implements semantic analysis for CUDA constructs. /// //===----------------------------------------------------------------------===// #include "clang/Sema/Sema.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/Sema/SemaDiagnostic.h" using namespace clang; 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, false, ConfigQTy, VK_LValue, LLLLoc); MarkFunctionReferenced(LLLLoc, ConfigDecl); return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr, /*IsExecConfig=*/true); } /// IdentifyCUDATarget - Determine the CUDA compilation target for this function Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { // Implicitly declared functions (e.g. copy constructors) are // __host__ __device__ if (D->isImplicit()) return CFT_HostDevice; if (D->hasAttr()) return CFT_Global; if (D->hasAttr()) { if (D->hasAttr()) return CFT_HostDevice; return CFT_Device; } return CFT_Host; } bool Sema::CheckCUDATarget(CUDAFunctionTarget CallerTarget, CUDAFunctionTarget CalleeTarget) { // CUDA B.1.1 "The __device__ qualifier declares a function that is... // Callable from the device only." if (CallerTarget == CFT_Host && CalleeTarget == CFT_Device) return true; // CUDA B.1.2 "The __global__ qualifier declares a function that is... // Callable from the host only." // CUDA B.1.3 "The __host__ qualifier declares a function that is... // Callable from the host only." if ((CallerTarget == CFT_Device || CallerTarget == CFT_Global) && (CalleeTarget == CFT_Host || CalleeTarget == CFT_Global)) return true; if (CallerTarget == CFT_HostDevice && CalleeTarget != CFT_HostDevice) return true; return false; }