Coverage Report

Created: 2022-01-22 13:19

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Parse/ParsePragma.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements the language specific #pragma handlers.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/AST/ASTContext.h"
14
#include "clang/Basic/PragmaKinds.h"
15
#include "clang/Basic/TargetInfo.h"
16
#include "clang/Lex/Preprocessor.h"
17
#include "clang/Lex/Token.h"
18
#include "clang/Parse/LoopHint.h"
19
#include "clang/Parse/ParseDiagnostic.h"
20
#include "clang/Parse/Parser.h"
21
#include "clang/Parse/RAIIObjectsForParser.h"
22
#include "clang/Sema/Scope.h"
23
#include "llvm/ADT/ArrayRef.h"
24
#include "llvm/ADT/StringSwitch.h"
25
using namespace clang;
26
27
namespace {
28
29
struct PragmaAlignHandler : public PragmaHandler {
30
85.4k
  explicit PragmaAlignHandler() : PragmaHandler("align") {}
31
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
32
                    Token &FirstToken) override;
33
};
34
35
struct PragmaGCCVisibilityHandler : public PragmaHandler {
36
85.4k
  explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
37
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
38
                    Token &FirstToken) override;
39
};
40
41
struct PragmaOptionsHandler : public PragmaHandler {
42
85.4k
  explicit PragmaOptionsHandler() : PragmaHandler("options") {}
43
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
44
                    Token &FirstToken) override;
45
};
46
47
struct PragmaPackHandler : public PragmaHandler {
48
85.4k
  explicit PragmaPackHandler() : PragmaHandler("pack") {}
49
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
50
                    Token &FirstToken) override;
51
};
52
53
struct PragmaClangSectionHandler : public PragmaHandler {
54
  explicit PragmaClangSectionHandler(Sema &S)
55
85.4k
             : PragmaHandler("section"), Actions(S) {}
56
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
57
                    Token &FirstToken) override;
58
59
private:
60
  Sema &Actions;
61
};
62
63
struct PragmaMSStructHandler : public PragmaHandler {
64
85.4k
  explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
65
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
66
                    Token &FirstToken) override;
67
};
68
69
struct PragmaUnusedHandler : public PragmaHandler {
70
85.4k
  PragmaUnusedHandler() : PragmaHandler("unused") {}
71
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
72
                    Token &FirstToken) override;
73
};
74
75
struct PragmaWeakHandler : public PragmaHandler {
76
85.4k
  explicit PragmaWeakHandler() : PragmaHandler("weak") {}
77
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
78
                    Token &FirstToken) override;
79
};
80
81
struct PragmaRedefineExtnameHandler : public PragmaHandler {
82
85.4k
  explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
83
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
84
                    Token &FirstToken) override;
85
};
86
87
struct PragmaOpenCLExtensionHandler : public PragmaHandler {
88
614
  PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
89
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
90
                    Token &FirstToken) override;
91
};
92
93
94
struct PragmaFPContractHandler : public PragmaHandler {
95
85.4k
  PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
96
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
97
                    Token &FirstToken) override;
98
};
99
100
// Pragma STDC implementations.
101
102
/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
103
struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
104
85.4k
  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
105
106
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
107
30
                    Token &Tok) override {
108
30
    Token PragmaName = Tok;
109
30
    if (!PP.getTargetInfo().hasStrictFP() && 
!PP.getLangOpts().ExpStrictFP3
) {
110
3
      PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
111
3
          << PragmaName.getIdentifierInfo()->getName();
112
3
      return;
113
3
    }
114
27
    tok::OnOffSwitch OOS;
115
27
    if (PP.LexOnOffSwitch(OOS))
116
3
     return;
117
118
24
    MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
119
24
                                1);
120
24
    Toks[0].startToken();
121
24
    Toks[0].setKind(tok::annot_pragma_fenv_access);
122
24
    Toks[0].setLocation(Tok.getLocation());
123
24
    Toks[0].setAnnotationEndLoc(Tok.getLocation());
124
24
    Toks[0].setAnnotationValue(reinterpret_cast<void*>(
125
24
                               static_cast<uintptr_t>(OOS)));
126
24
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
127
24
                        /*IsReinject=*/false);
128
24
  }
129
};
130
131
/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
132
struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
133
85.4k
  PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
134
135
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
136
9
                    Token &Tok) override {
137
9
    tok::OnOffSwitch OOS;
138
9
    PP.LexOnOffSwitch(OOS);
139
9
  }
140
};
141
142
/// Handler for "\#pragma STDC FENV_ROUND ...".
143
struct PragmaSTDC_FENV_ROUNDHandler : public PragmaHandler {
144
85.4k
  PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler("FENV_ROUND") {}
145
146
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
147
                    Token &Tok) override;
148
};
149
150
/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
151
struct PragmaSTDC_UnknownHandler : public PragmaHandler {
152
85.4k
  PragmaSTDC_UnknownHandler() = default;
153
154
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
155
2
                    Token &UnknownTok) override {
156
    // C99 6.10.6p2, unknown forms are not allowed.
157
2
    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
158
2
  }
159
};
160
161
struct PragmaFPHandler : public PragmaHandler {
162
85.4k
  PragmaFPHandler() : PragmaHandler("fp") {}
163
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
164
                    Token &FirstToken) override;
165
};
166
167
struct PragmaNoOpenMPHandler : public PragmaHandler {
168
73.5k
  PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
169
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
170
                    Token &FirstToken) override;
171
};
172
173
struct PragmaOpenMPHandler : public PragmaHandler {
174
11.8k
  PragmaOpenMPHandler() : PragmaHandler("omp") { }
175
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
176
                    Token &FirstToken) override;
177
};
178
179
/// PragmaCommentHandler - "\#pragma comment ...".
180
struct PragmaCommentHandler : public PragmaHandler {
181
  PragmaCommentHandler(Sema &Actions)
182
37.5k
    : PragmaHandler("comment"), Actions(Actions) {}
183
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
184
                    Token &FirstToken) override;
185
186
private:
187
  Sema &Actions;
188
};
189
190
struct PragmaDetectMismatchHandler : public PragmaHandler {
191
  PragmaDetectMismatchHandler(Sema &Actions)
192
11.0k
    : PragmaHandler("detect_mismatch"), Actions(Actions) {}
193
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
194
                    Token &FirstToken) override;
195
196
private:
197
  Sema &Actions;
198
};
199
200
struct PragmaFloatControlHandler : public PragmaHandler {
201
  PragmaFloatControlHandler(Sema &Actions)
202
85.4k
      : PragmaHandler("float_control") {}
203
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
204
                    Token &FirstToken) override;
205
};
206
207
struct PragmaMSPointersToMembers : public PragmaHandler {
208
11.0k
  explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
209
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
210
                    Token &FirstToken) override;
211
};
212
213
struct PragmaMSVtorDisp : public PragmaHandler {
214
11.0k
  explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
215
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
216
                    Token &FirstToken) override;
217
};
218
219
struct PragmaMSPragma : public PragmaHandler {
220
66.4k
  explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
221
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
222
                    Token &FirstToken) override;
223
};
224
225
/// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
226
struct PragmaOptimizeHandler : public PragmaHandler {
227
  PragmaOptimizeHandler(Sema &S)
228
85.4k
    : PragmaHandler("optimize"), Actions(S) {}
229
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
230
                    Token &FirstToken) override;
231
232
private:
233
  Sema &Actions;
234
};
235
236
struct PragmaLoopHintHandler : public PragmaHandler {
237
85.4k
  PragmaLoopHintHandler() : PragmaHandler("loop") {}
238
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
239
                    Token &FirstToken) override;
240
};
241
242
struct PragmaUnrollHintHandler : public PragmaHandler {
243
341k
  PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
244
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
245
                    Token &FirstToken) override;
246
};
247
248
struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
249
11.0k
  PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
250
};
251
252
struct PragmaMSIntrinsicHandler : public PragmaHandler {
253
11.0k
  PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
254
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
255
                    Token &FirstToken) override;
256
};
257
258
struct PragmaMSOptimizeHandler : public PragmaHandler {
259
11.0k
  PragmaMSOptimizeHandler() : PragmaHandler("optimize") {}
260
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
261
                    Token &FirstToken) override;
262
};
263
264
// "\#pragma fenv_access (on)".
265
struct PragmaMSFenvAccessHandler : public PragmaHandler {
266
11.0k
  PragmaMSFenvAccessHandler() : PragmaHandler("fenv_access") {}
267
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
268
11
                    Token &FirstToken) override {
269
11
    StringRef PragmaName = FirstToken.getIdentifierInfo()->getName();
270
11
    if (!PP.getTargetInfo().hasStrictFP() && 
!PP.getLangOpts().ExpStrictFP0
) {
271
0
      PP.Diag(FirstToken.getLocation(), diag::warn_pragma_fp_ignored)
272
0
          << PragmaName;
273
0
      return;
274
0
    }
275
276
11
    Token Tok;
277
11
    PP.Lex(Tok);
278
11
    if (Tok.isNot(tok::l_paren)) {
279
3
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
280
3
          << PragmaName;
281
3
      return;
282
3
    }
283
8
    PP.Lex(Tok); // Consume the l_paren.
284
8
    if (Tok.isNot(tok::identifier)) {
285
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
286
1
      return;
287
1
    }
288
7
    const IdentifierInfo *II = Tok.getIdentifierInfo();
289
7
    tok::OnOffSwitch OOS;
290
7
    if (II->isStr("on")) {
291
5
      OOS = tok::OOS_ON;
292
5
      PP.Lex(Tok);
293
5
    } else 
if (2
II->isStr("off")2
) {
294
2
      OOS = tok::OOS_OFF;
295
2
      PP.Lex(Tok);
296
2
    } else {
297
0
      PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
298
0
      return;
299
0
    }
300
7
    if (Tok.isNot(tok::r_paren)) {
301
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
302
1
          << PragmaName;
303
1
      return;
304
1
    }
305
6
    PP.Lex(Tok); // Consume the r_paren.
306
307
6
    if (Tok.isNot(tok::eod)) {
308
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
309
1
          << PragmaName;
310
1
      return;
311
1
    }
312
313
5
    MutableArrayRef<Token> Toks(
314
5
        PP.getPreprocessorAllocator().Allocate<Token>(1), 1);
315
5
    Toks[0].startToken();
316
5
    Toks[0].setKind(tok::annot_pragma_fenv_access_ms);
317
5
    Toks[0].setLocation(FirstToken.getLocation());
318
5
    Toks[0].setAnnotationEndLoc(Tok.getLocation());
319
5
    Toks[0].setAnnotationValue(
320
5
        reinterpret_cast<void*>(static_cast<uintptr_t>(OOS)));
321
5
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
322
5
                        /*IsReinject=*/false);
323
5
  }
324
};
325
326
struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
327
  PragmaForceCUDAHostDeviceHandler(Sema &Actions)
328
279
      : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
329
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
330
                    Token &FirstToken) override;
331
332
private:
333
  Sema &Actions;
334
};
335
336
/// PragmaAttributeHandler - "\#pragma clang attribute ...".
337
struct PragmaAttributeHandler : public PragmaHandler {
338
  PragmaAttributeHandler(AttributeFactory &AttrFactory)
339
85.4k
      : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
340
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
341
                    Token &FirstToken) override;
342
343
  /// A pool of attributes that were parsed in \#pragma clang attribute.
344
  ParsedAttributes AttributesForPragmaAttribute;
345
};
346
347
struct PragmaMaxTokensHereHandler : public PragmaHandler {
348
85.4k
  PragmaMaxTokensHereHandler() : PragmaHandler("max_tokens_here") {}
349
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
350
                    Token &FirstToken) override;
351
};
352
353
struct PragmaMaxTokensTotalHandler : public PragmaHandler {
354
85.4k
  PragmaMaxTokensTotalHandler() : PragmaHandler("max_tokens_total") {}
355
  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
356
                    Token &FirstToken) override;
357
};
358
359
1.68k
void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) {
360
1.68k
  for (auto &T : Toks)
361
42.9k
    T.setFlag(clang::Token::IsReinjected);
362
1.68k
}
363
}  // end namespace
364
365
85.4k
void Parser::initializePragmaHandlers() {
366
85.4k
  AlignHandler = std::make_unique<PragmaAlignHandler>();
367
85.4k
  PP.AddPragmaHandler(AlignHandler.get());
368
369
85.4k
  GCCVisibilityHandler = std::make_unique<PragmaGCCVisibilityHandler>();
370
85.4k
  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
371
372
85.4k
  OptionsHandler = std::make_unique<PragmaOptionsHandler>();
373
85.4k
  PP.AddPragmaHandler(OptionsHandler.get());
374
375
85.4k
  PackHandler = std::make_unique<PragmaPackHandler>();
376
85.4k
  PP.AddPragmaHandler(PackHandler.get());
377
378
85.4k
  MSStructHandler = std::make_unique<PragmaMSStructHandler>();
379
85.4k
  PP.AddPragmaHandler(MSStructHandler.get());
380
381
85.4k
  UnusedHandler = std::make_unique<PragmaUnusedHandler>();
382
85.4k
  PP.AddPragmaHandler(UnusedHandler.get());
383
384
85.4k
  WeakHandler = std::make_unique<PragmaWeakHandler>();
385
85.4k
  PP.AddPragmaHandler(WeakHandler.get());
386
387
85.4k
  RedefineExtnameHandler = std::make_unique<PragmaRedefineExtnameHandler>();
388
85.4k
  PP.AddPragmaHandler(RedefineExtnameHandler.get());
389
390
85.4k
  FPContractHandler = std::make_unique<PragmaFPContractHandler>();
391
85.4k
  PP.AddPragmaHandler("STDC", FPContractHandler.get());
392
393
85.4k
  STDCFenvAccessHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
394
85.4k
  PP.AddPragmaHandler("STDC", STDCFenvAccessHandler.get());
395
396
85.4k
  STDCFenvRoundHandler = std::make_unique<PragmaSTDC_FENV_ROUNDHandler>();
397
85.4k
  PP.AddPragmaHandler("STDC", STDCFenvRoundHandler.get());
398
399
85.4k
  STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
400
85.4k
  PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get());
401
402
85.4k
  STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
403
85.4k
  PP.AddPragmaHandler("STDC", STDCUnknownHandler.get());
404
405
85.4k
  PCSectionHandler = std::make_unique<PragmaClangSectionHandler>(Actions);
406
85.4k
  PP.AddPragmaHandler("clang", PCSectionHandler.get());
407
408
85.4k
  if (getLangOpts().OpenCL) {
409
614
    OpenCLExtensionHandler = std::make_unique<PragmaOpenCLExtensionHandler>();
410
614
    PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
411
412
614
    PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
413
614
  }
414
85.4k
  if (getLangOpts().OpenMP)
415
11.8k
    OpenMPHandler = std::make_unique<PragmaOpenMPHandler>();
416
73.5k
  else
417
73.5k
    OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
418
85.4k
  PP.AddPragmaHandler(OpenMPHandler.get());
419
420
85.4k
  if (getLangOpts().MicrosoftExt ||
421
85.4k
      
getTargetInfo().getTriple().isOSBinFormatELF()74.3k
) {
422
37.5k
    MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
423
37.5k
    PP.AddPragmaHandler(MSCommentHandler.get());
424
37.5k
  }
425
426
85.4k
  FloatControlHandler = std::make_unique<PragmaFloatControlHandler>(Actions);
427
85.4k
  PP.AddPragmaHandler(FloatControlHandler.get());
428
85.4k
  if (getLangOpts().MicrosoftExt) {
429
11.0k
    MSDetectMismatchHandler =
430
11.0k
        std::make_unique<PragmaDetectMismatchHandler>(Actions);
431
11.0k
    PP.AddPragmaHandler(MSDetectMismatchHandler.get());
432
11.0k
    MSPointersToMembers = std::make_unique<PragmaMSPointersToMembers>();
433
11.0k
    PP.AddPragmaHandler(MSPointersToMembers.get());
434
11.0k
    MSVtorDisp = std::make_unique<PragmaMSVtorDisp>();
435
11.0k
    PP.AddPragmaHandler(MSVtorDisp.get());
436
11.0k
    MSInitSeg = std::make_unique<PragmaMSPragma>("init_seg");
437
11.0k
    PP.AddPragmaHandler(MSInitSeg.get());
438
11.0k
    MSDataSeg = std::make_unique<PragmaMSPragma>("data_seg");
439
11.0k
    PP.AddPragmaHandler(MSDataSeg.get());
440
11.0k
    MSBSSSeg = std::make_unique<PragmaMSPragma>("bss_seg");
441
11.0k
    PP.AddPragmaHandler(MSBSSSeg.get());
442
11.0k
    MSConstSeg = std::make_unique<PragmaMSPragma>("const_seg");
443
11.0k
    PP.AddPragmaHandler(MSConstSeg.get());
444
11.0k
    MSCodeSeg = std::make_unique<PragmaMSPragma>("code_seg");
445
11.0k
    PP.AddPragmaHandler(MSCodeSeg.get());
446
11.0k
    MSSection = std::make_unique<PragmaMSPragma>("section");
447
11.0k
    PP.AddPragmaHandler(MSSection.get());
448
11.0k
    MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
449
11.0k
    PP.AddPragmaHandler(MSRuntimeChecks.get());
450
11.0k
    MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
451
11.0k
    PP.AddPragmaHandler(MSIntrinsic.get());
452
11.0k
    MSOptimize = std::make_unique<PragmaMSOptimizeHandler>();
453
11.0k
    PP.AddPragmaHandler(MSOptimize.get());
454
11.0k
    MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
455
11.0k
    PP.AddPragmaHandler(MSFenvAccess.get());
456
11.0k
  }
457
458
85.4k
  if (getLangOpts().CUDA) {
459
279
    CUDAForceHostDeviceHandler =
460
279
        std::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
461
279
    PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
462
279
  }
463
464
85.4k
  OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
465
85.4k
  PP.AddPragmaHandler("clang", OptimizeHandler.get());
466
467
85.4k
  LoopHintHandler = std::make_unique<PragmaLoopHintHandler>();
468
85.4k
  PP.AddPragmaHandler("clang", LoopHintHandler.get());
469
470
85.4k
  UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("unroll");
471
85.4k
  PP.AddPragmaHandler(UnrollHintHandler.get());
472
85.4k
  PP.AddPragmaHandler("GCC", UnrollHintHandler.get());
473
474
85.4k
  NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("nounroll");
475
85.4k
  PP.AddPragmaHandler(NoUnrollHintHandler.get());
476
85.4k
  PP.AddPragmaHandler("GCC", NoUnrollHintHandler.get());
477
478
85.4k
  UnrollAndJamHintHandler =
479
85.4k
      std::make_unique<PragmaUnrollHintHandler>("unroll_and_jam");
480
85.4k
  PP.AddPragmaHandler(UnrollAndJamHintHandler.get());
481
482
85.4k
  NoUnrollAndJamHintHandler =
483
85.4k
      std::make_unique<PragmaUnrollHintHandler>("nounroll_and_jam");
484
85.4k
  PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
485
486
85.4k
  FPHandler = std::make_unique<PragmaFPHandler>();
487
85.4k
  PP.AddPragmaHandler("clang", FPHandler.get());
488
489
85.4k
  AttributePragmaHandler =
490
85.4k
      std::make_unique<PragmaAttributeHandler>(AttrFactory);
491
85.4k
  PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
492
493
85.4k
  MaxTokensHerePragmaHandler = std::make_unique<PragmaMaxTokensHereHandler>();
494
85.4k
  PP.AddPragmaHandler("clang", MaxTokensHerePragmaHandler.get());
495
496
85.4k
  MaxTokensTotalPragmaHandler = std::make_unique<PragmaMaxTokensTotalHandler>();
497
85.4k
  PP.AddPragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
498
85.4k
}
499
500
85.3k
void Parser::resetPragmaHandlers() {
501
  // Remove the pragma handlers we installed.
502
85.3k
  PP.RemovePragmaHandler(AlignHandler.get());
503
85.3k
  AlignHandler.reset();
504
85.3k
  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
505
85.3k
  GCCVisibilityHandler.reset();
506
85.3k
  PP.RemovePragmaHandler(OptionsHandler.get());
507
85.3k
  OptionsHandler.reset();
508
85.3k
  PP.RemovePragmaHandler(PackHandler.get());
509
85.3k
  PackHandler.reset();
510
85.3k
  PP.RemovePragmaHandler(MSStructHandler.get());
511
85.3k
  MSStructHandler.reset();
512
85.3k
  PP.RemovePragmaHandler(UnusedHandler.get());
513
85.3k
  UnusedHandler.reset();
514
85.3k
  PP.RemovePragmaHandler(WeakHandler.get());
515
85.3k
  WeakHandler.reset();
516
85.3k
  PP.RemovePragmaHandler(RedefineExtnameHandler.get());
517
85.3k
  RedefineExtnameHandler.reset();
518
519
85.3k
  if (getLangOpts().OpenCL) {
520
614
    PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
521
614
    OpenCLExtensionHandler.reset();
522
614
    PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
523
614
  }
524
85.3k
  PP.RemovePragmaHandler(OpenMPHandler.get());
525
85.3k
  OpenMPHandler.reset();
526
527
85.3k
  if (getLangOpts().MicrosoftExt ||
528
85.3k
      
getTargetInfo().getTriple().isOSBinFormatELF()74.2k
) {
529
37.5k
    PP.RemovePragmaHandler(MSCommentHandler.get());
530
37.5k
    MSCommentHandler.reset();
531
37.5k
  }
532
533
85.3k
  PP.RemovePragmaHandler("clang", PCSectionHandler.get());
534
85.3k
  PCSectionHandler.reset();
535
536
85.3k
  PP.RemovePragmaHandler(FloatControlHandler.get());
537
85.3k
  FloatControlHandler.reset();
538
85.3k
  if (getLangOpts().MicrosoftExt) {
539
11.0k
    PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
540
11.0k
    MSDetectMismatchHandler.reset();
541
11.0k
    PP.RemovePragmaHandler(MSPointersToMembers.get());
542
11.0k
    MSPointersToMembers.reset();
543
11.0k
    PP.RemovePragmaHandler(MSVtorDisp.get());
544
11.0k
    MSVtorDisp.reset();
545
11.0k
    PP.RemovePragmaHandler(MSInitSeg.get());
546
11.0k
    MSInitSeg.reset();
547
11.0k
    PP.RemovePragmaHandler(MSDataSeg.get());
548
11.0k
    MSDataSeg.reset();
549
11.0k
    PP.RemovePragmaHandler(MSBSSSeg.get());
550
11.0k
    MSBSSSeg.reset();
551
11.0k
    PP.RemovePragmaHandler(MSConstSeg.get());
552
11.0k
    MSConstSeg.reset();
553
11.0k
    PP.RemovePragmaHandler(MSCodeSeg.get());
554
11.0k
    MSCodeSeg.reset();
555
11.0k
    PP.RemovePragmaHandler(MSSection.get());
556
11.0k
    MSSection.reset();
557
11.0k
    PP.RemovePragmaHandler(MSRuntimeChecks.get());
558
11.0k
    MSRuntimeChecks.reset();
559
11.0k
    PP.RemovePragmaHandler(MSIntrinsic.get());
560
11.0k
    MSIntrinsic.reset();
561
11.0k
    PP.RemovePragmaHandler(MSOptimize.get());
562
11.0k
    MSOptimize.reset();
563
11.0k
    PP.RemovePragmaHandler(MSFenvAccess.get());
564
11.0k
    MSFenvAccess.reset();
565
11.0k
  }
566
567
85.3k
  if (getLangOpts().CUDA) {
568
279
    PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
569
279
    CUDAForceHostDeviceHandler.reset();
570
279
  }
571
572
85.3k
  PP.RemovePragmaHandler("STDC", FPContractHandler.get());
573
85.3k
  FPContractHandler.reset();
574
575
85.3k
  PP.RemovePragmaHandler("STDC", STDCFenvAccessHandler.get());
576
85.3k
  STDCFenvAccessHandler.reset();
577
578
85.3k
  PP.RemovePragmaHandler("STDC", STDCFenvRoundHandler.get());
579
85.3k
  STDCFenvRoundHandler.reset();
580
581
85.3k
  PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get());
582
85.3k
  STDCCXLIMITHandler.reset();
583
584
85.3k
  PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
585
85.3k
  STDCUnknownHandler.reset();
586
587
85.3k
  PP.RemovePragmaHandler("clang", OptimizeHandler.get());
588
85.3k
  OptimizeHandler.reset();
589
590
85.3k
  PP.RemovePragmaHandler("clang", LoopHintHandler.get());
591
85.3k
  LoopHintHandler.reset();
592
593
85.3k
  PP.RemovePragmaHandler(UnrollHintHandler.get());
594
85.3k
  PP.RemovePragmaHandler("GCC", UnrollHintHandler.get());
595
85.3k
  UnrollHintHandler.reset();
596
597
85.3k
  PP.RemovePragmaHandler(NoUnrollHintHandler.get());
598
85.3k
  PP.RemovePragmaHandler("GCC", NoUnrollHintHandler.get());
599
85.3k
  NoUnrollHintHandler.reset();
600
601
85.3k
  PP.RemovePragmaHandler(UnrollAndJamHintHandler.get());
602
85.3k
  UnrollAndJamHintHandler.reset();
603
604
85.3k
  PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
605
85.3k
  NoUnrollAndJamHintHandler.reset();
606
607
85.3k
  PP.RemovePragmaHandler("clang", FPHandler.get());
608
85.3k
  FPHandler.reset();
609
610
85.3k
  PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
611
85.3k
  AttributePragmaHandler.reset();
612
613
85.3k
  PP.RemovePragmaHandler("clang", MaxTokensHerePragmaHandler.get());
614
85.3k
  MaxTokensHerePragmaHandler.reset();
615
616
85.3k
  PP.RemovePragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
617
85.3k
  MaxTokensTotalPragmaHandler.reset();
618
85.3k
}
619
620
/// Handle the annotation token produced for #pragma unused(...)
621
///
622
/// Each annot_pragma_unused is followed by the argument token so e.g.
623
/// "#pragma unused(x,y)" becomes:
624
/// annot_pragma_unused 'x' annot_pragma_unused 'y'
625
25
void Parser::HandlePragmaUnused() {
626
25
  assert(Tok.is(tok::annot_pragma_unused));
627
0
  SourceLocation UnusedLoc = ConsumeAnnotationToken();
628
25
  Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
629
25
  ConsumeToken(); // The argument token.
630
25
}
631
632
115
void Parser::HandlePragmaVisibility() {
633
115
  assert(Tok.is(tok::annot_pragma_vis));
634
0
  const IdentifierInfo *VisType =
635
115
    static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
636
115
  SourceLocation VisLoc = ConsumeAnnotationToken();
637
115
  Actions.ActOnPragmaVisibility(VisType, VisLoc);
638
115
}
639
640
namespace {
641
struct PragmaPackInfo {
642
  Sema::PragmaMsStackAction Action;
643
  StringRef SlotLabel;
644
  Token Alignment;
645
};
646
} // end anonymous namespace
647
648
254k
void Parser::HandlePragmaPack() {
649
254k
  assert(Tok.is(tok::annot_pragma_pack));
650
0
  PragmaPackInfo *Info =
651
254k
    static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
652
254k
  SourceLocation PragmaLoc = Tok.getLocation();
653
254k
  ExprResult Alignment;
654
254k
  if (Info->Alignment.is(tok::numeric_constant)) {
655
127k
    Alignment = Actions.ActOnNumericConstant(Info->Alignment);
656
127k
    if (Alignment.isInvalid()) {
657
0
      ConsumeAnnotationToken();
658
0
      return;
659
0
    }
660
127k
  }
661
254k
  Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
662
254k
                          Alignment.get());
663
  // Consume the token after processing the pragma to enable pragma-specific
664
  // #include warnings.
665
254k
  ConsumeAnnotationToken();
666
254k
}
667
668
14
void Parser::HandlePragmaMSStruct() {
669
14
  assert(Tok.is(tok::annot_pragma_msstruct));
670
0
  PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
671
14
      reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
672
14
  Actions.ActOnPragmaMSStruct(Kind);
673
14
  ConsumeAnnotationToken();
674
14
}
675
676
2.77k
void Parser::HandlePragmaAlign() {
677
2.77k
  assert(Tok.is(tok::annot_pragma_align));
678
0
  Sema::PragmaOptionsAlignKind Kind =
679
2.77k
    static_cast<Sema::PragmaOptionsAlignKind>(
680
2.77k
    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
681
2.77k
  Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
682
  // Consume the token after processing the pragma to enable pragma-specific
683
  // #include warnings.
684
2.77k
  ConsumeAnnotationToken();
685
2.77k
}
686
687
20
void Parser::HandlePragmaDump() {
688
20
  assert(Tok.is(tok::annot_pragma_dump));
689
0
  IdentifierInfo *II =
690
20
      reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
691
20
  Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
692
20
  ConsumeAnnotationToken();
693
20
}
694
695
91
void Parser::HandlePragmaWeak() {
696
91
  assert(Tok.is(tok::annot_pragma_weak));
697
0
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
698
91
  Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
699
91
                            Tok.getLocation());
700
91
  ConsumeToken(); // The weak name.
701
91
}
702
703
22
void Parser::HandlePragmaWeakAlias() {
704
22
  assert(Tok.is(tok::annot_pragma_weakalias));
705
0
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
706
22
  IdentifierInfo *WeakName = Tok.getIdentifierInfo();
707
22
  SourceLocation WeakNameLoc = Tok.getLocation();
708
22
  ConsumeToken();
709
22
  IdentifierInfo *AliasName = Tok.getIdentifierInfo();
710
22
  SourceLocation AliasNameLoc = Tok.getLocation();
711
22
  ConsumeToken();
712
22
  Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
713
22
                               WeakNameLoc, AliasNameLoc);
714
715
22
}
716
717
11
void Parser::HandlePragmaRedefineExtname() {
718
11
  assert(Tok.is(tok::annot_pragma_redefine_extname));
719
0
  SourceLocation RedefLoc = ConsumeAnnotationToken();
720
11
  IdentifierInfo *RedefName = Tok.getIdentifierInfo();
721
11
  SourceLocation RedefNameLoc = Tok.getLocation();
722
11
  ConsumeToken();
723
11
  IdentifierInfo *AliasName = Tok.getIdentifierInfo();
724
11
  SourceLocation AliasNameLoc = Tok.getLocation();
725
11
  ConsumeToken();
726
11
  Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
727
11
                                     RedefNameLoc, AliasNameLoc);
728
11
}
729
730
33
void Parser::HandlePragmaFPContract() {
731
33
  assert(Tok.is(tok::annot_pragma_fp_contract));
732
0
  tok::OnOffSwitch OOS =
733
33
    static_cast<tok::OnOffSwitch>(
734
33
    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
735
736
33
  LangOptions::FPModeKind FPC;
737
33
  switch (OOS) {
738
24
  case tok::OOS_ON:
739
24
    FPC = LangOptions::FPM_On;
740
24
    break;
741
7
  case tok::OOS_OFF:
742
7
    FPC = LangOptions::FPM_Off;
743
7
    break;
744
2
  case tok::OOS_DEFAULT:
745
2
    FPC = getLangOpts().getDefaultFPContractMode();
746
2
    break;
747
33
  }
748
749
33
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
750
33
  Actions.ActOnPragmaFPContract(PragmaLoc, FPC);
751
33
}
752
753
296
void Parser::HandlePragmaFloatControl() {
754
296
  assert(Tok.is(tok::annot_pragma_float_control));
755
756
  // The value that is held on the PragmaFloatControlStack encodes
757
  // the PragmaFloatControl kind and the MSStackAction kind
758
  // into a single 32-bit word. The MsStackAction is the high 16 bits
759
  // and the FloatControl is the lower 16 bits. Use shift and bit-and
760
  // to decode the parts.
761
0
  uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
762
296
  Sema::PragmaMsStackAction Action =
763
296
      static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
764
296
  PragmaFloatControlKind Kind = PragmaFloatControlKind(Value & 0xFFFF);
765
296
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
766
296
  Actions.ActOnPragmaFloatControl(PragmaLoc, Action, Kind);
767
296
}
768
769
25
void Parser::HandlePragmaFEnvAccess() {
770
25
  assert(Tok.is(tok::annot_pragma_fenv_access) ||
771
25
         Tok.is(tok::annot_pragma_fenv_access_ms));
772
0
  tok::OnOffSwitch OOS =
773
25
    static_cast<tok::OnOffSwitch>(
774
25
    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
775
776
25
  bool IsEnabled;
777
25
  switch (OOS) {
778
14
  case tok::OOS_ON:
779
14
    IsEnabled = true;
780
14
    break;
781
11
  case tok::OOS_OFF:
782
11
    IsEnabled = false;
783
11
    break;
784
0
  case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
785
0
    IsEnabled = false;
786
0
    break;
787
25
  }
788
789
25
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
790
25
  Actions.ActOnPragmaFEnvAccess(PragmaLoc, IsEnabled);
791
25
}
792
793
34
void Parser::HandlePragmaFEnvRound() {
794
34
  assert(Tok.is(tok::annot_pragma_fenv_round));
795
0
  auto RM = static_cast<llvm::RoundingMode>(
796
34
      reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
797
798
34
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
799
34
  Actions.setRoundingMode(PragmaLoc, RM);
800
34
}
801
802
StmtResult Parser::HandlePragmaCaptured()
803
57
{
804
57
  assert(Tok.is(tok::annot_pragma_captured));
805
0
  ConsumeAnnotationToken();
806
807
57
  if (Tok.isNot(tok::l_brace)) {
808
1
    PP.Diag(Tok, diag::err_expected) << tok::l_brace;
809
1
    return StmtError();
810
1
  }
811
812
56
  SourceLocation Loc = Tok.getLocation();
813
814
56
  ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope |
815
56
                                           Scope::CompoundStmtScope);
816
56
  Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
817
56
                                   /*NumParams=*/1);
818
819
56
  StmtResult R = ParseCompoundStatement();
820
56
  CapturedRegionScope.Exit();
821
822
56
  if (R.isInvalid()) {
823
0
    Actions.ActOnCapturedRegionError();
824
0
    return StmtError();
825
0
  }
826
827
56
  return Actions.ActOnCapturedRegionEnd(R.get());
828
56
}
829
830
namespace {
831
  enum OpenCLExtState : char {
832
    Disable, Enable, Begin, End
833
  };
834
  typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
835
}
836
837
1.26k
void Parser::HandlePragmaOpenCLExtension() {
838
1.26k
  assert(Tok.is(tok::annot_pragma_opencl_extension));
839
0
  OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
840
1.26k
  auto State = Data->second;
841
1.26k
  auto Ident = Data->first;
842
1.26k
  SourceLocation NameLoc = Tok.getLocation();
843
1.26k
  ConsumeAnnotationToken();
844
845
1.26k
  auto &Opt = Actions.getOpenCLOptions();
846
1.26k
  auto Name = Ident->getName();
847
  // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
848
  // overriding all previously issued extension directives, but only if the
849
  // behavior is set to disable."
850
1.26k
  if (Name == "all") {
851
84
    if (State == Disable)
852
75
      Opt.disableAll();
853
9
    else
854
9
      PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
855
1.17k
  } else if (State == Begin) {
856
28
    if (!Opt.isKnown(Name) || 
!Opt.isSupported(Name, getLangOpts())12
) {
857
16
      Opt.support(Name);
858
      // FIXME: Default behavior of the extension pragma is not defined.
859
      // Therefore, it should never be added by default.
860
16
      Opt.acceptsPragma(Name);
861
16
    }
862
1.14k
  } else if (State == End) {
863
    // There is no behavior for this directive. We only accept this for
864
    // backward compatibility.
865
1.11k
  } else if (!Opt.isKnown(Name) || 
!Opt.isWithPragma(Name)1.08k
)
866
298
    PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
867
819
  else if (Opt.isSupportedExtension(Name, getLangOpts()))
868
586
    Opt.enable(Name, State == Enable);
869
233
  else if (Opt.isSupportedCoreOrOptionalCore(Name, getLangOpts()))
870
154
    PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
871
79
  else
872
79
    PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
873
1.26k
}
874
875
25
void Parser::HandlePragmaMSPointersToMembers() {
876
25
  assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
877
0
  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
878
25
      static_cast<LangOptions::PragmaMSPointersToMembersKind>(
879
25
          reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
880
25
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
881
25
  Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
882
25
}
883
884
45
void Parser::HandlePragmaMSVtorDisp() {
885
45
  assert(Tok.is(tok::annot_pragma_ms_vtordisp));
886
0
  uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
887
45
  Sema::PragmaMsStackAction Action =
888
45
      static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
889
45
  MSVtorDispMode Mode = MSVtorDispMode(Value & 0xFFFF);
890
45
  SourceLocation PragmaLoc = ConsumeAnnotationToken();
891
45
  Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
892
45
}
893
894
146
void Parser::HandlePragmaMSPragma() {
895
146
  assert(Tok.is(tok::annot_pragma_ms_pragma));
896
  // Grab the tokens out of the annotation and enter them into the stream.
897
0
  auto TheTokens =
898
146
      (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
899
146
  PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true,
900
146
                      /*IsReinject=*/true);
901
146
  SourceLocation PragmaLocation = ConsumeAnnotationToken();
902
146
  assert(Tok.isAnyIdentifier());
903
0
  StringRef PragmaName = Tok.getIdentifierInfo()->getName();
904
146
  PP.Lex(Tok); // pragma kind
905
906
  // Figure out which #pragma we're dealing with.  The switch has no default
907
  // because lex shouldn't emit the annotation token for unrecognized pragmas.
908
146
  typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
909
146
  PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
910
146
    .Case("data_seg", &Parser::HandlePragmaMSSegment)
911
146
    .Case("bss_seg", &Parser::HandlePragmaMSSegment)
912
146
    .Case("const_seg", &Parser::HandlePragmaMSSegment)
913
146
    .Case("code_seg", &Parser::HandlePragmaMSSegment)
914
146
    .Case("section", &Parser::HandlePragmaMSSection)
915
146
    .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
916
917
146
  if (!(this->*Handler)(PragmaName, PragmaLocation)) {
918
    // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
919
    // until eof (really end of line) to prevent follow-on errors.
920
102
    while (Tok.isNot(tok::eof))
921
59
      PP.Lex(Tok);
922
43
    PP.Lex(Tok);
923
43
  }
924
146
}
925
926
bool Parser::HandlePragmaMSSection(StringRef PragmaName,
927
31
                                   SourceLocation PragmaLocation) {
928
31
  if (Tok.isNot(tok::l_paren)) {
929
1
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
930
1
    return false;
931
1
  }
932
30
  PP.Lex(Tok); // (
933
  // Parsing code for pragma section
934
30
  if (Tok.isNot(tok::string_literal)) {
935
2
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
936
2
        << PragmaName;
937
2
    return false;
938
2
  }
939
28
  ExprResult StringResult = ParseStringLiteralExpression();
940
28
  if (StringResult.isInvalid())
941
0
    return false; // Already diagnosed.
942
28
  StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
943
28
  if (SegmentName->getCharByteWidth() != 1) {
944
0
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
945
0
        << PragmaName;
946
0
    return false;
947
0
  }
948
28
  int SectionFlags = ASTContext::PSF_Read;
949
28
  bool SectionFlagsAreDefault = true;
950
82
  while (Tok.is(tok::comma)) {
951
58
    PP.Lex(Tok); // ,
952
    // Ignore "long" and "short".
953
    // They are undocumented, but widely used, section attributes which appear
954
    // to do nothing.
955
58
    if (Tok.is(tok::kw_long) || 
Tok.is(tok::kw_short)42
) {
956
17
      PP.Lex(Tok); // long/short
957
17
      continue;
958
17
    }
959
960
41
    if (!Tok.isAnyIdentifier()) {
961
2
      PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
962
2
          << PragmaName;
963
2
      return false;
964
2
    }
965
39
    ASTContext::PragmaSectionFlag Flag =
966
39
      llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
967
39
      Tok.getIdentifierInfo()->getName())
968
39
      .Case("read", ASTContext::PSF_Read)
969
39
      .Case("write", ASTContext::PSF_Write)
970
39
      .Case("execute", ASTContext::PSF_Execute)
971
39
      .Case("shared", ASTContext::PSF_Invalid)
972
39
      .Case("nopage", ASTContext::PSF_Invalid)
973
39
      .Case("nocache", ASTContext::PSF_Invalid)
974
39
      .Case("discard", ASTContext::PSF_Invalid)
975
39
      .Case("remove", ASTContext::PSF_Invalid)
976
39
      .Default(ASTContext::PSF_None);
977
39
    if (Flag == ASTContext::PSF_None || 
Flag == ASTContext::PSF_Invalid38
) {
978
2
      PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
979
2
                                  ? 
diag::warn_pragma_invalid_specific_action1
980
2
                                  : 
diag::warn_pragma_unsupported_action1
)
981
2
          << PragmaName << Tok.getIdentifierInfo()->getName();
982
2
      return false;
983
2
    }
984
37
    SectionFlags |= Flag;
985
37
    SectionFlagsAreDefault = false;
986
37
    PP.Lex(Tok); // Identifier
987
37
  }
988
  // If no section attributes are specified, the section will be marked as
989
  // read/write.
990
24
  if (SectionFlagsAreDefault)
991
5
    SectionFlags |= ASTContext::PSF_Write;
992
24
  if (Tok.isNot(tok::r_paren)) {
993
2
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
994
2
    return false;
995
2
  }
996
22
  PP.Lex(Tok); // )
997
22
  if (Tok.isNot(tok::eof)) {
998
0
    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
999
0
        << PragmaName;
1000
0
    return false;
1001
0
  }
1002
22
  PP.Lex(Tok); // eof
1003
22
  Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
1004
22
  return true;
1005
22
}
1006
1007
bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
1008
67
                                   SourceLocation PragmaLocation) {
1009
67
  if (Tok.isNot(tok::l_paren)) {
1010
2
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
1011
2
    return false;
1012
2
  }
1013
65
  PP.Lex(Tok); // (
1014
65
  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1015
65
  StringRef SlotLabel;
1016
65
  if (Tok.isAnyIdentifier()) {
1017
27
    StringRef PushPop = Tok.getIdentifierInfo()->getName();
1018
27
    if (PushPop == "push")
1019
20
      Action = Sema::PSK_Push;
1020
7
    else if (PushPop == "pop")
1021
7
      Action = Sema::PSK_Pop;
1022
0
    else {
1023
0
      PP.Diag(PragmaLocation,
1024
0
              diag::warn_pragma_expected_section_push_pop_or_name)
1025
0
          << PragmaName;
1026
0
      return false;
1027
0
    }
1028
27
    if (Action != Sema::PSK_Reset) {
1029
27
      PP.Lex(Tok); // push | pop
1030
27
      if (Tok.is(tok::comma)) {
1031
20
        PP.Lex(Tok); // ,
1032
        // If we've got a comma, we either need a label or a string.
1033
20
        if (Tok.isAnyIdentifier()) {
1034
4
          SlotLabel = Tok.getIdentifierInfo()->getName();
1035
4
          PP.Lex(Tok); // identifier
1036
4
          if (Tok.is(tok::comma))
1037
3
            PP.Lex(Tok);
1038
1
          else if (Tok.isNot(tok::r_paren)) {
1039
0
            PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
1040
0
                << PragmaName;
1041
0
            return false;
1042
0
          }
1043
4
        }
1044
20
      } else 
if (7
Tok.isNot(tok::r_paren)7
) {
1045
0
        PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
1046
0
        return false;
1047
0
      }
1048
27
    }
1049
27
  }
1050
  // Grab the string literal for our section name.
1051
65
  StringLiteral *SegmentName = nullptr;
1052
65
  if (Tok.isNot(tok::r_paren)) {
1053
53
    if (Tok.isNot(tok::string_literal)) {
1054
4
      unsigned DiagID = Action != Sema::PSK_Reset ? 
!SlotLabel.empty()2
?
1055
1
          diag::warn_pragma_expected_section_name :
1056
2
          
diag::warn_pragma_expected_section_label_or_name1
:
1057
4
          
diag::warn_pragma_expected_section_push_pop_or_name2
;
1058
4
      PP.Diag(PragmaLocation, DiagID) << PragmaName;
1059
4
      return false;
1060
4
    }
1061
49
    ExprResult StringResult = ParseStringLiteralExpression();
1062
49
    if (StringResult.isInvalid())
1063
1
      return false; // Already diagnosed.
1064
48
    SegmentName = cast<StringLiteral>(StringResult.get());
1065
48
    if (SegmentName->getCharByteWidth() != 1) {
1066
1
      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1067
1
          << PragmaName;
1068
1
      return false;
1069
1
    }
1070
    // Setting section "" has no effect
1071
47
    if (SegmentName->getLength())
1072
47
      Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1073
47
  }
1074
59
  if (Tok.isNot(tok::r_paren)) {
1075
2
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
1076
2
    return false;
1077
2
  }
1078
57
  PP.Lex(Tok); // )
1079
57
  if (Tok.isNot(tok::eof)) {
1080
0
    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
1081
0
        << PragmaName;
1082
0
    return false;
1083
0
  }
1084
57
  PP.Lex(Tok); // eof
1085
57
  Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
1086
57
                           SegmentName, PragmaName);
1087
57
  return true;
1088
57
}
1089
1090
// #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
1091
bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
1092
48
                                   SourceLocation PragmaLocation) {
1093
48
  if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
1094
3
    PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
1095
3
    return false;
1096
3
  }
1097
1098
45
  if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1099
45
                       PragmaName))
1100
6
    return false;
1101
1102
  // Parse either the known section names or the string section name.
1103
39
  StringLiteral *SegmentName = nullptr;
1104
39
  if (Tok.isAnyIdentifier()) {
1105
17
    auto *II = Tok.getIdentifierInfo();
1106
17
    StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
1107
17
                            .Case("compiler", "\".CRT$XCC\"")
1108
17
                            .Case("lib", "\".CRT$XCL\"")
1109
17
                            .Case("user", "\".CRT$XCU\"")
1110
17
                            .Default("");
1111
1112
17
    if (!Section.empty()) {
1113
      // Pretend the user wrote the appropriate string literal here.
1114
17
      Token Toks[1];
1115
17
      Toks[0].startToken();
1116
17
      Toks[0].setKind(tok::string_literal);
1117
17
      Toks[0].setLocation(Tok.getLocation());
1118
17
      Toks[0].setLiteralData(Section.data());
1119
17
      Toks[0].setLength(Section.size());
1120
17
      SegmentName =
1121
17
          cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
1122
17
      PP.Lex(Tok);
1123
17
    }
1124
22
  } else if (Tok.is(tok::string_literal)) {
1125
16
    ExprResult StringResult = ParseStringLiteralExpression();
1126
16
    if (StringResult.isInvalid())
1127
0
      return false;
1128
16
    SegmentName = cast<StringLiteral>(StringResult.get());
1129
16
    if (SegmentName->getCharByteWidth() != 1) {
1130
3
      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1131
3
          << PragmaName;
1132
3
      return false;
1133
3
    }
1134
    // FIXME: Add support for the '[, func-name]' part of the pragma.
1135
16
  }
1136
1137
36
  if (!SegmentName) {
1138
6
    PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
1139
6
    return false;
1140
6
  }
1141
1142
30
  if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1143
30
                       PragmaName) ||
1144
30
      ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1145
27
                       PragmaName))
1146
6
    return false;
1147
1148
24
  Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
1149
24
  return true;
1150
30
}
1151
1152
namespace {
1153
struct PragmaLoopHintInfo {
1154
  Token PragmaName;
1155
  Token Option;
1156
  ArrayRef<Token> Toks;
1157
};
1158
} // end anonymous namespace
1159
1160
2
static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
1161
2
  StringRef Str = PragmaName.getIdentifierInfo()->getName();
1162
2
  std::string ClangLoopStr = (llvm::Twine("clang loop ") + Str).str();
1163
2
  return std::string(llvm::StringSwitch<StringRef>(Str)
1164
2
                         .Case("loop", ClangLoopStr)
1165
2
                         .Case("unroll_and_jam", Str)
1166
2
                         .Case("unroll", Str)
1167
2
                         .Default(""));
1168
2
}
1169
1170
405
bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
1171
405
  assert(Tok.is(tok::annot_pragma_loop_hint));
1172
0
  PragmaLoopHintInfo *Info =
1173
405
      static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
1174
1175
405
  IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1176
405
  Hint.PragmaNameLoc = IdentifierLoc::create(
1177
405
      Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1178
1179
  // It is possible that the loop hint has no option identifier, such as
1180
  // #pragma unroll(4).
1181
405
  IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
1182
405
                                   ? 
Info->Option.getIdentifierInfo()310
1183
405
                                   : 
nullptr95
;
1184
405
  Hint.OptionLoc = IdentifierLoc::create(
1185
405
      Actions.Context, Info->Option.getLocation(), OptionInfo);
1186
1187
405
  llvm::ArrayRef<Token> Toks = Info->Toks;
1188
1189
  // Return a valid hint if pragma unroll or nounroll were specified
1190
  // without an argument.
1191
405
  auto IsLoopHint = llvm::StringSwitch<bool>(PragmaNameInfo->getName())
1192
405
                        .Cases("unroll", "nounroll", "unroll_and_jam",
1193
405
                               "nounroll_and_jam", true)
1194
405
                        .Default(false);
1195
1196
405
  if (Toks.empty() && 
IsLoopHint38
) {
1197
38
    ConsumeAnnotationToken();
1198
38
    Hint.Range = Info->PragmaName.getLocation();
1199
38
    return true;
1200
38
  }
1201
1202
  // The constant expression is always followed by an eof token, which increases
1203
  // the TokSize by 1.
1204
367
  assert(!Toks.empty() &&
1205
367
         "PragmaLoopHintInfo::Toks must contain at least one token.");
1206
1207
  // If no option is specified the argument is assumed to be a constant expr.
1208
0
  bool OptionUnroll = false;
1209
367
  bool OptionUnrollAndJam = false;
1210
367
  bool OptionDistribute = false;
1211
367
  bool OptionPipelineDisabled = false;
1212
367
  bool StateOption = false;
1213
367
  if (OptionInfo) { // Pragma Unroll does not specify an option.
1214
310
    OptionUnroll = OptionInfo->isStr("unroll");
1215
310
    OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
1216
310
    OptionDistribute = OptionInfo->isStr("distribute");
1217
310
    OptionPipelineDisabled = OptionInfo->isStr("pipeline");
1218
310
    StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1219
310
                      .Case("vectorize", true)
1220
310
                      .Case("interleave", true)
1221
310
                      .Case("vectorize_predicate", true)
1222
310
                      .Default(false) ||
1223
310
                  
OptionUnroll205
||
OptionUnrollAndJam166
||
OptionDistribute166
||
1224
310
                  
OptionPipelineDisabled141
;
1225
310
  }
1226
1227
367
  bool AssumeSafetyArg = !OptionUnroll && 
!OptionUnrollAndJam328
&&
1228
367
                         
!OptionDistribute328
&&
!OptionPipelineDisabled303
;
1229
  // Verify loop hint has an argument.
1230
367
  if (Toks[0].is(tok::eof)) {
1231
7
    ConsumeAnnotationToken();
1232
7
    Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1233
7
        << /*StateArgument=*/StateOption
1234
7
        << /*FullKeyword=*/(OptionUnroll || 
OptionUnrollAndJam6
)
1235
7
        << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1236
7
    return false;
1237
7
  }
1238
1239
  // Validate the argument.
1240
360
  if (StateOption) {
1241
174
    ConsumeAnnotationToken();
1242
174
    SourceLocation StateLoc = Toks[0].getLocation();
1243
174
    IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1244
1245
174
    bool Valid = StateInfo &&
1246
174
                 llvm::StringSwitch<bool>(StateInfo->getName())
1247
171
                     .Case("disable", true)
1248
171
                     .Case("enable", !OptionPipelineDisabled)
1249
171
                     .Case("full", OptionUnroll || 
OptionUnrollAndJam134
)
1250
171
                     .Case("assume_safety", AssumeSafetyArg)
1251
171
                     .Default(false);
1252
174
    if (!Valid) {
1253
14
      if (OptionPipelineDisabled) {
1254
2
        Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1255
12
      } else {
1256
12
        Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1257
12
            << /*FullKeyword=*/(OptionUnroll || 
OptionUnrollAndJam8
)
1258
12
            << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1259
12
      }
1260
14
      return false;
1261
14
    }
1262
160
    if (Toks.size() > 2)
1263
0
      Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1264
0
          << PragmaLoopHintString(Info->PragmaName, Info->Option);
1265
160
    Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1266
186
  } else if (OptionInfo && 
OptionInfo->getName() == "vectorize_width"131
) {
1267
60
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
1268
60
                        /*IsReinject=*/false);
1269
60
    ConsumeAnnotationToken();
1270
1271
60
    SourceLocation StateLoc = Toks[0].getLocation();
1272
60
    IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1273
60
    StringRef IsScalableStr = StateInfo ? 
StateInfo->getName()26
:
""34
;
1274
1275
    // Look for vectorize_width(fixed|scalable)
1276
60
    if (IsScalableStr == "scalable" || 
IsScalableStr == "fixed"57
) {
1277
6
      PP.Lex(Tok); // Identifier
1278
1279
6
      if (Toks.size() > 2) {
1280
0
        Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1281
0
            << PragmaLoopHintString(Info->PragmaName, Info->Option);
1282
0
        while (Tok.isNot(tok::eof))
1283
0
          ConsumeAnyToken();
1284
0
      }
1285
1286
6
      Hint.StateLoc =
1287
6
          IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1288
1289
6
      ConsumeToken(); // Consume the constant expression eof terminator.
1290
54
    } else {
1291
      // Enter constant expression including eof terminator into token stream.
1292
54
      ExprResult R = ParseConstantExpression();
1293
1294
54
      if (R.isInvalid() && 
!Tok.is(tok::comma)5
)
1295
5
        Diag(Toks[0].getLocation(),
1296
5
             diag::note_pragma_loop_invalid_vectorize_option);
1297
1298
54
      bool Arg2Error = false;
1299
54
      if (Tok.is(tok::comma)) {
1300
6
        PP.Lex(Tok); // ,
1301
1302
6
        StateInfo = Tok.getIdentifierInfo();
1303
6
        IsScalableStr = StateInfo->getName();
1304
1305
6
        if (IsScalableStr != "scalable" && 
IsScalableStr != "fixed"2
) {
1306
0
          Diag(Tok.getLocation(),
1307
0
               diag::err_pragma_loop_invalid_vectorize_option);
1308
0
          Arg2Error = true;
1309
0
        } else
1310
6
          Hint.StateLoc =
1311
6
              IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1312
1313
6
        PP.Lex(Tok); // Identifier
1314
6
      }
1315
1316
      // Tokens following an error in an ill-formed constant expression will
1317
      // remain in the token stream and must be removed.
1318
54
      if (Tok.isNot(tok::eof)) {
1319
0
        Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1320
0
            << PragmaLoopHintString(Info->PragmaName, Info->Option);
1321
0
        while (Tok.isNot(tok::eof))
1322
0
          ConsumeAnyToken();
1323
0
      }
1324
1325
54
      ConsumeToken(); // Consume the constant expression eof terminator.
1326
1327
54
      if (Arg2Error || R.isInvalid() ||
1328
54
          
Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())49
)
1329
8
        return false;
1330
1331
      // Argument is a constant expression with an integer type.
1332
46
      Hint.ValueExpr = R.get();
1333
46
    }
1334
126
  } else {
1335
    // Enter constant expression including eof terminator into token stream.
1336
126
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
1337
126
                        /*IsReinject=*/false);
1338
126
    ConsumeAnnotationToken();
1339
126
    ExprResult R = ParseConstantExpression();
1340
1341
    // Tokens following an error in an ill-formed constant expression will
1342
    // remain in the token stream and must be removed.
1343
126
    if (Tok.isNot(tok::eof)) {
1344
2
      Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1345
2
          << PragmaLoopHintString(Info->PragmaName, Info->Option);
1346
4
      while (Tok.isNot(tok::eof))
1347
2
        ConsumeAnyToken();
1348
2
    }
1349
1350
126
    ConsumeToken(); // Consume the constant expression eof terminator.
1351
1352
126
    if (R.isInvalid() ||
1353
126
        
Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())119
)
1354
19
      return false;
1355
1356
    // Argument is a constant expression with an integer type.
1357
107
    Hint.ValueExpr = R.get();
1358
107
  }
1359
1360
319
  Hint.Range = SourceRange(Info->PragmaName.getLocation(),
1361
319
                           Info->Toks.back().getLocation());
1362
319
  return true;
