PP: More clearly distinguish funtion-like and object-like macros
This commit is contained in:
parent
0a339ec20c
commit
4ee2f75294
@ -35,9 +35,9 @@ ERROR: 0:155: '#else' : unexpected tokens following directive
|
|||||||
ERROR: 0:158: '#else' : #else after #else
|
ERROR: 0:158: '#else' : #else after #else
|
||||||
ERROR: 0:160: '#endif' : unexpected tokens following directive
|
ERROR: 0:160: '#endif' : unexpected tokens following directive
|
||||||
ERROR: 0:164: '#define' : duplicate macro parameter
|
ERROR: 0:164: '#define' : duplicate macro parameter
|
||||||
ERROR: 0:173: '#define' : Macro redefined; different number of arguments: m4
|
ERROR: 0:173: '#define' : Macro redefined; function-like versus object-like: m4
|
||||||
ERROR: 0:178: '#define' : Macro redefined; different number of arguments: m5
|
ERROR: 0:177: '#define' : Macro redefined; function-like versus object-like: m5
|
||||||
ERROR: 0:182: '#define' : Macro redefined; different number of arguments: m6
|
ERROR: 0:181: '#define' : Macro redefined; different number of arguments: m6
|
||||||
ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7
|
ERROR: 0:185: '#define' : Macro redefined; different substitutions: m7
|
||||||
ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8
|
ERROR: 0:192: '#define' : Macro redefined; different substitutions: m8
|
||||||
ERROR: 0:196: '#define' : Macro redefined; different argument names: m9
|
ERROR: 0:196: '#define' : Macro redefined; different argument names: m9
|
||||||
|
|||||||
4
Test/cppSimple.vert
Normal file → Executable file
4
Test/cppSimple.vert
Normal file → Executable file
@ -170,7 +170,7 @@ int a = length("aoenatuh"); // ERROR
|
|||||||
|
|
||||||
// ERROR
|
// ERROR
|
||||||
#define m4(b)
|
#define m4(b)
|
||||||
#define m4 (b)
|
#define m4
|
||||||
|
|
||||||
// ERROR
|
// ERROR
|
||||||
#define m5 (b)
|
#define m5 (b)
|
||||||
@ -178,7 +178,7 @@ int a = length("aoenatuh"); // ERROR
|
|||||||
|
|
||||||
// ERROR
|
// ERROR
|
||||||
#define m6(a)
|
#define m6(a)
|
||||||
#define m6
|
#define m6(a,b)
|
||||||
|
|
||||||
// ERROR (whitespace)
|
// ERROR (whitespace)
|
||||||
#define m7 (a)
|
#define m7 (a)
|
||||||
|
|||||||
@ -109,11 +109,12 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
|
|
||||||
// save the macro name
|
// save the macro name
|
||||||
const int defAtom = atomStrings.getAddAtom(ppToken->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 (...)
|
// gather parameters to the macro, between (...)
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == '(' && ! ppToken->space) {
|
if (token == '(' && !ppToken->space) {
|
||||||
mac.emptyArgs = 1;
|
mac.functionLike = 1;
|
||||||
do {
|
do {
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (mac.args.size() == 0 && token == ')')
|
if (mac.args.size() == 0 && token == ')')
|
||||||
@ -123,7 +124,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
mac.emptyArgs = 0;
|
|
||||||
const int argAtom = atomStrings.getAddAtom(ppToken->name);
|
const int argAtom = atomStrings.getAddAtom(ppToken->name);
|
||||||
|
|
||||||
// check for duplication of parameter name
|
// check for duplication of parameter name
|
||||||
@ -149,7 +149,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// record the definition of the macro
|
// 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) {
|
while (token != '\n' && token != EndOfInput) {
|
||||||
mac.body.putToken(token, ppToken);
|
mac.body.putToken(token, ppToken);
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
@ -164,7 +163,9 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
|||||||
// 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 preprocessing tokens in both have the same number,
|
||||||
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
// 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));
|
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
||||||
else {
|
else {
|
||||||
if (existing->args != mac.args)
|
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
|
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
|
||||||
in->mac = macro;
|
in->mac = macro;
|
||||||
if (macro->args.size() > 0 || macro->emptyArgs) {
|
if (macro->functionLike) {
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
if (newLineOkay) {
|
if (newLineOkay) {
|
||||||
while (token == '\n')
|
while (token == '\n')
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
if (token != '(') {
|
if (token != '(') {
|
||||||
|
// function-like macro called with object-like syntax: okay, don't expand
|
||||||
UngetToken(token, ppToken);
|
UngetToken(token, ppToken);
|
||||||
delete in;
|
delete in;
|
||||||
return MacroExpandNotStarted;
|
return MacroExpandNotStarted;
|
||||||
|
|||||||
@ -267,12 +267,12 @@ public:
|
|||||||
//
|
//
|
||||||
|
|
||||||
struct MacroSymbol {
|
struct MacroSymbol {
|
||||||
MacroSymbol() : emptyArgs(0), busy(0), undef(0) { }
|
MacroSymbol() : functionLike(0), busy(0), undef(0) { }
|
||||||
TVector<int> args;
|
TVector<int> args;
|
||||||
TokenStream body;
|
TokenStream body;
|
||||||
unsigned emptyArgs : 1;
|
unsigned functionLike : 1; // 0 means object-like, 1 means function-like
|
||||||
unsigned busy : 1;
|
unsigned busy : 1;
|
||||||
unsigned undef : 1;
|
unsigned undef : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TMap<int, MacroSymbol> TSymbolMap;
|
typedef TMap<int, MacroSymbol> TSymbolMap;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user