From 6225dd4ba15c3b07c666d1ecdc8095233b7bc7e1 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 19 Feb 2019 03:12:02 -0700 Subject: [PATCH] PP: Faithfully track white-space through macro record/use, fixing bugs: This fixes the comparison in macro body redefinitions, where initial white-space differences do not matter, but internal white-space differences do matter. --- glslang/MachineIndependent/preprocessor/Pp.cpp | 36 +++++++++++++++------- .../MachineIndependent/preprocessor/PpContext.h | 3 ++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index ce6c22f..c74e44f 100755 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -166,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken) if (existing != nullptr) { if (! existing->undef) { // 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->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) - parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom)); + // "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->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) { + parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", + atomStrings.getString(defAtom)); + } + // set up to compare the two existing->body.reset(); mac.body.reset(); int newToken; + bool firstToken = true; do { int oldToken; TPpToken oldPpToken; TPpToken newPpToken; oldToken = existing->body.getToken(parseContext, &oldPpToken); newToken = mac.body.getToken(parseContext, &newPpToken); + // for the first token, preceding spaces don't matter + if (firstToken) { + newPpToken.space = oldPpToken.space; + firstToken = false; + } if (oldToken != newToken || oldPpToken != newPpToken) { - parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom)); + parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", + atomStrings.getString(defAtom)); break; } - } while (newToken > 0); + } while (newToken != EndOfInput); } } *existing = mac; diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index ae957f2..64649d5 100644 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -252,11 +252,13 @@ public: public: Token(int atom, const TPpToken& ppToken) : atom(atom), + space(ppToken.space), i64val(ppToken.i64val), name(ppToken.name) { } int get(TPpToken& ppToken) { ppToken.clear(); + ppToken.space = space; ppToken.i64val = i64val; snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str()); return atom; @@ -265,6 +267,7 @@ public: protected: Token() {} int atom; + bool space; // did a space precede the token? long long i64val; TString name; }; -- 2.7.4