Do qualifier-based checking independent of declaring a variable. Bug 11903.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@28502 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
39cf638945
commit
f0fce80aa7
11 changed files with 63 additions and 42 deletions
|
|
@ -1983,10 +1983,11 @@ void TParseContext::atomicUintCheck(TSourceLoc loc, const TType& type, const TSt
|
|||
}
|
||||
|
||||
//
|
||||
// move from parameter/unknown qualifiers to pipeline in/out qualifiers
|
||||
// Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level.
|
||||
//
|
||||
void TParseContext::pipeInOutFix(TSourceLoc loc, TQualifier& qualifier)
|
||||
void TParseContext::globalQualifierFixCheck(TSourceLoc loc, TQualifier& qualifier)
|
||||
{
|
||||
// move from parameter/unknown qualifiers to pipeline in/out qualifiers
|
||||
switch (qualifier.storage) {
|
||||
case EvqIn:
|
||||
profileRequires(loc, ENoProfile, 130, 0, "in for stage inputs");
|
||||
|
|
@ -2005,9 +2006,14 @@ void TParseContext::pipeInOutFix(TSourceLoc loc, TQualifier& qualifier)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
invariantCheck(loc, qualifier);
|
||||
}
|
||||
|
||||
void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& qualifier, const TPublicType& publicType)
|
||||
//
|
||||
// Check a full qualifier and type (no variable yet) at global level.
|
||||
//
|
||||
void TParseContext::globalQualifierTypeCheck(TSourceLoc loc, const TQualifier& qualifier, const TPublicType& publicType)
|
||||
{
|
||||
if (! symbolTable.atGlobalLevel())
|
||||
return;
|
||||
|
|
@ -3598,7 +3604,7 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TType& type)
|
|||
error(loc, "image variables not declared 'writeonly' must have a format layout qualifier", "", "");
|
||||
}
|
||||
|
||||
// Do layout error checking that can be done within a qualifier proper, not needing to know
|
||||
// Do layout error checking that can be done within a layout qualifier proper, not needing to know
|
||||
// if there are blocks, atomic counters, variables, etc.
|
||||
void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& qualifier)
|
||||
{
|
||||
|
|
@ -3896,7 +3902,6 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||
else
|
||||
nonInitConstCheck(loc, identifier, type);
|
||||
|
||||
invariantCheck(loc, type, identifier);
|
||||
samplerCheck(loc, type, identifier);
|
||||
atomicUintCheck(loc, type, identifier);
|
||||
|
||||
|
|
@ -4409,7 +4414,7 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr
|
|||
TType& memberType = *typeList[member].type;
|
||||
TQualifier& memberQualifier = memberType.getQualifier();
|
||||
TSourceLoc memberLoc = typeList[member].loc;
|
||||
pipeInOutFix(memberLoc, memberQualifier);
|
||||
globalQualifierFixCheck(memberLoc, memberQualifier);
|
||||
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage)
|
||||
error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
|
||||
memberQualifier.storage = currentBlockQualifier.storage;
|
||||
|
|
@ -4750,7 +4755,7 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
|||
if (intermediate.inIoAccessed(identifier))
|
||||
error(loc, "cannot change qualification after use", "invariant", "");
|
||||
symbol->getWritableType().getQualifier().invariant = true;
|
||||
invariantCheck(loc, symbol->getType(), identifier);
|
||||
invariantCheck(loc, symbol->getType().getQualifier());
|
||||
} else
|
||||
warn(loc, "unknown requalification", "", "");
|
||||
}
|
||||
|
|
@ -4761,19 +4766,19 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
|||
addQualifierToExisting(loc, qualifier, *identifiers[i]);
|
||||
}
|
||||
|
||||
void TParseContext::invariantCheck(TSourceLoc loc, const TType& type, const TString& identifier)
|
||||
void TParseContext::invariantCheck(TSourceLoc loc, const TQualifier& qualifier)
|
||||
{
|
||||
if (! type.getQualifier().invariant)
|
||||
if (! qualifier.invariant)
|
||||
return;
|
||||
|
||||
bool pipeOut = type.getQualifier().isPipeOutput();
|
||||
bool pipeIn = type.getQualifier().isPipeInput();
|
||||
bool pipeOut = qualifier.isPipeOutput();
|
||||
bool pipeIn = qualifier.isPipeInput();
|
||||
if (version >= 300 || profile != EEsProfile && version >= 420) {
|
||||
if (! pipeOut)
|
||||
error(loc, "can only apply to an output:", "invariant", identifier.c_str());
|
||||
error(loc, "can only apply to an output", "invariant", "");
|
||||
} else {
|
||||
if ((language == EShLangVertex && pipeIn) || (! pipeOut && ! pipeIn))
|
||||
error(loc, "can only apply to an output or an input in a non-vertex stage\n", "invariant", "");
|
||||
error(loc, "can only apply to an output, or to an input in a non-vertex stage\n", "invariant", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5002,7 +5007,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression,
|
|||
return expression;
|
||||
|
||||
if (lastStatements == 0) {
|
||||
warn(loc, "last case/default label not be followed by statements", "switch", "");
|
||||
warn(loc, "last case/default label not followed by statements", "switch", "");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ public:
|
|||
void boolCheck(TSourceLoc, const TPublicType&);
|
||||
void samplerCheck(TSourceLoc, const TType&, const TString& identifier);
|
||||
void atomicUintCheck(TSourceLoc, const TType&, const TString& identifier);
|
||||
void pipeInOutFix(TSourceLoc, TQualifier&);
|
||||
void globalQualifierCheck(TSourceLoc, const TQualifier&, const TPublicType&);
|
||||
void globalQualifierFixCheck(TSourceLoc, TQualifier&);
|
||||
void globalQualifierTypeCheck(TSourceLoc, const TQualifier&, const TPublicType&);
|
||||
bool structQualifierErrorCheck(TSourceLoc, const TPublicType& pType);
|
||||
void mergeQualifiers(TSourceLoc, TQualifier& dst, const TQualifier& src, bool force);
|
||||
void setDefaultPrecision(TSourceLoc, TPublicType&, TPrecisionQualifier);
|
||||
|
|
@ -180,7 +180,7 @@ public:
|
|||
void fixBlockUniformOffsets(TSourceLoc, TQualifier&, TTypeList&);
|
||||
void addQualifierToExisting(TSourceLoc, TQualifier, const TString& identifier);
|
||||
void addQualifierToExisting(TSourceLoc, TQualifier, TIdentifierList&);
|
||||
void invariantCheck(TSourceLoc, const TType&, const TString& identifier);
|
||||
void invariantCheck(TSourceLoc, const TQualifier&);
|
||||
void updateStandaloneQualifierDefaults(TSourceLoc, const TPublicType&);
|
||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||
TIntermNode* addSwitch(TSourceLoc, TIntermTyped* expression, TIntermAggregate* body);
|
||||
|
|
|
|||
|
|
@ -696,18 +696,16 @@ declaration
|
|||
$$ = 0;
|
||||
}
|
||||
| type_qualifier SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
parseContext.updateStandaloneQualifierDefaults($1.loc, $1);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER identifier_list SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
$3->push_back($2.string);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);
|
||||
|
|
@ -719,7 +717,7 @@ block_structure
|
|||
: type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
|
||||
--parseContext.structNestingLevel;
|
||||
parseContext.blockName = $2.string;
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.currentBlockQualifier = $1.qualifier;
|
||||
$$.loc = $1.loc;
|
||||
|
|
@ -943,7 +941,7 @@ fully_specified_type
|
|||
: type_specifier {
|
||||
$$ = $1;
|
||||
|
||||
parseContext.globalQualifierCheck($1.loc, $1.qualifier, $$);
|
||||
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $$);
|
||||
if ($1.arraySizes) {
|
||||
parseContext.profileRequires($1.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||
parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type");
|
||||
|
|
@ -952,8 +950,8 @@ fully_specified_type
|
|||
parseContext.precisionQualifierCheck($$.loc, $$);
|
||||
}
|
||||
| type_qualifier type_specifier {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierCheck($1.loc, $1.qualifier, $2);
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2);
|
||||
|
||||
if ($2.arraySizes) {
|
||||
parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||
|
|
@ -1965,6 +1963,7 @@ struct_declaration
|
|||
}
|
||||
}
|
||||
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
||||
parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
|
||||
if ($2.arraySizes) {
|
||||
parseContext.profileRequires($2.loc, ENoProfile, 120, GL_3DL_array_objects, "arrayed type");
|
||||
parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue