Block/structure fixes: Merge qualifiers with multiple declarators, handle arrays of blocks, more semantic checks for what's allowed.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21883 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ceb0623823
commit
0fbb0c4930
38
Test/300block.frag
Normal file
38
Test/300block.frag
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#version 300 es
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
vec4 u;
|
||||||
|
uvec4 v;
|
||||||
|
isampler3D sampler;
|
||||||
|
vec3 w;
|
||||||
|
struct T1 { // ERROR
|
||||||
|
int a;
|
||||||
|
} t;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform S s;
|
||||||
|
|
||||||
|
uniform fooBlock {
|
||||||
|
uvec4 bv;
|
||||||
|
mat2 bm2;
|
||||||
|
isampler2D sampler; // ERROR
|
||||||
|
struct T2 { // ERROR
|
||||||
|
int a;
|
||||||
|
} t;
|
||||||
|
S fbs;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform barBlock {
|
||||||
|
uvec4 nbv;
|
||||||
|
int ni;
|
||||||
|
} inst;
|
||||||
|
|
||||||
|
uniform barBlockArray {
|
||||||
|
uvec4 nbv;
|
||||||
|
int ni;
|
||||||
|
} insts[4];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
texture(s.sampler, vec3(inst.ni, bv.y, insts[2].nbv.z));
|
||||||
|
}
|
@ -27,6 +27,7 @@ comment.frag
|
|||||||
300layout.vert
|
300layout.vert
|
||||||
300layout.frag
|
300layout.frag
|
||||||
300operations.frag
|
300operations.frag
|
||||||
|
300block.frag
|
||||||
330.frag
|
330.frag
|
||||||
330comp.frag
|
330comp.frag
|
||||||
constErrors.frag
|
constErrors.frag
|
||||||
|
@ -392,7 +392,7 @@ typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
|
|||||||
class TType {
|
class TType {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||||
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) :
|
||||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
basicType(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)
|
||||||
@ -416,7 +416,10 @@ public:
|
|||||||
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
basicType(p.basicType), 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)
|
||||||
{
|
{
|
||||||
sampler = p.sampler;
|
if (basicType == EbtSampler)
|
||||||
|
sampler = p.sampler;
|
||||||
|
else
|
||||||
|
sampler.clear();
|
||||||
qualifier = p.qualifier;
|
qualifier = p.qualifier;
|
||||||
if (p.userDef) {
|
if (p.userDef) {
|
||||||
structure = p.userDef->getStruct();
|
structure = p.userDef->getStruct();
|
||||||
@ -494,6 +497,21 @@ public:
|
|||||||
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
|
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge type from parent, where a parentType is at the beginning of a declaration,
|
||||||
|
// establishing some charastics for all subsequent names, while this type
|
||||||
|
// is on the individual names.
|
||||||
|
void mergeType(const TPublicType& parentType)
|
||||||
|
{
|
||||||
|
// arrayness is currently the only child aspect that has to be preserved
|
||||||
|
setElementType(parentType.basicType, parentType.vectorSize, parentType.matrixCols, parentType.matrixRows, parentType.userDef);
|
||||||
|
qualifier = parentType.qualifier;
|
||||||
|
sampler = parentType.sampler;
|
||||||
|
if (parentType.arraySizes)
|
||||||
|
setArraySizes(parentType.arraySizes);
|
||||||
|
if (parentType.userDef)
|
||||||
|
setTypeName(parentType.userDef->getTypeName());
|
||||||
|
}
|
||||||
|
|
||||||
TType* clone(const TStructureMap& remapper)
|
TType* clone(const TStructureMap& remapper)
|
||||||
{
|
{
|
||||||
TType *newType = new TType();
|
TType *newType = new TType();
|
||||||
|
@ -676,7 +676,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do non in/out error checks
|
// Do non-in/out error checks
|
||||||
|
|
||||||
if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
|
if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
|
||||||
return true;
|
return true;
|
||||||
@ -1517,7 +1517,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for qualifiers that don't belong within a block
|
// check for qualifiers and types that don't belong within a block
|
||||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||||
TQualifier memberQualifier = typeList[member].type->getQualifier();
|
TQualifier memberQualifier = typeList[member].type->getQualifier();
|
||||||
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
|
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
|
||||||
@ -1531,6 +1531,12 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
|||||||
recover();
|
recover();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TBasicType basicType = typeList[member].type->getBasicType();
|
||||||
|
if (basicType == EbtSampler) {
|
||||||
|
error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
|
||||||
|
recover();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make default block qualification, and adjust the member qualifications
|
// Make default block qualification, and adjust the member qualifications
|
||||||
@ -1546,6 +1552,8 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
|||||||
// Build and add the interface block as a new type named blockName
|
// Build and add the interface block as a new type named blockName
|
||||||
|
|
||||||
TType blockType(&typeList, blockName, publicType.qualifier.storage);
|
TType blockType(&typeList, blockName, publicType.qualifier.storage);
|
||||||
|
if (arraySizes)
|
||||||
|
blockType.setArraySizes(arraySizes);
|
||||||
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
|
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
|
||||||
TVariable* userTypeDef = new TVariable(&blockName, blockType, true);
|
TVariable* userTypeDef = new TVariable(&blockName, blockType, true);
|
||||||
if (! symbolTable.insert(*userTypeDef)) {
|
if (! symbolTable.insert(*userTypeDef)) {
|
||||||
|
@ -1600,11 +1600,11 @@ fully_specified_type
|
|||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
$2.arraySizes = 0;
|
$2.arraySizes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
|
||||||
|
parseContext.recover();
|
||||||
|
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
$$.qualifier = $1.qualifier;
|
|
||||||
if ($$.qualifier.precision == EpqNone)
|
|
||||||
$$.qualifier.precision = $2.qualifier.precision;
|
|
||||||
|
|
||||||
if (! $$.qualifier.isInterpolation() && parseContext.language == EShLangFragment)
|
if (! $$.qualifier.isInterpolation() && parseContext.language == EShLangFragment)
|
||||||
$$.qualifier.smooth = true;
|
$$.qualifier.smooth = true;
|
||||||
@ -2560,6 +2560,10 @@ precision_qualifier
|
|||||||
struct_specifier
|
struct_specifier
|
||||||
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
|
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
|
||||||
// TODO: semantics: check for qualifiers that don't belong in a struct
|
// TODO: semantics: check for qualifiers that don't belong in a struct
|
||||||
|
|
||||||
|
// TODO: semantics: check that this is not nested inside a block or structure
|
||||||
|
// parseContext.error($1.line, "cannot nest a block or structure definitions", $1.userDef->getTypeName().c_str(), "");
|
||||||
|
|
||||||
TType* structure = new TType($4, *$2.string);
|
TType* structure = new TType($4, *$2.string);
|
||||||
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
|
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
|
||||||
if (! parseContext.symbolTable.insert(*userTypeDef)) {
|
if (! parseContext.symbolTable.insert(*userTypeDef)) {
|
||||||
@ -2608,17 +2612,8 @@ struct_declaration
|
|||||||
if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
|
if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
for (unsigned int i = 0; i < $$->size(); ++i)
|
||||||
//
|
(*$$)[i].type->mergeType($1);
|
||||||
// Careful not to replace already know aspects of type, like array-ness
|
|
||||||
//
|
|
||||||
(*$$)[i].type->setElementType($1.basicType, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
|
|
||||||
|
|
||||||
if ($1.arraySizes)
|
|
||||||
(*$$)[i].type->setArraySizes($1.arraySizes);
|
|
||||||
if ($1.userDef)
|
|
||||||
(*$$)[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) {
|
if ($2.arraySizes) {
|
||||||
@ -2632,17 +2627,8 @@ struct_declaration
|
|||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
|
if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
|
||||||
parseContext.recover();
|
parseContext.recover();
|
||||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
for (unsigned int i = 0; i < $$->size(); ++i)
|
||||||
//
|
(*$$)[i].type->mergeType($2);
|
||||||
// Careful not to replace already know aspects of type, like array-ness
|
|
||||||
//
|
|
||||||
(*$$)[i].type->setElementType($2.basicType, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
|
|
||||||
(*$$)[i].type->getQualifier() = $2.qualifier;
|
|
||||||
if ($2.arraySizes)
|
|
||||||
(*$$)[i].type->setArraySizes($2.arraySizes);
|
|
||||||
if ($2.userDef)
|
|
||||||
(*$$)[i].type->setTypeName($2.userDef->getTypeName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -982,7 +982,7 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp)
|
|||||||
// return a zero, for scanning a macro that was never defined
|
// return a zero, for scanning a macro that was never defined
|
||||||
static int zero_scan(InputSrc *inInput, yystypepp * yylvalpp)
|
static int zero_scan(InputSrc *inInput, yystypepp * yylvalpp)
|
||||||
{
|
{
|
||||||
MacroInputSrc* in = (MacroInputSrc*)inInput; //?? need to free this?
|
MacroInputSrc* in = (MacroInputSrc*)inInput;
|
||||||
|
|
||||||
strcpy(yylvalpp->symbol_name, "0");
|
strcpy(yylvalpp->symbol_name, "0");
|
||||||
yylvalpp->sc_int = 0;
|
yylvalpp->sc_int = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user