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