https://github.com/shader-slang/slang
Raw File
Tip revision: c5c8cfbb360d9a763f549df48636effde839eacd authored by Sai Praveen Bangaru on 27 September 2023, 00:50:13 UTC
Handle the case where the parent if-else region's after-block is unreachable. (#3241)
Tip revision: c5c8cfb
slang-type-text-util.cpp

#include "slang-type-text-util.h"
#include "slang-array-view.h"

#include "slang-string-util.h"

namespace Slang
{

namespace { // anonymous

#define SLANG_SCALAR_TYPES(x) \
    x(None, none) \
    x(Void, void) \
    x(Bool, bool) \
    x(Float16, half) \
    x(UInt32, uint32_t) \
    x(Int32, int32_t) \
    x(Int64, int64_t) \
    x(UInt64, uint64_t) \
    x(Float32, float) \
    x(Float64, double) 

struct ScalarTypeInfo
{
    slang::TypeReflection::ScalarType type;
    UnownedStringSlice text;
};

static const ScalarTypeInfo s_scalarTypeInfos[] =
{
    #define SLANG_SCALAR_TYPE_INFO(value, text) \
            { slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text) },
    SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO)
};

// Make sure to keep this table in sync with that in slang/slang-options.cpp getHelpText
static const TypeTextUtil::CompileTargetInfo s_compileTargetInfos[] =
{
    { SLANG_TARGET_UNKNOWN, "",                                                 "unknown"},
    { SLANG_TARGET_NONE,    "",                                                 "none"},
    { SLANG_HLSL,           "hlsl,fx",                                          "hlsl",                     "HLSL source code"},
    { SLANG_DXBC,           "dxbc",                                             "dxbc",                     "DirectX shader bytecode binary"},
    { SLANG_DXBC_ASM,       "dxbc-asm",                                         "dxbc-asm,dxbc-assembly",   "DirectX shader bytecode assembly" },
    { SLANG_DXIL,           "dxil",                                             "dxil",                     "DirectX Intermediate Language binary" },
    { SLANG_DXIL_ASM,       "dxil-asm",                                         "dxil-asm,dxil-assembly",   "DirectX Intermediate Language assembly"},
    { SLANG_GLSL,           "glsl,vert,frag,geom,tesc,tese,comp",               "glsl",                     "GLSL source code" },
    { SLANG_GLSL_VULKAN,    "",                                                 "glsl-vulkan",              "GLSL Vulkan source code" },
    { SLANG_GLSL_VULKAN_ONE_DESC, "",                                           "glsl-vulkan-one-desc",     "GLSL Vulkan source code" },
    { SLANG_SPIRV,          "spv",                                              "spirv",                    "SPIR-V binary"},
    { SLANG_SPIRV_ASM,      "spv-asm",                                          "spirv-asm,spirv-assembly", "SPIR-V assembly" },
    { SLANG_C_SOURCE,       "c",                                                "c",                        "C source code" },
    { SLANG_CPP_SOURCE,     "cpp,c++,cxx",                                      "cpp,c++,cxx",              "C++ source code" },
    { SLANG_CPP_PYTORCH_BINDING, "cpp,c++,cxx",                                 "torch,torch-binding,torch-cpp,torch-cpp-binding", "C++ for pytorch binding" },
    { SLANG_HOST_CPP_SOURCE, "cpp,c++,cxx",                                     "host-cpp,host-c++,host-cxx", "C++ source for host execution"},
    { SLANG_HOST_EXECUTABLE,"exe",                                              "exe,executable",           "Executable binary" },
    { SLANG_SHADER_SHARED_LIBRARY, "dll,so",                                    "sharedlib,sharedlibrary,dll", "Shared library/Dll" },
    { SLANG_CUDA_SOURCE,    "cu",                                               "cuda,cu",                  "CUDA source code"  },
    { SLANG_PTX,            "ptx",                                              "ptx",                      "PTX assembly" },
    { SLANG_CUDA_OBJECT_CODE, "obj,o",                                          "cuobj,cubin",              "CUDA binary" },
    { SLANG_SHADER_HOST_CALLABLE,  "",                                          "host-callable,callable",   "Host callable" },
    { SLANG_OBJECT_CODE,    "obj,o",                                            "object-code",              "Object code" },
    { SLANG_HOST_HOST_CALLABLE, "",                                             "host-host-callable",       "Host callable for host execution" },
};

