// Command-line options
enum TOptions {
- EOptionNone = 0x0000,
- EOptionIntermediate = 0x0001,
- EOptionSuppressInfolog = 0x0002,
- EOptionMemoryLeakMode = 0x0004,
- EOptionRelaxedErrors = 0x0008,
- EOptionGiveWarnings = 0x0010,
- EOptionLinkProgram = 0x0020,
- EOptionMultiThreaded = 0x0040,
- EOptionDumpConfig = 0x0080,
- EOptionDumpReflection = 0x0100,
- EOptionSuppressWarnings = 0x0200,
- EOptionDumpVersions = 0x0400,
- EOptionSpv = 0x0800,
- EOptionHumanReadableSpv = 0x1000,
- EOptionVulkanRules = 0x2000,
- EOptionDefaultDesktop = 0x4000,
- EOptionOutputPreprocessed = 0x8000,
- EOptionOutputHexadecimal = 0x10000,
- EOptionReadHlsl = 0x20000,
+ EOptionNone = 0,
+ EOptionIntermediate = (1 << 0),
+ EOptionSuppressInfolog = (1 << 1),
+ EOptionMemoryLeakMode = (1 << 2),
+ EOptionRelaxedErrors = (1 << 3),
+ EOptionGiveWarnings = (1 << 4),
+ EOptionLinkProgram = (1 << 5),
+ EOptionMultiThreaded = (1 << 6),
+ EOptionDumpConfig = (1 << 7),
+ EOptionDumpReflection = (1 << 8),
+ EOptionSuppressWarnings = (1 << 9),
+ EOptionDumpVersions = (1 << 10),
+ EOptionSpv = (1 << 11),
+ EOptionHumanReadableSpv = (1 << 12),
+ EOptionVulkanRules = (1 << 13),
+ EOptionDefaultDesktop = (1 << 14),
+ EOptionOutputPreprocessed = (1 << 15),
+ EOptionOutputHexadecimal = (1 << 16),
+ EOptionReadHlsl = (1 << 17),
+ EOptionCascadingErrors = (1 << 18),
};
//
case 'c':
Options |= EOptionDumpConfig;
break;
+ case 'C':
+ Options |= EOptionCascadingErrors;
+ break;
case 'd':
Options |= EOptionDefaultDesktop;
break;
messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
if (Options & EOptionReadHlsl)
messages = (EShMessages)(messages | EShMsgReadHlsl);
+ if (Options & EOptionCascadingErrors)
+ messages = (EShMessages)(messages | EShMsgCascadingErrors);
}
//
" errors will appear on stderr.\n"
" -c configuration dump;\n"
" creates the default configuration file (redirect to a .conf file)\n"
+ " -C cascading errors; risks crashes from accumulation of error recoveries\n"
" -d default to desktop (#version 110) when there is no shader #version\n"
" (default is ES version 100)\n"
" -D input is HLSL\n"
# reflection tests
#
echo Running reflection...
-$EXE -l -q reflection.vert > $TARGETDIR/reflection.vert.out
+$EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
#
# multi-threaded test
#
echo Comparing single thread to multithread for all tests in current directory...
-$EXE -i *.vert *.geom *.frag *.tes* *.comp > singleThread.out
-$EXE -i *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out
+$EXE -i -C *.vert *.geom *.frag *.tes* *.comp > singleThread.out
+$EXE -i -C *.vert *.geom *.frag *.tes* *.comp -t > multiThread.out
diff singleThread.out multiThread.out || HASERROR=1
if [ $HASERROR -eq 0 ]
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
va_end(args);
+
+ if ((messages & EShMsgCascadingErrors) == 0)
+ currentScanner->setEndOfInput();
}
void C_DECL TParseContext::warn(const TSourceLoc& loc, const char* szReason, const char* szToken,
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
va_end(args);
+
+ if ((messages & EShMsgCascadingErrors) == 0)
+ currentScanner->setEndOfInput();
}
void C_DECL TParseContext::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken,
namespace glslang {
-// Use a global end-of-input character, so no tranlation is needed across
+// Use a global end-of-input character, so no translation is needed across
// layers of encapsulation. Characters are all 8 bit, and positive, so there is
// no aliasing of character 255 onto -1, for example.
const int EndOfInput = -1;
int get()
{
int ret = peek();
- if (ret == EndOfInput) return ret;
+ if (ret == EndOfInput)
+ return ret;
++loc[currentSource].column;
++logicalSourceLoc.column;
if (ret == '\n') {
void unget()
{
// Do not roll back once we've reached the end of the file.
- if (endOfFileReached) return;
+ if (endOfFileReached)
+ return;
if (currentChar > 0) {
--currentChar;
loc[getLastValidSourceIndex()].column = col;
}
+ void setEndOfInput()
+ {
+ endOfFileReached = true;
+ currentSource = numSources;
+ }
+
const TSourceLoc& getSourceLoc() const
{
if (singleLogical) {
bool singleLogical; // treats the strings as a single logical string.
// locations will be reported from the first string.
- // set to true once peak() returns EndOfFile, so that we won't roll back
+ // Set to true once peek() returns EndOfFile, so that we won't roll back
// once we've reached EndOfFile.
bool endOfFileReached;
};
explicit DoPreprocessing(std::string* string): outputString(string) {}
bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
TInputScanner& input, bool versionWillBeError,
- TSymbolTable& , TIntermediate& ,
- EShOptimizationLevel , EShMessages )
+ TSymbolTable&, TIntermediate&,
+ EShOptimizationLevel, EShMessages)
{
// This is a list of tokens that do not require a space before or after.
static const std::string unNeededSpaceTokens = ";()[]";
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics
+ EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit
};
//
INSTANTIATE_TEST_CASE_P(
Glsl, ConfigTest,
::testing::ValuesIn(std::vector<TestCaseSpec>({
- {"specExamples.vert", "baseResults/test.conf", "specExamples.vert.out", EShMsgAST},
- {"100Limits.vert", "100.conf", "100LimitsConf.vert.out", EShMsgDefault},
+ {"specExamples.vert", "baseResults/test.conf", "specExamples.vert.out", (EShMessages)(EShMsgAST | EShMsgCascadingErrors)},
+ {"100Limits.vert", "100.conf", "100LimitsConf.vert.out", EShMsgCascadingErrors},
})),
);
// clang-format on
// gets fixed.
class GlslangInitializer {
public:
- GlslangInitializer() : lastMessages(EShMsgDefault)
+ GlslangInitializer() : lastMessages(EShMsgCascadingErrors)
{
glslang::InitializeProcess();
}
{
const auto& fileNames = GetParam();
const size_t fileCount = fileNames.size();
- const EShMessages controls = DeriveOptions(
- Source::GLSL, Semantics::OpenGL, Target::AST);
+ const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::OpenGL, Target::AST);
GlslangResult result;
// Compile each input shader file.
EShMessages DeriveOptions(Source source, Semantics semantics, Target target)
{
- EShMessages result = EShMsgDefault;
+ EShMessages result = EShMsgCascadingErrors;
switch (source) {
case Source::GLSL:
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
const EShMessages controls = DeriveOptions(source, semantics, target);
- GlslangResult result =
- compileAndLink(testName, input, entryPointName, controls);
+ GlslangResult result = compileAndLink(testName, input, entryPointName, controls);
// Generate the hybrid output in the way of glslangValidator.
std::ostringstream stream;
glslang::TShader::ForbidInclude includer;
const bool success = shader.preprocess(
&glslang::DefaultTBuiltInResource, defaultVersion, defaultProfile,
- forceVersionProfile, isForwardCompatible, EShMsgOnlyPreprocessor,
+ forceVersionProfile, isForwardCompatible, (EShMessages)(EShMsgOnlyPreprocessor | EShMsgCascadingErrors),
&ppShader, includer);
std::string log = shader.getInfoLog();