33
33
#include " clang/Lex/PreprocessorOptions.h"
34
34
#include " clang/Lex/PTHLexer.h"
35
35
#include " clang/Lex/Token.h"
36
+ #include " clang/Lex/VariadicMacroSupport.h"
36
37
#include " llvm/ADT/ArrayRef.h"
37
38
#include " llvm/ADT/SmallString.h"
38
39
#include " llvm/ADT/SmallVector.h"
@@ -2290,6 +2291,10 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2290
2291
Token Tok;
2291
2292
LexUnexpandedToken (Tok);
2292
2293
2294
+ // Used to un-poison and then re-poison identifiers of the __VA_ARGS__ ilk
2295
+ // within their appropriate context.
2296
+ VariadicMacroScopeGuard VariadicMacroScopeGuard (*this );
2297
+
2293
2298
// If this is a function-like macro definition, parse the argument list,
2294
2299
// marking each of the identifiers as being used as macro arguments. Also,
2295
2300
// check other constraints on the first token of the macro body.
@@ -2314,14 +2319,14 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2314
2319
return nullptr ;
2315
2320
}
2316
2321
2317
- // If this is a definition of a variadic C99 function-like macro, not using
2318
- // the GNU named varargs extension, enabled __VA_ARGS__.
2322
+ // If this is a definition of an ISO C/C++ variadic function-like macro (not
2323
+ // using the GNU named varargs extension) inform our variadic scope guard
2324
+ // which un-poisons and re-poisons certain identifiers (e.g. __VA_ARGS__)
2325
+ // allowed only within the definition of a variadic macro.
2319
2326
2320
- // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
2321
- // This gets unpoisoned where it is allowed.
2322
- assert (Ident__VA_ARGS__->isPoisoned () && " __VA_ARGS__ should be poisoned!" );
2323
- if (MI->isC99Varargs ())
2324
- Ident__VA_ARGS__->setIsPoisoned (false );
2327
+ if (MI->isC99Varargs ()) {
2328
+ VariadicMacroScopeGuard.enterScope ();
2329
+ }
2325
2330
2326
2331
// Read the first token after the arg list for down below.
2327
2332
LexUnexpandedToken (Tok);
@@ -2431,9 +2436,6 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2431
2436
} else {
2432
2437
Diag (Tok, diag::err_pp_stringize_not_parameter)
2433
2438
<< LastTok.is (tok::hashat);
2434
-
2435
- // Disable __VA_ARGS__ again.
2436
- Ident__VA_ARGS__->setIsPoisoned (true );
2437
2439
return nullptr ;
2438
2440
}
2439
2441
}
@@ -2448,9 +2450,6 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
2448
2450
}
2449
2451
}
2450
2452
MI->setDefinitionEndLoc (LastTok.getLocation ());
2451
- // Disable __VA_ARGS__ again.
2452
- Ident__VA_ARGS__->setIsPoisoned (true );
2453
-
2454
2453
return MI;
2455
2454
}
2456
2455
// / HandleDefineDirective - Implements \#define. This consumes the entire macro
0 commit comments