1363
360
}
1364
1365
namespace {
1366
struct PragmaAttributeInfo {
1367
  enum ActionType { Push, Pop, Attribute };
1368
  ParsedAttributes &Attributes;
1369
  ActionType Action;
1370
  const IdentifierInfo *Namespace = nullptr;
1371
  ArrayRef<Token> Tokens;
1372
1373
3.13k
  PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1374
};
1375
1376
#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1377
1378
} // end anonymous namespace
1379
1380
12.2k
static StringRef getIdentifier(const Token &Tok) {
1381
12.2k
  if (Tok.is(tok::identifier))
1382
11.3k
    return Tok.getIdentifierInfo()->getName();
1383
940
  const char *S = tok::getKeywordSpelling(Tok.getKind());
1384
940
  if (!S)
1385
14
    return "";
1386
926
  return S;
1387
940
}
1388
1389
11.0k
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
1390
11.0k
  using namespace attr;
1391
11.0k
  switch (Rule) {
1392
0
#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)                           \
1393
11.0k
  case Value:                                                                  \
1394
11.0k
    return IsAbstract;
1395
11.0k
#include 
"clang/Basic/AttrSubMatchRulesList.inc"0
1396
11.0k
  }
1397
0
  llvm_unreachable("Invalid attribute subject match rule");
1398
0
  return false;
1399
11.0k
}
1400
1401
static void diagnoseExpectedAttributeSubjectSubRule(
1402
    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1403
5
    SourceLocation SubRuleLoc) {
1404
5
  auto Diagnostic =
1405
5
      PRef.Diag(SubRuleLoc,
1406
5
                diag::err_pragma_attribute_expected_subject_sub_identifier)
1407
5
      << PrimaryRuleName;
1408
5
  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1409
3
    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1410
2
  else
1411
2
    Diagnostic << /*SubRulesSupported=*/0;
1412
5
}
1413
1414
static void diagnoseUnknownAttributeSubjectSubRule(
1415
    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1416
7
    StringRef SubRuleName, SourceLocation SubRuleLoc) {
1417
1418
7
  auto Diagnostic =
1419
7
      PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1420
7
      << SubRuleName << PrimaryRuleName;
1421
7
  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1422
4
    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1423
3
  else
1424
3
    Diagnostic << /*SubRulesSupported=*/0;
1425
7
}
1426
1427
bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1428
    attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
1429
1.10k
    SourceLocation &LastMatchRuleEndLoc) {
1430
1.10k
  bool IsAny = false;
1431
1.10k
  BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
1432
1.10k
  if (getIdentifier(Tok) == "any") {
1433
1.02k
    AnyLoc = ConsumeToken();
1434
1.02k
    IsAny = true;
1435
1.02k
    if (AnyParens.expectAndConsume())
1436
4
      return true;
1437
1.02k
  }
1438
1439
11.0k
  
do 1.09k
{
1440
    // Parse the subject matcher rule.
1441
11.0k
    StringRef Name = getIdentifier(Tok);
1442
11.0k
    if (Name.empty()) {
1443
7
      Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1444
7
      return true;
1445
7
    }
1446
11.0k
    std::pair<Optional<attr::SubjectMatchRule>,
1447
11.0k
              Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
1448
11.0k
        Rule = isAttributeSubjectMatchRule(Name);
1449
11.0k
    if (!Rule.first) {
1450
4
      Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1451
4
      return true;
1452
4
    }
1453
11.0k
    attr::SubjectMatchRule PrimaryRule = *Rule.first;
1454
11.0k
    SourceLocation RuleLoc = ConsumeToken();
1455
1456
11.0k
    BalancedDelimiterTracker Parens(*this, tok::l_paren);
1457
11.0k
    if (isAbstractAttrMatcherRule(PrimaryRule)) {
1458
5
      if (Parens.expectAndConsume())
1459
2
        return true;
1460
11.0k
    } else if (Parens.consumeOpen()) {
1461
10.9k
      if (!SubjectMatchRules
1462
10.9k
               .insert(
1463
10.9k
                   std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1464
10.9k
               .second)
1465
7
        Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1466
7
            << Name
1467
7
            << FixItHint::CreateRemoval(SourceRange(
1468
7
                   RuleLoc, Tok.is(tok::comma) ? 
Tok.getLocation()3
:
RuleLoc4
));
1469
10.9k
      LastMatchRuleEndLoc = RuleLoc;
1470
10.9k
      continue;
1471
10.9k
    }
1472
1473
    // Parse the sub-rules.
1474
111
    StringRef SubRuleName = getIdentifier(Tok);
1475
111
    if (SubRuleName.empty()) {
1476
3
      diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1477
3
                                              Tok.getLocation());
1478
3
      return true;
1479
3
    }
1480
108
    attr::SubjectMatchRule SubRule;
1481
108
    if (SubRuleName == "unless") {
1482
50
      SourceLocation SubRuleLoc = ConsumeToken();
1483
50
      BalancedDelimiterTracker Parens(*this, tok::l_paren);
1484
50
      if (Parens.expectAndConsume())
1485
2
        return true;
1486
48
      SubRuleName = getIdentifier(Tok);
1487
48
      if (SubRuleName.empty()) {
1488
2
        diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1489
2
                                                SubRuleLoc);
1490
2
        return true;
1491
2
      }
1492
46
      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
1493
46
      if (!SubRuleOrNone) {
1494
3
        std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1495
3
        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1496
3
                                               SubRuleUnlessName, SubRuleLoc);
1497
3
        return true;
1498
3
      }
1499
43
      SubRule = *SubRuleOrNone;
1500
43
      ConsumeToken();
1501
43
      if (Parens.consumeClose())
1502
1
        return true;
1503
58
    } else {
1504
58
      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
1505
58
      if (!SubRuleOrNone) {
1506
4
        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1507
4
                                               SubRuleName, Tok.getLocation());
1508
4
        return true;
1509
4
      }
1510
54
      SubRule = *SubRuleOrNone;
1511
54
      ConsumeToken();
1512
54
    }
1513
96
    SourceLocation RuleEndLoc = Tok.getLocation();
1514
96
    LastMatchRuleEndLoc = RuleEndLoc;
1515
96
    if (Parens.consumeClose())
1516
1
      return true;
1517
95
    if (!SubjectMatchRules
1518
95
             .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1519
95
             .second) {
1520
8
      Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1521
8
          << attr::getSubjectMatchRuleSpelling(SubRule)
1522
8
          << FixItHint::CreateRemoval(SourceRange(
1523
8
                 RuleLoc, Tok.is(tok::comma) ? 
Tok.getLocation()3
:
RuleEndLoc5
));
1524
8
      continue;
1525
8
    }
1526
10.9k
  } while (IsAny && 
TryConsumeToken(tok::comma)10.9k
);
1527
1528
1.06k
  if (IsAny)
1529
993
    if (AnyParens.consumeClose())
1530
2
      return true;
1531
1532
1.06k
  return false;
1533
1.06k
}
1534
1535
namespace {
1536
1537
/// Describes the stage at which attribute subject rule parsing was interrupted.
1538
enum class MissingAttributeSubjectRulesRecoveryPoint {
1539
  Comma,
1540
  ApplyTo,
1541
  Equals,
1542
  Any,
1543
  None,
1544
};
1545
1546
MissingAttributeSubjectRulesRecoveryPoint
1547
40
getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1548
40
  if (const auto *II = Tok.getIdentifierInfo()) {
1549
17
    if (II->isStr("apply_to"))
1550
2
      return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1551
15
    if (II->isStr("any"))
1552
6
      return MissingAttributeSubjectRulesRecoveryPoint::Any;
1553
15
  }
1554
32
  if (Tok.is(tok::equal))
1555
5
    return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1556
27
  return MissingAttributeSubjectRulesRecoveryPoint::None;
1557
32
}
1558
1559
/// Creates a diagnostic for the attribute subject rule parsing diagnostic that
1560
/// suggests the possible attribute subject rules in a fix-it together with
1561
/// any other missing tokens.
1562
DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1563
    unsigned DiagID, ParsedAttr &Attribute,
1564
40
    MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
1565
40
  SourceLocation Loc = PRef.getEndOfPreviousToken();
1566
40
  if (Loc.isInvalid())
1567
0
    Loc = PRef.getCurToken().getLocation();
1568
40
  auto Diagnostic = PRef.Diag(Loc, DiagID);
1569
40
  std::string FixIt;
1570
40
  MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1571
40
      getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1572
40
  if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1573
18
    FixIt = ", ";
1574
40
  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1575
40
      
EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo33
)
1576
31
    FixIt += "apply_to";
1577
40
  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1578
40
      EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1579
33
    FixIt += " = ";
1580
40
  SourceRange FixItRange(Loc);
1581
40
  if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1582
    // Gather the subject match rules that are supported by the attribute.
1583
27
    SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
1584
27
    Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
1585
27
    if (SubjectMatchRuleSet.empty()) {
1586
      // FIXME: We can emit a "fix-it" with a subject list placeholder when
1587
      // placeholders will be supported by the fix-its.
1588
9
      return Diagnostic;
1589
9
    }
1590
18
    FixIt += "any(";
1591
18
    bool NeedsComma = false;
1592
69
    for (const auto &I : SubjectMatchRuleSet) {
1593
      // Ensure that the missing rule is reported in the fix-it only when it's
1594
      // supported in the current language mode.
1595
69
      if (!I.second)
1596
1
        continue;
1597
68
      if (NeedsComma)
1598
50
        FixIt += ", ";
1599
18
      else
1600
18
        NeedsComma = true;
1601
68
      FixIt += attr::getSubjectMatchRuleSpelling(I.first);
1602
68
    }
1603
18
    FixIt += ")";
1604
    // Check if we need to remove the range
1605
18
    PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
1606
18
    FixItRange.setEnd(PRef.getCurToken().getLocation());
1607
18
  }
1608
31
  if (FixItRange.getBegin() == FixItRange.getEnd())
1609
18
    Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
1610
13
  else
1611
13
    Diagnostic << FixItHint::CreateReplacement(
1612
13
        CharSourceRange::getCharRange(FixItRange), FixIt);
1613
31
  return Diagnostic;
1614
40
}
1615
1616
} // end anonymous namespace
1617
1618
3.11k
void Parser::HandlePragmaAttribute() {
1619
3.11k
  assert(Tok.is(tok::annot_pragma_attribute) &&
1620
3.11k
         "Expected #pragma attribute annotation token");
1621
0
  SourceLocation PragmaLoc = Tok.getLocation();
1622
3.11k
  auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1623
3.11k
  if (Info->Action == PragmaAttributeInfo::Pop) {
1624
1.05k
    ConsumeAnnotationToken();
1625
1.05k
    Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1626
1.05k
    return;
1627
1.05k
  }
1628
  // Parse the actual attribute with its arguments.
1629
2.05k
  assert((Info->Action == PragmaAttributeInfo::Push ||
1630
2.05k
          Info->Action == PragmaAttributeInfo::Attribute) &&
1631
2.05k
         "Unexpected #pragma attribute command");
1632
1633
2.05k
  if (Info->Action == PragmaAttributeInfo::Push && 
Info->Tokens.empty()1.16k
) {
1634
890
    ConsumeAnnotationToken();
1635
890
    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1636
890
    return;
1637
890
  }
1638
1639
1.16k
  PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false,
1640
1.16k
                      /*IsReinject=*/false);
1641
1.16k
  ConsumeAnnotationToken();
1642
1643
1.16k
  ParsedAttributes &Attrs = Info->Attributes;
1644
1.16k
  Attrs.clearListOnly();
1645
1646
1.16k
  auto SkipToEnd = [this]() {
1647
102
    SkipUntil(tok::eof, StopBeforeMatch);
1648
102
    ConsumeToken();
1649
102
  };
1650
1651
1.16k
  if (Tok.is(tok::l_square) && 
NextToken().is(tok::l_square)29
) {
1652
    // Parse the CXX11 style attribute.
1653
29
    ParseCXX11AttributeSpecifier(Attrs);
1654
1.13k
  } else if (Tok.is(tok::kw___attribute)) {
1655
1.12k
    ConsumeToken();
1656
1.12k
    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1657
1.12k
                         "attribute"))
1658
1
      return SkipToEnd();
1659
1.12k
    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1660
1
      return SkipToEnd();
1661
1662
    // FIXME: The practical usefulness of completion here is limited because
1663
    // we only get here if the line has balanced parens.
1664
1.12k
    if (Tok.is(tok::code_completion)) {
1665
1
      cutOffParsing();
1666
      // FIXME: suppress completion of unsupported attributes?
1667
1
      Actions.CodeCompleteAttribute(AttributeCommonInfo::Syntax::AS_GNU);
1668
1
      return SkipToEnd();
1669
1
    }
1670
1671
1.12k
    if (Tok.isNot(tok::identifier)) {
1672
2
      Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1673
2
      SkipToEnd();
1674
2
      return;
1675
2
    }
1676
1.12k
    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1677
1.12k
    SourceLocation AttrNameLoc = ConsumeToken();
1678
1679
1.12k
    if (Tok.isNot(tok::l_paren))
1680
34
      Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1681
34
                   ParsedAttr::AS_GNU);
1682
1.08k
    else
1683
1.08k
      ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
1684
1.08k
                            /*ScopeName=*/nullptr,
1685
1.08k
                            /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
1686
1.08k
                            /*Declarator=*/nullptr);
1687
1688
1.12k
    if (ExpectAndConsume(tok::r_paren))
1689
2
      return SkipToEnd();
1690
1.12k
    if (ExpectAndConsume(tok::r_paren))
1691
1
      return SkipToEnd();
1692
1.12k
  } else 
if (10
Tok.is(tok::kw___declspec)10
) {
1693
4
    ParseMicrosoftDeclSpecs(Attrs);
1694
6
  } else {
1695
6
    Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1696
6
    if (Tok.getIdentifierInfo()) {
1697
      // If we suspect that this is an attribute suggest the use of
1698
      // '__attribute__'.
1699
5
      if (ParsedAttr::getParsedKind(
1700
5
              Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1701
5
              ParsedAttr::AS_GNU) != ParsedAttr::UnknownAttribute) {
1702
4
        SourceLocation InsertStartLoc = Tok.getLocation();
1703
4
        ConsumeToken();
1704
4
        if (Tok.is(tok::l_paren)) {
1705
2
          ConsumeAnyToken();
1706
2
          SkipUntil(tok::r_paren, StopBeforeMatch);
1707
2
          if (Tok.isNot(tok::r_paren))
1708
0
            return SkipToEnd();
1709
2
        }
1710
4
        Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1711
4
            << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1712
4
            << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1713
4
      }
1714
5
    }
1715
6
    SkipToEnd();
1716
6
    return;
1717
6
  }
1718
1719
1.15k
  if (Attrs.empty() || 
Attrs.begin()->isInvalid()1.14k
) {
1720
4
    SkipToEnd();
1721
4
    return;
1722
4
  }
1723
1724
  // Ensure that we don't have more than one attribute.
1725
1.14k
  if (Attrs.size() > 1) {
1726
3
    SourceLocation Loc = Attrs[1].getLoc();
1727
3
    Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1728
3
    SkipToEnd();
1729
3
    return;
1730
3
  }
1731
1732
1.14k
  ParsedAttr &Attribute = *Attrs.begin();
1733
1.14k
  if (!Attribute.isSupportedByPragmaAttribute()) {
1734
5
    Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1735
5
        << Attribute;
1736
5
    SkipToEnd();
1737
5
    return;
1738
5
  }
1739
1740
  // Parse the subject-list.
1741
1.14k
  if (!TryConsumeToken(tok::comma)) {
1742
18
    createExpectedAttributeSubjectRulesTokenDiagnostic(
1743
18
        diag::err_expected, Attribute,
1744
18
        MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
1745
18
        << tok::comma;
1746
18
    SkipToEnd();
1747
18
    return;
1748
18
  }
1749
1750
1.12k
  if (Tok.isNot(tok::identifier)) {
1751
8
    createExpectedAttributeSubjectRulesTokenDiagnostic(
1752
8
        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1753
8
        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1754
8
    SkipToEnd();
1755
8
    return;
1756
8
  }
1757
1.11k
  const IdentifierInfo *II = Tok.getIdentifierInfo();
1758
1.11k
  if (!II->isStr("apply_to")) {
1759
7
    createExpectedAttributeSubjectRulesTokenDiagnostic(
1760
7
        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1761
7
        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1762
7
    SkipToEnd();
1763
7
    return;
1764
7
  }
1765
1.10k
  ConsumeToken();
1766
1767
1.10k
  if (!TryConsumeToken(tok::equal)) {
1768
7
    createExpectedAttributeSubjectRulesTokenDiagnostic(
1769
7
        diag::err_expected, Attribute,
1770
7
        MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1771
7
        << tok::equal;
1772
7
    SkipToEnd();
1773
7
    return;
1774
7
  }
1775
1776
1.10k
  attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1777
1.10k
  SourceLocation AnyLoc, LastMatchRuleEndLoc;
1778
1.10k
  if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1779
1.10k
                                              LastMatchRuleEndLoc)) {
1780
35
    SkipToEnd();
1781
35
    return;
1782
35
  }
1783
1784
  // Tokens following an ill-formed attribute will remain in the token stream
1785
  // and must be removed.
1786
1.06k
  if (Tok.isNot(tok::eof)) {
1787
1
    Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1788
1
    SkipToEnd();
1789
1
    return;
1790
1
  }
1791
1792
  // Consume the eof terminator token.
1793
1.06k
  ConsumeToken();
1794
1795
  // Handle a mixed push/attribute by desurging to a push, then an attribute.
1796
1.06k
  if (Info->Action == PragmaAttributeInfo::Push)
1797
174
    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1798
1799
1.06k
  Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1800
1.06k
                                        std::move(SubjectMatchRules));
1801
1.06k
}
1802
1803
// #pragma GCC visibility comes in two variants:
1804
//   'push' '(' [visibility] ')'
1805
//   'pop'
1806
void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1807
                                              PragmaIntroducer Introducer,
1808
120
                                              Token &VisTok) {
1809
120
  SourceLocation VisLoc = VisTok.getLocation();
1810
1811
120
  Token Tok;
1812
120
  PP.LexUnexpandedToken(Tok);
1813
1814
120
  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1815
1816
120
  const IdentifierInfo *VisType;
1817
120
  if (PushPop && PushPop->isStr("pop")) {
1818
57
    VisType = nullptr;
1819
63
  } else if (PushPop && PushPop->isStr("push")) {
1820
62
    PP.LexUnexpandedToken(Tok);
1821
62
    if (Tok.isNot(tok::l_paren)) {
1822
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1823
1
        << "visibility";
1824
1
      return;
1825
1
    }
1826
61
    PP.LexUnexpandedToken(Tok);
1827
61
    VisType = Tok.getIdentifierInfo();
1828
61
    if (!VisType) {
1829
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1830
1
        << "visibility";
1831
1
      return;
1832
1
    }
1833
60
    PP.LexUnexpandedToken(Tok);
1834
60
    if (Tok.isNot(tok::r_paren)) {
1835
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1836
1
        << "visibility";
1837
1
      return;
1838
1
    }
1839
60
  } else {
1840
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1841
1
      << "visibility";
1842
1
    return;
1843
1
  }
1844
116
  SourceLocation EndLoc = Tok.getLocation();
1845
116
  PP.LexUnexpandedToken(Tok);
1846
116
  if (Tok.isNot(tok::eod)) {
1847
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1848
1
      << "visibility";
1849
1
    return;
1850
1
  }
1851
1852
115
  auto Toks = std::make_unique<Token[]>(1);
1853
115
  Toks[0].startToken();
1854
115
  Toks[0].setKind(tok::annot_pragma_vis);
1855
115
  Toks[0].setLocation(VisLoc);
1856
115
  Toks[0].setAnnotationEndLoc(EndLoc);
1857
115
  Toks[0].setAnnotationValue(
1858
115
      const_cast<void *>(static_cast<const void *>(VisType)));
1859
115
  PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true,
1860
115
                      /*IsReinject=*/false);
1861
115
}
1862
1863
// #pragma pack(...) comes in the following delicious flavors:
1864
//   pack '(' [integer] ')'
1865
//   pack '(' 'show' ')'
1866
//   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1867
void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1868
                                     PragmaIntroducer Introducer,
1869
254k
                                     Token &PackTok) {
1870
254k
  SourceLocation PackLoc = PackTok.getLocation();
1871
1872
254k
  Token Tok;
1873
254k
  PP.Lex(Tok);
1874
254k
  if (Tok.isNot(tok::l_paren)) {
1875
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1876
1
    return;
1877
1
  }
1878
1879
254k
  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1880
254k
  StringRef SlotLabel;
1881
254k
  Token Alignment;
1882
254k
  Alignment.startToken();
1883
254k
  PP.Lex(Tok);
1884
254k
  if (Tok.is(tok::numeric_constant)) {
1885
2.03k
    Alignment = Tok;
1886
1887
2.03k
    PP.Lex(Tok);
1888
1889
    // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1890
    // the push/pop stack.
1891
    // In Apple gcc/XL, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1892
2.03k
    Action = (PP.getLangOpts().ApplePragmaPack || 
PP.getLangOpts().XLPragmaPack2.03k
)
1893
2.03k
                 ? 
Sema::PSK_Push_Set61
1894
2.03k
                 : 
Sema::PSK_Set1.97k
;
1895
252k
  } else if (Tok.is(tok::identifier)) {
1896
250k
    const IdentifierInfo *II = Tok.getIdentifierInfo();
1897
250k
    if (II->isStr("show")) {
1898
80
      Action = Sema::PSK_Show;
1899
80
      PP.Lex(Tok);
1900
250k
    } else {
1901
250k
      if (II->isStr("push")) {
1902
125k
        Action = Sema::PSK_Push;
1903
125k
      } else if (II->isStr("pop")) {
1904
125k
        Action = Sema::PSK_Pop;
1905
125k
      } else {
1906
1
        PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1907
1
        return;
1908
1
      }
1909
250k
      PP.Lex(Tok);
1910
1911
250k
      if (Tok.is(tok::comma)) {
1912
125k
        PP.Lex(Tok);
1913
1914
125k
        if (Tok.is(tok::numeric_constant)) {
1915
125k
          Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1916
125k
          Alignment = Tok;
1917
1918
125k
          PP.Lex(Tok);
1919
125k
        } else 
if (28
Tok.is(tok::identifier)28
) {
1920
24
          SlotLabel = Tok.getIdentifierInfo()->getName();
1921
24
          PP.Lex(Tok);
1922
1923
24
          if (Tok.is(tok::comma)) {
1924
14
            PP.Lex(Tok);
1925
1926
14
            if (Tok.isNot(tok::numeric_constant)) {
1927
3
              PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1928
3
              return;
1929
3
            }
1930
1931
11
            Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1932
11
            Alignment = Tok;
1933
1934
11
            PP.Lex(Tok);
1935
11
          }
1936
24
        } else {
1937
4
          PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1938
4
          return;
1939
4
        }
1940
125k
      }
1941
250k
    }
1942
250k
  } else 
if (1.83k
PP.getLangOpts().ApplePragmaPack1.83k
||
1943
1.83k
             
PP.getLangOpts().XLPragmaPack1.83k
) {
1944
    // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1945
    // the push/pop stack.
1946
    // In Apple gcc and IBM XL, #pragma pack() is equivalent to #pragma
1947
    // pack(pop).
1948
11
    Action = Sema::PSK_Pop;
1949
11
  }
1950
1951
254k
  if (Tok.isNot(tok::r_paren)) {
1952
4
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1953
4
    return;
1954
4
  }
1955
1956
254k
  SourceLocation RParenLoc = Tok.getLocation();
1957
254k
  PP.Lex(Tok);
1958
254k
  if (Tok.isNot(tok::eod)) {
1959
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1960
0
    return;
1961
0
  }
1962
1963
254k
  PragmaPackInfo *Info =
1964
254k
      PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1965
254k
  Info->Action = Action;
1966
254k
  Info->SlotLabel = SlotLabel;
1967
254k
  Info->Alignment = Alignment;
1968
1969
254k
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1970
254k
                              1);
1971
254k
  Toks[0].startToken();
1972
254k
  Toks[0].setKind(tok::annot_pragma_pack);
1973
254k
  Toks[0].setLocation(PackLoc);
1974
254k
  Toks[0].setAnnotationEndLoc(RParenLoc);
1975
254k
  Toks[0].setAnnotationValue(static_cast<void*>(Info));
1976
254k
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1977
254k
                      /*IsReinject=*/false);
1978
254k
}
1979
1980
// #pragma ms_struct on
1981
// #pragma ms_struct off
1982
void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1983
                                         PragmaIntroducer Introducer,
1984
16
                                         Token &MSStructTok) {
1985
16
  PragmaMSStructKind Kind = PMSST_OFF;
1986
1987
16
  Token Tok;
1988
16
  PP.Lex(Tok);
1989
16
  if (Tok.isNot(tok::identifier)) {
1990
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1991
1
    return;
1992
1
  }
1993
15
  SourceLocation EndLoc = Tok.getLocation();
1994
15
  const IdentifierInfo *II = Tok.getIdentifierInfo();
1995
15
  if (II->isStr("on")) {
1996
11
    Kind = PMSST_ON;
1997
11
    PP.Lex(Tok);
1998
11
  }
1999
4
  else if (II->isStr("off") || 
II->isStr("reset")1
)
2000
4
    PP.Lex(Tok);
2001
0
  else {
2002
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
2003
0
    return;
2004
0
  }
2005
2006
15
  if (Tok.isNot(tok::eod)) {
2007
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2008
1
      << "ms_struct";
2009
1
    return;
2010
1
  }
2011
2012
14
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2013
14
                              1);
2014
14
  Toks[0].startToken();
2015
14
  Toks[0].setKind(tok::annot_pragma_msstruct);
2016
14
  Toks[0].setLocation(MSStructTok.getLocation());
2017
14
  Toks[0].setAnnotationEndLoc(EndLoc);
2018
14
  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2019
14
                             static_cast<uintptr_t>(Kind)));
2020
14
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2021
14
                      /*IsReinject=*/false);
2022
14
}
2023
2024
// #pragma clang section bss="abc" data="" rodata="def" text="" relro=""
2025
void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
2026
                                             PragmaIntroducer Introducer,
2027
63
                                             Token &FirstToken) {
2028
2029
63
  Token Tok;
2030
63
  auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
2031
2032
63
  PP.Lex(Tok); // eat 'section'
2033
154
  while (Tok.isNot(tok::eod)) {
2034
102
    if (Tok.isNot(tok::identifier)) {
2035
0
      PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
2036
0
      return;
2037
0
    }
2038
2039
102
    const IdentifierInfo *SecType = Tok.getIdentifierInfo();
2040
102
    if (SecType->isStr("bss"))
2041
25
      SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
2042
77
    else if (SecType->isStr("data"))
2043
22
      SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
2044
55
    else if (SecType->isStr("rodata"))
2045
23
      SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
2046
32
    else if (SecType->isStr("relro"))
2047
3
      SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
2048
29
    else if (SecType->isStr("text"))
2049
23
      SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
2050
6
    else {
2051
6
      PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
2052
6
      return;
2053
6
    }
2054
2055
96
    SourceLocation PragmaLocation = Tok.getLocation();
2056
96
    PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
2057
96
    if (Tok.isNot(tok::equal)) {
2058
5
      PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
2059
5
      return;
2060
5
    }
2061
2062
91
    std::string SecName;
2063
91
    if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
2064
0
      return;
2065
2066
91
    Actions.ActOnPragmaClangSection(
2067
91
        PragmaLocation,
2068
91
        (SecName.size() ? 
Sema::PragmaClangSectionAction::PCSA_Set46
2069
91
                        : 
Sema::PragmaClangSectionAction::PCSA_Clear45
),
2070
91
        SecKind, SecName);
2071
91
  }
2072
63
}
2073
2074
// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
2075
// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
2076
// #pragma 'align' '(' {'native','natural','mac68k','power','reset'} ')'
2077
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
2078
2.78k
                             bool IsOptions) {
2079
2.78k
  Token Tok;
2080
2081
2.78k
  if (IsOptions) {
2082
2.68k
    PP.Lex(Tok);
2083
2.68k
    if (Tok.isNot(tok::identifier) ||
2084
2.68k
        
!Tok.getIdentifierInfo()->isStr("align")2.68k
) {
2085
1
      PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
2086
1
      return;
2087
1
    }
2088
2.68k
  }
2089
2090
2.78k
  PP.Lex(Tok);
2091
2.78k
  if (PP.getLangOpts().XLPragmaPack) {
2092
86
    if (Tok.isNot(tok::l_paren)) {
2093
2
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "align";
2094
2
      return;
2095
2
    }
2096
2.69k
  } else if (Tok.isNot(tok::equal)) {
2097
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
2098
2
      << IsOptions;
2099
2
    return;
2100
2
  }
2101
2102
2.77k
  PP.Lex(Tok);
2103
2.77k
  if (Tok.isNot(tok::identifier)) {
2104
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2105
2
      << (IsOptions ? 
"options"1
:
"align"1
);
2106
2
    return;
2107
2
  }
2108
2109
2.77k
  Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
2110
2.77k
  const IdentifierInfo *II = Tok.getIdentifierInfo();
2111
2.77k
  if (II->isStr("native"))
2112
1
    Kind = Sema::POAK_Native;
2113
2.77k
  else if (II->isStr("natural"))
2114
29
    Kind = Sema::POAK_Natural;
2115
2.74k
  else if (II->isStr("packed"))
2116
25
    Kind = Sema::POAK_Packed;
2117
2.72k
  else if (II->isStr("power"))
2118
1.32k
    Kind = Sema::POAK_Power;
2119
1.39k
  else if (II->isStr("mac68k"))
2120
9
    Kind = Sema::POAK_Mac68k;
2121
1.38k
  else if (II->isStr("reset"))
2122
1.38k
    Kind = Sema::POAK_Reset;
2123
2
  else {
2124
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
2125
2
      << IsOptions;
2126
2
    return;
2127
2
  }
2128
2129
2.77k
  if (PP.getLangOpts().XLPragmaPack) {
2130
84
    PP.Lex(Tok);
2131
84
    if (Tok.isNot(tok::r_paren)) {
2132
0
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "align";
2133
0
      return;
2134
0
    }
2135
84
  }
2136
2137
2.77k
  SourceLocation EndLoc = Tok.getLocation();
2138
2.77k
  PP.Lex(Tok);
2139
2.77k
  if (Tok.isNot(tok::eod)) {
2140
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2141
2
      << (IsOptions ? 
"options"1
:
"align"1
);
2142
2
    return;
2143
2
  }
2144
2145
2.77k
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2146
2.77k
                              1);
2147
2.77k
  Toks[0].startToken();
2148
2.77k
  Toks[0].setKind(tok::annot_pragma_align);
2149
2.77k
  Toks[0].setLocation(FirstTok.getLocation());
2150
2.77k
  Toks[0].setAnnotationEndLoc(EndLoc);
2151
2.77k
  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2152
2.77k
                             static_cast<uintptr_t>(Kind)));
2153
2.77k
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2154
2.77k
                      /*IsReinject=*/false);
2155
2.77k
}
2156
2157
void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
2158
                                      PragmaIntroducer Introducer,
2159
100
                                      Token &AlignTok) {
2160
100
  ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
2161
100
}
2162
2163
void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
2164
                                        PragmaIntroducer Introducer,
2165
2.68k
                                        Token &OptionsTok) {
2166
2.68k
  ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
2167
2.68k
}
2168
2169
// #pragma unused(identifier)
2170
void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
2171
                                       PragmaIntroducer Introducer,
2172
23
                                       Token &UnusedTok) {
2173
  // FIXME: Should we be expanding macros here? My guess is no.
2174
23
  SourceLocation UnusedLoc = UnusedTok.getLocation();
2175
2176
  // Lex the left '('.
2177
23
  Token Tok;
2178
23
  PP.Lex(Tok);
2179
23
  if (Tok.isNot(tok::l_paren)) {
2180
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
2181
1
    return;
2182
1
  }
2183
2184
  // Lex the declaration reference(s).
2185
22
  SmallVector<Token, 5> Identifiers;
2186
22
  SourceLocation RParenLoc;
2187
22
  bool LexID = true;
2188
2189
55
  while (true) {
2190
55
    PP.Lex(Tok);
2191
2192
55
    if (LexID) {
2193
29
      if (Tok.is(tok::identifier)) {
2194
26
        Identifiers.push_back(Tok);
2195
26
        LexID = false;
2196
26
        continue;
2197
26
      }
2198
2199
      // Illegal token!
2200
3
      PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
2201
3
      return;
2202
29
    }
2203
2204
    // We are execting a ')' or a ','.
2205
26
    if (Tok.is(tok::comma)) {
2206
7
      LexID = true;
2207
7
      continue;
2208
7
    }
2209
2210
19
    if (Tok.is(tok::r_paren)) {
2211
19
      RParenLoc = Tok.getLocation();
2212
19
      break;
2213
19
    }
2214
2215
    // Illegal token!
2216
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
2217
0
    return;
2218
19
  }
2219
2220
19
  PP.Lex(Tok);
2221
19
  if (Tok.isNot(tok::eod)) {
2222
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2223
0
        "unused";
2224
0
    return;
2225
0
  }
2226
2227
  // Verify that we have a location for the right parenthesis.
2228
19
  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
2229
0
  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
2230
2231
  // For each identifier token, insert into the token stream a
2232
  // annot_pragma_unused token followed by the identifier token.
2233
  // This allows us to cache a "#pragma unused" that occurs inside an inline
2234
  // C++ member function.
2235
2236
0
  MutableArrayRef<Token> Toks(
2237
19
      PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
2238
19
      2 * Identifiers.size());
2239
44
  for (unsigned i=0; i != Identifiers.size(); 
i++25
) {
2240
25
    Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
2241
25
    pragmaUnusedTok.startToken();
2242
25
    pragmaUnusedTok.setKind(tok::annot_pragma_unused);
2243
25
    pragmaUnusedTok.setLocation(UnusedLoc);
2244
25
    idTok = Identifiers[i];
2245
25
  }
2246
19
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2247
19
                      /*IsReinject=*/false);
2248
19
}
2249
2250
// #pragma weak identifier
2251
// #pragma weak identifier '=' identifier
2252
void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
2253
                                     PragmaIntroducer Introducer,
2254
119
                                     Token &WeakTok) {
2255
119
  SourceLocation WeakLoc = WeakTok.getLocation();
2256
2257
119
  Token Tok;
2258
119
  PP.Lex(Tok);
2259
119
  if (Tok.isNot(tok::identifier)) {
2260
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
2261
1
    return;
2262
1
  }
2263
2264
118
  Token WeakName = Tok;
2265
118
  bool HasAlias = false;
2266
118
  Token AliasName;
2267
2268
118
  PP.Lex(Tok);
2269
118
  if (Tok.is(tok::equal)) {
2270
25
    HasAlias = true;
2271
25
    PP.Lex(Tok);
2272
25
    if (Tok.isNot(tok::identifier)) {
2273
2
      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2274
2
          << "weak";
2275
2
      return;
2276
2
    }
2277
23
    AliasName = Tok;
2278
23
    PP.Lex(Tok);
2279
23
  }
2280
2281
116
  if (Tok.isNot(tok::eod)) {
2282
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
2283
2
    return;
2284
2
  }
2285
2286
114
  if (HasAlias) {
2287
22
    MutableArrayRef<Token> Toks(
2288
22
        PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
2289
22
    Token &pragmaUnusedTok = Toks[0];
2290
22
    pragmaUnusedTok.startToken();
2291
22
    pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
2292
22
    pragmaUnusedTok.setLocation(WeakLoc);
2293
22
    pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
2294
22
    Toks[1] = WeakName;
2295
22
    Toks[2] = AliasName;
2296
22
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2297
22
                        /*IsReinject=*/false);
2298
92
  } else {
2299
92
    MutableArrayRef<Token> Toks(
2300
92
        PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
2301
92
    Token &pragmaUnusedTok = Toks[0];
2302
92
    pragmaUnusedTok.startToken();
2303
92
    pragmaUnusedTok.setKind(tok::annot_pragma_weak);
2304
92
    pragmaUnusedTok.setLocation(WeakLoc);
2305
92
    pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
2306
92
    Toks[1] = WeakName;
2307
92
    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2308
92
                        /*IsReinject=*/false);
2309
92
  }
2310
114
}
2311
2312
// #pragma redefine_extname identifier identifier
2313
void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
2314
                                                PragmaIntroducer Introducer,
2315
11
                                                Token &RedefToken) {
2316
11
  SourceLocation RedefLoc = RedefToken.getLocation();
2317
2318
11
  Token Tok;
2319
11
  PP.Lex(Tok);
2320
11
  if (Tok.isNot(tok::identifier)) {
2321
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2322
0
      "redefine_extname";
2323
0
    return;
2324
0
  }
2325
2326
11
  Token RedefName = Tok;
2327
11
  PP.Lex(Tok);
2328
2329
11
  if (Tok.isNot(tok::identifier)) {
2330
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2331
0
        << "redefine_extname";
2332
0
    return;
2333
0
  }
2334
2335
11
  Token AliasName = Tok;
2336
11
  PP.Lex(Tok);
2337
2338
11
  if (Tok.isNot(tok::eod)) {
2339
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2340
0
      "redefine_extname";
2341
0
    return;
2342
0
  }
2343
2344
11
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
2345
11
                              3);
2346
11
  Token &pragmaRedefTok = Toks[0];
2347
11
  pragmaRedefTok.startToken();
2348
11
  pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2349
11
  pragmaRedefTok.setLocation(RedefLoc);
2350
11
  pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
2351
11
  Toks[1] = RedefName;
2352
11
  Toks[2] = AliasName;
2353
11
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2354
11
                      /*IsReinject=*/false);
2355
11
}
2356
2357
void PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2358
                                           PragmaIntroducer Introducer,
2359
43
                                           Token &Tok) {
2360
43
  tok::OnOffSwitch OOS;
2361
43
  if (PP.LexOnOffSwitch(OOS))
2362
2
    return;
2363
2364
41
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2365
41
                              1);
2366
41
  Toks[0].startToken();
2367
41
  Toks[0].setKind(tok::annot_pragma_fp_contract);
2368
41
  Toks[0].setLocation(Tok.getLocation());
2369
41
  Toks[0].setAnnotationEndLoc(Tok.getLocation());
2370
41
  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2371
41
                             static_cast<uintptr_t>(OOS)));
2372
41
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2373
41
                      /*IsReinject=*/false);
2374
41
}
2375
2376
void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2377
                                                PragmaIntroducer Introducer,
2378
1.26k
                                                Token &Tok) {
2379
1.26k
  PP.LexUnexpandedToken(Tok);
2380
1.26k
  if (Tok.isNot(tok::identifier)) {
2381
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2382
0
      "OPENCL";
2383
0
    return;
2384
0
  }
2385
1.26k
  IdentifierInfo *Ext = Tok.getIdentifierInfo();
2386
1.26k
  SourceLocation NameLoc = Tok.getLocation();
2387
2388
1.26k
  PP.Lex(Tok);
2389
1.26k
  if (Tok.isNot(tok::colon)) {
2390
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2391
0
    return;
2392
0
  }
2393
2394
1.26k
  PP.Lex(Tok);
2395
1.26k
  if (Tok.isNot(tok::identifier)) {
2396
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2397
0
    return;
2398
0
  }
2399
1.26k
  IdentifierInfo *Pred = Tok.getIdentifierInfo();
2400
2401
1.26k
  OpenCLExtState State;
2402
1.26k
  if (Pred->isStr("enable")) {
2403
889
    State = Enable;
2404
889
  } else 
if (375
Pred->isStr("disable")375
) {
2405
306
    State = Disable;
2406
306
  } else 
if (69
Pred->isStr("begin")69
)
2407
32
    State = Begin;
2408
37
  else if (Pred->isStr("end"))
2409
36
    State = End;
2410
1
  else {
2411
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2412
1
      << Ext->isStr("all");
2413
1
    return;
2414
1
  }
2415
1.26k
  SourceLocation StateLoc = Tok.getLocation();
2416
2417
1.26k
  PP.Lex(Tok);
2418
1.26k
  if (Tok.isNot(tok::eod)) {
2419
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2420
0
      "OPENCL EXTENSION";
2421
0
    return;
2422
0
  }
2423
2424
1.26k
  auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
2425
1.26k
  Info->first = Ext;
2426
1.26k
  Info->second = State;
2427
1.26k
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2428
1.26k
                              1);
2429
1.26k
  Toks[0].startToken();
2430
1.26k
  Toks[0].setKind(tok::annot_pragma_opencl_extension);
2431
1.26k
  Toks[0].setLocation(NameLoc);
2432
1.26k
  Toks[0].setAnnotationValue(static_cast<void*>(Info));
2433
1.26k
  Toks[0].setAnnotationEndLoc(StateLoc);
2434
1.26k
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2435
1.26k
                      /*IsReinject=*/false);
2436
2437
1.26k
  if (PP.getPPCallbacks())
2438
1.26k
    PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
2439
1.26k
                                               StateLoc, State);
2440
1.26k
}
2441
2442
/// Handle '#pragma omp ...' when OpenMP is disabled.
2443
///
2444
void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
2445
                                         PragmaIntroducer Introducer,
2446
95
                                         Token &FirstTok) {
2447
95
  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
2448
95
                                     FirstTok.getLocation())) {
2449
2
    PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
2450
2
    PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
2451
2
                                    diag::Severity::Ignored, SourceLocation());
2452
2
  }
2453
95
  PP.DiscardUntilEndOfDirective();
2454
95
}
2455
2456
/// Handle '#pragma omp ...' when OpenMP is enabled.
2457
///
2458
void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
2459
                                       PragmaIntroducer Introducer,
2460
239k
                                       Token &FirstTok) {
2461
239k
  SmallVector<Token, 16> Pragma;
2462
239k
  Token Tok;
2463
239k
  Tok.startToken();
2464
239k
  Tok.setKind(tok::annot_pragma_openmp);
2465
239k
  Tok.setLocation(Introducer.Loc);
2466
2467
1.99M
  while (Tok.isNot(tok::eod) && 
Tok.isNot(tok::eof)1.75M
) {
2468
1.75M
    Pragma.push_back(Tok);
2469
1.75M
    PP.Lex(Tok);
2470
1.75M
    if (Tok.is(tok::annot_pragma_openmp)) {
2471
6
      PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2472
6
      unsigned InnerPragmaCnt = 1;
2473
18
      while (InnerPragmaCnt != 0) {
2474
12
        PP.Lex(Tok);
2475
12
        if (Tok.is(tok::annot_pragma_openmp))
2476
0
          ++InnerPragmaCnt;
2477
12
        else if (Tok.is(tok::annot_pragma_openmp_end))
2478
6
          --InnerPragmaCnt;
2479
12
      }
2480
6
      PP.Lex(Tok);
2481
6
    }
2482
1.75M
  }
2483
239k
  SourceLocation EodLoc = Tok.getLocation();
2484
239k
  Tok.startToken();
2485
239k
  Tok.setKind(tok::annot_pragma_openmp_end);
2486
239k
  Tok.setLocation(EodLoc);
2487
239k
  Pragma.push_back(Tok);
2488
2489
239k
  auto Toks = std::make_unique<Token[]>(Pragma.size());
2490
239k
  std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2491
239k
  PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2492
239k
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2493
239k
}
2494
2495
/// Handle '#pragma pointers_to_members'
2496
// The grammar for this pragma is as follows:
2497
//
2498
// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2499
//
2500
// #pragma pointers_to_members '(' 'best_case' ')'
2501
// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2502
// #pragma pointers_to_members '(' inheritance-model ')'
2503
void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2504
                                             PragmaIntroducer Introducer,
2505
27
                                             Token &Tok) {
2506
27
  SourceLocation PointersToMembersLoc = Tok.getLocation();
2507
27
  PP.Lex(Tok);
2508
27
  if (Tok.isNot(tok::l_paren)) {
2509
0
    PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2510
0
      << "pointers_to_members";
2511
0
    return;
2512
0
  }
2513
27
  PP.Lex(Tok);
2514
27
  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2515
27
  if (!Arg) {
2516
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2517
0
      << "pointers_to_members";
2518
0
    return;
2519
0
  }
2520
27
  PP.Lex(Tok);
2521
2522
27
  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2523
27
  if (Arg->isStr("best_case")) {
2524
10
    RepresentationMethod = LangOptions::PPTMK_BestCase;
2525
17
  } else {
2526
17
    if (Arg->isStr("full_generality")) {
2527
13
      if (Tok.is(tok::comma)) {
2528
13
        PP.Lex(Tok);
2529
2530
13
        Arg = Tok.getIdentifierInfo();
2531
13
        if (!Arg) {
2532
0
          PP.Diag(Tok.getLocation(),
2533
0
                  diag::err_pragma_pointers_to_members_unknown_kind)
2534
0
              << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2535
0
          return;
2536
0
        }
2537
13
        PP.Lex(Tok);
2538
13
      } else 
if (0
Tok.is(tok::r_paren)0
) {
2539
        // #pragma pointers_to_members(full_generality) implicitly specifies
2540
        // virtual_inheritance.
2541
0
        Arg = nullptr;
2542
0
        RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2543
0
      } else {
2544
0
        PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2545
0
            << "full_generality";
2546
0
        return;
2547
0
      }
2548
13
    }
2549
2550
17
    if (Arg) {
2551
17
      if (Arg->isStr("single_inheritance")) {
2552
2
        RepresentationMethod =
2553
2
            LangOptions::PPTMK_FullGeneralitySingleInheritance;
2554
15
      } else if (Arg->isStr("multiple_inheritance")) {
2555
2
        RepresentationMethod =
2556
2
            LangOptions::PPTMK_FullGeneralityMultipleInheritance;
2557
13
      } else if (Arg->isStr("virtual_inheritance")) {
2558
11
        RepresentationMethod =
2559
11
            LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2560
11
      } else {
2561
2
        PP.Diag(Tok.getLocation(),
2562
2
                diag::err_pragma_pointers_to_members_unknown_kind)
2563
2
            << Arg << /*HasPointerDeclaration*/ 1;
2564
2
        return;
2565
2
      }
2566
17
    }
2567
17
  }
2568
2569
25
  if (Tok.isNot(tok::r_paren)) {
2570
0
    PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2571
0
        << (Arg ? Arg->getName() : "full_generality");
2572
0
    return;
2573
0
  }
2574
2575
25
  SourceLocation EndLoc = Tok.getLocation();
2576
25
  PP.Lex(Tok);
2577
25
  if (Tok.isNot(tok::eod)) {
2578
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2579
0
      << "pointers_to_members";
2580
0
    return;
2581
0
  }
2582
2583
25
  Token AnnotTok;
2584
25
  AnnotTok.startToken();
2585
25
  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2586
25
  AnnotTok.setLocation(PointersToMembersLoc);
2587
25
  AnnotTok.setAnnotationEndLoc(EndLoc);
2588
25
  AnnotTok.setAnnotationValue(
2589
25
      reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2590
25
  PP.EnterToken(AnnotTok, /*IsReinject=*/true);
2591
25
}
2592
2593
/// Handle '#pragma vtordisp'
2594
// The grammar for this pragma is as follows:
2595
//
2596
// <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2597
//
2598
// #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2599
// #pragma vtordisp '(' 'pop' ')'
2600
// #pragma vtordisp '(' ')'
2601
void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2602
52
                                    PragmaIntroducer Introducer, Token &Tok) {
2603
52
  SourceLocation VtorDispLoc = Tok.getLocation();
2604
52
  PP.Lex(Tok);
2605
52
  if (Tok.isNot(tok::l_paren)) {
2606
1
    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2607
1
    return;
2608
1
  }
2609
51
  PP.Lex(Tok);
2610
2611
51
  Sema::PragmaMsStackAction Action = Sema::PSK_Set;
2612
51
  const IdentifierInfo *II = Tok.getIdentifierInfo();
2613
51
  if (II) {
2614
41
    if (II->isStr("push")) {
2615
      // #pragma vtordisp(push, mode)
2616
20
      PP.Lex(Tok);
2617
20
      if (Tok.isNot(tok::comma)) {
2618
0
        PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2619
0
        return;
2620
0
      }
2621
20
      PP.Lex(Tok);
2622
20
      Action = Sema::PSK_Push_Set;
2623
      // not push, could be on/off
2624
21
    } else if (II->isStr("pop")) {
2625
      // #pragma vtordisp(pop)
2626
20
      PP.Lex(Tok);
2627
20
      Action = Sema::PSK_Pop;
2628
20
    }
2629
    // not push or pop, could be on/off
2630
41
  } else {
2631
10
    if (Tok.is(tok::r_paren)) {
2632
      // #pragma vtordisp()
2633
4
      Action = Sema::PSK_Reset;
2634
4
    }
2635
10
  }
2636
2637
2638
51
  uint64_t Value = 0;
2639
51
  if (Action & Sema::PSK_Push || 
Action & Sema::PSK_Set31
) {
2640
27
    const IdentifierInfo *II = Tok.getIdentifierInfo();
2641
27
    if (II && 
II->isStr("off")1
) {
2642
0
      PP.Lex(Tok);
2643
0
      Value = 0;
2644
27
    } else if (II && 
II->isStr("on")1
) {
2645
0
      PP.Lex(Tok);
2646
0
      Value = 1;
2647
27
    } else if (Tok.is(tok::numeric_constant) &&
2648
27
               
PP.parseSimpleIntegerLiteral(Tok, Value)24
) {
2649
24
      if (Value > 2) {
2650
2
        PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2651
2
            << 0 << 2 << "vtordisp";
2652
2
        return;
2653
2
      }
2654
24
    } else {
2655
3
      PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2656
3
          << "vtordisp";
2657
3
      return;
2658
3
    }
2659
27
  }
2660
2661
  // Finish the pragma: ')' $
2662
46
  if (Tok.isNot(tok::r_paren)) {
2663
0
    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2664
0
    return;
2665
0
  }
2666
46
  SourceLocation EndLoc = Tok.getLocation();
2667
46
  PP.Lex(Tok);
2668
46
  if (Tok.isNot(tok::eod)) {
2669
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2670
1
        << "vtordisp";
2671
1
    return;
2672
1
  }
2673
2674
  // Enter the annotation.
2675
45
  Token AnnotTok;
2676
45
  AnnotTok.startToken();
2677
45
  AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2678
45
  AnnotTok.setLocation(VtorDispLoc);
2679
45
  AnnotTok.setAnnotationEndLoc(EndLoc);
2680
45
  AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2681
45
      static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2682
45
  PP.EnterToken(AnnotTok, /*IsReinject=*/false);
2683
45
}
2684
2685
/// Handle all MS pragmas.  Simply forwards the tokens after inserting
2686
/// an annotation token.
2687
void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2688
146
                                  PragmaIntroducer Introducer, Token &Tok) {
2689
146
  Token EoF, AnnotTok;
2690
146
  EoF.startToken();
2691
146
  EoF.setKind(tok::eof);
2692
146
  AnnotTok.startToken();
2693
146
  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2694
146
  AnnotTok.setLocation(Tok.getLocation());
2695
146
  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2696
146
  SmallVector<Token, 8> TokenVector;
2697
  // Suck up all of the tokens before the eod.
2698
874
  for (; Tok.isNot(tok::eod); 
PP.Lex(Tok)728
) {
2699
728
    TokenVector.push_back(Tok);
2700
728
    AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2701
728
  }
2702
  // Add a sentinel EoF token to the end of the list.
2703
146
  TokenVector.push_back(EoF);
2704
  // We must allocate this array with new because EnterTokenStream is going to
2705
  // delete it later.
2706
146
  markAsReinjectedForRelexing(TokenVector);
2707
146
  auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2708
146
  std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2709
146
  auto Value = new (PP.getPreprocessorAllocator())
2710
146
      std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2711
146
                                                  TokenVector.size());
2712
146
  AnnotTok.setAnnotationValue(Value);
2713
146
  PP.EnterToken(AnnotTok, /*IsReinject*/ false);
2714
146
}
2715
2716
/// Handle the \#pragma float_control extension.
2717
///
2718
/// The syntax is:
2719
/// \code
2720
///   #pragma float_control(keyword[, setting] [,push])
2721
/// \endcode
2722
/// Where 'keyword' and 'setting' are identifiers.
2723
// 'keyword' can be: precise, except, push, pop
2724
// 'setting' can be: on, off
2725
/// The optional arguments 'setting' and 'push' are supported only
2726
/// when the keyword is 'precise' or 'except'.
2727
void PragmaFloatControlHandler::HandlePragma(Preprocessor &PP,
2728
                                             PragmaIntroducer Introducer,
2729
305
                                             Token &Tok) {
2730
305
  Sema::PragmaMsStackAction Action = Sema::PSK_Set;
2731
305
  SourceLocation FloatControlLoc = Tok.getLocation();
2732
305
  Token PragmaName = Tok;
2733
305
  if (!PP.getTargetInfo().hasStrictFP() && 
!PP.getLangOpts().ExpStrictFP12
) {
2734
3
    PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
2735
3
        << PragmaName.getIdentifierInfo()->getName();
2736
3
    return;
2737
3
  }
2738
302
  PP.Lex(Tok);
2739
302
  if (Tok.isNot(tok::l_paren)) {
2740
0
    PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren;
2741
0
    return;
2742
0
  }
2743
2744
  // Read the identifier.
2745
302
  PP.Lex(Tok);
2746
302
  if (Tok.isNot(tok::identifier)) {
2747
0
    PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2748
0
    return;
2749
0
  }
2750
2751
  // Verify that this is one of the float control options.
2752
302
  IdentifierInfo *II = Tok.getIdentifierInfo();
2753
302
  PragmaFloatControlKind Kind =
2754
302
      llvm::StringSwitch<PragmaFloatControlKind>(II->getName())
2755
302
          .Case("precise", PFC_Precise)
2756
302
          .Case("except", PFC_Except)
2757
302
          .Case("push", PFC_Push)
2758
302
          .Case("pop", PFC_Pop)
2759
302
          .Default(PFC_Unknown);
2760
302
  PP.Lex(Tok); // the identifier
2761
302
  if (Kind == PFC_Unknown) {
2762
0
    PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2763
0
    return;
2764
302
  } else if (Kind == PFC_Push || 
Kind == PFC_Pop261
) {
2765
110
    if (Tok.isNot(tok::r_paren)) {
2766
0
      PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2767
0
      return;
2768
0
    }
2769
110
    PP.Lex(Tok); // Eat the r_paren
2770
110
    Action = (Kind == PFC_Pop) ? 
Sema::PSK_Pop69
:
Sema::PSK_Push41
;
2771
192
  } else {
2772
192
    if (Tok.is(tok::r_paren))
2773
      // Selecting Precise or Except
2774
0
      PP.Lex(Tok); // the r_paren
2775
192
    else if (Tok.isNot(tok::comma)) {
2776
0
      PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2777
0
      return;
2778
192
    } else {
2779
192
      PP.Lex(Tok); // ,
2780
192
      if (!Tok.isAnyIdentifier()) {
2781
0
        PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2782
0
        return;
2783
0
      }
2784
192
      StringRef PushOnOff = Tok.getIdentifierInfo()->getName();
2785
192
      if (PushOnOff == "on")
2786
        // Kind is set correctly
2787
120
        ;
2788
72
      else if (PushOnOff == "off") {
2789
72
        if (Kind == PFC_Precise)
2790
53
          Kind = PFC_NoPrecise;
2791
72
        if (Kind == PFC_Except)
2792
19
          Kind = PFC_NoExcept;
2793
72
      } else 
if (0
PushOnOff == "push"0
) {
2794
0
        Action = Sema::PSK_Push_Set;
2795
0
      } else {
2796
0
        PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2797
0
        return;
2798
0
      }
2799
192
      PP.Lex(Tok); // the identifier
2800
192
      if (Tok.is(tok::comma)) {
2801
12
        PP.Lex(Tok); // ,
2802
12
        if (!Tok.isAnyIdentifier()) {
2803
0
          PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2804
0
          return;
2805
0
        }
2806
12
        StringRef ExpectedPush = Tok.getIdentifierInfo()->getName();
2807
12
        if (ExpectedPush == "push") {
2808
12
          Action = Sema::PSK_Push_Set;
2809
12
        } else {
2810
0
          PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2811
0
          return;
2812
0
        }
2813
12
        PP.Lex(Tok); // the push identifier
2814
12
      }
2815
192
      if (Tok.isNot(tok::r_paren)) {
2816
1
        PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
2817
1
        return;
2818
1
      }
2819
191
      PP.Lex(Tok); // the r_paren
2820
191
    }
2821
192
  }
2822
301
  SourceLocation EndLoc = Tok.getLocation();
2823
301
  if (Tok.isNot(tok::eod)) {
2824
5
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2825
5
        << "float_control";
2826
5
    return;
2827
5
  }
2828
2829
  // Note: there is no accomodation for PP callback for this pragma.
2830
2831
  // Enter the annotation.
2832
296
  auto TokenArray = std::make_unique<Token[]>(1);
2833
296
  TokenArray[0].startToken();
2834
296
  TokenArray[0].setKind(tok::annot_pragma_float_control);
2835
296
  TokenArray[0].setLocation(FloatControlLoc);
2836
296
  TokenArray[0].setAnnotationEndLoc(EndLoc);
2837
  // Create an encoding of Action and Value by shifting the Action into
2838
  // the high 16 bits then union with the Kind.
2839
296
  TokenArray[0].setAnnotationValue(reinterpret_cast<void *>(
2840
296
      static_cast<uintptr_t>((Action << 16) | (Kind & 0xFFFF))));
2841
296
  PP.EnterTokenStream(std::move(TokenArray), 1,
2842
296
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2843
296
}
2844
2845
/// Handle the Microsoft \#pragma detect_mismatch extension.
2846
///
2847
/// The syntax is:
2848
/// \code
2849
///   #pragma detect_mismatch("name", "value")
2850
/// \endcode
2851
/// Where 'name' and 'value' are quoted strings.  The values are embedded in
2852
/// the object file and passed along to the linker.  If the linker detects a
2853
/// mismatch in the object file's values for the given name, a LNK2038 error
2854
/// is emitted.  See MSDN for more details.
2855
void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2856
                                               PragmaIntroducer Introducer,
2857
19
                                               Token &Tok) {
2858
19
  SourceLocation DetectMismatchLoc = Tok.getLocation();
2859
19
  PP.Lex(Tok);
2860
19
  if (Tok.isNot(tok::l_paren)) {
2861
0
    PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2862
0
    return;
2863
0
  }
2864
2865
  // Read the name to embed, which must be a string literal.
2866
19
  std::string NameString;
2867
19
  if (!PP.LexStringLiteral(Tok, NameString,
2868
19
                           "pragma detect_mismatch",
2869
19
                           /*AllowMacroExpansion=*/true))
2870
1
    return;
2871
2872
  // Read the comma followed by a second string literal.
2873
18
  std::string ValueString;
2874
18
  if (Tok.isNot(tok::comma)) {
2875
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2876
1
    return;
2877
1
  }
2878
2879
17
  if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2880
17
                           /*AllowMacroExpansion=*/true))
2881
1
    return;
2882
2883
16
  if (Tok.isNot(tok::r_paren)) {
2884
0
    PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2885
0
    return;
2886
0
  }
2887
16
  PP.Lex(Tok);  // Eat the r_paren.
2888
2889
16
  if (Tok.isNot(tok::eod)) {
2890
0
    PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2891
0
    return;
2892
0
  }
2893
2894
  // If the pragma is lexically sound, notify any interested PPCallbacks.
2895
16
  if (PP.getPPCallbacks())
2896
16
    PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2897
16
                                              ValueString);
2898
2899
16
  Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2900
16
}
2901
2902
/// Handle the microsoft \#pragma comment extension.
2903
///
2904
/// The syntax is:
2905
/// \code
2906
///   #pragma comment(linker, "foo")
2907
/// \endcode
2908
/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2909
/// "foo" is a string, which is fully macro expanded, and permits string
2910
/// concatenation, embedded escape characters etc.  See MSDN for more details.
2911
void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2912
                                        PragmaIntroducer Introducer,
2913
79
                                        Token &Tok) {
2914
79
  SourceLocation CommentLoc = Tok.getLocation();
2915
79
  PP.Lex(Tok);
2916
79
  if (Tok.isNot(tok::l_paren)) {
2917
0
    PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2918
0
    return;
2919
0
  }
2920
2921
  // Read the identifier.
2922
79
  PP.Lex(Tok);
2923
79
  if (Tok.isNot(tok::identifier)) {
2924
0
    PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2925
0
    return;
2926
0
  }
2927
2928
  // Verify that this is one of the 5 explicitly listed options.
2929
79
  IdentifierInfo *II = Tok.getIdentifierInfo();
2930
79
  PragmaMSCommentKind Kind =
2931
79
    llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2932
79
    .Case("linker",   PCK_Linker)
2933
79
    .Case("lib",      PCK_Lib)
2934
79
    .Case("compiler", PCK_Compiler)
2935
79
    .Case("exestr",   PCK_ExeStr)
2936
79
    .Case("user",     PCK_User)
2937
79
    .Default(PCK_Unknown);
2938
79
  if (Kind == PCK_Unknown) {
2939
3
    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2940
3
    return;
2941
3
  }
2942
2943
76
  if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && 
Kind != PCK_Lib36
) {
2944
19
    PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2945
19
        << II->getName();
2946
19
    return;
2947
19
  }
2948
2949
  // On PS4, issue a warning about any pragma comments other than
2950
  // #pragma comment lib.
2951
57
  if (PP.getTargetInfo().getTriple().isPS4() && 
Kind != PCK_Lib7
) {
2952
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2953
0
      << II->getName();
2954
0
    return;
2955
0
  }
2956
2957
  // Read the optional string if present.
2958
57
  PP.Lex(Tok);
2959
57
  std::string ArgumentString;
2960
57
  if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2961
54
                                                 "pragma comment",
2962
54
                                                 /*AllowMacroExpansion=*/true))
2963
1
    return;
2964
2965
  // FIXME: warn that 'exestr' is deprecated.
2966
  // FIXME: If the kind is "compiler" warn if the string is present (it is
2967
  // ignored).
2968
  // The MSDN docs say that "lib" and "linker" require a string and have a short
2969
  // list of linker options they support, but in practice MSVC doesn't
2970
  // issue a diagnostic.  Therefore neither does clang.
2971
2972
56
  if (Tok.isNot(tok::r_paren)) {
2973
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2974
1
    return;
2975
1
  }
2976
55
  PP.Lex(Tok);  // eat the r_paren.
2977
2978
55
  if (Tok.isNot(tok::eod)) {
2979
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2980
1
    return;
2981
1
  }
2982
2983
  // If the pragma is lexically sound, notify any interested PPCallbacks.
2984
54
  if (PP.getPPCallbacks())
2985
54
    PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2986
2987
54
  Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2988
54
}
2989
2990
// #pragma clang optimize off
2991
// #pragma clang optimize on
2992
void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2993
                                         PragmaIntroducer Introducer,
2994
33
                                         Token &FirstToken) {
2995
33
  Token Tok;
2996
33
  PP.Lex(Tok);
2997
33
  if (Tok.is(tok::eod)) {
2998
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2999
1
        << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
3000
1
    return;
3001
1
  }
3002
32
  if (Tok.isNot(tok::identifier)) {
3003
0
    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
3004
0
      << PP.getSpelling(Tok);
3005
0
    return;
3006
0
  }
3007
32
  const IdentifierInfo *II = Tok.getIdentifierInfo();
3008
  // The only accepted values are 'on' or 'off'.
3009
32
  bool IsOn = false;
3010
32
  if (II->isStr("on")) {
3011
15
    IsOn = true;
3012
17
  } else if (!II->isStr("off")) {
3013
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
3014
1
      << PP.getSpelling(Tok);
3015
1
    return;
3016
1
  }
3017
31
  PP.Lex(Tok);
3018
3019
31
  if (Tok.isNot(tok::eod)) {
3020
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
3021
1
      << PP.getSpelling(Tok);
3022
1
    return;
3023
1
  }
3024
3025
30
  Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
3026
30
}
3027
3028
namespace {
3029
/// Used as the annotation value for tok::annot_pragma_fp.
3030
struct TokFPAnnotValue {
3031
  enum FlagKinds { Contract, Reassociate, Exceptions };
3032
  enum FlagValues { On, Off, Fast };
3033
3034
  llvm::Optional<LangOptions::FPModeKind> ContractValue;
3035
  llvm::Optional<LangOptions::FPModeKind> ReassociateValue;
3036
  llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
3037
};
3038
} // end anonymous namespace
3039
3040
void PragmaFPHandler::HandlePragma(Preprocessor &PP,
3041
46
                                   PragmaIntroducer Introducer, Token &Tok) {
3042
  // fp
3043
46
  Token PragmaName = Tok;
3044
46
  SmallVector<Token, 1> TokenList;
3045
3046
46
  PP.Lex(Tok);
3047
46
  if (Tok.isNot(tok::identifier)) {
3048
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
3049
1
        << /*MissingOption=*/true << "";
3050
1
    return;
3051
1
  }
3052
3053
45
  auto *AnnotValue = new (PP.getPreprocessorAllocator()) TokFPAnnotValue;
3054
90
  while (Tok.is(tok::identifier)) {
3055
52
    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
3056
3057
52
    auto FlagKind =
3058
52
        llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
3059
52
            OptionInfo->getName())
3060
52
            .Case("contract", TokFPAnnotValue::Contract)
3061
52
            .Case("reassociate", TokFPAnnotValue::Reassociate)
3062
52
            .Case("exceptions", TokFPAnnotValue::Exceptions)
3063
52
            .Default(None);
3064
52
    if (!FlagKind) {
3065
1
      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
3066
1
          << /*MissingOption=*/false << OptionInfo;
3067
1
      return;
3068
1
    }
3069
51
    PP.Lex(Tok);
3070
3071
    // Read '('
3072
51
    if (Tok.isNot(tok::l_paren)) {
3073
1
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3074
1
      return;
3075
1
    }
3076
50
    PP.Lex(Tok);
3077
3078
50
    if (Tok.isNot(tok::identifier)) {
3079
1
      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3080
1
          << PP.getSpelling(Tok) << OptionInfo->getName()
3081
1
          << static_cast<int>(*FlagKind);
3082
1
      return;
3083
1
    }
3084
49
    const IdentifierInfo *II = Tok.getIdentifierInfo();
3085
3086
49
    if (FlagKind == TokFPAnnotValue::Contract) {
3087
24
      AnnotValue->ContractValue =
3088
24
          llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>(
3089
24
              II->getName())
3090
24
              .Case("on", LangOptions::FPModeKind::FPM_On)
3091
24
              .Case("off", LangOptions::FPModeKind::FPM_Off)
3092
24
              .Case("fast", LangOptions::FPModeKind::FPM_Fast)
3093
24
              .Default(llvm::None);
3094
24
      if (!AnnotValue->ContractValue) {
3095
1
        PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3096
1
            << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
3097
1
        return;
3098
1
      }
3099
25
    } else if (FlagKind == TokFPAnnotValue::Reassociate) {
3100
21
      AnnotValue->ReassociateValue =
3101
21
          llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>(
3102
21
              II->getName())
3103
21
              .Case("on", LangOptions::FPModeKind::FPM_On)
3104
21
              .Case("off", LangOptions::FPModeKind::FPM_Off)
3105
21
              .Default(llvm::None);
3106
21
      if (!AnnotValue->ReassociateValue) {
3107
1
        PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3108
1
            << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
3109
1
        return;
3110
1
      }
3111
21
    } else 
if (4
FlagKind == TokFPAnnotValue::Exceptions4
) {
3112
4
      AnnotValue->ExceptionsValue =
3113
4
          llvm::StringSwitch<llvm::Optional<LangOptions::FPExceptionModeKind>>(
3114
4
              II->getName())
3115
4
              .Case("ignore", LangOptions::FPE_Ignore)
3116
4
              .Case("maytrap", LangOptions::FPE_MayTrap)
3117
4
              .Case("strict", LangOptions::FPE_Strict)
3118
4
              .Default(llvm::None);
3119
4
      if (!AnnotValue->ExceptionsValue) {
3120
1
        PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3121
1
            << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
3122
1
        return;
3123
1
      }
3124
4
    }
3125
46
    PP.Lex(Tok);
3126
3127
    // Read ')'
3128
46
    if (Tok.isNot(tok::r_paren)) {
3129
1
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3130
1
      return;
3131
1
    }
3132
45
    PP.Lex(Tok);
3133
45
  }
3134
3135
38
  if (Tok.isNot(tok::eod)) {
3136
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3137
1
        << "clang fp";
3138
1
    return;
3139
1
  }
3140
3141
37
  Token FPTok;
3142
37
  FPTok.startToken();
3143
37
  FPTok.setKind(tok::annot_pragma_fp);
3144
37
  FPTok.setLocation(PragmaName.getLocation());
3145
37
  FPTok.setAnnotationEndLoc(PragmaName.getLocation());
3146
37
  FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
3147
37
  TokenList.push_back(FPTok);
3148
3149
37
  auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3150
37
  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3151
3152
37
  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3153
37
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3154
37
}
3155
3156
void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(Preprocessor &PP,
3157
                                                PragmaIntroducer Introducer,
3158
39
                                                Token &Tok) {
3159
39
  Token PragmaName = Tok;
3160
39
  SmallVector<Token, 1> TokenList;
3161
39
  if (!PP.getTargetInfo().hasStrictFP() && 
!PP.getLangOpts().ExpStrictFP3
) {
3162
3
    PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
3163
3
        << PragmaName.getIdentifierInfo()->getName();
3164
3
    return;
3165
3
  }
3166
3167
36
  PP.Lex(Tok);
3168
36
  if (Tok.isNot(tok::identifier)) {
3169
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
3170
0
        << PragmaName.getIdentifierInfo()->getName();
3171
0
    return;
3172
0
  }
3173
36
  IdentifierInfo *II = Tok.getIdentifierInfo();
3174
3175
36
  auto RM =
3176
36
      llvm::StringSwitch<llvm::RoundingMode>(II->getName())
3177
36
          .Case("FE_TOWARDZERO", llvm::RoundingMode::TowardZero)
3178
36
          .Case("FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven)
3179
36
          .Case("FE_UPWARD", llvm::RoundingMode::TowardPositive)
3180
36
          .Case("FE_DOWNWARD", llvm::RoundingMode::TowardNegative)
3181
36
          .Case("FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway)
3182
36
          .Case("FE_DYNAMIC", llvm::RoundingMode::Dynamic)
3183
36
          .Default(llvm::RoundingMode::Invalid);
3184
36
  if (RM == llvm::RoundingMode::Invalid) {
3185
1
    PP.Diag(Tok.getLocation(), diag::warn_stdc_unknown_rounding_mode);
3186
1
    return;
3187
1
  }
3188
35
  PP.Lex(Tok);
3189
3190
35
  if (Tok.isNot(tok::eod)) {
3191
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3192
0
        << "STDC FENV_ROUND";
3193
0
    return;
3194
0
  }
3195
3196
  // Until the pragma is fully implemented, issue a warning.
3197
35
  PP.Diag(Tok.getLocation(), diag::warn_stdc_fenv_round_not_supported);
3198
3199
35
  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
3200
35
                              1);
3201
35
  Toks[0].startToken();
3202
35
  Toks[0].setKind(tok::annot_pragma_fenv_round);
3203
35
  Toks[0].setLocation(Tok.getLocation());
3204
35
  Toks[0].setAnnotationEndLoc(Tok.getLocation());
3205
35
  Toks[0].setAnnotationValue(
3206
35
      reinterpret_cast<void *>(static_cast<uintptr_t>(RM)));
3207
35
  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
3208
35
                      /*IsReinject=*/false);
3209
35
}
3210
3211
34
void Parser::HandlePragmaFP() {
3212
34
  assert(Tok.is(tok::annot_pragma_fp));
3213
0
  auto *AnnotValue =
3214
34
      reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
3215
3216
34
  if (AnnotValue->ReassociateValue)
3217
18
    Actions.ActOnPragmaFPReassociate(Tok.getLocation(),
3218
18
                                     *AnnotValue->ReassociateValue ==
3219
18
                                         LangOptions::FPModeKind::FPM_On);
3220
34
  if (AnnotValue->ContractValue)
3221
18
    Actions.ActOnPragmaFPContract(Tok.getLocation(),
3222
18
                                  *AnnotValue->ContractValue);
3223
34
  if (AnnotValue->ExceptionsValue)
3224
3
    Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
3225
3
                                    *AnnotValue->ExceptionsValue);
3226
34
  ConsumeAnnotationToken();
3227
34
}
3228
3229
/// Parses loop or unroll pragma hint value and fills in Info.
3230
static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
3231
                               Token Option, bool ValueInParens,
3232
390
                               PragmaLoopHintInfo &Info) {
3233
390
  SmallVector<Token, 1> ValueList;
3234
390
  int OpenParens = ValueInParens ? 
1367
:
023
;
3235
  // Read constant expression.
3236
871
  while (Tok.isNot(tok::eod)) {
3237
831
    if (Tok.is(tok::l_paren))
3238
8
      OpenParens++;
3239
823
    else if (Tok.is(tok::r_paren)) {
3240
357
      OpenParens--;
3241
357
      if (OpenParens == 0 && 
ValueInParens350
)
3242
350
        break;
3243
357
    }
3244
3245
481
    ValueList.push_back(Tok);
3246
481
    PP.Lex(Tok);
3247
481
  }
3248
3249
390
  if (ValueInParens) {
3250
    // Read ')'
3251
367
    if (Tok.isNot(tok::r_paren)) {
3252
17
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3253
17
      return true;
3254
17
    }
3255
350
    PP.Lex(Tok);
3256
350
  }
3257
3258
373
  Token EOFTok;
3259
373
  EOFTok.startToken();
3260
373
  EOFTok.setKind(tok::eof);
3261
373
  EOFTok.setLocation(Tok.getLocation());
3262
373
  ValueList.push_back(EOFTok); // Terminates expression for parsing.
3263
3264
373
  markAsReinjectedForRelexing(ValueList);
3265
373
  Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
3266
3267
373
  Info.PragmaName = PragmaName;
3268
373
  Info.Option = Option;
3269
373
  return false;
3270
390
}
3271
3272
/// Handle the \#pragma clang loop directive.
3273
///  #pragma clang 'loop' loop-hints
3274
///
3275
///  loop-hints:
3276
///    loop-hint loop-hints[opt]
3277
///
3278
///  loop-hint:
3279
///    'vectorize' '(' loop-hint-keyword ')'
3280
///    'interleave' '(' loop-hint-keyword ')'
3281
///    'unroll' '(' unroll-hint-keyword ')'
3282
///    'vectorize_predicate' '(' loop-hint-keyword ')'
3283
///    'vectorize_width' '(' loop-hint-value ')'
3284
///    'interleave_count' '(' loop-hint-value ')'
3285
///    'unroll_count' '(' loop-hint-value ')'
3286
///    'pipeline' '(' disable ')'
3287
///    'pipeline_initiation_interval' '(' loop-hint-value ')'
3288
///
3289
///  loop-hint-keyword:
3290
///    'enable'
3291
///    'disable'
3292
///    'assume_safety'
3293
///
3294
///  unroll-hint-keyword:
3295
///    'enable'
3296
///    'disable'
3297
///    'full'
3298
///
3299
///  loop-hint-value:
3300
///    constant-expression
3301
///
3302
/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
3303
/// try vectorizing the instructions of the loop it precedes. Specifying
3304
/// interleave(enable) or interleave_count(_value_) instructs llvm to try
3305
/// interleaving multiple iterations of the loop it precedes. The width of the
3306
/// vector instructions is specified by vectorize_width() and the number of
3307
/// interleaved loop iterations is specified by interleave_count(). Specifying a
3308
/// value of 1 effectively disables vectorization/interleaving, even if it is
3309
/// possible and profitable, and 0 is invalid. The loop vectorizer currently
3310
/// only works on inner loops.
3311
///
3312
/// The unroll and unroll_count directives control the concatenation
3313
/// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
3314
/// completely if the trip count is known at compile time and unroll partially
3315
/// if the trip count is not known.  Specifying unroll(full) is similar to
3316
/// unroll(enable) but will unroll the loop only if the trip count is known at
3317
/// compile time.  Specifying unroll(disable) disables unrolling for the
3318
/// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
3319
/// loop the number of times indicated by the value.
3320
void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
3321
                                         PragmaIntroducer Introducer,
3322
274
                                         Token &Tok) {
3323
  // Incoming token is "loop" from "#pragma clang loop".
3324
274
  Token PragmaName = Tok;
3325
274
  SmallVector<Token, 1> TokenList;
3326
3327
  // Lex the optimization option and verify it is an identifier.
3328
274
  PP.Lex(Tok);
3329
274
  if (Tok.isNot(tok::identifier)) {
3330
1
    PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
3331
1
        << /*MissingOption=*/true << "";
3332
1
    return;
3333
1
  }
3334
3335
589
  
while (273
Tok.is(tok::identifier)) {
3336
341
    Token Option = Tok;
3337
341
    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
3338
3339
341
    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
3340
341
                           .Case("vectorize", true)
3341
341
                           .Case("interleave", true)
3342
341
                           .Case("unroll", true)
3343
341
                           .Case("distribute", true)
3344
341
                           .Case("vectorize_predicate", true)
3345
341
                           .Case("vectorize_width", true)
3346
341
                           .Case("interleave_count", true)
3347
341
                           .Case("unroll_count", true)
3348
341
                           .Case("pipeline", true)
3349
341
                           .Case("pipeline_initiation_interval", true)
3350
341
                           .Default(false);
3351
341
    if (!OptionValid) {
3352
4
      PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
3353
4
          << /*MissingOption=*/false << OptionInfo;
3354
4
      return;
3355
4
    }
3356
337
    PP.Lex(Tok);
3357
3358
    // Read '('
3359
337
    if (Tok.isNot(tok::l_paren)) {
3360
7
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3361
7
      return;
3362
7
    }
3363
330
    PP.Lex(Tok);
3364
3365
330
    auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
3366
330
    if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
3367
330
                           *Info))
3368
14
      return;
3369
3370
    // Generate the loop hint token.
3371
316
    Token LoopHintTok;
3372
316
    LoopHintTok.startToken();
3373
316
    LoopHintTok.setKind(tok::annot_pragma_loop_hint);
3374
316
    LoopHintTok.setLocation(Introducer.Loc);
3375
316
    LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
3376
316
    LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
3377
316
    TokenList.push_back(LoopHintTok);
3378
316
  }
3379
3380
248
  if (Tok.isNot(tok::eod)) {
3381
4
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3382
4
        << "clang loop";
3383
4
    return;
3384
4
  }
3385
3386
244
  auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3387
244
  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3388
3389
244
  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3390
244
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3391
244
}
3392
3393
/// Handle the loop unroll optimization pragmas.
3394
///  #pragma unroll
3395
///  #pragma unroll unroll-hint-value
3396
///  #pragma unroll '(' unroll-hint-value ')'
3397
///  #pragma nounroll
3398
///  #pragma unroll_and_jam
3399
///  #pragma unroll_and_jam unroll-hint-value
3400
///  #pragma unroll_and_jam '(' unroll-hint-value ')'
3401
///  #pragma nounroll_and_jam
3402
///
3403
///  unroll-hint-value:
3404
///    constant-expression
3405
///
3406
/// Loop unrolling hints can be specified with '#pragma unroll' or
3407
/// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
3408
/// contained in parentheses. With no argument the directive instructs llvm to
3409
/// try to unroll the loop completely. A positive integer argument can be
3410
/// specified to indicate the number of times the loop should be unrolled.  To
3411
/// maximize compatibility with other compilers the unroll count argument can be
3412
/// specified with or without parentheses.  Specifying, '#pragma nounroll'
3413
/// disables unrolling of the loop.
3414
void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
3415
                                           PragmaIntroducer Introducer,
3416
100
                                           Token &Tok) {
3417
  // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
3418
  // "#pragma nounroll".
3419
100
  Token PragmaName = Tok;
3420
100
  PP.Lex(Tok);
3421
100
  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
3422
100
  if (Tok.is(tok::eod)) {
3423
    // nounroll or unroll pragma without an argument.
3424
38
    Info->PragmaName = PragmaName;
3425
38
    Info->Option.startToken();
3426
62
  } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" ||
3427
62
             
PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam"61
) {
3428
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3429
2
        << PragmaName.getIdentifierInfo()->getName();
3430
2
    return;
3431
60
  } else {
3432
    // Unroll pragma with an argument: "#pragma unroll N" or
3433
    // "#pragma unroll(N)".
3434
    // Read '(' if it exists.
3435
60
    bool ValueInParens = Tok.is(tok::l_paren);
3436
60
    if (ValueInParens)
3437
37
      PP.Lex(Tok);
3438
3439
60
    Token Option;
3440
60
    Option.startToken();
3441
60
    if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
3442
3
      return;
3443
3444
    // In CUDA, the argument to '#pragma unroll' should not be contained in
3445
    // parentheses.
3446
57
    if (PP.getLangOpts().CUDA && 
ValueInParens2
)
3447
2
      PP.Diag(Info->Toks[0].getLocation(),
3448
2
              diag::warn_pragma_unroll_cuda_value_in_parens);
3449
3450
57
    if (Tok.isNot(tok::eod)) {
3451
0
      PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3452
0
          << "unroll";
3453
0
      return;
3454
0
    }
3455
57
  }
3456
3457
  // Generate the hint token.
3458
95
  auto TokenArray = std::make_unique<Token[]>(1);
3459
95
  TokenArray[0].startToken();
3460
95
  TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3461
95
  TokenArray[0].setLocation(Introducer.Loc);
3462
95
  TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
3463
95
  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3464
95
  PP.EnterTokenStream(std::move(TokenArray), 1,
3465
95
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3466
95
}
3467
3468
/// Handle the Microsoft \#pragma intrinsic extension.
3469
///
3470
/// The syntax is:
3471
/// \code
3472
///  #pragma intrinsic(memset)
3473
///  #pragma intrinsic(strlen, memcpy)
3474
/// \endcode
3475
///
3476
/// Pragma intrisic tells the compiler to use a builtin version of the
3477
/// function. Clang does it anyway, so the pragma doesn't really do anything.
3478
/// Anyway, we emit a warning if the function specified in \#pragma intrinsic
3479
/// isn't an intrinsic in clang and suggest to include intrin.h.
3480
void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
3481
                                            PragmaIntroducer Introducer,
3482
15
                                            Token &Tok) {
3483
15
  PP.Lex(Tok);
3484
3485
15
  if (Tok.isNot(tok::l_paren)) {
3486
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
3487
0
        << "intrinsic";
3488
0
    return;
3489
0
  }
3490
15
  PP.Lex(Tok);
3491
3492
15
  bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3493
3494
17
  while (Tok.is(tok::identifier)) {
3495
14
    IdentifierInfo *II = Tok.getIdentifierInfo();
3496
14
    if (!II->getBuiltinID())
3497
8
      PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3498
8
          << II << SuggestIntrinH;
3499
3500
14
    PP.Lex(Tok);
3501
14
    if (Tok.isNot(tok::comma))
3502
12
      break;
3503
2
    PP.Lex(Tok);
3504
2
  }
3505
3506
15
  if (Tok.isNot(tok::r_paren)) {
3507
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
3508
2
        << "intrinsic";
3509
2
    return;
3510
2
  }
3511
13
  PP.Lex(Tok);
3512
3513
13
  if (Tok.isNot(tok::eod))
3514
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3515
1
        << "intrinsic";
3516
13
}
3517
3518
// #pragma optimize("gsty", on|off)
3519
void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
3520
                                           PragmaIntroducer Introducer,
3521
7
                                           Token &Tok) {
3522
7
  SourceLocation StartLoc = Tok.getLocation();
3523
7
  PP.Lex(Tok);
3524
3525
7
  if (Tok.isNot(tok::l_paren)) {
3526
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
3527
1
    return;
3528
1
  }
3529
6
  PP.Lex(Tok);
3530
3531
6
  if (Tok.isNot(tok::string_literal)) {
3532
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
3533
2
    return;
3534
2
  }
3535
  // We could syntax check the string but it's probably not worth the effort.
3536
4
  PP.Lex(Tok);
3537
3538
4
  if (Tok.isNot(tok::comma)) {
3539
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
3540
1
    return;
3541
1
  }
3542
3
  PP.Lex(Tok);
3543
3544
3
  if (Tok.is(tok::eod) || 
Tok.is(tok::r_paren)2
) {
3545
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
3546
1
        << "optimize" << /*Expected=*/true << "'on' or 'off'";
3547
1
    return;
3548
1
  }
3549
2
  IdentifierInfo *II = Tok.getIdentifierInfo();
3550
2
  if (!II || (!II->isStr("on") && 
!II->isStr("off")1
)) {
3551
1
    PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
3552
1
        << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
3553
1
        << "'on' or 'off'";
3554
1
    return;
3555
1
  }
3556
1
  PP.Lex(Tok);
3557
3558
1
  if (Tok.isNot(tok::r_paren)) {
3559
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
3560
0
    return;
3561
0
  }
3562
1
  PP.Lex(Tok);
3563
3564
1
  if (Tok.isNot(tok::eod)) {
3565
0
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3566
0
        << "optimize";
3567
0
    return;
3568
0
  }
3569
1
  PP.Diag(StartLoc, diag::warn_pragma_optimize);
3570
1
}
3571
3572
void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3573
14
    Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) {
3574
14
  Token FirstTok = Tok;
3575
3576
14
  PP.Lex(Tok);
3577
14
  IdentifierInfo *Info = Tok.getIdentifierInfo();
3578
14
  if (!Info || 
(13
!Info->isStr("begin")13
&&
!Info->isStr("end")6
)) {
3579
2
    PP.Diag(FirstTok.getLocation(),
3580
2
            diag::warn_pragma_force_cuda_host_device_bad_arg);
3581
2
    return;
3582
2
  }
3583
3584
12
  if (Info->isStr("begin"))
3585
7
    Actions.PushForceCUDAHostDevice();
3586
5
  else if (!Actions.PopForceCUDAHostDevice())
3587
0
    PP.Diag(FirstTok.getLocation(),
3588
0
            diag::err_pragma_cannot_end_force_cuda_host_device);
3589
3590
12
  PP.Lex(Tok);
3591
12
  if (!Tok.is(tok::eod))
3592
1
    PP.Diag(FirstTok.getLocation(),
3593
1
            diag::warn_pragma_force_cuda_host_device_bad_arg);
3594
12
}
3595
3596
/// Handle the #pragma clang attribute directive.
3597
///
3598
/// The syntax is:
3599
/// \code
3600
///  #pragma clang attribute push (attribute, subject-set)
3601
///  #pragma clang attribute push
3602
///  #pragma clang attribute (attribute, subject-set)
3603
///  #pragma clang attribute pop
3604
/// \endcode
3605
///
3606
/// There are also 'namespace' variants of push and pop directives. The bare
3607
/// '#pragma clang attribute (attribute, subject-set)' version doesn't require a
3608
/// namespace, since it always applies attributes to the most recently pushed
3609
/// group, regardless of namespace.
3610
/// \code
3611
///  #pragma clang attribute namespace.push (attribute, subject-set)
3612
///  #pragma clang attribute namespace.push
3613
///  #pragma clang attribute namespace.pop
3614
/// \endcode
3615
///
3616
/// The subject-set clause defines the set of declarations which receive the
3617
/// attribute. Its exact syntax is described in the LanguageExtensions document
3618
/// in Clang's documentation.
3619
///
3620
/// This directive instructs the compiler to begin/finish applying the specified
3621
/// attribute to the set of attribute-specific declarations in the active range
3622
/// of the pragma.
3623
void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3624
                                          PragmaIntroducer Introducer,
3625
3.13k
                                          Token &FirstToken) {
3626
3.13k
  Token Tok;
3627
3.13k
  PP.Lex(Tok);
3628
3.13k
  auto *Info = new (PP.getPreprocessorAllocator())
3629
3.13k
      PragmaAttributeInfo(AttributesForPragmaAttribute);
3630
3631
  // Parse the optional namespace followed by a period.
3632
3.13k
  if (Tok.is(tok::identifier)) {
3633
2.24k
    IdentifierInfo *II = Tok.getIdentifierInfo();
3634
2.24k
    if (!II->isStr("push") && 
!II->isStr("pop")1.06k
) {
3635
16
      Info->Namespace = II;
3636
16
      PP.Lex(Tok);
3637
3638
16
      if (!Tok.is(tok::period)) {
3639
2
        PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
3640
2
            << II;
3641
2
        return;
3642
2
      }
3643
14
      PP.Lex(Tok);
3644
14
    }
3645
2.24k
  }
3646
3647
3.13k
  if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
3648
2
    PP.Diag(Tok.getLocation(),
3649
2
            diag::err_pragma_attribute_expected_push_pop_paren);
3650
2
    return;
3651
2
  }
3652
3653
  // Determine what action this pragma clang attribute represents.
3654
3.12k
  if (Tok.is(tok::l_paren)) {
3655
892
    if (Info->Namespace) {
3656
1
      PP.Diag(Tok.getLocation(),
3657
1
              diag::err_pragma_attribute_namespace_on_attribute);
3658
1
      PP.Diag(Tok.getLocation(),
3659
1
              diag::note_pragma_attribute_namespace_on_attribute);
3660
1
      return;
3661
1
    }
3662
891
    Info->Action = PragmaAttributeInfo::Attribute;
3663
2.23k
  } else {
3664
2.23k
    const IdentifierInfo *II = Tok.getIdentifierInfo();
3665
2.23k
    if (II->isStr("push"))
3666
1.17k
      Info->Action = PragmaAttributeInfo::Push;
3667
1.05k
    else if (II->isStr("pop"))
3668
1.05k
      Info->Action = PragmaAttributeInfo::Pop;
3669
0
    else {
3670
0
      PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
3671
0
          << PP.getSpelling(Tok);
3672
0
      return;
3673
0
    }
3674
3675
2.23k
    PP.Lex(Tok);
3676
2.23k
  }
3677
3678
  // Parse the actual attribute.
3679
3.12k
  if ((Info->Action == PragmaAttributeInfo::Push && 
Tok.isNot(tok::eod)1.17k
) ||
3680
3.12k
      
Info->Action == PragmaAttributeInfo::Attribute2.83k
) {
3681
1.18k
    if (Tok.isNot(tok::l_paren)) {
3682
0
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3683
0
      return;
3684
0
    }
3685
1.18k
    PP.Lex(Tok);
3686
3687
    // Lex the attribute tokens.
3688
1.18k
    SmallVector<Token, 16> AttributeTokens;
3689
1.18k
    int OpenParens = 1;
3690
41.4k
    while (Tok.isNot(tok::eod)) {
3691
41.4k
      if (Tok.is(tok::l_paren))
3692
4.59k
        OpenParens++;
3693
36.8k
      else if (Tok.is(tok::r_paren)) {
3694
5.75k
        OpenParens--;
3695
5.75k
        if (OpenParens == 0)
3696
1.16k
          break;
3697
5.75k
      }
3698
3699
40.2k
      AttributeTokens.push_back(Tok);
3700
40.2k
      PP.Lex(Tok);
3701
40.2k
    }
3702
3703
1.18k
    if (AttributeTokens.empty()) {
3704
2
      PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
3705
2
      return;
3706
2
    }
3707
1.17k
    if (Tok.isNot(tok::r_paren)) {
3708
10
      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3709
10
      return;
3710
10
    }
3711
1.16k
    SourceLocation EndLoc = Tok.getLocation();
3712
1.16k
    PP.Lex(Tok);
3713
3714
    // Terminate the attribute for parsing.
3715
1.16k
    Token EOFTok;
3716
1.16k
    EOFTok.startToken();
3717
1.16k
    EOFTok.setKind(tok::eof);
3718
1.16k
    EOFTok.setLocation(EndLoc);
3719
1.16k
    AttributeTokens.push_back(EOFTok);
3720
3721
1.16k
    markAsReinjectedForRelexing(AttributeTokens);
3722
1.16k
    Info->Tokens =
3723
1.16k
        llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
3724
1.16k
  }
3725
3726
3.11k
  if (Tok.isNot(tok::eod))
3727
2
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3728
2
        << "clang attribute";
3729
3730
  // Generate the annotated pragma token.
3731
3.11k
  auto TokenArray = std::make_unique<Token[]>(1);
3732
3.11k
  TokenArray[0].startToken();
3733
3.11k
  TokenArray[0].setKind(tok::annot_pragma_attribute);
3734
3.11k
  TokenArray[0].setLocation(FirstToken.getLocation());
3735
3.11k
  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
3736
3.11k
  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3737
3.11k
  PP.EnterTokenStream(std::move(TokenArray), 1,
3738
3.11k
                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3739
3.11k
}
3740
3741
// Handle '#pragma clang max_tokens 12345'.
3742
void PragmaMaxTokensHereHandler::HandlePragma(Preprocessor &PP,
3743
                                              PragmaIntroducer Introducer,
3744
12
                                              Token &Tok) {
3745
12
  PP.Lex(Tok);
3746
12
  if (Tok.is(tok::eod)) {
3747
3
    PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
3748
3
        << "clang max_tokens_here" << /*Expected=*/true << "integer";
3749
3
    return;
3750
3
  }
3751
3752
9
  SourceLocation Loc = Tok.getLocation();
3753
9
  uint64_t MaxTokens;
3754
9
  if (Tok.isNot(tok::numeric_constant) ||
3755
9
      
!PP.parseSimpleIntegerLiteral(Tok, MaxTokens)6
) {
3756
3
    PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
3757
3
        << "clang max_tokens_here";
3758
3
    return;
3759
3
  }
3760
3761
6
  if (Tok.isNot(tok::eod)) {
3762
3
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3763
3
        << "clang max_tokens_here";
3764
3
    return;
3765
3
  }
3766
3767
3
  if (PP.getTokenCount() > MaxTokens) {
3768
3
    PP.Diag(Loc, diag::warn_max_tokens)
3769
3
        << PP.getTokenCount() << (unsigned)MaxTokens;
3770
3
  }
3771
3
}
3772
3773
// Handle '#pragma clang max_tokens_total 12345'.
3774
void PragmaMaxTokensTotalHandler::HandlePragma(Preprocessor &PP,
3775
                                               PragmaIntroducer Introducer,
3776
10
                                               Token &Tok) {
3777
10
  PP.Lex(Tok);
3778
10
  if (Tok.is(tok::eod)) {
3779
3
    PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
3780
3
        << "clang max_tokens_total" << /*Expected=*/true << "integer";
3781
3
    return;
3782
3
  }
3783
3784
7
  SourceLocation Loc = Tok.getLocation();
3785
7
  uint64_t MaxTokens;
3786
7
  if (Tok.isNot(tok::numeric_constant) ||
3787
7
      
!PP.parseSimpleIntegerLiteral(Tok, MaxTokens)4
) {
3788
3
    PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
3789
3
        << "clang max_tokens_total";
3790
3
    return;
3791
3
  }
3792
3793
4
  if (Tok.isNot(tok::eod)) {
3794
3
    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3795
3
        << "clang max_tokens_total";
3796
3
    return;
3797
3
  }
3798
3799
1
  PP.overrideMaxTokens(MaxTokens, Loc);
3800
1
}