Track what ins/outs/uniforms are used, so that errors like "declare after use" or "can't use both XXX and YYY" can be issued. So far, used this for invariant, gl_FragColor et. al., and gl_FragCoord use before redeclaration.
Also made all tests in testlist include linker tests. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24156 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
23bcc02a20
commit
5134b9cf57
114 changed files with 835 additions and 24 deletions
|
|
@ -54,7 +54,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
|
|||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
|
||||
tokensBeforeEOF(false), currentScanner(0),
|
||||
numErrors(0), parsingBuiltins(pb), afterEOF(false),
|
||||
anyIndexLimits(false), fragCoordUsedBeforeRedeclaration(false)
|
||||
anyIndexLimits(false)
|
||||
{
|
||||
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
|
||||
linkage = new TIntermAggregate;
|
||||
|
|
@ -387,6 +387,7 @@ void C_DECL TParseContext::warn(TSourceLoc loc, const char *szReason, const char
|
|||
TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TString* string)
|
||||
{
|
||||
TIntermTyped* node = 0;
|
||||
bool noteAccess = false;
|
||||
|
||||
// Error check for function requiring specific extensions present.
|
||||
if (symbol && symbol->getNumExtensions())
|
||||
|
|
@ -403,6 +404,10 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
|
|||
|
||||
node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
|
||||
node->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
|
||||
if (variable->getType().getQualifier().isIo())
|
||||
noteAccess = true;
|
||||
|
||||
// TODO: does this create any accidental type sharing with the built-in level?
|
||||
} else {
|
||||
// The symbol table search was done in the lexical phase, but
|
||||
// if this is a new symbol, it wouldn't have found it.
|
||||
|
|
@ -419,18 +424,19 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
|
|||
TType* type;
|
||||
if (variable->isReadOnly()) {
|
||||
type = new TType;
|
||||
// break type sharing with built-ins
|
||||
// break type sharing with built-ins; only costs if there are arrays or structures
|
||||
type->deepCopy(variable->getType());
|
||||
|
||||
// track use of unredeclared gl_FragCoord
|
||||
if (variable->getName() == "gl_FragCoord")
|
||||
fragCoordUsedBeforeRedeclaration = true;
|
||||
} else
|
||||
type = &variable->getWritableType();
|
||||
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), *type, loc);
|
||||
if (type->getQualifier().isIo())
|
||||
noteAccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (noteAccess)
|
||||
intermediate.addIoAccessed(*string);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
@ -2069,10 +2075,8 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
|
|||
symbolQualifier.storage != qualifier.storage)
|
||||
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
|
||||
} else if (identifier == "gl_FragCoord") {
|
||||
if (fragCoordUsedBeforeRedeclaration)
|
||||
if (intermediate.inIoAccessed("gl_FragCoord"))
|
||||
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
|
||||
// Note: this did not catch the case of 1) declare, 2) use, 3) declare again, because the "use" was of a redeclaration, and so didn't set fragCoordUsedBeforeRedeclaration.
|
||||
// (and that's what the rules are too, as long as #3 matches #1)
|
||||
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
||||
qualifier.isMemory() || qualifier.isAuxiliary())
|
||||
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
||||
|
|
@ -3425,6 +3429,8 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
|||
symbol = symbolTable.copyUp(symbol);
|
||||
|
||||
if (qualifier.invariant) {
|
||||
if (intermediate.inIoAccessed(identifier))
|
||||
error(loc, "cannot change qualification after use", "invariant", "");
|
||||
symbol->getWritableType().getQualifier().invariant = true;
|
||||
invariantCheck(loc, symbol->getType(), identifier);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue