diff options
| -rw-r--r-- | source/slang/emit.cpp | 144 | ||||
| -rw-r--r-- | source/slang/mangle.cpp | 12 |
2 files changed, 147 insertions, 9 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index d95946204..7e4fca4e5 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -4677,7 +4677,7 @@ emitDeclImpl(decl, nullptr); if(c == '0') return 0; - int count = 0; + UInt count = 0; for(;;) { count = count*10 + c - '0'; @@ -4689,18 +4689,117 @@ emitDeclImpl(decl, nullptr); } } + void readGenericParam() + { + switch(peek()) + { + case 'T': + get(); + break; + + default: + SLANG_UNEXPECTED("bad name mangling"); + break; + } + } + + void readGenericParams() + { + expect("g"); + UInt paramCount = readCount(); + for(UInt pp = 0; pp < paramCount; pp++) + { + readGenericParam(); + } + } + + void readSimpleIntVal() + { + int c = peek(); + if(isDigit(c)) + { + get(); + } + else + { + readVal(); + } + } + + void readType() + { + int c = peek(); + switch(c) + { + case 'V': + case 'b': + case 'i': + case 'u': + case 'U': + case 'h': + case 'f': + case 'd': + get(); + break; + + case 'v': + get(); + readSimpleIntVal(); + readType(); + break; + + default: + // TODO: need to read a named type + // here... + break; + } + } + + void readVal() + { + // TODO: handle other cases here + readType(); + } + + void readGenericArg() + { + readVal(); + } + + void readGenericArgs() + { + expect("G"); + UInt argCount = readCount(); + for(UInt aa = 0; aa < argCount; aa++) + { + readGenericArg(); + } + } + UnownedStringSlice readSimpleName() { UnownedStringSlice result; for(;;) { int c = peek(); + + if(c == 'g') + { + readGenericParams(); + continue; + } + else if(c == 'G') + { + readGenericArgs(); + continue; + } + if(!isDigit((char)c)) return result; // Read the length part - int count = readCount(); - if(count > (end_ - cursor_)) + UInt count = readCount(); + if(count > UInt(end_ - cursor_)) { SLANG_UNEXPECTED("bad name mangling"); UNREACHABLE_RETURN(result); @@ -4710,6 +4809,12 @@ emitDeclImpl(decl, nullptr); cursor_ += count; } } + + UInt readParamCount() + { + expect("p"); + return readCount(); + } }; void emitIntrinsicCallExpr( @@ -4726,16 +4831,37 @@ emitDeclImpl(decl, nullptr); auto name = um.readSimpleName(); - // TODO: need to detect if name represents - // a member function, etc. + // The mangled function name currently records + // the number of explicit parameters, and thus + // doesn't include the implicit `this` parameter. + // We can compare the argument and parameter counts + // to figure out whether we have a member function call. + UInt paramCount = um.readParamCount(); + + // For a call with N arguments, the instruction will + // have N+1 operands. + UInt operandCount = inst->getArgCount(); + UInt argCount = operandCount - 1; + UInt operandIndex = 1; + + if(argCount != paramCount) + { + // Looks like a member function call + emit("("); + emitIROperand(ctx, inst->getArg(operandIndex)); + emit(")."); + + operandIndex++; + } emit(name); emit("("); - UInt argCount = inst->getArgCount(); - for( UInt aa = 1; aa < argCount; ++aa ) + bool first = true; + for(; operandIndex < operandCount; ++operandIndex ) { - if(aa != 1) emit(", "); - emitIROperand(ctx, inst->getArg(aa)); + if(!first) emit(", "); + emitIROperand(ctx, inst->getArg(operandIndex)); + first = false; } emit(")"); } diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index b9fba6380..dca48f671 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -152,6 +152,18 @@ namespace Slang // value, so we certainly don't want to include // it in the mangling. } + else if( auto genericParamIntVal = dynamic_cast<GenericParamIntVal*>(val) ) + { + // TODO: we shouldn't be including the names of generic parameters + // anywhere in mangled names, since changing parameter names + // shouldn't break binary compatibility. + // + // The right solution in the long term is for generic parameters + // (both types and values) to be mangled in terms of their + // "depth" (how many outer generics) and "index" (which + // parameter are they at the specified depth). + emitName(context, genericParamIntVal->declRef.GetName()); + } else { SLANG_UNEXPECTED("unimplemented case in mangling"); |
