llvm_unreachable("Unknown type of decl!");
}
+
/// Returns true if there hasn't been any invalid type diagnosed.
-static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D,
- DeclContext *DC, QualType R) {
+static bool diagnoseOpenCLTypes(Sema &Se, VarDecl *NewVD) {
+ DeclContext *DC = NewVD->getDeclContext();
+ QualType R = NewVD->getType();
+
// OpenCL v2.0 s6.9.b - Image type can only be used as a function argument.
// OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function
// argument.
if (R->isImageType() || R->isPipeType()) {
- Se.Diag(D.getIdentifierLoc(),
+ Se.Diag(NewVD->getLocation(),
diag::err_opencl_type_can_only_be_used_as_function_parameter)
<< R;
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
// OpenCL v2.0 s6.9.q:
// The clk_event_t and reserve_id_t types cannot be declared in program
// scope.
- if (NULL == S->getParent()) {
+ if (NewVD->hasGlobalStorage() && !NewVD->isStaticLocal()) {
if (R->isReserveIDT() || R->isClkEventT() || R->isEventT()) {
- Se.Diag(D.getIdentifierLoc(),
+ Se.Diag(NewVD->getLocation(),
diag::err_invalid_type_for_program_scope_var)
<< R;
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
}
NR->isReferenceType()) {
if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType() ||
NR->isFunctionReferenceType()) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer)
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_function_pointer)
<< NR->isReferenceType();
- D.setInvalidType();
+ NewVD->setInvalidDecl();
return false;
}
NR = NR->getPointeeType();
// OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
// half array type (unless the cl_khr_fp16 extension is enabled).
if (Se.Context.getBaseElementType(R)->isHalfType()) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_half_declaration) << R;
+ NewVD->setInvalidDecl();
return false;
}
}
// address space qualifiers.
if (R->isEventT()) {
if (R.getAddressSpace() != LangAS::opencl_private) {
- Se.Diag(D.getBeginLoc(), diag::err_event_t_addr_space_qual);
- D.setInvalidType();
+ Se.Diag(NewVD->getBeginLoc(), diag::err_event_t_addr_space_qual);
+ NewVD->setInvalidDecl();
return false;
}
}
- // C++ for OpenCL does not allow the thread_local storage qualifier.
- // OpenCL C does not support thread_local either, and
- // also reject all other thread storage class specifiers.
- DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
- if (TSC != TSCS_unspecified) {
- bool IsCXX = Se.getLangOpts().OpenCLCPlusPlus;
- Se.Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
- diag::err_opencl_unknown_type_specifier)
- << IsCXX << Se.getLangOpts().getOpenCLVersionTuple().getAsString()
- << DeclSpec::getSpecifierName(TSC) << 1;
- D.setInvalidType();
- return false;
- }
-
if (R->isSamplerT()) {
// OpenCL v1.2 s6.9.b p4:
// The sampler type cannot be used with the __local and __global address
// space qualifiers.
if (R.getAddressSpace() == LangAS::opencl_local ||
R.getAddressSpace() == LangAS::opencl_global) {
- Se.Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace);
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_wrong_sampler_addressspace);
+ NewVD->setInvalidDecl();
}
// OpenCL v1.2 s6.12.14.1:
if (DC->isTranslationUnit() &&
!(R.getAddressSpace() == LangAS::opencl_constant ||
R.isConstQualified())) {
- Se.Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler);
- D.setInvalidType();
+ Se.Diag(NewVD->getLocation(), diag::err_opencl_nonconst_global_sampler);
+ NewVD->setInvalidDecl();
}
- if (D.isInvalidType())
+ if (NewVD->isInvalidDecl())
return false;
}
+
return true;
}
}
if (getLangOpts().OpenCL) {
-
deduceOpenCLAddressSpace(NewVD);
- diagnoseOpenCLTypes(S, *this, D, DC, NewVD->getType());
+ DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
+ if (TSC != TSCS_unspecified) {
+ bool IsCXX = getLangOpts().OpenCLCPlusPlus;
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_opencl_unknown_type_specifier)
+ << IsCXX << getLangOpts().getOpenCLVersionTuple().getAsString()
+ << DeclSpec::getSpecifierName(TSC) << 1;
+ NewVD->setInvalidDecl();
+ }
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
}
if (getLangOpts().OpenCL) {
+ if (!diagnoseOpenCLTypes(*this, NewVD))
+ return;
+
// OpenCL v2.0 s6.12.5 - The __block storage type is not supported.
if (NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_opencl_block_storage_type);
return;
}
}
+
// OpenCL C v1.2 s6.5 - All program scope variables must be declared in the
// __constant address space.
// OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static