27#include "llvm/ADT/SmallVector.h"
36 if (
auto *A = D->
getAttr<AttrT>())
37 return !A->isImplicit();
42 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
43 ForceHostDeviceDepth++;
47 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
48 if (ForceHostDeviceDepth == 0)
50 ForceHostDeviceDepth--;
57 bool IsDeviceKernelCall =
false;
61 IsDeviceKernelCall =
true;
65 IsDeviceKernelCall =
true;
72 IsDeviceKernelCall =
false;
76 IsDeviceKernelCall =
false;
79 IsDeviceKernelCall =
false;
89 Diag(LLLLoc, diag::err_cuda_device_kernel_launch_not_supported));
99 if (IsDeviceKernelCall) {
110 SemaRef.MarkFunctionReferenced(LLLLoc, ConfigDecl);
112 if (IsDeviceKernelCall) {
119 SemaRef.Context.IntTy, LLLLoc));
123 SemaRef.Context.IntTy, LLLLoc));
125 llvm::append_range(Args, ExecConfig);
127 if (Args.size() < 4) {
128 llvm::APInt One(
SemaRef.Context.getTypeSize(
SemaRef.Context.IntTy), 1);
130 SemaRef.Context.IntTy, LLLLoc));
135 SemaRef.Context.IntTy, LLLLoc));
139 SemaRef.Context.NullPtrTy, LLLLoc));
140 return SemaRef.BuildCallExpr(S, ConfigDR, LLLLoc, Args, GGGLoc,
nullptr,
143 return SemaRef.BuildCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc,
nullptr,
148 bool HasHostAttr =
false;
149 bool HasDeviceAttr =
false;
150 bool HasGlobalAttr =
false;
151 bool HasInvalidTargetAttr =
false;
153 switch (AL.getKind()) {
154 case ParsedAttr::AT_CUDAGlobal:
155 HasGlobalAttr =
true;
157 case ParsedAttr::AT_CUDAHost:
160 case ParsedAttr::AT_CUDADevice:
161 HasDeviceAttr =
true;
163 case ParsedAttr::AT_CUDAInvalidTarget:
164 HasInvalidTargetAttr =
true;
171 if (HasInvalidTargetAttr)
177 if (HasHostAttr && HasDeviceAttr)
189 return isa<A>(Attribute) &&
190 !(IgnoreImplicitAttr && Attribute->isImplicit());
199 auto *VD = dyn_cast_or_null<VarDecl>(D);
200 if (VD && VD->hasGlobalStorage() && !VD->isStaticLocal()) {
207 S.CurCUDATargetCtx = {
Target, K, VD};
213 bool IgnoreImplicitHDAttr) {
224 if (D->
hasAttr<CUDAInvalidTargetAttr>())
227 if (D->
hasAttr<CUDAGlobalAttr>())
240 !IgnoreImplicitHDAttr) {
251 if (Var->
hasAttr<HIPManagedAttr>())
257 Var->
hasAttr<CUDAConstantAttr>() &&
260 if (Var->
hasAttr<CUDADeviceAttr>() || Var->
hasAttr<CUDAConstantAttr>() ||
261 Var->
hasAttr<CUDASharedAttr>() ||
314 assert(Callee &&
"Callee must be valid.");
345 if (CalleeTarget == CallerTarget ||
389 llvm_unreachable(
"All cases should've been handled by now.");
395 if (
auto *A = D->
getAttr<AttrT>())
396 return A->isImplicit();
403 return IsImplicitDevAttr && IsImplicitHostAttr;
413 if (Matches.size() <= 1)
416 using Pair = std::pair<DeclAccessPair, FunctionDecl *>;
419 auto GetCFP = [&](
const Pair &
Match) {
425 GetCFP(*llvm::max_element(Matches, [&](
const Pair &M1,
const Pair &M2) {
426 return GetCFP(M1) < GetCFP(M2);
430 llvm::erase_if(Matches,
431 [&](
const Pair &
Match) {
return GetCFP(
Match) < BestCFP; });
451 *ResolvedTarget = Target2;
453 *ResolvedTarget = Target1;
454 }
else if (Target1 != Target2) {
457 *ResolvedTarget = Target1;
472 bool HasH = MemberDecl->
hasAttr<CUDAHostAttr>();
473 bool HasD = MemberDecl->
hasAttr<CUDADeviceAttr>();
474 bool HasExplicitAttr =
475 (HasD && !MemberDecl->
getAttr<CUDADeviceAttr>()->isImplicit()) ||
476 (HasH && !MemberDecl->
getAttr<CUDAHostAttr>()->isImplicit());
477 if (!InClass || HasExplicitAttr)
480 std::optional<CUDAFunctionTarget> InferredTarget;
492 for (
const auto &B : ClassDecl->
bases()) {
493 if (!B.isVirtual()) {
499 llvm::append_range(Bases, llvm::make_pointer_range(ClassDecl->
vbases()));
501 for (
const auto *B : Bases) {
502 auto *BaseClassDecl = B->getType()->getAsCXXRecordDecl();
507 SemaRef.LookupSpecialMember(BaseClassDecl, CSM,
519 if (!InferredTarget) {
520 InferredTarget = BaseMethodTarget;
523 *InferredTarget, BaseMethodTarget, &*InferredTarget);
524 if (ResolutionError) {
527 diag::note_implicit_member_target_infer_collision)
528 << (
unsigned)CSM << *InferredTarget << BaseMethodTarget;
538 for (
const auto *F : ClassDecl->
fields()) {
539 if (F->isInvalidDecl()) {
549 SemaRef.LookupSpecialMember(FieldRecDecl, CSM,
550 ConstRHS && !F->isMutable(),
561 if (!InferredTarget) {
562 InferredTarget = FieldMethodTarget;
565 *InferredTarget, FieldMethodTarget, &*InferredTarget);
566 if (ResolutionError) {
569 diag::note_implicit_member_target_infer_collision)
570 << (
unsigned)CSM << *InferredTarget << FieldMethodTarget;
581 bool NeedsH =
true, NeedsD =
true;
582 if (InferredTarget) {
627 if (const CXXConstructExpr *CE =
628 dyn_cast<CXXConstructExpr>(CI->getInit()))
629 return isEmptyConstructor(Loc, CE->getConstructor());
671 if (CXXRecordDecl *RD = BS.getType()->getAsCXXRecordDecl())
672 return isEmptyDestructor(Loc, RD->getDestructor());
679 if (CXXRecordDecl *RD = Field->getType()
680 ->getBaseElementTypeUnsafe()
681 ->getAsCXXRecordDecl())
682 return isEmptyDestructor(Loc, RD->getDestructor());
691enum CUDAInitializerCheckKind {
692 CICK_DeviceOrConstant,
696bool IsDependentVar(
VarDecl *VD) {
700 return Init->isValueDependent();
713bool HasAllowedCUDADeviceStaticInitializer(
SemaCUDA &S, VarDecl *VD,
714 CUDAInitializerCheckKind CheckKind) {
716 assert(!IsDependentVar(VD) &&
"do not check dependent var");
718 auto IsEmptyInit = [&](
const Expr *
Init) {
721 if (
const auto *CE = dyn_cast<CXXConstructExpr>(
Init)) {
726 auto IsConstantInit = [&](
const Expr *
Init) {
728 ASTContext::CUDAConstantEvalContextRAII EvalCtx(S.
getASTContext(),
733 auto HasEmptyDtor = [&](VarDecl *VD) {
738 if (CheckKind == CICK_Shared)
739 return IsEmptyInit(
Init) && HasEmptyDtor(VD);
741 ((IsEmptyInit(
Init) || IsConstantInit(
Init)) && HasEmptyDtor(VD));
753 bool IsSharedVar = VD->
hasAttr<CUDASharedAttr>();
754 bool IsDeviceOrConstantVar =
756 (VD->
hasAttr<CUDADeviceAttr>() || VD->
hasAttr<CUDAConstantAttr>());
757 if ((IsSharedVar || IsDeviceOrConstantVar) &&
769 if (IsDeviceOrConstantVar || IsSharedVar) {
770 if (HasAllowedCUDADeviceStaticInitializer(
771 *
this, VD, IsSharedVar ? CICK_Shared : CICK_DeviceOrConstant))
774 IsSharedVar ? diag::err_shared_var_init : diag::err_dynamic_var_init)
775 <<
Init->getSourceRange();
792 diag::err_ref_bad_target_global_initializer)
793 << InitFnTarget << FD;
794 SCRef.
Diag(FD->getLocation(), diag::note_previous_decl) << FD;
803 if (
auto *VarD = dyn_cast<VarDecl>(DRE->
getDecl());
804 VarD && VarD->hasAttr<HIPManagedAttr>()) {
806 diag::err_cuda_invalid_use_of_managedvar);
808 diag::note_cuda_managed_var_in_glob_init);
811 void VisitCallExpr(
const CallExpr *CE) {
814 CheckForWrongSidedCall(InitFn);
815 Base::VisitCallExpr(CE);
821 CheckForWrongSidedCall(Ctor);
822 for (
auto *I : Ctor->
inits())
825 Base::VisitCXXConstructExpr(CE);
836 GlobVarInitChecker Checker(*
this, VD);
857 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(Caller))))
877 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
879 if (ForceHostDeviceDepth > 0) {
880 if (!NewD->
hasAttr<CUDAHostAttr>())
882 if (!NewD->
hasAttr<CUDADeviceAttr>())
889 if (
getLangOpts().OffloadImplicitHostDeviceTemplates &&
890 !NewD->
hasAttr<CUDAHostAttr>() && !NewD->
hasAttr<CUDADeviceAttr>() &&
891 !NewD->
hasAttr<CUDAGlobalAttr>() &&
901 NewD->
hasAttr<CUDADeviceAttr>() || NewD->
hasAttr<CUDAGlobalAttr>())
906 auto IsMatchingDeviceFn = [&](
NamedDecl *D) {
908 D = Using->getTargetDecl();
910 return OldD && OldD->
hasAttr<CUDADeviceAttr>() &&
911 !OldD->
hasAttr<CUDAHostAttr>() &&
912 !
SemaRef.IsOverload(NewD, OldD,
916 auto It = llvm::find_if(
Previous, IsMatchingDeviceFn);
923 if (!
SemaRef.getSourceManager().isInSystemHeader(
Match->getLocation())) {
925 diag::err_cuda_unattributed_constexpr_cannot_overload_device)
928 diag::note_cuda_conflicting_device_function_declared_here);
944 !VD->
hasAttr<CUDASharedAttr>() &&
946 !IsDependentVar(VD) &&
948 HasAllowedCUDADeviceStaticInitializer(*
this, VD,
949 CICK_DeviceOrConstant))) {
956 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
958 SemaRef.getCurFunctionDecl(
true);
959 SemaDiagnosticBuilder::Kind DiagKind = [&] {
961 return SemaDiagnosticBuilder::K_Nop;
965 return SemaDiagnosticBuilder::K_Immediate;
971 return SemaDiagnosticBuilder::K_Nop;
972 if (
SemaRef.IsLastErrorImmediate &&
974 return SemaDiagnosticBuilder::K_Immediate;
976 return SemaDiagnosticBuilder::K_Deferred;
977 return (
SemaRef.getEmissionStatus(CurFunContext) ==
979 ? SemaDiagnosticBuilder::K_ImmediateWithCallStack
980 : SemaDiagnosticBuilder::K_Deferred;
982 return SemaDiagnosticBuilder::K_Nop;
990 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
992 SemaRef.getCurFunctionDecl(
true);
993 SemaDiagnosticBuilder::Kind DiagKind = [&] {
995 return SemaDiagnosticBuilder::K_Nop;
998 return SemaDiagnosticBuilder::K_Immediate;
1004 return SemaDiagnosticBuilder::K_Nop;
1005 if (
SemaRef.IsLastErrorImmediate &&
1007 return SemaDiagnosticBuilder::K_Immediate;
1008 return (
SemaRef.getEmissionStatus(CurFunContext) ==
1010 ? SemaDiagnosticBuilder::K_ImmediateWithCallStack
1011 : SemaDiagnosticBuilder::K_Deferred;
1013 return SemaDiagnosticBuilder::K_Nop;
1019bool SemaCUDA::isDeviceVarInit()
const {
1025 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
1027 if (isa_and_present<ParmVarDecl>(
1028 SemaRef.currentEvaluationContext().ManglingContextDecl))
1031 if (
SemaRef.getCurFunctionDecl(
true)) {
1038 if (isDeviceVarInit())
1039 Diag(Loc, diag::err_cuda_device_rtti_var_init) << Op;
1045 const Expr *Use =
nullptr;
1049 ShouldVisitImplicitCode =
true;
1051 ShouldVisitLambdaBody =
false;
1059 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E)
override {
1061 QualType DestTy = E->
getType();
1073 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
1075 "Expected a default member initializer or default argument");
1077 if (!CurFn && !isDeviceVarInit())
1079 RTTIUseFinder Finder;
1080 Finder.TraverseStmt(
Init);
1081 const Expr *Use = Finder.Use;
1085 if (!RTTICheckedDefaultInits.insert({D, CurFn}).second)
1092 Diag(UseLoc, diag::note_cuda_device_rtti_default_used_here) << IsDefaultArg;
1107 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
1108 assert(Callee &&
"Callee may not be null.");
1110 const auto &ExprEvalCtx =
SemaRef.currentEvaluationContext();
1111 if (ExprEvalCtx.isUnevaluated() || ExprEvalCtx.isConstantEvaluated() ||
1112 ExprEvalCtx.isDiscardedStatementContext())
1129 bool CallerKnownEmitted =
SemaRef.getEmissionStatus(Caller) ==
1131 bool CallerIsImplicitHDExplicitInst =
1133 SemaDiagnosticBuilder::Kind DiagKind = [
this, Caller, Callee,
1135 CallerIsImplicitHDExplicitInst] {
1139 assert(Caller &&
"Never/wrongSide calls require a non-null caller");
1143 return (CallerKnownEmitted && !CallerIsImplicitHDExplicitInst)
1144 ? SemaDiagnosticBuilder::K_ImmediateWithCallStack
1145 : SemaDiagnosticBuilder::K_Deferred;
1147 return SemaDiagnosticBuilder::K_Nop;
1152 bool CallerHD = Caller && Caller->
hasAttr<CUDAHostAttr>() &&
1153 Caller->
hasAttr<CUDADeviceAttr>();
1154 bool CallerDiscard =
SemaRef.getEmissionStatus(Caller) ==
1156 bool RDC =
getLangOpts().GPURelocatableDeviceCode;
1157 if (IsDeviceKernelCall && !(CallerHD && CallerDiscard) && !RDC) {
1158 Diag(Loc, diag::err_cuda_device_kernel_launch_require_rdc);
1162 if (DiagKind == SemaDiagnosticBuilder::K_Nop) {
1165 Callee->hasAttr<CUDAGlobalAttr>() && !Callee->isDefined() &&
1184 if (!Callee->getBuiltinID())
1186 diag::note_previous_decl, Caller,
SemaRef)
1188 return DiagKind != SemaDiagnosticBuilder::K_Immediate &&
1189 DiagKind != SemaDiagnosticBuilder::K_ImmediateWithCallStack;
1220 bool CalleeIsDevice = Callee->hasAttr<CUDADeviceAttr>();
1222 !Caller->
hasAttr<CUDAGlobalAttr>() && !Caller->
hasAttr<CUDADeviceAttr>();
1223 bool ShouldCheck = CalleeIsDevice && CallerIsHost;
1226 auto DiagKind = SemaDiagnosticBuilder::K_Deferred;
1229 diag::err_capture_bad_target, Callee,
SemaRef)
1237 diag::warn_maybe_capture_bad_target_this_ptr, Callee,
1243 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
1244 if (
Method->hasAttr<CUDAHostAttr>() ||
Method->hasAttr<CUDADeviceAttr>())
1252 assert(
getLangOpts().
CUDA &&
"Should only be called during CUDA compilation");
1265 if (NewTarget != OldTarget &&
1266 !
SemaRef.IsOverload(NewFD, OldFD,
false,
1269 !(
getLangOpts().OffloadImplicitHostDeviceTemplates &&
1273 !(
getLangOpts().OffloadImplicitHostDeviceTemplates &&
1279 << NewTarget << NewFD->
getDeclName() << OldTarget << OldFD;
1280 Diag(OldFD->getLocation(), diag::note_previous_declaration);
1289 << NewTarget << OldTarget;
1296template <
typename AttrTy>
1301 if (AttrTy *Attribute = TemplateFD.
getAttr<AttrTy>()) {
1302 AttrTy *Clone = Attribute->clone(S.
Context);
1303 Clone->setInherited(
true);
1318 return "__llvmPushCallConfiguration";
1321 return getLangOpts().HIPUseNewLaunchAPI ?
"__hipPushCallConfiguration"
1322 :
"hipConfigureCall";
1327 return "__cudaPushCallConfiguration";
1330 return "cudaConfigureCall";
1334 return "cudaGetParameterBuffer";
1338 return "cudaLaunchDevice";
1349 for (
unsigned I = 0; I < Arguments.size(); ++I) {
1350 auto *DeclRef = dyn_cast<DeclRefExpr>(Arguments[I]);
1353 auto *Variable = dyn_cast<VarDecl>(DeclRef->getDecl());
1354 if (!Variable || !Variable->isLocalVarDecl() || !Variable->isConstexpr())
1357 bool HostByValue =
false, HostByRef =
false;
1358 bool DeviceByValue =
false, DeviceByRef =
false;
1362 if (!Callee || I >= Callee->getNumParams())
1375 bool IsRef = Callee->getParamDecl(I)->getType()->isReferenceType();
1376 HostByValue |= CoversHost && !IsRef;
1377 HostByRef |= CoversHost && IsRef;
1378 DeviceByValue |= CoversDevice && !IsRef;
1379 DeviceByRef |= CoversDevice && IsRef;
1382 if ((HostByValue && DeviceByRef) || (HostByRef && DeviceByValue))
static bool hasImplicitAttr(const ValueDecl *D)
Defines the clang::ASTContext interface.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::Preprocessor interface.
static bool resolveCalleeCUDATargetConflict(CUDAFunctionTarget Target1, CUDAFunctionTarget Target2, CUDAFunctionTarget *ResolvedTarget)
When an implicitly-declared special member has to invoke more than one base/field special member,...
static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)
static void copyAttrIfPresent(Sema &S, FunctionDecl *FD, const FunctionDecl &TemplateFD)
static bool hasExplicitAttr(const VarDecl *D)
This file declares semantic analysis for CUDA constructs.
FunctionDecl * getcudaGetParameterBufferDecl()
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
llvm::SetVector< const ValueDecl * > CUDAExternalDeviceDeclODRUsedByHost
Keep track of CUDA/HIP external kernels or device variables ODR-used by host code.
llvm::DenseSet< const FunctionDecl * > CUDAImplicitHostDeviceFunUsedByDevice
Keep track of CUDA/HIP implicit host device functions used on device side in device compilation.
FunctionDecl * getcudaConfigureCallDecl()
FunctionDecl * getcudaLaunchDeviceDecl()
Attr - This represents one attribute.
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Represents a C++ constructor within a class.
Represents a C++ base or member initializer.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CastKind getCastKind() const
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
This represents one expression.
Represents a member of a struct/union/class.
Represents a function declaration or definition.
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
bool isImplicitHDExplicitInstantiation() const
True if both host and device are implicit attributes and this is (or is a member of) an explicit temp...
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the results of name lookup.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
ParsedAttr - Represents a syntactic attribute.
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
LangAS getAddressSpace() const
field_range fields() const
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Scope - A scope is a transient data structure that is used while parsing the program.
A generic diagnostic builder for errors which may or may not be deferred.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
std::string getLaunchDeviceFuncName() const
Return the name of the device kernel launch function.
void PushForceHostDevice()
Increments our count of the number of times we've seen a pragma forcing functions to be host device.
void checkAllowedInitializer(VarDecl *VD)
void RecordImplicitHostDeviceFuncUsedByDevice(const FunctionDecl *FD)
Record FD if it is a CUDA/HIP implicit host device function used on device side in device compilation...
std::string getConfigureFuncName() const
Returns the name of the launch configuration function.
bool PopForceHostDevice()
Decrements our count of the number of times we've seen a pragma forcing functions to be host device.
CUDAFunctionTarget IdentifyTarget(const FunctionDecl *D, bool IgnoreImplicitHDAttr=false)
Determines whether the given function is a CUDA device/host/kernel/etc.
static bool isImplicitHDExplicitInstantiation(const FunctionDecl *FD)
Null-tolerant wrapper for FunctionDecl::isImplicitHDExplicitInstantiation.
void maybeAddHostDeviceAttrs(FunctionDecl *FD, const LookupResult &Previous)
May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, depending on FD and the current co...
ExprResult ActOnExecConfigExpr(Scope *S, SourceLocation LLLLoc, MultiExprArg ExecConfig, SourceLocation GGGLoc)
bool isEmptyConstructor(SourceLocation Loc, CXXConstructorDecl *CD)
std::string getGetParameterBufferFuncName() const
Return the name of the parameter buffer allocation function for the device kernel launch.
bool isEmptyDestructor(SourceLocation Loc, CXXDestructorDecl *CD)
void checkTargetOverload(FunctionDecl *NewFD, const LookupResult &Previous)
Check whether NewFD is a valid overload for CUDA.
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
SemaDiagnosticBuilder DiagIfHostCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as host cod...
bool inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, CXXMethodDecl *MemberDecl, bool ConstRHS, bool Diagnose)
Given a implicit special member, infer its CUDA target from the calls it needs to make to underlying ...
struct clang::SemaCUDA::CUDATargetContext CurCUDATargetCtx
CUDATargetContextKind
Defines kinds of CUDA global host/device context where a function may be called.
@ CTCK_InitGlobalVar
Unknown context.
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
llvm::DenseSet< FunctionDeclAndLoc > LocsWithCUDACallDiags
FunctionDecls and SourceLocations for which CheckCall has emitted a (maybe deferred) "bad call" diagn...
bool CheckCall(SourceLocation Loc, FunctionDecl *Callee)
Check whether we're allowed to call Callee from the current context.
void inheritTargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD)
Copies target attributes from the template TD to the function FD.
static bool isImplicitHostDeviceFunction(const FunctionDecl *D)
void CheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture)
void MaybeAddConstantAttr(VarDecl *VD)
May add implicit CUDAConstantAttr attribute to VD, depending on VD and current compilation settings.
void EraseUnwantedMatches(const FunctionDecl *Caller, llvm::SmallVectorImpl< std::pair< DeclAccessPair, FunctionDecl * > > &Matches)
Finds a function in Matches with highest calling priority from Caller context and erases all function...
void checkRTTIInDefaultInit(const ValueDecl *D, const Expr *Init, SourceLocation UseLoc)
Diagnoses a use of RTTI in Init, the default argument or default member initializer of D if it is use...
void SetLambdaAttrs(CXXMethodDecl *Method)
Set device or host device attributes on the given lambda operator() method.
void checkRTTIUse(SourceLocation Loc, StringRef Op)
Diagnoses a use of RTTI at Loc if it is in device function or the initializer of a device variable,...
CUDAFunctionPreference IdentifyPreference(const FunctionDecl *Caller, const FunctionDecl *Callee)
Identifies relative preference of a given Caller/Callee combination, based on their host/device attri...
void recordPotentialODRUsedVariable(MultiExprArg Args, OverloadCandidateSet &CandidateSet)
Record variables that are potentially ODR-used in CUDA/HIP.
@ CVT_Host
Emitted on device side with a shadow variable on host side.
@ CVT_Both
Emitted on host side only.
@ CVT_Unified
Emitted on both sides with different addresses.
SpecialMemberOverloadResult - The overloading result for a special member function.
CXXMethodDecl * getMethod() const
Sema - This implements semantic analysis and AST building for C.
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isFileVarDecl() const
Returns true for file scoped variable declaration.
const Expr * getInit() const
ValueDecl * getVariable() const
bool isVariableCapture() const
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
bool isThisCapture() const
bool isReferenceCapture() const
llvm::SmallPtrSet< VarDecl *, 4 > CUDAPotentialODRUsedVars
Variables that are potentially ODR-used in CUDA/HIP.
Defines the clang::TargetInfo interface.
Top level wrappers for InstallAPI frontend operations.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
DynamicRecursiveASTVisitorBase< true > ConstDynamicRecursiveASTVisitor
MutableArrayRef< Expr * > MultiExprArg
bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature)
CXXSpecialMemberKind
Kinds of C++ special members.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
ActionResult< Expr * > ExprResult
OverloadCandidate - A single candidate in an overload set (C++ 13.3).
CUDATargetContextKind Kind
CUDAFunctionTarget Target