Commit aae1ad82 by Andrew Woloszyn

Added error output to the preprocessor.

This patch distinguishes preprocessing errors with normal parsing errors and gives glslangValidator the ability to output preprocessing errors.
parent 3a194f7b
......@@ -611,6 +611,8 @@ void SetMessageOptions(EShMessages& messages)
messages = (EShMessages)(messages | EShMsgSpvRules);
if (Options & EOptionVulkanRules)
messages = (EShMessages)(messages | EShMsgVulkanRules);
if (Options & EOptionOutputPreprocessed)
messages = (EShMessages)(messages | EShMsgOnlyPreprocessor);
}
//
......@@ -645,13 +647,22 @@ const char* GlslStd450DebugNames[GLSL_STD_450::Count];
// Outputs the given string, but only if it is non-null and non-empty.
// This prevents erroneous newlines from appearing.
void puts_if_non_empty(const char* str)
void PutsIfNonEmpty(const char* str)
{
if (str && str[0]) {
puts(str);
}
}
// Outputs the given string to stderr, but only if it is non-null and non-empty.
// This prevents erroneous newlines from appearing.
void StderrIfNonEmpty(const char* str)
{
if (str && str[0]) {
fprintf(stderr, "%s\n", str);
}
}
//
// For linking mode: Will independently parse each item in the worklist, but then put them
// in the same program and link them together.
......@@ -689,8 +700,14 @@ void CompileAndLinkShaders()
shader->setStrings(shaderStrings, 1);
if (Options & EOptionOutputPreprocessed) {
std::string str;
shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, messages, &str);
puts(str.c_str());
if (shader->preprocess(&Resources, defaultVersion, ENoProfile,
false, false, messages, &str)) {
PutsIfNonEmpty(str.c_str());
} else {
CompileFailed = true;
}
StderrIfNonEmpty(shader->getInfoLog());
StderrIfNonEmpty(shader->getInfoDebugLog());
FreeFileData(shaderStrings);
continue;
}
......@@ -700,9 +717,9 @@ void CompileAndLinkShaders()
program.addShader(shader);
if (! (Options & EOptionSuppressInfolog)) {
puts_if_non_empty(workItem->name.c_str());
puts_if_non_empty(shader->getInfoLog());
puts_if_non_empty(shader->getInfoDebugLog());
PutsIfNonEmpty(workItem->name.c_str());
PutsIfNonEmpty(shader->getInfoLog());
PutsIfNonEmpty(shader->getInfoDebugLog());
}
FreeFileData(shaderStrings);
......@@ -716,8 +733,8 @@ void CompileAndLinkShaders()
LinkFailed = true;
if (! (Options & EOptionSuppressInfolog)) {
puts_if_non_empty(program.getInfoLog());
puts_if_non_empty(program.getInfoDebugLog());
PutsIfNonEmpty(program.getInfoLog());
PutsIfNonEmpty(program.getInfoDebugLog());
}
if (Options & EOptionDumpReflection) {
......@@ -814,8 +831,8 @@ int C_DECL main(int argc, char* argv[])
for (int w = 0; w < NumWorkItems; ++w) {
if (Work[w]) {
if (printShaderNames)
puts_if_non_empty(Work[w]->name.c_str());
puts_if_non_empty(Work[w]->results.c_str());
PutsIfNonEmpty(Work[w]->name.c_str());
PutsIfNonEmpty(Work[w]->results.c_str());
delete Work[w];
}
}
......@@ -943,7 +960,8 @@ void usage()
" -G create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
" default file name is <stage>.spv (-o overrides this)\n"
" -H print human readable form of SPIR-V; turns on -V\n"
" -E print pre-processed GLSL; cannot be used with -l.\n"
" -E print pre-processed GLSL; cannot be used with -l;\n"
" errors will appear on stderr.\n"
" -c configuration dump;\n"
" creates the default configuration file (redirect to a .conf file)\n"
" -d default to desktop (#version 110) when there is no shader #version\n"
......
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
ERROR: 0:9: '#error' : This should show up in pp output .
ERROR: 0:14: '#' : invalid directive: def
ERROR: 0:15: 'preprocessor evaluation' : undefined macro in expression not allowed in es profile Y
ERROR: 0:21: '' : missing #endif
ERROR: 4 compilation errors. No code generated.
#version 310 es
#error This should show up in pp output .
int main(){
}
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
WARNING: 0:5: '#extension' : extension is only partially supported: GL_EXT_gpu_shader5
WARNING: 0:6: '#extension' : extension not supported: GL_EXT_shader_texture_image_samples
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
Warning, version 310 is not yet complete; most version-specific features are present, but some are missing.
#version 310 es
#define X
#define X 1
#if X
#if Y
#ifdef Y
#error This should not show up in pp output.
#endif
#error This should show up in pp output.
......@@ -11,5 +11,10 @@
#error This should not show up in pp output.
#endif
#def X
#if Y
#extension a
int main() {
}
int x() {
something that shouldnt compile;
}
......@@ -61,8 +61,9 @@ rm -f comp.spv frag.spv geom.spv tesc.spv tese.spv vert.spv
while read t; do
echo Running Preprocessor $t...
b=`basename $t`
$EXE -E $t > $TARGETDIR/$b.out
$EXE -E $t > $TARGETDIR/$b.out 2> $TARGETDIR/$b.err
diff -b $BASEDIR/$b.out $TARGETDIR/$b.out || HASERROR=1
diff -b $BASEDIR/$b.err $TARGETDIR/$b.err || HASERROR=1
done < test-preprocessor-list
#
......
......@@ -5,3 +5,4 @@ preprocessor.function_macro.vert
preprocessor.line.vert
preprocessor.pragma.vert
preprocessor.simple.vert
preprocessor.success_if_parse_would_fail.vert
......@@ -341,24 +341,35 @@ bool TParseContext::parseVectorFields(TSourceLoc loc, const TString& compString,
//
// Used to output syntax, parsing, and semantic errors.
//
void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...)
void TParseContext::outputMessage(TSourceLoc loc, const char* szReason,
const char* szToken,
const char* szExtraInfoFormat,
TPrefixType prefix, va_list args)
{
const int maxSize = GlslangMaxTokenLength + 200;
char szExtraInfo[maxSize];
va_list marker;
va_start(marker, szExtraInfoFormat);
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
infoSink.info.prefix(EPrefixError);
infoSink.info.prefix(prefix);
infoSink.info.location(loc);
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
va_end(marker);
if (prefix == EPrefixError) {
++numErrors;
}
}
++numErrors;
void C_DECL TParseContext::error(TSourceLoc loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...)
{
if (messages & EShMsgOnlyPreprocessor)
return;
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
va_end(args);
}
void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char* szToken,
......@@ -366,20 +377,28 @@ void C_DECL TParseContext::warn(TSourceLoc loc, const char* szReason, const char
{
if (suppressWarnings())
return;
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
va_end(args);
}
const int maxSize = GlslangMaxTokenLength + 200;
char szExtraInfo[maxSize];
va_list marker;
va_start(marker, szExtraInfoFormat);
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, marker);
infoSink.info.prefix(EPrefixWarning);
infoSink.info.location(loc);
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
void C_DECL TParseContext::ppError(TSourceLoc loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...)
{
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
va_end(args);
}
va_end(marker);
void C_DECL TParseContext::ppWarn(TSourceLoc loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...)
{
va_list args;
va_start(args, szExtraInfoFormat);
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
va_end(args);
}
//
......@@ -1815,18 +1834,18 @@ void TParseContext::reservedPpErrorCheck(TSourceLoc loc, const char* identifier,
// compile-time error."
// however, before that, ES tests required an error.
if (strncmp(identifier, "GL_", 3) == 0)
error(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
else if (strstr(identifier, "__") != 0) {
if (profile == EEsProfile && version >= 300 &&
(strcmp(identifier, "__LINE__") == 0 ||
strcmp(identifier, "__FILE__") == 0 ||
strcmp(identifier, "__VERSION__") == 0))
error(loc, "predefined names can't be (un)defined:", op, identifier);
ppError(loc, "predefined names can't be (un)defined:", op, identifier);
else {
if (profile == EEsProfile && version <= 300)
error(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier);
ppError(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier);
else
warn(loc, "names containing consecutive underscores are reserved:", op, identifier);
ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier);
}
}
}
......
......@@ -78,6 +78,10 @@ public:
const char* szExtraInfoFormat, ...);
void C_DECL warn(TSourceLoc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
void C_DECL ppError(TSourceLoc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
void C_DECL ppWarn(TSourceLoc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
......@@ -249,6 +253,9 @@ protected:
TOperator mapTypeToConstructorOp(const TType&) const;
void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
void finalErrorCheck();
void outputMessage(TSourceLoc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, TPrefixType prefix,
va_list args);
public:
//
......
......@@ -714,7 +714,13 @@ struct DoPreprocessing {
outputStream << std::endl;
*outputString = outputStream.str();
return true;
bool success = true;
if (parseContext.getNumErrors() > 0) {
success = false;
parseContext.infoSink.info.prefix(EPrefixError);
parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n";
}
return success;
}
std::string* outputString;
};
......
......@@ -134,7 +134,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
// get macro name
int token = scanToken(ppToken);
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "must be followed by macro name", "#define", "");
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
return token;
}
int atom = ppToken->atom;
......@@ -154,7 +154,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
if (argc == 0 && token == ')')
break;
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "bad argument", "#define", "");
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
return token;
}
......@@ -162,7 +162,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
bool duplicate = false;
for (int a = 0; a < argc; ++a) {
if (args[a] == ppToken->atom) {
parseContext.error(ppToken->loc, "duplicate macro parameter", "#define", "");
parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
duplicate = true;
break;
}
......@@ -171,12 +171,12 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
if (argc < maxMacroArgs)
args[argc++] = ppToken->atom;
else
parseContext.error(ppToken->loc, "too many macro parameters", "#define", "");
parseContext.ppError(ppToken->loc, "too many macro parameters", "#define", "");
}
token = scanToken(ppToken);
} while (token == ',');
if (token != ')') {
parseContext.error(ppToken->loc, "missing parenthesis", "#define", "");
parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", "");
return token;
}
......@@ -204,11 +204,11 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
if (symb->mac.argc != mac.argc)
parseContext.error(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(atom));
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(atom));
else {
for (int argc = 0; argc < mac.argc; argc++) {
if (symb->mac.args[argc] != mac.args[argc])
parseContext.error(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(atom));
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(atom));
}
RewindTokenStream(symb->mac.body);
RewindTokenStream(mac.body);
......@@ -220,7 +220,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
oldToken = ReadToken(symb->mac.body, &oldPpToken);
newToken = ReadToken(mac.body, &newPpToken);
if (oldToken != newToken || oldPpToken != newPpToken) {
parseContext.error(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(atom));
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(atom));
break;
}
} while (newToken > 0);
......@@ -241,7 +241,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
int token = scanToken(ppToken);
Symbol *symb;
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
return token;
}
......@@ -255,7 +255,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
}
token = scanToken(ppToken);
if (token != '\n')
parseContext.error(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
return token;
}
......@@ -311,7 +311,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
break;
} else if (atom == elifAtom) {
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#elif after #else", "#elif", "");
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
/* we decrement ifdepth here, because CPPif will increment
* it and we really want to leave it alone */
if (ifdepth) {
......@@ -324,13 +324,13 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
}
} else if (atom == elseAtom) {
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#else after #else", "#else", "");
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
else
elseSeen[elsetracker] = true;
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
} else if (atom == elifAtom) {
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#elif after #else", "#elif", "");
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
}
}
......@@ -358,9 +358,9 @@ int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
label = "";
if (parseContext.relaxedErrors())
parseContext.warn(ppToken->loc, message, label, "");
parseContext.ppWarn(ppToken->loc, message, label, "");
else
parseContext.error(ppToken->loc, message, label, "");
parseContext.ppError(ppToken->loc, message, label, "");
while (token != '\n')
token = scanToken(ppToken);
......@@ -448,7 +448,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
token = scanToken(ppToken);
}
if (token != CPP_IDENTIFIER) {
parseContext.error(loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
parseContext.ppError(loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
err = true;
res = 0;
......@@ -459,7 +459,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
token = scanToken(ppToken);
if (needclose) {
if (token != ')') {
parseContext.error(loc, "expected ')'", "preprocessor evaluation", "");
parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
err = true;
res = 0;
......@@ -479,7 +479,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
token = eval(token, MIN_PRECEDENCE, shortCircuit, res, err, ppToken);
if (! err) {
if (token != ')') {
parseContext.error(loc, "expected ')'", "preprocessor evaluation", "");
parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
err = true;
res = 0;
......@@ -498,7 +498,7 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
token = eval(token, UNARY, shortCircuit, res, err, ppToken);
res = unop[op].op(res);
} else {
parseContext.error(loc, "bad expression", "preprocessor evaluation", "");
parseContext.ppError(loc, "bad expression", "preprocessor evaluation", "");
err = true;
res = 0;
......@@ -543,7 +543,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
while (token == CPP_IDENTIFIER && ppToken->atom != definedAtom) {
int macroReturn = MacroExpand(ppToken->atom, ppToken, true, false);
if (macroReturn == 0) {
parseContext.error(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
err = true;
res = 0;
token = scanToken(ppToken);
......@@ -554,9 +554,9 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
const char* message = "undefined macro in expression not allowed in es profile";
const char* name = GetAtomString(ppToken->atom);
if (parseContext.relaxedErrors())
parseContext.warn(ppToken->loc, message, "preprocessor evaluation", name);
parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", name);
else
parseContext.error(ppToken->loc, message, "preprocessor evaluation", name);
parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", name);
}
}
token = scanToken(ppToken);
......@@ -573,7 +573,7 @@ int TPpContext::CPPif(TPpToken* ppToken)
if (! ifdepth++)
ifloc = ppToken->loc;
if (ifdepth > maxIfNesting) {
parseContext.error(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
return 0;
}
int res = 0;
......@@ -592,20 +592,20 @@ int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
int token = scanToken(ppToken);
int name = ppToken->atom;
if (++ifdepth > maxIfNesting) {
parseContext.error(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
return 0;
}
elsetracker++;
if (token != CPP_IDENTIFIER) {
if (defined)
parseContext.error(ppToken->loc, "must be followed by macro name", "#ifdef", "");
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
else
parseContext.error(ppToken->loc, "must be followed by macro name", "#ifndef", "");
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
} else {
Symbol *s = LookUpSymbol(name);
token = scanToken(ppToken);
if (token != '\n') {
parseContext.error(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
while (token != '\n')
token = scanToken(ppToken);
}
......@@ -625,7 +625,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
int token = scanToken(ppToken);
if (token == '\n') {
parseContext.error(ppToken->loc, "must by followed by an integral literal", "#line", "");
parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", "");
return token;
}
......@@ -688,7 +688,7 @@ int TPpContext::CPPerror(TPpToken* ppToken)
}
parseContext.notifyErrorDirective(loc.line, message.c_str());
//store this msg into the shader's information log..set the Compile Error flag!!!!
parseContext.error(loc, message.c_str(), "#error", "");
parseContext.ppError(loc, message.c_str(), "#error", "");
return '\n';
}
......@@ -724,7 +724,7 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
}
if (token == EOF)
parseContext.error(loc, "directive must end with a newline", "#pragma", "");
parseContext.ppError(loc, "directive must end with a newline", "#pragma", "");
else
parseContext.handlePragma(loc, tokens);
......@@ -737,17 +737,17 @@ int TPpContext::CPPversion(TPpToken* ppToken)
int token = scanToken(ppToken);
if (errorOnVersion || versionSeen)
parseContext.error(ppToken->loc, "must occur first in shader", "#version", "");
parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
versionSeen = true;
if (token == '\n') {
parseContext.error(ppToken->loc, "must be followed by version number", "#version", "");
parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");
return token;
}
if (token != CPP_INTCONSTANT)
parseContext.error(ppToken->loc, "must be followed by version number", "#version", "");
parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");
ppToken->ival = atoi(ppToken->name);
int versionNumber = ppToken->ival;
......@@ -761,14 +761,14 @@ int TPpContext::CPPversion(TPpToken* ppToken)
if (ppToken->atom != coreAtom &&
ppToken->atom != compatibilityAtom &&
ppToken->atom != esAtom)
parseContext.error(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
parseContext.notifyVersion(line, versionNumber, GetAtomString(ppToken->atom));
token = scanToken(ppToken);
if (token == '\n')
return token;
else
parseContext.error(ppToken->loc, "bad tokens following profile -- expected newline", "#version", "");
parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", "");
}
return token;
......@@ -782,24 +782,24 @@ int TPpContext::CPPextension(TPpToken* ppToken)
char extensionName[80];
if (token=='\n') {
parseContext.error(ppToken->loc, "extension name not specified", "#extension", "");
parseContext.ppError(ppToken->loc, "extension name not specified", "#extension", "");
return token;
}
if (token != CPP_IDENTIFIER)
parseContext.error(ppToken->loc, "extension name expected", "#extension", "");
parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
strcpy(extensionName, GetAtomString(ppToken->atom));
token = scanToken(ppToken);
if (token != ':') {
parseContext.error(ppToken->loc, "':' missing after extension name", "#extension", "");
parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", "");
return token;
}
token = scanToken(ppToken);
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "behavior for extension not specified", "#extension", "");
parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", "");
return token;
}
......@@ -809,7 +809,7 @@ int TPpContext::CPPextension(TPpToken* ppToken)
if (token == '\n')
return token;
else
parseContext.error(ppToken->loc, "extra tokens -- expected newline", "#extension","");
parseContext.ppError(ppToken->loc, "extra tokens -- expected newline", "#extension","");
return token;
}
......@@ -823,17 +823,17 @@ int TPpContext::readCPPline(TPpToken* ppToken)
token = CPPdefine(ppToken);
} else if (ppToken->atom == elseAtom) {
if (elsetracker[elseSeen])
parseContext.error(ppToken->loc, "#else after #else", "#else", "");
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
elsetracker[elseSeen] = true;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
token = extraTokenCheck(elseAtom, ppToken, scanToken(ppToken));
token = CPPelse(0, ppToken);
} else if (ppToken->atom == elifAtom) {
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#elif after #else", "#elif", "");
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
// this token is really a dont care, but we still need to eat the tokens
token = scanToken(ppToken);
while (token != '\n')
......@@ -843,7 +843,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
elseSeen[elsetracker] = false;
--elsetracker;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
else
--ifdepth;
token = extraTokenCheck(endifAtom, ppToken, scanToken(ppToken));
......@@ -866,10 +866,10 @@ int TPpContext::readCPPline(TPpToken* ppToken)
} else if (ppToken->atom == extensionAtom) {
token = CPPextension(ppToken);
} else {
parseContext.error(ppToken->loc, "invalid directive:", "#", GetAtomString(ppToken->atom));
parseContext.ppError(ppToken->loc, "invalid directive:", "#", GetAtomString(ppToken->atom));
}
} else if (token != '\n' && token != EOF)
parseContext.error(ppToken->loc, "invalid directive", "#", "");
parseContext.ppError(ppToken->loc, "invalid directive", "#", "");
while (token != '\n' && token != 0 && token != EOF)
token = scanToken(ppToken);
......@@ -1012,7 +1012,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
token = scanToken(ppToken);
}
if (token != '(') {
parseContext.error(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
UngetToken(token, ppToken);
ppToken->atom = atom;
......@@ -1029,20 +1029,20 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
while (1) {
token = scanToken(ppToken);
if (token == EOF) {
parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
delete in;
return 0;
}
if (token == '\n') {
if (! newLineOkay) {
parseContext.error(loc, "end of line in macro substitution:", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "end of line in macro substitution:", "macro expansion", GetAtomString(atom));
delete in;
return 0;
}
continue;
}
if (token == '#') {
parseContext.error(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
delete in;
return 0;
}
......@@ -1067,7 +1067,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
} while (arg < in->mac->argc);
if (arg < in->mac->argc)
parseContext.error(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
else if (token != ')') {
depth=0;
while (token != EOF && (depth > 0 || token != ')')) {
......@@ -1079,11 +1079,11 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
}
if (token == EOF) {
parseContext.error(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "EOF in macro", "macro expansion", GetAtomString(atom));
delete in;
return 0;
}
parseContext.error(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
}
for (int i = 0; i < in->mac->argc; i++)
in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
......
......@@ -138,7 +138,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
}
ch = getChar();
} else {
parseContext.error(ppToken->loc, "float literal too long", "", "");
parseContext.PpError(ppToken->loc, "float literal too long", "", "");
len = 1;
str_len = 1;
}
......@@ -150,7 +150,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
if (ch == 'e' || ch == 'E') {
HasDecimalOrExponent = true;
if (len >= TPpToken::maxTokenLength) {
parseContext.error(ppToken->loc, "float literal too long", "", "");
parseContext.PpError(ppToken->loc, "float literal too long", "", "");
len = 1;
str_len = 1;
} else {
......@@ -169,13 +169,13 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
str[len++] = (char)ch;
ch = getChar();
} else {
parseContext.error(ppToken->loc, "float literal too long", "", "");
parseContext.PpError(ppToken->loc, "float literal too long", "", "");
len = 1;
str_len = 1;
}
}
} else {
parseContext.error(ppToken->loc, "bad character in float exponent", "", "");
parseContext.PpError(ppToken->loc, "bad character in float exponent", "", "");
}
}
}
......@@ -187,7 +187,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
if (ch == 'l' || ch == 'L') {
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
parseContext.PpError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
int ch2 = getChar();
if (ch2 != 'f' && ch2 != 'F') {
ungetChar();
......@@ -198,7 +198,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
str[len++] = (char)ch2;
isDouble = 1;
} else {
parseContext.error(ppToken->loc, "float literal too long", "", "");
parseContext.PpError(ppToken->loc, "float literal too long", "", "");
len = 1,str_len=1;
}
}
......@@ -207,11 +207,11 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
if (! parseContext.relaxedErrors())
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
parseContext.PpError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
if (len < TPpToken::maxTokenLength)
str[len++] = (char)ch;
else {
parseContext.error(ppToken->loc, "float literal too long", "", "");
parseContext.PpError(ppToken->loc, "float literal too long", "", "");
len = 1,str_len=1;
}
} else
......@@ -276,7 +276,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ch = pp->getChar();
} else {
if (! AlreadyComplained) {
pp->parseContext.error(ppToken->loc, "name too long", "", "");
pp->parseContext.PpError(ppToken->loc, "name too long", "", "");
AlreadyComplained = 1;
}
ch = pp->getChar();
......@@ -319,11 +319,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
} else if (ch >= 'a' && ch <= 'f') {
ii = ch - 'a' + 10;
} else
pp->parseContext.error(ppToken->loc, "bad digit in hexidecimal literal", "", "");
pp->parseContext.PpError(ppToken->loc, "bad digit in hexidecimal literal", "", "");
ival = (ival << 4) | ii;
} else {
if (! AlreadyComplained) {
pp->parseContext.error(ppToken->loc, "hexidecimal literal too big", "", "");
pp->parseContext.PpError(ppToken->loc, "hexidecimal literal too big", "", "");
AlreadyComplained = 1;
}
ival = 0xffffffff;
......@@ -333,7 +333,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
(ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f'));
} else {
pp->parseContext.error(ppToken->loc, "bad digit in hexidecimal literal", "", "");
pp->parseContext.PpError(ppToken->loc, "bad digit in hexidecimal literal", "", "");
}
if (ch == 'u' || ch == 'U') {
if (len < TPpToken::maxTokenLength)
......@@ -361,7 +361,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (len < TPpToken::maxTokenLength)
ppToken->name[len++] = (char)ch;
else if (! AlreadyComplained) {
pp->parseContext.error(ppToken->loc, "numeric literal too long", "", "");
pp->parseContext.PpError(ppToken->loc, "numeric literal too long", "", "");
AlreadyComplained = 1;
}
if (ival <= 0x1fffffff) {
......@@ -379,7 +379,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (len < TPpToken::maxTokenLength)
ppToken->name[len++] = (char)ch;
else if (! AlreadyComplained) {
pp->parseContext.error(ppToken->loc, "numeric literal too long", "", "");
pp->parseContext.PpError(ppToken->loc, "numeric literal too long", "", "");
AlreadyComplained = 1;
}
ch = pp->getChar();
......@@ -390,7 +390,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
// wasn't a float, so must be octal...
if (nonOctal)
pp->parseContext.error(ppToken->loc, "octal literal digit too large", "", "");
pp->parseContext.PpError(ppToken->loc, "octal literal digit too large", "", "");
if (ch == 'u' || ch == 'U') {
if (len < TPpToken::maxTokenLength)
......@@ -401,7 +401,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->name[len] = '\0';
if (octalOverflow)
pp->parseContext.error(ppToken->loc, "octal literal too big", "", "");
pp->parseContext.PpError(ppToken->loc, "octal literal too big", "", "");
ppToken->ival = (int)ival;
......@@ -419,7 +419,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
if (len < TPpToken::maxTokenLength)
ppToken->name[len++] = (char)ch;
else if (! AlreadyComplained) {
pp->parseContext.error(ppToken->loc, "numeric literal too long", "", "");
pp->parseContext.PpError(ppToken->loc, "numeric literal too long", "", "");
AlreadyComplained = 1;
}
ch = pp->getChar();
......@@ -444,7 +444,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
for (int i = 0; i < numericLen; i++) {
ch = ppToken->name[i] - '0';
if ((ival > oneTenthMaxInt) || (ival == oneTenthMaxInt && ch > remainderMaxInt)) {
pp->parseContext.error(ppToken->loc, "numeric literal too big", "", "");
pp->parseContext.PpError(ppToken->loc, "numeric literal too big", "", "");
ival = 0xFFFFFFFFu;
break;
} else
......@@ -627,14 +627,14 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
do {
while (ch != '*') {
if (ch == EOF) {
pp->parseContext.error(ppToken->loc, "EOF in comment", "comment", "");
pp->parseContext.PpError(ppToken->loc, "EOF in comment", "comment", "");
return endOfInput;
}
ch = pp->getChar();
}
ch = pp->getChar();
if (ch == EOF) {
pp->parseContext.error(ppToken->loc, "EOF in comment", "comment", "");
pp->parseContext.PpError(ppToken->loc, "EOF in comment", "comment", "");
return endOfInput;
}
} while (ch != '/');
......@@ -663,7 +663,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
ppToken->atom = pp->LookUpAddString(tokenText);
return CPP_STRCONSTANT;
} else {
pp->parseContext.error(ppToken->loc, "end of line in string", "string", "");
pp->parseContext.PpError(ppToken->loc, "end of line in string", "string", "");
return CPP_ERROR_SY;
}
}
......@@ -700,7 +700,7 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
}
continue;
} else {
parseContext.error(ppToken->loc, "preprocessor directive cannot be preceded by another token", "#", "");
parseContext.PpError(ppToken->loc, "preprocessor directive cannot be preceded by another token", "#", "");
return nullptr;
}
}
......@@ -719,10 +719,10 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
tokenString = ppToken->name;
else if (token == CPP_STRCONSTANT) {
parseContext.error(ppToken->loc, "string literals not supported", "\"\"", "");
parseContext.PpError(ppToken->loc, "string literals not supported", "\"\"", "");
tokenString = nullptr;
} else if (token == '\'') {
parseContext.error(ppToken->loc, "character literals not supported", "\'", "");
parseContext.PpError(ppToken->loc, "character literals not supported", "\'", "");
tokenString = nullptr;
} else
tokenString = GetAtomString(token);
......@@ -740,7 +740,7 @@ const char* TPpContext::tokenize(TPpToken* ppToken)
void TPpContext::missingEndifCheck()
{
if (ifdepth > 0)
parseContext.error(parseContext.getCurrentLoc(), "missing #endif", "", "");
parseContext.PpError(parseContext.getCurrentLoc(), "missing #endif", "", "");
}
} // end namespace glslang
......@@ -131,6 +131,7 @@ enum EShMessages {
EShMsgAST = (1 << 2), // print the AST intermediate representation
EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation
EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V
EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor
};
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment