diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9923,7 +9923,7 @@ def err_opencl_variadic_function : Error< "invalid prototype, variadic arguments are not allowed in OpenCL">; def err_opencl_requires_extension : Error< - "use of %select{type|declaration}0 %1 requires %2 extension to be enabled">; + "use of %select{type|declaration}0 %1 requires %2 support">; def warn_opencl_generic_address_space_arg : Warning< "passing non-generic address space pointer to %0" " may cause dynamic conversion affecting performance">, diff --git a/clang/include/clang/Basic/OpenCLOptions.h b/clang/include/clang/Basic/OpenCLOptions.h --- a/clang/include/clang/Basic/OpenCLOptions.h +++ b/clang/include/clang/Basic/OpenCLOptions.h @@ -112,7 +112,10 @@ bool isKnown(llvm::StringRef Ext) const; - bool isEnabled(llvm::StringRef Ext) const; + // For core or optional core feature check that it is supported + // by a target, for any other option (extension) check that it is + // enabled via pragma + bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const; bool isWithPragma(llvm::StringRef Ext) const; @@ -160,15 +163,15 @@ // Disable all extensions void disableAll(); - // Enable supported core and optional core features - void enableSupportedCore(const LangOptions &LO); - friend class ASTWriter; friend class ASTReader; using OpenCLOptionInfoMap = llvm::StringMap; private: + // Option is enabled via pragma + bool isEnabled(llvm::StringRef Ext) const; + OpenCLOptionInfoMap OptMap; }; diff --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp --- a/clang/lib/Basic/OpenCLOptions.cpp +++ b/clang/lib/Basic/OpenCLOptions.cpp @@ -14,9 +14,21 @@ return OptMap.find(Ext) != OptMap.end(); } +bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext, + const LangOptions &LO) const { + if (!isKnown(Ext)) + return false; + + auto &OptInfo = OptMap.find(Ext)->getValue(); + if (OptInfo.isCoreIn(LO) || OptInfo.isOptionalCoreIn(LO)) + return isSupported(Ext, LO); + + return isEnabled(Ext); +} + bool OpenCLOptions::isEnabled(llvm::StringRef Ext) const { - auto E = OptMap.find(Ext); - return E != OptMap.end() && E->second.Enabled; + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Enabled; } bool OpenCLOptions::isWithPragma(llvm::StringRef Ext) const { @@ -26,32 +38,23 @@ bool OpenCLOptions::isSupported(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isAvailableIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isAvailableIn(LO); } bool OpenCLOptions::isSupportedCore(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isCoreIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isCoreIn(LO); } bool OpenCLOptions::isSupportedOptionalCore(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isOptionalCoreIn(LO); + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isOptionalCoreIn(LO); } bool OpenCLOptions::isSupportedCoreOrOptionalCore(llvm::StringRef Ext, @@ -61,12 +64,9 @@ bool OpenCLOptions::isSupportedExtension(llvm::StringRef Ext, const LangOptions &LO) const { - auto E = OptMap.find(Ext); - if (E == OptMap.end()) { - return false; - } - auto I = OptMap.find(Ext)->getValue(); - return I.Supported && I.isAvailableIn(LO) && + auto I = OptMap.find(Ext); + return I != OptMap.end() && I->getValue().Supported && + I->getValue().isAvailableIn(LO) && !isSupportedCoreOrOptionalCore(Ext, LO); } @@ -105,10 +105,4 @@ Opt.getValue().Enabled = false; } -void OpenCLOptions::enableSupportedCore(const LangOptions &LO) { - for (auto &Opt : OptMap) - if (isSupportedCoreOrOptionalCore(Opt.getKey(), LO)) - Opt.getValue().Enabled = true; -} - } // end namespace clang diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3646,8 +3646,8 @@ // C++ for OpenCL does not allow virtual function qualifier, to avoid // function pointers restricted in OpenCL v2.0 s6.9.a. if (getLangOpts().OpenCLCPlusPlus && - !getActions().getOpenCLOptions().isEnabled( - "__cl_clang_function_pointers")) { + !getActions().getOpenCLOptions().isAvailableOption( + "__cl_clang_function_pointers", getLangOpts())) { DiagID = diag::err_openclcxx_virtual_function; PrevSpec = Tok.getIdentifierInfo()->getNameStart(); isInvalid = true; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1807,8 +1807,9 @@ // These can be followed by postfix-expr pieces. PreferredType = SavedType; Res = ParsePostfixExpressionSuffix(Res); - if (getLangOpts().OpenCL && !getActions().getOpenCLOptions().isEnabled( - "__cl_clang_function_pointers")) + if (getLangOpts().OpenCL && + !getActions().getOpenCLOptions().isAvailableOption( + "__cl_clang_function_pointers", getLangOpts())) if (Expr *PostfixExpr = Res.get()) { QualType Ty = PostfixExpr->getType(); if (!Ty.isNull() && Ty->isFunctionType()) { diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -771,12 +771,10 @@ // overriding all previously issued extension directives, but only if the // behavior is set to disable." if (Name == "all") { - if (State == Disable) { + if (State == Disable) Opt.disableAll(); - Opt.enableSupportedCore(getLangOpts()); - } else { + else PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1; - } } else if (State == Begin) { if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) { Opt.support(Name); diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -625,7 +625,8 @@ // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class // specifiers are not supported." if (S.getLangOpts().OpenCL && - !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) { + !S.getOpenCLOptions().isAvailableOption( + "cl_clang_storage_class_specifiers", S.getLangOpts())) { switch (SC) { case SCS_extern: case SCS_private_extern: diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -299,7 +299,6 @@ if (getLangOpts().OpenCL) { getOpenCLOptions().addSupport( Context.getTargetInfo().getSupportedOpenCLOpts(), getLangOpts()); - getOpenCLOptions().enableSupportedCore(getLangOpts()); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { @@ -309,25 +308,13 @@ addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); addImplicitTypedef("atomic_uint", Context.getAtomicType(Context.UnsignedIntTy)); - auto AtomicLongT = Context.getAtomicType(Context.LongTy); - addImplicitTypedef("atomic_long", AtomicLongT); - auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); - addImplicitTypedef("atomic_ulong", AtomicULongT); addImplicitTypedef("atomic_float", Context.getAtomicType(Context.FloatTy)); - auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); - addImplicitTypedef("atomic_double", AtomicDoubleT); // OpenCLC v2.0, s6.13.11.6 requires that atomic_flag is implemented as // 32-bit integer and OpenCLC v2.0, s6.1.1 int is always 32-bit wide. addImplicitTypedef("atomic_flag", Context.getAtomicType(Context.IntTy)); - auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); - addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); - auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); - addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); auto AtomicSizeT = Context.getAtomicType(Context.getSizeType()); addImplicitTypedef("atomic_size_t", AtomicSizeT); - auto AtomicPtrDiffT = Context.getAtomicType(Context.getPointerDiffType()); - addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); // OpenCL v2.0 s6.13.11.6: // - The atomic_long and atomic_ulong types are supported if the @@ -341,20 +328,42 @@ // atomic_ptrdiff_t are supported if the cl_khr_int64_base_atomics and // cl_khr_int64_extended_atomics extensions are supported. std::vector Atomic64BitTypes; - Atomic64BitTypes.push_back(AtomicLongT); - Atomic64BitTypes.push_back(AtomicULongT); - Atomic64BitTypes.push_back(AtomicDoubleT); - if (Context.getTypeSize(AtomicSizeT) == 64) { - Atomic64BitTypes.push_back(AtomicSizeT); - Atomic64BitTypes.push_back(AtomicIntPtrT); - Atomic64BitTypes.push_back(AtomicUIntPtrT); - Atomic64BitTypes.push_back(AtomicPtrDiffT); + if (getOpenCLOptions().isSupported("cl_khr_int64_base_atomics", + getLangOpts()) && + getOpenCLOptions().isSupported("cl_khr_int64_extended_atomics", + getLangOpts())) { + if (getOpenCLOptions().isSupported("cl_khr_fp64", getLangOpts())) { + auto AtomicDoubleT = Context.getAtomicType(Context.DoubleTy); + addImplicitTypedef("atomic_double", AtomicDoubleT); + setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); + Atomic64BitTypes.push_back(AtomicDoubleT); + } + auto AtomicLongT = Context.getAtomicType(Context.LongTy); + auto AtomicULongT = Context.getAtomicType(Context.UnsignedLongTy); + auto AtomicIntPtrT = Context.getAtomicType(Context.getIntPtrType()); + auto AtomicUIntPtrT = Context.getAtomicType(Context.getUIntPtrType()); + auto AtomicPtrDiffT = + Context.getAtomicType(Context.getPointerDiffType()); + + addImplicitTypedef("atomic_long", AtomicLongT); + addImplicitTypedef("atomic_ulong", AtomicULongT); + addImplicitTypedef("atomic_intptr_t", AtomicIntPtrT); + addImplicitTypedef("atomic_uintptr_t", AtomicUIntPtrT); + addImplicitTypedef("atomic_ptrdiff_t", AtomicPtrDiffT); + + Atomic64BitTypes.push_back(AtomicLongT); + Atomic64BitTypes.push_back(AtomicULongT); + if (Context.getTypeSize(AtomicSizeT) == 64) { + Atomic64BitTypes.push_back(AtomicSizeT); + Atomic64BitTypes.push_back(AtomicIntPtrT); + Atomic64BitTypes.push_back(AtomicUIntPtrT); + Atomic64BitTypes.push_back(AtomicPtrDiffT); + } } + for (auto &I : Atomic64BitTypes) setOpenCLExtensionForType(I, "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"); - - setOpenCLExtensionForType(AtomicDoubleT, "cl_khr_fp64"); } setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); @@ -362,9 +371,11 @@ #define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ setOpenCLExtensionForType(Context.Id, Ext); #include "clang/Basic/OpenCLImageTypes.def" -#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ - addImplicitTypedef(#ExtType, Context.Id##Ty); \ - setOpenCLExtensionForType(Context.Id##Ty, #Ext); +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \ + addImplicitTypedef(#ExtType, Context.Id##Ty); \ + setOpenCLExtensionForType(Context.Id##Ty, #Ext); \ + } #include "clang/Basic/OpenCLExtensionTypes.def" } @@ -2511,7 +2522,7 @@ if (Loc == OpenCLDeclExtMap.end()) return false; for (auto &I : Loc->second) { - if (!getOpenCLOptions().isEnabled(I)) + if (!getOpenCLOptions().isAvailableOption(I, getLangOpts())) return true; } return false; @@ -2527,7 +2538,8 @@ return false; bool Disabled = false; for (auto &I : Loc->second) { - if (I != CurrOpenCLExtension && !getOpenCLOptions().isEnabled(I)) { + if (I != CurrOpenCLExtension && + !getOpenCLOptions().isAvailableOption(I, getLangOpts())) { Diag(DiagLoc, diag::err_opencl_requires_extension) << Selector << DiagInfo << I << SrcRange; Disabled = true; diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2916,8 +2916,8 @@ } } - if (Self.getLangOpts().OpenCL && - !Self.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption( + "cl_khr_fp16", Self.getLangOpts())) { if (DestType->isHalfType()) { Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half) << DestType << SrcExpr.get()->getSourceRange(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -837,7 +837,8 @@ } static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_subgroups")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_subgroups", + S.getLangOpts())) { S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension) << 1 << Call->getDirectCallee() << "cl_khr_subgroups"; return true; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6750,7 +6750,8 @@ } // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. - if (!Se.getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + if (!Se.getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + Se.getLangOpts())) { QualType NR = R.getCanonicalType(); while (NR->isPointerType() || NR->isMemberFunctionPointerType() || NR->isReferenceType()) { @@ -6765,7 +6766,8 @@ } } - if (!Se.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!Se.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + Se.getLangOpts())) { // 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()) { @@ -7888,7 +7890,8 @@ // OpenCL v1.2 s6.8 - The static qualifier is valid only in program // scope. if (getLangOpts().OpenCLVersion == 120 && - !getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers") && + !getOpenCLOptions().isAvailableOption("cl_clang_storage_class_specifiers", + getLangOpts()) && NewVD->isStaticLocal()) { Diag(NewVD->getLocation(), diag::err_static_function_scope); NewVD->setInvalidDecl(); @@ -8660,7 +8663,8 @@ // OpenCL extension spec v1.2 s9.5: // This extension adds support for half scalar and vector types as built-in // types that can be used for arithmetic operations, conversions etc. - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16") && PT->isHalfType()) + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", S.getLangOpts()) && + PT->isHalfType()) return InvalidKernelParam; if (PT->isRecordType()) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -658,7 +658,8 @@ return E; // OpenCL usually rejects direct accesses to values of 'half' type. - if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && + if (getLangOpts().OpenCL && + !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && T->isHalfType()) { Diag(E->getExprLoc(), diag::err_opencl_half_load_store) << 0 << T; @@ -830,10 +831,10 @@ if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); - } + !getOpenCLOptions().isAvailableOption("cl_khr_fp64", getLangOpts())) { + if (BTy->getKind() == BuiltinType::Half) { + E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); + } } else { E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); } @@ -3820,7 +3821,7 @@ } else if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isHalf){ - if (getOpenCLOptions().isEnabled("cl_khr_fp16")) + if (getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts())) Ty = Context.HalfTy; else { Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); @@ -3844,8 +3845,8 @@ if (Ty->castAs()->getKind() != BuiltinType::Float) { Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); } - } else if (getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("cl_khr_fp64")) { + } else if (getLangOpts().OpenCL && !getOpenCLOptions().isAvailableOption( + "cl_khr_fp64", getLangOpts())) { // Impose single-precision float type when cl_khr_fp64 is not enabled. Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64); Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get(); @@ -12934,8 +12935,9 @@ // OpenCL v1.2 s6.1.1.1 p2: // The half data type can only be used to declare a pointer to a buffer that // contains half values - if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp16") && - LHSType->isHalfType()) { + if (getLangOpts().OpenCL && + !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) && + LHSType->isHalfType()) { Diag(Loc, diag::err_opencl_half_load_store) << 1 << LHSType.getUnqualifiedType(); return QualType(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5607,8 +5607,8 @@ // We should allow zero initialization for all types defined in the // cl_intel_device_side_avc_motion_estimation extension, except // intel_sub_group_avc_mce_payload_t and intel_sub_group_avc_mce_result_t. - if (S.getOpenCLOptions().isEnabled( - "cl_intel_device_side_avc_motion_estimation") && + if (S.getOpenCLOptions().isAvailableOption( + "cl_intel_device_side_avc_motion_estimation", S.getLangOpts()) && DestType->isOCLIntelSubgroupAVCType()) { if (DestType->isOCLIntelSubgroupAVCMcePayloadType() || DestType->isOCLIntelSubgroupAVCMceResultType()) @@ -8795,8 +8795,8 @@ unsigned AddressingMode = (0x0E & SamplerValue) >> 1; unsigned FilterMode = (0x30 & SamplerValue) >> 4; if (FilterMode != 1 && FilterMode != 2 && - !S.getOpenCLOptions().isEnabled( - "cl_intel_device_side_avc_motion_estimation")) + !S.getOpenCLOptions().isAvailableOption( + "cl_intel_device_side_avc_motion_estimation", S.getLangOpts())) S.Diag(Kind.getLocation(), diag::warn_sampler_initializer_invalid_bits) << "Filter Mode"; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2088,7 +2088,8 @@ } if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0; return QualType(); } @@ -2162,7 +2163,8 @@ return QualType(); if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*reference*/ 1; return QualType(); } @@ -2894,7 +2896,8 @@ } if (T->isFunctionType() && getLangOpts().OpenCL && - !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + !getOpenCLOptions().isAvailableOption("__cl_clang_function_pointers", + getLangOpts())) { Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0; return QualType(); } @@ -5004,7 +5007,8 @@ // FIXME: This really should be in BuildFunctionType. if (T->isHalfType()) { if (S.getLangOpts().OpenCL) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + S.getLangOpts())) { S.Diag(D.getIdentifierLoc(), diag::err_opencl_invalid_return) << T << 0 /*pointer hint*/; D.setInvalidType(true); @@ -5029,7 +5033,8 @@ // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. // We also allow here any toolchain reserved identifiers. if (FTI.isVariadic && - !S.getOpenCLOptions().isEnabled("__cl_clang_variadic_functions") && + !S.getOpenCLOptions().isAvailableOption( + "__cl_clang_variadic_functions", S.getLangOpts()) && !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || @@ -5224,7 +5229,8 @@ // Disallow half FP parameters. // FIXME: This really should be in BuildFunctionType. if (S.getLangOpts().OpenCL) { - if (!S.getOpenCLOptions().isEnabled("cl_khr_fp16")) { + if (!S.getOpenCLOptions().isAvailableOption("cl_khr_fp16", + S.getLangOpts())) { S.Diag(Param->getLocation(), diag::err_opencl_invalid_param) << ParamTy << 0; D.setInvalidType(); diff --git a/clang/test/Parser/opencl-atomics-cl20.cl b/clang/test/Parser/opencl-atomics-cl20.cl --- a/clang/test/Parser/opencl-atomics-cl20.cl +++ b/clang/test/Parser/opencl-atomics-cl20.cl @@ -42,21 +42,21 @@ // expected-error@-16 {{use of undeclared identifier 'atomic_size_t'}} // expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} #elif !EXT -// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error@-26 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_base_atomics support}} +// expected-error@-27 {{use of type 'atomic_long' (aka '_Atomic(long)') requires cl_khr_int64_extended_atomics support}} +// expected-error@-27 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_base_atomics support}} +// expected-error@-28 {{use of type 'atomic_ulong' (aka '_Atomic(unsigned long)') requires cl_khr_int64_extended_atomics support}} +// expected-error@-27 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_base_atomics support}} +// expected-error@-28 {{use of type 'atomic_double' (aka '_Atomic(double)') requires cl_khr_int64_extended_atomics support}} #if __LP64__ -// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} -// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} -// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} +// expected-error-re@-28 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-29 {{use of type 'atomic_intptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-29 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-30 {{use of type 'atomic_uintptr_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-30 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-31 {{use of type 'atomic_size_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} +// expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics support}} +// expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics support}} #endif #endif diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl --- a/clang/test/SemaOpenCL/access-qualifier.cl +++ b/clang/test/SemaOpenCL/access-qualifier.cl @@ -76,7 +76,7 @@ #endif #if __OPENCL_C_VERSION__ < 200 -kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes extension to be enabled}} +kernel void test_image3d_wo(write_only image3d_t img) {} // expected-error {{use of type '__write_only image3d_t' requires cl_khr_3d_image_writes support}} #endif #if __OPENCL_C_VERSION__ >= 200 diff --git a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl --- a/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl +++ b/clang/test/SemaOpenCL/cl20-device-side-enqueue.cl @@ -235,11 +235,11 @@ kernel void foo1(global unsigned int *buf) { ndrange_t n; - buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups extension to be enabled}} + buf[0] = get_kernel_max_sub_group_size_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_max_sub_group_size_for_ndrange' requires cl_khr_subgroups support}} } kernel void bar1(global unsigned int *buf) { ndrange_t n; - buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups extension to be enabled}} + buf[0] = get_kernel_sub_group_count_for_ndrange(n, ^(){}); // expected-error {{use of declaration 'get_kernel_sub_group_count_for_ndrange' requires cl_khr_subgroups support}} } diff --git a/clang/test/SemaOpenCL/extension-begin.cl b/clang/test/SemaOpenCL/extension-begin.cl --- a/clang/test/SemaOpenCL/extension-begin.cl +++ b/clang/test/SemaOpenCL/extension-begin.cl @@ -41,11 +41,11 @@ #pragma OPENCL EXTENSION my_ext : disable void test_f2(void) { - struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} - const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext extension to be enabled}} - TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext extension to be enabled}} - PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const __private struct A *') requires my_ext extension to be enabled}} - f(); // expected-error {{use of declaration 'f' requires my_ext extension to be enabled}} + struct A test_A2; // expected-error {{use of type 'struct A' requires my_ext support}} + const struct A test_A_local; // expected-error {{use of type 'struct A' requires my_ext support}} + TypedefOfA test_typedef_A; // expected-error {{use of type 'TypedefOfA' (aka 'struct A') requires my_ext support}} + PointerOfA test_A_pointer; // expected-error {{use of type 'PointerOfA' (aka 'const __private struct A *') requires my_ext support}} + f(); // expected-error {{use of declaration 'f' requires my_ext support}} g(0); // expected-error {{no matching function for call to 'g'}} // expected-note@extension-begin.h:18 {{candidate unavailable as it requires OpenCL extension 'my_ext' to be enabled}} // expected-note@extension-begin.h:23 {{candidate function not viable: requires 0 arguments, but 1 was provided}} diff --git a/clang/test/SemaOpenCL/extensions.cl b/clang/test/SemaOpenCL/extensions.cl --- a/clang/test/SemaOpenCL/extensions.cl +++ b/clang/test/SemaOpenCL/extensions.cl @@ -43,8 +43,8 @@ #endif #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) -void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}} - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} +void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 support}} + double d; // expected-error {{type 'double' requires cl_khr_fp64 support}} (void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}} } #endif @@ -72,14 +72,14 @@ void f2(void) { double d; #ifdef NOFP64 -// expected-error@-2{{use of type 'double' requires cl_khr_fp64 extension to be enabled}} +// expected-error@-2{{use of type 'double' requires cl_khr_fp64 support}} #endif typedef double double4 __attribute__((ext_vector_type(4))); double4 d4 = {0.0f, 2.0f, 3.0f, 1.0f}; #ifdef NOFP64 -// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 extension to be enabled}} -// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 extension to be enabled}} +// expected-error@-3 {{use of type 'double' requires cl_khr_fp64 support}} +// expected-error@-3 {{use of type 'double4' (vector of 4 'double' values) requires cl_khr_fp64 support}} #endif (void) 1.0; @@ -96,6 +96,6 @@ #if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120) void f3(void) { - double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}} + double d; // expected-error {{type 'double' requires cl_khr_fp64 support}} } #endif diff --git a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl --- a/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl +++ b/clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl @@ -1,6 +1,9 @@ -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=+cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify -DEXT %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -cl-ext=-cl_intel_device_side_avc_motion_estimation -fsyntax-only -verify %s +#ifdef cl_intel_device_side_avc_motion_estimation #pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable +#endif // All intel_sub_group_avc_* types can only be used as argument or return value // of built-in functions defined in the extension. @@ -16,55 +19,77 @@ // negative test cases for initializers void foo(char c, float f, void* v, struct st ss) { intel_sub_group_avc_mce_payload_t payload_mce = 0; // No zero initializer for mce types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ime_payload_t payload_ime = 1; // No literal initializer for *payload_t types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ref_payload_t payload_ref = f; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} intel_sub_group_avc_sic_payload_t payload_sic = ss; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} - intel_sub_group_avc_mce_result_t result_mce = 0; // No zero initializer for mce types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ime_result_t result_ime = 1; // No literal initializer for *result_t types - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} intel_sub_group_avc_ref_result_t result_ref = f; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} intel_sub_group_avc_sic_result_t result_sic = ss; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} - intel_sub_group_avc_ime_result_single_reference_streamout_t sstreamout = v; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} - intel_sub_group_avc_ime_result_dual_reference_streamout_t dstreamin_list = {0x0, 0x1}; - // expected-warning@-1 {{excess elements in struct initializer}} intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list2 = {}; - // expected-error@-1 {{scalar initializer cannot be empty}} intel_sub_group_avc_ime_single_reference_streamin_t dstreamin_list3 = {c}; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list4 = {1}; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} +#ifdef EXT +// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_payload_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_payload_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private float'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_payload_t' with an expression of incompatible type '__private struct st'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_mce_result_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_t' with an expression of incompatible type 'int'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ref_result_t' with an expression of incompatible type '__private float'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_sic_result_t' with an expression of incompatible type '__private struct st'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_result_single_reference_streamout_t' with an expression of incompatible type '__private void *__private'}} +// expected-warning@-14 {{excess elements in struct initializer}} +// expected-error@-14 {{scalar initializer cannot be empty}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} +// expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} +#else +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_payload_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_single_reference_streamout_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_dual_reference_streamout_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_single_reference_streamin_t'}} +// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +#endif } // negative tests for initializers and assignment void far() { intel_sub_group_avc_mce_payload_t payload_mce; intel_sub_group_avc_mce_payload_t payload_mce2 = payload_mce; - intel_sub_group_avc_ime_payload_t payload_ime; intel_sub_group_avc_ref_payload_t payload_ref = payload_ime; - // expected-error@-1 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} - intel_sub_group_avc_sic_result_t result_sic; intel_sub_group_avc_ime_result_t result_ime; result_sic = result_ime; - // expected-error@-1 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} +#ifdef EXT +// expected-error@-5 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} +// expected-error@-3 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} +#else +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} +// expected-error@-11 {{use of undeclared identifier 'result_sic'}} expected-error@-11 {{use of undeclared identifier 'result_ime'}} +#endif } // Using 0x0 directly allows us not to include opencl-c.h header and not to // redefine all of these CLK_AVC_*_INTITIALIZE_INTEL macro. '0x0' value must // be in sync with ones defined in opencl-c.h +#ifdef EXT // positive test cases void bar() { const sampler_t vme_sampler = 0x0; @@ -102,4 +127,4 @@ intel_sub_group_avc_ime_single_reference_streamin_t sstreamin_list = {0}; intel_sub_group_avc_ime_dual_reference_streamin_t dstreamin_list = {0}; } - +#endif //EXT