static const NamesDescriptionValue s_languageInfos[] =
{
    { SLANG_SOURCE_LANGUAGE_C, "c,C", "C language" },
    { SLANG_SOURCE_LANGUAGE_CPP, "cpp,c++,C++,cxx", "C++ language" },
    { SLANG_SOURCE_LANGUAGE_SLANG, "slang", "Slang language" },
    { SLANG_SOURCE_LANGUAGE_GLSL, "glsl", "GLSL language" },
    { SLANG_SOURCE_LANGUAGE_HLSL, "hlsl", "HLSL language" },
    { SLANG_SOURCE_LANGUAGE_CUDA, "cu,cuda", "CUDA" },
};
    
static const NamesDescriptionValue s_compilerInfos[] = 
{
    { SLANG_PASS_THROUGH_NONE,      "none",     "Unknown" },
    { SLANG_PASS_THROUGH_FXC,       "fxc",      "FXC HLSL compiler" },
    { SLANG_PASS_THROUGH_DXC,       "dxc",      "DXC HLSL compiler" },
    { SLANG_PASS_THROUGH_GLSLANG,   "glslang",  "GLSLANG GLSL compiler" },
    { SLANG_PASS_THROUGH_SPIRV_DIS, "spirv-dis",  "spirv-tools SPIRV disassembler" },
    { SLANG_PASS_THROUGH_VISUAL_STUDIO, "visualstudio,vs", "Visual Studio C/C++ compiler" },
    { SLANG_PASS_THROUGH_CLANG,     "clang",    "Clang C/C++ compiler" },
    { SLANG_PASS_THROUGH_GCC,       "gcc",      "GCC C/C++ compiler" },
    { SLANG_PASS_THROUGH_GENERIC_C_CPP, "genericcpp,c,cpp", "A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system and availability)" },
    { SLANG_PASS_THROUGH_NVRTC,     "nvrtc",     "NVRTC CUDA compiler" },
    { SLANG_PASS_THROUGH_LLVM,      "llvm",     "LLVM/Clang `slang-llvm`" },
};

static const NamesDescriptionValue s_archiveTypeInfos[] =
{
    { SLANG_ARCHIVE_TYPE_RIFF_DEFLATE, "riff-deflate", "Slang RIFF using deflate compression" },
    { SLANG_ARCHIVE_TYPE_RIFF_LZ4, "riff-lz4", "Slang RIFF using LZ4 compression" },
    { SLANG_ARCHIVE_TYPE_ZIP, "zip", "Zip file" },
    { SLANG_ARCHIVE_TYPE_RIFF, "riff", "Slang RIFF without compression" },
};

static const NamesDescriptionValue s_debugInfoFormatInfos[] = 
{
    { SLANG_DEBUG_INFO_FORMAT_DEFAULT,  "default-format", "Use the default debugging format for the target" },
    { SLANG_DEBUG_INFO_FORMAT_C7,       "c7",           "CodeView C7 format (typically means debugging infomation is embedded in the binary)" },
    { SLANG_DEBUG_INFO_FORMAT_PDB,      "pdb",          "Program database" },
    { SLANG_DEBUG_INFO_FORMAT_STABS,    "stabs",        "STABS debug format" },
    { SLANG_DEBUG_INFO_FORMAT_COFF,     "coff",         "COFF debug format" },
    { SLANG_DEBUG_INFO_FORMAT_DWARF,    "dwarf",        "DWARF debug format"},
};

static const NamesDescriptionValue s_lineDirectiveInfos[] = 
{
    { SLANG_LINE_DIRECTIVE_MODE_NONE, "none", "Don't emit `#line` directives at all"}, 
    { SLANG_LINE_DIRECTIVE_MODE_SOURCE_MAP, "source-map", "Use source map to track line associations (doen't emit #line)"},
    { SLANG_LINE_DIRECTIVE_MODE_DEFAULT, "default", "Default behavior"},
    { SLANG_LINE_DIRECTIVE_MODE_STANDARD, "standard", "Emit standard C-style `#line` directives." },
    { SLANG_LINE_DIRECTIVE_MODE_GLSL, "glsl", "Emit GLSL-style directives with file *number* instead of name." },
};

