From 4ee2f7529465b5cfb65691b5b1fba69e98c547f2 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 7 Nov 2018 17:14:46 -0700 Subject: [PATCH] PP: More clearly distinguish funtion-like and object-like macros --- Test/baseResults/cppSimple.vert.out | 6 +++--- Test/cppSimple.vert | 4 ++-- glslang/MachineIndependent/preprocessor/Pp.cpp | 14 ++++++++------ .../MachineIndependent/preprocessor/PpContext.h | 8 ++++---- 4 files changed, 17 insertions(+), 15 deletions(-) mode change 100644 => 100755 Test/cppSimple.vert diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out index 8da3ae67..90d17cea 100644 --- a/Test/baseResults/cppSimple.vert.out +++ b/Test/baseResults/cppSimple.vert.out @@ -35,9 +35,9 @@ ERROR: 0:155: '#else' : unexpected tokens following directive ERROR: 0:158: '#else' : #else after #else ERROR: 0:160: '#endif' : unexpected tokens following directive ERROR: 0:164: '#define' : duplicate macro parameter -ERROR: 0:173: '#define' : Macro redefined; different number of arguments: m4 -ERROR: 0:178: '#define' : Macro redefined; different number of arguments: m5 -ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6 +ERROR: 0:173: '#define' : Macro redefined; function-like versus object-like: m4 +ERROR: 0:177: '#define' : Macro redefined; function-like versus object-like: m5 +ERROR: 0:181: '#define' : Macro redefined; different number of arguments: m6 ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7 ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8 ERROR: 0:196: '#define' : Macro redefined; different argument names: m9 diff --git a/Test/cppSimple.vert b/Test/cppSimple.vert old mode 100644 new mode 100755 index fdd14221..2f7de30f --- a/Test/cppSimple.vert +++ b/Test/cppSimple.vert @@ -170,7 +170,7 @@ int a = length("aoenatuh"); // ERROR // ERROR #define m4(b) -#define m4 (b) +#define m4 // ERROR #define m5 (b) @@ -178,7 +178,7 @@ int a = length("aoenatuh"); // ERROR // ERROR #define m6(a) -#define m6 +#define m6(a,b) // ERROR (whitespace) #define m7 (a) diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index 12353550..c8def989 100644 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -109,11 +109,12 @@ int TPpContext::CPPdefine(TPpToken* ppToken) // save the macro name const int defAtom = atomStrings.getAddAtom(ppToken->name); + TSourceLoc defineLoc = ppToken->loc; // because ppToken might go to the next line before we report errors // gather parameters to the macro, between (...) token = scanToken(ppToken); - if (token == '(' && ! ppToken->space) { - mac.emptyArgs = 1; + if (token == '(' && !ppToken->space) { + mac.functionLike = 1; do { token = scanToken(ppToken); if (mac.args.size() == 0 && token == ')') @@ -123,7 +124,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken) return token; } - mac.emptyArgs = 0; const int argAtom = atomStrings.getAddAtom(ppToken->name); // check for duplication of parameter name @@ -149,7 +149,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken) } // record the definition of the macro - TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors while (token != '\n' && token != EndOfInput) { mac.body.putToken(token, ppToken); token = scanToken(ppToken); @@ -164,7 +163,9 @@ int TPpContext::CPPdefine(TPpToken* ppToken) // Already defined -- need to make sure they are identical: // "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 (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs) + if (existing->functionLike != mac.functionLike) + parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom)); + else if (existing->args.size() != mac.args.size()) parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom)); else { if (existing->args != mac.args) @@ -1190,13 +1191,14 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error in->mac = macro; - if (macro->args.size() > 0 || macro->emptyArgs) { + if (macro->functionLike) { int token = scanToken(ppToken); if (newLineOkay) { while (token == '\n') token = scanToken(ppToken); } if (token != '(') { + // function-like macro called with object-like syntax: okay, don't expand UngetToken(token, ppToken); delete in; return MacroExpandNotStarted; diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index 5c260816..64681fc3 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -267,12 +267,12 @@ public: // struct MacroSymbol { - MacroSymbol() : emptyArgs(0), busy(0), undef(0) { } + MacroSymbol() : functionLike(0), busy(0), undef(0) { } TVector args; TokenStream body; - unsigned emptyArgs : 1; - unsigned busy : 1; - unsigned undef : 1; + unsigned functionLike : 1; // 0 means object-like, 1 means function-like + unsigned busy : 1; + unsigned undef : 1; }; typedef TMap TSymbolMap;