// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
-#define GLSLANG_REVISION "Overload400-PrecQual.1897"
-#define GLSLANG_DATE "10-Mar-2017"
+#define GLSLANG_REVISION "Overload400-PrecQual.1899"
+#define GLSLANG_DATE "11-Mar-2017"
if (peekTokenClass(EHTokLeftParen)) {
// member function
TIntermTyped* thisNode = node;
- node = parseContext.handleBuiltInMethod(field.loc, node, *field.string);
- if (node == nullptr) {
- expected("built-in method");
- return false;
- }
// arguments
if (! acceptFunctionCall(field, node, thisNode)) {
// function_call
// : [idToken] arguments
//
-bool HlslGrammar::acceptFunctionCall(HlslToken idToken, TIntermTyped*& node, TIntermTyped* base)
+bool HlslGrammar::acceptFunctionCall(HlslToken callToken, TIntermTyped*& node, TIntermTyped* base)
{
// arguments
- TFunction* function = new TFunction(idToken.string, TType(EbtVoid));
+ TFunction* function = new TFunction(callToken.string, TType(EbtVoid));
TIntermTyped* arguments = nullptr;
- // methods have an implicit first argument of the calling object.
- if (base != nullptr)
+ // member functions have an implicit first argument of the calling object.
+ if (base != nullptr) {
+ if (! parseContext.isBuiltInMethod(callToken.loc, node, *callToken.string)) {
+ expected("built-in method");
+ return false;
+ }
parseContext.handleFunctionArgument(function, arguments, base);
+ }
if (! acceptArguments(function, arguments))
return false;
- node = parseContext.handleFunctionCall(idToken.loc, function, arguments);
+ node = parseContext.handleFunctionCall(callToken.loc, function, arguments);
return true;
}
return childNode;
}
-
-//
-// Return true if the name is a sampler method
-//
-bool HlslParseContext::isSamplerMethod(const TString& name) const
-{
- return
- name == "CalculateLevelOfDetail" ||
- name == "CalculateLevelOfDetailUnclamped" ||
- name == "Gather" ||
- name == "GatherRed" ||
- name == "GatherGreen" ||
- name == "GatherBlue" ||
- name == "GatherAlpha" ||
- name == "GatherCmp" ||
- name == "GatherCmpRed" ||
- name == "GatherCmpGreen" ||
- name == "GatherCmpBlue" ||
- name == "GatherCmpAlpha" ||
- name == "GetDimensions" ||
- name == "GetSamplePosition" ||
- name == "Load" ||
- name == "Sample" ||
- name == "SampleBias" ||
- name == "SampleCmp" ||
- name == "SampleCmpLevelZero" ||
- name == "SampleGrad" ||
- name == "SampleLevel";
-}
-
//
// Return true if the name is a struct buffer method
//
}
//
-// Handle seeing a base.field dereference in the grammar, where 'field' is a
-// built-in method name.
-//
-// Return nullptr if 'field' is not a built-in method.
+// Return true if the field should be treated as a built-in method.
+// Return false otherwise.
//
-TIntermTyped* HlslParseContext::handleBuiltInMethod(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
+bool HlslParseContext::isBuiltInMethod(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
{
variableCheck(base);
- //
- // Methods can't be resolved until we finish seeing the function-calling syntax.
- // Save away the name in the AST for now.
- //
- if (isSamplerMethod(field) && base->getType().getBasicType() == EbtSampler) {
- // If it's not a method on a sampler object, we fall through to let other objects have a go.
- const TSampler& sampler = base->getType().getSampler();
- if (! sampler.isPureSampler()) {
- const int vecSize = sampler.isShadow() ? 1 : 4; // TODO: handle arbitrary sample return sizes
- return intermediate.addMethod(base, TType(sampler.type, EvqTemporary, vecSize), &field, loc);
- }
- } else if (isStructBufferType(base->getType())) {
- TType retType(base->getType(), 0);
- return intermediate.addMethod(base, retType, &field, loc);
+ if (base->getType().getBasicType() == EbtSampler) {
+ return true;
+ } else if (isStructBufferType(base->getType()) && isStructBufferMethod(field)) {
+ return true;
} else if (field == "Append" ||
field == "RestartStrip") {
// We cannot check the type here: it may be sanitized if we're not compiling a geometry shader, but
// the code is around in the shader source.
- return intermediate.addMethod(base, TType(EbtVoid), &field, loc);
- }
-
- return nullptr;
+ return true;
+ } else
+ return false;
}
// Split the type of the given node into two structs:
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
- TIntermTyped* handleBuiltInMethod(const TSourceLoc&, TIntermTyped* base, const TString& field);
+ bool isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, const TString& field);
void assignLocations(TVariable& variable);
TFunction& handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree);
void clearUniformInputOutput(TQualifier& qualifier);
// Test method names
- bool isSamplerMethod(const TString& name) const;
bool isStructBufferMethod(const TString& name) const;
TType* getStructBufferContentType(const TType& type) const;