Add #line functionality to allow expressions instead of just literals. Also made some preprocessor code slightly more clear.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24294 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
b06c378cc9
commit
1abc4045ce
@ -61,8 +61,17 @@ ERROR: 0:235: 'line continuation' : not supported for this version or the enable
|
|||||||
ERROR: 0:236: '#error' : good continuation
|
ERROR: 0:236: '#error' : good continuation
|
||||||
ERROR: 0:238: '#' : invalid directive: flizbit
|
ERROR: 0:238: '#' : invalid directive: flizbit
|
||||||
ERROR: 0:242: '#' : invalid directive: directive
|
ERROR: 0:242: '#' : invalid directive: directive
|
||||||
ERROR: 0:246: '' : missing #endif
|
ERROR: 0:12001: '#error' : line should be 12001
|
||||||
ERROR: 62 compilation errors. No code generated.
|
ERROR: 7:13001: '#error' : line should be 13001 , string 7
|
||||||
|
ERROR: 7:14014: '#error' : line should be 14014 , string 7
|
||||||
|
ERROR: 12:14014: '#error' : line should be 14014 , string 12
|
||||||
|
ERROR: 12:14026: '#error' : line should be 14026 , string 12
|
||||||
|
ERROR: 12:1234: '#line' : unexpected tokens following directive
|
||||||
|
ERROR: 12:20001: '#error' : line should be 20001
|
||||||
|
ERROR: 12:20011: '#error' : line should be 20011
|
||||||
|
ERROR: 12:20021: '#error' : line should be 20021
|
||||||
|
ERROR: 12:10003: '' : missing #endif
|
||||||
|
ERROR: 71 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
ERROR: node is still EOpNull!
|
ERROR: node is still EOpNull!
|
||||||
|
|||||||
@ -241,6 +241,29 @@ double f = f1;
|
|||||||
|
|
||||||
#directive directive was expanded
|
#directive directive was expanded
|
||||||
|
|
||||||
|
#line 12000
|
||||||
|
#error line should be 12001
|
||||||
|
#line 13000 7
|
||||||
|
#error line should be 13001, string 7
|
||||||
|
#define L1 14000
|
||||||
|
#define L2 13
|
||||||
|
#define F1 5
|
||||||
|
#define F2 7
|
||||||
|
#line L1 + L2
|
||||||
|
#error line should be 14014, string 7
|
||||||
|
#line L1 + L2 F1 + F2
|
||||||
|
#error line should be 14014, string 12
|
||||||
|
#line L1 + L2 + F1 + F2
|
||||||
|
#error line should be 14026, string 12
|
||||||
|
#line 1234 F1 + F2 extra
|
||||||
|
#line (20000)
|
||||||
|
#error line should be 20001
|
||||||
|
#line (20000+10)
|
||||||
|
#error line should be 20011
|
||||||
|
#line +20020
|
||||||
|
#error line should be 20021
|
||||||
|
|
||||||
|
#line 10000
|
||||||
#if 1
|
#if 1
|
||||||
#else
|
#else
|
||||||
// ERROR, missing #endif
|
// ERROR, missing #endif
|
||||||
@ -125,6 +125,7 @@ int TPpContext::InitCPP()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle #define
|
||||||
int TPpContext::CPPdefine(TPpToken* ppToken)
|
int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token, atom, args[maxMacroArgs], argc;
|
int token, atom, args[maxMacroArgs], argc;
|
||||||
@ -237,6 +238,7 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
return '\n';
|
return '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle #undef
|
||||||
int TPpContext::CPPundef(TPpToken* ppToken)
|
int TPpContext::CPPundef(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
@ -261,6 +263,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle #else
|
||||||
/* Skip forward to appropriate spot. This is used both
|
/* Skip forward to appropriate spot. This is used both
|
||||||
** to skip to a #endif after seeing an #else, AND to skip to a #else,
|
** to skip to a #endif after seeing an #else, AND to skip to a #else,
|
||||||
** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false.
|
** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false.
|
||||||
@ -334,6 +337,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call when there should be no more tokens left on a line.
|
||||||
int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
|
int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
|
||||||
{
|
{
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
@ -348,6 +352,8 @@ int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
|
|||||||
label = "#endif";
|
label = "#endif";
|
||||||
else if (atom == ifAtom)
|
else if (atom == ifAtom)
|
||||||
label = "#if";
|
label = "#if";
|
||||||
|
else if (atom == lineAtom)
|
||||||
|
label = "#line";
|
||||||
else
|
else
|
||||||
label = "";
|
label = "";
|
||||||
|
|
||||||
@ -364,9 +370,9 @@ int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum eval_prec {
|
enum eval_prec {
|
||||||
MIN_PREC,
|
MIN_PRECEDENCE,
|
||||||
COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
|
COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
|
||||||
MAX_PREC
|
MAX_PRECEDENCE
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -397,7 +403,7 @@ namespace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Tbinops {
|
struct Tbinops {
|
||||||
int token, prec, (*op)(int, int);
|
int token, precedence, (*op)(int, int);
|
||||||
} binop[] = {
|
} binop[] = {
|
||||||
{ CPP_OR_OP, LOGOR, op_logor },
|
{ CPP_OR_OP, LOGOR, op_logor },
|
||||||
{ CPP_AND_OP, LOGAND, op_logand },
|
{ CPP_AND_OP, LOGAND, op_logand },
|
||||||
@ -430,7 +436,7 @@ struct tunops {
|
|||||||
|
|
||||||
#define ALEN(A) (sizeof(A)/sizeof(A[0]))
|
#define ALEN(A) (sizeof(A)/sizeof(A[0]))
|
||||||
|
|
||||||
int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
|
int TPpContext::eval(int token, int precedence, int& res, bool& err, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int i, val;
|
int i, val;
|
||||||
Symbol *s;
|
Symbol *s;
|
||||||
@ -445,19 +451,18 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
if (token != CPP_IDENTIFIER) {
|
if (token != CPP_IDENTIFIER) {
|
||||||
parseContext.error(ppToken->loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
|
||||||
*err = 1;
|
err = true;
|
||||||
*res = 0;
|
res = 0;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
*res = (s = LookUpSymbol(ppToken->atom))
|
res = (s = LookUpSymbol(ppToken->atom)) ? !s->mac.undef : 0;
|
||||||
? !s->mac.undef : 0;
|
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
if (needclose) {
|
if (needclose) {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
parseContext.error(ppToken->loc, "#else after #else", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "#else after #else", "preprocessor evaluation", "");
|
||||||
*err = 1;
|
err = true;
|
||||||
*res = 0;
|
res = 0;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@ -467,8 +472,8 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
|
|||||||
int macroReturn = MacroExpand(ppToken->atom, ppToken, 1);
|
int macroReturn = MacroExpand(ppToken->atom, ppToken, 1);
|
||||||
if (macroReturn == 0) {
|
if (macroReturn == 0) {
|
||||||
parseContext.error(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
|
||||||
*err = 1;
|
err = true;
|
||||||
*res = 0;
|
res = 0;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
} else {
|
} else {
|
||||||
@ -479,26 +484,26 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
|
|||||||
else {
|
else {
|
||||||
parseContext.error(ppToken->loc, "undefined macro in expression", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "undefined macro in expression", "preprocessor evaluation", "");
|
||||||
|
|
||||||
*err = 1;
|
err = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
|
|
||||||
return eval(token, prec, res, err, ppToken);
|
return eval(token, precedence, res, err, ppToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (token == CPP_INTCONSTANT) {
|
} else if (token == CPP_INTCONSTANT) {
|
||||||
*res = ppToken->ival;
|
res = ppToken->ival;
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
} else if (token == '(') {
|
} else if (token == '(') {
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
token = eval(token, MIN_PREC, res, err, ppToken);
|
token = eval(token, MIN_PRECEDENCE, res, err, ppToken);
|
||||||
if (!*err) {
|
if (! err) {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
parseContext.error(ppToken->loc, "expected ')'", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "expected ')'", "preprocessor evaluation", "");
|
||||||
*err = 1;
|
err = true;
|
||||||
*res = 0;
|
res = 0;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@ -512,37 +517,37 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken* ppToken)
|
|||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
token = eval(token, UNARY, res, err, ppToken);
|
token = eval(token, UNARY, res, err, ppToken);
|
||||||
*res = unop[i].op(*res);
|
res = unop[i].op(res);
|
||||||
} else {
|
} else {
|
||||||
parseContext.error(ppToken->loc, "bad expression", "preprocessor evaluation", "");
|
parseContext.error(ppToken->loc, "bad expression", "preprocessor evaluation", "");
|
||||||
*err = 1;
|
err = true;
|
||||||
*res = 0;
|
res = 0;
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!*err) {
|
while (! err) {
|
||||||
if (token == ')' || token == '\n')
|
if (token == ')' || token == '\n')
|
||||||
break;
|
break;
|
||||||
for (i = ALEN(binop) - 1; i >= 0; i--) {
|
for (i = ALEN(binop) - 1; i >= 0; i--) {
|
||||||
if (binop[i].token == token)
|
if (binop[i].token == token)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i < 0 || binop[i].prec <= prec)
|
if (i < 0 || binop[i].precedence <= precedence)
|
||||||
break;
|
break;
|
||||||
val = *res;
|
val = res;
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = currentInput->scan(this, currentInput, ppToken);
|
||||||
token = eval(token, binop[i].prec, res, err, ppToken);
|
token = eval(token, binop[i].precedence, res, err, ppToken);
|
||||||
*res = binop[i].op(val, *res);
|
res = binop[i].op(val, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
} // eval
|
}
|
||||||
|
|
||||||
|
// Handle #if
|
||||||
int TPpContext::CPPif(TPpToken* ppToken)
|
int TPpContext::CPPif(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
int res = 0, err = 0;
|
|
||||||
elsetracker++;
|
elsetracker++;
|
||||||
if (! ifdepth++)
|
if (! ifdepth++)
|
||||||
ifloc = ppToken->loc;
|
ifloc = ppToken->loc;
|
||||||
@ -550,7 +555,9 @@ int TPpContext::CPPif(TPpToken* ppToken)
|
|||||||
parseContext.error(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
parseContext.error(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
token = eval(token, MIN_PREC, &res, &err, ppToken);
|
int res = 0;
|
||||||
|
bool err = false;
|
||||||
|
token = eval(token, MIN_PRECEDENCE, res, err, ppToken);
|
||||||
token = extraTokenCheck(ifAtom, ppToken, token);
|
token = extraTokenCheck(ifAtom, ppToken, token);
|
||||||
if (!res && !err)
|
if (!res && !err)
|
||||||
token = CPPelse(1, ppToken);
|
token = CPPelse(1, ppToken);
|
||||||
@ -558,7 +565,8 @@ int TPpContext::CPPif(TPpToken* ppToken)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPpContext::CPPifdef(int defined, TPpToken * ppToken)
|
// Handle #ifdef
|
||||||
|
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
int name = ppToken->atom;
|
int name = ppToken->atom;
|
||||||
@ -588,35 +596,36 @@ int TPpContext::CPPifdef(int defined, TPpToken * ppToken)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle #line
|
// Handle #line
|
||||||
int TPpContext::CPPline(TPpToken * ppToken)
|
int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
if (token == '\n') {
|
if (token == '\n') {
|
||||||
parseContext.error(ppToken->loc, "must by followed by an integral literal", "#line", "");
|
parseContext.error(ppToken->loc, "must by followed by an integral literal", "#line", "");
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
else if (token == CPP_INTCONSTANT) {
|
|
||||||
parseContext.setCurrentLine(atoi(ppToken->name));
|
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
|
||||||
|
|
||||||
if (token == CPP_INTCONSTANT) {
|
int lineRes = 0;
|
||||||
parseContext.setCurrentString(atoi(ppToken->name));
|
bool lineErr = false;
|
||||||
token = currentInput->scan(this, currentInput, ppToken);
|
token = eval(token, MIN_PRECEDENCE, lineRes, lineErr, ppToken);
|
||||||
if (token != '\n')
|
if (! lineErr) {
|
||||||
parseContext.error(parseContext.getCurrentLoc(), "cannot be followed by more than two integral literals", "#line", "");
|
if (token == '\n')
|
||||||
} else if (token == '\n')
|
++lineRes;
|
||||||
|
parseContext.setCurrentLine(lineRes);
|
||||||
return token;
|
if (token != '\n') {
|
||||||
else
|
int fileRes = 0;
|
||||||
parseContext.error(parseContext.getCurrentLoc(), "second argument can only be an integral literal", "#line", "");
|
bool fileErr = false;
|
||||||
} else
|
token = eval(token, MIN_PRECEDENCE, fileRes, fileErr, ppToken);
|
||||||
parseContext.error(parseContext.getCurrentLoc(), "first argument can only be an integral literal", "#line", "");
|
if (! fileErr)
|
||||||
|
parseContext.setCurrentString(fileRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token = extraTokenCheck(lineAtom, ppToken, token);
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle #error
|
// Handle #error
|
||||||
int TPpContext::CPPerror(TPpToken * ppToken)
|
int TPpContext::CPPerror(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
std::string message;
|
std::string message;
|
||||||
@ -640,6 +649,7 @@ int TPpContext::CPPerror(TPpToken * ppToken)
|
|||||||
return '\n';
|
return '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle #pragma
|
||||||
int TPpContext::CPPpragma(TPpToken* ppToken)
|
int TPpContext::CPPpragma(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
char SrcStrName[2];
|
char SrcStrName[2];
|
||||||
@ -679,8 +689,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is just for error checking: the version and profile are decided before preprocessing starts
|
// #version: This is just for error checking: the version and profile are decided before preprocessing starts
|
||||||
int TPpContext::CPPversion(TPpToken * ppToken)
|
int TPpContext::CPPversion(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
|
|
||||||
@ -717,11 +727,11 @@ int TPpContext::CPPversion(TPpToken * ppToken)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
} // CPPversion
|
}
|
||||||
|
|
||||||
int TPpContext::CPPextension(TPpToken * ppToken)
|
// Handle #extension
|
||||||
|
int TPpContext::CPPextension(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
|
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
char extensionName[80];
|
char extensionName[80];
|
||||||
|
|
||||||
@ -756,9 +766,9 @@ int TPpContext::CPPextension(TPpToken * ppToken)
|
|||||||
parseContext.error(ppToken->loc, "extra tokens -- expected newline", "#extension","");
|
parseContext.error(ppToken->loc, "extra tokens -- expected newline", "#extension","");
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
} // CPPextension
|
}
|
||||||
|
|
||||||
int TPpContext::readCPPline(TPpToken * ppToken)
|
int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = currentInput->scan(this, currentInput, ppToken);
|
int token = currentInput->scan(this, currentInput, ppToken);
|
||||||
bool isVersion = false;
|
bool isVersion = false;
|
||||||
@ -847,7 +857,7 @@ void TPpContext::PopEofSrc()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken * ppToken)
|
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token;
|
int token;
|
||||||
TokenStream *n;
|
TokenStream *n;
|
||||||
|
|||||||
@ -244,7 +244,7 @@ protected:
|
|||||||
int CPPundef(TPpToken * ppToken);
|
int CPPundef(TPpToken * ppToken);
|
||||||
int CPPelse(int matchelse, TPpToken * ppToken);
|
int CPPelse(int matchelse, TPpToken * ppToken);
|
||||||
int extraTokenCheck(int atom, TPpToken* ppToken, int token);
|
int extraTokenCheck(int atom, TPpToken* ppToken, int token);
|
||||||
int eval(int token, int prec, int *res, int *err, TPpToken * ppToken);
|
int eval(int token, int precedence, int& res, bool& err, TPpToken * ppToken);
|
||||||
int CPPif (TPpToken * ppToken);
|
int CPPif (TPpToken * ppToken);
|
||||||
int CPPifdef(int defined, TPpToken * ppToken);
|
int CPPifdef(int defined, TPpToken * ppToken);
|
||||||
int CPPline(TPpToken * ppToken);
|
int CPPline(TPpToken * ppToken);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user