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