summaryrefslogtreecommitdiffstats
path: root/source/slang/mangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/mangle.cpp')
-rw-r--r--source/slang/mangle.cpp231
1 files changed, 180 insertions, 51 deletions
diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp
index ce36a97b6..71c0605a9 100644
--- a/source/slang/mangle.cpp
+++ b/source/slang/mangle.cpp
@@ -44,75 +44,193 @@ namespace Slang
context->sb.append(str);
}
+ void emitVal(
+ ManglingContext* context,
+ Val* val);
+
+ void emitQualifiedName(
+ ManglingContext* context,
+ DeclRef<Decl> declRef);
+
+ void emitSimpleIntVal(
+ ManglingContext* context,
+ Val* val)
+ {
+ if( auto constVal = dynamic_cast<ConstantIntVal*>(val) )
+ {
+ auto val = constVal->value;
+ if( val >= 0 && val <= 9 )
+ {
+ emit(context, (UInt) val);
+ return;
+ }
+ }
+
+ // Fallback:
+ emitVal(context, val);
+ }
+
void emitType(
ManglingContext* context,
Type* type)
{
// TODO: actually implement this bit...
+
+ if( auto basicType = dynamic_cast<BasicExpressionType*>(type) )
+ {
+ switch( basicType->baseType )
+ {
+ case BaseType::Void: emitRaw(context, "V"); break;
+ case BaseType::Bool: emitRaw(context, "b"); break;
+ case BaseType::Int: emitRaw(context, "i"); break;
+ case BaseType::UInt: emitRaw(context, "u"); break;
+ case BaseType::UInt64: emitRaw(context, "U"); break;
+ case BaseType::Half: emitRaw(context, "h"); break;
+ case BaseType::Float: emitRaw(context, "f"); break;
+ case BaseType::Double: emitRaw(context, "d"); break;
+ break;
+
+ default:
+ SLANG_UNEXPECTED("unimplemented case in mangling");
+ break;
+ }
+ }
+ else if( auto vecType = dynamic_cast<VectorExpressionType*>(type) )
+ {
+ emitRaw(context, "v");
+ emitSimpleIntVal(context, vecType->elementCount);
+ emitType(context, vecType->elementType);
+ }
+ else if( auto matType = dynamic_cast<MatrixExpressionType*>(type) )
+ {
+ emitRaw(context, "m");
+ emitSimpleIntVal(context, matType->getRowCount());
+ emitRaw(context, "x");
+ emitSimpleIntVal(context, matType->getColumnCount());
+ emitType(context, matType->getElementType());
+ }
+ else if( auto namedType = dynamic_cast<NamedExpressionType*>(type) )
+ {
+ emitType(context, GetType(namedType->declRef));
+ }
+ else if( auto declRefType = dynamic_cast<DeclRefType*>(type) )
+ {
+ emitQualifiedName(context, declRefType->declRef);
+ }
+ else
+ {
+ SLANG_UNEXPECTED("unimplemented case in mangling");
+ }
+ }
+
+ void emitVal(
+ ManglingContext* context,
+ Val* val)
+ {
+ if( auto type = dynamic_cast<Type*>(val) )
+ {
+ emitType(context, type);
+ }
+ else
+ {
+ SLANG_UNEXPECTED("unimplemented case in mangling");
+ }
}
void emitQualifiedName(
ManglingContext* context,
- Decl* decl)
+ DeclRef<Decl> declRef)
{
- auto parentDecl = decl->ParentDecl;
- if( parentDecl )
+ auto parentDeclRef = declRef.GetParent();
+ auto parentGenericDeclRef = parentDeclRef.As<GenericDecl>();
+ if( parentDeclRef )
{
- emitQualifiedName(context, parentDecl);
+ // In certain cases we want to skip emitting the parent
+ if(parentGenericDeclRef && (parentGenericDeclRef.getDecl()->inner.Ptr() != declRef.getDecl()))
+ {
+ }
+ else if(parentDeclRef.As<FunctionDeclBase>())
+ {
+ }
+ else
+ {
+ emitQualifiedName(context, parentDeclRef);
+ }
}
// A generic declaration is kind of a pseudo-declaration
// as far as the user is concerned; so we don't want
// to emit its name.
- if( auto genericDecl = dynamic_cast<GenericDecl*>(decl) )
+ if(auto genericDeclRef = declRef.As<GenericDecl>())
{
return;
}
- emitName(context, decl->nameAndLoc.name);
+ emitName(context, declRef.GetName());
- if( auto parentGenericDecl = dynamic_cast<GenericDecl*>(parentDecl))
+ // Are we the "inner" declaration beneath a generic decl?
+ if(parentGenericDeclRef && (parentGenericDeclRef.getDecl()->inner.Ptr() == declRef.getDecl()))
{
- emitRaw(context, "g");
- UInt genericParameterCount = 0;
- for( auto mm : parentGenericDecl->Members )
+ // There are two cases here: either we have specializations
+ // in place for the parent generic declaration, or we don't.
+
+ auto subst = declRef.substitutions;
+ if( subst && subst->genericDecl == parentGenericDeclRef.getDecl() )
{
- if(mm.As<GenericTypeParamDecl>())
- {
- genericParameterCount++;
- }
- else if(mm.As<GenericValueParamDecl>())
- {
- genericParameterCount++;
- }
- else if(mm.As<GenericTypeConstraintDecl>())
- {
- genericParameterCount++;
- }
- else
+ // This is the case where we *do* have substitutions.
+ emitRaw(context, "G");
+ UInt genericArgCount = subst->args.Count();
+ emit(context, genericArgCount);
+ for( auto aa : subst->args )
{
+ emitVal(context, aa);
}
}
-
- emit(context, genericParameterCount);
- for( auto mm : parentGenericDecl->Members )
+ else
{
- if(auto genericTypeParamDecl = mm.As<GenericTypeParamDecl>())
+ // We don't have substitutions, so we will emit
+ // information about the parameters of the generic here.
+ emitRaw(context, "g");
+ UInt genericParameterCount = 0;
+ for( auto mm : getMembers(parentGenericDeclRef) )
{
- emitRaw(context, "T");
+ if(mm.As<GenericTypeParamDecl>())
+ {
+ genericParameterCount++;
+ }
+ else if(mm.As<GenericValueParamDecl>())
+ {
+ genericParameterCount++;
+ }
+ else if(mm.As<GenericTypeConstraintDecl>())
+ {
+ genericParameterCount++;
+ }
+ else
+ {
+ }
}
- else if(auto genericValueParamDecl = mm.As<GenericValueParamDecl>())
- {
- emitRaw(context, "v");
- emitType(context, genericValueParamDecl->getType());
- }
- else if(mm.As<GenericTypeConstraintDecl>())
- {
- emitRaw(context, "C");
- // TODO: actually emit info about the constraint
- }
- else
+
+ emit(context, genericParameterCount);
+ for( auto mm : getMembers(parentGenericDeclRef) )
{
+ if(auto genericTypeParamDecl = mm.As<GenericTypeParamDecl>())
+ {
+ emitRaw(context, "T");
+ }
+ else if(auto genericValueParamDecl = mm.As<GenericValueParamDecl>())
+ {
+ emitRaw(context, "v");
+ emitType(context, GetType(genericValueParamDecl));
+ }
+ else if(mm.As<GenericTypeConstraintDecl>())
+ {
+ emitRaw(context, "C");
+ // TODO: actually emit info about the constraint
+ }
+ else
+ {
+ }
}
}
}
@@ -124,23 +242,25 @@ namespace Slang
// We'll also go ahead and emit the result type as well,
// just for completeness.
//
- if( auto callableDecl = dynamic_cast<CallableDecl*>(decl) )
+ if( auto callableDeclRef = declRef.As<CallableDecl>())
{
emitRaw(context, "p");
- UInt parameterCount = callableDecl->GetParameters().Count();
+
+ auto parameters = GetParameters(callableDeclRef);
+ UInt parameterCount = parameters.Count();
emit(context, parameterCount);
- for(auto pp : callableDecl->GetParameters())
+ for(auto paramDeclRef : parameters)
{
- emitType(context, pp->getType());
+ emitType(context, GetType(paramDeclRef));
}
- emitType(context, callableDecl->ReturnType);
+ emitType(context, GetResultType(callableDeclRef));
}
}
void mangleName(
ManglingContext* context,
- Decl* decl)
+ DeclRef<Decl> declRef)
{
// TODO: catch cases where the declaration should
// forward to something else? E.g., what if we
@@ -150,6 +270,8 @@ namespace Slang
// clashes with user-defined symbols:
emitRaw(context, "_S");
+ auto decl = declRef.getDecl();
+
// Next we will add a bit of info to register
// the *kind* of declaration we are dealing with.
//
@@ -174,17 +296,24 @@ namespace Slang
}
// Now we encode the qualified name of the decl.
- emitQualifiedName(context, decl);
+ emitQualifiedName(context, declRef);
}
-
-
- String getMangledName(Decl* decl)
+ String getMangledName(DeclRef<Decl> const& declRef)
{
ManglingContext context;
+ mangleName(&context, declRef);
+ return context.sb.ProduceString();
+ }
- mangleName(&context, decl);
+ String getMangledName(DeclRefBase const & declRef)
+ {
+ return getMangledName(
+ DeclRef<Decl>(declRef.decl, declRef.substitutions));
+ }
- return context.sb.ProduceString();
+ String getMangledName(Decl* decl)
+ {
+ return getMangledName(makeDeclRef(decl));
}
}