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