PP: More clearly distinguish funtion-like and object-like macros
This commit is contained in:
parent
0a339ec20c
commit
4ee2f75294
4 changed files with 17 additions and 15 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue