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