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.
This commit is contained in:
parent
5cdf3c5a23
commit
6225dd4ba1
@ -166,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
if (existing != nullptr) {
|
if (existing != nullptr) {
|
||||||
if (! existing->undef) {
|
if (! existing->undef) {
|
||||||
// Already defined -- need to make sure they are identical:
|
// 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,
|
// "Two replacement lists are identical if and only if the
|
||||||
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
// preprocessing tokens in both have the same number,
|
||||||
if (existing->functionLike != mac.functionLike)
|
// ordering, spelling, and white-space separation, where all
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom));
|
// white-space separations are considered identical."
|
||||||
else if (existing->args.size() != mac.args.size())
|
if (existing->functionLike != mac.functionLike) {
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define",
|
||||||
else {
|
atomStrings.getString(defAtom));
|
||||||
if (existing->args != mac.args)
|
} else if (existing->args.size() != mac.args.size()) {
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
|
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();
|
existing->body.reset();
|
||||||
mac.body.reset();
|
mac.body.reset();
|
||||||
int newToken;
|
int newToken;
|
||||||
|
bool firstToken = true;
|
||||||
do {
|
do {
|
||||||
int oldToken;
|
int oldToken;
|
||||||
TPpToken oldPpToken;
|
TPpToken oldPpToken;
|
||||||
TPpToken newPpToken;
|
TPpToken newPpToken;
|
||||||
oldToken = existing->body.getToken(parseContext, &oldPpToken);
|
oldToken = existing->body.getToken(parseContext, &oldPpToken);
|
||||||
newToken = mac.body.getToken(parseContext, &newPpToken);
|
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) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
} while (newToken > 0);
|
} while (newToken != EndOfInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*existing = mac;
|
*existing = mac;
|
||||||
|
|||||||
@ -252,11 +252,13 @@ public:
|
|||||||
public:
|
public:
|
||||||
Token(int atom, const TPpToken& ppToken) :
|
Token(int atom, const TPpToken& ppToken) :
|
||||||
atom(atom),
|
atom(atom),
|
||||||
|
space(ppToken.space),
|
||||||
i64val(ppToken.i64val),
|
i64val(ppToken.i64val),
|
||||||
name(ppToken.name) { }
|
name(ppToken.name) { }
|
||||||
int get(TPpToken& ppToken)
|
int get(TPpToken& ppToken)
|
||||||
{
|
{
|
||||||
ppToken.clear();
|
ppToken.clear();
|
||||||
|
ppToken.space = space;
|
||||||
ppToken.i64val = i64val;
|
ppToken.i64val = i64val;
|
||||||
snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str());
|
snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str());
|
||||||
return atom;
|
return atom;
|
||||||
@ -265,6 +267,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
Token() {}
|
Token() {}
|
||||||
int atom;
|
int atom;
|
||||||
|
bool space; // did a space precede the token?
|
||||||
long long i64val;
|
long long i64val;
|
||||||
TString name;
|
TString name;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user