Simultaneously fix only known memory leak and take the next step in supporting arrays of arrays. Improved several minor things along the way.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20514 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
6968b823ef
commit
dadf945fd7
@ -254,6 +254,7 @@ bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBui
|
|||||||
#ifdef MEASURE_MEMORY
|
#ifdef MEASURE_MEMORY
|
||||||
|
|
||||||
GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
|
GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters));
|
||||||
|
printf("Working set size: %d\n", counters.WorkingSetSize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
57
Test/array.frag
Normal file
57
Test/array.frag
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#version 130
|
||||||
|
|
||||||
|
float gu[];
|
||||||
|
float g4[4];
|
||||||
|
float g5[5];
|
||||||
|
|
||||||
|
uniform int a;
|
||||||
|
|
||||||
|
float[4] foo(float a[5])
|
||||||
|
{
|
||||||
|
return float[](a[0], a[1], a[2], a[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bar(float[5]) {}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
float gu[2]; // okay, new scope
|
||||||
|
|
||||||
|
gu[2] = 4.0; // ERROR, overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
gu[2] = 4.0; // okay
|
||||||
|
|
||||||
|
gu[3] = 3.0;
|
||||||
|
gu[a] = 5.0; // ERROR
|
||||||
|
|
||||||
|
g4 = foo(g5);
|
||||||
|
g5 = g4; // ERROR
|
||||||
|
gu = g4; // ERROR
|
||||||
|
|
||||||
|
foo(gu); // ERROR
|
||||||
|
bar(g5);
|
||||||
|
|
||||||
|
if (float[4](1.0, 2.0, 3.0, 4.0) == g4)
|
||||||
|
gu[0] = 2.0;
|
||||||
|
|
||||||
|
float u[];
|
||||||
|
u[2] = 3.0; // okay
|
||||||
|
float u[5];
|
||||||
|
u[5] = 5.0; // ERROR
|
||||||
|
foo(u); // okay
|
||||||
|
|
||||||
|
gl_FragData[1000] = vec4(1.0); // ERROR
|
||||||
|
gl_FragData[-1] = vec4(1.0); // ERROR
|
||||||
|
gl_FragData[3] = vec4(1.0);
|
||||||
|
|
||||||
|
const int ca[] = int[](3, 2);
|
||||||
|
int sum = ca[0];
|
||||||
|
sum += ca[1];
|
||||||
|
sum += ca[2]; // ERROR
|
||||||
|
|
||||||
|
const int ca3[3] = int[](3, 2); // ERROR
|
||||||
|
int ica[] = int[](3, 2);
|
||||||
|
int ica3[3] = int[](3, 2); // ERROR
|
||||||
|
}
|
48
Test/array100.frag
Normal file
48
Test/array100.frag
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
float gu[];
|
||||||
|
float g4[4];
|
||||||
|
float g5[5];
|
||||||
|
|
||||||
|
uniform int a;
|
||||||
|
|
||||||
|
float[4] foo(float[5] a) // ERROR // ERROR
|
||||||
|
{
|
||||||
|
return float[](a[0], a[1], a[2], a[3]); // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
void bar(float[5]) {}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
float gu[2]; // okay, new scope
|
||||||
|
|
||||||
|
gu[2] = 4.0; // ERROR, overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
gu[2] = 4.0; // okay
|
||||||
|
|
||||||
|
gu[3] = 3.0;
|
||||||
|
gu[a] = 5.0; // ERROR
|
||||||
|
|
||||||
|
g4 = foo(g5);
|
||||||
|
g5 = g4; // ERROR
|
||||||
|
gu = g4; // ERROR
|
||||||
|
|
||||||
|
foo(gu); // ERROR
|
||||||
|
bar(g5);
|
||||||
|
|
||||||
|
if (float[4](1.0, 2.0, 3.0, 4.0) == g4) // ERROR
|
||||||
|
gu[0] = 2.0;
|
||||||
|
|
||||||
|
float u[];
|
||||||
|
u[2] = 3.0; // okay
|
||||||
|
float u[5];
|
||||||
|
u[5] = 5.0; // ERROR
|
||||||
|
foo(u); // okay
|
||||||
|
|
||||||
|
gl_FragData[1000] = vec4(1.0); // ERROR
|
||||||
|
gl_FragData[-1] = vec4(1.0); // ERROR
|
||||||
|
gl_FragData[3] = vec4(1.0);
|
||||||
|
}
|
@ -17,3 +17,5 @@ cppIndent.vert
|
|||||||
cppNest.vert
|
cppNest.vert
|
||||||
cppComplexExpr.vert
|
cppComplexExpr.vert
|
||||||
pointCoord.frag
|
pointCoord.frag
|
||||||
|
array.frag
|
||||||
|
array100.frag
|
@ -104,14 +104,12 @@ enum TStorageQualifier {
|
|||||||
EvqLast,
|
EvqLast,
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
// These will show up in error messages
|
||||||
// This is just for debug print out, carried along with the definitions above.
|
|
||||||
//
|
|
||||||
__inline const char* getStorageQualifierString(TStorageQualifier q)
|
__inline const char* getStorageQualifierString(TStorageQualifier q)
|
||||||
{
|
{
|
||||||
switch (q) {
|
switch (q) {
|
||||||
case EvqTemporary: return "Temporary"; break;
|
case EvqTemporary: return "temporary"; break;
|
||||||
case EvqGlobal: return "Global"; break;
|
case EvqGlobal: return "global"; break;
|
||||||
case EvqConst: return "const"; break;
|
case EvqConst: return "const"; break;
|
||||||
case EvqConstReadOnly: return "const (read only)"; break;
|
case EvqConstReadOnly: return "const (read only)"; break;
|
||||||
case EvqAttribute: return "attribute"; break;
|
case EvqAttribute: return "attribute"; break;
|
||||||
@ -121,14 +119,14 @@ __inline const char* getStorageQualifierString(TStorageQualifier q)
|
|||||||
case EvqIn: return "in"; break;
|
case EvqIn: return "in"; break;
|
||||||
case EvqOut: return "out"; break;
|
case EvqOut: return "out"; break;
|
||||||
case EvqInOut: return "inout"; break;
|
case EvqInOut: return "inout"; break;
|
||||||
case EvqPosition: return "Position"; break;
|
case EvqPosition: return "gl_Position"; break;
|
||||||
case EvqPointSize: return "PointSize"; break;
|
case EvqPointSize: return "gl_PointSize"; break;
|
||||||
case EvqClipVertex: return "ClipVertex"; break;
|
case EvqClipVertex: return "gl_ClipVertex"; break;
|
||||||
case EvqFace: return "FrontFacing"; break;
|
case EvqFace: return "gl_FrontFacing"; break;
|
||||||
case EvqFragCoord: return "FragCoord"; break;
|
case EvqFragCoord: return "gl_FragCoord"; break;
|
||||||
case EvqPointCoord: return "PointCoord"; break;
|
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||||
case EvqFragColor: return "FragColor"; break;
|
case EvqFragColor: return "fragment out"; break;
|
||||||
case EvqFragDepth: return "FragDepth"; break;
|
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||||
default: return "unknown qualifier";
|
default: return "unknown qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,24 @@ inline TTypeList* NewPoolTTypeList()
|
|||||||
return new(memory) TTypeList;
|
return new(memory) TTypeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: TArraySizes memory: This could be replaced by something smaller.
|
||||||
|
// Almost all arrays could be handled by two sizes each fitting
|
||||||
|
// in 16 bits, needing a real vector only in the cases where there
|
||||||
|
// are more than 3 sizes or a size needing more than 16 bits.
|
||||||
|
//
|
||||||
|
// The type is a pointer, so that it can be non-allocated and zero
|
||||||
|
// for the vast majority of non-array types. Note that means if it
|
||||||
|
// is used, it will be containing at least one size.
|
||||||
|
|
||||||
|
typedef TVector<int>* TArraySizes;
|
||||||
|
|
||||||
|
inline TArraySizes NewPoolTArraySizes()
|
||||||
|
{
|
||||||
|
void* memory = GlobalPoolAllocator.allocate(sizeof(TVector<int>));
|
||||||
|
return new(memory) TVector<int>;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is a workaround for a problem with the yacc stack, It can't have
|
// This is a workaround for a problem with the yacc stack, It can't have
|
||||||
// types that it thinks have non-trivial constructors. It should
|
// types that it thinks have non-trivial constructors. It should
|
||||||
@ -79,9 +97,8 @@ public:
|
|||||||
int vectorSize : 4;
|
int vectorSize : 4;
|
||||||
int matrixCols : 4;
|
int matrixCols : 4;
|
||||||
int matrixRows : 4;
|
int matrixRows : 4;
|
||||||
bool array;
|
TArraySizes arraySizes;
|
||||||
int arraySize;
|
const TType* userDef;
|
||||||
TType* userDef;
|
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
void initType(int ln = 0)
|
void initType(int ln = 0)
|
||||||
@ -90,8 +107,7 @@ public:
|
|||||||
vectorSize = 1;
|
vectorSize = 1;
|
||||||
matrixRows = 0;
|
matrixRows = 0;
|
||||||
matrixCols = 0;
|
matrixCols = 0;
|
||||||
array = false;
|
arraySizes = 0;
|
||||||
arraySize = 0;
|
|
||||||
userDef = 0;
|
userDef = 0;
|
||||||
line = ln;
|
line = ln;
|
||||||
}
|
}
|
||||||
@ -110,6 +126,8 @@ public:
|
|||||||
|
|
||||||
void setVector(int s)
|
void setVector(int s)
|
||||||
{
|
{
|
||||||
|
matrixRows = 0;
|
||||||
|
matrixCols = 0;
|
||||||
vectorSize = s;
|
vectorSize = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +137,6 @@ public:
|
|||||||
matrixCols = c;
|
matrixCols = c;
|
||||||
vectorSize = 0;
|
vectorSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setArray(bool a, int s = 0)
|
|
||||||
{
|
|
||||||
array = a;
|
|
||||||
arraySize = s;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<TTypeList*, TTypeList*> TStructureMap;
|
typedef std::map<TTypeList*, TTypeList*> TStructureMap;
|
||||||
@ -136,7 +148,7 @@ class TType {
|
|||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||||
explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
||||||
type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), array(false), arraySize(0),
|
type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
|
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
|
||||||
fieldName(0), mangled(0), typeName(0)
|
fieldName(0), mangled(0), typeName(0)
|
||||||
{
|
{
|
||||||
@ -144,7 +156,7 @@ public:
|
|||||||
qualifier.precision = EpqNone;
|
qualifier.precision = EpqNone;
|
||||||
}
|
}
|
||||||
explicit TType(const TPublicType &p) :
|
explicit TType(const TPublicType &p) :
|
||||||
type(p.type), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), array(p.array), arraySize(p.arraySize),
|
type(p.type), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
||||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||||
{
|
{
|
||||||
qualifier = p.qualifier;
|
qualifier = p.qualifier;
|
||||||
@ -154,7 +166,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
explicit TType(TTypeList* userDef, const TString& n) :
|
explicit TType(TTypeList* userDef, const TString& n) :
|
||||||
type(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), array(false), arraySize(0),
|
type(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0),
|
||||||
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
|
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
|
||||||
{
|
{
|
||||||
qualifier.storage = EvqTemporary;
|
qualifier.storage = EvqTemporary;
|
||||||
@ -173,9 +185,13 @@ public:
|
|||||||
vectorSize = copyOf.vectorSize;
|
vectorSize = copyOf.vectorSize;
|
||||||
matrixCols = copyOf.matrixCols;
|
matrixCols = copyOf.matrixCols;
|
||||||
matrixRows = copyOf.matrixRows;
|
matrixRows = copyOf.matrixRows;
|
||||||
array = copyOf.array;
|
|
||||||
arraySize = copyOf.arraySize;
|
if (copyOf.arraySizes) {
|
||||||
|
arraySizes = NewPoolTArraySizes();
|
||||||
|
*arraySizes = *copyOf.arraySizes;
|
||||||
|
} else
|
||||||
|
arraySizes = 0;
|
||||||
|
|
||||||
TStructureMapIterator iter;
|
TStructureMapIterator iter;
|
||||||
if (copyOf.structure) {
|
if (copyOf.structure) {
|
||||||
if ((iter = remapper.find(structure)) == remapper.end()) {
|
if ((iter = remapper.find(structure)) == remapper.end()) {
|
||||||
@ -220,9 +236,8 @@ public:
|
|||||||
|
|
||||||
virtual void dereference()
|
virtual void dereference()
|
||||||
{
|
{
|
||||||
if (array) {
|
if (arraySizes) {
|
||||||
array = false;
|
arraySizes = 0;
|
||||||
arraySize = 0;
|
|
||||||
maxArraySize = 0;
|
maxArraySize = 0;
|
||||||
} else if (matrixCols > 0) {
|
} else if (matrixCols > 0) {
|
||||||
vectorSize = matrixRows;
|
vectorSize = matrixRows;
|
||||||
@ -232,7 +247,7 @@ public:
|
|||||||
vectorSize = 1;
|
vectorSize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setElementType(TBasicType t, int s, int mc, int mr, TType* userDef)
|
virtual void setElementType(TBasicType t, int s, int mc, int mr, const TType* userDef)
|
||||||
{
|
{
|
||||||
type = t;
|
type = t;
|
||||||
vectorSize = s;
|
vectorSize = s;
|
||||||
@ -265,9 +280,15 @@ public:
|
|||||||
virtual int getMatrixRows() const { return matrixRows; }
|
virtual int getMatrixRows() const { return matrixRows; }
|
||||||
|
|
||||||
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
virtual bool isMatrix() const { return matrixCols ? true : false; }
|
||||||
virtual bool isArray() const { return array ? true : false; }
|
virtual bool isArray() const { return arraySizes != 0; }
|
||||||
int getArraySize() const { return arraySize; }
|
int getArraySize() const { return arraySizes->front(); }
|
||||||
void setArraySize(int s) { array = true; arraySize = s; }
|
void setArraySizes(TArraySizes s) {
|
||||||
|
// copy; we don't want distinct types sharing the same descriptor
|
||||||
|
if (! arraySizes)
|
||||||
|
arraySizes = NewPoolTArraySizes();
|
||||||
|
*arraySizes = *s;
|
||||||
|
}
|
||||||
|
void changeArraySize(int s) { arraySizes->front() = s; }
|
||||||
void setMaxArraySize (int s) { maxArraySize = s; }
|
void setMaxArraySize (int s) { maxArraySize = s; }
|
||||||
int getMaxArraySize () const { return maxArraySize; }
|
int getMaxArraySize () const { return maxArraySize; }
|
||||||
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
void setArrayInformationType(TType* t) { arrayInformationType = t; }
|
||||||
@ -336,7 +357,7 @@ public:
|
|||||||
vectorSize == right.vectorSize &&
|
vectorSize == right.vectorSize &&
|
||||||
matrixCols == right.matrixCols &&
|
matrixCols == right.matrixCols &&
|
||||||
matrixRows == right.matrixRows &&
|
matrixRows == right.matrixRows &&
|
||||||
array == right.array && (!array || arraySize == right.arraySize) &&
|
(arraySizes == 0 && right.arraySizes == 0 || (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes)) &&
|
||||||
structure == right.structure;
|
structure == right.structure;
|
||||||
// don't check the qualifier, it's not ever what's being sought after
|
// don't check the qualifier, it's not ever what's being sought after
|
||||||
}
|
}
|
||||||
@ -353,10 +374,9 @@ protected:
|
|||||||
int vectorSize : 4;
|
int vectorSize : 4;
|
||||||
int matrixCols : 4;
|
int matrixCols : 4;
|
||||||
int matrixRows : 4;
|
int matrixRows : 4;
|
||||||
unsigned int array : 1;
|
|
||||||
TQualifier qualifier;
|
TQualifier qualifier;
|
||||||
|
|
||||||
int arraySize;
|
TArraySizes arraySizes;
|
||||||
|
|
||||||
TTypeList* structure; // 0 unless this is a struct
|
TTypeList* structure; // 0 unless this is a struct
|
||||||
mutable int structureSize;
|
mutable int structureSize;
|
||||||
|
@ -713,7 +713,7 @@ void TBuiltIns::initialize()
|
|||||||
void TBuiltIns::initialize(const TBuiltInResource &resources)
|
void TBuiltIns::initialize(const TBuiltInResource &resources)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Initialize all the built-in strings for parsing.
|
// Initialize the context-dependent (resource-dependent) built-in strings for parsing.
|
||||||
//
|
//
|
||||||
TString StandardUniforms;
|
TString StandardUniforms;
|
||||||
|
|
||||||
@ -939,7 +939,9 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBu
|
|||||||
case EShLangFragment: {
|
case EShLangFragment: {
|
||||||
// Set up gl_FragData. The array size.
|
// Set up gl_FragData. The array size.
|
||||||
TType fragData(EbtFloat, EvqFragColor, 4);
|
TType fragData(EbtFloat, EvqFragColor, 4);
|
||||||
fragData.setArraySize(resources.maxDrawBuffers);
|
TArraySizes arraySizes = NewPoolTArraySizes();
|
||||||
|
arraySizes->push_back(resources.maxDrawBuffers);
|
||||||
|
fragData.setArraySizes(arraySizes);
|
||||||
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
|
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -571,9 +571,14 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
|
|||||||
if (constType)
|
if (constType)
|
||||||
type->getQualifier().storage = EvqConst;
|
type->getQualifier().storage = EvqConst;
|
||||||
|
|
||||||
if (type->isArray() && type->getArraySize() != function.getParamCount()) {
|
if (type->isArray()) {
|
||||||
error(line, "array constructor needs one argument per array element", "constructor", "");
|
if (type->getArraySize() == 0) {
|
||||||
return true;
|
// auto adapt the constructor type to the number of arguments
|
||||||
|
type->changeArraySize(function.getParamCount());
|
||||||
|
} else if (type->getArraySize() != function.getParamCount()) {
|
||||||
|
error(line, "array constructor needs one argument per array element", "constructor", "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrayArg && op != EOpConstructStruct) {
|
if (arrayArg && op != EOpConstructStruct) {
|
||||||
@ -653,7 +658,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
|
|||||||
//
|
//
|
||||||
bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
|
bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
|
||||||
{
|
{
|
||||||
if (pType.type != EbtBool || pType.array || pType.matrixCols > 1 || (pType.vectorSize > 1)) {
|
if (pType.type != EbtBool || pType.arraySizes || pType.matrixCols > 1 || (pType.vectorSize > 1)) {
|
||||||
error(line, "boolean expression expected", "", "");
|
error(line, "boolean expression expected", "", "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -743,7 +748,7 @@ bool TParseContext::parameterSamplerErrorCheck(int line, TStorageQualifier quali
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TParseContext::containsSampler(TType& type)
|
bool TParseContext::containsSampler(const TType& type)
|
||||||
{
|
{
|
||||||
if (IsSampler(type.getBasicType()))
|
if (IsSampler(type.getBasicType()))
|
||||||
return true;
|
return true;
|
||||||
@ -866,9 +871,6 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
|
|||||||
|
|
||||||
variable = new TVariable(&identifier, TType(type));
|
variable = new TVariable(&identifier, TType(type));
|
||||||
|
|
||||||
if (type.arraySize)
|
|
||||||
variable->getType().setArraySize(type.arraySize);
|
|
||||||
|
|
||||||
if (! symbolTable.insert(*variable)) {
|
if (! symbolTable.insert(*variable)) {
|
||||||
delete variable;
|
delete variable;
|
||||||
error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
|
error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
|
||||||
@ -897,16 +899,15 @@ bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType t
|
|||||||
|
|
||||||
TType* t = variable->getArrayInformationType();
|
TType* t = variable->getArrayInformationType();
|
||||||
while (t != 0) {
|
while (t != 0) {
|
||||||
if (t->getMaxArraySize() > type.arraySize) {
|
if (t->getMaxArraySize() > type.arraySizes->front()) {
|
||||||
error(line, "higher index value already used for the array", identifier.c_str(), "");
|
error(line, "higher index value already used for the array", identifier.c_str(), "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
t->setArraySize(type.arraySize);
|
t->setArraySizes(type.arraySizes);
|
||||||
t = t->getArrayInformationType();
|
t = t->getArrayInformationType();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.arraySize)
|
variable->getType().setArraySizes(type.arraySizes);
|
||||||
variable->getType().setArraySize(type.arraySize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voidErrorCheck(line, identifier, type))
|
if (voidErrorCheck(line, identifier, type))
|
||||||
@ -1094,10 +1095,15 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
|
|||||||
error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
|
error(line, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix arrayness if variable is unsized, getting size for initializer
|
||||||
|
if (initializer->getType().isArray() && initializer->getType().getArraySize() > 0 &&
|
||||||
|
type.isArray() && type.getArraySize() == 0)
|
||||||
|
type.changeArraySize(initializer->getType().getArraySize());
|
||||||
|
|
||||||
//
|
//
|
||||||
// test for and propagate constant
|
// test for and propagate constant
|
||||||
//
|
//
|
||||||
|
|
||||||
if (qualifier == EvqConst) {
|
if (qualifier == EvqConst) {
|
||||||
if (qualifier != initializer->getType().getQualifier().storage) {
|
if (qualifier != initializer->getType().getQualifier().storage) {
|
||||||
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||||
@ -1471,8 +1477,8 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||||||
TType arrayElementType = node->getType();
|
TType arrayElementType = node->getType();
|
||||||
arrayElementType.dereference();
|
arrayElementType.dereference();
|
||||||
|
|
||||||
if (index >= node->getType().getArraySize()) {
|
if (index >= node->getType().getArraySize() || index < 0) {
|
||||||
error(line, "", "[", "array index out of range '%d'", index);
|
error(line, "", "[", "array index '%d' out of range", index);
|
||||||
recover();
|
recover();
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ struct TParseContext {
|
|||||||
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
bool structQualifierErrorCheck(int line, const TPublicType& pType);
|
||||||
void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
|
void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
|
||||||
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
|
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
|
||||||
bool containsSampler(TType& type);
|
bool containsSampler(const TType& type);
|
||||||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
|
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||||
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
|
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||||
bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type);
|
bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type);
|
||||||
@ -154,7 +154,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
|
|||||||
void PaReservedWord();
|
void PaReservedWord();
|
||||||
int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
|
int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
|
||||||
int PaParseComment(int &lineno, TParseContext&);
|
int PaParseComment(int &lineno, TParseContext&);
|
||||||
void setInitialState();
|
void ResetFlex();
|
||||||
|
|
||||||
typedef TParseContext* TParseContextPointer;
|
typedef TParseContext* TParseContextPointer;
|
||||||
extern TParseContextPointer& GetGlobalParseContext();
|
extern TParseContextPointer& GetGlobalParseContext();
|
||||||
|
@ -194,13 +194,11 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
|
|||||||
|
|
||||||
GlobalParseContext = &parseContext;
|
GlobalParseContext = &parseContext;
|
||||||
|
|
||||||
setInitialState();
|
|
||||||
|
|
||||||
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
|
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parse the built-ins. This should only happen once per
|
// Parse the built-ins. This should only happen once per
|
||||||
// language symbol table.
|
// language symbol table when no 'resources' are passed in.
|
||||||
//
|
//
|
||||||
// Push the symbol table to give it an initial scope. This
|
// Push the symbol table to give it an initial scope. This
|
||||||
// push should not have a corresponding pop, so that built-ins
|
// push should not have a corresponding pop, so that built-ins
|
||||||
@ -208,6 +206,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
|
|||||||
//
|
//
|
||||||
|
|
||||||
symbolTable->push();
|
symbolTable->push();
|
||||||
|
|
||||||
|
|
||||||
//Initialize the Preprocessor
|
//Initialize the Preprocessor
|
||||||
int ret = InitPreprocessor();
|
int ret = InitPreprocessor();
|
||||||
@ -215,6 +214,8 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
|
|||||||
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
|
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResetFlex();
|
||||||
|
|
||||||
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
|
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
|
||||||
i != BuiltInStrings[parseContext.language].end(); ++i) {
|
i != BuiltInStrings[parseContext.language].end(); ++i) {
|
||||||
@ -229,15 +230,13 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FinalizePreprocessor();
|
||||||
|
|
||||||
if (resources) {
|
if (resources) {
|
||||||
IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
|
IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
|
||||||
} else {
|
} else {
|
||||||
IdentifyBuiltIns(parseContext.language, *symbolTable);
|
IdentifyBuiltIns(parseContext.language, *symbolTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
FinalizePreprocessor();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +278,8 @@ int ShCompile(
|
|||||||
TIntermediate intermediate(compiler->infoSink);
|
TIntermediate intermediate(compiler->infoSink);
|
||||||
TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]);
|
TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]);
|
||||||
|
|
||||||
|
// Add built-in symbols that are potentially context dependent;
|
||||||
|
// they get popped again further down.
|
||||||
GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
|
GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
|
||||||
|
|
||||||
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink, defaultVersion);
|
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink, defaultVersion);
|
||||||
@ -286,9 +287,9 @@ int ShCompile(
|
|||||||
|
|
||||||
GlobalParseContext = &parseContext;
|
GlobalParseContext = &parseContext;
|
||||||
|
|
||||||
setInitialState();
|
ResetFlex();
|
||||||
|
InitPreprocessor();
|
||||||
|
|
||||||
InitPreprocessor();
|
|
||||||
//
|
//
|
||||||
// Parse the application's shaders. All the following symbol table
|
// Parse the application's shaders. All the following symbol table
|
||||||
// work will be throw-away, so push a new allocation scope that can
|
// work will be throw-away, so push a new allocation scope that can
|
||||||
|
@ -87,10 +87,10 @@ void TType::buildMangledName(TString& mangledName)
|
|||||||
mangledName += static_cast<char>('0' + getMatrixRows());
|
mangledName += static_cast<char>('0' + getMatrixRows());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArray()) {
|
if (arraySizes) {
|
||||||
const int maxSize = 10;
|
const int maxSize = 10;
|
||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
sprintf_s(buf, maxSize, "%d", arraySize);
|
sprintf_s(buf, maxSize, "%d", arraySizes->front());
|
||||||
mangledName += '[';
|
mangledName += '[';
|
||||||
mangledName += buf;
|
mangledName += buf;
|
||||||
mangledName += ']';
|
mangledName += ']';
|
||||||
|
@ -861,7 +861,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
|
|||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
void setInitialState()
|
void ResetFlex()
|
||||||
{
|
{
|
||||||
yy_start = 1;
|
yy_start = 1;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ Jutta Degener, 1995
|
|||||||
TParameter param;
|
TParameter param;
|
||||||
TTypeLine typeLine;
|
TTypeLine typeLine;
|
||||||
TTypeList* typeList;
|
TTypeList* typeList;
|
||||||
TVector<int>* intVector;
|
TArraySizes arraySizes;
|
||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
}
|
}
|
||||||
@ -321,7 +321,8 @@ postfix_expression
|
|||||||
if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
|
if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
}
|
||||||
} else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
|
} else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize() ||
|
||||||
|
$3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0) {
|
||||||
parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
|
parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
}
|
||||||
@ -345,8 +346,8 @@ postfix_expression
|
|||||||
TType newType = $1->getType();
|
TType newType = $1->getType();
|
||||||
newType.dereference();
|
newType.dereference();
|
||||||
$$->setType(newType);
|
$$->setType(newType);
|
||||||
//?? why didn't the code above get the type right?
|
//?? why wouldn't the code above get the type right?
|
||||||
//?? write a deference test
|
//?? write a dereference test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| function_call {
|
| function_call {
|
||||||
@ -444,8 +445,7 @@ postfix_expression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//?? fix message
|
parseContext.error($2.line, " dot operator requires structure, array, vector, or matrix on left hand side", $3.string->c_str(), "");
|
||||||
parseContext.error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
|
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
@ -489,13 +489,16 @@ function_call
|
|||||||
TOperator op = fnCall->getBuiltInOp();
|
TOperator op = fnCall->getBuiltInOp();
|
||||||
if (op == EOpArrayLength) {
|
if (op == EOpArrayLength) {
|
||||||
// TODO: check for no arguments to .length()
|
// TODO: check for no arguments to .length()
|
||||||
if ($1.intermNode->getAsTyped() == 0 || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
|
int length;
|
||||||
|
if ($1.intermNode->getAsTyped() == 0 || ! $1.intermNode->getAsTyped()->getType().isArray() || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
|
||||||
parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
|
parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
length = 1;
|
||||||
|
} else
|
||||||
|
length = $1.intermNode->getAsTyped()->getType().getArraySize();
|
||||||
|
|
||||||
constUnion *unionArray = new constUnion[1];
|
constUnion *unionArray = new constUnion[1];
|
||||||
unionArray->setIConst($1.intermNode->getAsTyped()->getType().getArraySize());
|
unionArray->setIConst(length);
|
||||||
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
|
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
|
||||||
} else if (op != EOpNull) {
|
} else if (op != EOpNull) {
|
||||||
//
|
//
|
||||||
@ -647,8 +650,9 @@ function_identifier
|
|||||||
$$.function = 0;
|
$$.function = 0;
|
||||||
$$.intermNode = 0;
|
$$.intermNode = 0;
|
||||||
|
|
||||||
if ($1.array) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
|
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed constructor");
|
||||||
|
parseContext.profileRequires($1.line, EEsProfile, 300, "GL_3DL_array_objects", "arrayed constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
$1.qualifier.precision = EpqNone;
|
$1.qualifier.precision = EpqNone;
|
||||||
@ -1284,6 +1288,10 @@ function_header
|
|||||||
parameter_declarator
|
parameter_declarator
|
||||||
// Type + name
|
// Type + name
|
||||||
: type_specifier IDENTIFIER {
|
: type_specifier IDENTIFIER {
|
||||||
|
if ($1.arraySizes) {
|
||||||
|
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
|
}
|
||||||
if ($1.type == EbtVoid) {
|
if ($1.type == EbtVoid) {
|
||||||
parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
|
parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
@ -1296,13 +1304,18 @@ parameter_declarator
|
|||||||
$$.param = param;
|
$$.param = param;
|
||||||
}
|
}
|
||||||
| type_specifier IDENTIFIER array_specifier {
|
| type_specifier IDENTIFIER array_specifier {
|
||||||
if (parseContext.arraySizeRequiredErrorCheck($3.line, $3.intVector->front()))
|
if ($1.arraySizes) {
|
||||||
|
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseContext.arraySizeRequiredErrorCheck($3.line, $3.arraySizes->front()))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
|
|
||||||
if (parseContext.reservedErrorCheck($2.line, *$2.string))
|
if (parseContext.reservedErrorCheck($2.line, *$2.string))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
|
|
||||||
$1.setArray(true, $3.intVector->front());
|
$1.arraySizes = $3.arraySizes;
|
||||||
|
|
||||||
TParameter param = { $2.string, new TType($1)};
|
TParameter param = { $2.string, new TType($1)};
|
||||||
$$.line = $2.line;
|
$$.line = $2.line;
|
||||||
@ -1389,7 +1402,7 @@ init_declarator_list
|
|||||||
if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
|
if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
else {
|
else {
|
||||||
$1.type.setArray(true, $4.intVector->front());
|
$1.type.arraySizes = $4.arraySizes;
|
||||||
TVariable* variable;
|
TVariable* variable;
|
||||||
if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
@ -1405,7 +1418,7 @@ init_declarator_list
|
|||||||
if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
|
if (parseContext.arrayQualifierErrorCheck($4.line, $1.type))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
else {
|
else {
|
||||||
$1.type.setArray(true, $4.intVector->front());
|
$1.type.arraySizes = $4.arraySizes;
|
||||||
if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
if (parseContext.arrayErrorCheck($4.line, *$3.string, $1.type, variable))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
}
|
||||||
@ -1490,7 +1503,7 @@ single_declaration
|
|||||||
if (parseContext.arrayQualifierErrorCheck($3.line, $1))
|
if (parseContext.arrayQualifierErrorCheck($3.line, $1))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
else {
|
else {
|
||||||
$1.setArray(true, $3.intVector->front());
|
$1.arraySizes = $3.arraySizes;
|
||||||
TVariable* variable;
|
TVariable* variable;
|
||||||
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
|
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
@ -1508,7 +1521,7 @@ single_declaration
|
|||||||
if (parseContext.arrayQualifierErrorCheck($3.line, $1))
|
if (parseContext.arrayQualifierErrorCheck($3.line, $1))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
else {
|
else {
|
||||||
$1.setArray(true, $3.intVector->front());
|
$1.arraySizes = $3.arraySizes;
|
||||||
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
|
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
}
|
||||||
@ -1556,17 +1569,20 @@ fully_specified_type
|
|||||||
: type_specifier {
|
: type_specifier {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
|
||||||
if ($1.array) {
|
if ($1.arraySizes) {
|
||||||
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
|
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| type_qualifier type_specifier {
|
| type_qualifier type_specifier {
|
||||||
if ($2.array)
|
if ($2.arraySizes) {
|
||||||
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "array");
|
parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
|
}
|
||||||
|
|
||||||
if ($2.array && parseContext.arrayQualifierErrorCheck($2.line, $1)) {
|
if ($2.arraySizes && parseContext.arrayQualifierErrorCheck($2.line, $1)) {
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
$2.setArray(false);
|
$2.arraySizes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($1.qualifier.storage == EvqAttribute &&
|
if ($1.qualifier.storage == EvqAttribute &&
|
||||||
@ -1833,28 +1849,28 @@ type_specifier
|
|||||||
| type_specifier_nonarray array_specifier {
|
| type_specifier_nonarray array_specifier {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
|
$$.qualifier.precision = parseContext.defaultPrecision[$$.type];
|
||||||
$$.setArray(true, $2.intVector->front());
|
$$.arraySizes = $2.arraySizes;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
array_specifier
|
array_specifier
|
||||||
: LEFT_BRACKET RIGHT_BRACKET {
|
: LEFT_BRACKET RIGHT_BRACKET {
|
||||||
$$.line = $1.line;
|
$$.line = $1.line;
|
||||||
$$.intVector = new TVector<int>;
|
$$.arraySizes = NewPoolTArraySizes();
|
||||||
$$.intVector->push_back(0);
|
$$.arraySizes->push_back(0);
|
||||||
}
|
}
|
||||||
| LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
| LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
||||||
$$.line = $1.line;
|
$$.line = $1.line;
|
||||||
$$.intVector = new TVector<int>;
|
$$.arraySizes = NewPoolTArraySizes();
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
if (parseContext.arraySizeErrorCheck($2->getLine(), $2, size))
|
if (parseContext.arraySizeErrorCheck($2->getLine(), $2, size))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
$$.intVector->push_back(size);
|
$$.arraySizes->push_back(size);
|
||||||
}
|
}
|
||||||
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
|
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$.intVector->push_back(0);
|
$$.arraySizes->push_back(0);
|
||||||
}
|
}
|
||||||
| array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
| array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -1862,7 +1878,7 @@ array_specifier
|
|||||||
int size;
|
int size;
|
||||||
if (parseContext.arraySizeErrorCheck($3->getLine(), $3, size))
|
if (parseContext.arraySizeErrorCheck($3->getLine(), $3, size))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
$$.intVector->push_back(size);
|
$$.arraySizes->push_back(size);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2443,7 +2459,7 @@ type_specifier_nonarray
|
|||||||
// This is for user defined type names. The lexical phase looked up the
|
// This is for user defined type names. The lexical phase looked up the
|
||||||
// type.
|
// type.
|
||||||
//
|
//
|
||||||
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
|
const TType& structure = static_cast<const TVariable*>($1.symbol)->getType();
|
||||||
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
$$.init($1.line, parseContext.symbolTable.atGlobalLevel());
|
||||||
$$.type = EbtStruct;
|
$$.type = EbtStruct;
|
||||||
$$.userDef = &structure;
|
$$.userDef = &structure;
|
||||||
@ -2511,6 +2527,11 @@ struct_declaration_list
|
|||||||
|
|
||||||
struct_declaration
|
struct_declaration
|
||||||
: type_specifier struct_declarator_list SEMICOLON {
|
: type_specifier struct_declarator_list SEMICOLON {
|
||||||
|
if ($1.arraySizes) {
|
||||||
|
parseContext.profileRequires($1.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($1.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
|
}
|
||||||
|
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
|
|
||||||
if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
|
if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
|
||||||
@ -2522,13 +2543,18 @@ struct_declaration
|
|||||||
//
|
//
|
||||||
(*$$)[i].type->setElementType($1.type, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
|
(*$$)[i].type->setElementType($1.type, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
|
||||||
|
|
||||||
if ($1.array)
|
if ($1.arraySizes)
|
||||||
(*$$)[i].type->setArraySize($1.arraySize);
|
(*$$)[i].type->setArraySizes($1.arraySizes);
|
||||||
if ($1.userDef)
|
if ($1.userDef)
|
||||||
(*$$)[i].type->setTypeName($1.userDef->getTypeName());
|
(*$$)[i].type->setTypeName($1.userDef->getTypeName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
||||||
|
if ($2.arraySizes) {
|
||||||
|
parseContext.profileRequires($2.line, ENoProfile, 120, "GL_3DL_array_objects", "arrayed type");
|
||||||
|
parseContext.profileRequires($2.line, EEsProfile, 300, 0, "arrayed type");
|
||||||
|
}
|
||||||
|
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
|
|
||||||
if (parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2)) {
|
if (parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2)) {
|
||||||
@ -2540,8 +2566,8 @@ struct_declaration
|
|||||||
//
|
//
|
||||||
(*$$)[i].type->setElementType($2.type, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
|
(*$$)[i].type->setElementType($2.type, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
|
||||||
|
|
||||||
if ($2.array)
|
if ($2.arraySizes)
|
||||||
(*$$)[i].type->setArraySize($2.arraySize);
|
(*$$)[i].type->setArraySizes($2.arraySizes);
|
||||||
if ($2.userDef)
|
if ($2.userDef)
|
||||||
(*$$)[i].type->setTypeName($2.userDef->getTypeName());
|
(*$$)[i].type->setTypeName($2.userDef->getTypeName());
|
||||||
}
|
}
|
||||||
@ -2568,7 +2594,7 @@ struct_declarator
|
|||||||
$$.type = new TType(EbtVoid);
|
$$.type = new TType(EbtVoid);
|
||||||
$$.line = $1.line;
|
$$.line = $1.line;
|
||||||
$$.type->setFieldName(*$1.string);
|
$$.type->setFieldName(*$1.string);
|
||||||
$$.type->setArraySize($2.intVector->front());
|
$$.type->setArraySizes($2.arraySizes);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -64,8 +64,12 @@ TString TType::getCompleteString() const
|
|||||||
|
|
||||||
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
|
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
|
||||||
p += sprintf_s(p, end - p, "%s ", getStorageQualifierString());
|
p += sprintf_s(p, end - p, "%s ", getStorageQualifierString());
|
||||||
if (array)
|
if (arraySizes) {
|
||||||
p += sprintf_s(p, end - p, "array of ");
|
if (arraySizes->front() == 0)
|
||||||
|
p += sprintf_s(p, end - p, "unsized array of ");
|
||||||
|
else
|
||||||
|
p += sprintf_s(p, end - p, "%d-element array of ", arraySizes->front());
|
||||||
|
}
|
||||||
if (qualifier.precision != EpqNone)
|
if (qualifier.precision != EpqNone)
|
||||||
p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
|
p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
|
||||||
if (matrixCols > 0)
|
if (matrixCols > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user