33 "Should only be called during SYCL compilation");
35 SemaDiagnosticBuilder::Kind DiagKind = [
this, FD] {
37 return SemaDiagnosticBuilder::K_Nop;
39 return SemaDiagnosticBuilder::K_ImmediateWithCallStack;
40 return SemaDiagnosticBuilder::K_Deferred;
47 return CAT->isZeroSize();
52 llvm::DenseSet<QualType>
Visited,
55 "Should only be called during SYCL compilation");
58 bool NeedToEmitNotes =
true;
61 bool ErrorFound =
false;
68 if (NeedToEmitNotes) {
69 if (
auto *FD = dyn_cast<FieldDecl>(
D))
71 diag::note_illegal_field_declared_here)
72 << FD->getType()->isPointerType() << FD->getType();
83 StackForRecursion.push_back(DeclToCheck);
87 History.push_back(
nullptr);
90 const ValueDecl *Next = StackForRecursion.pop_back_val();
92 assert(!History.empty());
99 if (!
Visited.insert(NextTy).second)
102 auto EmitHistory = [&]() {
104 for (uint64_t Index = 1; Index < History.size(); ++Index) {
106 diag::note_within_field_of_type)
107 << History[Index]->getType();
111 if (Check(NextTy, Next)) {
114 NeedToEmitNotes =
false;
125 if (Check(NextTy, Next)) {
128 NeedToEmitNotes =
false;
133 if (
auto *NextFD = dyn_cast<FieldDecl>(Next))
134 History.push_back(NextFD);
137 StackForRecursion.push_back(
nullptr);
138 llvm::append_range(StackForRecursion, RecDecl->fields());
140 }
while (!StackForRecursion.empty());
168 const auto *FD = cast<FunctionDecl>(
D);
170 assert(FT &&
"Function template is expected");
174 if (TL->
size() < 2) {
175 Diag(FT->
getLocation(), diag::warn_sycl_kernel_num_of_template_params);
180 for (
unsigned I = 0; I < 2; ++I) {
182 if (isa<NonTypeTemplateParmDecl>(TParam)) {
184 diag::warn_sycl_kernel_invalid_template_param_type);
191 Diag(FT->
getLocation(), diag::warn_sycl_kernel_num_of_function_params);
202 handleSimpleAttribute<DeviceKernelAttr>(*
this,
D, AL);
209 assert(TSI &&
"no type source info for attribute argument");
223 if (
const TagType *TT = dyn_cast<TagType>(
T))
224 Loc = TT->getOriginalDecl()->getLocation();
226 Loc = ObjCIT->getDecl()->getLocation();
243 S.
Diag(
Loc, diag::warn_sycl_kernel_name_not_a_class_type) << KernelName;
246 S.
Diag(DeclTypeLoc, diag::note_entity_declared_at) << KernelName;
254 const auto *SEAttr = FD->
getAttr<SYCLExternalAttr>();
255 assert(SEAttr &&
"Missing sycl_external attribute");
260 Diag(SEAttr->getLocation(), diag::err_sycl_external_invalid_linkage)
264 Diag(SEAttr->getLocation(),
265 diag::err_sycl_external_invalid_deleted_function)
273 SYCLKernelEntryPointAttr *SKEPAttr =
nullptr;
274 for (
auto *SAI : FD->
specific_attrs<SYCLKernelEntryPointAttr>()) {
280 SKEPAttr->getKernelName())) {
281 Diag(SAI->getLocation(), diag::err_sycl_entry_point_invalid_redeclaration)
282 << SKEPAttr << SAI->getKernelName() << SKEPAttr->getKernelName();
283 Diag(SKEPAttr->getLocation(), diag::note_previous_attribute);
284 SAI->setInvalidAttr();
286 Diag(SAI->getLocation(),
287 diag::warn_sycl_entry_point_redundant_declaration)
289 Diag(SKEPAttr->getLocation(), diag::note_previous_attribute);
292 assert(SKEPAttr &&
"Missing sycl_kernel_entry_point attribute");
295 if (!SKEPAttr->getKernelName()->isDependentType() &&
297 SKEPAttr->getKernelName()))
298 SKEPAttr->setInvalidAttr();
304 const auto *PrevSKEPAttr = PrevFD->
getAttr<SYCLKernelEntryPointAttr>();
305 if (PrevSKEPAttr && !PrevSKEPAttr->isInvalidAttr()) {
307 PrevSKEPAttr->getKernelName())) {
308 Diag(SKEPAttr->getLocation(),
309 diag::err_sycl_entry_point_invalid_redeclaration)
310 << SKEPAttr << SKEPAttr->getKernelName()
311 << PrevSKEPAttr->getKernelName();
312 Diag(PrevSKEPAttr->getLocation(), diag::note_previous_decl) << PrevFD;
313 SKEPAttr->setInvalidAttr();
318 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
319 if (!MD->isStatic()) {
320 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
322 SKEPAttr->setInvalidAttr();
327 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
329 SKEPAttr->setInvalidAttr();
333 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
335 SKEPAttr->setInvalidAttr();
337 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
339 SKEPAttr->setInvalidAttr();
343 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
345 SKEPAttr->setInvalidAttr();
347 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
349 SKEPAttr->setInvalidAttr();
353 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
355 SKEPAttr->setInvalidAttr();
359 Diag(SKEPAttr->getLocation(),
360 diag::err_sycl_entry_point_deduced_return_type)
362 SKEPAttr->setInvalidAttr();
365 Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_return_type)
367 SKEPAttr->setInvalidAttr();
371 !SKEPAttr->isInvalidAttr()) {
381 diag::note_previous_declaration);
382 SKEPAttr->setInvalidAttr();
397class OutlinedFunctionDeclBodyInstantiator
398 :
public TreeTransform<OutlinedFunctionDeclBodyInstantiator> {
400 using ParmDeclMap = llvm::DenseMap<ParmVarDecl *, VarDecl *>;
402 OutlinedFunctionDeclBodyInstantiator(
Sema &S, ParmDeclMap &M)
403 :
TreeTransform<OutlinedFunctionDeclBodyInstantiator>(S), SemaRef(S),
407 bool AlwaysRebuild() {
return true; }
413 ParmDeclMap::iterator I = MapRef.find(PVD);
414 if (I != MapRef.end()) {
416 assert(SemaRef.getASTContext().hasSameUnqualifiedType(PVD->
getType(),
419 SemaRef.getASTContext()));
443 const auto *SKEPAttr = FD->
getAttr<SYCLKernelEntryPointAttr>();
444 assert(SKEPAttr &&
"Missing sycl_kernel_entry_point attribute");
445 assert(!SKEPAttr->isInvalidAttr() &&
446 "sycl_kernel_entry_point attribute is invalid");
453 "SYCL kernel name conflict");
456 using ParmDeclMap = OutlinedFunctionDeclBodyInstantiator::ParmDeclMap;
472 OutlinedFunctionDeclBodyInstantiator OFDBodyInstantiator(
SemaRef, ParmMap);
473 Stmt *OFDBody = OFDBodyInstantiator.TransformStmt(Body).get();
Defines the Diagnostic-related interfaces.
llvm::DenseSet< const void * > Visited
This file declares types used to describe SYCL kernels.
static bool isZeroSizedArray(const ConstantArrayType *CAT)
static SourceLocation SourceLocationForUserDeclaredType(QualType QT)
static bool CheckSYCLKernelName(Sema &S, SourceLocation Loc, QualType KernelName)
This file declares semantic analysis for SYCL constructs.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Allows QualTypes to be sorted and hence used in maps and sets.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
void registerSYCLEntryPointFunction(FunctionDecl *FD)
Generates and stores SYCL kernel metadata for the provided SYCL kernel entry point function.
const SYCLKernelInfo & getSYCLKernelInfo(QualType T) const
Given a type used as a SYCL kernel name, returns a reference to the metadata generated from the corre...
const SYCLKernelInfo * findSYCLKernelInfo(QualType T) const
Returns a pointer to the metadata generated from the corresponding SYCLkernel entry point if the prov...
CompoundStmt - This represents a group of statements like { stmt stmt }.
A reference to a declared variable, function, enum, etc.
DeclarationNameInfo getNameInfo() const
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
Decl - This represents one declaration (or definition), e.g.
bool isTemplated() const
Determine whether this declaration is a templated entity (whether it is.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
void setIsUsed()
Set whether the declaration is used, in the sense of odr-use.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Represents a function declaration or definition.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
FunctionTemplateSpecializationInfo * getTemplateSpecializationInfo() const
If this function is actually a function template specialization, retrieve information about this func...
bool isVariadic() const
Whether this function is variadic.
bool isDeleted() const
Whether this function has been deleted.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isDeletedAsWritten() const
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Declaration of a template function.
bool isExplicitSpecialization() const
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
bool isExternallyVisible() const
Interfaces are the core concept in Objective-C for object oriented design.
Represents a partial function definition.
static OutlinedFunctionDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
void setNothrow(bool Nothrow=true)
void setParam(unsigned i, ImplicitParamDecl *P)
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
const ParsedType & getTypeArg() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isMoreQualifiedThan(QualType Other, const ASTContext &Ctx) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
const FunctionDecl * getKernelEntryPointDecl() const
static SYCLUniqueStableNameExpr * Create(const ASTContext &Ctx, SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, TypeSourceInfo *TSI)
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
void CheckSYCLExternalFunctionDecl(FunctionDecl *FD)
ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, TypeSourceInfo *TSI)
void handleKernelEntryPointAttr(Decl *D, const ParsedAttr &AL)
void deepTypeCheckForDevice(SourceLocation UsedAt, llvm::DenseSet< QualType > Visited, ValueDecl *DeclToCheck)
void handleKernelAttr(Decl *D, const ParsedAttr &AL)
StmtResult BuildSYCLKernelCallStmt(FunctionDecl *FD, CompoundStmt *Body)
void CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD)
ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, ParsedType ParsedTy)
Sema - This implements semantic analysis and AST building for C.
ASTContext & getASTContext() const
DeclContext * getCurLexicalContext() const
FunctionEmissionStatus getEmissionStatus(const FunctionDecl *Decl, bool Final=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Stmt - This represents one statement.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
A container of type source information.
The base class of the type hierarchy.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isReferenceType() const
const Type * getArrayElementTypeNoTypeQual() const
If this is an array type, return the element type of the array, potentially with type qualifiers miss...
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 isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isStructureOrClassType() const
bool isAnyPointerType() const
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
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.
The JSON file list parser is used to communicate input to InstallAPI.
QualType getFunctionOrMethodResultType(const Decl *D)
const FunctionProtoType * T
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
@ Other
Other implicit parameter.