static const NamesDescriptionValue s_floatingPointModes[] =
{
    { SLANG_FLOATING_POINT_MODE_PRECISE, "precise",
    "Disable optimization that could change the output of floating-"
    "point computations, including around infinities, NaNs, denormalized "
    "values, and negative zero. Prefer the most precise versions of special "
    "functions supported by the target."},
    { SLANG_FLOATING_POINT_MODE_FAST,"fast",
    "Allow optimizations that may change results of floating-point "
    "computations. Prefer the fastest version of special functions supported "
    "by the target."},
    { SLANG_FLOATING_POINT_MODE_DEFAULT, "default", 
    "Default floating point mode" }
};

static const NamesDescriptionValue s_optimizationLevels[] =
{
    { SLANG_OPTIMIZATION_LEVEL_NONE,    "0,none",       "Disable all optimizations" },
    { SLANG_OPTIMIZATION_LEVEL_DEFAULT, "1,default",    "Enable a default level of optimization.This is the default if no -o options are used." },
    { SLANG_OPTIMIZATION_LEVEL_HIGH,    "2,high",       "Enable aggressive optimizations for speed." },
    { SLANG_OPTIMIZATION_LEVEL_MAXIMAL, "3,maximal",    "Enable further optimizations, which might have a significant impact on compile time, or involve unwanted tradeoffs in terms of code size." },
};

static const NamesDescriptionValue s_debugLevels[] =
{
    { SLANG_DEBUG_INFO_LEVEL_NONE,      "0,none",       "Don't emit debug information at all." }, 
    { SLANG_DEBUG_INFO_LEVEL_MINIMAL,   "1,minimal",    "Emit as little debug information as possible, while still supporting stack traces." },
    { SLANG_DEBUG_INFO_LEVEL_STANDARD,  "2,standard",   "Emit whatever is the standard level of debug information for each target." },
    { SLANG_DEBUG_INFO_LEVEL_MAXIMAL,   "3,maximal",    "Emit as much debug information as possible for each target." },
};

static const NamesDescriptionValue s_fileSystemTypes[] =
{
    { ValueInt(TypeTextUtil::FileSystemType::Default),     "default",      "Default fike system." },
    { ValueInt(TypeTextUtil::FileSystemType::LoadFile),    "load-file",    "Just implements loadFile interface, so will be wrapped with CacheFileSystem internally." },
    { ValueInt(TypeTextUtil::FileSystemType::Os),          "os",           "Use the OS based file system directly (without file system caching)" },
};

} // anonymous

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFileSystemTypeInfos()
{
    return makeConstArrayView(s_fileSystemTypes);
}

