summaryrefslogtreecommitdiffstats
path: root/source/slang/mangle.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 17:20:37 -0400
committerGitHub <noreply@github.com>2019-05-31 17:20:37 -0400
commit6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f (patch)
tree5a23cb47782e9e2a77762c90dd35da1005eba8d0 /source/slang/mangle.cpp
parentb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (diff)
Use slang- prefix on slang compiler and core source (#973)
* Prefixing source files in source/slang with slang- * Prefix source in source/slang with slang- prefix. * Rename core source files with slang- prefix. * Update project files. * Fix problems from automatic merge.
Diffstat (limited to 'source/slang/mangle.cpp')
-rw-r--r--source/slang/mangle.cpp478
1 files changed, 0 insertions, 478 deletions
diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp
deleted file mode 100644
index 2ed9cfea6..000000000
--- a/source/slang/mangle.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-#include "mangle.h"
-
-#include "name.h"
-#include "syntax.h"
-
-namespace Slang
-{
- struct ManglingContext
- {
- StringBuilder sb;
- };
-
- void emitRaw(
- ManglingContext* context,
- char const* text)
- {
- context->sb.append(text);
- }
-
- void emit(
- ManglingContext* context,
- UInt value)
- {
- context->sb.append(value);
- }
-
- void emit(
- ManglingContext* context,
- String const& value)
- {
- context->sb.append(value);
- }
-
- void emitName(
- ManglingContext* context,
- Name* name)
- {
- String str = getText(name);
-
- // If the name consists of only traditional "identifer characters"
- // (`[a-zA-Z_]`), then we wnat to emit it more or less directly.
- //
- // If it contains code points outside that range, we'll need to
- // do something to encode them. I don't want to deal with
- // that right now, so I'm going to ignore it.
-
- // We prefix the string with its byte length, so that
- // decoding doesn't have to worry about finding a terminator.
- Index length = str.getLength();
- emit(context, length);
- 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 = as<ConstantIntVal>(val) )
- {
- auto cVal = constVal->value;
- if(cVal >= 0 && cVal <= 9 )
- {
- emit(context, (UInt)cVal);
- return;
- }
- }
-
- // Fallback:
- emitVal(context, val);
- }
-
- void emitBaseType(
- ManglingContext* context,
- BaseType baseType)
- {
- switch( baseType )
- {
- case BaseType::Void: emitRaw(context, "V"); break;
- case BaseType::Bool: emitRaw(context, "b"); break;
- case BaseType::Int8: emitRaw(context, "c"); break;
- case BaseType::Int16: emitRaw(context, "s"); break;
- case BaseType::Int: emitRaw(context, "i"); break;
- case BaseType::Int64: emitRaw(context, "I"); break;
- case BaseType::UInt8: emitRaw(context, "C"); break;
- case BaseType::UInt16: emitRaw(context, "S"); 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;
- }
- }
-
- void emitType(
- ManglingContext* context,
- Type* type)
- {
- // TODO: actually implement this bit...
-
- if( auto basicType = dynamicCast<BasicExpressionType>(type) )
- {
- emitBaseType(context, basicType->baseType);
- }
- else if( auto vecType = dynamicCast<VectorExpressionType>(type) )
- {
- emitRaw(context, "v");
- emitSimpleIntVal(context, vecType->elementCount);
- emitType(context, vecType->elementType);
- }
- else if( auto matType = dynamicCast<MatrixExpressionType>(type) )
- {
- emitRaw(context, "m");
- emitSimpleIntVal(context, matType->getRowCount());
- emitRaw(context, "x");
- emitSimpleIntVal(context, matType->getColumnCount());
- emitType(context, matType->getElementType());
- }
- else if( auto namedType = dynamicCast<NamedExpressionType>(type) )
- {
- emitType(context, GetType(namedType->declRef));
- }
- else if( auto declRefType = dynamicCast<DeclRefType>(type) )
- {
- emitQualifiedName(context, declRefType->declRef);
- }
- else if (auto arrType = dynamicCast<ArrayExpressionType>(type))
- {
- emitRaw(context, "a");
- emitSimpleIntVal(context, arrType->ArrayLength);
- emitType(context, arrType->baseType);
- }
- else if( auto taggedUnionType = dynamicCast<TaggedUnionType>(type) )
- {
- emitRaw(context, "u");
- for( auto caseType : taggedUnionType->caseTypes )
- {
- emitType(context, caseType);
- }
- emitRaw(context, "U");
- }
- else
- {
- SLANG_UNEXPECTED("unimplemented case in mangling");
- }
- }
-
- void emitVal(
- ManglingContext* context,
- Val* val)
- {
- if( auto type = dynamicCast<Type>(val) )
- {
- emitType(context, type);
- }
- else if( auto witness = dynamicCast<Witness>(val) )
- {
- // We don't emit witnesses as part of a mangled
- // name, because the way that the front-end
- // arrived at the witness is not important;
- // what matters is that the type constraint
- // was satisfied.
- //
- // TODO: make sure we can't get name collisions
- // between specializations of declarations
- // with the same numbers of generic parameters,
- // but different constraints. We might have
- // to mangle in the constraints even when
- // the whole thing is specialized...
- }
- else if( auto genericParamIntVal = dynamicCast<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).
- emitRaw(context, "K");
- emitName(context, genericParamIntVal->declRef.GetName());
- }
- else if( auto constantIntVal = dynamicCast<ConstantIntVal>(val) )
- {
- // TODO: need to figure out what prefix/suffix is needed
- // to allow demangling later.
- emitRaw(context, "k");
- emit(context, (UInt) constantIntVal->value);
- }
- else
- {
- SLANG_UNEXPECTED("unimplemented case in mangling");
- }
- }
-
- void emitQualifiedName(
- ManglingContext* context,
- DeclRef<Decl> declRef)
- {
- auto parentDeclRef = declRef.GetParent();
- auto parentGenericDeclRef = parentDeclRef.as<GenericDecl>();
- if( parentDeclRef )
- {
- // 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 genericDeclRef = declRef.as<GenericDecl>())
- {
- return;
- }
-
- // Inheritance declarations don't have meaningful names,
- // and so we should emit them based on the type
- // that is doing the inheriting.
- if(auto inheritanceDeclRef = declRef.as<InheritanceDecl>())
- {
- emit(context, "I");
- emitType(context, GetSup(inheritanceDeclRef));
- return;
- }
-
- // Similarly, an extension doesn't have a name worth
- // emitting, and we should base things on its target
- // type instead.
- if(auto extensionDeclRef = declRef.as<ExtensionDecl>())
- {
- // TODO: as a special case, an "unconditional" extension
- // that is in the same module as the type it extends should
- // be treated as equivalent to the type itself.
- emit(context, "X");
- emitType(context, GetTargetType(extensionDeclRef));
- return;
- }
-
- emitName(context, declRef.GetName());
-
- // Special case: accessors need some way to distinguish themselves
- // so that a getter/setter/ref-er don't all compile to the same name.
- {
- if (declRef.is<GetterDecl>()) emitRaw(context, "Ag");
- if (declRef.is<SetterDecl>()) emitRaw(context, "As");
- if (declRef.is<RefAccessorDecl>()) emitRaw(context, "Ar");
- }
-
- // Are we the "inner" declaration beneath a generic decl?
- if(parentGenericDeclRef && (parentGenericDeclRef.getDecl()->inner.Ptr() == declRef.getDecl()))
- {
- // There are two cases here: either we have specializations
- // in place for the parent generic declaration, or we don't.
-
- auto subst = findInnerMostGenericSubstitution(declRef.substitutions);
- if( subst && subst->genericDecl == parentGenericDeclRef.getDecl() )
- {
- // This is the case where we *do* have substitutions.
- emitRaw(context, "G");
- UInt genericArgCount = subst->args.getCount();
- emit(context, genericArgCount);
- for( auto aa : subst->args )
- {
- emitVal(context, aa);
- }
- }
- else
- {
- // 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) )
- {
- if(mm.is<GenericTypeParamDecl>())
- {
- genericParameterCount++;
- }
- else if(mm.is<GenericValueParamDecl>())
- {
- genericParameterCount++;
- }
- else if(mm.is<GenericTypeConstraintDecl>())
- {
- genericParameterCount++;
- }
- 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
- {
- }
- }
- }
- }
-
- // If the declaration has parameters, then we need to emit
- // those parameters to distinguish it from other declarations
- // of the same name that might have different parameters.
- //
- // We'll also go ahead and emit the result type as well,
- // just for completeness.
- //
- if( auto callableDeclRef = declRef.as<CallableDecl>())
- {
- auto parameters = GetParameters(callableDeclRef);
- UInt parameterCount = parameters.Count();
-
- emitRaw(context, "p");
- emit(context, parameterCount);
- emitRaw(context, "p");
-
- for(auto paramDeclRef : parameters)
- {
- emitType(context, GetType(paramDeclRef));
- }
-
- // Don't print result type for an initializer/constructor,
- // since it is implicit in the qualified name.
- if (!callableDeclRef.is<ConstructorDecl>())
- {
- emitType(context, GetResultType(callableDeclRef));
- }
- }
- }
-
- void mangleName(
- ManglingContext* context,
- DeclRef<Decl> declRef)
- {
- // TODO: catch cases where the declaration should
- // forward to something else? E.g., what if we
- // are asked to mangle the name of a `typedef`?
-
- // We will start with a unique prefix to avoid
- // 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.
- //
- // Functions will get no prefix, since we assume
- // they are a common case:
- if(as<FuncDecl>(decl))
- {}
- // Types will get a `T` prefix:
- else if(as<AggTypeDecl>(decl))
- emitRaw(context, "T");
- else if(as<TypeDefDecl>(decl))
- emitRaw(context, "T");
- // Variables will get a `V` prefix:
- //
- // TODO: probably need to pull constant-buffer
- // declarations out of this...
- else if(as<VarDeclBase>(decl))
- emitRaw(context, "V");
- else
- {
- // TODO: handle other cases
- }
-
- // Now we encode the qualified name of the decl.
- emitQualifiedName(context, declRef);
- }
-
- String getMangledName(DeclRef<Decl> const& declRef)
- {
- ManglingContext context;
- mangleName(&context, declRef);
- return context.sb.ProduceString();
- }
-
- String getMangledName(DeclRefBase const & declRef)
- {
- return getMangledName(
- DeclRef<Decl>(declRef.decl, declRef.substitutions));
- }
-
- String getMangledName(Decl* decl)
- {
- return getMangledName(makeDeclRef(decl));
- }
-
- String getMangledNameForConformanceWitness(
- DeclRef<Decl> sub,
- DeclRef<Decl> sup)
- {
- ManglingContext context;
- emitRaw(&context, "_SW");
- emitQualifiedName(&context, sub);
- emitQualifiedName(&context, sup);
- return context.sb.ProduceString();
- }
-
- String getMangledNameForConformanceWitness(
- DeclRef<Decl> sub,
- Type* sup)
- {
- // The mangled form for a witness that `sub`
- // conforms to `sup` will be named:
- //
- // {Conforms(sub,sup)} => _SW{sub}{sup}
- //
- ManglingContext context;
- emitRaw(&context, "_SW");
- emitQualifiedName(&context, sub);
- emitType(&context, sup);
- return context.sb.ProduceString();
- }
-
- String getMangledNameForConformanceWitness(
- Type* sub,
- Type* sup)
- {
- // The mangled form for a witness that `sub`
- // conforms to `sup` will be named:
- //
- // {Conforms(sub,sup)} => _SW{sub}{sup}
- //
- ManglingContext context;
- emitRaw(&context, "_SW");
- emitType(&context, sub);
- emitType(&context, sup);
- return context.sb.ProduceString();
- }
-
- String getMangledTypeName(Type* type)
- {
- ManglingContext context;
- emitType(&context, type);
- return context.sb.ProduceString();
- }
-
-
-}