diff options
Diffstat (limited to 'source/slang/mangle.cpp')
| -rw-r--r-- | source/slang/mangle.cpp | 231 |
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)); } } |
