HLSL: Plumb in HLSL parse context and keywords, and most basic HLSL parser and test.

This commit is contained in:
John Kessenich 2016-03-12 20:11:22 -07:00
parent b3dc3acd59
commit e01a9bc8c0
16 changed files with 5047 additions and 16 deletions

View file

@ -46,6 +46,7 @@
#include <sstream>
#include "SymbolTable.h"
#include "ParseHelper.h"
#include "../../hlsl/hlslParseHelper.h"
#include "Scan.h"
#include "ScanContext.h"
@ -598,26 +599,37 @@ bool ProcessDeferred(
// Now we can process the full shader under proper symbols and rules.
//
intermediate.setEntryPoint("main");
TParseContext parseContext(symbolTable, intermediate, false, version, profile, spv, vulkan, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
glslang::TScanContext scanContext(parseContext);
TPpContext ppContext(parseContext, includer);
parseContext.setScanContext(&scanContext);
parseContext.setPpContext(&ppContext);
parseContext.setLimits(*resources);
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");
parseContext = new TParseContext(symbolTable, intermediate, false, version, profile, spv, vulkan,
compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
}
TPpContext ppContext(*parseContext, includer);
// 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)
parseContext.addError();
parseContext->addError();
if (warnVersionNotFirst) {
TSourceLoc loc;
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.
strings[0] = parseContext.getPreamble();
strings[0] = parseContext->getPreamble();
lengths[0] = strlen(strings[0]);
names[0] = nullptr;
strings[1] = customPreamble;
@ -635,14 +647,14 @@ bool ProcessDeferred(
// Push a new symbol allocation scope that will get used for the shader's globals.
symbolTable.push();
bool success = processingContext(parseContext, ppContext, fullInput,
bool success = processingContext(*parseContext, ppContext, fullInput,
versionWillBeError, symbolTable,
intermediate, optLevel, messages);
// Clean up the symbol table. The AST is self-sufficient now.
delete symbolTableMemory;
delete parseContext;
delete [] lengths;
delete [] strings;
delete [] names;

View file

@ -69,6 +69,18 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
//
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;
numErrors += unit.numErrors;
numPushConstants += unit.numPushConstants;
@ -355,8 +367,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
// Also, lock in defaults of things not set, including array sizes.
//
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");
if (numPushConstants > 1)