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