TIntermAggregate* ir_grow_declaration(TIntermTyped* declaration, TIntermSymbol *symbol, TIntermTyped *initializer, TParseContext& ctx) { TIntermTyped* added_decl = ir_add_declaration (symbol, initializer, symbol->getLine(), ctx); if (declaration->getAsDeclaration()) { TIntermAggregate* aggregate = ir_make_aggregate(declaration, declaration->getLine()); aggregate->setOperator(EOpSequence); declaration = aggregate; } assert (declaration->getAsAggregate()); TIntermAggregate* aggregate = ir_grow_aggregate(declaration, added_decl, added_decl->getLine(), EOpSequence); aggregate->setOperator(EOpSequence); return aggregate; }
// This is the safe way to change the operator on an aggregate, as it // does lots of error checking and fixing. Especially for establishing // a function call's operation on it's set of parameters. Sequences // of instructions are also aggregates, but they just direnctly set // their operator to EOpSequence. // // Returns an aggregate node, which could be the one passed in if // it was already an aggregate. TIntermAggregate* ir_set_aggregate_op(TIntermNode* node, TOperator op, TSourceLoc line) { TIntermAggregate* aggNode; // // Make sure we have an aggregate. If not turn it into one. // if (node) { aggNode = node->getAsAggregate(); if (aggNode == 0 || aggNode->getOp() != EOpNull) { // // Make an aggregate containing this node. // aggNode = new TIntermAggregate(); aggNode->getNodes().push_back(node); if (line.line == 0) line = node->getLine(); } } else aggNode = new TIntermAggregate(); // // Set the operator. // aggNode->setOperator(op); if (line.line != 0) aggNode->setLine(line); return aggNode; }
TIntermDeclaration* ir_grow_declaration(TIntermDeclaration* declaration, TIntermSymbol *symbol, TIntermTyped *initializer, TInfoSink& infoSink) { TIntermTyped* added_decl = symbol; if (initializer) added_decl = ir_add_assign(EOpAssign, symbol, initializer, symbol->getLine(), infoSink); if (declaration->isSingleDeclaration()) { TIntermTyped* current = declaration->getDeclaration(); TIntermAggregate* aggregate = ir_make_aggregate(current, current->getLine()); aggregate->setOperator(EOpComma); declaration->getDeclaration() = aggregate; } TIntermAggregate* aggregate = ir_grow_aggregate(declaration->getDeclaration(), added_decl, added_decl->getLine()); aggregate->setOperator(EOpComma); declaration->getDeclaration() = aggregate; return declaration; }
// // This is to be executed once the final root is put on top by the parsing // process. // bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language) { if (root == 0) return true; // // First, finish off the top level sequence, if any // TIntermAggregate* aggRoot = root->getAsAggregate(); if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); return true; }
int C_DECL Hlsl2Glsl_Parse( const ShHandle handle, const char* shaderString, ETargetVersion targetVersion, Hlsl2Glsl_ParseCallbacks* callbacks, unsigned options) { if (!InitThread()) return 0; if (handle == 0) return 0; HlslCrossCompiler* compiler = handle; GlobalPoolAllocator.push(); compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); if (!shaderString) return 1; TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]); GenerateBuiltInSymbolTable(compiler->infoSink, &symbolTable, compiler->getLanguage()); TParseContext parseContext(symbolTable, compiler->getLanguage(), targetVersion, options, compiler->infoSink); GlobalParseContext = &parseContext; setInitialState(); // // Parse the application's shaders. All the following symbol table // work will be throw-away, so push a new allocation scope that can // be thrown away, then push a scope for the current shader's globals. // bool success = true; symbolTable.push(); if (!symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); int ret = PaParseString(const_cast<char*>(shaderString), parseContext, callbacks); if (ret) success = false; if (success && parseContext.treeRoot) { TIntermAggregate* aggRoot = parseContext.treeRoot->getAsAggregate(); if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); if (options & ETranslateOpIntermediate) ir_output_tree(parseContext.treeRoot, parseContext.infoSink); compiler->TransformAST (parseContext.treeRoot); compiler->ProduceGLSL (parseContext.treeRoot, targetVersion, options); } else if (!success) { // only add "X compilation errors" message if somehow there are no other errors whatsoever, yet // we still failed. for some reason. if (parseContext.infoSink.info.IsEmpty()) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; } success = false; if (options & ETranslateOpIntermediate) ir_output_tree(parseContext.treeRoot, parseContext.infoSink); } ir_remove_tree(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (! symbolTable.atSharedBuiltInLevel()) symbolTable.pop(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }
int C_DECL Hlsl2Glsl_Parse( const ShHandle handle, const char* shaderString, int options ) { if (!InitThread()) return 0; if (handle == 0) return 0; HlslCrossCompiler* compiler = handle; GlobalPoolAllocator.push(); compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); if (!shaderString) return 1; TIntermediate intermediate(compiler->infoSink); TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]); GenerateBuiltInSymbolTable(compiler->infoSink, &symbolTable, compiler->getLanguage()); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink); GlobalParseContext = &parseContext; setInitialState(); InitPreprocessor(); // // Parse the application's shaders. All the following symbol table // work will be throw-away, so push a new allocation scope that can // be thrown away, then push a scope for the current shader's globals. // bool success = true; symbolTable.push(); if (!symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); int ret = PaParseString(const_cast<char*>(shaderString), parseContext); if (ret) success = false; if (success && parseContext.treeRoot) { TIntermAggregate* aggRoot = parseContext.treeRoot->getAsAggregate(); if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); if (options & ETranslateOpIntermediate) intermediate.outputTree(parseContext.treeRoot); compiler->TransformAST (parseContext.treeRoot); compiler->ProduceGLSL (parseContext.treeRoot, (options & ETranslateOpUsePrecision) ? true : false); } else if (!success) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; if (options & ETranslateOpIntermediate) intermediate.outputTree(parseContext.treeRoot); } intermediate.remove(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (! symbolTable.atSharedBuiltInLevel()) symbolTable.pop(); FinalizePreprocessor(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }