Fixes to scanning:

- do version checking for the line-continuation character
 - check for built-in names in #undef
 - bug fix for #elif after #else
 - do version checking for use of floating point suffixes (f, LF, etc.)


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24011 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-11-12 03:31:24 +00:00
parent 67c9f3a720
commit 69aa9c1b84
21 changed files with 210 additions and 59 deletions

View file

@ -151,13 +151,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
const char* definedName = GetAtomString(atom);
if (ppToken->loc.string >= 0) {
// We are in user code; check for reserved name use:
// "All macro names containing two consecutive underscores ( __ ) are reserved for future use as predefined
// macro names. All macro names prefixed with "GL_" ("GL" followed by a single underscore) are also
// reserved."
if (strncmp(definedName, "GL_", 3) == 0)
parseContext.error(ppToken->loc, "reserved built-in name prefix:", "#define", "GL_");
else if (strstr(definedName, "__") != 0)
parseContext.error(ppToken->loc, "names containing consecutive underscores are reserved", "#define", "");
parseContext.reservedPpErrorCheck(ppToken->loc, definedName, "#define");
}
token = currentInput->scan(this, currentInput, ppToken);
if (token == '(' && !ppToken->ival) {
@ -203,6 +197,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
mac.body = NewTokenStream(pool);
while (token != '\n') {
if (token == '\\') {
parseContext.lineContinuationCheck(ppToken->loc);
token = currentInput->scan(this, currentInput, ppToken);
if (token == '\n')
token = currentInput->scan(this, currentInput, ppToken);
@ -253,21 +248,19 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
return '\n';
}
int TPpContext::CPPundef(TPpToken * ppToken)
int TPpContext::CPPundef(TPpToken* ppToken)
{
int token = currentInput->scan(this, currentInput, ppToken);
Symbol *symb;
if (token == '\n') {
parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
return token;
}
if (token != CPP_IDENTIFIER) {
parseContext.error(ppToken->loc, "must be followed by macro name", "#undef", "");
return token;
}
const char* name = GetAtomString(ppToken->atom); // TODO preprocessor simplification: the token text should have been built into the ppToken during currentInput->scan()
parseContext.reservedPpErrorCheck(ppToken->loc, name, "#undef");
symb = LookUpSymbol(ppToken->atom);
if (symb) {
symb->mac.undef = 1;
@ -311,7 +304,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
elsetracker++;
} else if (atom == endifAtom) {
token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
elsedepth[elsetracker] = 0;
elseSeen[elsetracker] = false;
--elsetracker;
if (depth == 0) {
// found the #endif we are looking for
@ -331,21 +324,21 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
* it and we really want to leave it alone */
if (ifdepth) {
--ifdepth;
elsedepth[elsetracker] = 0;
elseSeen[elsetracker] = false;
--elsetracker;
}
return CPPif(ppToken);
}
} else if (atom == elseAtom || atom == elifAtom) {
if (! ChkCorrectElseNesting()) {
if (atom == elseAtom)
parseContext.error(ppToken->loc, "#else after #else", "#else", "");
else
parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
}
if (atom == elseAtom)
token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
} else if (atom == elseAtom) {
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#else after #else", "#else", "");
else
elseSeen[elsetracker] = true;
token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
} else if (atom == elifAtom) {
if (elseSeen[elsetracker])
parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
}
}
@ -807,7 +800,8 @@ int TPpContext::readCPPline(TPpToken * ppToken)
if (ppToken->atom == defineAtom) {
token = CPPdefine(ppToken);
} else if (ppToken->atom == elseAtom) {
if (ChkCorrectElseNesting()) {
if (! elsetracker[elseSeen]) {
elsetracker[elseSeen] = true;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
@ -826,7 +820,7 @@ int TPpContext::readCPPline(TPpToken * ppToken)
token = currentInput->scan(this, currentInput, ppToken);
token = CPPelse(0, ppToken);
} else if (ppToken->atom == endifAtom) {
elsedepth[elsetracker] = 0;
elseSeen[elsetracker] = false;
--elsetracker;
if (! ifdepth)
parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
@ -1106,15 +1100,4 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, int expandUndef)
return 1;
}
int TPpContext::ChkCorrectElseNesting()
{
if (elsedepth[elsetracker] == 0) {
elsedepth[elsetracker] = 1;
return 1;
}
return 0;
}
} // end namespace glslang

View file

@ -91,7 +91,7 @@ TPpContext::TPpContext(TParseContext& pc) :
ifdepth = 0;
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
elsedepth[elsetracker] = 0;
elseSeen[elsetracker] = false;
elsetracker = 0;
}

View file

@ -196,9 +196,9 @@ protected:
static const int maxMacroArgs = 64;
static const int maxIfNesting = 64;
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
int elsedepth[maxIfNesting]; // Keep a track of #if depth..Max allowed is 64.
int elsetracker; // #if-#else and #endif constructs...Counter.
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
int elsetracker; // #if-#else and #endif constructs...Counter.
const char *ErrMsg;
struct MacroInputSrc {
@ -262,7 +262,6 @@ protected:
static int macro_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken);
static int zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken * ppToken);
int MacroExpand(int atom, TPpToken* ppToken, int expandUndef);
int ChkCorrectElseNesting();
//
// from PpSymbols.cpp

View file

@ -202,6 +202,7 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
strcpy(str, "0.0");
} else {
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", "", "");
int ch2 = currentInput->getch(this, currentInput, ppToken);
@ -219,6 +220,8 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
}
}
} else if (ch == 'f' || ch == 'F') {
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, 0, "floating-point suffix");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, 0, "floating-point suffix");
if (! HasDecimalOrExponent)
parseContext.error(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
if (len < TPpToken::maxTokenLength)
@ -230,7 +233,7 @@ int TPpContext::lFloatConst(char* str, int len, int ch, TPpToken* ppToken)
} else
currentInput->ungetch(this, currentInput, ch, ppToken);
str[len]='\0';
str[len]='\0';
ppToken->dval = strtod(str, 0);
}
@ -282,6 +285,7 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
do {
if (ch == '\\') {
// escaped character
pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\r' || ch == '\n') {
int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@ -631,6 +635,7 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\\') {
// allow an escaped newline, otherwise escapes in comments are meaningless
pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\r' || ch == '\n') {
int nextch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
@ -678,7 +683,8 @@ int TPpContext::sourceScan(TPpContext* pp, InputSrc*, TPpToken* ppToken)
case '"':
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
while (ch != '"' && ch != '\n' && ch != EOF) {
if (ch == '\\') {
if (ch == '\\') {
pp->parseContext.lineContinuationCheck(ppToken->loc);
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
if (ch == '\n' || ch == EOF) {
break;