@@ -6117,6 +6117,22 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
6117
6117
return false;
6118
6118
}
6119
6119
6120
+ void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) {
6121
+ if (Decl->getType().getQualifiers().hasAddressSpace())
6122
+ return;
6123
+ if (VarDecl *Var = dyn_cast<VarDecl>(Decl)) {
6124
+ QualType Type = Var->getType();
6125
+ if (Type->isSamplerT() || Type->isVoidType())
6126
+ return;
6127
+ LangAS ImplAS = LangAS::opencl_private;
6128
+ if ((getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) &&
6129
+ Var->hasGlobalStorage())
6130
+ ImplAS = LangAS::opencl_global;
6131
+ Type = Context.getAddrSpaceQualType(Type, ImplAS);
6132
+ Decl->setType(Type);
6133
+ }
6134
+ }
6135
+
6120
6136
static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
6121
6137
// Ensure that an auto decl is deduced otherwise the checks below might cache
6122
6138
// the wrong linkage.
@@ -6474,6 +6490,105 @@ static bool isDeclExternC(const Decl *D) {
6474
6490
6475
6491
llvm_unreachable("Unknown type of decl!");
6476
6492
}
6493
+ /// Returns true if there hasn't been any invalid type diagnosed.
6494
+ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D,
6495
+ DeclContext *DC, QualType R) {
6496
+ // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument.
6497
+ // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function
6498
+ // argument.
6499
+ if (R->isImageType() || R->isPipeType()) {
6500
+ Se.Diag(D.getIdentifierLoc(),
6501
+ diag::err_opencl_type_can_only_be_used_as_function_parameter)
6502
+ << R;
6503
+ D.setInvalidType();
6504
+ return false;
6505
+ }
6506
+
6507
+ // OpenCL v1.2 s6.9.r:
6508
+ // The event type cannot be used to declare a program scope variable.
6509
+ // OpenCL v2.0 s6.9.q:
6510
+ // The clk_event_t and reserve_id_t types cannot be declared in program
6511
+ // scope.
6512
+ if (NULL == S->getParent()) {
6513
+ if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) {
6514
+ Se.Diag(D.getIdentifierLoc(),
6515
+ diag::err_invalid_type_for_program_scope_var)
6516
+ << R;
6517
+ D.setInvalidType();
6518
+ return false;
6519
+ }
6520
+ }
6521
+
6522
+ // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
6523
+ QualType NR = R;
6524
+ while (NR->isPointerType()) {
6525
+ if (NR->isFunctionPointerType()) {
6526
+ Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer);
6527
+ D.setInvalidType();
6528
+ return false;
6529
+ }
6530
+ NR = NR->getPointeeType();
6531
+ }
6532
+
6533
+ if (!Se.getOpenCLOptions().isEnabled("cl_khr_fp16")) {
6534
+ // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
6535
+ // half array type (unless the cl_khr_fp16 extension is enabled).
6536
+ if (Se.Context.getBaseElementType(R)->isHalfType()) {
6537
+ Se.Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
6538
+ D.setInvalidType();
6539
+ return false;
6540
+ }
6541
+ }
6542
+
6543
+ // OpenCL v1.2 s6.9.r:
6544
+ // The event type cannot be used with the __local, __constant and __global
6545
+ // address space qualifiers.
6546
+ if (R->isEventT()) {
6547
+ if (R.getAddressSpace() != LangAS::opencl_private) {
6548
+ Se.Diag(D.getBeginLoc(), diag::err_event_t_addr_space_qual);
6549
+ D.setInvalidType();
6550
+ return false;
6551
+ }
6552
+ }
6553
+
6554
+ // C++ for OpenCL does not allow the thread_local storage qualifier.
6555
+ // OpenCL C does not support thread_local either, and
6556
+ // also reject all other thread storage class specifiers.
6557
+ DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
6558
+ if (TSC != TSCS_unspecified) {
6559
+ bool IsCXX = Se.getLangOpts().OpenCLCPlusPlus;
6560
+ Se.Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
6561
+ diag::err_opencl_unknown_type_specifier)
6562
+ << IsCXX << Se.getLangOpts().getOpenCLVersionTuple().getAsString()
6563
+ << DeclSpec::getSpecifierName(TSC) << 1;
6564
+ D.setInvalidType();
6565
+ return false;
6566
+ }
6567
+
6568
+ if (R->isSamplerT()) {
6569
+ // OpenCL v1.2 s6.9.b p4:
6570
+ // The sampler type cannot be used with the __local and __global address
6571
+ // space qualifiers.
6572
+ if (R.getAddressSpace() == LangAS::opencl_local ||
6573
+ R.getAddressSpace() == LangAS::opencl_global) {
6574
+ Se.Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
6575
+ D.setInvalidType();
6576
+ }
6577
+
6578
+ // OpenCL v1.2 s6.12.14.1:
6579
+ // A global sampler must be declared with either the constant address
6580
+ // space qualifier or with the const qualifier.
6581
+ if (DC->isTranslationUnit() &&
6582
+ !(R.getAddressSpace() == LangAS::opencl_constant ||
6583
+ R.isConstQualified())) {
6584
+ Se.Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
6585
+ D.setInvalidType();
6586
+ }
6587
+ if (D.isInvalidType())
6588
+ return false;
6589
+ }
6590
+ return true;
6591
+ }
6477
6592
6478
6593
NamedDecl *Sema::ActOnVariableDeclarator(
6479
6594
Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
@@ -6497,95 +6612,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
6497
6612
return nullptr;
6498
6613
}
6499
6614
6500
- if (getLangOpts().OpenCL) {
6501
- // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument.
6502
- // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function
6503
- // argument.
6504
- if (R->isImageType() || R->isPipeType()) {
6505
- Diag(D.getIdentifierLoc(),
6506
- diag::err_opencl_type_can_only_be_used_as_function_parameter)
6507
- << R;
6508
- D.setInvalidType();
6509
- return nullptr;
6510
- }
6511
-
6512
- // OpenCL v1.2 s6.9.r:
6513
- // The event type cannot be used to declare a program scope variable.
6514
- // OpenCL v2.0 s6.9.q:
6515
- // The clk_event_t and reserve_id_t types cannot be declared in program scope.
6516
- if (NULL == S->getParent()) {
6517
- if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) {
6518
- Diag(D.getIdentifierLoc(),
6519
- diag::err_invalid_type_for_program_scope_var) << R;
6520
- D.setInvalidType();
6521
- return nullptr;
6522
- }
6523
- }
6524
-
6525
- // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
6526
- QualType NR = R;
6527
- while (NR->isPointerType()) {
6528
- if (NR->isFunctionPointerType()) {
6529
- Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer);
6530
- D.setInvalidType();
6531
- break;
6532
- }
6533
- NR = NR->getPointeeType();
6534
- }
6535
-
6536
- if (!getOpenCLOptions().isEnabled("cl_khr_fp16")) {
6537
- // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
6538
- // half array type (unless the cl_khr_fp16 extension is enabled).
6539
- if (Context.getBaseElementType(R)->isHalfType()) {
6540
- Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
6541
- D.setInvalidType();
6542
- }
6543
- }
6544
-
6545
- if (R->isSamplerT()) {
6546
- // OpenCL v1.2 s6.9.b p4:
6547
- // The sampler type cannot be used with the __local and __global address
6548
- // space qualifiers.
6549
- if (R.getAddressSpace() == LangAS::opencl_local ||
6550
- R.getAddressSpace() == LangAS::opencl_global) {
6551
- Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
6552
- }
6553
-
6554
- // OpenCL v1.2 s6.12.14.1:
6555
- // A global sampler must be declared with either the constant address
6556
- // space qualifier or with the const qualifier.
6557
- if (DC->isTranslationUnit() &&
6558
- !(R.getAddressSpace() == LangAS::opencl_constant ||
6559
- R.isConstQualified())) {
6560
- Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
6561
- D.setInvalidType();
6562
- }
6563
- }
6564
-
6565
- // OpenCL v1.2 s6.9.r:
6566
- // The event type cannot be used with the __local, __constant and __global
6567
- // address space qualifiers.
6568
- if (R->isEventT()) {
6569
- if (R.getAddressSpace() != LangAS::opencl_private) {
6570
- Diag(D.getBeginLoc(), diag::err_event_t_addr_space_qual);
6571
- D.setInvalidType();
6572
- }
6573
- }
6574
-
6575
- // C++ for OpenCL does not allow the thread_local storage qualifier.
6576
- // OpenCL C does not support thread_local either, and
6577
- // also reject all other thread storage class specifiers.
6578
- DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
6579
- if (TSC != TSCS_unspecified) {
6580
- bool IsCXX = getLangOpts().OpenCLCPlusPlus;
6581
- Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
6582
- diag::err_opencl_unknown_type_specifier)
6583
- << IsCXX << getLangOpts().getOpenCLVersionTuple().getAsString()
6584
- << DeclSpec::getSpecifierName(TSC) << 1;
6585
- D.setInvalidType();
6586
- return nullptr;
6587
- }
6588
- }
6589
6615
6590
6616
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
6591
6617
StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());
@@ -6942,6 +6968,13 @@ NamedDecl *Sema::ActOnVariableDeclarator(
6942
6968
}
6943
6969
}
6944
6970
6971
+ if (getLangOpts().OpenCL) {
6972
+
6973
+ deduceOpenCLAddressSpace(NewVD);
6974
+
6975
+ diagnoseOpenCLTypes(S, *this, D, DC, NewVD->getType());
6976
+ }
6977
+
6945
6978
// Handle attributes prior to checking for duplicates in MergeVarDecl
6946
6979
ProcessDeclAttributes(S, NewVD, D);
6947
6980
@@ -11285,6 +11318,9 @@ bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
11285
11318
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
11286
11319
VDecl->setInvalidDecl();
11287
11320
11321
+ if (getLangOpts().OpenCL)
11322
+ deduceOpenCLAddressSpace(VDecl);
11323
+
11288
11324
// If this is a redeclaration, check that the type we just deduced matches
11289
11325
// the previously declared type.
11290
11326
if (VarDecl *Old = VDecl->getPreviousDecl()) {
@@ -13107,6 +13143,10 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
13107
13143
if (New->hasAttr<BlocksAttr>()) {
13108
13144
Diag(New->getLocation(), diag::err_block_on_nonlocal);
13109
13145
}
13146
+
13147
+ if (getLangOpts().OpenCL)
13148
+ deduceOpenCLAddressSpace(New);
13149
+
13110
13150
return New;
13111
13151
}
13112
13152
0 commit comments