Array of Array prep: Turn a batch of 0's into nullptr or UnsizedArraySize.

Added some const as well. This will remove camouflage of the next commit,
which will add the bulk of Array of Array semantics and functionality.
(Note the basic grammar and data structure is already in place.)
This commit is contained in:
John Kessenich 2015-08-09 14:27:34 -06:00
parent 6726cccc91
commit b35483587f
7 changed files with 139 additions and 138 deletions

View File

@ -419,13 +419,13 @@ class TConstUnionArray {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TConstUnionArray() : unionArray(0) { } TConstUnionArray() : unionArray(nullptr) { }
virtual ~TConstUnionArray() { } virtual ~TConstUnionArray() { }
explicit TConstUnionArray(int size) explicit TConstUnionArray(int size)
{ {
if (size == 0) if (size == 0)
unionArray = 0; unionArray = nullptr;
else else
unionArray = new TConstUnionVector(size); unionArray = new TConstUnionVector(size);
} }
@ -473,7 +473,7 @@ public:
return sum; return sum;
} }
bool empty() const { return unionArray == 0; } bool empty() const { return unionArray == nullptr; }
protected: protected:
typedef TVector<TConstUnion> TConstUnionVector; typedef TVector<TConstUnion> TConstUnionVector;

View File

@ -804,8 +804,8 @@ public:
vectorSize = 1; vectorSize = 1;
matrixRows = 0; matrixRows = 0;
matrixCols = 0; matrixCols = 0;
arraySizes = 0; arraySizes = nullptr;
userDef = 0; userDef = nullptr;
loc = l; loc = l;
} }
@ -840,7 +840,7 @@ public:
bool isScalar() const bool isScalar() const
{ {
return matrixCols == 0 && vectorSize == 1 && arraySizes == 0 && userDef == 0; return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
} }
bool isImage() const bool isImage() const
@ -858,8 +858,8 @@ public:
// for "empty" type (no args) or simple scalar/vector/matrix // for "empty" type (no args) or simple scalar/vector/matrix
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) : explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0), basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(nullptr),
structure(0), fieldName(0), typeName(0) structure(nullptr), fieldName(nullptr), typeName(nullptr)
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -867,8 +867,8 @@ public:
} }
// for explicit precision qualifier // for explicit precision qualifier
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) : TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0), basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(nullptr),
structure(0), fieldName(0), typeName(0) structure(nullptr), fieldName(nullptr), typeName(nullptr)
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -879,7 +879,7 @@ public:
// for turning a TPublicType into a TType // for turning a TPublicType into a TType
explicit TType(const TPublicType& p) : explicit TType(const TPublicType& p) :
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes), basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
structure(0), fieldName(0), typeName(0) structure(nullptr), fieldName(nullptr), typeName(nullptr)
{ {
if (basicType == EbtSampler) if (basicType == EbtSampler)
sampler = p.sampler; sampler = p.sampler;
@ -910,7 +910,7 @@ public:
// for making structures, ... // for making structures, ...
TType(TTypeList* userDef, const TString& n) : TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0),
arraySizes(0), structure(userDef), fieldName(0) arraySizes(nullptr), structure(userDef), fieldName(nullptr)
{ {
sampler.clear(); sampler.clear();
qualifier.clear(); qualifier.clear();
@ -919,7 +919,7 @@ public:
// For interface blocks // For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) : TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0),
qualifier(q), arraySizes(0), structure(userDef), fieldName(0) qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr)
{ {
sampler.clear(); sampler.clear();
typeName = NewPoolTString(n.c_str()); typeName = NewPoolTString(n.c_str());
@ -1000,7 +1000,7 @@ public:
virtual void dereference(bool rowMajor = false) virtual void dereference(bool rowMajor = false)
{ {
if (arraySizes) if (arraySizes)
arraySizes = 0; arraySizes = nullptr;
else if (matrixCols > 0) { else if (matrixCols > 0) {
if (rowMajor) if (rowMajor)
vectorSize = matrixCols; vectorSize = matrixCols;
@ -1039,17 +1039,17 @@ public:
virtual int getMatrixCols() const { return matrixCols; } virtual int getMatrixCols() const { return matrixCols; }
virtual int getMatrixRows() const { return matrixRows; } virtual int getMatrixRows() const { return matrixRows; }
virtual int getArraySize() const { return arraySizes->getOuterSize(); } virtual int getArraySize() const { return arraySizes->getOuterSize(); }
virtual bool isArrayOfArrays() const { return arraySizes && arraySizes->getNumDims() > 1; } virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); } virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); }
virtual bool isVector() const { return vectorSize > 1; } virtual bool isVector() const { return vectorSize > 1; }
virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isMatrix() const { return matrixCols ? true : false; }
virtual bool isArray() const { return arraySizes != 0; } virtual bool isArray() const { return arraySizes != nullptr; }
virtual bool isImplicitlySizedArray() const { return isArray() && ! getArraySize() && qualifier.storage != EvqBuffer; } virtual bool isExplicitlySizedArray() const { return isArray() && getArraySize() != UnsizedArraySize; }
virtual bool isExplicitlySizedArray() const { return isArray() && getArraySize(); } virtual bool isImplicitlySizedArray() const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; }
virtual bool isRuntimeSizedArray() const { return isArray() && ! getArraySize() && qualifier.storage == EvqBuffer; } virtual bool isRuntimeSizedArray() const { return isArray() && getArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; }
virtual bool isStruct() const { return structure != 0; } virtual bool isStruct() const { return structure != nullptr; }
virtual bool isImage() const { return basicType == EbtSampler && getSampler().image; } virtual bool isImage() const { return basicType == EbtSampler && getSampler().image; }
// Recursively checks if the type contains the given basic type // Recursively checks if the type contains the given basic type
@ -1071,7 +1071,7 @@ public:
{ {
if (isArray()) if (isArray())
return true; return true;
if (! structure) if (structure == nullptr)
return false; return false;
for (unsigned int i = 0; i < structure->size(); ++i) { for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->containsArray()) if ((*structure)[i].type->containsArray())
@ -1083,7 +1083,7 @@ public:
// Check the structure for any structures, needed for some error checks // Check the structure for any structures, needed for some error checks
virtual bool containsStructure() const virtual bool containsStructure() const
{ {
if (! structure) if (structure == nullptr)
return false; return false;
for (unsigned int i = 0; i < structure->size(); ++i) { for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->structure) if ((*structure)[i].type->structure)
@ -1097,7 +1097,7 @@ public:
{ {
if (isImplicitlySizedArray()) if (isImplicitlySizedArray())
return true; return true;
if (! structure) if (structure == nullptr)
return false; return false;
for (unsigned int i = 0; i < structure->size(); ++i) { for (unsigned int i = 0; i < structure->size(); ++i) {
if ((*structure)[i].type->containsImplicitlySizedArray()) if ((*structure)[i].type->containsImplicitlySizedArray())
@ -1242,11 +1242,10 @@ public:
p += snprintf(p, end - p, "writeonly "); p += snprintf(p, end - p, "writeonly ");
p += snprintf(p, end - p, "%s ", getStorageQualifierString()); p += snprintf(p, end - p, "%s ", getStorageQualifierString());
if (arraySizes) { if (arraySizes) {
if (arraySizes->getOuterSize() == 0) { if (arraySizes->getOuterSize() == UnsizedArraySize) {
p += snprintf(p, end - p, "implicitly-sized array of "); p += snprintf(p, end - p, "implicitly-sized array of ");
} else { } else {
for(int i = 0; i < (int)arraySizes->getNumDims() ; ++i) { for(int i = 0; i < (int)arraySizes->getNumDims() ; ++i) {
// p += snprintf(p, end - p, "%s%d", (i == 0 ? "" : "x"), arraySizes->sizes[numDimensions-1-i]);
p += snprintf(p, end - p, "%d-element array of ", (*arraySizes)[i]); p += snprintf(p, end - p, "%d-element array of ", (*arraySizes)[i]);
} }
} }
@ -1337,12 +1336,12 @@ public:
// //
bool sameStructType(const TType& right) const bool sameStructType(const TType& right) const
{ {
// Most commonly, they are both 0, or the same pointer to the same actual structure // Most commonly, they are both nullptr, or the same pointer to the same actual structure
if (structure == right.structure) if (structure == right.structure)
return true; return true;
// Both being 0 was caught above, now they both have to be structures of the same number of elements // Both being nullptr was caught above, now they both have to be structures of the same number of elements
if (structure == 0 || right.structure == 0 || if (structure == nullptr || right.structure == nullptr ||
structure->size() != right.structure->size()) structure->size() != right.structure->size())
return false; return false;
@ -1371,7 +1370,7 @@ public:
// See if two type's arrayness match // See if two type's arrayness match
bool sameArrayness(const TType& right) const bool sameArrayness(const TType& right) const
{ {
return ((arraySizes == 0 && right.arraySizes == 0) || return ((arraySizes == nullptr && right.arraySizes == nullptr) ||
(arraySizes && right.arraySizes && *arraySizes == *right.arraySizes)); (arraySizes && right.arraySizes && *arraySizes == *right.arraySizes));
} }
@ -1410,8 +1409,8 @@ protected:
TSampler sampler; TSampler sampler;
TQualifier qualifier; TQualifier qualifier;
TArraySizes* arraySizes; // 0 unless an array; can be shared across types TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
TTypeList* structure; // 0 unless this is a struct; can be shared across types TTypeList* structure; // nullptr unless this is a struct; can be shared across types
TString *fieldName; // for structure field names TString *fieldName; // for structure field names
TString *typeName; // for structure type name TString *typeName; // for structure type name
}; };

View File

@ -43,6 +43,10 @@
namespace glslang { namespace glslang {
// This is used to mean there is no size yet, it is waiting to get a size from somewhere else.
// Historically, this is not fully encapsulated, trying to catch them all...
const int UnsizedArraySize = 0;
// //
// TSmallArrayVector is used as the container for the set of sizes in TArraySizes. // TSmallArrayVector is used as the container for the set of sizes in TArraySizes.
// It has generic-container semantics, while TArraySizes has array-of-array semantics. // It has generic-container semantics, while TArraySizes has array-of-array semantics.
@ -56,7 +60,7 @@ struct TSmallArrayVector {
// //
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSmallArrayVector() : sizes(0) { } TSmallArrayVector() : sizes(nullptr) { }
virtual ~TSmallArrayVector() { dealloc(); } virtual ~TSmallArrayVector() { dealloc(); }
// For breaking into two non-shared copies, independently modifiable. // For breaking into two non-shared copies, independently modifiable.
@ -72,14 +76,14 @@ struct TSmallArrayVector {
return *this; return *this;
} }
int size() int size() const
{ {
if (sizes == nullptr) if (sizes == nullptr)
return 0; return 0;
return (int)sizes->size(); return (int)sizes->size();
} }
unsigned int front() unsigned int front() const
{ {
assert(sizes != nullptr && sizes->size() > 0); assert(sizes != nullptr && sizes->size() > 0);
return sizes->front(); return sizes->front();
@ -97,13 +101,13 @@ struct TSmallArrayVector {
sizes->push_back(e); sizes->push_back(e);
} }
unsigned int operator[](int i) unsigned int operator[](int i) const
{ {
assert(sizes && (int)sizes->size() > i); assert(sizes && (int)sizes->size() > i);
return (*sizes)[i]; return (*sizes)[i];
} }
bool operator==(const TSmallArrayVector& rhs) bool operator==(const TSmallArrayVector& rhs) const
{ {
if (sizes == nullptr && rhs.sizes == nullptr) if (sizes == nullptr && rhs.sizes == nullptr)
return true; return true;
@ -150,14 +154,14 @@ struct TArraySizes {
} }
// translate from array-of-array semantics to container semantics // translate from array-of-array semantics to container semantics
int getNumDims() { return sizes.size(); } int getNumDims() const { return sizes.size(); }
int getOuterSize() { return sizes.front(); } int getOuterSize() const { return sizes.front(); }
void setOuterSize(int s) { sizes.push_back((unsigned)s); } void setOuterSize(int s) { sizes.push_back((unsigned)s); }
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
int getImplicitSize() { return (int)implicitArraySize; } int getImplicitSize() const { return (int)implicitArraySize; }
void setImplicitSize(int s) { implicitArraySize = s; } void setImplicitSize(int s) { implicitArraySize = s; }
int operator[](int i) { return sizes[i]; } int operator[](int i) const { return sizes[i]; }
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; }
protected: protected:
TSmallArrayVector sizes; TSmallArrayVector sizes;

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "2.3.704" #define GLSLANG_REVISION "2.3.706"
#define GLSLANG_DATE "06-Aug-2015" #define GLSLANG_DATE "09-Aug-2015"

View File

@ -53,9 +53,9 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
version(v), profile(p), forwardCompatible(fc), version(v), profile(p), forwardCompatible(fc),
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0), contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
postMainReturn(false), postMainReturn(false),
tokensBeforeEOF(false), limits(resources.limits), messages(m), currentScanner(0), tokensBeforeEOF(false), limits(resources.limits), messages(m), currentScanner(nullptr),
numErrors(0), parsingBuiltins(pb), afterEOF(false), numErrors(0), parsingBuiltins(pb), afterEOF(false),
atomicUintOffsets(0), anyIndexLimits(false) atomicUintOffsets(nullptr), anyIndexLimits(false)
{ {
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms // ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
linkage = new TIntermAggregate; linkage = new TIntermAggregate;
@ -406,7 +406,7 @@ void C_DECL TParseContext::ppWarn(const TSourceLoc& loc, const char* szReason, c
// //
TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string) TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
{ {
TIntermTyped* node = 0; TIntermTyped* node = nullptr;
// Error check for requiring specific extensions present. // Error check for requiring specific extensions present.
if (symbol && symbol->getNumExtensions()) if (symbol && symbol->getNumExtensions())
@ -426,12 +426,12 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
} }
const TVariable* variable; const TVariable* variable;
const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : 0; const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr;
if (anon) { if (anon) {
// It was a member of an anonymous container. // It was a member of an anonymous container.
// The "getNumExtensions()" mechanism above doesn't yet work for block members // The "getNumExtensions()" mechanism above doesn't yet work for block members
blockMemberExtensionCheck(loc, 0, *string); blockMemberExtensionCheck(loc, nullptr, *string);
// Create a subtree for its dereference. // Create a subtree for its dereference.
variable = anon->getAnonContainer().getAsVariable(); variable = anon->getAnonContainer().getAsVariable();
@ -447,7 +447,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
// The symbol table search was done in the lexical phase. // The symbol table search was done in the lexical phase.
// See if it was a variable. // See if it was a variable.
variable = symbol ? symbol->getAsVariable() : 0; variable = symbol ? symbol->getAsVariable() : nullptr;
if (variable) { if (variable) {
if ((variable->getType().getBasicType() == EbtBlock || if ((variable->getType().getBasicType() == EbtBlock ||
variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) { variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) {
@ -480,7 +480,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
// //
TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index) TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{ {
TIntermTyped* result = 0; TIntermTyped* result = nullptr;
int indexValue = 0; int indexValue = 0;
if (index->getQualifier().storage == EvqConst) { if (index->getQualifier().storage == EvqConst) {
@ -533,7 +533,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
} }
} }
if (result == 0) { if (result == nullptr) {
// Insert dummy error-recovery result // Insert dummy error-recovery result
result = intermediate.addConstantUnion(0.0, EbtFloat, loc); result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
} else { } else {
@ -939,7 +939,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
{ {
currentCaller = function.getMangledName(); currentCaller = function.getMangledName();
TSymbol* symbol = symbolTable.find(function.getMangledName()); TSymbol* symbol = symbolTable.find(function.getMangledName());
TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr;
if (! prevDec) if (! prevDec)
error(loc, "can't find function", function.getName().c_str(), ""); error(loc, "can't find function", function.getName().c_str(), "");
@ -989,7 +989,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
TIntermAggregate* paramNodes = new TIntermAggregate; TIntermAggregate* paramNodes = new TIntermAggregate;
for (int i = 0; i < function.getParamCount(); i++) { for (int i = 0; i < function.getParamCount(); i++) {
TParameter& param = function[i]; TParameter& param = function[i];
if (param.name != 0) { if (param.name != nullptr) {
TVariable *variable = new TVariable(param.name, *param.type); TVariable *variable = new TVariable(param.name, *param.type);
// Insert the parameters with name in the symbol table. // Insert the parameters with name in the symbol table.
@ -997,7 +997,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
error(loc, "redefinition", variable->getName().c_str(), ""); error(loc, "redefinition", variable->getName().c_str(), "");
else { else {
// Transfer ownership of name pointer to symbol table. // Transfer ownership of name pointer to symbol table.
param.name = 0; param.name = nullptr;
// Add the parameter to the HIL // Add the parameter to the HIL
paramNodes = intermediate.growAggregate(paramNodes, paramNodes = intermediate.growAggregate(paramNodes,
@ -1027,7 +1027,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
// //
TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments) TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
{ {
TIntermTyped* result = 0; TIntermTyped* result = nullptr;
TOperator op = function->getBuiltInOp(); TOperator op = function->getBuiltInOp();
if (op == EOpArrayLength) if (op == EOpArrayLength)
@ -1044,7 +1044,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
// It's a constructor, of type 'type'. // It's a constructor, of type 'type'.
// //
result = addConstructor(loc, arguments, type, op); result = addConstructor(loc, arguments, type, op);
if (result == 0) if (result == nullptr)
error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), "");
} }
} else { } else {
@ -1105,7 +1105,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
// A function call mapped to a built-in operation. // A function call mapped to a built-in operation.
checkLocation(loc, op); checkLocation(loc, op);
result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType()); result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType());
if (result == 0) { if (result == nullptr) {
error(arguments->getLoc(), " wrong operand type", "Internal Error", error(arguments->getLoc(), " wrong operand type", "Internal Error",
"built in unary operator function. Type: %s", "built in unary operator function. Type: %s",
static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str()); static_cast<TIntermTyped*>(arguments)->getCompleteString().c_str());
@ -1144,7 +1144,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
// generic error recovery // generic error recovery
// TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades // TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
if (result == 0) if (result == nullptr)
result = intermediate.addConstantUnion(0.0, EbtFloat, loc); result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
return result; return result;
@ -1284,8 +1284,8 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
// void: function(arg, ...) -> ( function(tempArg, ...), arg = tempArg, ...) // void: function(arg, ...) -> ( function(tempArg, ...), arg = tempArg, ...)
// ret = function(arg, ...) -> ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet) // ret = function(arg, ...) -> ret = (tempRet = function(tempArg, ...), arg = tempArg, ..., tempRet)
// Where the "tempArg" type needs no conversion as an argument, but will convert on assignment. // Where the "tempArg" type needs no conversion as an argument, but will convert on assignment.
TIntermTyped* conversionTree = 0; TIntermTyped* conversionTree = nullptr;
TVariable* tempRet = 0; TVariable* tempRet = nullptr;
if (intermNode.getBasicType() != EbtVoid) { if (intermNode.getBasicType() != EbtVoid) {
// do the "tempRet = function(...), " bit from above // do the "tempRet = function(...), " bit from above
tempRet = makeInternalVariable("tempReturn", intermNode.getType()); tempRet = makeInternalVariable("tempReturn", intermNode.getType());
@ -1691,12 +1691,12 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
} }
const char* symbol = 0; const char* symbol = nullptr;
TIntermSymbol* symNode = node->getAsSymbolNode(); TIntermSymbol* symNode = node->getAsSymbolNode();
if (symNode != 0) if (symNode != nullptr)
symbol = symNode->getName().c_str(); symbol = symNode->getName().c_str();
const char* message = 0; const char* message = nullptr;
switch (node->getQualifier().storage) { switch (node->getQualifier().storage) {
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;
@ -1736,7 +1736,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
} }
} }
if (message == 0 && binaryNode == 0 && symNode == 0) { if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
error(loc, " l-value required", op, "", ""); error(loc, " l-value required", op, "", "");
return true; return true;
@ -1746,7 +1746,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
// //
// Everything else is okay, no error. // Everything else is okay, no error.
// //
if (message == 0) if (message == nullptr)
return false; return false;
// //
@ -2034,7 +2034,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
} }
TIntermTyped* typed = node->getAsTyped(); TIntermTyped* typed = node->getAsTyped();
if (typed == 0) { if (typed == nullptr) {
error(loc, "constructor argument does not have a type", "constructor", ""); error(loc, "constructor argument does not have a type", "constructor", "");
return true; return true;
} }
@ -2442,7 +2442,7 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas
void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, int& size) void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, int& size)
{ {
TIntermConstantUnion* constant = expr->getAsConstantUnion(); TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) { if (constant == nullptr || (constant->getBasicType() != EbtInt && constant->getBasicType() != EbtUint)) {
error(loc, "array size must be a constant integer expression", "", ""); error(loc, "array size must be a constant integer expression", "", "");
size = 1; size = 1;
@ -2508,7 +2508,7 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
// //
void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, int size) void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, int size)
{ {
if (size == 0) if (size == UnsizedArraySize)
error(loc, "array size required", "", ""); error(loc, "array size required", "", "");
} }
@ -2590,8 +2590,6 @@ void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, TArr
// Do all the semantic checking for declaring or redeclaring an array, with and // Do all the semantic checking for declaring or redeclaring an array, with and
// without a size, and make the right changes to the symbol table. // without a size, and make the right changes to the symbol table.
// //
// size == 0 means no specified size.
//
void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration) void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, const TType& type, TSymbol*& symbol, bool& newDeclaration)
{ {
if (! symbol) { if (! symbol) {
@ -2602,7 +2600,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, con
// bad shader (errors already reported) trying to redeclare a built-in name as an array // bad shader (errors already reported) trying to redeclare a built-in name as an array
return; return;
} }
if (symbol == 0 || ! currentScope) { if (symbol == nullptr || ! currentScope) {
// //
// Successfully process a new definition. // Successfully process a new definition.
// (Redeclarations have to take place at the same scope; otherwise they are hiding declarations) // (Redeclarations have to take place at the same scope; otherwise they are hiding declarations)
@ -2623,7 +2621,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, TString& identifier, con
} }
if (symbol->getAsAnonMember()) { if (symbol->getAsAnonMember()) {
error(loc, "cannot redeclare a user-block member array", identifier.c_str(), ""); error(loc, "cannot redeclare a user-block member array", identifier.c_str(), "");
symbol = 0; symbol = nullptr;
return; return;
} }
} }
@ -2675,9 +2673,9 @@ void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *
// Figure out what symbol to lookup, as we will use its type to edit for the size change, // Figure out what symbol to lookup, as we will use its type to edit for the size change,
// as that type will be shared through shallow copies for future references. // as that type will be shared through shallow copies for future references.
TSymbol* symbol = 0; TSymbol* symbol = nullptr;
int blockIndex = -1; int blockIndex = -1;
const TString* lookupName = 0; const TString* lookupName = nullptr;
if (node->getAsSymbolNode()) if (node->getAsSymbolNode())
lookupName = &node->getAsSymbolNode()->getName(); lookupName = &node->getAsSymbolNode()->getName();
else if (node->getAsBinaryNode()) { else if (node->getAsBinaryNode()) {
@ -2687,7 +2685,7 @@ void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *
// return early now to avoid crashing later in this function. // return early now to avoid crashing later in this function.
if (! deref->getLeft()->getAsSymbolNode() || deref->getLeft()->getBasicType() != EbtBlock || if (! deref->getLeft()->getAsSymbolNode() || deref->getLeft()->getBasicType() != EbtBlock ||
deref->getLeft()->getType().getQualifier().storage == EvqUniform || deref->getLeft()->getType().getQualifier().storage == EvqUniform ||
deref->getRight()->getAsConstantUnion() == 0) deref->getRight()->getAsConstantUnion() == nullptr)
return; return;
blockIndex = deref->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); blockIndex = deref->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
@ -2699,7 +2697,7 @@ void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *
// Lookup the symbol, should only fail if shader code is incorrect // Lookup the symbol, should only fail if shader code is incorrect
symbol = symbolTable.find(*lookupName); symbol = symbolTable.find(*lookupName);
if (symbol == 0) if (symbol == nullptr)
return; return;
if (symbol->getAsFunction()) { if (symbol->getAsFunction()) {
@ -2743,7 +2741,7 @@ void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier
// copy the symbol table's read-only built-in variable to the current // copy the symbol table's read-only built-in variable to the current
// global level, where it can be modified based on the passed in type. // global level, where it can be modified based on the passed in type.
// //
// Returns 0 if no redeclaration took place; meaning a normal declaration still // Returns nullptr if no redeclaration took place; meaning a normal declaration still
// needs to occur for it, not necessarily an error. // needs to occur for it, not necessarily an error.
// //
// Returns a redeclared and type-modified variable if a redeclarated occurred. // Returns a redeclared and type-modified variable if a redeclarated occurred.
@ -2751,12 +2749,12 @@ void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier
TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration) TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
{ {
if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
return 0; return nullptr;
bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord")); bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord"));
bool esRedecls = (profile == EEsProfile && extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks)); bool esRedecls = (profile == EEsProfile && extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks));
if (! esRedecls && ! nonEsRedecls) if (! esRedecls && ! nonEsRedecls)
return 0; return nullptr;
// Special case when using GL_ARB_separate_shader_objects // Special case when using GL_ARB_separate_shader_objects
bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination
@ -2789,7 +2787,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
// If the symbol was not found, this must be a version/profile/stage // If the symbol was not found, this must be a version/profile/stage
// that doesn't have it. // that doesn't have it.
if (! symbol) if (! symbol)
return 0; return nullptr;
// If it wasn't at a built-in level, then it's already been redeclared; // If it wasn't at a built-in level, then it's already been redeclared;
// that is, this is a redeclaration of a redeclaration; reuse that initial // that is, this is a redeclaration of a redeclaration; reuse that initial
@ -2866,7 +2864,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
return symbol; return symbol;
} }
return 0; return nullptr;
} }
// //
@ -2987,14 +2985,14 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
if (numOriginalMembersFound < newTypeList.size()) if (numOriginalMembersFound < newTypeList.size())
error(loc, "block redeclaration has extra members", blockName.c_str(), ""); error(loc, "block redeclaration has extra members", blockName.c_str(), "");
if (type.isArray() != (arraySizes != 0)) if (type.isArray() != (arraySizes != nullptr))
error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), ""); error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), "");
else if (type.isArray()) { else if (type.isArray()) {
if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == 0) if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize)
error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), ""); error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), "");
else if (type.isExplicitlySizedArray() && type.getArraySize() != arraySizes->getOuterSize()) else if (type.isExplicitlySizedArray() && type.getArraySize() != arraySizes->getOuterSize())
error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); error(loc, "cannot change array size of redeclared block", blockName.c_str(), "");
else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() > 0) else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize)
type.changeArraySize(arraySizes->getOuterSize()); type.changeArraySize(arraySizes->getOuterSize());
} }
@ -3691,7 +3689,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
switch (qualifier.storage) { switch (qualifier.storage) {
case EvqUniform: case EvqUniform:
case EvqBuffer: case EvqBuffer:
if (symbol.getAsVariable() == 0) if (symbol.getAsVariable() == nullptr)
error(loc, "can only be used on variable declaration", "location", ""); error(loc, "can only be used on variable declaration", "location", "");
break; break;
default: default:
@ -4006,15 +4004,15 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
// //
// Look up a function name in the symbol table, and make sure it is a function. // Look up a function name in the symbol table, and make sure it is a function.
// //
// Return the function symbol if found, otherwise 0. // Return the function symbol if found, otherwise nullptr.
// //
const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
const TFunction* function = 0; const TFunction* function = nullptr;
if (symbolTable.isFunctionNameVariable(call.getName())) { if (symbolTable.isFunctionNameVariable(call.getName())) {
error(loc, "can't use function syntax on variable", call.getName().c_str(), ""); error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
return 0; return nullptr;
} }
if (profile == EEsProfile || version < 120) if (profile == EEsProfile || version < 120)
@ -4031,10 +4029,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn) const TFunction* TParseContext::findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{ {
TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
if (symbol == 0) { if (symbol == nullptr) {
error(loc, "no matching overloaded function found", call.getName().c_str(), ""); error(loc, "no matching overloaded function found", call.getName().c_str(), "");
return 0; return nullptr;
} }
return symbol->getAsFunction(); return symbol->getAsFunction();
@ -4057,7 +4055,7 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
// a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match
// more than one function." // more than one function."
const TFunction* candidate = 0; const TFunction* candidate = nullptr;
TVector<TFunction*> candidateList; TVector<TFunction*> candidateList;
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
@ -4102,7 +4100,7 @@ const TFunction* TParseContext::findFunction120(const TSourceLoc& loc, const TFu
} }
} }
if (candidate == 0) if (candidate == nullptr)
error(loc, "no matching overloaded function found", call.getName().c_str(), ""); error(loc, "no matching overloaded function found", call.getName().c_str(), "");
return candidate; return candidate;
@ -4138,14 +4136,14 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType
// table, and all error checking. // table, and all error checking.
// //
// Returns a subtree node that computes an initializer, if needed. // Returns a subtree node that computes an initializer, if needed.
// Returns 0 if there is no code to execute for initialization. // Returns nullptr if there is no code to execute for initialization.
// //
TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
{ {
TType type(publicType); TType type(publicType);
if (voidErrorCheck(loc, identifier, type.getBasicType())) if (voidErrorCheck(loc, identifier, type.getBasicType()))
return 0; return nullptr;
if (initializer) if (initializer)
rValueErrorCheck(loc, "initializer", initializer); rValueErrorCheck(loc, "initializer", initializer);
@ -4196,15 +4194,15 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
} }
if (! symbol) if (! symbol)
return 0; return nullptr;
// Deal with initializer // Deal with initializer
TIntermNode* initNode = 0; TIntermNode* initNode = nullptr;
if (symbol && initializer) { if (symbol && initializer) {
TVariable* variable = symbol->getAsVariable(); TVariable* variable = symbol->getAsVariable();
if (! variable) { if (! variable) {
error(loc, "initializer requires a variable, not a member", identifier.c_str(), ""); error(loc, "initializer requires a variable, not a member", identifier.c_str(), "");
return 0; return nullptr;
} }
initNode = executeInitializer(loc, initializer, variable); initNode = executeInitializer(loc, initializer, variable);
} }
@ -4261,7 +4259,7 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, TString& identi
// add variable to symbol table // add variable to symbol table
if (! symbolTable.insert(*variable)) { if (! symbolTable.insert(*variable)) {
error(loc, "redefinition", variable->getName().c_str(), ""); error(loc, "redefinition", variable->getName().c_str(), "");
return 0; return nullptr;
} else { } else {
newDeclaration = true; newDeclaration = true;
return variable; return variable;
@ -4271,7 +4269,7 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, TString& identi
// //
// Handle all types of initializers from the grammar. // Handle all types of initializers from the grammar.
// //
// Returning 0 just means there is no code to execute to handle the // Returning nullptr just means there is no code to execute to handle the
// initializer, which will, for example, be the case for constant initializers. // initializer, which will, for example, be the case for constant initializers.
// //
TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable) TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable)
@ -4284,7 +4282,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst || if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
(qualifier == EvqUniform && profile != EEsProfile && version >= 120))) { (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) {
error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
return 0; return nullptr;
} }
arrayObjectCheck(loc, variable->getType(), "array initializer"); arrayObjectCheck(loc, variable->getType(), "array initializer");
@ -4298,7 +4296,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
// error recovery; don't leave const without constant values // error recovery; don't leave const without constant values
if (qualifier == EvqConst) if (qualifier == EvqConst)
variable->getWritableType().getQualifier().storage = EvqTemporary; variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0; return nullptr;
} }
// Fix arrayness if variable is unsized, getting size from the initializer // Fix arrayness if variable is unsized, getting size from the initializer
@ -4310,12 +4308,12 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
if (qualifier == EvqUniform && initializer->getType().getQualifier().storage != EvqConst) { if (qualifier == EvqUniform && initializer->getType().getQualifier().storage != EvqConst) {
error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(loc, "uniform initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getWritableType().getQualifier().storage = EvqTemporary; variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0; return nullptr;
} }
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) { if (qualifier == EvqConst && symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) {
error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str()); error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getWritableType().getQualifier().storage = EvqTemporary; variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0; return nullptr;
} }
// Const variables require a constant initializer, depending on version // Const variables require a constant initializer, depending on version
@ -4349,7 +4347,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
error(loc, "non-matching or non-convertible constant type for const initializer", error(loc, "non-matching or non-convertible constant type for const initializer",
variable->getType().getStorageQualifierString(), ""); variable->getType().getStorageQualifierString(), "");
variable->getWritableType().getQualifier().storage = EvqTemporary; variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0; return nullptr;
} }
variable->setConstArray(initializer->getAsConstantUnion()->getConstArray()); variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
@ -4363,7 +4361,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp
return initNode; return initNode;
} }
return 0; return nullptr;
} }
// //
@ -4398,40 +4396,40 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
TType elementType(arrayType, 0); // dereferenced type TType elementType(arrayType, 0); // dereferenced type
for (size_t i = 0; i < initList->getSequence().size(); ++i) { for (size_t i = 0; i < initList->getSequence().size(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped()); initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
if (initList->getSequence()[i] == 0) if (initList->getSequence()[i] == nullptr)
return 0; return nullptr;
} }
return addConstructor(loc, initList, arrayType, mapTypeToConstructorOp(arrayType)); return addConstructor(loc, initList, arrayType, mapTypeToConstructorOp(arrayType));
} else if (type.isStruct()) { } else if (type.isStruct()) {
if (type.getStruct()->size() != initList->getSequence().size()) { if (type.getStruct()->size() != initList->getSequence().size()) {
error(loc, "wrong number of structure members", "initializer list", ""); error(loc, "wrong number of structure members", "initializer list", "");
return 0; return nullptr;
} }
for (size_t i = 0; i < type.getStruct()->size(); ++i) { for (size_t i = 0; i < type.getStruct()->size(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped()); initList->getSequence()[i] = convertInitializerList(loc, *(*type.getStruct())[i].type, initList->getSequence()[i]->getAsTyped());
if (initList->getSequence()[i] == 0) if (initList->getSequence()[i] == nullptr)
return 0; return nullptr;
} }
} else if (type.isMatrix()) { } else if (type.isMatrix()) {
if (type.getMatrixCols() != (int)initList->getSequence().size()) { if (type.getMatrixCols() != (int)initList->getSequence().size()) {
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str()); error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
return 0; return nullptr;
} }
TType vectorType(type, 0); // dereferenced type TType vectorType(type, 0); // dereferenced type
for (int i = 0; i < type.getMatrixCols(); ++i) { for (int i = 0; i < type.getMatrixCols(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped()); initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
if (initList->getSequence()[i] == 0) if (initList->getSequence()[i] == nullptr)
return 0; return nullptr;
} }
} else if (type.isVector()) { } else if (type.isVector()) {
if (type.getVectorSize() != (int)initList->getSequence().size()) { if (type.getVectorSize() != (int)initList->getSequence().size()) {
error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str()); error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
return 0; return nullptr;
} }
} else { } else {
error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str()); error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
return 0; return nullptr;
} }
// now that the subtree is processed, process this node // now that the subtree is processed, process this node
@ -4442,12 +4440,12 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
// Test for the correctness of the parameters passed to various constructor functions // Test for the correctness of the parameters passed to various constructor functions
// and also convert them to the right data type, if allowed and required. // and also convert them to the right data type, if allowed and required.
// //
// Returns 0 for an error or the constructed node (aggregate or typed) for no error. // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
// //
TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type, TOperator op) TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type, TOperator op)
{ {
if (node == 0 || node->getAsTyped() == 0) if (node == nullptr || node->getAsTyped() == nullptr)
return 0; return nullptr;
rValueErrorCheck(loc, "constructor", node->getAsTyped()); rValueErrorCheck(loc, "constructor", node->getAsTyped());
TIntermAggregate* aggrNode = node->getAsAggregate(); TIntermAggregate* aggrNode = node->getAsAggregate();
@ -4512,7 +4510,7 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
if (newNode) if (newNode)
*p = newNode; *p = newNode;
else else
return 0; return nullptr;
} }
TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc); TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, type, loc);
@ -4525,7 +4523,7 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a // the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
// float, then float is converted to int. // float, then float is converted to int.
// //
// Returns 0 for an error or the constructed node. // Returns nullptr for an error or the constructed node.
// //
TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset) TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset)
{ {
@ -4592,12 +4590,12 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
default: default:
error(loc, "unsupported construction", "", ""); error(loc, "unsupported construction", "", "");
return 0; return nullptr;
} }
newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc()); newNode = intermediate.addUnaryMath(basicOp, node, node->getLoc());
if (newNode == 0) { if (newNode == nullptr) {
error(loc, "can't convert", "constructor", ""); error(loc, "can't convert", "constructor", "");
return 0; return nullptr;
} }
// //
@ -4615,7 +4613,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
// 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
// an error message if the expected type does not match the parameter passed to the constructor. // an error message if the expected type does not match the parameter passed to the constructor.
// //
// Returns 0 for an error or the input node itself if the expected and the given parameter types match. // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
// //
TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc) TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
{ {
@ -4624,7 +4622,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str()); node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str());
return 0; return nullptr;
} }
return converted; return converted;
@ -4639,7 +4637,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
blockQualifierCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier);
if (arraySizes) if (arraySizes)
arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes->getOuterSize(), false); arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes->getOuterSize(), false);
arrayDimCheck(loc, arraySizes, 0); arrayDimCheck(loc, arraySizes, nullptr);
// fix and check for member storage qualifiers and types that don't belong within a block // fix and check for member storage qualifiers and types that don't belong within a block
for (unsigned int member = 0; member < typeList.size(); ++member) { for (unsigned int member = 0; member < typeList.size(); ++member) {
@ -5270,10 +5268,10 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
if (prevBranch) { if (prevBranch) {
TIntermTyped* prevExpression = prevBranch->getExpression(); TIntermTyped* prevExpression = prevBranch->getExpression();
TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression(); TIntermTyped* newExpression = branchNode->getAsBranchNode()->getExpression();
if (prevExpression == 0 && newExpression == 0) if (prevExpression == nullptr && newExpression == nullptr)
error(branchNode->getLoc(), "duplicate label", "default", ""); error(branchNode->getLoc(), "duplicate label", "default", "");
else if (prevExpression != 0 && else if (prevExpression != nullptr &&
newExpression != 0 && newExpression != nullptr &&
prevExpression->getAsConstantUnion() && prevExpression->getAsConstantUnion() &&
newExpression->getAsConstantUnion() && newExpression->getAsConstantUnion() &&
prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() == prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
@ -5296,7 +5294,7 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
wrapupSwitchSubsequence(lastStatements, nullptr); wrapupSwitchSubsequence(lastStatements, nullptr);
if (expression == 0 || if (expression == nullptr ||
(expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) || (expression->getBasicType() != EbtInt && expression->getBasicType() != EbtUint) ||
expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector()) expression->getType().isArray() || expression->getType().isMatrix() || expression->getType().isVector())
error(loc, "condition must be a scalar integer expression", "switch", ""); error(loc, "condition must be a scalar integer expression", "switch", "");
@ -5306,7 +5304,7 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
if (switchSequence->size() == 0) if (switchSequence->size() == 0)
return expression; return expression;
if (lastStatements == 0) { if (lastStatements == nullptr) {
// This was originally an ERRROR, because early versions of the specification said // This was originally an ERRROR, because early versions of the specification said
// "it is an error to have no statement between a label and the end of the switch statement." // "it is an error to have no statement between a label and the end of the switch statement."
// The specifications were updated to remove this (being ill-defined what a "statement" was), // The specifications were updated to remove this (being ill-defined what a "statement" was),

View File

@ -295,8 +295,8 @@ namespace {
// A single global usable by all threads, by all versions, by all languages. // A single global usable by all threads, by all versions, by all languages.
// After a single process-level initialization, this is read only and thread safe // After a single process-level initialization, this is read only and thread safe
std::unordered_map<std::string, int>* KeywordMap = 0; std::unordered_map<std::string, int>* KeywordMap = nullptr;
std::unordered_set<std::string>* ReservedSet = 0; std::unordered_set<std::string>* ReservedSet = nullptr;
}; };
@ -304,7 +304,7 @@ namespace glslang {
void TScanContext::fillInKeywordMap() void TScanContext::fillInKeywordMap()
{ {
if (KeywordMap != 0) { if (KeywordMap != nullptr) {
// this is really an error, as this should called only once per process // this is really an error, as this should called only once per process
// but, the only risk is if two threads called simultaneously // but, the only risk is if two threads called simultaneously
return; return;
@ -522,9 +522,9 @@ void TScanContext::fillInKeywordMap()
void TScanContext::deleteKeywordMap() void TScanContext::deleteKeywordMap()
{ {
delete KeywordMap; delete KeywordMap;
KeywordMap = 0; KeywordMap = nullptr;
delete ReservedSet; delete ReservedSet;
ReservedSet = 0; ReservedSet = nullptr;
} }
int TScanContext::tokenize(TPpContext* pp, TParserToken& token) int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
@ -533,7 +533,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
parserToken = &token; parserToken = &token;
TPpToken ppToken; TPpToken ppToken;
tokenText = pp->tokenize(&ppToken); tokenText = pp->tokenize(&ppToken);
if (tokenText == 0) if (tokenText == nullptr)
return 0; return 0;
loc = ppToken.loc; loc = ppToken.loc;

View File

@ -133,7 +133,7 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo
{ {
TInductiveTraverser it(loopId, symbolTable); TInductiveTraverser it(loopId, symbolTable);
if (! body) if (body == nullptr)
return; return;
body->traverse(&it); body->traverse(&it);