Parser: Precise: Recognize 'precise', tag types, and do related semantic checking.

This partly overlaps pull request #222, we have divided the work on this one.
This commit is contained in:
John Kessenich 2016-05-04 12:36:14 -06:00
parent 758bb5520d
commit 17f0786418
15 changed files with 797 additions and 742 deletions

View file

@ -2703,8 +2703,10 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
(profile == EEsProfile && version < 310))
&& ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) {
// non-function parameters
if (src.noContraction && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
error(loc, "precise qualifier must appear first", "", "");
if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
error(loc, "invariant qualifier must appear first", "", "");
error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", "");
else if (src.isInterpolation() && (dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone))
error(loc, "interpolation qualifiers must appear before storage and precision qualifiers", "", "");
else if (src.isAuxiliary() && (dst.storage != EvqTemporary || dst.precision != EpqNone))
@ -2713,6 +2715,8 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
error(loc, "precision qualifier must appear as last qualifier", "", "");
// function parameters
if (src.noContraction && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut))
error(loc, "precise qualifier must appear first", "", "");
if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut))
error(loc, "in/out must appear before const", "", "");
}
@ -2743,6 +2747,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
bool repeated = false;
#define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
MERGE_SINGLETON(invariant);
MERGE_SINGLETON(noContraction);
MERGE_SINGLETON(centroid);
MERGE_SINGLETON(smooth);
MERGE_SINGLETON(flat);
@ -3448,6 +3453,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
oldType.getQualifier().centroid = newType.getQualifier().centroid;
oldType.getQualifier().sample = newType.getQualifier().sample;
oldType.getQualifier().invariant = newType.getQualifier().invariant;
oldType.getQualifier().noContraction = newType.getQualifier().noContraction;
oldType.getQualifier().smooth = newType.getQualifier().smooth;
oldType.getQualifier().flat = newType.getQualifier().flat;
oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
@ -3534,7 +3540,9 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
if (qualifier.hasLayout())
error(loc, "cannot use layout qualifiers on a function parameter", "", "");
if (qualifier.invariant)
error(loc, "cannot use invariant qualifier on a function parameter", "", "");
error(loc, "cannot use invariant qualifier on a function parameter", "", "");
if (qualifier.noContraction && qualifier.storage != EvqOut && qualifier.storage != EvqInOut)
warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
paramCheckFix(loc, qualifier.storage, type);
}
@ -5560,7 +5568,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
}
}
// Do all block-declaration checking regarding its qualifers.
// Do all block-declaration checking regarding its qualifiers.
void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier, bool instanceName)
{
// The 4.5 specification says:
@ -5760,6 +5768,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua
error(loc, "cannot change qualification after use", "invariant", "");
symbol->getWritableType().getQualifier().invariant = true;
invariantCheck(loc, symbol->getType().getQualifier());
} else if (qualifier.noContraction) {
if (intermediate.inIoAccessed(identifier))
error(loc, "cannot change qualification after use", "precise", "");
symbol->getWritableType().getQualifier().noContraction = true;
} else if (qualifier.specConstant) {
symbol->getWritableType().getQualifier().makeSpecConstant();
if (qualifier.hasSpecConstantId())
@ -5774,6 +5786,7 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua
addQualifierToExisting(loc, qualifier, *identifiers[i]);
}
// Make sure 'invariant' isn't being applied to a non-allowed object.
void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{
if (! qualifier.invariant)