Change ParseHelper.cpp indenting from tabs to spaces

TRAC #11868 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@197 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 86a7a138
...@@ -23,90 +23,90 @@ ...@@ -23,90 +23,90 @@
// //
bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line) bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
{ {
fields.num = (int) compString.size(); fields.num = (int) compString.size();
if (fields.num > 4) { if (fields.num > 4) {
error(line, "illegal vector field selection", compString.c_str(), ""); error(line, "illegal vector field selection", compString.c_str(), "");
return false; return false;
} }
enum { enum {
exyzw, exyzw,
ergba, ergba,
estpq, estpq,
} fieldSet[4]; } fieldSet[4];
for (int i = 0; i < fields.num; ++i) { for (int i = 0; i < fields.num; ++i) {
switch (compString[i]) { switch (compString[i]) {
case 'x': case 'x':
fields.offsets[i] = 0; fields.offsets[i] = 0;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'r': case 'r':
fields.offsets[i] = 0; fields.offsets[i] = 0;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 's': case 's':
fields.offsets[i] = 0; fields.offsets[i] = 0;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'y': case 'y':
fields.offsets[i] = 1; fields.offsets[i] = 1;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'g': case 'g':
fields.offsets[i] = 1; fields.offsets[i] = 1;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 't': case 't':
fields.offsets[i] = 1; fields.offsets[i] = 1;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'z': case 'z':
fields.offsets[i] = 2; fields.offsets[i] = 2;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'b': case 'b':
fields.offsets[i] = 2; fields.offsets[i] = 2;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 'p': case 'p':
fields.offsets[i] = 2; fields.offsets[i] = 2;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
case 'w': case 'w':
fields.offsets[i] = 3; fields.offsets[i] = 3;
fieldSet[i] = exyzw; fieldSet[i] = exyzw;
break; break;
case 'a': case 'a':
fields.offsets[i] = 3; fields.offsets[i] = 3;
fieldSet[i] = ergba; fieldSet[i] = ergba;
break; break;
case 'q': case 'q':
fields.offsets[i] = 3; fields.offsets[i] = 3;
fieldSet[i] = estpq; fieldSet[i] = estpq;
break; break;
default: default:
error(line, "illegal vector field selection", compString.c_str(), ""); error(line, "illegal vector field selection", compString.c_str(), "");
return false; return false;
} }
} }
for (int i = 0; i < fields.num; ++i) { for (int i = 0; i < fields.num; ++i) {
if (fields.offsets[i] >= vecSize) { if (fields.offsets[i] >= vecSize) {
error(line, "vector field selection out of range", compString.c_str(), ""); error(line, "vector field selection out of range", compString.c_str(), "");
return false; return false;
} }
if (i > 0) { if (i > 0) {
if (fieldSet[i] != fieldSet[i-1]) { if (fieldSet[i] != fieldSet[i-1]) {
error(line, "illegal - vector component fields not from the same set", compString.c_str(), ""); error(line, "illegal - vector component fields not from the same set", compString.c_str(), "");
return false; return false;
} }
} }
} }
return true; return true;
} }
...@@ -116,46 +116,46 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV ...@@ -116,46 +116,46 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
// //
bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line) bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
{ {
fields.wholeRow = false; fields.wholeRow = false;
fields.wholeCol = false; fields.wholeCol = false;
fields.row = -1; fields.row = -1;
fields.col = -1; fields.col = -1;
if (compString.size() != 2) { if (compString.size() != 2) {
error(line, "illegal length of matrix field selection", compString.c_str(), ""); error(line, "illegal length of matrix field selection", compString.c_str(), "");
return false; return false;
} }
if (compString[0] == '_') { if (compString[0] == '_') {
if (compString[1] < '0' || compString[1] > '3') { if (compString[1] < '0' || compString[1] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str(), "");
return false; return false;
} }
fields.wholeCol = true; fields.wholeCol = true;
fields.col = compString[1] - '0'; fields.col = compString[1] - '0';
} else if (compString[1] == '_') { } else if (compString[1] == '_') {
if (compString[0] < '0' || compString[0] > '3') { if (compString[0] < '0' || compString[0] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str(), "");
return false; return false;
} }
fields.wholeRow = true; fields.wholeRow = true;
fields.row = compString[0] - '0'; fields.row = compString[0] - '0';
} else { } else {
if (compString[0] < '0' || compString[0] > '3' || if (compString[0] < '0' || compString[0] > '3' ||
compString[1] < '0' || compString[1] > '3') { compString[1] < '0' || compString[1] > '3') {
error(line, "illegal matrix field selection", compString.c_str(), ""); error(line, "illegal matrix field selection", compString.c_str(), "");
return false; return false;
} }
fields.row = compString[0] - '0'; fields.row = compString[0] - '0';
fields.col = compString[1] - '0'; fields.col = compString[1] - '0';
} }
if (fields.row >= matSize || fields.col >= matSize) { if (fields.row >= matSize || fields.col >= matSize) {
error(line, "matrix field selection out of range", compString.c_str(), ""); error(line, "matrix field selection out of range", compString.c_str(), "");
return false; return false;
} }
return true; return true;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
...@@ -169,30 +169,30 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM ...@@ -169,30 +169,30 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM
// //
void TParseContext::recover() void TParseContext::recover()
{ {
recoveredFromError = true; recoveredFromError = true;
} }
// //
// Used by flex/bison to output all syntax and parsing errors. // Used by flex/bison to output all syntax and parsing errors.
// //
void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken, void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken,
const char *szExtraInfoFormat, ...) const char *szExtraInfoFormat, ...)
{ {
char szExtraInfo[400]; char szExtraInfo[400];
va_list marker; va_list marker;
va_start(marker, szExtraInfoFormat); va_start(marker, szExtraInfoFormat);
_vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker); _vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
/* VC++ format: file(linenum) : error #: 'token' : extrainfo */ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
infoSink.info.prefix(EPrefixError); infoSink.info.prefix(EPrefixError);
infoSink.info.location(nLine); infoSink.info.location(nLine);
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
va_end(marker); va_end(marker);
++numErrors; ++numErrors;
} }
// //
...@@ -200,8 +200,8 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c ...@@ -200,8 +200,8 @@ void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const c
// //
void TParseContext::assignError(int line, const char* op, TString left, TString right) void TParseContext::assignError(int line, const char* op, TString left, TString right)
{ {
error(line, "", op, "cannot convert from '%s' to '%s'", error(line, "", op, "cannot convert from '%s' to '%s'",
right.c_str(), left.c_str()); right.c_str(), left.c_str());
} }
// //
...@@ -210,8 +210,8 @@ void TParseContext::assignError(int line, const char* op, TString left, TString ...@@ -210,8 +210,8 @@ void TParseContext::assignError(int line, const char* op, TString left, TString
void TParseContext::unaryOpError(int line, const char* op, TString operand) void TParseContext::unaryOpError(int line, const char* op, TString operand)
{ {
error(line, " wrong operand type", op, error(line, " wrong operand type", op,
"no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)", "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
op, operand.c_str()); op, operand.c_str());
} }
// //
...@@ -219,10 +219,10 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand) ...@@ -219,10 +219,10 @@ void TParseContext::unaryOpError(int line, const char* op, TString operand)
// //
void TParseContext::binaryOpError(int line, const char* op, TString left, TString right) void TParseContext::binaryOpError(int line, const char* op, TString left, TString right)
{ {
error(line, " wrong operand types ", op, error(line, " wrong operand types ", op,
"no operation '%s' exists that takes a left-hand operand of type '%s' and " "no operation '%s' exists that takes a left-hand operand of type '%s' and "
"a right operand of type '%s' (or there is no acceptable conversion)", "a right operand of type '%s' (or there is no acceptable conversion)",
op, left.c_str(), right.c_str()); op, left.c_str(), right.c_str());
} }
// //
...@@ -233,102 +233,102 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin ...@@ -233,102 +233,102 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin
// //
bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node) bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* node)
{ {
TIntermSymbol* symNode = node->getAsSymbolNode(); TIntermSymbol* symNode = node->getAsSymbolNode();
TIntermBinary* binaryNode = node->getAsBinaryNode(); TIntermBinary* binaryNode = node->getAsBinaryNode();
if (binaryNode) { if (binaryNode) {
bool errorReturn; bool errorReturn;
switch(binaryNode->getOp()) { switch(binaryNode->getOp()) {
case EOpIndexDirect: case EOpIndexDirect:
case EOpIndexIndirect: case EOpIndexIndirect:
case EOpIndexDirectStruct: case EOpIndexDirectStruct:
return lValueErrorCheck(line, op, binaryNode->getLeft()); return lValueErrorCheck(line, op, binaryNode->getLeft());
case EOpVectorSwizzle: case EOpVectorSwizzle:
errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
if (!errorReturn) { if (!errorReturn) {
int offset[4] = {0,0,0,0}; int offset[4] = {0,0,0,0};
TIntermTyped* rightNode = binaryNode->getRight(); TIntermTyped* rightNode = binaryNode->getRight();
TIntermAggregate *aggrNode = rightNode->getAsAggregate(); TIntermAggregate *aggrNode = rightNode->getAsAggregate();
for (TIntermSequence::iterator p = aggrNode->getSequence().begin(); for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
p != aggrNode->getSequence().end(); p++) { p != aggrNode->getSequence().end(); p++) {
int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
offset[value]++; offset[value]++;
if (offset[value] > 1) { if (offset[value] > 1) {
error(line, " l-value of swizzle cannot have duplicate components", op, "", ""); error(line, " l-value of swizzle cannot have duplicate components", op, "", "");
return true; return true;
} }
} }
} }
return errorReturn; return errorReturn;
default: default:
break; break;
} }
error(line, " l-value required", op, "", ""); error(line, " l-value required", op, "", "");
return true; return true;
} }
const char* symbol = 0; const char* symbol = 0;
if (symNode != 0) if (symNode != 0)
symbol = symNode->getSymbol().c_str(); symbol = symNode->getSymbol().c_str();
const char* message = 0; const char* message = 0;
switch (node->getQualifier()) { switch (node->getQualifier()) {
case EvqConst: message = "can't modify a const"; break; case EvqConst: message = "can't modify a const"; break;
case EvqConstReadOnly: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break; case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; break; case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break; case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInput: message = "can't modify an input"; break; case EvqInput: message = "can't modify an input"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break; case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break; case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
case EvqPointCoord: message = "can't modify gl_PointCoord"; break; case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
default: default:
// //
// Type that can't be written to? // Type that can't be written to?
// //
switch (node->getBasicType()) { switch (node->getBasicType()) {
case EbtSampler2D: case EbtSampler2D:
case EbtSamplerCube: case EbtSamplerCube:
message = "can't modify a sampler"; message = "can't modify a sampler";
break; break;
case EbtVoid: case EbtVoid:
message = "can't modify void"; message = "can't modify void";
break; break;
default: default:
break; break;
} }
} }
if (message == 0 && binaryNode == 0 && symNode == 0) { if (message == 0 && binaryNode == 0 && symNode == 0) {
error(line, " l-value required", op, "", ""); error(line, " l-value required", op, "", "");
return true; return true;
} }
// //
// Everything else is okay, no error. // Everything else is okay, no error.
// //
if (message == 0) if (message == 0)
return false; return false;
// //
// If we get here, we have an error and a message. // If we get here, we have an error and a message.
// //
if (symNode) if (symNode)
error(line, " l-value required", op, "\"%s\" (%s)", symbol, message); error(line, " l-value required", op, "\"%s\" (%s)", symbol, message);
else else
error(line, " l-value required", op, "(%s)", message); error(line, " l-value required", op, "(%s)", message);
return true; return true;
} }
// //
...@@ -339,12 +339,12 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -339,12 +339,12 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
// //
bool TParseContext::constErrorCheck(TIntermTyped* node) bool TParseContext::constErrorCheck(TIntermTyped* node)
{ {
if (node->getQualifier() == EvqConst) if (node->getQualifier() == EvqConst)
return false; return false;
error(node->getLine(), "constant expression required", "", ""); error(node->getLine(), "constant expression required", "", "");
return true; return true;
} }
// //
...@@ -355,12 +355,12 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) ...@@ -355,12 +355,12 @@ bool TParseContext::constErrorCheck(TIntermTyped* node)
// //
bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
{ {
if (node->getBasicType() == EbtInt && node->getNominalSize() == 1) if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
return false; return false;
error(node->getLine(), "integer expression required", token, ""); error(node->getLine(), "integer expression required", token, "");
return true; return true;
} }
// //
...@@ -371,12 +371,12 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) ...@@ -371,12 +371,12 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
// //
bool TParseContext::globalErrorCheck(int line, bool global, const char* token) bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
{ {
if (global) if (global)
return false; return false;
error(line, "only allowed at global scope", token, ""); error(line, "only allowed at global scope", token, "");
return true; return true;
} }
// //
...@@ -388,20 +388,20 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token) ...@@ -388,20 +388,20 @@ bool TParseContext::globalErrorCheck(int line, bool global, const char* token)
// //
bool TParseContext::reservedErrorCheck(int line, const TString& identifier) bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
{ {
if (!symbolTable.atBuiltInLevel()) { if (!symbolTable.atBuiltInLevel()) {
if (identifier.substr(0, 3) == TString("gl_")) { if (identifier.substr(0, 3) == TString("gl_")) {
error(line, "reserved built-in name", "gl_", ""); error(line, "reserved built-in name", "gl_", "");
return true; return true;
} }
if (identifier.find("__") != TString::npos) { if (identifier.find("__") != TString::npos) {
//error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", ""); //error(line, "Two consecutive underscores are reserved for future use.", identifier.c_str(), "", "");
//return true; //return true;
infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line); infoSink.info.message(EPrefixWarning, "Two consecutive underscores are reserved for future use.", line);
return false; return false;
} }
} }
return false; return false;
} }
// //
...@@ -413,95 +413,95 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) ...@@ -413,95 +413,95 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
// //
bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type) bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
{ {
*type = function.getReturnType(); *type = function.getReturnType();
bool constructingMatrix = false; bool constructingMatrix = false;
switch(op) { switch(op) {
case EOpConstructMat2: case EOpConstructMat2:
case EOpConstructMat3: case EOpConstructMat3:
case EOpConstructMat4: case EOpConstructMat4:
constructingMatrix = true; constructingMatrix = true;
break; break;
default: default:
break; break;
} }
// //
// Note: It's okay to have too many components available, but not okay to have unused // Note: It's okay to have too many components available, but not okay to have unused
// arguments. 'full' will go to true when enough args have been seen. If we loop // arguments. 'full' will go to true when enough args have been seen. If we loop
// again, there is an extra argument, so 'overfull' will become true. // again, there is an extra argument, so 'overfull' will become true.
// //
int size = 0; int size = 0;
bool constType = true; bool constType = true;
bool full = false; bool full = false;
bool overFull = false; bool overFull = false;
bool matrixInMatrix = false; bool matrixInMatrix = false;
bool arrayArg = false; bool arrayArg = false;
for (int i = 0; i < function.getParamCount(); ++i) { for (int i = 0; i < function.getParamCount(); ++i) {
size += function[i].type->getObjectSize(); size += function[i].type->getObjectSize();
if (constructingMatrix && function[i].type->isMatrix()) if (constructingMatrix && function[i].type->isMatrix())
matrixInMatrix = true; matrixInMatrix = true;
if (full) if (full)
overFull = true; overFull = true;
if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize()) if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
full = true; full = true;
if (function[i].type->getQualifier() != EvqConst) if (function[i].type->getQualifier() != EvqConst)
constType = false; constType = false;
if (function[i].type->isArray()) if (function[i].type->isArray())
arrayArg = true; arrayArg = true;
} }
if (constType) if (constType)
type->changeQualifier(EvqConst); type->changeQualifier(EvqConst);
if (type->isArray() && type->getArraySize() != function.getParamCount()) { if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", ""); error(line, "array constructor needs one argument per array element", "constructor", "");
return true; return true;
} }
if (arrayArg && op != EOpConstructStruct) { if (arrayArg && op != EOpConstructStruct) {
error(line, "constructing from a non-dereferenced array", "constructor", ""); error(line, "constructing from a non-dereferenced array", "constructor", "");
return true; return true;
} }
if (matrixInMatrix && !type->isArray()) { if (matrixInMatrix && !type->isArray()) {
error(line, "constructing matrix from matrix", "constructor", "(reserved)"); error(line, "constructing matrix from matrix", "constructor", "(reserved)");
return true; return true;
} }
if (overFull) { if (overFull) {
error(line, "too many arguments", "constructor", ""); error(line, "too many arguments", "constructor", "");
return true; return true;
} }
if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->size() != function.getParamCount()) { if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->size() != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
return true; return true;
} }
if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
(op == EOpConstructStruct && size < type->getObjectSize())) { (op == EOpConstructStruct && size < type->getObjectSize())) {
error(line, "not enough data provided for construction", "constructor", ""); error(line, "not enough data provided for construction", "constructor", "");
return true; return true;
} }
TIntermTyped* typed = node->getAsTyped(); TIntermTyped* typed = node->getAsTyped();
if (typed == 0) { if (typed == 0) {
error(line, "constructor argument does not have a type", "constructor", ""); error(line, "constructor argument does not have a type", "constructor", "");
return true; return true;
} }
if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) { if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
error(line, "cannot convert a sampler", "constructor", ""); error(line, "cannot convert a sampler", "constructor", "");
return true; return true;
} }
if (typed->getBasicType() == EbtVoid) { if (typed->getBasicType() == EbtVoid) {
error(line, "cannot convert a void", "constructor", ""); error(line, "cannot convert a void", "constructor", "");
return true; return true;
} }
return false; return false;
} }
// This function checks to see if a void variable has been declared and raise an error message for such a case // This function checks to see if a void variable has been declared and raise an error message for such a case
...@@ -510,12 +510,12 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction ...@@ -510,12 +510,12 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
// //
bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType) bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
{ {
if (pubType.type == EbtVoid) { if (pubType.type == EbtVoid) {
error(line, "illegal use of type 'void'", identifier.c_str(), ""); error(line, "illegal use of type 'void'", identifier.c_str(), "");
return true; return true;
} }
return false; return false;
} }
// This function checks to see if the node (for the expression) contains a scalar boolean expression or not // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
...@@ -524,12 +524,12 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP ...@@ -524,12 +524,12 @@ bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TP
// //
bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
{ {
if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
error(line, "boolean expression expected", "", ""); error(line, "boolean expression expected", "", "");
return true; return true;
} }
return false; return false;
} }
// This function checks to see if the node (for the expression) contains a scalar boolean expression or not // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
...@@ -538,73 +538,73 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type) ...@@ -538,73 +538,73 @@ 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.matrix || (pType.size > 1)) { if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
error(line, "boolean expression expected", "", ""); error(line, "boolean expression expected", "", "");
return true; return true;
} }
return false; return false;
} }
bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason) bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
{ {
if (pType.type == EbtStruct) { if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) { if (containsSampler(*pType.userDef)) {
error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)"); error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
return true; return true;
} }
return false; return false;
} else if (IsSampler(pType.type)) { } else if (IsSampler(pType.type)) {
error(line, reason, TType::getBasicString(pType.type), ""); error(line, reason, TType::getBasicString(pType.type), "");
return true; return true;
} }
return false; return false;
} }
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType) bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{ {
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
pType.type == EbtStruct) { pType.type == EbtStruct) {
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), ""); error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), "");
return true; return true;
} }
if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform")) if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
return true; return true;
return false; return false;
} }
bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type) bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
{ {
if ((qualifier == EvqOut || qualifier == EvqInOut) && if ((qualifier == EvqOut || qualifier == EvqInOut) &&
type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
error(line, "samplers cannot be output parameters", type.getBasicString(), ""); error(line, "samplers cannot be output parameters", type.getBasicString(), "");
return true; return true;
} }
return false; return false;
} }
bool TParseContext::containsSampler(TType& type) bool TParseContext::containsSampler(TType& type)
{ {
if (IsSampler(type.getBasicType())) if (IsSampler(type.getBasicType()))
return true; return true;
if (type.getBasicType() == EbtStruct) { if (type.getBasicType() == EbtStruct) {
TTypeList& structure = *type.getStruct(); TTypeList& structure = *type.getStruct();
for (unsigned int i = 0; i < structure.size(); ++i) { for (unsigned int i = 0; i < structure.size(); ++i) {
if (containsSampler(*structure[i].type)) if (containsSampler(*structure[i].type))
return true; return true;
} }
} }
return false; return false;
} }
// //
...@@ -614,21 +614,21 @@ bool TParseContext::containsSampler(TType& type) ...@@ -614,21 +614,21 @@ bool TParseContext::containsSampler(TType& type)
// //
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
{ {
TIntermConstantUnion* constant = expr->getAsConstantUnion(); TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || constant->getBasicType() != EbtInt) { if (constant == 0 || constant->getBasicType() != EbtInt) {
error(line, "array size must be a constant integer expression", "", ""); error(line, "array size must be a constant integer expression", "", "");
return true; return true;
} }
size = constant->getUnionArrayPointer()->getIConst(); size = constant->getUnionArrayPointer()->getIConst();
if (size <= 0) { if (size <= 0) {
error(line, "array size must be a positive integer", "", ""); error(line, "array size must be a positive integer", "", "");
size = 1; size = 1;
return true; return true;
} }
return false; return false;
} }
// //
...@@ -638,15 +638,15 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size) ...@@ -638,15 +638,15 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
// //
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
{ {
if (type.qualifier == EvqAttribute) { if (type.qualifier == EvqAttribute) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), ""); error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
return true; return true;
} }
if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects")) if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects"))
return true; return true;
return false; return false;
} }
// //
...@@ -656,15 +656,15 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type) ...@@ -656,15 +656,15 @@ bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
// //
bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
{ {
// //
// Can the type be an array? // Can the type be an array?
// //
if (type.array) { if (type.array) {
error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str(), ""); error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str(), "");
return true; return true;
} }
return false; return false;
} }
// //
...@@ -677,114 +677,114 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type) ...@@ -677,114 +677,114 @@ bool TParseContext::arrayTypeErrorCheck(int line, TPublicType type)
// //
bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable) bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
{ {
// //
// Don't check for reserved word use until after we know it's not in the symbol table, // Don't check for reserved word use until after we know it's not in the symbol table,
// because reserved arrays can be redeclared. // because reserved arrays can be redeclared.
// //
bool builtIn = false; bool builtIn = false;
bool sameScope = false; bool sameScope = false;
TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope); TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
if (symbol == 0 || !sameScope) { if (symbol == 0 || !sameScope) {
if (reservedErrorCheck(line, identifier)) if (reservedErrorCheck(line, identifier))
return true; return true;
variable = new TVariable(&identifier, TType(type)); variable = new TVariable(&identifier, TType(type));
if (type.arraySize) if (type.arraySize)
variable->getType().setArraySize(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(), "");
return true; return true;
} }
} else { } else {
if (! symbol->isVariable()) { if (! symbol->isVariable()) {
error(line, "variable expected", identifier.c_str(), ""); error(line, "variable expected", identifier.c_str(), "");
return true; return true;
} }
variable = static_cast<TVariable*>(symbol); variable = static_cast<TVariable*>(symbol);
if (! variable->getType().isArray()) { if (! variable->getType().isArray()) {
error(line, "redeclaring non-array as array", identifier.c_str(), ""); error(line, "redeclaring non-array as array", identifier.c_str(), "");
return true; return true;
} }
if (variable->getType().getArraySize() > 0) { if (variable->getType().getArraySize() > 0) {
error(line, "redeclaration of array with size", identifier.c_str(), ""); error(line, "redeclaration of array with size", identifier.c_str(), "");
return true; return true;
} }
if (! variable->getType().sameElementType(TType(type))) { if (! variable->getType().sameElementType(TType(type))) {
error(line, "redeclaration of array with a different type", identifier.c_str(), ""); error(line, "redeclaration of array with a different type", identifier.c_str(), "");
return true; return true;
} }
TType* t = variable->getArrayInformationType(); TType* t = variable->getArrayInformationType();
while (t != 0) { while (t != 0) {
if (t->getMaxArraySize() > type.arraySize) { if (t->getMaxArraySize() > type.arraySize) {
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->setArraySize(type.arraySize);
t = t->getArrayInformationType(); t = t->getArrayInformationType();
} }
if (type.arraySize) if (type.arraySize)
variable->getType().setArraySize(type.arraySize); variable->getType().setArraySize(type.arraySize);
} }
if (voidErrorCheck(line, identifier, type)) if (voidErrorCheck(line, identifier, type))
return true; return true;
return false; return false;
} }
bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line) bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
{ {
bool builtIn = false; bool builtIn = false;
TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn); TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
if (symbol == 0) { if (symbol == 0) {
error(line, " undeclared identifier", node->getSymbol().c_str(), ""); error(line, " undeclared identifier", node->getSymbol().c_str(), "");
return true; return true;
} }
TVariable* variable = static_cast<TVariable*>(symbol); TVariable* variable = static_cast<TVariable*>(symbol);
type->setArrayInformationType(variable->getArrayInformationType()); type->setArrayInformationType(variable->getArrayInformationType());
variable->updateArrayInformationType(type); variable->updateArrayInformationType(type);
// special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers
// its an error // its an error
if (node->getSymbol() == "gl_FragData") { if (node->getSymbol() == "gl_FragData") {
TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn); TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn);
if (fragData == 0) { if (fragData == 0) {
infoSink.info.message(EPrefixInternalError, "gl_MaxDrawBuffers not defined", line); infoSink.info.message(EPrefixInternalError, "gl_MaxDrawBuffers not defined", line);
return true; return true;
} }
int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst();
if (fragDataValue <= size) { if (fragDataValue <= size) {
error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers", ""); error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers", "");
return true; return true;
} }
} }
// we dont want to update the maxArraySize when this flag is not set, we just want to include this // we dont want to update the maxArraySize when this flag is not set, we just want to include this
// node type in the chain of node types so that its updated when a higher maxArraySize comes in. // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
if (!updateFlag) if (!updateFlag)
return false; return false;
size++; size++;
variable->getType().setMaxArraySize(size); variable->getType().setMaxArraySize(size);
type->setMaxArraySize(size); type->setMaxArraySize(size);
TType* tt = type; TType* tt = type;
while(tt->getArrayInformationType() != 0) { while(tt->getArrayInformationType() != 0) {
tt = tt->getArrayInformationType(); tt = tt->getArrayInformationType();
tt->setMaxArraySize(size); tt->setMaxArraySize(size);
} }
return false; return false;
} }
// //
...@@ -794,16 +794,16 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, ...@@ -794,16 +794,16 @@ bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size,
// //
bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type) bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type)
{ {
// //
// Make the qualifier make sense. // Make the qualifier make sense.
// //
if (type.qualifier == EvqConst) { if (type.qualifier == EvqConst) {
type.qualifier = EvqTemporary; type.qualifier = EvqTemporary;
error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), ""); error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
return true; return true;
} }
return false; return false;
} }
// //
...@@ -814,54 +814,54 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli ...@@ -814,54 +814,54 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli
// //
bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type) bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type)
{ {
if (reservedErrorCheck(line, identifier)) if (reservedErrorCheck(line, identifier))
recover(); recover();
TVariable* variable = new TVariable(&identifier, TType(type)); TVariable* variable = new TVariable(&identifier, TType(type));
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
error(line, "redefinition", variable->getName().c_str(), ""); error(line, "redefinition", variable->getName().c_str(), "");
delete variable; delete variable;
return true; return true;
} }
if (voidErrorCheck(line, identifier, type)) if (voidErrorCheck(line, identifier, type))
return true; return true;
return false; return false;
} }
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type) bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
{ {
if (qualifier != EvqConst && qualifier != EvqTemporary) { if (qualifier != EvqConst && qualifier != EvqTemporary) {
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), ""); error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), "");
return true; return true;
} }
if (qualifier == EvqConst && paramQualifier != EvqIn) { if (qualifier == EvqConst && paramQualifier != EvqIn) {
error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier)); error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
return true; return true;
} }
if (qualifier == EvqConst) if (qualifier == EvqConst)
type->changeQualifier(EvqConstReadOnly); type->changeQualifier(EvqConstReadOnly);
else else
type->changeQualifier(paramQualifier); type->changeQualifier(paramQualifier);
return false; return false;
} }
bool TParseContext::extensionErrorCheck(int line, const char* extension) bool TParseContext::extensionErrorCheck(int line, const char* extension)
{ {
if (extensionBehavior[extension] == EBhWarn) { if (extensionBehavior[extension] == EBhWarn) {
infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line); infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
return false; return false;
} }
if (extensionBehavior[extension] == EBhDisable) { if (extensionBehavior[extension] == EBhDisable) {
error(line, "extension", extension, "is disabled"); error(line, "extension", extension, "is disabled");
return true; return true;
} }
return false; return false;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
...@@ -877,21 +877,21 @@ bool TParseContext::extensionErrorCheck(int line, const char* extension) ...@@ -877,21 +877,21 @@ bool TParseContext::extensionErrorCheck(int line, const char* extension)
// //
const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn) const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
{ {
const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn); const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
if (symbol == 0) { if (symbol == 0) {
error(line, "no matching overloaded function found", call->getName().c_str(), ""); error(line, "no matching overloaded function found", call->getName().c_str(), "");
return 0; return 0;
} }
if (! symbol->isFunction()) { if (! symbol->isFunction()) {
error(line, "function name expected", call->getName().c_str(), ""); error(line, "function name expected", call->getName().c_str(), "");
return 0; return 0;
} }
const TFunction* function = static_cast<const TFunction*>(symbol); const TFunction* function = static_cast<const TFunction*>(symbol);
return function; return function;
} }
// //
...@@ -899,106 +899,106 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu ...@@ -899,106 +899,106 @@ const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *bu
// code to handle them here. // code to handle them here.
// //
bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
{ {
TType type = TType(pType); TType type = TType(pType);
if (variable == 0) { if (variable == 0) {
if (reservedErrorCheck(line, identifier)) if (reservedErrorCheck(line, identifier))
return true; return true;
if (voidErrorCheck(line, identifier, pType)) if (voidErrorCheck(line, identifier, pType))
return true; return true;
// //
// add variable to symbol table // add variable to symbol table
// //
variable = new TVariable(&identifier, type); variable = new TVariable(&identifier, type);
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
error(line, "redefinition", variable->getName().c_str(), ""); error(line, "redefinition", variable->getName().c_str(), "");
return true; return true;
// don't delete variable, it's used by error recovery, and the pool // don't delete variable, it's used by error recovery, and the pool
// pop will take care of the memory // pop will take care of the memory
} }
} }
// //
// identifier must be of type constant, a global, or a temporary // identifier must be of type constant, a global, or a temporary
// //
TQualifier qualifier = variable->getType().getQualifier(); TQualifier qualifier = variable->getType().getQualifier();
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), "");
return true; return true;
} }
// //
// test for and propagate constant // test for and propagate constant
// //
if (qualifier == EvqConst) { if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier()) { if (qualifier != initializer->getType().getQualifier()) {
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getType().changeQualifier(EvqTemporary); variable->getType().changeQualifier(EvqTemporary);
return true; return true;
} }
if (type != initializer->getType()) { if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ", error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), ""); variable->getType().getQualifierString(), "");
variable->getType().changeQualifier(EvqTemporary); variable->getType().changeQualifier(EvqTemporary);
return true; return true;
} }
if (initializer->getAsConstantUnion()) { if (initializer->getAsConstantUnion()) {
constUnion* unionArray = variable->getConstPointer(); constUnion* unionArray = variable->getConstPointer();
if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) { if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
*unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0]; *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
} else { } else {
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
} }
} else if (initializer->getAsSymbolNode()) { } else if (initializer->getAsSymbolNode()) {
const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol()); const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
const TVariable* tVar = static_cast<const TVariable*>(symbol); const TVariable* tVar = static_cast<const TVariable*>(symbol);
constUnion* constArray = tVar->getConstPointer(); constUnion* constArray = tVar->getConstPointer();
variable->shareConstPointer(constArray); variable->shareConstPointer(constArray);
} else { } else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getType().changeQualifier(EvqTemporary); variable->getType().changeQualifier(EvqTemporary);
return true; return true;
} }
} }
if (qualifier != EvqConst) { if (qualifier != EvqConst) {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line); intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
if (intermNode == 0) { if (intermNode == 0) {
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true; return true;
} }
} else } else
intermNode = 0; intermNode = 0;
return false; return false;
} }
bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
{ {
if (!aggrNode->isConstructor()) if (!aggrNode->isConstructor())
return false; return false;
bool allConstant = true; bool allConstant = true;
// check if all the child nodes are constants so that they can be inserted into // check if all the child nodes are constants so that they can be inserted into
// the parent node // the parent node
if (aggrNode) { if (aggrNode) {
TIntermSequence &childSequenceVector = aggrNode->getSequence() ; TIntermSequence &childSequenceVector = aggrNode->getSequence() ;
for (TIntermSequence::iterator p = childSequenceVector.begin(); for (TIntermSequence::iterator p = childSequenceVector.begin();
p != childSequenceVector.end(); p++) { p != childSequenceVector.end(); p++) {
if (!(*p)->getAsTyped()->getAsConstantUnion()) if (!(*p)->getAsTyped()->getAsConstantUnion())
return false; return false;
} }
} }
return allConstant; return allConstant;
} }
// This function is used to test for the correctness of the parameters passed to various constructor functions // This function is used to test for the correctness of the parameters passed to various constructor functions
...@@ -1008,103 +1008,103 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) ...@@ -1008,103 +1008,103 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
// //
TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line) TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
{ {
if (node == 0) if (node == 0)
return 0; return 0;
TIntermAggregate* aggrNode = node->getAsAggregate(); TIntermAggregate* aggrNode = node->getAsAggregate();
TTypeList::iterator memberTypes; TTypeList::iterator memberTypes;
if (op == EOpConstructStruct) if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin(); memberTypes = type->getStruct()->begin();
TType elementType = *type; TType elementType = *type;
if (type->isArray()) if (type->isArray())
elementType.clearArrayness(); elementType.clearArrayness();
bool singleArg; bool singleArg;
if (aggrNode) { if (aggrNode) {
if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1) if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
singleArg = true; singleArg = true;
else else
singleArg = false; singleArg = false;
} else } else
singleArg = true; singleArg = true;
TIntermTyped *newNode; TIntermTyped *newNode;
if (singleArg) { if (singleArg) {
// If structure constructor or array constructor is being called // If structure constructor or array constructor is being called
// for only one parameter inside the structure, we need to call constructStruct function once. // for only one parameter inside the structure, we need to call constructStruct function once.
if (type->isArray()) if (type->isArray())
newNode = constructStruct(node, &elementType, 1, node->getLine(), false); newNode = constructStruct(node, &elementType, 1, node->getLine(), false);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false); newNode = constructStruct(node, (*memberTypes).type, 1, node->getLine(), false);
else else
newNode = constructBuiltIn(type, op, node, node->getLine(), false); newNode = constructBuiltIn(type, op, node, node->getLine(), false);
if (newNode && newNode->getAsAggregate()) { if (newNode && newNode->getAsAggregate()) {
TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type); TIntermTyped* constConstructor = foldConstConstructor(newNode->getAsAggregate(), *type);
if (constConstructor) if (constConstructor)
return constConstructor; return constConstructor;
} }
return newNode; return newNode;
} }
// //
// Handle list of arguments. // Handle list of arguments.
// //
TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor
// if the structure constructor contains more than one parameter, then construct // if the structure constructor contains more than one parameter, then construct
// each parameter // each parameter
int paramCount = 0; // keeps a track of the constructor parameter number being checked int paramCount = 0; // keeps a track of the constructor parameter number being checked
// for each parameter to the constructor call, check to see if the right type is passed or convert them // for each parameter to the constructor call, check to see if the right type is passed or convert them
// to the right type if possible (and allowed). // to the right type if possible (and allowed).
// for structure constructors, just check if the right type is passed, no conversion is allowed. // for structure constructors, just check if the right type is passed, no conversion is allowed.
for (TIntermSequence::iterator p = sequenceVector.begin(); for (TIntermSequence::iterator p = sequenceVector.begin();
p != sequenceVector.end(); p++, paramCount++) { p != sequenceVector.end(); p++, paramCount++) {
if (type->isArray()) if (type->isArray())
newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true); newNode = constructStruct(*p, &elementType, paramCount+1, node->getLine(), true);
else if (op == EOpConstructStruct) else if (op == EOpConstructStruct)
newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true); newNode = constructStruct(*p, (memberTypes[paramCount]).type, paramCount+1, node->getLine(), true);
else else
newNode = constructBuiltIn(type, op, *p, node->getLine(), true); newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
if (newNode) { if (newNode) {
*p = newNode; *p = newNode;
} }
} }
TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line); TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type); TIntermTyped* constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
if (constConstructor) if (constConstructor)
return constConstructor; return constConstructor;
return constructor; return constructor;
} }
TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type) TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type)
{ {
bool canBeFolded = areAllChildConst(aggrNode); bool canBeFolded = areAllChildConst(aggrNode);
aggrNode->setType(type); aggrNode->setType(type);
if (canBeFolded) { if (canBeFolded) {
bool returnVal = false; bool returnVal = false;
constUnion* unionArray = new constUnion[type.getObjectSize()]; constUnion* unionArray = new constUnion[type.getObjectSize()];
if (aggrNode->getSequence().size() == 1) { if (aggrNode->getSequence().size() == 1) {
returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type, true); returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type, true);
} }
else { else {
returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type); returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type);
} }
if (returnVal) if (returnVal)
return 0; return 0;
return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine()); return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine());
} }
return 0; return 0;
} }
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
...@@ -1116,59 +1116,59 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co ...@@ -1116,59 +1116,59 @@ TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, co
// //
TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset) TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
{ {
TIntermTyped* newNode; TIntermTyped* newNode;
TOperator basicOp; TOperator basicOp;
// //
// First, convert types as needed. // First, convert types as needed.
// //
switch (op) { switch (op) {
case EOpConstructVec2: case EOpConstructVec2:
case EOpConstructVec3: case EOpConstructVec3:
case EOpConstructVec4: case EOpConstructVec4:
case EOpConstructMat2: case EOpConstructMat2:
case EOpConstructMat3: case EOpConstructMat3:
case EOpConstructMat4: case EOpConstructMat4:
case EOpConstructFloat: case EOpConstructFloat:
basicOp = EOpConstructFloat; basicOp = EOpConstructFloat;
break; break;
case EOpConstructIVec2: case EOpConstructIVec2:
case EOpConstructIVec3: case EOpConstructIVec3:
case EOpConstructIVec4: case EOpConstructIVec4:
case EOpConstructInt: case EOpConstructInt:
basicOp = EOpConstructInt; basicOp = EOpConstructInt;
break; break;
case EOpConstructBVec2: case EOpConstructBVec2:
case EOpConstructBVec3: case EOpConstructBVec3:
case EOpConstructBVec4: case EOpConstructBVec4:
case EOpConstructBool: case EOpConstructBool:
basicOp = EOpConstructBool; basicOp = EOpConstructBool;
break; break;
default: default:
error(line, "unsupported construction", "", ""); error(line, "unsupported construction", "", "");
recover(); recover();
return 0; return 0;
} }
newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable); newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable);
if (newNode == 0) { if (newNode == 0) {
error(line, "can't convert", "constructor", ""); error(line, "can't convert", "constructor", "");
return 0; return 0;
} }
// //
// Now, if there still isn't an operation to do the construction, and we need one, add one. // Now, if there still isn't an operation to do the construction, and we need one, add one.
// //
// Otherwise, skip out early. // Otherwise, skip out early.
if (subset || (newNode != node && newNode->getType() == *type)) if (subset || (newNode != node && newNode->getType() == *type))
return newNode; return newNode;
// setAggregateOperator will insert a new node for the constructor, as needed. // setAggregateOperator will insert a new node for the constructor, as needed.
return intermediate.setAggregateOperator(newNode, op, line); return intermediate.setAggregateOperator(newNode, op, line);
} }
// This function tests for the type of the parameters to the structures constructors. Raises // This function tests for the type of the parameters to the structures constructors. Raises
...@@ -1178,18 +1178,18 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T ...@@ -1178,18 +1178,18 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
// //
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset) TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
{ {
if (*type == node->getAsTyped()->getType()) { if (*type == node->getAsTyped()->getType()) {
if (subset) if (subset)
return node->getAsTyped(); return node->getAsTyped();
else else
return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line); return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
} else { } else {
error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
node->getAsTyped()->getType().getBasicString(), type->getBasicString()); node->getAsTyped()->getType().getBasicString(), type->getBasicString());
recover(); recover();
} }
return 0; return 0;
} }
// //
...@@ -1201,40 +1201,40 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int ...@@ -1201,40 +1201,40 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int
// //
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
constUnion *unionArray; constUnion *unionArray;
if (tempConstantNode) { if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer(); unionArray = tempConstantNode->getUnionArrayPointer();
if (!unionArray) { // this error message should never be raised if (!unionArray) { // this error message should never be raised
infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line); infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line);
recover(); recover();
return node; return node;
} }
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
error(line, "Cannot offset into the vector", "Error", ""); error(line, "Cannot offset into the vector", "Error", "");
recover(); recover();
return 0; return 0;
} }
constUnion* constArray = new constUnion[fields.num]; constUnion* constArray = new constUnion[fields.num];
for (int i = 0; i < fields.num; i++) { for (int i = 0; i < fields.num; i++) {
if (fields.offsets[i] >= node->getType().getObjectSize()) { if (fields.offsets[i] >= node->getType().getObjectSize()) {
error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]); error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]);
recover(); recover();
fields.offsets[i] = 0; fields.offsets[i] = 0;
} }
constArray[i] = unionArray[fields.offsets[i]]; constArray[i] = unionArray[fields.offsets[i]];
} }
typedNode = intermediate.addConstantUnion(constArray, node->getType(), line); typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
return typedNode; return typedNode;
} }
// //
...@@ -1245,27 +1245,27 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy ...@@ -1245,27 +1245,27 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
// //
TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
if (index >= node->getType().getNominalSize()) { if (index >= node->getType().getNominalSize()) {
error(line, "", "[", "matrix field selection out of range '%d'", index); error(line, "", "[", "matrix field selection out of range '%d'", index);
recover(); recover();
index = 0; index = 0;
} }
if (tempConstantNode) { if (tempConstantNode) {
constUnion* unionArray = tempConstantNode->getUnionArrayPointer(); constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
int size = tempConstantNode->getType().getNominalSize(); int size = tempConstantNode->getType().getNominalSize();
typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
} else { } else {
error(line, "Cannot offset into the matrix", "Error", ""); error(line, "Cannot offset into the matrix", "Error", "");
recover(); recover();
return 0; return 0;
} }
return typedNode; return typedNode;
} }
...@@ -1277,30 +1277,30 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T ...@@ -1277,30 +1277,30 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
// //
TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line)
{ {
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
TType arrayElementType = node->getType(); TType arrayElementType = node->getType();
arrayElementType.clearArrayness(); arrayElementType.clearArrayness();
if (index >= node->getType().getArraySize()) { if (index >= node->getType().getArraySize()) {
error(line, "", "[", "array field selection out of range '%d'", index); error(line, "", "[", "array field selection out of range '%d'", index);
recover(); recover();
index = 0; index = 0;
} }
int arrayElementSize = arrayElementType.getObjectSize(); int arrayElementSize = arrayElementType.getObjectSize();
if (tempConstantNode) { if (tempConstantNode) {
constUnion* unionArray = tempConstantNode->getUnionArrayPointer(); constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line);
} else { } else {
error(line, "Cannot offset into the array", "Error", ""); error(line, "Cannot offset into the array", "Error", "");
recover(); recover();
return 0; return 0;
} }
return typedNode; return typedNode;
} }
...@@ -1311,32 +1311,32 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS ...@@ -1311,32 +1311,32 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
// //
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line) TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{ {
TTypeList* fields = node->getType().getStruct(); TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode; TIntermTyped *typedNode;
int instanceSize = 0; int instanceSize = 0;
unsigned int index = 0; unsigned int index = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
for ( index = 0; index < fields->size(); ++index) { for ( index = 0; index < fields->size(); ++index) {
if ((*fields)[index].type->getFieldName() == identifier) { if ((*fields)[index].type->getFieldName() == identifier) {
break; break;
} else { } else {
instanceSize += (*fields)[index].type->getObjectSize(); instanceSize += (*fields)[index].type->getObjectSize();
} }
} }
if (tempConstantNode) { if (tempConstantNode) {
constUnion* constArray = tempConstantNode->getUnionArrayPointer(); constUnion* constArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
} else { } else {
error(line, "Cannot offset into the structure", "Error", ""); error(line, "Cannot offset into the structure", "Error", "");
recover(); recover();
return 0; return 0;
} }
return typedNode; return typedNode;
} }
// //
...@@ -1344,96 +1344,96 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n ...@@ -1344,96 +1344,96 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
// //
void TParseContext::initializeExtensionBehavior() void TParseContext::initializeExtensionBehavior()
{ {
// //
// example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of // example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of
// supported extension // supported extension
// //
extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire; extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire;
extensionBehavior["GL_3DL_array_objects"] = EBhDisable; extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
} }
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX; OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex() bool InitializeParseContextIndex()
{ {
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) { if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false; return false;
} }
// //
// Allocate a TLS index. // Allocate a TLS index.
// //
GlobalParseContextIndex = OS_AllocTLSIndex(); GlobalParseContextIndex = OS_AllocTLSIndex();
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false; return false;
} }
return true; return true;
} }
bool InitializeGlobalParseContext() bool InitializeGlobalParseContext()
{ {
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised"); assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised");
return false; return false;
} }
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext != 0) { if (lpParseContext != 0) {
assert(0 && "InitializeParseContextIndex(): Parse Context already initalised"); assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
return false; return false;
} }
TThreadParseContext *lpThreadData = new TThreadParseContext(); TThreadParseContext *lpThreadData = new TThreadParseContext();
if (lpThreadData == 0) { if (lpThreadData == 0) {
assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context"); assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
return false; return false;
} }
lpThreadData->lpGlobalParseContext = 0; lpThreadData->lpGlobalParseContext = 0;
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData); OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
return true; return true;
} }
TParseContextPointer& GetGlobalParseContext() TParseContextPointer& GetGlobalParseContext()
{ {
// //
// Minimal error checking for speed // Minimal error checking for speed
// //
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
return lpParseContext->lpGlobalParseContext; return lpParseContext->lpGlobalParseContext;
} }
bool FreeParseContext() bool FreeParseContext()
{ {
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContext(): Parse Context index not initalised"); assert(0 && "FreeParseContext(): Parse Context index not initalised");
return false; return false;
} }
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex)); TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
if (lpParseContext) if (lpParseContext)
delete lpParseContext; delete lpParseContext;
return true; return true;
} }
bool FreeParseContextIndex() bool FreeParseContextIndex()
{ {
OS_TLSIndex tlsiIndex = GlobalParseContextIndex; OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) { if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "FreeParseContextIndex(): Parse Context index not initalised"); assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
return false; return false;
} }
GlobalParseContextIndex = OS_INVALID_TLS_INDEX; GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
return OS_FreeTLSIndex(tlsiIndex); return OS_FreeTLSIndex(tlsiIndex);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment