Coverage Report

Created: 2020-09-15 12:33

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