void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) { TInfoSinkBase &out = objSink(); if (node != NULL) { node->traverse(this); // Single statements not part of a sequence need to be terminated // with semi-colon. if (isSingleStatement(node)) out << ";\n"; } else { out << "{\n}\n"; // Empty code block. } }
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) { bool visitChildren = true; TInfoSinkBase &out = objSink(); bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction()); switch (node->getOp()) { case EOpSequence: // Scope the sequences except when at the global scope. if (mDepth > 0) { out << "{\n"; } incrementDepth(node); for (TIntermSequence::const_iterator iter = node->getSequence()->begin(); iter != node->getSequence()->end(); ++iter) { TIntermNode *curNode = *iter; ASSERT(curNode != NULL); curNode->traverse(this); if (isSingleStatement(curNode)) out << ";\n"; } decrementDepth(); // Scope the sequences except when at the global scope. if (mDepth > 0) { out << "}\n"; } visitChildren = false; break; case EOpPrototype: // Function declaration. ASSERT(visit == PreVisit); { const TType &type = node->getType(); writeVariableType(type); if (type.isArray()) out << arrayBrackets(type); } out << " " << hashFunctionNameIfNeeded(node->getNameObj()); out << "("; writeFunctionParameters(*(node->getSequence())); out << ")"; visitChildren = false; break; case EOpFunction: { // Function definition. ASSERT(visit == PreVisit); { const TType &type = node->getType(); writeVariableType(type); if (type.isArray()) out << arrayBrackets(type); } out << " " << hashFunctionNameIfNeeded(node->getNameObj()); incrementDepth(node); // Function definition node contains one or two children nodes // representing function parameters and function body. The latter // is not present in case of empty function bodies. const TIntermSequence &sequence = *(node->getSequence()); ASSERT((sequence.size() == 1) || (sequence.size() == 2)); TIntermSequence::const_iterator seqIter = sequence.begin(); // Traverse function parameters. TIntermAggregate *params = (*seqIter)->getAsAggregate(); ASSERT(params != NULL); ASSERT(params->getOp() == EOpParameters); params->traverse(this); // Traverse function body. TIntermAggregate *body = ++seqIter != sequence.end() ? (*seqIter)->getAsAggregate() : NULL; visitCodeBlock(body); decrementDepth(); // Fully processed; no need to visit children. visitChildren = false; break; } case EOpFunctionCall: // Function call. if (visit == PreVisit) out << hashFunctionNameIfNeeded(node->getNameObj()) << "("; else if (visit == InVisit) out << ", "; else out << ")"; break; case EOpParameters: // Function parameters. ASSERT(visit == PreVisit); out << "("; writeFunctionParameters(*(node->getSequence())); out << ")"; visitChildren = false; break; case EOpDeclaration: // Variable declaration. if (visit == PreVisit) { const TIntermSequence &sequence = *(node->getSequence()); const TIntermTyped *variable = sequence.front()->getAsTyped(); writeVariableType(variable->getType()); out << " "; mDeclaringVariables = true; } else if (visit == InVisit) { out << ", "; mDeclaringVariables = true; } else { mDeclaringVariables = false; } break; case EOpInvariantDeclaration: // Invariant declaration. ASSERT(visit == PreVisit); { const TIntermSequence *sequence = node->getSequence(); ASSERT(sequence && sequence->size() == 1); const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); ASSERT(symbol); out << "invariant " << hashVariableName(symbol->getSymbol()); } visitChildren = false; break; case EOpConstructFloat: writeConstructorTriplet(visit, node->getType(), "float"); break; case EOpConstructVec2: writeConstructorTriplet(visit, node->getType(), "vec2"); break; case EOpConstructVec3: writeConstructorTriplet(visit, node->getType(), "vec3"); break; case EOpConstructVec4: writeConstructorTriplet(visit, node->getType(), "vec4"); break; case EOpConstructBool: writeConstructorTriplet(visit, node->getType(), "bool"); break; case EOpConstructBVec2: writeConstructorTriplet(visit, node->getType(), "bvec2"); break; case EOpConstructBVec3: writeConstructorTriplet(visit, node->getType(), "bvec3"); break; case EOpConstructBVec4: writeConstructorTriplet(visit, node->getType(), "bvec4"); break; case EOpConstructInt: writeConstructorTriplet(visit, node->getType(), "int"); break; case EOpConstructIVec2: writeConstructorTriplet(visit, node->getType(), "ivec2"); break; case EOpConstructIVec3: writeConstructorTriplet(visit, node->getType(), "ivec3"); break; case EOpConstructIVec4: writeConstructorTriplet(visit, node->getType(), "ivec4"); break; case EOpConstructUInt: writeConstructorTriplet(visit, node->getType(), "uint"); break; case EOpConstructUVec2: writeConstructorTriplet(visit, node->getType(), "uvec2"); break; case EOpConstructUVec3: writeConstructorTriplet(visit, node->getType(), "uvec3"); break; case EOpConstructUVec4: writeConstructorTriplet(visit, node->getType(), "uvec4"); break; case EOpConstructMat2: writeConstructorTriplet(visit, node->getType(), "mat2"); break; case EOpConstructMat2x3: writeConstructorTriplet(visit, node->getType(), "mat2x3"); break; case EOpConstructMat2x4: writeConstructorTriplet(visit, node->getType(), "mat2x4"); break; case EOpConstructMat3x2: writeConstructorTriplet(visit, node->getType(), "mat3x2"); break; case EOpConstructMat3: writeConstructorTriplet(visit, node->getType(), "mat3"); break; case EOpConstructMat3x4: writeConstructorTriplet(visit, node->getType(), "mat3x4"); break; case EOpConstructMat4x2: writeConstructorTriplet(visit, node->getType(), "mat4x2"); break; case EOpConstructMat4x3: writeConstructorTriplet(visit, node->getType(), "mat4x3"); break; case EOpConstructMat4: writeConstructorTriplet(visit, node->getType(), "mat4"); break; case EOpConstructStruct: { const TType &type = node->getType(); ASSERT(type.getBasicType() == EbtStruct); TString constructorName = hashName(type.getStruct()->name()); writeConstructorTriplet(visit, node->getType(), constructorName.c_str()); break; } case EOpOuterProduct: writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction); break; case EOpLessThan: writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction); break; case EOpGreaterThan: writeBuiltInFunctionTriplet(visit, "greaterThan(", useEmulatedFunction); break; case EOpLessThanEqual: writeBuiltInFunctionTriplet(visit, "lessThanEqual(", useEmulatedFunction); break; case EOpGreaterThanEqual: writeBuiltInFunctionTriplet(visit, "greaterThanEqual(", useEmulatedFunction); break; case EOpVectorEqual: writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction); break; case EOpVectorNotEqual: writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction); break; case EOpComma: writeTriplet(visit, "(", ", ", ")"); break; case EOpMod: writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction); break; case EOpModf: writeBuiltInFunctionTriplet(visit, "modf(", useEmulatedFunction); break; case EOpPow: writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction); break; case EOpAtan: writeBuiltInFunctionTriplet(visit, "atan(", useEmulatedFunction); break; case EOpMin: writeBuiltInFunctionTriplet(visit, "min(", useEmulatedFunction); break; case EOpMax: writeBuiltInFunctionTriplet(visit, "max(", useEmulatedFunction); break; case EOpClamp: writeBuiltInFunctionTriplet(visit, "clamp(", useEmulatedFunction); break; case EOpMix: writeBuiltInFunctionTriplet(visit, "mix(", useEmulatedFunction); break; case EOpStep: writeBuiltInFunctionTriplet(visit, "step(", useEmulatedFunction); break; case EOpSmoothStep: writeBuiltInFunctionTriplet(visit, "smoothstep(", useEmulatedFunction); break; case EOpDistance: writeBuiltInFunctionTriplet(visit, "distance(", useEmulatedFunction); break; case EOpDot: writeBuiltInFunctionTriplet(visit, "dot(", useEmulatedFunction); break; case EOpCross: writeBuiltInFunctionTriplet(visit, "cross(", useEmulatedFunction); break; case EOpFaceForward: writeBuiltInFunctionTriplet(visit, "faceforward(", useEmulatedFunction); break; case EOpReflect: writeBuiltInFunctionTriplet(visit, "reflect(", useEmulatedFunction); break; case EOpRefract: writeBuiltInFunctionTriplet(visit, "refract(", useEmulatedFunction); break; case EOpMul: writeBuiltInFunctionTriplet(visit, "matrixCompMult(", useEmulatedFunction); break; default: UNREACHABLE(); } return visitChildren; }
bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) { bool visitChildren = true; TInfoSinkBase& out = objSink(); TString preString; bool delayedWrite = false; switch (node->getOp()) { case EOpSequence: { // Scope the sequences except when at the global scope. if (depth > 0) out << "{\n"; incrementDepth(); const TIntermSequence& sequence = node->getSequence(); for (TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter) { TIntermNode* node = *iter; ASSERT(node != NULL); node->traverse(this); if (isSingleStatement(node)) out << ";\n"; } decrementDepth(); // Scope the sequences except when at the global scope. if (depth > 0) out << "}\n"; visitChildren = false; break; } case EOpPrototype: { // Function declaration. ASSERT(visit == PreVisit); writeVariableType(node->getType()); out << " " << node->getName(); out << "("; writeFunctionParameters(node->getSequence()); out << ")"; visitChildren = false; break; } case EOpFunction: { // Function definition. ASSERT(visit == PreVisit); writeVariableType(node->getType()); out << " " << TFunction::unmangleName(node->getName()); incrementDepth(); // Function definition node contains one or two children nodes // representing function parameters and function body. The latter // is not present in case of empty function bodies. const TIntermSequence& sequence = node->getSequence(); ASSERT((sequence.size() == 1) || (sequence.size() == 2)); TIntermSequence::const_iterator seqIter = sequence.begin(); // Traverse function parameters. TIntermAggregate* params = (*seqIter)->getAsAggregate(); ASSERT(params != NULL); ASSERT(params->getOp() == EOpParameters); params->traverse(this); // Traverse function body. TIntermAggregate* body = ++seqIter != sequence.end() ? (*seqIter)->getAsAggregate() : NULL; visitCodeBlock(body); decrementDepth(); // Fully processed; no need to visit children. visitChildren = false; break; } case EOpFunctionCall: // Function call. if (visit == PreVisit) { TString functionName = TFunction::unmangleName(node->getName()); out << functionName << "("; } else if (visit == InVisit) { out << ", "; } else { out << ")"; } break; case EOpParameters: { // Function parameters. ASSERT(visit == PreVisit); out << "("; writeFunctionParameters(node->getSequence()); out << ")"; visitChildren = false; break; } case EOpDeclaration: { // Variable declaration. if (visit == PreVisit) { const TIntermSequence& sequence = node->getSequence(); const TIntermTyped* variable = sequence.front()->getAsTyped(); writeVariableType(variable->getType()); out << " "; mDeclaringVariables = true; } else if (visit == InVisit) { out << ", "; mDeclaringVariables = true; } else { mDeclaringVariables = false; } break; } case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break; case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break; case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break; case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break; case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break; case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break; case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break; case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break; case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break; case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break; case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break; case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break; case EOpConstructStruct: if (visit == PreVisit) { const TType& type = node->getType(); ASSERT(type.getBasicType() == EbtStruct); out << type.getTypeName() << "("; } else if (visit == InVisit) { out << ", "; } else { out << ")"; } break; case EOpLessThan: preString = "lessThan("; delayedWrite = true; break; case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break; case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break; case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break; case EOpVectorEqual: preString = "equal("; delayedWrite = true; break; case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break; case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break; case EOpMod: preString = "mod("; delayedWrite = true; break; case EOpPow: preString = "pow("; delayedWrite = true; break; case EOpAtan: preString = "atan("; delayedWrite = true; break; case EOpMin: preString = "min("; delayedWrite = true; break; case EOpMax: preString = "max("; delayedWrite = true; break; case EOpClamp: preString = "clamp("; delayedWrite = true; break; case EOpMix: preString = "mix("; delayedWrite = true; break; case EOpStep: preString = "step("; delayedWrite = true; break; case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break; case EOpDistance: preString = "distance("; delayedWrite = true; break; case EOpDot: preString = "dot("; delayedWrite = true; break; case EOpCross: preString = "cross("; delayedWrite = true; break; case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break; case EOpReflect: preString = "reflect("; delayedWrite = true; break; case EOpRefract: preString = "refract("; delayedWrite = true; break; case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break; default: UNREACHABLE(); break; } if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction()) preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); if (delayedWrite) writeTriplet(visit, preString.c_str(), ", ", ")"); return visitChildren; }
static void findTag (tokenInfo *const token) { if (currentContext->kind != K_UNDEFINED) { /* Drop context, but only if an end token is found */ dropContext (token); } if (token->kind == K_CONSTANT && vStringItem (token->name, 0) == '`') { /* Bug #961001: Verilog compiler directives are line-based. */ int c = skipWhite (vGetc ()); readIdentifier (token, c); createTag (token); /* Skip the rest of the line. */ do { c = vGetc(); } while (c != EOF && c != '\n'); vUngetc (c); } else if (token->kind == K_BLOCK) { /* Process begin..end blocks */ processBlock (token); } else if (token->kind == K_FUNCTION || token->kind == K_TASK) { /* Functions are treated differently because they may also include the * type of the return value. * Tasks are treated in the same way, although not having a return * value.*/ processFunction (token); } else if (token->kind == K_ASSERTION) { if (vStringLength (currentContext->blockName) > 0) { vStringCopy (token->name, currentContext->blockName); createTag (token); skipToSemiColon (); } } else if (token->kind == K_TYPEDEF) { processTypedef (token); } else if (token->kind == K_CLASS) { processClass (token); } else if (token->kind == K_IGNORE && isSingleStatement (token)) { currentContext->singleStat = TRUE; } else if (isVariable (token)) { int c = skipWhite (vGetc ()); tagNameList (token, c); } else if (token->kind != K_UNDEFINED && token->kind != K_IGNORE) { int c = skipWhite (vGetc ()); if (isIdentifierCharacter (c)) { readIdentifier (token, c); while (getKind (token) == K_IGNORE) { c = skipWhite (vGetc ()); readIdentifier (token, c); } createTag (token); /* Get port list if required */ c = skipWhite (vGetc ()); if (c == '(' && hasSimplePortList (token)) { processPortList (c); } else { vUngetc (c); } } } }