/* static */ConstArrayView<TypeTextUtil::CompileTargetInfo> TypeTextUtil::getCompileTargetInfos()
{
    return makeConstArrayView(s_compileTargetInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLanguageInfos()
{
    return makeConstArrayView(s_languageInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getCompilerInfos()
{
    return makeConstArrayView(s_compilerInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getArchiveTypeInfos()
{
    return makeConstArrayView(s_archiveTypeInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugInfoFormatInfos()
{
    return makeConstArrayView(s_debugInfoFormatInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getLineDirectiveInfos()
{
    return makeConstArrayView(s_lineDirectiveInfos);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getFloatingPointModeInfos()
{
    return makeConstArrayView(s_floatingPointModes);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getOptimizationLevelInfos()
{
    return makeConstArrayView(s_optimizationLevels);
}

/* static */ConstArrayView<NamesDescriptionValue> TypeTextUtil::getDebugLevelInfos()
{
    return makeConstArrayView(s_debugLevels);
}

/* static */SlangArchiveType TypeTextUtil::findArchiveType(const UnownedStringSlice& slice)
{
    return NameValueUtil::findValue(getArchiveTypeInfos(), slice, SLANG_ARCHIVE_TYPE_UNDEFINED);
}

/* static */SlangResult TypeTextUtil::findDebugInfoFormat(const Slang::UnownedStringSlice& text, SlangDebugInfoFormat& out)
{
    const ValueInt value = NameValueUtil::findValue(getDebugInfoFormatInfos(), text, -1);
    if (value >= 0)
    {
        out = SlangDebugInfoFormat(value);
        return SLANG_OK;
    }
    return SLANG_FAIL;
}

/* static */UnownedStringSlice TypeTextUtil::getDebugInfoFormatName(SlangDebugInfoFormat format) 
{
    return NameValueUtil::findName(getDebugInfoFormatInfos(), format, toSlice("unknown"));
}

/* static */UnownedStringSlice TypeTextUtil::getScalarTypeName(slang::TypeReflection::ScalarType scalarType)
{    
    typedef slang::TypeReflection::ScalarType ScalarType;
    switch (scalarType)
    {
#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) case ScalarType::value:             return UnownedStringSlice::fromLiteral(#text);       
        SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_TO_TEXT)
        default: break;
    }

    return UnownedStringSlice();
}

/* static */slang::TypeReflection::ScalarType TypeTextUtil::findScalarType(const UnownedStringSlice& inText)
{
    for (Index i = 0; i < SLANG_COUNT_OF(s_scalarTypeInfos); ++i)
    {
        const auto& info = s_scalarTypeInfos[i];
        if (info.text == inText)
        {
            return info.type;
        }
    }
    return slang::TypeReflection::ScalarType::None;
}


/* static */UnownedStringSlice TypeTextUtil::getPassThroughAsHumanText(SlangPassThrough type)
{
    return NameValueUtil::findName(getCompilerInfos(), type, toSlice("unknown"));
}

/* static */SlangSourceLanguage TypeTextUtil::findSourceLanguage(const UnownedStringSlice& text)
{
    return NameValueUtil::findValue(getLanguageInfos(), text, SLANG_SOURCE_LANGUAGE_UNKNOWN);
}

/* static */SlangPassThrough TypeTextUtil::findPassThrough(const UnownedStringSlice& slice)
{
    return NameValueUtil::findValue(getCompilerInfos(), slice, SLANG_PASS_THROUGH_NONE);
}

/* static */SlangResult TypeTextUtil::findPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough)
{
    outPassThrough = findPassThrough(slice);
    // It could be none on error - if it's not equal to "none" then it must be an error
    if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none"))
    {
        return SLANG_FAIL;
    }
    return SLANG_OK;
}

/* static */UnownedStringSlice TypeTextUtil::getPassThroughName(SlangPassThrough passThru)
{
    return NameValueUtil::findName(getCompilerInfos(), passThru, toSlice("unknown"));
}

/* static */SlangCompileTarget TypeTextUtil::findCompileTargetFromExtension(const UnownedStringSlice& slice)
{
    if (slice.getLength())
    {
        for (const auto& info : s_compileTargetInfos)
        {
            if (StringUtil::indexOfInSplit(UnownedStringSlice(info.extensions), ',', slice) >= 0)
            {
                return info.target;
            }
        }
    }
    return SLANG_TARGET_UNKNOWN;
}

/* static */ SlangCompileTarget TypeTextUtil::findCompileTargetFromName(const UnownedStringSlice& slice)
{
    if (slice.getLength())
    {
        for (const auto& info : s_compileTargetInfos)
        {
            if (StringUtil::indexOfInSplit(UnownedStringSlice(info.names), ',', slice) >= 0)
            {
                return info.target;
            }
        }
    }
    return SLANG_TARGET_UNKNOWN;
}

static Index _getTargetInfoIndex(SlangCompileTarget target)
{
    for (Index i = 0; i < SLANG_COUNT_OF(s_compileTargetInfos); ++i)
    {
        if (s_compileTargetInfos[i].target == target)
        {
            return i;
        }
    }
    return -1;
}

UnownedStringSlice TypeTextUtil::getCompileTargetName(SlangCompileTarget target)
{
    const Index index = _getTargetInfoIndex(target);
    // Return the first name
    return index >= 0 ? StringUtil::getAtInSplit(UnownedStringSlice(s_compileTargetInfos[index].names), ',', 0) : UnownedStringSlice();
}

}

back to top