@@ -121,6 +121,40 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP,
121
121
// Preprocessor Pragma Directive Handling.
122
122
// ===----------------------------------------------------------------------===//
123
123
124
+ namespace {
125
+ // TokenCollector provides the option to collect tokens that were "read"
126
+ // and return them to the stream to be read later.
127
+ // Currently used when reading _Pragma/__pragma directives.
128
+ struct TokenCollector {
129
+ Preprocessor &Self;
130
+ bool Collect;
131
+ SmallVector<Token, 3 > Tokens;
132
+ Token &Tok;
133
+
134
+ void lex () {
135
+ if (Collect)
136
+ Tokens.push_back (Tok);
137
+ Self.Lex (Tok);
138
+ }
139
+
140
+ void revert () {
141
+ assert (Collect && " did not collect tokens" );
142
+ assert (!Tokens.empty () && " collected unexpected number of tokens" );
143
+
144
+ // Push the ( "string" ) tokens into the token stream.
145
+ auto Toks = std::make_unique<Token[]>(Tokens.size ());
146
+ std::copy (Tokens.begin () + 1 , Tokens.end (), Toks.get ());
147
+ Toks[Tokens.size () - 1 ] = Tok;
148
+ Self.EnterTokenStream (std::move (Toks), Tokens.size (),
149
+ /* DisableMacroExpansion*/ true ,
150
+ /* IsReinject*/ true );
151
+
152
+ // ... and return the pragma token unchanged.
153
+ Tok = *Tokens.begin ();
154
+ }
155
+ };
156
+ } // namespace
157
+
124
158
// / HandlePragmaDirective - The "\#pragma" directive has been parsed. Lex the
125
159
// / rest of the pragma, passing it to the registered pragma handlers.
126
160
void Preprocessor::HandlePragmaDirective (PragmaIntroducer Introducer) {
@@ -166,35 +200,6 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
166
200
// In Case #2, we check the syntax now, but then put the tokens back into the
167
201
// token stream for later consumption.
168
202
169
- struct TokenCollector {
170
- Preprocessor &Self;
171
- bool Collect;
172
- SmallVector<Token, 3 > Tokens;
173
- Token &Tok;
174
-
175
- void lex () {
176
- if (Collect)
177
- Tokens.push_back (Tok);
178
- Self.Lex (Tok);
179
- }
180
-
181
- void revert () {
182
- assert (Collect && " did not collect tokens" );
183
- assert (!Tokens.empty () && " collected unexpected number of tokens" );
184
-
185
- // Push the ( "string" ) tokens into the token stream.
186
- auto Toks = std::make_unique<Token[]>(Tokens.size ());
187
- std::copy (Tokens.begin () + 1 , Tokens.end (), Toks.get ());
188
- Toks[Tokens.size () - 1 ] = Tok;
189
- Self.EnterTokenStream (std::move (Toks), Tokens.size (),
190
- /* DisableMacroExpansion*/ true ,
191
- /* IsReinject*/ true );
192
-
193
- // ... and return the _Pragma token unchanged.
194
- Tok = *Tokens.begin ();
195
- }
196
- };
197
-
198
203
TokenCollector Toks = {*this , InMacroArgPreExpansion, {}, Tok};
199
204
200
205
// Remember the pragma token location.
@@ -328,11 +333,15 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
328
333
// / HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
329
334
// / is not enclosed within a string literal.
330
335
void Preprocessor::HandleMicrosoft__pragma (Token &Tok) {
336
+ // During macro pre-expansion, check the syntax now but put the tokens back
337
+ // into the token stream for later consumption. Same as Handle_Pragma.
338
+ TokenCollector Toks = {*this , InMacroArgPreExpansion, {}, Tok};
339
+
331
340
// Remember the pragma token location.
332
341
SourceLocation PragmaLoc = Tok.getLocation ();
333
342
334
343
// Read the '('.
335
- Lex (Tok );
344
+ Toks. lex ( );
336
345
if (Tok.isNot (tok::l_paren)) {
337
346
Diag (PragmaLoc, diag::err__Pragma_malformed);
338
347
return ;
@@ -341,21 +350,27 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
341
350
// Get the tokens enclosed within the __pragma(), as well as the final ')'.
342
351
SmallVector<Token, 32 > PragmaToks;
343
352
int NumParens = 0 ;
344
- Lex (Tok );
353
+ Toks. lex ( );
345
354
while (Tok.isNot (tok::eof)) {
346
355
PragmaToks.push_back (Tok);
347
356
if (Tok.is (tok::l_paren))
348
357
NumParens++;
349
358
else if (Tok.is (tok::r_paren) && NumParens-- == 0 )
350
359
break ;
351
- Lex (Tok );
360
+ Toks. lex ( );
352
361
}
353
362
354
363
if (Tok.is (tok::eof)) {
355
364
Diag (PragmaLoc, diag::err_unterminated___pragma);
356
365
return ;
357
366
}
358
367
368
+ // If we're expanding a macro argument, put the tokens back.
369
+ if (InMacroArgPreExpansion) {
370
+ Toks.revert ();
371
+ return ;
372
+ }
373
+
359
374
PragmaToks.front ().setFlag (Token::LeadingSpace);
360
375
361
376
// Replace the ')' with an EOD to mark the end of the pragma.
0 commit comments