Ejemplo n.º 1
0
static void writeAnnotatedConstructorType(A2PWriter writer, A2PType constructorType){
	A2PConstructorType t = (A2PConstructorType) constructorType->theType;
	char *name = t->name;
        int nameLength = dataArraySize(name);
	HTHashtable hashtable = t->declaredAnnotations;
	HTIterator iterator = HTcreateIterator(hashtable);
	int nrOfAnnotations = HTsize(hashtable);
	HTEntry *nextAnnotation;

        writeByteToBuffer(writer->buffer, PDB_ANNOTATED_CONSTRUCTOR_TYPE_HEADER);

        printInteger(writer->buffer, nameLength);
        writeDataToBuffer(writer->buffer, name, nameLength);

        writeType(writer, t->children);

        writeType(writer, t->adt);
	
	printInteger(writer->buffer, nrOfAnnotations);
	
	while((nextAnnotation = HTgetNext(iterator)) != NULL){
		char *label = (char*) nextAnnotation->key;
		int labelLength = dataArraySize(label);
		
		printInteger(writer->buffer, labelLength);
		writeDataToBuffer(writer->buffer, label, labelLength);
		
		writeType(writer, (A2PType) nextAnnotation->value);
	}
}
Ejemplo n.º 2
0
static void writeTupleType(A2PWriter writer, A2PType tupleType){
	A2PTupleType t = (A2PTupleType) tupleType->theType;
	A2PType *fieldTypes = t->fieldTypes;
	char **fieldNames = t->fieldNames;
	int nrOfFields = typeArraySize(fieldTypes);
	int hasFieldNames = (fieldNames == NULL) ? 0 : 1;
	int i;
	
	if(hasFieldNames == 0){
		writeByteToBuffer(writer->buffer, PDB_TUPLE_TYPE_HEADER);
		
		printInteger(writer->buffer, nrOfFields);
		
		for(i = 0; i < nrOfFields; i++){
			writeType(writer, t->fieldTypes[i]);
		}
	}else{
		writeByteToBuffer(writer->buffer, PDB_TUPLE_TYPE_HEADER | PDB_HAS_FIELD_NAMES);
		
		printInteger(writer->buffer, nrOfFields);
		
		for(i = 0; i < nrOfFields; i++){
			char *fieldName = fieldNames[i];
			int fieldNameLength = dataArraySize(fieldName);
			
			writeType(writer, t->fieldTypes[i]);
			
			printInteger(writer->buffer, fieldNameLength);
			writeDataToBuffer(writer->buffer, fieldName, fieldNameLength);
		}
	}
}
Ejemplo n.º 3
0
//------------------------------------------------------------
// BinaryWriter
//------------------------------------------------------------
void BinaryWriter::writeString(const XCHAR * pszStr)
{
    if (pszStr)
    {
        // Not text? append a null at the end.
        if (!m_pTextEncoding->isNeedConvert()) {
            int32 nLen = _tcslen(pszStr);
            writeType(nLen);
            write(pszStr, nLen * sizeof(XCHAR));
        }
        else
        {
            ByteBuffer buf;
            m_pTextEncoding->getBytes(buf, pszStr);
            if (buf.getLength() > 0) {
                writeType(buf.getLength());
                write(buf.base(), buf.getLength());
            }
        }
    }
    else
    {
        writeType<XCHAR>(0);
    }
}
Ejemplo n.º 4
0
static void writeMapType(A2PWriter writer, A2PType mapType){
	A2PMapType t = (A2PMapType) mapType->theType;
	
	writeByteToBuffer(writer->buffer, PDB_MAP_TYPE_HEADER);
	
	writeType(writer, t->keyType);
	writeType(writer, t->valueType);
}
Ejemplo n.º 5
0
static void writeAliasType(A2PWriter writer, A2PType aliasType){
	A2PAliasType t = (A2PAliasType) aliasType->theType;
	char *name = t->name;
	int nameLength = dataArraySize(name);
	
	writeByteToBuffer(writer->buffer, PDB_ALIAS_TYPE_HEADER);
	
	printInteger(writer->buffer, nameLength);
	writeDataToBuffer(writer->buffer, name, nameLength);
	
	writeType(writer, t->aliased);
	
	writeType(writer, t->parametersTuple);
}
Ejemplo n.º 6
0
static void writeConstructorType(A2PWriter writer, A2PType constructorType){
	A2PConstructorType t = (A2PConstructorType) constructorType->theType;
	char *name = t->name;
	int nameLength = dataArraySize(name);
	
	writeByteToBuffer(writer->buffer, PDB_CONSTRUCTOR_TYPE_HEADER);
	
	printInteger(writer->buffer, nameLength);
	writeDataToBuffer(writer->buffer, name, nameLength);
	
	writeType(writer, t->children);
	
	writeType(writer, t->adt);
}
Ejemplo n.º 7
0
static void writeRelationType(A2PWriter writer, A2PType relationType){
	A2PRelationType t = (A2PRelationType) relationType->theType;
	
	writeByteToBuffer(writer->buffer, PDB_RELATION_TYPE_HEADER);
	
	writeType(writer, t->tupleType);
}
Ejemplo n.º 8
0
static void writeSetType(A2PWriter writer, A2PType setType){
	A2PSetType t = (A2PSetType) setType->theType;
	
	writeByteToBuffer(writer->buffer, PDB_SET_TYPE_HEADER);
	
	writeType(writer, t->elementType);
}
Ejemplo n.º 9
0
static void writeListType(A2PWriter writer, A2PType listType){
	A2PListType t = (A2PListType) listType->theType;
	
	writeByteToBuffer(writer->buffer, PDB_LIST_TYPE_HEADER);
	
	writeType(writer, t->elementType);
}
Ejemplo n.º 10
0
void GlslSymbol::writeDecl (std::stringstream &out, bool local, bool skipUniform)
{
	switch (qual)
	{
	case EqtNone:            break;
	case EqtUniform:
		if (!skipUniform)
			out << "uniform ";
		break;
	case EqtMutableUniform:
		if (!local)
			out << "uniform ";
		break;
	case EqtConst:           out << "const ";   break;
	case EqtIn:              out << "in ";      break;
	case EqtOut:             out << "out ";     break;
	case EqtInOut:           out << "inout ";   break;
	}

	writeType (out, type, structPtr, precision);

	out << " " << (local ? mutableMangledName : mangledName);
	if (arraySize)
		out << "[" << arraySize << "]";
	
	if (local && qual == EqtMutableUniform)
		out << " = " << mangledName;

}
Ejemplo n.º 11
0
void BinWriter::writeModules(json_t *json)
{
    // modules
    json_t *module_array = json_object_get(json, "modules");

    bytes.writeInt((int)json_array_size(module_array));

    for (UTsize i = 0; i < json_array_size(module_array); i++)
    {
        json_t *jmodule = json_array_get(module_array, i);

        int itype    = poolJString(json_object_get(jmodule, "type"));
        int iname    = poolJString(json_object_get(jmodule, "name"));
        int iversion = poolJString(json_object_get(jmodule, "version"));

        bytes.writeInt(itype);
        bytes.writeInt(iname);
        bytes.writeInt(iversion);

        // types
        json_t *type_array = json_object_get(jmodule, "types");

        bytes.writeInt((int)json_array_size(type_array));

        for (UTsize j = 0; j < json_array_size(type_array); j++)
        {
            json_t *jtype = json_array_get(type_array, j);
            writeType(jtype);
        }
    }
}
Ejemplo n.º 12
0
/*!
  */
