TIntermNode* getFunctionBySignature(const char *sig, TIntermNode* root) // Assumption: 1. roots hold all function definitions. // for single file shaders this should hold. // Todo: Add solution for multiple files compiled in one shader. { TIntermAggregate *aggregate; TIntermSequence sequence; TIntermSequence::iterator sit; // Root must be aggregate if (!(aggregate = root->getAsAggregate())) { return NULL; } if (aggregate->getOp() == EOpFunction) { // do not stop search at function prototypes if (aggregate->getSequence().size() != 0) { if (!strcmp(sig, aggregate->getName().c_str())) { return aggregate; } } } else { sequence = aggregate->getSequence(); for (sit = sequence.begin(); sit != sequence.end(); sit++) { if ((*sit)->getAsAggregate() && (*sit)->getAsAggregate()->getOp() == EOpFunction) { // do not stop search at function prototypes if ((*sit)->getAsAggregate()->getSequence().size() != 0) { if (!strcmp(sig, (*sit)->getAsAggregate()->getName().c_str())) { return *sit; } } } } } return NULL; }
// // Merge the function bodies and global-level initializers from unitGlobals into globals. // Will error check duplication of function bodies for the same signature. // void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals) { // TODO: link-time performance: Processing in alphabetical order will be faster // Error check the global objects, not including the linker objects for (unsigned int child = 0; child < globals.size() - 1; ++child) { for (unsigned int unitChild = 0; unitChild < unitGlobals.size() - 1; ++unitChild) { TIntermAggregate* body = globals[child]->getAsAggregate(); TIntermAggregate* unitBody = unitGlobals[unitChild]->getAsAggregate(); if (body && unitBody && body->getOp() == EOpFunction && unitBody->getOp() == EOpFunction && body->getName() == unitBody->getName()) { error(infoSink, "Multiple function bodies in multiple compilation units for the same signature in the same stage:"); infoSink.info << " " << globals[child]->getAsAggregate()->getName() << "\n"; } } } // Merge the global objects, just in front of the linker objects globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1); }