mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
Add productions/data for about 14 qualifiers (versions 1.2 through 4.3). Fixed some case issues for rect/array keywords.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20742 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
4b67103b02
commit
ca8899c9ae
@ -9,6 +9,9 @@ float precision;
|
||||
in vec4 i;
|
||||
out vec4 o;
|
||||
|
||||
uniform sampler2D s2D;
|
||||
centroid varying vec2 centTexCoord;
|
||||
|
||||
uniform mat4x2 m;
|
||||
|
||||
struct s {
|
||||
@ -58,4 +61,6 @@ void main()
|
||||
b = a; // ERROR
|
||||
b = b + f; // ERROR
|
||||
f |= b; // ERROR
|
||||
|
||||
gl_FragColor = texture2D(s2D, centTexCoord);
|
||||
}
|
||||
|
18
Test/120.vert
Normal file
18
Test/120.vert
Normal file
@ -0,0 +1,18 @@
|
||||
#version 120
|
||||
|
||||
in vec4 i;
|
||||
out vec4 o;
|
||||
|
||||
attribute vec2 attv2;
|
||||
attribute vec4 attv4;
|
||||
uniform sampler2D s2D;
|
||||
invariant varying vec2 centTexCoord;
|
||||
invariant gl_Position;
|
||||
|
||||
centroid centroid foo;
|
||||
|
||||
void main()
|
||||
{
|
||||
centTexCoord = attv2;
|
||||
gl_Position = attv4;
|
||||
}
|
@ -6,6 +6,7 @@ versionsClean.frag
|
||||
versionsClean.vert
|
||||
versionsErrors.frag
|
||||
versionsErrors.vert
|
||||
120.vert
|
||||
120.frag
|
||||
130.frag
|
||||
140.frag
|
||||
|
@ -169,19 +169,52 @@ inline TArraySizes NewPoolTArraySizes()
|
||||
}
|
||||
|
||||
//
|
||||
// This is a workaround for a problem with the yacc stack, It can't have
|
||||
// TPublicType is a workaround for a problem with the yacc stack, It can't have
|
||||
// types that it thinks have non-trivial constructors. It should
|
||||
// just be used while recognizing the grammar, not anything else. Pointers
|
||||
// could be used, but also trying to avoid lots of memory management overhead.
|
||||
//
|
||||
// Not as bad as it looks, there is no actual assumption that the fields
|
||||
// match up or are name the same or anything like that.
|
||||
// match up or are named the same or anything like that.
|
||||
//
|
||||
|
||||
class TQualifier {
|
||||
public:
|
||||
void clear()
|
||||
{
|
||||
storage = EvqTemporary;
|
||||
precision = EpqNone;
|
||||
buffer = false;
|
||||
invariant = false;
|
||||
centroid = false;
|
||||
smooth = false;
|
||||
flat = false;
|
||||
nopersp = false;
|
||||
patch = false;
|
||||
sample = false;
|
||||
shared = false;
|
||||
coherent = false;
|
||||
volatil = false;
|
||||
restrict = false;
|
||||
readonly = false;
|
||||
writeonly = false;
|
||||
}
|
||||
TStorageQualifier storage : 7;
|
||||
TPrecisionQualifier precision : 3;
|
||||
bool buffer : 1;
|
||||
bool invariant : 1;
|
||||
bool centroid : 1;
|
||||
bool smooth : 1;
|
||||
bool flat : 1;
|
||||
bool nopersp : 1;
|
||||
bool patch : 1;
|
||||
bool sample : 1;
|
||||
bool shared : 1;
|
||||
bool coherent : 1;
|
||||
bool volatil : 1;
|
||||
bool restrict : 1;
|
||||
bool readonly : 1;
|
||||
bool writeonly : 1;
|
||||
};
|
||||
|
||||
class TPublicType {
|
||||
@ -209,8 +242,9 @@ public:
|
||||
|
||||
void initQualifiers(bool global = false)
|
||||
{
|
||||
qualifier.storage = global ? EvqGlobal : EvqTemporary;
|
||||
qualifier.precision = EpqNone;
|
||||
qualifier.clear();
|
||||
if (global)
|
||||
qualifier.storage = EvqGlobal;
|
||||
}
|
||||
|
||||
void init(int line = 0, bool global = false)
|
||||
@ -249,8 +283,8 @@ public:
|
||||
fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
qualifier.storage = q;
|
||||
qualifier.precision = EpqNone;
|
||||
}
|
||||
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
|
||||
type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||
@ -258,6 +292,7 @@ public:
|
||||
fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
qualifier.storage = q;
|
||||
qualifier.precision = p;
|
||||
assert(p >= 0 && p <= EpqHigh);
|
||||
@ -278,8 +313,7 @@ public:
|
||||
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.storage = EvqTemporary;
|
||||
qualifier.precision = EpqNone;
|
||||
qualifier.clear();
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
explicit TType() {}
|
||||
@ -421,11 +455,39 @@ public:
|
||||
|
||||
TString TType::getCompleteString() const
|
||||
{
|
||||
const int maxSize = 100;
|
||||
const int maxSize = 200;
|
||||
char buf[maxSize];
|
||||
char *p = &buf[0];
|
||||
char *end = &buf[maxSize];
|
||||
|
||||
if (qualifier.buffer)
|
||||
p += snprintf(p, end - p, "buffer ");
|
||||
if (qualifier.invariant)
|
||||
p += snprintf(p, end - p, "invariant ");
|
||||
if (qualifier.centroid)
|
||||
p += snprintf(p, end - p, "centroid ");
|
||||
if (qualifier.smooth)
|
||||
p += snprintf(p, end - p, "smooth ");
|
||||
if (qualifier.flat)
|
||||
p += snprintf(p, end - p, "flat ");
|
||||
if (qualifier.nopersp)
|
||||
p += snprintf(p, end - p, "noperspective ");
|
||||
if (qualifier.patch)
|
||||
p += snprintf(p, end - p, "patch ");
|
||||
if (qualifier.sample)
|
||||
p += snprintf(p, end - p, "sample ");
|
||||
if (qualifier.shared)
|
||||
p += snprintf(p, end - p, "shared ");
|
||||
if (qualifier.coherent)
|
||||
p += snprintf(p, end - p, "coherent ");
|
||||
if (qualifier.volatil)
|
||||
p += snprintf(p, end - p, "volatile ");
|
||||
if (qualifier.restrict)
|
||||
p += snprintf(p, end - p, "restrict ");
|
||||
if (qualifier.readonly)
|
||||
p += snprintf(p, end - p, "readonly ");
|
||||
if (qualifier.writeonly)
|
||||
p += snprintf(p, end - p, "writeonly ");
|
||||
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
|
||||
p += snprintf(p, end - p, "%s ", getStorageQualifierString());
|
||||
if (arraySizes) {
|
||||
|
@ -668,6 +668,62 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Merge characteristics of the 'right' qualifier into the 'left'.
|
||||
// If there is duplication, issue error messages.
|
||||
//
|
||||
// Return true if there was an error.
|
||||
//
|
||||
bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right)
|
||||
{
|
||||
bool bad = false;
|
||||
|
||||
// Storage qualification
|
||||
if (left.qualifier.storage == EvqTemporary)
|
||||
left.qualifier.storage = right.qualifier.storage;
|
||||
else if (left.qualifier.storage == EvqIn && right.qualifier.storage == EvqOut ||
|
||||
left.qualifier.storage == EvqOut && right.qualifier.storage == EvqIn)
|
||||
left.qualifier.storage = EvqInOut;
|
||||
else if (left.qualifier.storage == EvqIn && right.qualifier.storage == EvqConst ||
|
||||
left.qualifier.storage == EvqConst && right.qualifier.storage == EvqIn)
|
||||
left.qualifier.storage = EvqConstReadOnly;
|
||||
else if ( left.qualifier.storage != EvqTemporary &&
|
||||
right.qualifier.storage != EvqTemporary) {
|
||||
error(line, "too many storage qualifiers", getStorageQualifierString(right.qualifier.storage), "");
|
||||
bad = true;
|
||||
}
|
||||
|
||||
// Precision qualifiers
|
||||
if (left.qualifier.precision == EpqNone)
|
||||
left.qualifier.precision = right.qualifier.precision;
|
||||
else if (right.qualifier.precision) {
|
||||
error(line, "only one precision qualifier allowed", getPrecisionQualifierString(right.qualifier.precision), "");
|
||||
bad = true;
|
||||
}
|
||||
|
||||
// other qualifiers
|
||||
#define MERGE_SINGLETON(field) bad |= left.qualifier.field && right.qualifier.field; left.qualifier.field |= right.qualifier.field;
|
||||
MERGE_SINGLETON(buffer);
|
||||
MERGE_SINGLETON(invariant);
|
||||
MERGE_SINGLETON(centroid);
|
||||
MERGE_SINGLETON(smooth);
|
||||
MERGE_SINGLETON(flat);
|
||||
MERGE_SINGLETON(nopersp);
|
||||
MERGE_SINGLETON(patch);
|
||||
MERGE_SINGLETON(sample);
|
||||
MERGE_SINGLETON(shared);
|
||||
MERGE_SINGLETON(coherent);
|
||||
MERGE_SINGLETON(volatil);
|
||||
MERGE_SINGLETON(restrict);
|
||||
MERGE_SINGLETON(readonly);
|
||||
MERGE_SINGLETON(writeonly);
|
||||
|
||||
if (bad)
|
||||
error(line, "replicated qualifiers", "", "");
|
||||
|
||||
return bad;
|
||||
}
|
||||
|
||||
void TParseContext::setDefaultPrecision(int line, TBasicType type, TPrecisionQualifier qualifier)
|
||||
{
|
||||
if (type == EbtSampler || type == EbtInt || type == EbtFloat) {
|
||||
|
@ -120,6 +120,7 @@ struct TParseContext {
|
||||
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
|
||||
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
|
||||
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
||||
bool mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right);
|
||||
void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
|
||||
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
|
||||
bool containsSampler(const TType& type);
|
||||
|
@ -268,30 +268,30 @@ int yy_input(char* buf, int max_size);
|
||||
"image3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE3D); }
|
||||
"iimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE3D); }
|
||||
"uimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE3D); }
|
||||
"image2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DRECT); }
|
||||
"iimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DRECT); }
|
||||
"uimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DRECT); }
|
||||
"image2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DRECT); }
|
||||
"iimage2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DRECT); }
|
||||
"uimage2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DRECT); }
|
||||
"imageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBE); }
|
||||
"iimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBE); }
|
||||
"uimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBE); }
|
||||
"imageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGEBUFFER); }
|
||||
"iimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGEBUFFER); }
|
||||
"uimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGEBUFFER); }
|
||||
"image1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1DARRAY); }
|
||||
"iimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1DARRAY); }
|
||||
"uimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1DARRAY); }
|
||||
"image2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DARRAY); }
|
||||
"iimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DARRAY); }
|
||||
"uimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DARRAY); }
|
||||
"imageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBEARRAY); }
|
||||
"iimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBEARRAY); }
|
||||
"uimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBEARRAY); }
|
||||
"image1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1DARRAY); }
|
||||
"iimage1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1DARRAY); }
|
||||
"uimage1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1DARRAY); }
|
||||
"image2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DARRAY); }
|
||||
"iimage2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DARRAY); }
|
||||
"uimage2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DARRAY); }
|
||||
"imageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBEARRAY); }
|
||||
"iimageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBEARRAY); }
|
||||
"uimageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBEARRAY); }
|
||||
"image2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMS); }
|
||||
"iimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMS); }
|
||||
"uimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMS); }
|
||||
"image2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMSARRAY); }
|
||||
"iimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMSARRAY); }
|
||||
"uimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMSARRAY); }
|
||||
"image2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMSARRAY); }
|
||||
"iimage2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMSARRAY); }
|
||||
"uimage2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMSARRAY); }
|
||||
|
||||
"struct" { pyylval->lex.line = yylineno; return(STRUCT); }
|
||||
|
||||
|
@ -1601,20 +1601,42 @@ fully_specified_type
|
||||
|
||||
invariant_qualifier
|
||||
: INVARIANT {
|
||||
parseContext.profileRequires($$.line, ENoProfile, 120, 0, "invariant");
|
||||
$$.init($1.line);
|
||||
$$.qualifier.invariant = true;
|
||||
}
|
||||
;
|
||||
|
||||
interpolation_qualifier
|
||||
: SMOOTH {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth"))
|
||||
parseContext.recover();
|
||||
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "smooth");
|
||||
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "smooth");
|
||||
$$.init($1.line);
|
||||
$$.qualifier.smooth = true;
|
||||
}
|
||||
| FLAT {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat"))
|
||||
parseContext.recover();
|
||||
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "flat");
|
||||
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "flat");
|
||||
$$.init($1.line);
|
||||
$$.qualifier.flat = true;
|
||||
}
|
||||
| NOPERSPECTIVE {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective"))
|
||||
parseContext.recover();
|
||||
parseContext.requireProfile($$.line, static_cast<EProfileMask>(~EEsProfileMask), "noperspective");
|
||||
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "noperspective");
|
||||
$$.init($1.line);
|
||||
$$.qualifier.nopersp = true;
|
||||
}
|
||||
;
|
||||
|
||||
layout_qualifier
|
||||
: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
|
||||
$$.init($1.line);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1635,6 +1657,7 @@ layout_qualifier_id
|
||||
|
||||
precise_qualifier
|
||||
: PRECISE {
|
||||
$$.init($1.line);
|
||||
}
|
||||
;
|
||||
|
||||
@ -1644,24 +1667,11 @@ type_qualifier
|
||||
}
|
||||
| type_qualifier single_type_qualifier {
|
||||
$$ = $1;
|
||||
// TODO: merge qualifiers in $1 and $2 and check for duplication
|
||||
|
||||
if ($$.type == EbtVoid) {
|
||||
if ($$.type == EbtVoid)
|
||||
$$.type = $2.type;
|
||||
}
|
||||
|
||||
if ($$.qualifier.storage == EvqTemporary) {
|
||||
$$.qualifier.storage = $2.qualifier.storage;
|
||||
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqOut ||
|
||||
$$.qualifier.storage == EvqOut && $2.qualifier.storage == EvqIn) {
|
||||
$$.qualifier.storage = EvqInOut;
|
||||
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqConst ||
|
||||
$$.qualifier.storage == EvqConst && $2.qualifier.storage == EvqIn) {
|
||||
$$.qualifier.storage = EvqConstReadOnly;
|
||||
}
|
||||
|
||||
if ($$.qualifier.precision == EpqNone)
|
||||
$$.qualifier.precision = $2.qualifier.precision;
|
||||
if (parseContext.mergeQualifiersErrorCheck($$.line, $$, $2))
|
||||
parseContext.recover();
|
||||
}
|
||||
;
|
||||
|
||||
@ -1741,24 +1751,24 @@ storage_qualifier
|
||||
$$.qualifier.storage = EvqOut;
|
||||
}
|
||||
| CENTROID {
|
||||
parseContext.profileRequires($$.line, ENoProfile, 120, 0, "centroid");
|
||||
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "centroid");
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqVaryingIn;
|
||||
$$.qualifier.centroid = true;
|
||||
}
|
||||
| PATCH {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.patch = true;
|
||||
}
|
||||
| SAMPLE {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.sample = true;
|
||||
}
|
||||
| UNIFORM {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
|
||||
@ -1770,48 +1780,32 @@ storage_qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.buffer = true;
|
||||
}
|
||||
| SHARED {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "shared"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.shared = true;
|
||||
}
|
||||
| COHERENT {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.coherent = true;
|
||||
}
|
||||
| VOLATILE {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.volatil = true;
|
||||
}
|
||||
| RESTRICT {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.restrict = true;
|
||||
}
|
||||
| READONLY {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.readonly = true;
|
||||
}
|
||||
| WRITEONLY {
|
||||
// TODO: implement this qualifier
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.writeonly = true;
|
||||
}
|
||||
| SUBROUTINE {
|
||||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
|
||||
|
Loading…
Reference in New Issue
Block a user