зеркало из https://github.com/stride3d/xkslang.git
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:
Родитель
5cdf3c5a23
Коммит
6225dd4ba1
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче