Coverage Report

Created: 2021-08-24 07:12

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