Coverage Report

Created: 2019-07-24 05:18

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