void BvhSettingNode::writeData(std::ostream* data_stream) const noexcept
{
  writeType(data_stream);
  // Write properties
  zisc::write(&bvh_type_, data_stream);
  if (parameters_)
    parameters_->writeData(data_stream);
}
Ejemplo n.º 13
0
/*!
  */
void CameraSettingNode::writeData(std::ostream* data_stream) const noexcept
{
  writeType(data_stream);

  // Write properties
  zisc::write(&type_, data_stream);
  zisc::write(&jittering_, data_stream);
  if (parameters_)
    parameters_->writeData(data_stream);
}
Ejemplo n.º 14
0
static void writeADTType(A2PWriter writer, A2PType adtType){
	A2PAbstractDataType t = (A2PAbstractDataType) adtType->theType;
	char *name = t->name;
	int nameLength = dataArraySize(name);
	
	writeByteToBuffer(writer->buffer, PDB_ADT_TYPE_HEADER);
	
	printInteger(writer->buffer, nameLength);
	writeDataToBuffer(writer->buffer, name, nameLength);
	
	writeType(writer, A2PvoidType());
}
Ejemplo n.º 15
0
static void writeParameterType(A2PWriter writer, A2PType parameterType){
	A2PParameterType t = (A2PParameterType) parameterType->theType;
	char *name = t->name;
	int nameLength = dataArraySize(name);
	
	writeByteToBuffer(writer->buffer, PDB_PARAMETER_TYPE_HEADER);
	
	printInteger(writer->buffer, nameLength);
	writeDataToBuffer(writer->buffer, name, nameLength);
	
	writeType(writer, t->bound);
}
Ejemplo n.º 16
0
/*!
  */
