summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp198
-rw-r--r--source/slang/ir-insts.h11
-rw-r--r--source/slang/ir-legalize-types.cpp67
-rw-r--r--source/slang/ir-ssa.cpp21
-rw-r--r--source/slang/ir.cpp8
-rw-r--r--source/slang/ir.h1
-rw-r--r--source/slang/legalize-types.cpp5
-rw-r--r--source/slang/lower-to-ir.cpp111
8 files changed, 411 insertions, 11 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index 9f9a089c8..4ed7dd5a7 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -136,6 +136,14 @@ struct SharedEmitContext
// How far are we indented?
Int indentLevel = 0;
+
+ // Map a string name to the number of times we have seen this
+ // name used so far during code emission.
+ Dictionary<String, UInt> uniqueNameCounters;
+
+ // Map an IR instruction to the name that we've decided
+ // to use for it when emitting code.
+ Dictionary<IRInst*, String> mapInstToName;
};
struct EmitContext
@@ -1895,8 +1903,128 @@ struct EmitVisitor
return id;
}
- String getIRName(
- IRInst* inst)
+ /// "Scrub" a name so that it complies with restrictions of the target language.
+ String scrubName(
+ String const& name)
+ {
+ // We will use a plain `U` as a dummy character to insert
+ // whenever we need to insert things to make a string into
+ // valid name.
+ //
+ char const* dummyChar = "U";
+
+ // Special case a name that is the empty string, just in case.
+ if(name.Length() == 0)
+ return dummyChar;
+
+ // Otherwise, we are going to walk over the name byte by byte
+ // and write some legal characters to the output as we go.
+ StringBuilder sb;
+
+ if(getTarget(context) == CodeGenTarget::GLSL)
+ {
+ // GLSL reserverse all names that start with `gl_`,
+ // so if we are in danger of collision, then make
+ // our name start with a dummy character instead.
+ if(name.StartsWith("gl_"))
+ {
+ sb.append(dummyChar);
+ }
+ }
+
+ // We will also detect user-defined names that
+ // might overlap with our convention for mangled names,
+ // to avoid an possible collision.
+ if(name.StartsWith("_S"))
+ {
+ sb.Append(dummyChar);
+ }
+
+ // TODO: This is where we might want to consult
+ // a dictionary of reserved words for the chosen target
+ //
+ // if(isReservedWord(name)) { sb.Append(dummyChar); }
+ //
+
+ // We need to track the previous byte in
+ // order to detect consecutive underscores for GLSL.
+ int prevChar = -1;
+
+ for(auto c : name)
+ {
+ // We will treat a dot character just like an underscore
+ // for the purposes of producing a scrubbed name, so
+ // that we translate `SomeType.someMethod` into
+ // `SomeType_someMethod`.
+ //
+ // By handling this case at the top of this loop, we
+ // ensure that a `.`-turned-`_` is handled just like
+ // a `_` in the original name, and will be properly
+ // scrubbed for GLSL output.
+ //
+ if(c == '.')
+ {
+ c = '_';
+ }
+
+ if(((c >= 'a') && (c <= 'z'))
+ || ((c >= 'A') && (c <= 'Z')))
+ {
+ // Ordinary ASCII alphabetic characters are assumed
+ // to always be okay.
+ }
+ else if((c >= '0') && (c <= '9'))
+ {
+ // We don't want to allow a digit as the first
+ // byte in a name, since the result wouldn't
+ // be a valid identifier in many target languages.
+ if(prevChar == -1)
+ {
+ sb.append(dummyChar);
+ }
+ }
+ else if(c == '_')
+ {
+ // We will collapse any consecutive sequence of `_`
+ // characters into a single one (this means that
+ // some names that were unique in the original
+ // code might not resolve to unique names after
+ // scrubbing, but that was true in general).
+
+ if(prevChar == '_')
+ {
+ // Skip this underscore, so we don't output
+ // more than one in a row.
+ continue;
+ }
+ }
+ else
+ {
+ // If we run into a character that wouldn't normally
+ // be allowed in an identifier, we need to translate
+ // it into something that *is* valid.
+ //
+ // Our solution for now will be very clumsy: we will
+ // emit `x` and then the hexadecimal version of
+ // the byte we were given.
+ sb.append("x");
+ sb.append(uint32_t((unsigned char) c), 16);
+
+ // We don't want to apply the default handling below,
+ // so skip to the top of the loop now.
+ prevChar = c;
+ continue;
+ }
+
+ sb.append(c);
+ prevChar = c;
+ }
+
+ return sb.ProduceString();
+ }
+
+ String generateIRName(
+ IRInst* inst)
{
// If the instruction names something
// that should be emitted as a target intrinsic,
@@ -1906,6 +2034,58 @@ struct EmitVisitor
return intrinsicDecoration->definition;
}
+ // If we have a name hint on the instruction, then we will try to use that
+ // to provide the actual name in the output code.
+ //
+ // We need to be careful that the name follows the rules of the target language,
+ // so there is a "scrubbing" step that needs to be applied here.
+ //
+ // We also need to make sure that the name won't collide with other declarations
+ // that might have the same name hint applied, so we will still unique
+ // them by appending the numeric ID of the instruction.
+ //
+ // TODO: Find cases where we can drop the suffix safely.
+ //
+ // TODO: When we start having to handle symbols with external linkage for
+ // things like DXIL libraries, we will need to *not* use the friendly
+ // names for stuff that should be link-able.
+ //
+ if(auto nameHintDecoration = inst->findDecoration<IRNameHintDecoration>())
+ {
+ // The name we output will basically be:
+ //
+ // <nameHint>_<uniqueID>
+ //
+ // Except that we will "scrub" the name hint first,
+ // and we will omit the underscore if the (scrubbed)
+ // name hint already ends with one.
+ //
+
+ String nameHint = nameHintDecoration->name->text;
+ nameHint = scrubName(nameHint);
+
+ StringBuilder sb;
+ sb.append(nameHint);
+
+ // Avoid introducing a double underscore
+ if(!nameHint.EndsWith("_"))
+ {
+ sb.append("_");
+ }
+
+ String key = sb.ProduceString();
+ UInt count = 0;
+ context->shared->uniqueNameCounters.TryGetValue(key, count);
+
+ context->shared->uniqueNameCounters[key] = count+1;
+
+ sb.append(count);
+ return sb.ProduceString();
+ }
+
+
+
+
// If the instruction has a mangled name, then emit using that.
if (auto globalValue = as<IRGlobalValue>(inst))
{
@@ -1925,9 +2105,23 @@ struct EmitVisitor
StringBuilder sb;
sb << "_S";
sb << getID(inst);
+
+
return sb.ProduceString();
}
+ String getIRName(
+ IRInst* inst)
+ {
+ String name;
+ if(!context->shared->mapInstToName.TryGetValue(inst, name))
+ {
+ name = generateIRName(inst);
+ context->shared->mapInstToName.Add(inst, name);
+ }
+ return name;
+ }
+
struct IRDeclaratorInfo
{
enum class Flavor
diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h
index 22685f316..804c393c2 100644
--- a/source/slang/ir-insts.h
+++ b/source/slang/ir-insts.h
@@ -121,6 +121,17 @@ struct IRInterpolationModeDecoration : IRDecoration
IRInterpolationMode mode;
};
+/// A decoration that provides a desired name to be used
+/// in conjunction with the given instruction. Back-end
+/// code generation may use this to help derive symbol
+/// names, emit debug information, etc.
+struct IRNameHintDecoration : IRDecoration
+{
+ enum { kDecorationOp = kIRDecorationOp_NameHint };
+
+ Name* name;
+};
+
//
// An IR node to represent a reference to an AST-level
diff --git a/source/slang/ir-legalize-types.cpp b/source/slang/ir-legalize-types.cpp
index 25bd498b8..3465662f3 100644
--- a/source/slang/ir-legalize-types.cpp
+++ b/source/slang/ir-legalize-types.cpp
@@ -117,6 +117,7 @@ static LegalVal declareVars(
LegalType type,
TypeLayout* typeLayout,
LegalVarChain* varChain,
+ String const* nameHint,
IRGlobalNameInfo* globalNameInfo);
static LegalType legalizeType(
@@ -708,6 +709,15 @@ RefPtr<VarLayout> findVarLayout(IRInst* value)
return nullptr;
}
+static String const* findNameHint(IRInst* inst)
+{
+ if( auto nameHintDecoration = inst->findDecoration<IRNameHintDecoration>() )
+ {
+ return &nameHintDecoration->name->text;
+ }
+ return nullptr;
+}
+
static LegalVal legalizeLocalVar(
IRTypeLegalizationContext* context,
IRVar* irLocalVar)
@@ -763,7 +773,8 @@ static LegalVal legalizeLocalVar(
varChain = &varChainStorage;
}
- LegalVal newVal = declareVars(context, kIROp_Var, legalValueType, typeLayout, varChain, nullptr);
+ String const* nameHint = findNameHint(irLocalVar);
+ LegalVal newVal = declareVars(context, kIROp_Var, legalValueType, typeLayout, varChain, nameHint, nullptr);
// Remove the old local var.
irLocalVar->removeFromParent();
@@ -794,7 +805,8 @@ static LegalVal legalizeParam(
context->insertBeforeParam = originalParam;
- auto newVal = declareVars(context, kIROp_Param, legalParamType, nullptr, nullptr, nullptr);
+ String const* nameHint = findNameHint(originalParam);
+ auto newVal = declareVars(context, kIROp_Param, legalParamType, nullptr, nullptr, nameHint, nullptr);
originalParam->removeFromParent();
context->replacedInstructions.Add(originalParam);
@@ -996,12 +1008,25 @@ static LegalVal legalizeFunc(
return LegalVal::simple(irFunc);
}
+static void addNameHint(
+ IRTypeLegalizationContext* context,
+ IRInst* inst,
+ String const& text)
+{
+ if(text.Length() == 0)
+ return;
+
+ auto name = context->session->getNameObj(text);
+ context->builder->addDecoration<IRNameHintDecoration>(inst)->name = name;
+}
+
static LegalVal declareSimpleVar(
IRTypeLegalizationContext* context,
IROp op,
IRType* type,
TypeLayout* typeLayout,
LegalVarChain* varChain,
+ String const* nameHint,
IRGlobalNameInfo* globalNameInfo)
{
RefPtr<VarLayout> varLayout = createVarLayout(varChain, typeLayout);
@@ -1087,17 +1112,23 @@ static LegalVal declareSimpleVar(
{
builder->addHighLevelDeclDecoration(irVar, varDeclRef.getDecl());
}
+
+ if( nameHint )
+ {
+ addNameHint(context, irVar, *nameHint);
+ }
}
return legalVarVal;
}
static LegalVal declareVars(
- IRTypeLegalizationContext* context,
+ IRTypeLegalizationContext* context,
IROp op,
LegalType type,
TypeLayout* typeLayout,
LegalVarChain* varChain,
+ String const* nameHint,
IRGlobalNameInfo* globalNameInfo)
{
switch (type.flavor)
@@ -1106,7 +1137,7 @@ static LegalVal declareVars(
return LegalVal();
case LegalType::Flavor::simple:
- return declareSimpleVar(context, op, type.getSimple(), typeLayout, varChain, globalNameInfo);
+ return declareSimpleVar(context, op, type.getSimple(), typeLayout, varChain, nameHint, globalNameInfo);
break;
case LegalType::Flavor::implicitDeref:
@@ -1120,6 +1151,7 @@ static LegalVal declareVars(
type.getImplicitDeref()->valueType,
getDerefTypeLayout(typeLayout),
varChain,
+ nameHint,
globalNameInfo);
return LegalVal::implicitDeref(val);
}
@@ -1128,8 +1160,8 @@ static LegalVal declareVars(
case LegalType::Flavor::pair:
{
auto pairType = type.getPair();
- auto ordinaryVal = declareVars(context, op, pairType->ordinaryType, typeLayout, varChain, globalNameInfo);
- auto specialVal = declareVars(context, op, pairType->specialType, typeLayout, varChain, globalNameInfo);
+ auto ordinaryVal = declareVars(context, op, pairType->ordinaryType, typeLayout, varChain, nameHint, globalNameInfo);
+ auto specialVal = declareVars(context, op, pairType->specialType, typeLayout, varChain, nameHint, globalNameInfo);
return LegalVal::pair(ordinaryVal, specialVal, pairType->pairInfo);
}
@@ -1158,12 +1190,28 @@ static LegalVal declareVars(
newVarChain = &newVarChainStorage;
}
+ String* fieldNameHint = nullptr;
+ String joinedNameHintStorage;
+ if( nameHint )
+ {
+ if( auto fieldNameHintDecoration = ee.key->findDecoration<IRNameHintDecoration>() )
+ {
+ joinedNameHintStorage.append(*nameHint);
+ joinedNameHintStorage.append(".");
+ joinedNameHintStorage.append(fieldNameHintDecoration->name->text);
+
+ fieldNameHint = &joinedNameHintStorage;
+ }
+
+ }
+
LegalVal fieldVal = declareVars(
context,
op,
ee.type,
fieldTypeLayout,
newVarChain,
+ fieldNameHint,
globalNameInfo);
TuplePseudoVal::Element element;
@@ -1222,7 +1270,8 @@ static LegalVal legalizeGlobalVar(
globalNameInfo.globalVar = irGlobalVar;
globalNameInfo.counter = 0;
- LegalVal newVal = declareVars(context, kIROp_GlobalVar, legalValueType, typeLayout, varChain, &globalNameInfo);
+ String const* nameHint = findNameHint(irGlobalVar);
+ LegalVal newVal = declareVars(context, kIROp_GlobalVar, legalValueType, typeLayout, varChain, nameHint, &globalNameInfo);
// Register the new value as the replacement for the old
registerLegalizedValue(context, irGlobalVar, newVal);
@@ -1263,7 +1312,9 @@ static LegalVal legalizeGlobalConstant(
globalNameInfo.counter = 0;
// TODO: need to handle initializer here!
- LegalVal newVal = declareVars(context, kIROp_GlobalConstant, legalValueType, nullptr, nullptr, &globalNameInfo);
+
+ String const* nameHint = findNameHint(irGlobalConstant);
+ LegalVal newVal = declareVars(context, kIROp_GlobalConstant, legalValueType, nullptr, nullptr, nameHint, &globalNameInfo);
// Register the new value as the replacement for the old
registerLegalizedValue(context, irGlobalConstant, newVal);
diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp
index e97298969..6c4cfa8ff 100644
--- a/source/slang/ir-ssa.cpp
+++ b/source/slang/ir-ssa.cpp
@@ -350,6 +350,24 @@ IRInst* readVar(
SSABlockInfo* blockInfo,
IRVar* var);
+/// Try to take any name hint on `var` and apply it to `val`.
+///
+/// Doesn't do anything if `val` already has a name hint,
+/// or if `var` doesn't have one to transfer over.
+///
+void maybeApplyNameHint(
+ ConstructSSAContext* context,
+ IRVar* var,
+ IRInst* val)
+{
+ if( auto nameHint = var->findDecoration<IRNameHintDecoration>() )
+ {
+ if( !val->findDecoration<IRNameHintDecoration>() )
+ {
+ context->getBuilder()->addDecoration<IRNameHintDecoration>(val)->name = nameHint->name;
+ }
+ }
+}
// Add a phi node to represent the given variable
PhiInfo* addPhi(
@@ -365,6 +383,7 @@ PhiInfo* addPhi(
valueType = context->getBuilder()->getRateQualifiedType(rate, valueType);
}
IRParam* phi = builder->createParam(valueType);
+ maybeApplyNameHint(context, var, phi);
RefPtr<PhiInfo> phiInfo = new PhiInfo();
context->phiInfos.Add(phi, phiInfo);
@@ -755,6 +774,8 @@ void processBlock(
// block.
auto val = readVar(context, blockInfo, var);
+ maybeApplyNameHint(context, var, val);
+
val = applyAccessChain(context, &blockInfo->builder, ptrArg, val);
// We can just replace all uses of this
diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp
index 53050b6b9..f8ca54639 100644
--- a/source/slang/ir.cpp
+++ b/source/slang/ir.cpp
@@ -4713,6 +4713,14 @@ namespace Slang
}
break;
+ case kIRDecorationOp_NameHint:
+ {
+ auto originalDecoration = (IRNameHintDecoration*)dd;
+ auto newDecoration = context->builder->addDecoration<IRNameHintDecoration>(clonedValue);
+ newDecoration->name = originalDecoration->name;
+ }
+ break;
+
default:
// Don't clone any decorations we don't understand.
break;
diff --git a/source/slang/ir.h b/source/slang/ir.h
index 4a393cae0..5d9948b70 100644
--- a/source/slang/ir.h
+++ b/source/slang/ir.h
@@ -125,6 +125,7 @@ enum IRDecorationOp : uint16_t
kIRDecorationOp_GLSLOuterArray,
kIRDecorationOp_Semantic,
kIRDecorationOp_InterpolationMode,
+ kIRDecorationOp_NameHint,
};
// represents an object allocated in an IR memory pool
diff --git a/source/slang/legalize-types.cpp b/source/slang/legalize-types.cpp
index 6922a5174..bbfa6264d 100644
--- a/source/slang/legalize-types.cpp
+++ b/source/slang/legalize-types.cpp
@@ -341,6 +341,11 @@ struct TupleTypeBuilder
ordinaryStructType->sourceLoc = originalStructType->sourceLoc;
ordinaryStructType->mangledName = originalStructType->mangledName;
+ if(auto nameHintDecoration = originalStructType->findDecoration<IRNameHintDecoration>())
+ {
+ builder->addDecoration<IRNameHintDecoration>(ordinaryStructType)->name = nameHintDecoration->name;
+ }
+
// The new struct type will appear right after the original in the IR,
// so that we can be sure any instruction that could reference the
// original can also reference the new one.
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 2d5f169f3..ea82e4b70 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1232,7 +1232,92 @@ void maybeSetRate(
}
}
+static Name* getNameForNameHint(
+ IRGenContext* context,
+ Decl* decl)
+{
+ // We will use a bit of an ad hoc convention here for now.
+
+ Name* leafName = decl->getName();
+
+ // Handle custom name for a global parameter group (e.g., a `cbuffer`)
+ if(auto reflectionNameModifier = decl->FindModifier<ParameterGroupReflectionName>())
+ {
+ leafName = reflectionNameModifier->nameAndLoc.name;
+ }
+
+ // There is no point in trying to provide a name hint for something with no name,
+ // or with an empty name
+ if(!leafName)
+ return nullptr;
+ if(leafName->text.Length() == 0)
+ return nullptr;
+
+
+ if(auto varDecl = dynamic_cast<VarDeclBase*>(decl))
+ {
+ // For an ordinary local variable, global variable,
+ // parameter, or field, we will just use the name
+ // as declared, and now work in anything from
+ // its parent declaration(s).
+ //
+ // TODO: consider whether global/static variables should
+ // follow different rules.
+ //
+ return leafName;
+ }
+
+ // For other cases of declaration, we want to consider
+ // merging its name with the name of its parent declaration.
+ auto parentDecl = decl->ParentDecl;
+
+ // Skip past a generic parent, if we are a declaration nested in a generic.
+ if(auto genericParentDecl = dynamic_cast<GenericDecl*>(parentDecl))
+ parentDecl = genericParentDecl->ParentDecl;
+
+ auto parentName = getNameForNameHint(context, parentDecl);
+ if(!parentName)
+ {
+ return leafName;
+ }
+
+ // TODO: at some point we will start giving `ModuleDecl`s names,
+ // and in that case we need to think carefully about whether to
+ // include their names here or not.
+ // We will now construct a new `Name` to use as the hint,
+ // combining the name of the parent and the leaf declaration.
+
+ StringBuilder sb;
+ sb.append(parentName->text);
+ sb.append(".");
+ sb.append(leafName->text);
+
+ return context->getSession()->getNameObj(sb.ProduceString());
+}
+
+/// Try to add an appropriate name hint to the instruction,
+/// that can be used for back-end code emission or debug info.
+static void addNameHint(
+ IRGenContext* context,
+ IRInst* inst,
+ Decl* decl)
+{
+ Name* name = getNameForNameHint(context, decl);
+ if(!name)
+ return;
+ context->irBuilder->addDecoration<IRNameHintDecoration>(inst)->name = name;
+}
+
+/// Add a name hint based on a fixed string.
+static void addNameHint(
+ IRGenContext* context,
+ IRInst* inst,
+ char const* text)
+{
+ Name* name = context->getSession()->getNameObj(text);
+ context->irBuilder->addDecoration<IRNameHintDecoration>(inst)->name = name;
+}
LoweredValInfo createVar(
IRGenContext* context,
@@ -1249,6 +1334,8 @@ LoweredValInfo createVar(
addVarDecorations(context, irAlloc, decl);
builder->addHighLevelDeclDecoration(irAlloc, decl);
+
+ addNameHint(context, irAlloc, decl);
}
return LoweredValInfo::ptr(irAlloc);
@@ -3406,6 +3493,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
globalVal = LoweredValInfo::ptr(irGlobal);
}
irGlobal->mangledName = context->getSession()->getNameObj(getMangledName(decl));
+ addNameHint(context, irGlobal, decl);
maybeSetRate(context, irGlobal, decl);
@@ -3605,6 +3693,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
subContext->irBuilder = subBuilder;
IRStructType* irStruct = subBuilder->createStructType();
+ addNameHint(context, irStruct, decl);
setMangledName(irStruct, getMangledName(decl));
@@ -3664,6 +3753,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto builder = getBuilder();
auto irFieldKey = builder->createStructKey();
+ addNameHint(context, irFieldKey, fieldDecl);
addVarDecorations(context, irFieldKey, fieldDecl);
@@ -4074,12 +4164,14 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// TODO: use a `TypeKind` to represent the
// classifier of the parameter.
auto param = subBuilder->emitParam(nullptr);
+ addNameHint(context, param, typeParamDecl);
setValue(subContext, typeParamDecl, LoweredValInfo::simple(param));
}
else if (auto valDecl = member.As<GenericValueParamDecl>())
{
auto paramType = lowerType(subContext, valDecl->getType());
auto param = subBuilder->emitParam(paramType);
+ addNameHint(context, param, valDecl);
setValue(subContext, valDecl, LoweredValInfo::simple(param));
}
}
@@ -4092,6 +4184,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// TODO: use a `WitnessTableKind` to represent the
// classifier of the parameter.
auto param = subBuilder->emitParam(nullptr);
+ addNameHint(context, param, constraintDecl);
setValue(subContext, constraintDecl, LoweredValInfo::simple(param));
}
}
@@ -4172,6 +4265,18 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
}
}
+ void addParamNameHint(IRInst* inst, ParameterInfo info)
+ {
+ if(auto decl = info.decl)
+ {
+ addNameHint(context, inst, decl);
+ }
+ else if( info.isThisParam )
+ {
+ addNameHint(context, inst, "this");
+ }
+ }
+
LoweredValInfo lowerFuncDecl(FunctionDeclBase* decl)
{
// We are going to use a nested builder, because we will
@@ -4221,6 +4326,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// need to create an IR function here
IRFunc* irFunc = subBuilder->createFunc();
+ addNameHint(context, irFunc, decl);
setMangledName(irFunc, getMangledName(decl));
@@ -4335,6 +4441,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
{
subBuilder->addHighLevelDeclDecoration(irParamPtr, paramDecl);
}
+ addParamNameHint(irParamPtr, paramInfo);
paramVal = LoweredValInfo::ptr(irParamPtr);
@@ -4361,6 +4468,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
{
subBuilder->addHighLevelDeclDecoration(irParam, paramDecl);
}
+ addParamNameHint(irParam, paramInfo);
paramVal = LoweredValInfo::simple(irParam);
//
// HLSL allows a function parameter to be used as a local
@@ -4416,7 +4524,8 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
{
// Add the IR parameter for the new value
IRType* irParamType = irResultType;
- subBuilder->emitParam(irParamType);
+ auto irParam = subBuilder->emitParam(irParamType);
+ addNameHint(context, irParam, "newValue");
// TODO: we need some way to wire this up to the `newValue`
// or whatever name we give for that parameter inside