diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -798,19 +798,16 @@ // as argument. Only meaningful for generic types, otherwise equals 1. unsigned GenTypeMaxCnt; + ASTContext &Context = S.Context; + for (unsigned SignatureIndex = 0; SignatureIndex < Len; SignatureIndex++) { const OpenCLBuiltinStruct &OpenCLBuiltin = BuiltinTable[FctIndex + SignatureIndex]; - ASTContext &Context = S.Context; - // Ignore this BIF if its version does not match the language options. - unsigned OpenCLVersion = Context.getLangOpts().OpenCLVersion; - if (Context.getLangOpts().OpenCLCPlusPlus) - OpenCLVersion = 200; - if (OpenCLVersion < OpenCLBuiltin.MinVersion) - continue; - if ((OpenCLBuiltin.MaxVersion != 0) && - (OpenCLVersion >= OpenCLBuiltin.MaxVersion)) + // Ignore this builtin function if it is not available in the currently + // selected language version. + if (!isOpenCLVersionContainedInMask(Context.getLangOpts(), + OpenCLBuiltin.Versions)) continue; // Ignore this builtin function if it carries an extension macro that is diff --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp --- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp +++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp @@ -339,10 +339,8 @@ const bool IsConv : 1; // OpenCL extension(s) required for this overload. const unsigned short Extension; - // First OpenCL version in which this overload was introduced (e.g. CL20). - const unsigned short MinVersion; - // First OpenCL version in which this overload was removed (e.g. CL20). - const unsigned short MaxVersion; + // OpenCL versions in which this overload is available. + const unsigned short Versions; }; )"; @@ -490,6 +488,29 @@ OS << "};\n\n"; } +// Encode a range MinVersion..MaxVersion into a single bit mask that can be +// checked against LangOpts using isOpenCLVersionContainedInMask(). +// This must be kept in sync with OpenCLVersionID in OpenCLOptions.h. +// (Including OpenCLOptions.h here would be a layering violation.) +static unsigned short EncodeVersions(unsigned int MinVersion, + unsigned int MaxVersion) { + unsigned short Encoded = 0; + + // A maximum version of 0 means available in all later versions. + if (MaxVersion == 0) { + MaxVersion = UINT_MAX; + } + + unsigned VersionIDs[] = {100, 110, 120, 200, 300}; + for (unsigned I = 0; I < sizeof(VersionIDs) / sizeof(VersionIDs[0]); I++) { + if (VersionIDs[I] >= MinVersion && VersionIDs[I] < MaxVersion) { + Encoded |= 1 << I; + } + } + + return Encoded; +} + void BuiltinNameEmitter::EmitBuiltinTable() { unsigned Index = 0; @@ -510,9 +531,10 @@ << (Overload.first->getValueAsBit("IsConst")) << ", " << (Overload.first->getValueAsBit("IsConv")) << ", " << FunctionExtensionIndex[ExtName] << ", " - << Overload.first->getValueAsDef("MinVersion")->getValueAsInt("ID") - << ", " - << Overload.first->getValueAsDef("MaxVersion")->getValueAsInt("ID") + << EncodeVersions(Overload.first->getValueAsDef("MinVersion") + ->getValueAsInt("ID"), + Overload.first->getValueAsDef("MaxVersion") + ->getValueAsInt("ID")) << " },\n"; Index++; }