void GroupObjectSettingNode::writeData(std::ostream* data_stream) const noexcept
{
  writeType(data_stream);

  // Write properties
  {
    const auto& object_list = objectList();
    const uint32 size = zisc::cast<uint32>(object_list.size());
    zisc::write(&size, data_stream);
    for (const auto object : object_list)
      object->writeData(data_stream);
  }
}
Ejemplo n.º 17
0
void HlslLinker::emitMainStart(const HlslCrossCompiler* compiler, const EGlslSymbolType retType, GlslFunction* funcMain, unsigned options, bool usePrecision, std::stringstream& preamble, const std::vector<GlslSymbol*>& constants)
{
	preamble << "void main() {\n";
	
	// initialize mutable uniforms with the original uniform values
	const unsigned n_constants = constants.size();
	for (unsigned i = 0; i != n_constants; ++i) {
		GlslSymbol* s = constants[i];
		if (s->getIsMutable()) {
			s->writeDecl(preamble, GlslSymbol::kWriteDeclMutableInit);
			preamble << ";\n";
		}
	}
	
	std::string arrayInit = compiler->m_DeferredArrayInit.str();
	if (!arrayInit.empty())
	{
		const bool emit_120_arrays = (m_Target >= ETargetGLSL_120);
		const bool emit_old_arrays = !emit_120_arrays || (options & ETranslateOpEmitGLSL120ArrayInitWorkaround);
		const bool emit_both = emit_120_arrays && emit_old_arrays;
		
		if (emit_both)
			preamble << "#if defined(HLSL2GLSL_ENABLE_ARRAY_120_WORKAROUND)" << std::endl;
		preamble << arrayInit;
		if (emit_both)
			preamble << "\n#endif" << std::endl;
	}
	std::string matrixInit = compiler->m_DeferredMatrixInit.str();
	if (!matrixInit.empty())
	{
		preamble << matrixInit;
	}
	
	if (retType == EgstStruct)
	{
		GlslStruct* retStruct = funcMain->getStruct();
		assert(retStruct);
		preamble << "    " << retStruct->getName() << " xl_retval;\n";
	}
	else if (retType != EgstVoid)
	{
		preamble << "    ";
		writeType (preamble, retType, NULL, usePrecision?funcMain->getPrecision():EbpUndefined);
		preamble << " xl_retval;\n";
	}
}
Ejemplo n.º 18
0
void HlslLinker::emitOutputNonStructParam(GlslSymbol* sym, EShLanguage lang, bool usePrecision, EAttribSemantic attrSem, std::stringstream& varying, std::stringstream& preamble, std::stringstream& postamble, std::stringstream& call)
{
	std::string name, ctor;
	int pad;
	
	if (!getArgumentData( sym, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad))
	{
		//should deal with fall through cases here
		assert(0);
		infoSink.info << "Unsupported type for shader entry parameter (";
		infoSink.info << getTypeString(sym->getType()) << ")\n";
		return;
	}
	
	// For "inout" parameters, the preamble was already written so no need to do it here.
	if (sym->getQualifier() != EqtInOut)
	{
		preamble << "    ";

        // UNITY CUSTOM: for vprog output with position semantic - force highp
        TPrecision prec = usePrecision ? sym->getPrecision() : EbpUndefined;
        if(sym->hasSemantic() && usePrecision)
        {
            const char* str = sym->getSemantic().c_str();
            int         len = sym->getSemantic().length();

            extern bool IsPositionSemantics(const char* sem, int len);
            if(IsPositionSemantics(str, len))
                prec = EbpHigh;
        }

        writeType (preamble, sym->getType(), NULL,prec);
		preamble << " xlt_" << sym->getName() << ";\n";                     
	}
	
	// In vertex shader, add to varyings
	if (lang == EShLangVertex)
		AddVertexOutput (varying, m_Target, sym->getPrecision(), ctor, name);
	
	call << "xlt_" << sym->getName();
	
	postamble << "    ";
	postamble << name << " = ";
	emitSymbolWithPad (postamble, ctor, "xlt_"+sym->getName(), pad);
	postamble << ";\n";
}
Ejemplo n.º 19
0
void writeConstantConstructor( std::stringstream& out, EGlslSymbolType t, TPrecision prec, TIntermConstant *c, GlslStruct *structure = 0 )
{
	unsigned n_elems = getElements(t);
	bool construct = n_elems > 1 || structure != 0;

	if (construct) {
		writeType (out, t, structure, EbpUndefined);
		out << "(";
	}
	
	if (structure) {
		// compound type
		unsigned n_members = structure->memberCount();
		for (unsigned i = 0; i != n_members; ++i) {
			const GlslStruct::member &m = structure->getMember(i);
			if (construct && i > 0)
				out << ", ";
			writeConstantConstructor (out, m.type, m.precision, c);
		}
	} else {
		// simple type
		unsigned n_constants = c->getCount();
		for (unsigned i = 0; i != n_elems; ++i) {
			unsigned v = Min(i, n_constants - 1);
			if (construct && i > 0)
				out << ", ";
			
			switch (c->getBasicType()) {
				case EbtBool:
					out << (c->toBool(v) ? "true" : "false");
					break;
				case EbtInt:
					out << c->toInt(v);
					break;
				case EbtFloat:
					GlslSymbol::writeFloat(out, c->toFloat(v));
					break;
				default:
					assert(0);
			}
		}
	}

	if (construct)
		out << ")";
}
Ejemplo n.º 20
0
std::string GlslFunction::getPrototype() const
{
	std::stringstream out;

	writeType (out, returnType, structPtr, precision);
	out << " " << name << "( ";
	
	for (std::vector<GlslSymbol*>::const_iterator it = parameters.begin(), itEnd = parameters.end(); it != itEnd; ++it)
	{
		if (it != parameters.begin())
			out << ", ";
		(*it)->writeDecl(out,GlslSymbol::kWriteDeclDefault);
	}
	
	out << " )";

	return out.str();
}
void TypeObjectGenerator::extract(const QString &data)
{
    QDir().mkpath(m_dst);

    QMap<QString, QList<GeneratorTypes::TypeStruct> > types = extractTypes(data, "object", QString(), "types");
    QMapIterator<QString, QList<GeneratorTypes::TypeStruct> > i(types);
    while(i.hasNext())
    {
        i.next();
        const QString &name = i.key();
        const QList<GeneratorTypes::TypeStruct> &types = i.value();
        writeType(name, types);
    }

    writePri(types.keys());
    writeMainHeader(types.keys());
    writeQmlRegister(types.keys());
    copyEmbeds();
}
Ejemplo n.º 22
0
static void writeAnnotatedNodeType(A2PWriter writer, A2PType nodeType){
	A2PNodeType t = (A2PNodeType) nodeType->theType;
	HTHashtable hashtable = t->declaredAnnotations;
	HTIterator iterator = HTcreateIterator(hashtable);
        int nrOfAnnotations = HTsize(hashtable);
	HTEntry *nextAnnotation;
	
	writeByteToBuffer(writer->buffer, PDB_ANNOTATED_NODE_TYPE_HEADER);
	
	printInteger(writer->buffer, nrOfAnnotations);

        while((nextAnnotation = HTgetNext(iterator)) != NULL){
                char *label = (char*) nextAnnotation->key;
                int labelLength = dataArraySize(label);

                printInteger(writer->buffer, labelLength);
                writeDataToBuffer(writer->buffer, label, labelLength);

                writeType(writer, (A2PType) nextAnnotation->value);
        }
}
Ejemplo n.º 23
0
void HlslLinker::emitInputNonStructParam(GlslSymbol* sym, EShLanguage lang, bool usePrecision, EAttribSemantic attrSem, std::stringstream& attrib, std::stringstream& varying, std::stringstream& preamble, std::stringstream& call)
{
	std::string name, ctor;
	int pad;
	
	if (!getArgumentData (sym, lang==EShLangVertex ? EClassAttrib : EClassVarIn, name, ctor, pad))
	{
		// should deal with fall through cases here
		assert(0);
		infoSink.info << "Unsupported type for shader entry parameter (";
		infoSink.info << getTypeString(sym->getType()) << ")\n";
		return;
	}
	
	
	// In fragment shader, pass zero for POSITION inputs
	if (lang == EShLangFragment && attrSem == EAttrSemPosition)
	{
		call << ctor << "(0.0)";
		return; // noting more to do
	}
	// For "in" parameters, just call directly to the main
	else if ( sym->getQualifier() != EqtInOut )
	{
		emitSymbolWithPad (call, ctor, name, pad);
	}
	// For "inout" parameters, declare a temp and initialize it
	else
	{
		preamble << "    ";
		writeType (preamble, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
		preamble << " xlt_" << sym->getName() << " = ";
		emitSymbolWithPad (preamble, ctor, name, pad);
		preamble << ";\n";
	}

	if (!sym->outputSuppressedBy())
		emitSingleInputVariable (lang, m_Target, name, ctor, sym->getType(), sym->getPrecision(), attrib, varying);
}
Ejemplo n.º 24
0
std::string GlslStruct::getDecl() const
{
   std::stringstream out;

   out << "struct " << name << " {\n";

   for (std::vector<member>::const_iterator it = memberList.begin(); it != memberList.end(); it++) 
   {
      out << "    ";
      writeType (out, it->type, it->structType, it->precision);
      out << " " << it->name;

      if (it->arraySize > 0)
         out << "[" << it->arraySize << "]";

      out << ";\n";
   }

   out << "};\n";

   return out.str();
}
Ejemplo n.º 25
0
/*
 * Writes the stub implementation
 */
void generateStubImpl(const QString &idl, const QString &header, const QString & /*headerBase*/, const QString &filename, QDomElement de)
{
    QFile impl(filename);
    if(!impl.open(IO_WriteOnly))
        qFatal("Could not write to %s", filename.latin1());

    QTextStream str(&impl);

    str << "/****************************************************************************" << endl;
    str << "**" << endl;
    str << "** DCOP Stub Implementation created by dcopidl2cpp from " << idl << endl;
    str << "**" << endl;
    str << "** WARNING! All changes made in this file will be lost!" << endl;
    str << "**" << endl;
    str << "*****************************************************************************/" << endl;
    str << endl;

    str << "#include \"" << header << "\"" << endl;
    str << "#include <dcopclient.h>" << endl << endl;
    str << "#include <qdatastream.h>" << endl;

    QDomElement e = de.firstChild().toElement();
    for(; !e.isNull(); e = e.nextSibling().toElement())
    {
        if(e.tagName() != "CLASS")
            continue;
        QDomElement n = e.firstChild().toElement();
        Q_ASSERT(n.tagName() == "NAME");
        QString classNameBase = n.firstChild().toText().data();
        QString className_stub = classNameBase + "_stub";

        QString classNameFull = className_stub; // class name with possible namespaces prepended
                                                // namespaces will be removed from className now
        int namespace_count = 0;
        QString namespace_tmp = className_stub;
        str << endl;
        for(;;)
        {
            int pos = namespace_tmp.find("::");
            if(pos < 0)
            {
                className_stub = namespace_tmp;
                break;
            }
            str << "namespace " << namespace_tmp.left(pos) << " {" << endl;
            ++namespace_count;
            namespace_tmp = namespace_tmp.mid(pos + 2);
        }

        str << endl;

        // Write constructors
        str << className_stub << "::" << className_stub << "( const QCString& app, const QCString& obj )" << endl;
        str << "  : ";

        // Always explicitly call DCOPStub constructor, because it's virtual base class.
        // Calling other ones doesn't matter, as they don't do anything important.
        str << "DCOPStub( app, obj )" << endl;

        str << "{" << endl;
        str << "}" << endl << endl;

        str << className_stub << "::" << className_stub << "( DCOPClient* client, const QCString& app, const QCString& obj )" << endl;
        str << "  : ";

        str << "DCOPStub( client, app, obj )" << endl;

        str << "{" << endl;
        str << "}" << endl << endl;

        str << className_stub << "::" << className_stub << "( const DCOPRef& ref )" << endl;
        str << "  : ";

        str << "DCOPStub( ref )" << endl;

        str << "{" << endl;
        str << "}" << endl << endl;

        // Write marshalling code
        QDomElement s = e.firstChild().toElement();
        for(; !s.isNull(); s = s.nextSibling().toElement())
        {
            if(s.tagName() != "FUNC")
                continue;
            QDomElement r = s.firstChild().toElement();
            Q_ASSERT(r.tagName() == "TYPE");
            QString result = r.firstChild().toText().data();
            bool async = result == "ASYNC";
            if(async)
            {
                result = "void";
                str << result << " ";
            }
            else
                result = writeType(str, r);

            r = r.nextSibling().toElement();
            Q_ASSERT(r.tagName() == "NAME");
            QString funcName = r.firstChild().toText().data();
            str << className_stub << "::" << funcName << "(";

            QStringList args;
            QStringList argtypes;
            bool first = true;
            r = r.nextSibling().toElement();
            for(; !r.isNull(); r = r.nextSibling().toElement())
            {
                if(!first)
                    str << ", ";
                else
                    str << " ";
                first = false;
                Q_ASSERT(r.tagName() == "ARG");
                QDomElement a = r.firstChild().toElement();
                QString type = writeType(str, a);
                argtypes.append(type);
                args.append(QString("arg") + QString::number(args.count()));
                str << args.last();
            }
            if(!first)
                str << " ";
            str << ")";

            // const methods in a stub can't compile, they need to call setStatus()
            // if ( s.hasAttribute("qual") )
            //   str << " " << s.attribute("qual");
            str << endl;

            str << "{" << endl;


            funcName += "(";
            first = true;
            for(QStringList::Iterator it = argtypes.begin(); it != argtypes.end(); ++it)
            {
                if(!first)
                    funcName += ",";
                first = false;
                funcName += *it;
            }
            funcName += ")";

            if(async)
            {

                str << "    if ( !dcopClient()  ) {" << endl;
                str << "\tsetStatus( CallFailed );" << endl;
                str << "\treturn;" << endl;
                str << "    }" << endl;

                str << "    QByteArray data;" << endl;
                if(!args.isEmpty())
                {
                    str << "    QDataStream arg( data, IO_WriteOnly );" << endl;
                    for(QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count)
                    {
                        str << "    arg << " << *args_count << ";" << endl;
                    }
                }

                str << "    dcopClient()->send( app(), obj(), \"" << funcName << "\", data );" << endl;
                str << "    setStatus( CallSucceeded );" << endl;
            }
            else
            {

                if(result != "void")
                {
                    str << "    " << result << " result";
                    if(isIntType(result))
                        str << " = 0";
                    else if(result == "float" || result == "double")
                        str << " = 0.0";
                    else if(result == "bool")
                        str << " = false";

                    str << ";" << endl;
                }

                str << "    if ( !dcopClient()  ) {" << endl;
                str << "\tsetStatus( CallFailed );" << endl;
                if(result != "void")
                    str << "\treturn result;" << endl;
                else
                    str << "\treturn;" << endl;
                str << "    }" << endl;

                str << "    QByteArray data, replyData;" << endl;
                str << "    QCString replyType;" << endl;

                if(!args.isEmpty())
                {
                    str << "    QDataStream arg( data, IO_WriteOnly );" << endl;
                    for(QStringList::Iterator args_count = args.begin(); args_count != args.end(); ++args_count)
                    {
                        str << "    arg << " << *args_count << ";" << endl;
                    }
                }
                str << "    if ( dcopClient()->call( app(), obj(), \"" << funcName << "\",";
                str << " data, replyType, replyData ) ) {" << endl;
                if(result != "void")
                {
                    str << "\tif ( replyType == \"" << result << "\" ) {" << endl;
                    str << "\t    QDataStream _reply_stream( replyData, IO_ReadOnly );" << endl;
                    str << "\t    _reply_stream >> result;" << endl;
                    str << "\t    setStatus( CallSucceeded );" << endl;
                    str << "\t} else {" << endl;
                    str << "\t    callFailed();" << endl;
                    str << "\t}" << endl;
                }
                else
                {
                    str << "\tsetStatus( CallSucceeded );" << endl;
                }
                str << "    } else { " << endl;
                str << "\tcallFailed();" << endl;
                str << "    }" << endl;
                if(result != "void")
                    str << "    return result;" << endl;
            }
            str << "}" << endl << endl;
        }

        for(; namespace_count > 0; --namespace_count)
            str << "} // namespace" << endl;
        str << endl;
    }
    impl.close();
}
Ejemplo n.º 26
0
bool TGlslOutputTraverser::traverseDeclaration(bool preVisit, TIntermDeclaration* decl, TIntermTraverser* it) {
	TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it);
	GlslFunction *current = goit->current;
	std::stringstream& out = current->getActiveOutput();
	EGlslSymbolType symbol_type = translateType(decl->getTypePointer());
	TType& type = *decl->getTypePointer();
	
	
	bool emit_osx10_6_arrays = goit->m_EmitSnowLeopardCompatibleArrayInitializers
		&& decl->containsArrayInitialization();
	
	if (emit_osx10_6_arrays) {
		assert(decl->isSingleInitialization() && "Emission of multiple in-line array declarations isn't supported when running in OS X 10.6 compatible mode.");
		
		current->indent(out);
		out << "#if defined(OSX_SNOW_LEOPARD)" << std::endl;
		current->increaseDepth();
		
		TQualifier q = type.getQualifier();
		if (q == EvqConst)
			q = EvqTemporary;
		
		current->beginStatement();
		if (q != EvqTemporary && q != EvqGlobal)
			out << type.getQualifierString() << " ";
		
		TIntermBinary* assign = decl->getDeclaration()->getAsBinaryNode();
		TIntermSymbol* sym = assign->getLeft()->getAsSymbolNode();
		TIntermSequence& init = assign->getRight()->getAsAggregate()->getSequence();
		
		writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined);
		out << "[" << type.getArraySize() << "] " << sym->getSymbol();
		current->endStatement();
		
		unsigned n_vals = init.size();
		for (unsigned i = 0; i != n_vals; ++i) {
			current->beginStatement();
			sym->traverse(goit);
			out << "[" << i << "]" << " = ";
			init[i]->traverse(goit);
			current->endStatement();
		}
		
		current->decreaseDepth();
		current->indent(out);
		out << "#else" << std::endl;
		current->increaseDepth();
	}
	
	current->beginStatement();
	
	if (type.getQualifier() != EvqTemporary && type.getQualifier() != EvqGlobal)
		out << type.getQualifierString() << " ";
	
	if (type.getBasicType() == EbtStruct)
		out << type.getTypeName();
	else
		writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined);
	
	if (type.isArray())
		out << "[" << type.getArraySize() << "]";
	
	out << " ";
	
	decl->getDeclaration()->traverse(goit);
	
	current->endStatement();
	
	if (emit_osx10_6_arrays) {
		current->decreaseDepth();
		current->indent(out);
		out << "#endif" << std::endl;
	}
	
	return false;
}
Ejemplo n.º 27
0
bool HlslLinker::link(HlslCrossCompiler* compiler, const char* entryFunc, ETargetVersion targetVersion, unsigned options)
{
	m_Target = targetVersion;
	m_Options = options;
	m_Extensions.clear();
	if (!linkerSanityCheck(compiler, entryFunc))
		return false;
	
	const bool usePrecision = Hlsl2Glsl_VersionUsesPrecision(targetVersion);
	
	EShLanguage lang = compiler->getLanguage();
	std::string entryPoint = GetEntryName (entryFunc);
	
	
	// figure out all relevant functions
	GlslFunction* globalFunction = NULL;
	std::vector<GlslFunction*> functionList;
	FunctionSet calledFunctions;
	GlslFunction* funcMain = NULL;
	if (!buildFunctionLists(compiler, lang, entryPoint, globalFunction, functionList, calledFunctions, funcMain))
		return false;
	assert(globalFunction);
	assert(funcMain);
	
	// uniforms and used built-in functions
	std::vector<GlslSymbol*> constants;
	std::set<TOperator> libFunctions;
	buildUniformsAndLibFunctions(calledFunctions, constants, libFunctions);
	// add built-in functions possibly used by uniform initializers
	const std::set<TOperator>& referencedGlobalFunctions = globalFunction->getLibFunctions();
	libFunctions.insert (referencedGlobalFunctions.begin(), referencedGlobalFunctions.end());
	
	buildUniformReflection (constants);


	// print all the components collected above.

	emitLibraryFunctions (libFunctions, lang, usePrecision);
	emitStructs(compiler);
	emitGlobals (globalFunction, constants);
	EmitCalledFunctions (shader, calledFunctions);

	
	// Generate a main function that calls the specified entrypoint.
	// That main function uses semantics on the arguments and return values to
	// connect items appropriately.	
	
	std::stringstream attrib;
	std::stringstream uniform;
	std::stringstream preamble;
	std::stringstream postamble;
	std::stringstream varying;
	std::stringstream call;

	markDuplicatedInSemantics(funcMain);

	// Declare return value
	const EGlslSymbolType retType = funcMain->getReturnType();
	emitMainStart(compiler, retType, funcMain, m_Options, usePrecision, preamble, constants);
	

	// Call the entry point
	call << "    ";
	if (retType != EgstVoid)
		call << "xl_retval = ";
	call << funcMain->getName() << "( ";
	

	// Entry point parameters
	const int pCount = funcMain->getParameterCount();
	for (int ii=0; ii<pCount; ii++)
	{
		GlslSymbol *sym = funcMain->getParameter(ii);
		EAttribSemantic attrSem = parseAttributeSemantic( sym->getSemantic());
		
		add_extension_from_semantic(attrSem, m_Target, m_Extensions);

		switch (sym->getQualifier())
		{

		// -------- IN & OUT parameters
		case EqtIn:
		case EqtInOut:
		case EqtConst:
			if (sym->getType() != EgstStruct)
			{
				emitInputNonStructParam(sym, lang, usePrecision, attrSem, attrib, varying, preamble, call);
			}
			else
			{
				emitInputStructParam(sym, lang, attrib, varying, preamble, call);
			}

			// NOTE: for "inout" parameters need to fallthrough to the next case
			if (sym->getQualifier() != EqtInOut)
			{
				break;
			}


		// -------- OUT parameters; also fall-through for INOUT (see the check above)
		case EqtOut:

			if ( sym->getType() != EgstStruct)
			{
				emitOutputNonStructParam(sym, lang, usePrecision, attrSem, varying, preamble, postamble, call);
			}
			else
			{
				emitOutputStructParam(sym, lang, usePrecision, attrSem, varying, preamble, postamble, call);
			}
			break;

		case EqtUniform:
			uniform << "uniform ";
			writeType (uniform, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
			uniform << " xlu_" << sym->getName();
			if(sym->getArraySize())
				uniform << "[" << sym->getArraySize() << "]";
			uniform << ";\n";
			call << "xlu_" << sym->getName();
			break;

		default:
			assert(0);
		};
		if (ii != pCount -1)
			call << ", ";
	}

	call << ");\n";


	// Entry point return value
	if (!emitReturnValue(retType, funcMain, lang, varying, postamble))
		return false;

	postamble << "}\n\n";
	
	
	// Generate final code of the pieces above.
	{
		shaderPrefix << kTargetVersionStrings[targetVersion];
		ExtensionSet::const_iterator it = m_Extensions.begin(), end = m_Extensions.end();
		for (; it != end; ++it)
			shaderPrefix << "#extension " << *it << " : require" << std::endl;
	}

	EmitIfNotEmpty (shader, uniform);
	EmitIfNotEmpty (shader, attrib);
	EmitIfNotEmpty (shader, varying);

	shader << preamble.str() << "\n";
	shader << call.str() << "\n";
	shader << postamble.str() << "\n";

	return true;
}
Ejemplo n.º 28
0
		void restore() {
			writeType(address, original);
		}
Ejemplo n.º 29
0
		void patch() {
			writeType(address, replaced);
		}
Ejemplo n.º 30
0
bool HlslLinker::link(HlslCrossCompiler* compiler, const char* entryFunc, bool usePrecision)
{
	std::vector<GlslFunction*> globalList;
	std::vector<GlslFunction*> functionList;
	std::string entryPoint;
	GlslFunction* funcMain = NULL;
	FunctionSet calledFunctions;
	std::set<TOperator> libFunctions;
	std::map<std::string,GlslSymbol*> globalSymMap;
	std::map<std::string,GlslStruct*> structMap;

	if (!compiler)
	{
		infoSink.info << "No shader compiler provided\n";
		return false;
	}

	EShLanguage lang = compiler->getLanguage();

	if (!entryFunc)
	{
		infoSink.info << "No shader entry function provided\n";
		return false;
	}

	entryPoint = GetEntryName (entryFunc);

	//build the list of functions
	HlslCrossCompiler *comp = static_cast<HlslCrossCompiler*>(compiler);

	std::vector<GlslFunction*> &fl = comp->functionList;

	for ( std::vector<GlslFunction*>::iterator fit = fl.begin(); fit < fl.end(); fit++)
	{
		if ( (*fit)->getName() == "__global__")
			globalList.push_back( *fit);
		else
			functionList.push_back( *fit);

		if ((*fit)->getName() == entryPoint)
		{
			if (funcMain)
			{
				infoSink.info << kShaderTypeNames[lang] << " entry function cannot be overloaded\n";
				return false;
			}
			funcMain = *fit;
		}
	}

	// check to ensure that we found the entry function
	if (!funcMain)
	{
		infoSink.info << "Failed to find entry function: '" << entryPoint <<"'\n";
		return false;
	}

	//add all the called functions to the list
	calledFunctions.push_back (funcMain);
	if (!addCalledFunctions (funcMain, calledFunctions, functionList))
	{
		infoSink.info << "Failed to resolve all called functions in the " << kShaderTypeNames[lang] << " shader\n";
	}

	//iterate over the functions, building a global list of structure declaractions and symbols
	// assume a single compilation unit for expediency (eliminates name clashes, as type checking
	// withing a single compilation unit has been performed)
	for (FunctionSet::iterator it=calledFunctions.begin(); it != calledFunctions.end(); it++)
	{
		//get each symbol and each structure, and add them to the map
		// checking that any previous entries are equivalent
		const std::vector<GlslSymbol*> &symList = (*it)->getSymbols();

		for (std::vector<GlslSymbol*>::const_iterator cit = symList.begin(); cit < symList.end(); cit++)
		{
			if ( (*cit)->getIsGlobal())
			{
				//should check for already added ones here
				globalSymMap[(*cit)->getName()] = *cit;
			}
		}

		//take each referenced library function, and add it to the set
		const std::set<TOperator> &libSet = (*it)->getLibFunctions();

		libFunctions.insert( libSet.begin(), libSet.end());
	}


	// The following code is what is used to generate the actual shader and "main"
	// function. The process is to take all the components collected above, and
	// write them to the appropriate code stream. Finally, a main function is
	// generated that calls the specified entrypoint. That main function uses
	// semantics on the arguments and return values to connect items appropriately.

	//
	// Write Library Functions & required extensions
	std::string shaderExtensions, shaderLibFunctions;
	if (!libFunctions.empty())
	{
		for (std::set<TOperator>::iterator it = libFunctions.begin(); it != libFunctions.end(); it++)
		{
			const std::string &func = getHLSLSupportCode(*it, shaderExtensions, lang==EShLangVertex);
			if (!func.empty())
			{
				shaderLibFunctions += func;
				shaderLibFunctions += '\n';
			}
		}
	}
	shader << shaderExtensions;
	shader << shaderLibFunctions;

	//
	//Structure addition hack
	// Presently, structures are not tracked per function, just dump them all
	// This could be improved by building a complete list of structures for the
	// shaders based on the variables in each function
	//
	{
		HlslCrossCompiler *comp = static_cast<HlslCrossCompiler*>(compiler);
		std::vector<GlslStruct*> &sList = comp->structList;

		if (!sList.empty())
		{
			for (std::vector<GlslStruct*>::iterator it = sList.begin(); it < sList.end(); it++)
			{
				shader << (*it)->getDecl() << "\n";
			}
		}
	}

	//
	// Write global variables
	//

	if (!globalSymMap.empty())
	{
		for (std::map<std::string,GlslSymbol*>::iterator sit = globalSymMap.begin(); sit != globalSymMap.end(); sit++)
		{
			sit->second->writeDecl(shader,false,false);
			shader << ";\n";

			if ( sit->second->getIsMutable() )
			{
				sit->second->writeDecl(shader, true, false);
				shader << ";\n";
			}         
		}
	}

	//
	// Write function declarations and definitions
	//
	EmitCalledFunctions (shader, calledFunctions);

	// 
	// Gather the uniforms into the uniform list
	//
	for (std::map<std::string, GlslSymbol*>::iterator it = globalSymMap.begin(); it != globalSymMap.end(); it++)
	{
		if (it->second->getQualifier() != EqtUniform)
			continue;

		ShUniformInfo infoStruct;
		infoStruct.name = new char[it->first.size()+1];
		strcpy( infoStruct.name, it->first.c_str());
		if (it->second->getSemantic() != "")
		{
			infoStruct.semantic = new char[it->second->getSemantic().size()+1];
			strcpy( infoStruct.semantic, it->second->getSemantic().c_str());
		}
		else
			infoStruct.semantic = 0;

		//gigantic hack, the enumerations are kept in alignment
		infoStruct.type = (EShType)it->second->getType();
		infoStruct.arraySize = it->second->getArraySize();

		if ( it->second->hasInitializer() )
		{
			int initSize = it->second->initializerSize();
			infoStruct.init = new float[initSize];
			memcpy( infoStruct.init, it->second->getInitializer(), sizeof(float) * initSize);
		}
		else
			infoStruct.init = 0;

		//TODO: need to add annotation

		uniforms.push_back( infoStruct);
	}

	//
	// Generate the main function
	//

		std::stringstream attrib;
		std::stringstream uniform;
		std::stringstream preamble;
		std::stringstream postamble;
		std::stringstream varying;
		std::stringstream call;
		const int pCount = funcMain->getParameterCount();

		preamble << "void main() {\n";
		const EGlslSymbolType retType = funcMain->getReturnType();
		GlslStruct *retStruct = funcMain->getStruct();
		if (  retType == EgstStruct)
		{
			assert(retStruct);
			preamble << "    " << retStruct->getName() << " xl_retval;\n";
		}
		else
		{
			if ( retType != EgstVoid)
			{
				preamble << "    ";
				writeType (preamble, retType, NULL, usePrecision?funcMain->getPrecision():EbpUndefined);
				preamble << " xl_retval;\n";
			}
		}

		// Write all mutable initializations
		if ( calledFunctions.size() > 0 )
		{
			for (FunctionSet::iterator fit = calledFunctions.begin(); fit != calledFunctions.end(); fit++)
			{
				std::string mutableDecls = (*fit)->getMutableDecls(1, calledFunctions.begin(), fit);

				if ( mutableDecls.size() > 0 )
				{
					preamble << mutableDecls;
				}
			}
		}

		call << "    ";
		if (retType != EgstVoid)
			call << "xl_retval = " << funcMain->getName() << "( ";
		else
			call << funcMain->getName() << "( ";

		// pass main function parameters
		for (int ii=0; ii<pCount; ii++)
		{
			GlslSymbol *sym = funcMain->getParameter(ii);
			EAttribSemantic attrSem = parseAttributeSemantic( sym->getSemantic());

			switch (sym->getQualifier())
			{

			// -------- IN & OUT parameters
			case EqtIn:
			case EqtInOut:
				if ( sym->getType() != EgstStruct)
				{
					std::string name, ctor;
					int pad;

					if ( getArgumentData( sym, lang==EShLangVertex ? EClassAttrib : EClassVarIn, name, ctor, pad) )
					{
						// In fragment shader, pass zero for POSITION inputs
						bool ignoredPositionInFragment = false;
						if (lang == EShLangFragment && attrSem == EAttrSemPosition)
						{
							call << ctor << "(0.0)";
							ignoredPositionInFragment = true;
						}
						// For "in" parameters, just call directly to the main
						else if ( sym->getQualifier() != EqtInOut )
						{
							call << ctor << "(" << name;
							for (int ii = 0; ii<pad; ii++)
								call << ", 0.0";
							call << ")";
						}
						// For "inout" parameters, declare a temp and initialize the temp
						else
						{
							preamble << "    ";
							writeType (preamble, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
							preamble << " xlt_" << sym->getName() << " = ";
							preamble << ctor << "(" << name;
							for (int ii = 0; ii<pad; ii++)
								preamble << ", 0.0";
							preamble << ");\n";
						}

						if (lang == EShLangVertex) // vertex shader: deal with gl_ attributes
						{
							if ( strncmp( name.c_str(), "gl_", 3))
							{
								int typeOffset = 0;

								// If the type is integer or bool based, we must convert to a float based
								// type.  This is because GLSL does not allow int or bool based vertex attributes.
								if ( sym->getType() >= EgstInt && sym->getType() <= EgstInt4)
								{
									typeOffset += 4;
								}

								if ( sym->getType() >= EgstBool && sym->getType() <= EgstBool4)
								{
									typeOffset += 8;
								}

								// This is an undefined attribute
								attrib << "attribute " << getTypeString((EGlslSymbolType)(sym->getType() + typeOffset)) << " " << name << ";\n";
							}
						}

						if (lang == EShLangFragment) // deal with varyings
						{
							if (!ignoredPositionInFragment)
								AddToVaryings (varying, sym->getPrecision(), ctor, name);
						}
					}
					else
					{
						//should deal with fall through cases here
						assert(0);
						infoSink.info << "Unsupported type for shader entry parameter (";
						infoSink.info << getTypeString(sym->getType()) << ")\n";
					}
				}
				else
				{
					//structs must pass the struct, then process per element
					GlslStruct *Struct = sym->getStruct();
					assert(Struct);

					//first create the temp
					std::string tempVar = "xlt_" + sym->getName();
					preamble << "    " << Struct->getName() << " ";
					preamble << tempVar <<";\n";
					call << tempVar;

					const int elem = Struct->memberCount();
					for (int jj=0; jj<elem; jj++)
					{
						const GlslStruct::member &current = Struct->getMember(jj);
						EAttribSemantic memberSem = parseAttributeSemantic (current.semantic);
						std::string name, ctor;
						int pad;
						int numArrayElements = 1;
						bool bIsArray = false;

						// If it is an array, loop over each member
						if ( current.arraySize > 0 )
						{
							numArrayElements = current.arraySize;
							bIsArray = true;
						}

						for ( int arrayIndex = 0; arrayIndex <  numArrayElements; arrayIndex++ )
						{
							if ( getArgumentData2( current.name, current.semantic, current.type,
								lang==EShLangVertex ? EClassAttrib : EClassVarIn, name, ctor, pad, arrayIndex ) )
							{

								preamble << "    ";
								preamble << tempVar << "." << current.name;

								if ( bIsArray )
									preamble << "[" << arrayIndex << "]";

								// In fragment shader, pass zero for POSITION inputs
								bool ignoredPositionInFragment = false;
								if (lang == EShLangFragment && memberSem == EAttrSemPosition)
								{
									preamble << " = " << ctor << "(0.0);\n";
									ignoredPositionInFragment = true;
								}
								else
								{
									preamble << " = " << ctor << "( " << name;
									for (int ii = 0; ii<pad; ii++)
										preamble << ", 0.0";
									preamble << ");\n";
								}

								if (lang == EShLangVertex) // vertex shader: gl_ attributes
								{
									if ( strncmp( name.c_str(), "gl_", 3))
									{

										int typeOffset = 0;

										// If the type is integer or bool based, we must convert to a float based
										// type.  This is because GLSL does not allow int or bool based vertex attributes.
										if ( current.type >= EgstInt && current.type <= EgstInt4)
										{
											typeOffset += 4;
										}

										if ( current.type >= EgstBool && current.type <= EgstBool4)
										{
											typeOffset += 8;
										}

										// This is an undefined attribute
										attrib << "attribute " << getTypeString((EGlslSymbolType)(current.type + typeOffset)) << " " << name << ";\n";

									}
								}
								
								if (lang == EShLangFragment) // deal with varyings
								{
									if (!ignoredPositionInFragment)
										AddToVaryings (varying, current.precision, ctor, name);
								}
							}
							else
							{
								//should deal with fall through cases here
								assert(0);
								infoSink.info << "Unsupported type for struct element in shader entry parameter (";
								infoSink.info << getTypeString(current.type) << ")\n";
							}
						}
					}
				}

				//
				// NOTE: This check only breaks out of the case if we have an "in" parameter, for
				//       "inout" it will fallthrough to the next case
				//
				if ( sym->getQualifier() != EqtInOut )
				{
					break;
				}


			// -------- OUT parameters; also fall-through for INOUT (see the check above)
			case EqtOut:

				if ( sym->getType() != EgstStruct)
				{
					std::string name, ctor;
					int pad;

					if ( getArgumentData( sym, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad) )
					{
						// For "inout" parameters, the preamble was already written so no need to do it here.
						if ( sym->getQualifier() != EqtInOut )
						{
							preamble << "    ";
							writeType (preamble, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
							preamble << " xlt_" << sym->getName() << ";\n";                     
						}
						
						if (lang == EShLangVertex) // deal with varyings
						{
							AddToVaryings (varying, sym->getPrecision(), ctor, name);
						}

						call << "xlt_" << sym->getName();

						postamble << "    ";
						postamble << name << " = " << ctor << "( xlt_" <<sym->getName();
						for (int ii = 0; ii<pad; ii++)
							postamble << ", 0.0";

						postamble << ");\n";
					}
					else
					{
						//should deal with fall through cases here
						assert(0);
						infoSink.info << "Unsupported type for shader entry parameter (";
						infoSink.info << getTypeString(sym->getType()) << ")\n";
					}
				}
				else
				{
					//structs must pass the struct, then process per element
					GlslStruct *Struct = sym->getStruct();
					assert(Struct);

					//first create the temp
					std::string tempVar = "xlt_" + sym->getName();

					// For "inout" parmaeters the preamble and call were already written, no need to do it here
					if ( sym->getQualifier() != EqtInOut )
					{
						preamble << "    " << Struct->getName() << " ";
						preamble << tempVar <<";\n";
						call << tempVar;
					}

					const int elem = Struct->memberCount();
					for (int ii=0; ii<elem; ii++)
					{
						const GlslStruct::member &current = Struct->getMember(ii);
						std::string name, ctor;
						int pad;

						if ( getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, 0) )
						{
							postamble << "    ";
							postamble << name << " = " << ctor;
							postamble << "( " << tempVar << "." << current.name;
							for (int ii = 0; ii<pad; ii++)
								postamble << ", 0.0";

							postamble << ");\n";

							if (lang == EShLangVertex) // deal with varyings
							{
								AddToVaryings (varying, current.precision, ctor, name);
							}
						}
						else
						{
							//should deal with fall through cases here
							assert(0);
							infoSink.info << "Unsupported type in struct element for shader entry parameter (";
							infoSink.info << getTypeString(current.type) << ")\n";
						}
					}
				}
				break;

			case EqtUniform:
				uniform << "uniform ";
				writeType (uniform, sym->getType(), NULL, usePrecision?sym->getPrecision():EbpUndefined);
				uniform << " xlu_" << sym->getName() << ";\n";
				call << "xlu_" << sym->getName();
				break;

			default:
				assert(0);
			};
			if (ii != pCount -1)
				call << ", ";
		}

		call << ");\n";


		// -------- return value of main entry point
		if (retType != EgstVoid)
		{

			if (retType != EgstStruct)
			{
				std::string name, ctor;
				int pad;

				if ( getArgumentData2( "", funcMain->getSemantic(), retType, lang==EShLangVertex ? EClassVarOut : EClassRes,
					name, ctor, pad, 0) )
				{

					postamble << "    ";
					postamble << name << " = " << ctor << "( xl_retval";
					for (int ii = 0; ii<pad; ii++)
						postamble << ", 0.0";

					postamble << ");\n";

					if (lang == EShLangVertex) // deal with varyings
					{
						AddToVaryings (varying, funcMain->getPrecision(), ctor, name);
					}
				}
				else
				{
					//should deal with fall through cases here
					assert(0);
					infoSink.info << (lang==EShLangVertex ? "Unsupported type for shader return value (" : "Unsupported return type for shader entry function (");
					infoSink.info << getTypeString(retType) << ")\n";
				}
			}
			else
			{
				const int elem = retStruct->memberCount();
				for (int ii=0; ii<elem; ii++)
				{
					const GlslStruct::member &current = retStruct->getMember(ii);
					std::string name, ctor;
					int pad;
					int numArrayElements = 1;
					bool bIsArray = false;

					if (lang == EShLangVertex) // vertex shader
					{
						// If it is an array, loop over each member
						if ( current.arraySize > 0 )
						{
							numArrayElements = current.arraySize;
							bIsArray = true;
						}
					}

					for ( int arrayIndex = 0; arrayIndex < numArrayElements; arrayIndex++ )
					{

						if ( getArgumentData2( current.name, current.semantic, current.type, lang==EShLangVertex ? EClassVarOut : EClassRes, name, ctor, pad, arrayIndex) )
						{
							postamble << "    ";
							postamble << name;                                                            
							postamble << " = " << ctor;
							postamble << "( xl_retval." << current.name;
							if ( bIsArray )
							{
								postamble << "[" << arrayIndex << "]";
							}
							for (int ii = 0; ii<pad; ii++)
								postamble << ", 0.0";

							postamble << ");\n";

							if (lang == EShLangVertex) // deal with varyings
							{
								AddToVaryings (varying, current.precision, ctor, name);
							}
						}
						else
						{
							//should deal with fall through cases here
							//assert(0);
							infoSink.info << (lang==EShLangVertex ? "Unsupported element type in struct for shader return value (" : "Unsupported struct element type in return type for shader entry function (");
							infoSink.info << getTypeString(current.type) << ")\n";
							return false;
						}
					}
				}
			}
		}
		else
		{
			if (lang == EShLangFragment) // fragment shader
			{
				// If no return type, close off the output
				postamble << ";\n";
			}
		}

		postamble << "}\n\n";

		EmitIfNotEmpty (shader, uniform);
		EmitIfNotEmpty (shader, attrib);
		EmitIfNotEmpty (shader, varying);

		shader << preamble.str() << "\n";
		shader << call.str() << "\n";
		shader << postamble.str() << "\n";

	return true;
}