зеркало из https://github.com/stride3d/xkslang.git
HLSL: Plumb in HLSL parse context and keywords, and most basic HLSL parser and test.
This commit is contained in:
Родитель
b3dc3acd59
Коммит
e01a9bc8c0
|
@ -24,3 +24,4 @@ add_subdirectory(glslang)
|
||||||
add_subdirectory(OGLCompilersDLL)
|
add_subdirectory(OGLCompilersDLL)
|
||||||
add_subdirectory(StandAlone)
|
add_subdirectory(StandAlone)
|
||||||
add_subdirectory(SPIRV)
|
add_subdirectory(SPIRV)
|
||||||
|
add_subdirectory(hlsl)
|
||||||
|
|
|
@ -10,6 +10,7 @@ set(LIBRARIES
|
||||||
glslang
|
glslang
|
||||||
OGLCompiler
|
OGLCompiler
|
||||||
OSDependent
|
OSDependent
|
||||||
|
HLSL
|
||||||
SPIRV)
|
SPIRV)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
hlsl.frag
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80001
|
||||||
|
// Id's are bound by 6
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "PixelShaderFunction"
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source HLSL 100
|
||||||
|
Name 4 "PixelShaderFunction"
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
4(PixelShaderFunction): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
FunctionEnd
|
|
@ -0,0 +1,11 @@
|
||||||
|
//float4x4 World;
|
||||||
|
//float4x4 View;
|
||||||
|
//float4x4 Projection;
|
||||||
|
//
|
||||||
|
//float4 AmbientColor = float4(1, 1, 1, 1);
|
||||||
|
//float AmbientIntensity = 0.1;
|
||||||
|
//
|
||||||
|
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||||
|
//{
|
||||||
|
// return AmbientColor * AmbientIntensity;
|
||||||
|
//}
|
|
@ -55,6 +55,24 @@ while read t; do
|
||||||
done < test-spirv-list
|
done < test-spirv-list
|
||||||
rm -f comp.spv frag.spv geom.spv tesc.spv tese.spv vert.spv
|
rm -f comp.spv frag.spv geom.spv tesc.spv tese.spv vert.spv
|
||||||
|
|
||||||
|
#
|
||||||
|
# HLSL -> SPIR-V code generation tests
|
||||||
|
#
|
||||||
|
while read t; do
|
||||||
|
case $t in
|
||||||
|
\#*)
|
||||||
|
# Skip comment lines in the test list file.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo Running HLSL-to-SPIR-V $t...
|
||||||
|
b=`basename $t`
|
||||||
|
$EXE -D -e PixelShaderFunction -H $t > $TARGETDIR/$b.out
|
||||||
|
diff -b $BASEDIR/$b.out $TARGETDIR/$b.out || HASERROR=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < test-hlsl-spirv-list
|
||||||
|
rm -f comp.spv frag.spv geom.spv tesc.spv tese.spv vert.spv
|
||||||
|
|
||||||
#
|
#
|
||||||
# Preprocessor tests
|
# Preprocessor tests
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Test looping constructs.
|
||||||
|
# No tests yet for making sure break and continue from a nested loop
|
||||||
|
# goes to the innermost target.
|
||||||
|
hlsl.frag
|
|
@ -46,6 +46,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "SymbolTable.h"
|
#include "SymbolTable.h"
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
#include "../../hlsl/hlslParseHelper.h"
|
||||||
#include "Scan.h"
|
#include "Scan.h"
|
||||||
#include "ScanContext.h"
|
#include "ScanContext.h"
|
||||||
|
|
||||||
|
@ -598,26 +599,37 @@ bool ProcessDeferred(
|
||||||
// Now we can process the full shader under proper symbols and rules.
|
// Now we can process the full shader under proper symbols and rules.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
TParseContextBase* parseContext;
|
||||||
|
if (source == EShSourceHlsl) {
|
||||||
|
parseContext = new HlslParseContext(symbolTable, intermediate, false, version, profile, spv, vulkan,
|
||||||
|
compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
|
||||||
|
}
|
||||||
|
else {
|
||||||
intermediate.setEntryPoint("main");
|
intermediate.setEntryPoint("main");
|
||||||
TParseContext parseContext(symbolTable, intermediate, false, version, profile, spv, vulkan, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
|
parseContext = new TParseContext(symbolTable, intermediate, false, version, profile, spv, vulkan,
|
||||||
glslang::TScanContext scanContext(parseContext);
|
compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
|
||||||
TPpContext ppContext(parseContext, includer);
|
}
|
||||||
parseContext.setScanContext(&scanContext);
|
TPpContext ppContext(*parseContext, includer);
|
||||||
parseContext.setPpContext(&ppContext);
|
|
||||||
parseContext.setLimits(*resources);
|
// only GLSL (bison triggered, really) needs an externally set scan context
|
||||||
|
glslang::TScanContext scanContext(*parseContext);
|
||||||
|
if ((messages & EShMsgReadHlsl) == 0)
|
||||||
|
parseContext->setScanContext(&scanContext);
|
||||||
|
|
||||||
|
parseContext->setPpContext(&ppContext);
|
||||||
|
parseContext->setLimits(*resources);
|
||||||
if (! goodVersion)
|
if (! goodVersion)
|
||||||
parseContext.addError();
|
parseContext->addError();
|
||||||
if (warnVersionNotFirst) {
|
if (warnVersionNotFirst) {
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
loc.init();
|
loc.init();
|
||||||
parseContext.warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
parseContext.initializeExtensionBehavior();
|
parseContext->initializeExtensionBehavior();
|
||||||
|
|
||||||
|
|
||||||
// Fill in the strings as outlined above.
|
// Fill in the strings as outlined above.
|
||||||
strings[0] = parseContext.getPreamble();
|
strings[0] = parseContext->getPreamble();
|
||||||
lengths[0] = strlen(strings[0]);
|
lengths[0] = strlen(strings[0]);
|
||||||
names[0] = nullptr;
|
names[0] = nullptr;
|
||||||
strings[1] = customPreamble;
|
strings[1] = customPreamble;
|
||||||
|
@ -635,14 +647,14 @@ bool ProcessDeferred(
|
||||||
// Push a new symbol allocation scope that will get used for the shader's globals.
|
// Push a new symbol allocation scope that will get used for the shader's globals.
|
||||||
symbolTable.push();
|
symbolTable.push();
|
||||||
|
|
||||||
bool success = processingContext(parseContext, ppContext, fullInput,
|
bool success = processingContext(*parseContext, ppContext, fullInput,
|
||||||
versionWillBeError, symbolTable,
|
versionWillBeError, symbolTable,
|
||||||
intermediate, optLevel, messages);
|
intermediate, optLevel, messages);
|
||||||
|
|
||||||
// Clean up the symbol table. The AST is self-sufficient now.
|
// Clean up the symbol table. The AST is self-sufficient now.
|
||||||
delete symbolTableMemory;
|
delete symbolTableMemory;
|
||||||
|
|
||||||
|
delete parseContext;
|
||||||
delete [] lengths;
|
delete [] lengths;
|
||||||
delete [] strings;
|
delete [] strings;
|
||||||
delete [] names;
|
delete [] names;
|
||||||
|
|
|
@ -69,6 +69,18 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
||||||
//
|
//
|
||||||
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
{
|
{
|
||||||
|
if (source == EShSourceNone)
|
||||||
|
source = unit.source;
|
||||||
|
|
||||||
|
if (source != unit.source)
|
||||||
|
error(infoSink, "can't link compilation units from different source languages");
|
||||||
|
|
||||||
|
if (source == EShSourceHlsl && unit.entryPoint.size() > 0) {
|
||||||
|
if (entryPoint.size() > 0)
|
||||||
|
error(infoSink, "can't handle multiple entry points per stage");
|
||||||
|
else
|
||||||
|
entryPoint = unit.entryPoint;
|
||||||
|
}
|
||||||
numMains += unit.numMains;
|
numMains += unit.numMains;
|
||||||
numErrors += unit.numErrors;
|
numErrors += unit.numErrors;
|
||||||
numPushConstants += unit.numPushConstants;
|
numPushConstants += unit.numPushConstants;
|
||||||
|
@ -356,7 +368,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
//
|
//
|
||||||
void TIntermediate::finalCheck(TInfoSink& infoSink)
|
void TIntermediate::finalCheck(TInfoSink& infoSink)
|
||||||
{
|
{
|
||||||
if (numMains < 1)
|
if (source == EShSourceGlsl && numMains < 1)
|
||||||
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
|
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
|
||||||
|
|
||||||
if (numPushConstants > 1)
|
if (numPushConstants > 1)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
hlslParseHelper.cpp
|
||||||
|
hlslScanContext.cpp
|
||||||
|
hlslGrammar.cpp)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
hlslParseHelper.h
|
||||||
|
hlslTokens.h
|
||||||
|
hlslScanContext.h
|
||||||
|
hlslGrammar.h)
|
||||||
|
|
||||||
|
add_library(HLSL STATIC ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
install(TARGETS HLSL
|
||||||
|
ARCHIVE DESTINATION lib)
|
|
@ -0,0 +1,93 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "hlslTokens.h"
|
||||||
|
#include "hlslGrammar.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
// Root entry point to this recursive decent parser.
|
||||||
|
// Return true if compilation unit was successfully accepted.
|
||||||
|
bool HlslGrammar::parse()
|
||||||
|
{
|
||||||
|
advanceToken();
|
||||||
|
return acceptCompilationUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HlslGrammar::expected(const char* syntax)
|
||||||
|
{
|
||||||
|
parseContext.error(token.loc, "Expected", syntax, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load 'token' with the next token in the stream of tokens.
|
||||||
|
void HlslGrammar::advanceToken()
|
||||||
|
{
|
||||||
|
scanContext.tokenize(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true and advance to the next token if the current token is the
|
||||||
|
// expected (passed in) token class.
|
||||||
|
bool HlslGrammar::acceptTokenClass(EHlslTokenClass tokenClass)
|
||||||
|
{
|
||||||
|
if (token.tokenClass == tokenClass) {
|
||||||
|
advanceToken();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compilationUnit
|
||||||
|
// : list of externalDeclaration
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptCompilationUnit()
|
||||||
|
{
|
||||||
|
while (token.tokenClass != EHTokNone) {
|
||||||
|
if (! acceptDeclaration())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// declaration
|
||||||
|
// : dummy stub
|
||||||
|
bool HlslGrammar::acceptDeclaration()
|
||||||
|
{
|
||||||
|
advanceToken();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
|
@ -0,0 +1,68 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HLSLGRAMMAR_H_
|
||||||
|
#define HLSLGRAMMAR_H_
|
||||||
|
|
||||||
|
#include "hlslScanContext.h"
|
||||||
|
#include "hlslParseHelper.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
class HlslGrammar {
|
||||||
|
public:
|
||||||
|
HlslGrammar(HlslScanContext& scanContext, HlslParseContext& parseContext)
|
||||||
|
: scanContext(scanContext), parseContext(parseContext) { }
|
||||||
|
virtual ~HlslGrammar() { }
|
||||||
|
|
||||||
|
bool parse();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void expected(const char*);
|
||||||
|
void advanceToken();
|
||||||
|
bool acceptTokenClass(EHlslTokenClass);
|
||||||
|
|
||||||
|
bool acceptCompilationUnit();
|
||||||
|
bool acceptDeclaration();
|
||||||
|
|
||||||
|
HlslScanContext& scanContext;
|
||||||
|
HlslParseContext& parseContext;
|
||||||
|
|
||||||
|
HlslToken token;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // HLSLGRAMMAR_H_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,222 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
#ifndef HLSL_PARSE_INCLUDED_
|
||||||
|
#define HLSL_PARSE_INCLUDED_
|
||||||
|
|
||||||
|
#include "../glslang/MachineIndependent/parseVersions.h"
|
||||||
|
#include "../glslang/MachineIndependent/ParseHelper.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
class HlslParseContext : public TParseContextBase {
|
||||||
|
public:
|
||||||
|
HlslParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins,
|
||||||
|
int version, EProfile, int spv, int vulkan, EShLanguage, TInfoSink&,
|
||||||
|
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
||||||
|
virtual ~HlslParseContext();
|
||||||
|
void setLimits(const TBuiltInResource&);
|
||||||
|
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
|
||||||
|
const char* getPreamble();
|
||||||
|
|
||||||
|
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
|
||||||
|
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) { }
|
||||||
|
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) { return true; }
|
||||||
|
bool lineDirectiveShouldSetNextLine() const { return true; }
|
||||||
|
bool builtInName(const TString&);
|
||||||
|
|
||||||
|
void handlePragma(const TSourceLoc&, const TVector<TString>&);
|
||||||
|
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
|
||||||
|
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
void checkIndex(const TSourceLoc&, const TType&, int& index);
|
||||||
|
|
||||||
|
void makeEditable(TSymbol*&);
|
||||||
|
TVariable* getEditableVariable(const char* name);
|
||||||
|
bool isIoResizeArray(const TType&) const;
|
||||||
|
void fixIoArraySize(const TSourceLoc&, TType&);
|
||||||
|
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
||||||
|
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
|
||||||
|
int getIoArrayImplicitSize() const;
|
||||||
|
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
|
||||||
|
|
||||||
|
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||||
|
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||||
|
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||||
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
|
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
|
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
|
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
|
||||||
|
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
||||||
|
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
|
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
||||||
|
|
||||||
|
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
||||||
|
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
|
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||||
|
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
|
void variableCheck(TIntermTyped*& nodePtr);
|
||||||
|
void constantValueCheck(TIntermTyped* node, const char* token);
|
||||||
|
void integerCheck(const TIntermTyped* node, const char* token);
|
||||||
|
void globalCheck(const TSourceLoc&, const char* token);
|
||||||
|
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
|
||||||
|
bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
|
||||||
|
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&);
|
||||||
|
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
||||||
|
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
||||||
|
void arrayDimMerge(TType& type, const TArraySizes* sizes);
|
||||||
|
bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
|
||||||
|
void boolCheck(const TSourceLoc&, const TIntermTyped*);
|
||||||
|
void boolCheck(const TSourceLoc&, const TPublicType&);
|
||||||
|
void globalQualifierFix(const TSourceLoc&, TQualifier&);
|
||||||
|
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
||||||
|
void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force);
|
||||||
|
int computeSamplerTypeIndex(TSampler&);
|
||||||
|
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
|
||||||
|
void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
|
||||||
|
void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
|
||||||
|
void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
|
||||||
|
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
||||||
|
|
||||||
|
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
|
||||||
|
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
||||||
|
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||||
|
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||||
|
|
||||||
|
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
|
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||||
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
|
||||||
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
|
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
||||||
|
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||||
|
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
|
||||||
|
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
|
||||||
|
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
|
||||||
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier);
|
||||||
|
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||||
|
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||||
|
|
||||||
|
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void inheritGlobalDefaults(TQualifier& dst) const;
|
||||||
|
TVariable* makeInternalVariable(const char* name, const TType&) const;
|
||||||
|
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool& newDeclaration);
|
||||||
|
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
|
||||||
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
|
TOperator mapTypeToConstructorOp(const TType&) const;
|
||||||
|
void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||||
|
va_list args);
|
||||||
|
|
||||||
|
// Current state of parsing
|
||||||
|
struct TPragma contextPragma;
|
||||||
|
int loopNestingLevel; // 0 if outside all loops
|
||||||
|
int structNestingLevel; // 0 if outside blocks and structures
|
||||||
|
int controlFlowNestingLevel; // 0 if outside all flow control
|
||||||
|
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
||||||
|
TList<TIntermSequence*> switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
||||||
|
TList<int> switchLevel; // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
|
bool inEntrypoint; // if inside a function, true if the function is the entry point
|
||||||
|
bool postMainReturn; // if inside a function, true if the function is the entry point and this is after a return statement
|
||||||
|
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||||
|
bool functionReturnsValue; // true if a non-void function has a return
|
||||||
|
const TString* blockName;
|
||||||
|
TQualifier currentBlockQualifier;
|
||||||
|
TBuiltInResource resources;
|
||||||
|
TLimits& limits;
|
||||||
|
|
||||||
|
HlslParseContext(HlslParseContext&);
|
||||||
|
HlslParseContext& operator=(HlslParseContext&);
|
||||||
|
|
||||||
|
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
||||||
|
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2)); // see computeSamplerTypeIndex()
|
||||||
|
bool afterEOF;
|
||||||
|
TQualifier globalBufferDefaults;
|
||||||
|
TQualifier globalUniformDefaults;
|
||||||
|
TQualifier globalInputDefaults;
|
||||||
|
TQualifier globalOutputDefaults;
|
||||||
|
TString currentCaller; // name of last function body entered (not valid when at global scope)
|
||||||
|
TIdSetType inductiveLoopIds;
|
||||||
|
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Geometry shader input arrays:
|
||||||
|
// - array sizing is based on input primitive and/or explicit size
|
||||||
|
//
|
||||||
|
// Tessellation control output arrays:
|
||||||
|
// - array sizing is based on output layout(vertices=...) and/or explicit size
|
||||||
|
//
|
||||||
|
// Both:
|
||||||
|
// - array sizing is retroactive
|
||||||
|
// - built-in block redeclarations interact with this
|
||||||
|
//
|
||||||
|
// Design:
|
||||||
|
// - use a per-context "resize-list", a list of symbols whose array sizes
|
||||||
|
// can be fixed
|
||||||
|
//
|
||||||
|
// - the resize-list starts empty at beginning of user-shader compilation, it does
|
||||||
|
// not have built-ins in it
|
||||||
|
//
|
||||||
|
// - on built-in array use: copyUp() symbol and add it to the resize-list
|
||||||
|
//
|
||||||
|
// - on user array declaration: add it to the resize-list
|
||||||
|
//
|
||||||
|
// - on block redeclaration: copyUp() symbol and add it to the resize-list
|
||||||
|
// * note, that appropriately gives an error if redeclaring a block that
|
||||||
|
// was already used and hence already copied-up
|
||||||
|
//
|
||||||
|
// - on seeing a layout declaration that sizes the array, fix everything in the
|
||||||
|
// resize-list, giving errors for mismatch
|
||||||
|
//
|
||||||
|
// - on seeing an array size declaration, give errors on mismatch between it and previous
|
||||||
|
// array-sizing declarations
|
||||||
|
//
|
||||||
|
TVector<TSymbol*> ioArraySymbolResizeList;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // HLSL_PARSE_INCLUDED_
|
|
@ -0,0 +1,619 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// HLSL scanning, leveraging the scanning done by the preprocessor.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "../glslang/Include/Types.h"
|
||||||
|
#include "../glslang/MachineIndependent/SymbolTable.h"
|
||||||
|
#include "../glslang/MachineIndependent/ParseHelper.h"
|
||||||
|
#include "hlslScanContext.h"
|
||||||
|
#include "hlslTokens.h"
|
||||||
|
//#include "Scan.h"
|
||||||
|
|
||||||
|
// preprocessor includes
|
||||||
|
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
|
||||||
|
#include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct str_eq
|
||||||
|
{
|
||||||
|
bool operator()(const char* lhs, const char* rhs) const
|
||||||
|
{
|
||||||
|
return strcmp(lhs, rhs) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct str_hash
|
||||||
|
{
|
||||||
|
size_t operator()(const char* str) const
|
||||||
|
{
|
||||||
|
// djb2
|
||||||
|
unsigned long hash = 5381;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while ((c = *str++) != 0)
|
||||||
|
hash = ((hash << 5) + hash) + c;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A single global usable by all threads, by all versions, by all languages.
|
||||||
|
// After a single process-level initialization, this is read only and thread safe
|
||||||
|
std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
|
||||||
|
std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
void HlslScanContext::fillInKeywordMap()
|
||||||
|
{
|
||||||
|
if (KeywordMap != nullptr) {
|
||||||
|
// this is really an error, as this should called only once per process
|
||||||
|
// but, the only risk is if two threads called simultaneously
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
|
||||||
|
|
||||||
|
(*KeywordMap)["static"] = EHTokStatic;
|
||||||
|
(*KeywordMap)["const"] = EHTokConst;
|
||||||
|
(*KeywordMap)["unorm"] = EHTokUnorm;
|
||||||
|
(*KeywordMap)["snorm"] = EHTokSNorm;
|
||||||
|
(*KeywordMap)["extern"] = EHTokExtern;
|
||||||
|
(*KeywordMap)["uniform"] = EHTokUniform;
|
||||||
|
(*KeywordMap)["volatile"] = EHTokVolatile;
|
||||||
|
(*KeywordMap)["shared"] = EHTokShared;
|
||||||
|
(*KeywordMap)["groupshared"] = EHTokGroupShared;
|
||||||
|
(*KeywordMap)["linear"] = EHTokLinear;
|
||||||
|
(*KeywordMap)["centroid"] = EHTokCentroid;
|
||||||
|
(*KeywordMap)["nointerpolation"] = EHTokNointerpolation;
|
||||||
|
(*KeywordMap)["noperspective"] = EHTokNoperspective;
|
||||||
|
(*KeywordMap)["sample"] = EHTokSample;
|
||||||
|
(*KeywordMap)["row_major"] = EHTokRowMajor;
|
||||||
|
(*KeywordMap)["column_major"] = EHTokColumnMajor;
|
||||||
|
(*KeywordMap)["packoffset"] = EHTokPackOffset;
|
||||||
|
|
||||||
|
(*KeywordMap)["Buffer"] = EHTokBuffer;
|
||||||
|
(*KeywordMap)["vector"] = EHTokVector;
|
||||||
|
(*KeywordMap)["matrix"] = EHTokMatrix;
|
||||||
|
|
||||||
|
(*KeywordMap)["void"] = EHTokVoid;
|
||||||
|
(*KeywordMap)["bool"] = EHTokBool;
|
||||||
|
(*KeywordMap)["int"] = EHTokInt;
|
||||||
|
(*KeywordMap)["uint"] = EHTokUint;
|
||||||
|
(*KeywordMap)["dword"] = EHTokDword;
|
||||||
|
(*KeywordMap)["half"] = EHTokHalf;
|
||||||
|
(*KeywordMap)["float"] = EHTokFloat;
|
||||||
|
(*KeywordMap)["double"] = EHTokDouble;
|
||||||
|
(*KeywordMap)["min16float"] = EHTokMin16float;
|
||||||
|
(*KeywordMap)["min10float"] = EHTokMin10float;
|
||||||
|
(*KeywordMap)["min16int"] = EHTokMin16int;
|
||||||
|
(*KeywordMap)["min12int"] = EHTokMin12int;
|
||||||
|
(*KeywordMap)["min16uint"] = EHTokMin16int;
|
||||||
|
|
||||||
|
(*KeywordMap)["bool1"] = EHTokBool1;
|
||||||
|
(*KeywordMap)["bool2"] = EHTokBool2;
|
||||||
|
(*KeywordMap)["bool3"] = EHTokBool3;
|
||||||
|
(*KeywordMap)["bool4"] = EHTokBool4;
|
||||||
|
(*KeywordMap)["float1"] = EHTokFloat1;
|
||||||
|
(*KeywordMap)["float2"] = EHTokFloat2;
|
||||||
|
(*KeywordMap)["float3"] = EHTokFloat3;
|
||||||
|
(*KeywordMap)["float4"] = EHTokFloat4;
|
||||||
|
(*KeywordMap)["int1"] = EHTokInt1;
|
||||||
|
(*KeywordMap)["int2"] = EHTokInt2;
|
||||||
|
(*KeywordMap)["int3"] = EHTokInt3;
|
||||||
|
(*KeywordMap)["int4"] = EHTokInt4;
|
||||||
|
(*KeywordMap)["double1"] = EHTokDouble1;
|
||||||
|
(*KeywordMap)["double2"] = EHTokDouble2;
|
||||||
|
(*KeywordMap)["double3"] = EHTokDouble3;
|
||||||
|
(*KeywordMap)["double4"] = EHTokDouble4;
|
||||||
|
(*KeywordMap)["uint1"] = EHTokUint1;
|
||||||
|
(*KeywordMap)["uint2"] = EHTokUint2;
|
||||||
|
(*KeywordMap)["uint3"] = EHTokUint3;
|
||||||
|
(*KeywordMap)["uint4"] = EHTokUint4;
|
||||||
|
|
||||||
|
(*KeywordMap)["int1x1"] = EHTokInt1x1;
|
||||||
|
(*KeywordMap)["int1x2"] = EHTokInt1x2;
|
||||||
|
(*KeywordMap)["int1x3"] = EHTokInt1x3;
|
||||||
|
(*KeywordMap)["int1x4"] = EHTokInt1x4;
|
||||||
|
(*KeywordMap)["int2x1"] = EHTokInt2x1;
|
||||||
|
(*KeywordMap)["int2x2"] = EHTokInt2x2;
|
||||||
|
(*KeywordMap)["int2x3"] = EHTokInt2x3;
|
||||||
|
(*KeywordMap)["int2x4"] = EHTokInt2x4;
|
||||||
|
(*KeywordMap)["int3x1"] = EHTokInt3x1;
|
||||||
|
(*KeywordMap)["int3x2"] = EHTokInt3x2;
|
||||||
|
(*KeywordMap)["int3x3"] = EHTokInt3x3;
|
||||||
|
(*KeywordMap)["int3x4"] = EHTokInt3x4;
|
||||||
|
(*KeywordMap)["int4x1"] = EHTokInt4x1;
|
||||||
|
(*KeywordMap)["int4x2"] = EHTokInt4x2;
|
||||||
|
(*KeywordMap)["int4x3"] = EHTokInt4x3;
|
||||||
|
(*KeywordMap)["int4x4"] = EHTokInt4x4;
|
||||||
|
(*KeywordMap)["float1x1"] = EHTokFloat1x1;
|
||||||
|
(*KeywordMap)["float1x2"] = EHTokFloat1x2;
|
||||||
|
(*KeywordMap)["float1x3"] = EHTokFloat1x3;
|
||||||
|
(*KeywordMap)["float1x4"] = EHTokFloat1x4;
|
||||||
|
(*KeywordMap)["float2x1"] = EHTokFloat2x1;
|
||||||
|
(*KeywordMap)["float2x2"] = EHTokFloat2x2;
|
||||||
|
(*KeywordMap)["float2x3"] = EHTokFloat2x3;
|
||||||
|
(*KeywordMap)["float2x4"] = EHTokFloat2x4;
|
||||||
|
(*KeywordMap)["float3x1"] = EHTokFloat3x1;
|
||||||
|
(*KeywordMap)["float3x2"] = EHTokFloat3x2;
|
||||||
|
(*KeywordMap)["float3x3"] = EHTokFloat3x3;
|
||||||
|
(*KeywordMap)["float3x4"] = EHTokFloat3x4;
|
||||||
|
(*KeywordMap)["float4x1"] = EHTokFloat4x1;
|
||||||
|
(*KeywordMap)["float4x2"] = EHTokFloat4x2;
|
||||||
|
(*KeywordMap)["float4x3"] = EHTokFloat4x3;
|
||||||
|
(*KeywordMap)["float4x4"] = EHTokFloat4x4;
|
||||||
|
(*KeywordMap)["double1x1"] = EHTokDouble1x1;
|
||||||
|
(*KeywordMap)["double1x2"] = EHTokDouble1x2;
|
||||||
|
(*KeywordMap)["double1x3"] = EHTokDouble1x3;
|
||||||
|
(*KeywordMap)["double1x4"] = EHTokDouble1x4;
|
||||||
|
(*KeywordMap)["double2x1"] = EHTokDouble2x1;
|
||||||
|
(*KeywordMap)["double2x2"] = EHTokDouble2x2;
|
||||||
|
(*KeywordMap)["double2x3"] = EHTokDouble2x3;
|
||||||
|
(*KeywordMap)["double2x4"] = EHTokDouble2x4;
|
||||||
|
(*KeywordMap)["double3x1"] = EHTokDouble3x1;
|
||||||
|
(*KeywordMap)["double3x2"] = EHTokDouble3x2;
|
||||||
|
(*KeywordMap)["double3x3"] = EHTokDouble3x3;
|
||||||
|
(*KeywordMap)["double3x4"] = EHTokDouble3x4;
|
||||||
|
(*KeywordMap)["double4x1"] = EHTokDouble4x1;
|
||||||
|
(*KeywordMap)["double4x2"] = EHTokDouble4x2;
|
||||||
|
(*KeywordMap)["double4x3"] = EHTokDouble4x3;
|
||||||
|
(*KeywordMap)["double4x4"] = EHTokDouble4x4;
|
||||||
|
|
||||||
|
(*KeywordMap)["sampler"] = EHTokSampler;
|
||||||
|
(*KeywordMap)["sampler1D"] = EHTokSampler1d;
|
||||||
|
(*KeywordMap)["sampler2D"] = EHTokSampler2d;
|
||||||
|
(*KeywordMap)["sampler3D"] = EHTokSampler3d;
|
||||||
|
(*KeywordMap)["samplerCube"] = EHTokSamplerCube;
|
||||||
|
(*KeywordMap)["sampler_state"] = EHTokSamplerState;
|
||||||
|
(*KeywordMap)["SamplerState"] = EHTokSamplerState;
|
||||||
|
(*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;
|
||||||
|
(*KeywordMap)["texture"] = EHTokTexture;
|
||||||
|
(*KeywordMap)["Texture1D"] = EHTokTexture1d;
|
||||||
|
(*KeywordMap)["Texture1DArray"] = EHTokTexture1darray;
|
||||||
|
(*KeywordMap)["Texture2D"] = EHTokTexture2d;
|
||||||
|
(*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
|
||||||
|
(*KeywordMap)["Texture3D"] = EHTokTexture3d;
|
||||||
|
(*KeywordMap)["TextureCube"] = EHTokTextureCube;
|
||||||
|
|
||||||
|
(*KeywordMap)["struct"] = EHTokStruct;
|
||||||
|
(*KeywordMap)["typedef"] = EHTokTypedef;
|
||||||
|
|
||||||
|
(*KeywordMap)["true"] = EHTokBoolConstant;
|
||||||
|
(*KeywordMap)["false"] = EHTokBoolConstant;
|
||||||
|
|
||||||
|
(*KeywordMap)["for"] = EHTokFor;
|
||||||
|
(*KeywordMap)["do"] = EHTokDo;
|
||||||
|
(*KeywordMap)["while"] = EHTokWhile;
|
||||||
|
(*KeywordMap)["break"] = EHTokBreak;
|
||||||
|
(*KeywordMap)["continue"] = EHTokContinue;
|
||||||
|
(*KeywordMap)["if"] = EHTokIf;
|
||||||
|
(*KeywordMap)["else"] = EHTokElse;
|
||||||
|
(*KeywordMap)["discard"] = EHTokDiscard;
|
||||||
|
(*KeywordMap)["return"] = EHTokReturn;
|
||||||
|
(*KeywordMap)["switch"] = EHTokSwitch;
|
||||||
|
(*KeywordMap)["case"] = EHTokCase;
|
||||||
|
(*KeywordMap)["default"] = EHTokDefault;
|
||||||
|
|
||||||
|
// TODO: get correct set here
|
||||||
|
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
||||||
|
|
||||||
|
ReservedSet->insert("common");
|
||||||
|
ReservedSet->insert("partition");
|
||||||
|
ReservedSet->insert("active");
|
||||||
|
ReservedSet->insert("asm");
|
||||||
|
ReservedSet->insert("class");
|
||||||
|
ReservedSet->insert("union");
|
||||||
|
ReservedSet->insert("enum");
|
||||||
|
ReservedSet->insert("template");
|
||||||
|
ReservedSet->insert("this");
|
||||||
|
ReservedSet->insert("goto");
|
||||||
|
ReservedSet->insert("inline");
|
||||||
|
ReservedSet->insert("noinline");
|
||||||
|
ReservedSet->insert("public");
|
||||||
|
ReservedSet->insert("extern");
|
||||||
|
ReservedSet->insert("external");
|
||||||
|
ReservedSet->insert("interface");
|
||||||
|
ReservedSet->insert("long");
|
||||||
|
ReservedSet->insert("short");
|
||||||
|
ReservedSet->insert("half");
|
||||||
|
ReservedSet->insert("fixed");
|
||||||
|
ReservedSet->insert("unsigned");
|
||||||
|
ReservedSet->insert("input");
|
||||||
|
ReservedSet->insert("output");
|
||||||
|
ReservedSet->insert("filter");
|
||||||
|
ReservedSet->insert("sizeof");
|
||||||
|
ReservedSet->insert("cast");
|
||||||
|
ReservedSet->insert("namespace");
|
||||||
|
ReservedSet->insert("using");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HlslScanContext::deleteKeywordMap()
|
||||||
|
{
|
||||||
|
delete KeywordMap;
|
||||||
|
KeywordMap = nullptr;
|
||||||
|
delete ReservedSet;
|
||||||
|
ReservedSet = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper for tokenizeClass()"] = to get everything inside the token.
|
||||||
|
void HlslScanContext::tokenize(HlslToken& token)
|
||||||
|
{
|
||||||
|
token.isType = false;
|
||||||
|
EHlslTokenClass tokenClass = tokenizeClass(token);
|
||||||
|
token.tokenClass = tokenClass;
|
||||||
|
if (token.isType)
|
||||||
|
afterType = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill in token information for the next token, except for the token class.
|
||||||
|
// Returns the enum value of the token class of the next token found.
|
||||||
|
// Return 0 (EndOfTokens) on end of input.
|
||||||
|
//
|
||||||
|
EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
parserToken = &token;
|
||||||
|
TPpToken ppToken;
|
||||||
|
tokenText = ppContext.tokenize(&ppToken);
|
||||||
|
if (tokenText == nullptr)
|
||||||
|
return EHTokNone;
|
||||||
|
|
||||||
|
loc = ppToken.loc;
|
||||||
|
parserToken->loc = loc;
|
||||||
|
switch (ppToken.token) {
|
||||||
|
case ';': afterType = false; return EHTokSemicolon;
|
||||||
|
case ',': afterType = false; return EHTokComma;
|
||||||
|
case ':': return EHTokColon;
|
||||||
|
case '=': afterType = false; return EHTokEqual;
|
||||||
|
case '(': afterType = false; return EHTokLeftParen;
|
||||||
|
case ')': afterType = false; return EHTokRightParen;
|
||||||
|
case '.': field = true; return EHTokDot;
|
||||||
|
case '!': return EHTokBang;
|
||||||
|
case '-': return EHTokDash;
|
||||||
|
case '~': return EHTokTilde;
|
||||||
|
case '+': return EHTokPlus;
|
||||||
|
case '*': return EHTokStar;
|
||||||
|
case '/': return EHTokSlash;
|
||||||
|
case '%': return EHTokPercent;
|
||||||
|
case '<': return EHTokLeftAngle;
|
||||||
|
case '>': return EHTokRightAngle;
|
||||||
|
case '|': return EHTokVerticalBar;
|
||||||
|
case '^': return EHTokCaret;
|
||||||
|
case '&': return EHTokAmpersand;
|
||||||
|
case '?': return EHTokQuestion;
|
||||||
|
case '[': return EHTokLeftBracket;
|
||||||
|
case ']': return EHTokRightBracket;
|
||||||
|
case '{': return EHTokLeftBrace;
|
||||||
|
case '}': return EHTokRightBrace;
|
||||||
|
case '\\':
|
||||||
|
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PpAtomAdd: return EHTokAddAssign;
|
||||||
|
case PpAtomSub: return EHTokSubAssign;
|
||||||
|
case PpAtomMul: return EHTokMulAssign;
|
||||||
|
case PpAtomDiv: return EHTokDivAssign;
|
||||||
|
case PpAtomMod: return EHTokModAssign;
|
||||||
|
|
||||||
|
case PpAtomRight: return EHTokRightOp;
|
||||||
|
case PpAtomLeft: return EHTokLeftOp;
|
||||||
|
|
||||||
|
case PpAtomRightAssign: return EHTokRightAssign;
|
||||||
|
case PpAtomLeftAssign: return EHTokLeftAssign;
|
||||||
|
case PpAtomAndAssign: return EHTokAndAssign;
|
||||||
|
case PpAtomOrAssign: return EHTokOrAssign;
|
||||||
|
case PpAtomXorAssign: return EHTokXorAssign;
|
||||||
|
|
||||||
|
case PpAtomAnd: return EHTokAndOp;
|
||||||
|
case PpAtomOr: return EHTokOrOp;
|
||||||
|
case PpAtomXor: return EHTokXorOp;
|
||||||
|
|
||||||
|
case PpAtomEQ: return EHTokEqOp;
|
||||||
|
case PpAtomGE: return EHTokGeOp;
|
||||||
|
case PpAtomNE: return EHTokNeOp;
|
||||||
|
case PpAtomLE: return EHTokLeOp;
|
||||||
|
|
||||||
|
case PpAtomDecrement: return EHTokDecOp;
|
||||||
|
case PpAtomIncrement: return EHTokIncOp;
|
||||||
|
|
||||||
|
case PpAtomConstInt: parserToken->i = ppToken.ival; return EHTokIntConstant;
|
||||||
|
case PpAtomConstUint: parserToken->i = ppToken.ival; return EHTokUintConstant;
|
||||||
|
case PpAtomConstFloat: parserToken->d = ppToken.dval; return EHTokFloatConstant;
|
||||||
|
case PpAtomConstDouble: parserToken->d = ppToken.dval; return EHTokDoubleConstant;
|
||||||
|
case PpAtomIdentifier:
|
||||||
|
{
|
||||||
|
EHlslTokenClass token = tokenizeIdentifier();
|
||||||
|
field = false;
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EndOfInput: return EHTokNone;
|
||||||
|
|
||||||
|
default:
|
||||||
|
char buf[2];
|
||||||
|
buf[0] = (char)ppToken.token;
|
||||||
|
buf[1] = 0;
|
||||||
|
parseContext.error(loc, "unexpected token", buf, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
EHlslTokenClass HlslScanContext::tokenizeIdentifier()
|
||||||
|
{
|
||||||
|
if (ReservedSet->find(tokenText) != ReservedSet->end())
|
||||||
|
return reservedWord();
|
||||||
|
|
||||||
|
auto it = KeywordMap->find(tokenText);
|
||||||
|
if (it == KeywordMap->end()) {
|
||||||
|
// Should have an identifier of some sort
|
||||||
|
return identifierOrType();
|
||||||
|
}
|
||||||
|
keyword = it->second;
|
||||||
|
|
||||||
|
switch (keyword) {
|
||||||
|
|
||||||
|
// qualifiers
|
||||||
|
case EHTokStatic:
|
||||||
|
case EHTokConst:
|
||||||
|
case EHTokSNorm:
|
||||||
|
case EHTokUnorm:
|
||||||
|
case EHTokExtern:
|
||||||
|
case EHTokUniform:
|
||||||
|
case EHTokVolatile:
|
||||||
|
case EHTokShared:
|
||||||
|
case EHTokGroupShared:
|
||||||
|
case EHTokLinear:
|
||||||
|
case EHTokCentroid:
|
||||||
|
case EHTokNointerpolation:
|
||||||
|
case EHTokNoperspective:
|
||||||
|
case EHTokSample:
|
||||||
|
case EHTokRowMajor:
|
||||||
|
case EHTokColumnMajor:
|
||||||
|
case EHTokPackOffset:
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
// template types
|
||||||
|
case EHTokBuffer:
|
||||||
|
case EHTokVector:
|
||||||
|
case EHTokMatrix:
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
// scalar types
|
||||||
|
case EHTokVoid:
|
||||||
|
case EHTokBool:
|
||||||
|
case EHTokInt:
|
||||||
|
case EHTokUint:
|
||||||
|
case EHTokDword:
|
||||||
|
case EHTokHalf:
|
||||||
|
case EHTokFloat:
|
||||||
|
case EHTokDouble:
|
||||||
|
case EHTokMin16float:
|
||||||
|
case EHTokMin10float:
|
||||||
|
case EHTokMin16int:
|
||||||
|
case EHTokMin12int:
|
||||||
|
case EHTokMin16uint:
|
||||||
|
|
||||||
|
// vector types
|
||||||
|
case EHTokBool1:
|
||||||
|
case EHTokBool2:
|
||||||
|
case EHTokBool3:
|
||||||
|
case EHTokBool4:
|
||||||
|
case EHTokFloat1:
|
||||||
|
case EHTokFloat2:
|
||||||
|
case EHTokFloat3:
|
||||||
|
case EHTokFloat4:
|
||||||
|
case EHTokInt1:
|
||||||
|
case EHTokInt2:
|
||||||
|
case EHTokInt3:
|
||||||
|
case EHTokInt4:
|
||||||
|
case EHTokDouble1:
|
||||||
|
case EHTokDouble2:
|
||||||
|
case EHTokDouble3:
|
||||||
|
case EHTokDouble4:
|
||||||
|
case EHTokUint1:
|
||||||
|
case EHTokUint2:
|
||||||
|
case EHTokUint3:
|
||||||
|
case EHTokUint4:
|
||||||
|
|
||||||
|
// matrix types
|
||||||
|
case EHTokInt1x1:
|
||||||
|
case EHTokInt1x2:
|
||||||
|
case EHTokInt1x3:
|
||||||
|
case EHTokInt1x4:
|
||||||
|
case EHTokInt2x1:
|
||||||
|
case EHTokInt2x2:
|
||||||
|
case EHTokInt2x3:
|
||||||
|
case EHTokInt2x4:
|
||||||
|
case EHTokInt3x1:
|
||||||
|
case EHTokInt3x2:
|
||||||
|
case EHTokInt3x3:
|
||||||
|
case EHTokInt3x4:
|
||||||
|
case EHTokInt4x1:
|
||||||
|
case EHTokInt4x2:
|
||||||
|
case EHTokInt4x3:
|
||||||
|
case EHTokInt4x4:
|
||||||
|
case EHTokFloat1x1:
|
||||||
|
case EHTokFloat1x2:
|
||||||
|
case EHTokFloat1x3:
|
||||||
|
case EHTokFloat1x4:
|
||||||
|
case EHTokFloat2x1:
|
||||||
|
case EHTokFloat2x2:
|
||||||
|
case EHTokFloat2x3:
|
||||||
|
case EHTokFloat2x4:
|
||||||
|
case EHTokFloat3x1:
|
||||||
|
case EHTokFloat3x2:
|
||||||
|
case EHTokFloat3x3:
|
||||||
|
case EHTokFloat3x4:
|
||||||
|
case EHTokFloat4x1:
|
||||||
|
case EHTokFloat4x2:
|
||||||
|
case EHTokFloat4x3:
|
||||||
|
case EHTokFloat4x4:
|
||||||
|
case EHTokDouble1x1:
|
||||||
|
case EHTokDouble1x2:
|
||||||
|
case EHTokDouble1x3:
|
||||||
|
case EHTokDouble1x4:
|
||||||
|
case EHTokDouble2x1:
|
||||||
|
case EHTokDouble2x2:
|
||||||
|
case EHTokDouble2x3:
|
||||||
|
case EHTokDouble2x4:
|
||||||
|
case EHTokDouble3x1:
|
||||||
|
case EHTokDouble3x2:
|
||||||
|
case EHTokDouble3x3:
|
||||||
|
case EHTokDouble3x4:
|
||||||
|
case EHTokDouble4x1:
|
||||||
|
case EHTokDouble4x2:
|
||||||
|
case EHTokDouble4x3:
|
||||||
|
case EHTokDouble4x4:
|
||||||
|
parserToken->isType = true;
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
// texturing types
|
||||||
|
case EHTokSampler:
|
||||||
|
case EHTokSampler1d:
|
||||||
|
case EHTokSampler2d:
|
||||||
|
case EHTokSampler3d:
|
||||||
|
case EHTokSamplerCube:
|
||||||
|
case EHTokSamplerState:
|
||||||
|
case EHTokSamplerComparisonState:
|
||||||
|
case EHTokTexture:
|
||||||
|
case EHTokTexture1d:
|
||||||
|
case EHTokTexture1darray:
|
||||||
|
case EHTokTexture2d:
|
||||||
|
case EHTokTexture2darray:
|
||||||
|
case EHTokTexture3d:
|
||||||
|
case EHTokTextureCube:
|
||||||
|
parserToken->isType = true;
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
// variable, user type, ...
|
||||||
|
case EHTokStruct:
|
||||||
|
case EHTokTypedef:
|
||||||
|
|
||||||
|
case EHTokBoolConstant:
|
||||||
|
if (strcmp("true", tokenText) == 0)
|
||||||
|
parserToken->b = true;
|
||||||
|
else
|
||||||
|
parserToken->b = false;
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
// control flow
|
||||||
|
case EHTokFor:
|
||||||
|
case EHTokDo:
|
||||||
|
case EHTokWhile:
|
||||||
|
case EHTokBreak:
|
||||||
|
case EHTokContinue:
|
||||||
|
case EHTokIf:
|
||||||
|
case EHTokElse:
|
||||||
|
case EHTokDiscard:
|
||||||
|
case EHTokReturn:
|
||||||
|
case EHTokCase:
|
||||||
|
case EHTokSwitch:
|
||||||
|
case EHTokDefault:
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
default:
|
||||||
|
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
|
||||||
|
return EHTokNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EHlslTokenClass HlslScanContext::identifierOrType()
|
||||||
|
{
|
||||||
|
parserToken->string = NewPoolTString(tokenText);
|
||||||
|
if (field)
|
||||||
|
return EHTokIdentifier;
|
||||||
|
|
||||||
|
parserToken->symbol = parseContext.symbolTable.find(*parserToken->string);
|
||||||
|
if (afterType == false && parserToken->symbol) {
|
||||||
|
if (const TVariable* variable = parserToken->symbol->getAsVariable()) {
|
||||||
|
if (variable->isUserType()) {
|
||||||
|
afterType = true;
|
||||||
|
|
||||||
|
return EHTokTypeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EHTokIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give an error for use of a reserved symbol.
|
||||||
|
// However, allow built-in declarations to use reserved words, to allow
|
||||||
|
// extension support before the extension is enabled.
|
||||||
|
EHlslTokenClass HlslScanContext::reservedWord()
|
||||||
|
{
|
||||||
|
if (! parseContext.symbolTable.atBuiltInLevel())
|
||||||
|
parseContext.error(loc, "Reserved word.", tokenText, "", "");
|
||||||
|
|
||||||
|
return EHTokNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
EHlslTokenClass HlslScanContext::identifierOrReserved(bool reserved)
|
||||||
|
{
|
||||||
|
if (reserved) {
|
||||||
|
reservedWord();
|
||||||
|
|
||||||
|
return EHTokNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseContext.forwardCompatible)
|
||||||
|
parseContext.warn(loc, "using future reserved keyword", tokenText, "");
|
||||||
|
|
||||||
|
return identifierOrType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For a keyword that was never reserved, until it suddenly
|
||||||
|
// showed up.
|
||||||
|
EHlslTokenClass HlslScanContext::nonreservedKeyword(int version)
|
||||||
|
{
|
||||||
|
if (parseContext.version < version)
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
|
return keyword;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
|
@ -0,0 +1,102 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// This holds context specific to the GLSL scanner, which
|
||||||
|
// sits between the preprocessor scanner and parser.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HLSLSCANCONTEXT_H_
|
||||||
|
#define HLSLSCANCONTEXT_H_
|
||||||
|
|
||||||
|
#include "../glslang/MachineIndependent/ParseHelper.h"
|
||||||
|
#include "hlslTokens.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
class TPpContext;
|
||||||
|
class TPpToken;
|
||||||
|
|
||||||
|
struct HlslToken {
|
||||||
|
TSourceLoc loc;
|
||||||
|
EHlslTokenClass tokenClass;
|
||||||
|
bool isType;
|
||||||
|
union {
|
||||||
|
glslang::TString *string;
|
||||||
|
int i;
|
||||||
|
unsigned int u;
|
||||||
|
bool b;
|
||||||
|
double d;
|
||||||
|
};
|
||||||
|
glslang::TSymbol* symbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HlslScanContext {
|
||||||
|
public:
|
||||||
|
HlslScanContext(TParseContextBase& parseContext, TPpContext& ppContext)
|
||||||
|
: parseContext(parseContext), ppContext(ppContext), afterType(false), field(false) { }
|
||||||
|
virtual ~HlslScanContext() { }
|
||||||
|
|
||||||
|
static void fillInKeywordMap();
|
||||||
|
static void deleteKeywordMap();
|
||||||
|
|
||||||
|
void tokenize(HlslToken&);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HlslScanContext(HlslScanContext&);
|
||||||
|
HlslScanContext& operator=(HlslScanContext&);
|
||||||
|
|
||||||
|
EHlslTokenClass tokenizeClass(HlslToken&);
|
||||||
|
EHlslTokenClass tokenizeIdentifier();
|
||||||
|
EHlslTokenClass identifierOrType();
|
||||||
|
EHlslTokenClass reservedWord();
|
||||||
|
EHlslTokenClass identifierOrReserved(bool reserved);
|
||||||
|
EHlslTokenClass nonreservedKeyword(int version);
|
||||||
|
|
||||||
|
TParseContextBase& parseContext;
|
||||||
|
TPpContext& ppContext;
|
||||||
|
bool afterType; // true if we've recognized a type, so can only be looking for an identifier
|
||||||
|
bool field; // true if we're on a field, right after a '.'
|
||||||
|
TSourceLoc loc;
|
||||||
|
TPpToken* ppToken;
|
||||||
|
HlslToken* parserToken;
|
||||||
|
|
||||||
|
const char* tokenText;
|
||||||
|
EHlslTokenClass keyword;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // HLSLSCANCONTEXT_H_
|
|
@ -0,0 +1,248 @@
|
||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef EHLSLTOKENS_H_
|
||||||
|
#define EHLSLTOKENS_H_
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
enum EHlslTokenClass {
|
||||||
|
EHTokNone = 0,
|
||||||
|
|
||||||
|
// qualifiers
|
||||||
|
EHTokStatic,
|
||||||
|
EHTokConst,
|
||||||
|
EHTokSNorm,
|
||||||
|
EHTokUnorm,
|
||||||
|
EHTokExtern,
|
||||||
|
EHTokUniform,
|
||||||
|
EHTokVolatile,
|
||||||
|
EHTokShared,
|
||||||
|
EHTokGroupShared,
|
||||||
|
EHTokLinear,
|
||||||
|
EHTokCentroid,
|
||||||
|
EHTokNointerpolation,
|
||||||
|
EHTokNoperspective,
|
||||||
|
EHTokSample,
|
||||||
|
EHTokRowMajor,
|
||||||
|
EHTokColumnMajor,
|
||||||
|
EHTokPackOffset,
|
||||||
|
|
||||||
|
// template types
|
||||||
|
EHTokBuffer,
|
||||||
|
EHTokVector,
|
||||||
|
EHTokMatrix,
|
||||||
|
|
||||||
|
// scalar types
|
||||||
|
EHTokVoid,
|
||||||
|
EHTokBool,
|
||||||
|
EHTokInt,
|
||||||
|
EHTokUint,
|
||||||
|
EHTokDword,
|
||||||
|
EHTokHalf,
|
||||||
|
EHTokFloat,
|
||||||
|
EHTokDouble,
|
||||||
|
EHTokMin16float,
|
||||||
|
EHTokMin10float,
|
||||||
|
EHTokMin16int,
|
||||||
|
EHTokMin12int,
|
||||||
|
EHTokMin16uint,
|
||||||
|
|
||||||
|
// vector types
|
||||||
|
EHTokBool1,
|
||||||
|
EHTokBool2,
|
||||||
|
EHTokBool3,
|
||||||
|
EHTokBool4,
|
||||||
|
EHTokFloat1,
|
||||||
|
EHTokFloat2,
|
||||||
|
EHTokFloat3,
|
||||||
|
EHTokFloat4,
|
||||||
|
EHTokInt1,
|
||||||
|
EHTokInt2,
|
||||||
|
EHTokInt3,
|
||||||
|
EHTokInt4,
|
||||||
|
EHTokDouble1,
|
||||||
|
EHTokDouble2,
|
||||||
|
EHTokDouble3,
|
||||||
|
EHTokDouble4,
|
||||||
|
EHTokUint1,
|
||||||
|
EHTokUint2,
|
||||||
|
EHTokUint3,
|
||||||
|
EHTokUint4,
|
||||||
|
|
||||||
|
// matrix types
|
||||||
|
EHTokInt1x1,
|
||||||
|
EHTokInt1x2,
|
||||||
|
EHTokInt1x3,
|
||||||
|
EHTokInt1x4,
|
||||||
|
EHTokInt2x1,
|
||||||
|
EHTokInt2x2,
|
||||||
|
EHTokInt2x3,
|
||||||
|
EHTokInt2x4,
|
||||||
|
EHTokInt3x1,
|
||||||
|
EHTokInt3x2,
|
||||||
|
EHTokInt3x3,
|
||||||
|
EHTokInt3x4,
|
||||||
|
EHTokInt4x1,
|
||||||
|
EHTokInt4x2,
|
||||||
|
EHTokInt4x3,
|
||||||
|
EHTokInt4x4,
|
||||||
|
EHTokFloat1x1,
|
||||||
|
EHTokFloat1x2,
|
||||||
|
EHTokFloat1x3,
|
||||||
|
EHTokFloat1x4,
|
||||||
|
EHTokFloat2x1,
|
||||||
|
EHTokFloat2x2,
|
||||||
|
EHTokFloat2x3,
|
||||||
|
EHTokFloat2x4,
|
||||||
|
EHTokFloat3x1,
|
||||||
|
EHTokFloat3x2,
|
||||||
|
EHTokFloat3x3,
|
||||||
|
EHTokFloat3x4,
|
||||||
|
EHTokFloat4x1,
|
||||||
|
EHTokFloat4x2,
|
||||||
|
EHTokFloat4x3,
|
||||||
|
EHTokFloat4x4,
|
||||||
|
EHTokDouble1x1,
|
||||||
|
EHTokDouble1x2,
|
||||||
|
EHTokDouble1x3,
|
||||||
|
EHTokDouble1x4,
|
||||||
|
EHTokDouble2x1,
|
||||||
|
EHTokDouble2x2,
|
||||||
|
EHTokDouble2x3,
|
||||||
|
EHTokDouble2x4,
|
||||||
|
EHTokDouble3x1,
|
||||||
|
EHTokDouble3x2,
|
||||||
|
EHTokDouble3x3,
|
||||||
|
EHTokDouble3x4,
|
||||||
|
EHTokDouble4x1,
|
||||||
|
EHTokDouble4x2,
|
||||||
|
EHTokDouble4x3,
|
||||||
|
EHTokDouble4x4,
|
||||||
|
|
||||||
|
// texturing types
|
||||||
|
EHTokSampler,
|
||||||
|
EHTokSampler1d,
|
||||||
|
EHTokSampler2d,
|
||||||
|
EHTokSampler3d,
|
||||||
|
EHTokSamplerCube,
|
||||||
|
EHTokSamplerState,
|
||||||
|
EHTokSamplerComparisonState,
|
||||||
|
EHTokTexture,
|
||||||
|
EHTokTexture1d,
|
||||||
|
EHTokTexture1darray,
|
||||||
|
EHTokTexture2d,
|
||||||
|
EHTokTexture2darray,
|
||||||
|
EHTokTexture3d,
|
||||||
|
EHTokTextureCube,
|
||||||
|
|
||||||
|
// variable, user type, ...
|
||||||
|
EHTokIdentifier,
|
||||||
|
EHTokTypeName,
|
||||||
|
EHTokStruct,
|
||||||
|
EHTokTypedef,
|
||||||
|
|
||||||
|
// constant
|
||||||
|
EHTokFloatConstant,
|
||||||
|
EHTokDoubleConstant,
|
||||||
|
EHTokIntConstant,
|
||||||
|
EHTokUintConstant,
|
||||||
|
EHTokBoolConstant,
|
||||||
|
|
||||||
|
// control flow
|
||||||
|
EHTokFor,
|
||||||
|
EHTokDo,
|
||||||
|
EHTokWhile,
|
||||||
|
EHTokBreak,
|
||||||
|
EHTokContinue,
|
||||||
|
EHTokIf,
|
||||||
|
EHTokElse,
|
||||||
|
EHTokDiscard,
|
||||||
|
EHTokReturn,
|
||||||
|
EHTokSwitch,
|
||||||
|
EHTokCase,
|
||||||
|
EHTokDefault,
|
||||||
|
|
||||||
|
// expressions
|
||||||
|
EHTokLeftOp,
|
||||||
|
EHTokRightOp,
|
||||||
|
EHTokIncOp,
|
||||||
|
EHTokDecOp,
|
||||||
|
EHTokLeOp,
|
||||||
|
EHTokGeOp,
|
||||||
|
EHTokEqOp,
|
||||||
|
EHTokNeOp,
|
||||||
|
EHTokAndOp,
|
||||||
|
EHTokOrOp,
|
||||||
|
EHTokXorOp,
|
||||||
|
EHTokMulAssign,
|
||||||
|
EHTokDivAssign,
|
||||||
|
EHTokAddAssign,
|
||||||
|
EHTokModAssign,
|
||||||
|
EHTokLeftAssign,
|
||||||
|
EHTokRightAssign,
|
||||||
|
EHTokAndAssign,
|
||||||
|
EHTokXorAssign,
|
||||||
|
EHTokOrAssign,
|
||||||
|
EHTokSubAssign,
|
||||||
|
EHTokLeftParen,
|
||||||
|
EHTokRightParen,
|
||||||
|
EHTokLeftBracket,
|
||||||
|
EHTokRightBracket,
|
||||||
|
EHTokLeftBrace,
|
||||||
|
EHTokRightBrace,
|
||||||
|
EHTokDot,
|
||||||
|
EHTokComma,
|
||||||
|
EHTokColon,
|
||||||
|
EHTokEqual,
|
||||||
|
EHTokSemicolon,
|
||||||
|
EHTokBang,
|
||||||
|
EHTokDash,
|
||||||
|
EHTokTilde,
|
||||||
|
EHTokPlus,
|
||||||
|
EHTokStar,
|
||||||
|
EHTokSlash,
|
||||||
|
EHTokPercent,
|
||||||
|
EHTokLeftAngle,
|
||||||
|
EHTokRightAngle,
|
||||||
|
EHTokVerticalBar,
|
||||||
|
EHTokCaret,
|
||||||
|
EHTokAmpersand,
|
||||||
|
EHTokQuestion,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // EHLSLTOKENS_H_
|
Загрузка…
Ссылка в новой задаче