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