clang  7.0.0
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, ParsedAttr &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(), ParsedAttr::AS_GNU,
1379  /*Declarator=*/nullptr);
1380 
1381  if (ExpectAndConsume(tok::r_paren))
1382  return SkipToEnd();
1383  if (ExpectAndConsume(tok::r_paren))
1384  return SkipToEnd();
1385  } else if (Tok.is(tok::kw___declspec)) {
1386  ParseMicrosoftDeclSpecs(Attrs);
1387  } else {
1388  Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1389  if (Tok.getIdentifierInfo()) {
1390  // If we suspect that this is an attribute suggest the use of
1391  // '__attribute__'.
1392  if (ParsedAttr::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1393  ParsedAttr::AS_GNU) !=
1395  SourceLocation InsertStartLoc = Tok.getLocation();
1396  ConsumeToken();
1397  if (Tok.is(tok::l_paren)) {
1398  ConsumeAnyToken();
1399  SkipUntil(tok::r_paren, StopBeforeMatch);
1400  if (Tok.isNot(tok::r_paren))
1401  return SkipToEnd();
1402  }
1403  Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1404  << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1405  << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1406  }
1407  }
1408  SkipToEnd();
1409  return;
1410  }
1411 
1412  if (Attrs.empty() || Attrs.begin()->isInvalid()) {
1413  SkipToEnd();
1414  return;
1415  }
1416 
1417  // Ensure that we don't have more than one attribute.
1418  if (Attrs.size() > 1) {
1419  SourceLocation Loc = Attrs[1].getLoc();
1420  Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1421  SkipToEnd();
1422  return;
1423  }
1424 
1425  ParsedAttr &Attribute = *Attrs.begin();
1426  if (!Attribute.isSupportedByPragmaAttribute()) {
1427  Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1428  << Attribute.getName();
1429  SkipToEnd();
1430  return;
1431  }
1432 
1433  // Parse the subject-list.
1434  if (!TryConsumeToken(tok::comma)) {
1435  createExpectedAttributeSubjectRulesTokenDiagnostic(
1436  diag::err_expected, Attribute,
1438  << tok::comma;
1439  SkipToEnd();
1440  return;
1441  }
1442 
1443  if (Tok.isNot(tok::identifier)) {
1444  createExpectedAttributeSubjectRulesTokenDiagnostic(
1445  diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1446  MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1447  SkipToEnd();
1448  return;
1449  }
1450  const IdentifierInfo *II = Tok.getIdentifierInfo();
1451  if (!II->isStr("apply_to")) {
1452  createExpectedAttributeSubjectRulesTokenDiagnostic(
1453  diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1454  MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1455  SkipToEnd();
1456  return;
1457  }
1458  ConsumeToken();
1459 
1460  if (!TryConsumeToken(tok::equal)) {
1461  createExpectedAttributeSubjectRulesTokenDiagnostic(
1462  diag::err_expected, Attribute,
1463  MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1464  << tok::equal;
1465  SkipToEnd();
1466  return;
1467  }
1468 
1469  attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1470  SourceLocation AnyLoc, LastMatchRuleEndLoc;
1471  if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1472  LastMatchRuleEndLoc)) {
1473  SkipToEnd();
1474  return;
1475  }
1476 
1477  // Tokens following an ill-formed attribute will remain in the token stream
1478  // and must be removed.
1479  if (Tok.isNot(tok::eof)) {
1480  Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1481  SkipToEnd();
1482  return;
1483  }
1484 
1485  // Consume the eof terminator token.
1486  ConsumeToken();
1487 
1488  Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
1489  std::move(SubjectMatchRules));
1490 }
1491 
1492 // #pragma GCC visibility comes in two variants:
1493 // 'push' '(' [visibility] ')'
1494 // 'pop'
1495 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1496  PragmaIntroducerKind Introducer,
1497  Token &VisTok) {
1498  SourceLocation VisLoc = VisTok.getLocation();
1499 
1500  Token Tok;
1501  PP.LexUnexpandedToken(Tok);
1502 
1503  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1504 
1505  const IdentifierInfo *VisType;
1506  if (PushPop && PushPop->isStr("pop")) {
1507  VisType = nullptr;
1508  } else if (PushPop && PushPop->isStr("push")) {
1509  PP.LexUnexpandedToken(Tok);
1510  if (Tok.isNot(tok::l_paren)) {
1511  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1512  << "visibility";
1513  return;
1514  }
1515  PP.LexUnexpandedToken(Tok);
1516  VisType = Tok.getIdentifierInfo();
1517  if (!VisType) {
1518  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1519  << "visibility";
1520  return;
1521  }
1522  PP.LexUnexpandedToken(Tok);
1523  if (Tok.isNot(tok::r_paren)) {
1524  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1525  << "visibility";
1526  return;
1527  }
1528  } else {
1529  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1530  << "visibility";
1531  return;
1532  }
1533  SourceLocation EndLoc = Tok.getLocation();
1534  PP.LexUnexpandedToken(Tok);
1535  if (Tok.isNot(tok::eod)) {
1536  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1537  << "visibility";
1538  return;
1539  }
1540 
1541  auto Toks = llvm::make_unique<Token[]>(1);
1542  Toks[0].startToken();
1543  Toks[0].setKind(tok::annot_pragma_vis);
1544  Toks[0].setLocation(VisLoc);
1545  Toks[0].setAnnotationEndLoc(EndLoc);
1546  Toks[0].setAnnotationValue(
1547  const_cast<void*>(static_cast<const void*>(VisType)));
1548  PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true);
1549 }
1550 
1551 // #pragma pack(...) comes in the following delicious flavors:
1552 // pack '(' [integer] ')'
1553 // pack '(' 'show' ')'
1554 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1555 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1556  PragmaIntroducerKind Introducer,
1557  Token &PackTok) {
1558  SourceLocation PackLoc = PackTok.getLocation();
1559 
1560  Token Tok;
1561  PP.Lex(Tok);
1562  if (Tok.isNot(tok::l_paren)) {
1563  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1564  return;
1565  }
1566 
1568  StringRef SlotLabel;
1569  Token Alignment;
1570  Alignment.startToken();
1571  PP.Lex(Tok);
1572  if (Tok.is(tok::numeric_constant)) {
1573  Alignment = Tok;
1574 
1575  PP.Lex(Tok);
1576 
1577  // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1578  // the push/pop stack.
1579  // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1580  Action =
1581  PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1582  } else if (Tok.is(tok::identifier)) {
1583  const IdentifierInfo *II = Tok.getIdentifierInfo();
1584  if (II->isStr("show")) {
1585  Action = Sema::PSK_Show;
1586  PP.Lex(Tok);
1587  } else {
1588  if (II->isStr("push")) {
1589  Action = Sema::PSK_Push;
1590  } else if (II->isStr("pop")) {
1591  Action = Sema::PSK_Pop;
1592  } else {
1593  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1594  return;
1595  }
1596  PP.Lex(Tok);
1597 
1598  if (Tok.is(tok::comma)) {
1599  PP.Lex(Tok);
1600 
1601  if (Tok.is(tok::numeric_constant)) {
1602  Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1603  Alignment = Tok;
1604 
1605  PP.Lex(Tok);
1606  } else if (Tok.is(tok::identifier)) {
1607  SlotLabel = Tok.getIdentifierInfo()->getName();
1608  PP.Lex(Tok);
1609 
1610  if (Tok.is(tok::comma)) {
1611  PP.Lex(Tok);
1612 
1613  if (Tok.isNot(tok::numeric_constant)) {
1614  PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1615  return;
1616  }
1617 
1618  Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1619  Alignment = Tok;
1620 
1621  PP.Lex(Tok);
1622  }
1623  } else {
1624  PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1625  return;
1626  }
1627  }
1628  }
1629  } else if (PP.getLangOpts().ApplePragmaPack) {
1630  // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1631  // the push/pop stack.
1632  // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1633  Action = Sema::PSK_Pop;
1634  }
1635 
1636  if (Tok.isNot(tok::r_paren)) {
1637  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1638  return;
1639  }
1640 
1641  SourceLocation RParenLoc = Tok.getLocation();
1642  PP.Lex(Tok);
1643  if (Tok.isNot(tok::eod)) {
1644  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1645  return;
1646  }
1647 
1648  PragmaPackInfo *Info =
1649  PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1650  Info->Action = Action;
1651  Info->SlotLabel = SlotLabel;
1652  Info->Alignment = Alignment;
1653 
1654  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1655  1);
1656  Toks[0].startToken();
1657  Toks[0].setKind(tok::annot_pragma_pack);
1658  Toks[0].setLocation(PackLoc);
1659  Toks[0].setAnnotationEndLoc(RParenLoc);
1660  Toks[0].setAnnotationValue(static_cast<void*>(Info));
1661  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1662 }
1663 
1664 // #pragma ms_struct on
1665 // #pragma ms_struct off
1666 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1667  PragmaIntroducerKind Introducer,
1668  Token &MSStructTok) {
1670 
1671  Token Tok;
1672  PP.Lex(Tok);
1673  if (Tok.isNot(tok::identifier)) {
1674  PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1675  return;
1676  }
1677  SourceLocation EndLoc = Tok.getLocation();
1678  const IdentifierInfo *II = Tok.getIdentifierInfo();
1679  if (II->isStr("on")) {
1680  Kind = PMSST_ON;
1681  PP.Lex(Tok);
1682  }
1683  else if (II->isStr("off") || II->isStr("reset"))
1684  PP.Lex(Tok);
1685  else {
1686  PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1687  return;
1688  }
1689 
1690  if (Tok.isNot(tok::eod)) {
1691  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1692  << "ms_struct";
1693  return;
1694  }
1695 
1696  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1697  1);
1698  Toks[0].startToken();
1699  Toks[0].setKind(tok::annot_pragma_msstruct);
1700  Toks[0].setLocation(MSStructTok.getLocation());
1701  Toks[0].setAnnotationEndLoc(EndLoc);
1702  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1703  static_cast<uintptr_t>(Kind)));
1704  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1705 }
1706 
1707 // #pragma clang section bss="abc" data="" rodata="def" text=""
1708 void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
1709  PragmaIntroducerKind Introducer, Token &FirstToken) {
1710 
1711  Token Tok;
1712  auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1713 
1714  PP.Lex(Tok); // eat 'section'
1715  while (Tok.isNot(tok::eod)) {
1716  if (Tok.isNot(tok::identifier)) {
1717  PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1718  return;
1719  }
1720 
1721  const IdentifierInfo *SecType = Tok.getIdentifierInfo();
1722  if (SecType->isStr("bss"))
1723  SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1724  else if (SecType->isStr("data"))
1725  SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1726  else if (SecType->isStr("rodata"))
1727  SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1728  else if (SecType->isStr("text"))
1729  SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1730  else {
1731  PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1732  return;
1733  }
1734 
1735  PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
1736  if (Tok.isNot(tok::equal)) {
1737  PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1738  return;
1739  }
1740 
1741  std::string SecName;
1742  if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
1743  return;
1744 
1745  Actions.ActOnPragmaClangSection(Tok.getLocation(),
1746  (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1747  Sema::PragmaClangSectionAction::PCSA_Clear),
1748  SecKind, SecName);
1749  }
1750 }
1751 
1752 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1753 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1754 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1755  bool IsOptions) {
1756  Token Tok;
1757 
1758  if (IsOptions) {
1759  PP.Lex(Tok);
1760  if (Tok.isNot(tok::identifier) ||
1761  !Tok.getIdentifierInfo()->isStr("align")) {
1762  PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1763  return;
1764  }
1765  }
1766 
1767  PP.Lex(Tok);
1768  if (Tok.isNot(tok::equal)) {
1769  PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1770  << IsOptions;
1771  return;
1772  }
1773 
1774  PP.Lex(Tok);
1775  if (Tok.isNot(tok::identifier)) {
1776  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1777  << (IsOptions ? "options" : "align");
1778  return;
1779  }
1780 
1782  const IdentifierInfo *II = Tok.getIdentifierInfo();
1783  if (II->isStr("native"))
1784  Kind = Sema::POAK_Native;
1785  else if (II->isStr("natural"))
1786  Kind = Sema::POAK_Natural;
1787  else if (II->isStr("packed"))
1788  Kind = Sema::POAK_Packed;
1789  else if (II->isStr("power"))
1790  Kind = Sema::POAK_Power;
1791  else if (II->isStr("mac68k"))
1792  Kind = Sema::POAK_Mac68k;
1793  else if (II->isStr("reset"))
1794  Kind = Sema::POAK_Reset;
1795  else {
1796  PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1797  << IsOptions;
1798  return;
1799  }
1800 
1801  SourceLocation EndLoc = Tok.getLocation();
1802  PP.Lex(Tok);
1803  if (Tok.isNot(tok::eod)) {
1804  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1805  << (IsOptions ? "options" : "align");
1806  return;
1807  }
1808 
1809  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1810  1);
1811  Toks[0].startToken();
1812  Toks[0].setKind(tok::annot_pragma_align);
1813  Toks[0].setLocation(FirstTok.getLocation());
1814  Toks[0].setAnnotationEndLoc(EndLoc);
1815  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1816  static_cast<uintptr_t>(Kind)));
1817  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1818 }
1819 
1820 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1821  PragmaIntroducerKind Introducer,
1822  Token &AlignTok) {
1823  ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1824 }
1825 
1826 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1827  PragmaIntroducerKind Introducer,
1828  Token &OptionsTok) {
1829  ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1830 }
1831 
1832 // #pragma unused(identifier)
1833 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1834  PragmaIntroducerKind Introducer,
1835  Token &UnusedTok) {
1836  // FIXME: Should we be expanding macros here? My guess is no.
1837  SourceLocation UnusedLoc = UnusedTok.getLocation();
1838 
1839  // Lex the left '('.
1840  Token Tok;
1841  PP.Lex(Tok);
1842  if (Tok.isNot(tok::l_paren)) {
1843  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1844  return;
1845  }
1846 
1847  // Lex the declaration reference(s).
1848  SmallVector<Token, 5> Identifiers;
1849  SourceLocation RParenLoc;
1850  bool LexID = true;
1851 
1852  while (true) {
1853  PP.Lex(Tok);
1854 
1855  if (LexID) {
1856  if (Tok.is(tok::identifier)) {
1857  Identifiers.push_back(Tok);
1858  LexID = false;
1859  continue;
1860  }
1861 
1862  // Illegal token!
1863  PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1864  return;
1865  }
1866 
1867  // We are execting a ')' or a ','.
1868  if (Tok.is(tok::comma)) {
1869  LexID = true;
1870  continue;
1871  }
1872 
1873  if (Tok.is(tok::r_paren)) {
1874  RParenLoc = Tok.getLocation();
1875  break;
1876  }
1877 
1878  // Illegal token!
1879  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1880  return;
1881  }
1882 
1883  PP.Lex(Tok);
1884  if (Tok.isNot(tok::eod)) {
1885  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1886  "unused";
1887  return;
1888  }
1889 
1890  // Verify that we have a location for the right parenthesis.
1891  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1892  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1893 
1894  // For each identifier token, insert into the token stream a
1895  // annot_pragma_unused token followed by the identifier token.
1896  // This allows us to cache a "#pragma unused" that occurs inside an inline
1897  // C++ member function.
1898 
1900  PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1901  2 * Identifiers.size());
1902  for (unsigned i=0; i != Identifiers.size(); i++) {
1903  Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1904  pragmaUnusedTok.startToken();
1905  pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1906  pragmaUnusedTok.setLocation(UnusedLoc);
1907  idTok = Identifiers[i];
1908  }
1909  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1910 }
1911 
1912 // #pragma weak identifier
1913 // #pragma weak identifier '=' identifier
1914 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1915  PragmaIntroducerKind Introducer,
1916  Token &WeakTok) {
1917  SourceLocation WeakLoc = WeakTok.getLocation();
1918 
1919  Token Tok;
1920  PP.Lex(Tok);
1921  if (Tok.isNot(tok::identifier)) {
1922  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1923  return;
1924  }
1925 
1926  Token WeakName = Tok;
1927  bool HasAlias = false;
1928  Token AliasName;
1929 
1930  PP.Lex(Tok);
1931  if (Tok.is(tok::equal)) {
1932  HasAlias = true;
1933  PP.Lex(Tok);
1934  if (Tok.isNot(tok::identifier)) {
1935  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1936  << "weak";
1937  return;
1938  }
1939  AliasName = Tok;
1940  PP.Lex(Tok);
1941  }
1942 
1943  if (Tok.isNot(tok::eod)) {
1944  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1945  return;
1946  }
1947 
1948  if (HasAlias) {
1950  PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
1951  Token &pragmaUnusedTok = Toks[0];
1952  pragmaUnusedTok.startToken();
1953  pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1954  pragmaUnusedTok.setLocation(WeakLoc);
1955  pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1956  Toks[1] = WeakName;
1957  Toks[2] = AliasName;
1958  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1959  } else {
1961  PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
1962  Token &pragmaUnusedTok = Toks[0];
1963  pragmaUnusedTok.startToken();
1964  pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1965  pragmaUnusedTok.setLocation(WeakLoc);
1966  pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1967  Toks[1] = WeakName;
1968  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1969  }
1970 }
1971 
1972 // #pragma redefine_extname identifier identifier
1973 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
1974  PragmaIntroducerKind Introducer,
1975  Token &RedefToken) {
1976  SourceLocation RedefLoc = RedefToken.getLocation();
1977 
1978  Token Tok;
1979  PP.Lex(Tok);
1980  if (Tok.isNot(tok::identifier)) {
1981  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1982  "redefine_extname";
1983  return;
1984  }
1985 
1986  Token RedefName = Tok;
1987  PP.Lex(Tok);
1988 
1989  if (Tok.isNot(tok::identifier)) {
1990  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1991  << "redefine_extname";
1992  return;
1993  }
1994 
1995  Token AliasName = Tok;
1996  PP.Lex(Tok);
1997 
1998  if (Tok.isNot(tok::eod)) {
1999  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2000  "redefine_extname";
2001  return;
2002  }
2003 
2004  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
2005  3);
2006  Token &pragmaRedefTok = Toks[0];
2007  pragmaRedefTok.startToken();
2008  pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2009  pragmaRedefTok.setLocation(RedefLoc);
2010  pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
2011  Toks[1] = RedefName;
2012  Toks[2] = AliasName;
2013  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2014 }
2015 
2016 
2017 void
2018 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2019  PragmaIntroducerKind Introducer,
2020  Token &Tok) {
2021  tok::OnOffSwitch OOS;
2022  if (PP.LexOnOffSwitch(OOS))
2023  return;
2024 
2025  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2026  1);
2027  Toks[0].startToken();
2028  Toks[0].setKind(tok::annot_pragma_fp_contract);
2029  Toks[0].setLocation(Tok.getLocation());
2030  Toks[0].setAnnotationEndLoc(Tok.getLocation());
2031  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2032  static_cast<uintptr_t>(OOS)));
2033  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2034 }
2035 
2036 void
2037 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2038  PragmaIntroducerKind Introducer,
2039  Token &Tok) {
2040  PP.LexUnexpandedToken(Tok);
2041  if (Tok.isNot(tok::identifier)) {
2042  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2043  "OPENCL";
2044  return;
2045  }
2046  IdentifierInfo *Ext = Tok.getIdentifierInfo();
2047  SourceLocation NameLoc = Tok.getLocation();
2048 
2049  PP.Lex(Tok);
2050  if (Tok.isNot(tok::colon)) {
2051  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2052  return;
2053  }
2054 
2055  PP.Lex(Tok);
2056  if (Tok.isNot(tok::identifier)) {
2057  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2058  return;
2059  }
2060  IdentifierInfo *Pred = Tok.getIdentifierInfo();
2061 
2063  if (Pred->isStr("enable")) {
2064  State = Enable;
2065  } else if (Pred->isStr("disable")) {
2066  State = Disable;
2067  } else if (Pred->isStr("begin"))
2068  State = Begin;
2069  else if (Pred->isStr("end"))
2070  State = End;
2071  else {
2072  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2073  << Ext->isStr("all");
2074  return;
2075  }
2076  SourceLocation StateLoc = Tok.getLocation();
2077 
2078  PP.Lex(Tok);
2079  if (Tok.isNot(tok::eod)) {
2080  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2081  "OPENCL EXTENSION";
2082  return;
2083  }
2084 
2085  auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
2086  Info->first = Ext;
2087  Info->second = State;
2088  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2089  1);
2090  Toks[0].startToken();
2091  Toks[0].setKind(tok::annot_pragma_opencl_extension);
2092  Toks[0].setLocation(NameLoc);
2093  Toks[0].setAnnotationValue(static_cast<void*>(Info));
2094  Toks[0].setAnnotationEndLoc(StateLoc);
2095  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2096 
2097  if (PP.getPPCallbacks())
2098  PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
2099  StateLoc, State);
2100 }
2101 
2102 /// Handle '#pragma omp ...' when OpenMP is disabled.
2103 ///
2104 void
2105 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
2106  PragmaIntroducerKind Introducer,
2107  Token &FirstTok) {
2108  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
2109  FirstTok.getLocation())) {
2110  PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
2111  PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
2113  }
2115 }
2116 
2117 /// Handle '#pragma omp ...' when OpenMP is enabled.
2118 ///
2119 void
2120 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
2121  PragmaIntroducerKind Introducer,
2122  Token &FirstTok) {
2124  Token Tok;
2125  Tok.startToken();
2126  Tok.setKind(tok::annot_pragma_openmp);
2127  Tok.setLocation(FirstTok.getLocation());
2128 
2129  while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
2130  Pragma.push_back(Tok);
2131  PP.Lex(Tok);
2132  if (Tok.is(tok::annot_pragma_openmp)) {
2133  PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2134  unsigned InnerPragmaCnt = 1;
2135  while (InnerPragmaCnt != 0) {
2136  PP.Lex(Tok);
2137  if (Tok.is(tok::annot_pragma_openmp))
2138  ++InnerPragmaCnt;
2139  else if (Tok.is(tok::annot_pragma_openmp_end))
2140  --InnerPragmaCnt;
2141  }
2142  PP.Lex(Tok);
2143  }
2144  }
2145  SourceLocation EodLoc = Tok.getLocation();
2146  Tok.startToken();
2147  Tok.setKind(tok::annot_pragma_openmp_end);
2148  Tok.setLocation(EodLoc);
2149  Pragma.push_back(Tok);
2150 
2151  auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2152  std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2153  PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2154  /*DisableMacroExpansion=*/false);
2155 }
2156 
2157 /// Handle '#pragma pointers_to_members'
2158 // The grammar for this pragma is as follows:
2159 //
2160 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2161 //
2162 // #pragma pointers_to_members '(' 'best_case' ')'
2163 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2164 // #pragma pointers_to_members '(' inheritance-model ')'
2165 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2166  PragmaIntroducerKind Introducer,
2167  Token &Tok) {
2168  SourceLocation PointersToMembersLoc = Tok.getLocation();
2169  PP.Lex(Tok);
2170  if (Tok.isNot(tok::l_paren)) {
2171  PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2172  << "pointers_to_members";
2173  return;
2174  }
2175  PP.Lex(Tok);
2176  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2177  if (!Arg) {
2178  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2179  << "pointers_to_members";
2180  return;
2181  }
2182  PP.Lex(Tok);
2183 
2184  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2185  if (Arg->isStr("best_case")) {
2186  RepresentationMethod = LangOptions::PPTMK_BestCase;
2187  } else {
2188  if (Arg->isStr("full_generality")) {
2189  if (Tok.is(tok::comma)) {
2190  PP.Lex(Tok);
2191 
2192  Arg = Tok.getIdentifierInfo();
2193  if (!Arg) {
2194  PP.Diag(Tok.getLocation(),
2195  diag::err_pragma_pointers_to_members_unknown_kind)
2196  << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2197  return;
2198  }
2199  PP.Lex(Tok);
2200  } else if (Tok.is(tok::r_paren)) {
2201  // #pragma pointers_to_members(full_generality) implicitly specifies
2202  // virtual_inheritance.
2203  Arg = nullptr;
2205  } else {
2206  PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2207  << "full_generality";
2208  return;
2209  }
2210  }
2211 
2212  if (Arg) {
2213  if (Arg->isStr("single_inheritance")) {
2214  RepresentationMethod =
2216  } else if (Arg->isStr("multiple_inheritance")) {
2217  RepresentationMethod =
2219  } else if (Arg->isStr("virtual_inheritance")) {
2220  RepresentationMethod =
2222  } else {
2223  PP.Diag(Tok.getLocation(),
2224  diag::err_pragma_pointers_to_members_unknown_kind)
2225  << Arg << /*HasPointerDeclaration*/ 1;
2226  return;
2227  }
2228  }
2229  }
2230 
2231  if (Tok.isNot(tok::r_paren)) {
2232  PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2233  << (Arg ? Arg->getName() : "full_generality");
2234  return;
2235  }
2236 
2237  SourceLocation EndLoc = Tok.getLocation();
2238  PP.Lex(Tok);
2239  if (Tok.isNot(tok::eod)) {
2240  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2241  << "pointers_to_members";
2242  return;
2243  }
2244 
2245  Token AnnotTok;
2246  AnnotTok.startToken();
2247  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2248  AnnotTok.setLocation(PointersToMembersLoc);
2249  AnnotTok.setAnnotationEndLoc(EndLoc);
2250  AnnotTok.setAnnotationValue(
2251  reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2252  PP.EnterToken(AnnotTok);
2253 }
2254 
2255 /// Handle '#pragma vtordisp'
2256 // The grammar for this pragma is as follows:
2257 //
2258 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2259 //
2260 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2261 // #pragma vtordisp '(' 'pop' ')'
2262 // #pragma vtordisp '(' ')'
2263 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2264  PragmaIntroducerKind Introducer,
2265  Token &Tok) {
2266  SourceLocation VtorDispLoc = Tok.getLocation();
2267  PP.Lex(Tok);
2268  if (Tok.isNot(tok::l_paren)) {
2269  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2270  return;
2271  }
2272  PP.Lex(Tok);
2273 
2275  const IdentifierInfo *II = Tok.getIdentifierInfo();
2276  if (II) {
2277  if (II->isStr("push")) {
2278  // #pragma vtordisp(push, mode)
2279  PP.Lex(Tok);
2280  if (Tok.isNot(tok::comma)) {
2281  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2282  return;
2283  }
2284  PP.Lex(Tok);
2285  Action = Sema::PSK_Push_Set;
2286  // not push, could be on/off
2287  } else if (II->isStr("pop")) {
2288  // #pragma vtordisp(pop)
2289  PP.Lex(Tok);
2290  Action = Sema::PSK_Pop;
2291  }
2292  // not push or pop, could be on/off
2293  } else {
2294  if (Tok.is(tok::r_paren)) {
2295  // #pragma vtordisp()
2296  Action = Sema::PSK_Reset;
2297  }
2298  }
2299 
2300 
2301  uint64_t Value = 0;
2302  if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
2303  const IdentifierInfo *II = Tok.getIdentifierInfo();
2304  if (II && II->isStr("off")) {
2305  PP.Lex(Tok);
2306  Value = 0;
2307  } else if (II && II->isStr("on")) {
2308  PP.Lex(Tok);
2309  Value = 1;
2310  } else if (Tok.is(tok::numeric_constant) &&
2311  PP.parseSimpleIntegerLiteral(Tok, Value)) {
2312  if (Value > 2) {
2313  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2314  << 0 << 2 << "vtordisp";
2315  return;
2316  }
2317  } else {
2318  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2319  << "vtordisp";
2320  return;
2321  }
2322  }
2323 
2324  // Finish the pragma: ')' $
2325  if (Tok.isNot(tok::r_paren)) {
2326  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2327  return;
2328  }
2329  SourceLocation EndLoc = Tok.getLocation();
2330  PP.Lex(Tok);
2331  if (Tok.isNot(tok::eod)) {
2332  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2333  << "vtordisp";
2334  return;
2335  }
2336 
2337  // Enter the annotation.
2338  Token AnnotTok;
2339  AnnotTok.startToken();
2340  AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2341  AnnotTok.setLocation(VtorDispLoc);
2342  AnnotTok.setAnnotationEndLoc(EndLoc);
2343  AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2344  static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2345  PP.EnterToken(AnnotTok);
2346 }
2347 
2348 /// Handle all MS pragmas. Simply forwards the tokens after inserting
2349 /// an annotation token.
2350 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2351  PragmaIntroducerKind Introducer,
2352  Token &Tok) {
2353  Token EoF, AnnotTok;
2354  EoF.startToken();
2355  EoF.setKind(tok::eof);
2356  AnnotTok.startToken();
2357  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2358  AnnotTok.setLocation(Tok.getLocation());
2359  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2360  SmallVector<Token, 8> TokenVector;
2361  // Suck up all of the tokens before the eod.
2362  for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2363  TokenVector.push_back(Tok);
2364  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2365  }
2366  // Add a sentinel EoF token to the end of the list.
2367  TokenVector.push_back(EoF);
2368  // We must allocate this array with new because EnterTokenStream is going to
2369  // delete it later.
2370  auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2371  std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2372  auto Value = new (PP.getPreprocessorAllocator())
2373  std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2374  TokenVector.size());
2375  AnnotTok.setAnnotationValue(Value);
2376  PP.EnterToken(AnnotTok);
2377 }
2378 
2379 /// Handle the Microsoft \#pragma detect_mismatch extension.
2380 ///
2381 /// The syntax is:
2382 /// \code
2383 /// #pragma detect_mismatch("name", "value")
2384 /// \endcode
2385 /// Where 'name' and 'value' are quoted strings. The values are embedded in
2386 /// the object file and passed along to the linker. If the linker detects a
2387 /// mismatch in the object file's values for the given name, a LNK2038 error
2388 /// is emitted. See MSDN for more details.
2389 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2390  PragmaIntroducerKind Introducer,
2391  Token &Tok) {
2392  SourceLocation DetectMismatchLoc = Tok.getLocation();
2393  PP.Lex(Tok);
2394  if (Tok.isNot(tok::l_paren)) {
2395  PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2396  return;
2397  }
2398 
2399  // Read the name to embed, which must be a string literal.
2400  std::string NameString;
2401  if (!PP.LexStringLiteral(Tok, NameString,
2402  "pragma detect_mismatch",
2403  /*MacroExpansion=*/true))
2404  return;
2405 
2406  // Read the comma followed by a second string literal.
2407  std::string ValueString;
2408  if (Tok.isNot(tok::comma)) {
2409  PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2410  return;
2411  }
2412 
2413  if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2414  /*MacroExpansion=*/true))
2415  return;
2416 
2417  if (Tok.isNot(tok::r_paren)) {
2418  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2419  return;
2420  }
2421  PP.Lex(Tok); // Eat the r_paren.
2422 
2423  if (Tok.isNot(tok::eod)) {
2424  PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2425  return;
2426  }
2427 
2428  // If the pragma is lexically sound, notify any interested PPCallbacks.
2429  if (PP.getPPCallbacks())
2430  PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2431  ValueString);
2432 
2433  Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2434 }
2435 
2436 /// Handle the microsoft \#pragma comment extension.
2437 ///
2438 /// The syntax is:
2439 /// \code
2440 /// #pragma comment(linker, "foo")
2441 /// \endcode
2442 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2443 /// "foo" is a string, which is fully macro expanded, and permits string
2444 /// concatenation, embedded escape characters etc. See MSDN for more details.
2445 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2446  PragmaIntroducerKind Introducer,
2447  Token &Tok) {
2448  SourceLocation CommentLoc = Tok.getLocation();
2449  PP.Lex(Tok);
2450  if (Tok.isNot(tok::l_paren)) {
2451  PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2452  return;
2453  }
2454 
2455  // Read the identifier.
2456  PP.Lex(Tok);
2457  if (Tok.isNot(tok::identifier)) {
2458  PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2459  return;
2460  }
2461 
2462  // Verify that this is one of the 5 whitelisted options.
2463  IdentifierInfo *II = Tok.getIdentifierInfo();
2464  PragmaMSCommentKind Kind =
2465  llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2466  .Case("linker", PCK_Linker)
2467  .Case("lib", PCK_Lib)
2468  .Case("compiler", PCK_Compiler)
2469  .Case("exestr", PCK_ExeStr)
2470  .Case("user", PCK_User)
2471  .Default(PCK_Unknown);
2472  if (Kind == PCK_Unknown) {
2473  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2474  return;
2475  }
2476 
2477  if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
2478  PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2479  << II->getName();
2480  return;
2481  }
2482 
2483  // On PS4, issue a warning about any pragma comments other than
2484  // #pragma comment lib.
2485  if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
2486  PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2487  << II->getName();
2488  return;
2489  }
2490 
2491  // Read the optional string if present.
2492  PP.Lex(Tok);
2493  std::string ArgumentString;
2494  if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2495  "pragma comment",
2496  /*MacroExpansion=*/true))
2497  return;
2498 
2499  // FIXME: warn that 'exestr' is deprecated.
2500  // FIXME: If the kind is "compiler" warn if the string is present (it is
2501  // ignored).
2502  // The MSDN docs say that "lib" and "linker" require a string and have a short
2503  // whitelist of linker options they support, but in practice MSVC doesn't
2504  // issue a diagnostic. Therefore neither does clang.
2505 
2506  if (Tok.isNot(tok::r_paren)) {
2507  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2508  return;
2509  }
2510  PP.Lex(Tok); // eat the r_paren.
2511 
2512  if (Tok.isNot(tok::eod)) {
2513  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2514  return;
2515  }
2516 
2517  // If the pragma is lexically sound, notify any interested PPCallbacks.
2518  if (PP.getPPCallbacks())
2519  PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2520 
2521  Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2522 }
2523 
2524 // #pragma clang optimize off
2525 // #pragma clang optimize on
2526 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2527  PragmaIntroducerKind Introducer,
2528  Token &FirstToken) {
2529  Token Tok;
2530  PP.Lex(Tok);
2531  if (Tok.is(tok::eod)) {
2532  PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2533  << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
2534  return;
2535  }
2536  if (Tok.isNot(tok::identifier)) {
2537  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2538  << PP.getSpelling(Tok);
2539  return;
2540  }
2541  const IdentifierInfo *II = Tok.getIdentifierInfo();
2542  // The only accepted values are 'on' or 'off'.
2543  bool IsOn = false;
2544  if (II->isStr("on")) {
2545  IsOn = true;
2546  } else if (!II->isStr("off")) {
2547  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2548  << PP.getSpelling(Tok);
2549  return;
2550  }
2551  PP.Lex(Tok);
2552 
2553  if (Tok.isNot(tok::eod)) {
2554  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
2555  << PP.getSpelling(Tok);
2556  return;
2557  }
2558 
2559  Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
2560 }
2561 
2562 namespace {
2563 /// Used as the annotation value for tok::annot_pragma_fp.
2564 struct TokFPAnnotValue {
2565  enum FlagKinds { Contract };
2566  enum FlagValues { On, Off, Fast };
2567 
2568  FlagKinds FlagKind;
2569  FlagValues FlagValue;
2570 };
2571 } // end anonymous namespace
2572 
2573 void PragmaFPHandler::HandlePragma(Preprocessor &PP,
2574  PragmaIntroducerKind Introducer,
2575  Token &Tok) {
2576  // fp
2577  Token PragmaName = Tok;
2578  SmallVector<Token, 1> TokenList;
2579 
2580  PP.Lex(Tok);
2581  if (Tok.isNot(tok::identifier)) {
2582  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2583  << /*MissingOption=*/true << "";
2584  return;
2585  }
2586 
2587  while (Tok.is(tok::identifier)) {
2588  IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2589 
2590  auto FlagKind =
2591  llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2592  OptionInfo->getName())
2593  .Case("contract", TokFPAnnotValue::Contract)
2594  .Default(None);
2595  if (!FlagKind) {
2596  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2597  << /*MissingOption=*/false << OptionInfo;
2598  return;
2599  }
2600  PP.Lex(Tok);
2601 
2602  // Read '('
2603  if (Tok.isNot(tok::l_paren)) {
2604  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2605  return;
2606  }
2607  PP.Lex(Tok);
2608 
2609  if (Tok.isNot(tok::identifier)) {
2610  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2611  << PP.getSpelling(Tok) << OptionInfo->getName();
2612  return;
2613  }
2614  const IdentifierInfo *II = Tok.getIdentifierInfo();
2615 
2616  auto FlagValue =
2617  llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2618  II->getName())
2619  .Case("on", TokFPAnnotValue::On)
2620  .Case("off", TokFPAnnotValue::Off)
2621  .Case("fast", TokFPAnnotValue::Fast)
2622  .Default(llvm::None);
2623 
2624  if (!FlagValue) {
2625  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2626  << PP.getSpelling(Tok) << OptionInfo->getName();
2627  return;
2628  }
2629  PP.Lex(Tok);
2630 
2631  // Read ')'
2632  if (Tok.isNot(tok::r_paren)) {
2633  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2634  return;
2635  }
2636  PP.Lex(Tok);
2637 
2638  auto *AnnotValue = new (PP.getPreprocessorAllocator())
2639  TokFPAnnotValue{*FlagKind, *FlagValue};
2640  // Generate the loop hint token.
2641  Token FPTok;
2642  FPTok.startToken();
2643  FPTok.setKind(tok::annot_pragma_fp);
2644  FPTok.setLocation(PragmaName.getLocation());
2645  FPTok.setAnnotationEndLoc(PragmaName.getLocation());
2646  FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
2647  TokenList.push_back(FPTok);
2648  }
2649 
2650  if (Tok.isNot(tok::eod)) {
2651  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2652  << "clang fp";
2653  return;
2654  }
2655 
2656  auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2657  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2658 
2659  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2660  /*DisableMacroExpansion=*/false);
2661 }
2662 
2663 void Parser::HandlePragmaFP() {
2664  assert(Tok.is(tok::annot_pragma_fp));
2665  auto *AnnotValue =
2666  reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
2667 
2669  switch (AnnotValue->FlagValue) {
2670  case TokFPAnnotValue::On:
2671  FPC = LangOptions::FPC_On;
2672  break;
2673  case TokFPAnnotValue::Fast:
2674  FPC = LangOptions::FPC_Fast;
2675  break;
2676  case TokFPAnnotValue::Off:
2677  FPC = LangOptions::FPC_Off;
2678  break;
2679  }
2680 
2681  Actions.ActOnPragmaFPContract(FPC);
2682  ConsumeAnnotationToken();
2683 }
2684 
2685 /// Parses loop or unroll pragma hint value and fills in Info.
2686 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
2687  Token Option, bool ValueInParens,
2688  PragmaLoopHintInfo &Info) {
2690  int OpenParens = ValueInParens ? 1 : 0;
2691  // Read constant expression.
2692  while (Tok.isNot(tok::eod)) {
2693  if (Tok.is(tok::l_paren))
2694  OpenParens++;
2695  else if (Tok.is(tok::r_paren)) {
2696  OpenParens--;
2697  if (OpenParens == 0 && ValueInParens)
2698  break;
2699  }
2700 
2701  ValueList.push_back(Tok);
2702  PP.Lex(Tok);
2703  }
2704 
2705  if (ValueInParens) {
2706  // Read ')'
2707  if (Tok.isNot(tok::r_paren)) {
2708  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2709  return true;
2710  }
2711  PP.Lex(Tok);
2712  }
2713 
2714  Token EOFTok;
2715  EOFTok.startToken();
2716  EOFTok.setKind(tok::eof);
2717  EOFTok.setLocation(Tok.getLocation());
2718  ValueList.push_back(EOFTok); // Terminates expression for parsing.
2719 
2720  Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
2721 
2722  Info.PragmaName = PragmaName;
2723  Info.Option = Option;
2724  return false;
2725 }
2726 
2727 /// Handle the \#pragma clang loop directive.
2728 /// #pragma clang 'loop' loop-hints
2729 ///
2730 /// loop-hints:
2731 /// loop-hint loop-hints[opt]
2732 ///
2733 /// loop-hint:
2734 /// 'vectorize' '(' loop-hint-keyword ')'
2735 /// 'interleave' '(' loop-hint-keyword ')'
2736 /// 'unroll' '(' unroll-hint-keyword ')'
2737 /// 'vectorize_width' '(' loop-hint-value ')'
2738 /// 'interleave_count' '(' loop-hint-value ')'
2739 /// 'unroll_count' '(' loop-hint-value ')'
2740 ///
2741 /// loop-hint-keyword:
2742 /// 'enable'
2743 /// 'disable'
2744 /// 'assume_safety'
2745 ///
2746 /// unroll-hint-keyword:
2747 /// 'enable'
2748 /// 'disable'
2749 /// 'full'
2750 ///
2751 /// loop-hint-value:
2752 /// constant-expression
2753 ///
2754 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2755 /// try vectorizing the instructions of the loop it precedes. Specifying
2756 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
2757 /// interleaving multiple iterations of the loop it precedes. The width of the
2758 /// vector instructions is specified by vectorize_width() and the number of
2759 /// interleaved loop iterations is specified by interleave_count(). Specifying a
2760 /// value of 1 effectively disables vectorization/interleaving, even if it is
2761 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
2762 /// only works on inner loops.
2763 ///
2764 /// The unroll and unroll_count directives control the concatenation
2765 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2766 /// completely if the trip count is known at compile time and unroll partially
2767 /// if the trip count is not known. Specifying unroll(full) is similar to
2768 /// unroll(enable) but will unroll the loop only if the trip count is known at
2769 /// compile time. Specifying unroll(disable) disables unrolling for the
2770 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2771 /// loop the number of times indicated by the value.
2772 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2773  PragmaIntroducerKind Introducer,
2774  Token &Tok) {
2775  // Incoming token is "loop" from "#pragma clang loop".
2776  Token PragmaName = Tok;
2777  SmallVector<Token, 1> TokenList;
2778 
2779  // Lex the optimization option and verify it is an identifier.
2780  PP.Lex(Tok);
2781  if (Tok.isNot(tok::identifier)) {
2782  PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2783  << /*MissingOption=*/true << "";
2784  return;
2785  }
2786 
2787  while (Tok.is(tok::identifier)) {
2788  Token Option = Tok;
2789  IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2790 
2791  bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2792  .Case("vectorize", true)
2793  .Case("interleave", true)
2794  .Case("unroll", true)
2795  .Case("distribute", true)
2796  .Case("vectorize_width", true)
2797  .Case("interleave_count", true)
2798  .Case("unroll_count", true)
2799  .Default(false);
2800  if (!OptionValid) {
2801  PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2802  << /*MissingOption=*/false << OptionInfo;
2803  return;
2804  }
2805  PP.Lex(Tok);
2806 
2807  // Read '('
2808  if (Tok.isNot(tok::l_paren)) {
2809  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2810  return;
2811  }
2812  PP.Lex(Tok);
2813 
2814  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2815  if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2816  *Info))
2817  return;
2818 
2819  // Generate the loop hint token.
2820  Token LoopHintTok;
2821  LoopHintTok.startToken();
2822  LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2823  LoopHintTok.setLocation(PragmaName.getLocation());
2824  LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2825  LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2826  TokenList.push_back(LoopHintTok);
2827  }
2828 
2829  if (Tok.isNot(tok::eod)) {
2830  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2831  << "clang loop";
2832  return;
2833  }
2834 
2835  auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2836  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2837 
2838  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2839  /*DisableMacroExpansion=*/false);
2840 }
2841 
2842 /// Handle the loop unroll optimization pragmas.
2843 /// #pragma unroll
2844 /// #pragma unroll unroll-hint-value
2845 /// #pragma unroll '(' unroll-hint-value ')'
2846 /// #pragma nounroll
2847 ///
2848 /// unroll-hint-value:
2849 /// constant-expression
2850 ///
2851 /// Loop unrolling hints can be specified with '#pragma unroll' or
2852 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2853 /// contained in parentheses. With no argument the directive instructs llvm to
2854 /// try to unroll the loop completely. A positive integer argument can be
2855 /// specified to indicate the number of times the loop should be unrolled. To
2856 /// maximize compatibility with other compilers the unroll count argument can be
2857 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2858 /// disables unrolling of the loop.
2859 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2860  PragmaIntroducerKind Introducer,
2861  Token &Tok) {
2862  // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2863  // "#pragma nounroll".
2864  Token PragmaName = Tok;
2865  PP.Lex(Tok);
2866  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2867  if (Tok.is(tok::eod)) {
2868  // nounroll or unroll pragma without an argument.
2869  Info->PragmaName = PragmaName;
2870  Info->Option.startToken();
2871  } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2872  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2873  << "nounroll";
2874  return;
2875  } else {
2876  // Unroll pragma with an argument: "#pragma unroll N" or
2877  // "#pragma unroll(N)".
2878  // Read '(' if it exists.
2879  bool ValueInParens = Tok.is(tok::l_paren);
2880  if (ValueInParens)
2881  PP.Lex(Tok);
2882 
2883  Token Option;
2884  Option.startToken();
2885  if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2886  return;
2887 
2888  // In CUDA, the argument to '#pragma unroll' should not be contained in
2889  // parentheses.
2890  if (PP.getLangOpts().CUDA && ValueInParens)
2891  PP.Diag(Info->Toks[0].getLocation(),
2892  diag::warn_pragma_unroll_cuda_value_in_parens);
2893 
2894  if (Tok.isNot(tok::eod)) {
2895  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2896  << "unroll";
2897  return;
2898  }
2899  }
2900 
2901  // Generate the hint token.
2902  auto TokenArray = llvm::make_unique<Token[]>(1);
2903  TokenArray[0].startToken();
2904  TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2905  TokenArray[0].setLocation(PragmaName.getLocation());
2906  TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2907  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2908  PP.EnterTokenStream(std::move(TokenArray), 1,
2909  /*DisableMacroExpansion=*/false);
2910 }
2911 
2912 /// Handle the Microsoft \#pragma intrinsic extension.
2913 ///
2914 /// The syntax is:
2915 /// \code
2916 /// #pragma intrinsic(memset)
2917 /// #pragma intrinsic(strlen, memcpy)
2918 /// \endcode
2919 ///
2920 /// Pragma intrisic tells the compiler to use a builtin version of the
2921 /// function. Clang does it anyway, so the pragma doesn't really do anything.
2922 /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
2923 /// isn't an intrinsic in clang and suggest to include intrin.h.
2924 void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
2925  PragmaIntroducerKind Introducer,
2926  Token &Tok) {
2927  PP.Lex(Tok);
2928 
2929  if (Tok.isNot(tok::l_paren)) {
2930  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
2931  << "intrinsic";
2932  return;
2933  }
2934  PP.Lex(Tok);
2935 
2936  bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
2937 
2938  while (Tok.is(tok::identifier)) {
2939  IdentifierInfo *II = Tok.getIdentifierInfo();
2940  if (!II->getBuiltinID())
2941  PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
2942  << II << SuggestIntrinH;
2943 
2944  PP.Lex(Tok);
2945  if (Tok.isNot(tok::comma))
2946  break;
2947  PP.Lex(Tok);
2948  }
2949 
2950  if (Tok.isNot(tok::r_paren)) {
2951  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
2952  << "intrinsic";
2953  return;
2954  }
2955  PP.Lex(Tok);
2956 
2957  if (Tok.isNot(tok::eod))
2958  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2959  << "intrinsic";
2960 }
2961 
2962 // #pragma optimize("gsty", on|off)
2963 void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
2964  PragmaIntroducerKind Introducer,
2965  Token &Tok) {
2966  SourceLocation StartLoc = Tok.getLocation();
2967  PP.Lex(Tok);
2968 
2969  if (Tok.isNot(tok::l_paren)) {
2970  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
2971  return;
2972  }
2973  PP.Lex(Tok);
2974 
2975  if (Tok.isNot(tok::string_literal)) {
2976  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
2977  return;
2978  }
2979  // We could syntax check the string but it's probably not worth the effort.
2980  PP.Lex(Tok);
2981 
2982  if (Tok.isNot(tok::comma)) {
2983  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
2984  return;
2985  }
2986  PP.Lex(Tok);
2987 
2988  if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
2989  PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
2990  << "optimize" << /*Expected=*/true << "'on' or 'off'";
2991  return;
2992  }
2993  IdentifierInfo *II = Tok.getIdentifierInfo();
2994  if (!II || (!II->isStr("on") && !II->isStr("off"))) {
2995  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
2996  << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
2997  << "'on' or 'off'";
2998  return;
2999  }
3000  PP.Lex(Tok);
3001 
3002  if (Tok.isNot(tok::r_paren)) {
3003  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
3004  return;
3005  }
3006  PP.Lex(Tok);
3007 
3008  if (Tok.isNot(tok::eod)) {
3009  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3010  << "optimize";
3011  return;
3012  }
3013  PP.Diag(StartLoc, diag::warn_pragma_optimize);
3014 }
3015 
3016 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3017  Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
3018  Token FirstTok = Tok;
3019 
3020  PP.Lex(Tok);
3021  IdentifierInfo *Info = Tok.getIdentifierInfo();
3022  if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
3023  PP.Diag(FirstTok.getLocation(),
3024  diag::warn_pragma_force_cuda_host_device_bad_arg);
3025  return;
3026  }
3027 
3028  if (Info->isStr("begin"))
3029  Actions.PushForceCUDAHostDevice();
3030  else if (!Actions.PopForceCUDAHostDevice())
3031  PP.Diag(FirstTok.getLocation(),
3032  diag::err_pragma_cannot_end_force_cuda_host_device);
3033 
3034  PP.Lex(Tok);
3035  if (!Tok.is(tok::eod))
3036  PP.Diag(FirstTok.getLocation(),
3037  diag::warn_pragma_force_cuda_host_device_bad_arg);
3038 }
3039 
3040 /// Handle the #pragma clang attribute directive.
3041 ///
3042 /// The syntax is:
3043 /// \code
3044 /// #pragma clang attribute push(attribute, subject-set)
3045 /// #pragma clang attribute pop
3046 /// \endcode
3047 ///
3048 /// The subject-set clause defines the set of declarations which receive the
3049 /// attribute. Its exact syntax is described in the LanguageExtensions document
3050 /// in Clang's documentation.
3051 ///
3052 /// This directive instructs the compiler to begin/finish applying the specified
3053 /// attribute to the set of attribute-specific declarations in the active range
3054 /// of the pragma.
3055 void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3056  PragmaIntroducerKind Introducer,
3057  Token &FirstToken) {
3058  Token Tok;
3059  PP.Lex(Tok);
3060  auto *Info = new (PP.getPreprocessorAllocator())
3061  PragmaAttributeInfo(AttributesForPragmaAttribute);
3062 
3063  // Parse the 'push' or 'pop'.
3064  if (Tok.isNot(tok::identifier)) {
3065  PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop);
3066  return;
3067  }
3068  const auto *II = Tok.getIdentifierInfo();
3069  if (II->isStr("push"))
3070  Info->Action = PragmaAttributeInfo::Push;
3071  else if (II->isStr("pop"))
3072  Info->Action = PragmaAttributeInfo::Pop;
3073  else {
3074  PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
3075  << PP.getSpelling(Tok);
3076  return;
3077  }
3078  PP.Lex(Tok);
3079 
3080  // Parse the actual attribute.
3081  if (Info->Action == PragmaAttributeInfo::Push) {
3082  if (Tok.isNot(tok::l_paren)) {
3083  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3084  return;
3085  }
3086  PP.Lex(Tok);
3087 
3088  // Lex the attribute tokens.
3089  SmallVector<Token, 16> AttributeTokens;
3090  int OpenParens = 1;
3091  while (Tok.isNot(tok::eod)) {
3092  if (Tok.is(tok::l_paren))
3093  OpenParens++;
3094  else if (Tok.is(tok::r_paren)) {
3095  OpenParens--;
3096  if (OpenParens == 0)
3097  break;
3098  }
3099 
3100  AttributeTokens.push_back(Tok);
3101  PP.Lex(Tok);
3102  }
3103 
3104  if (AttributeTokens.empty()) {
3105  PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
3106  return;
3107  }
3108  if (Tok.isNot(tok::r_paren)) {
3109  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3110  return;
3111  }
3112  SourceLocation EndLoc = Tok.getLocation();
3113  PP.Lex(Tok);
3114 
3115  // Terminate the attribute for parsing.
3116  Token EOFTok;
3117  EOFTok.startToken();
3118  EOFTok.setKind(tok::eof);
3119  EOFTok.setLocation(EndLoc);
3120  AttributeTokens.push_back(EOFTok);
3121 
3122  Info->Tokens =
3123  llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
3124  }
3125 
3126  if (Tok.isNot(tok::eod))
3127  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3128  << "clang attribute";
3129 
3130  // Generate the annotated pragma token.
3131  auto TokenArray = llvm::make_unique<Token[]>(1);
3132  TokenArray[0].startToken();
3133  TokenArray[0].setKind(tok::annot_pragma_attribute);
3134  TokenArray[0].setLocation(FirstToken.getLocation());
3135  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
3136  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3137  PP.EnterTokenStream(std::move(TokenArray), 1,
3138  /*DisableMacroExpansion=*/false);
3139 }
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:833
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
SourceLocation getEndOfPreviousToken()
Definition: Parser.h:450
SizeType size() const
Definition: ParsedAttr.h:727
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
Definition: Pragma.cpp:882
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:941
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:8312
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:57
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
Definition: ParsedAttr.cpp:29
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
attribute((...))
Definition: ParsedAttr.h:110
Parse and apply any fixits to the source.
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:1039
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
LineState State
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Definition: ParsedAttr.cpp:196
const TargetInfo & getTargetInfo() const
Definition: Preprocessor.h:822
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:1667
const LangOptions & getLangOpts() const
Definition: Preprocessor.h:821
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:1666
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
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:277
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
Kind getKind() const
Definition: ParsedAttr.h:423
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:365
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:917
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:359
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
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:105
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
Definition: ParsedAttr.h:822
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:926
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:2249
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
Definition: ParsedAttr.h:363
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:382
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:73
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp: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
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...
Definition: ParsedAttr.h:552
DiagnosticsEngine & getDiagnostics() const
Definition: Preprocessor.h:818
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:1585
Defines the clang::TargetInfo interface.
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:221
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.
Definition: ParsedAttr.h:803
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
Stop skipping at specified token, but don&#39;t skip the token itself.
Definition: Parser.h:1021
SourceLocation getEndLoc() const
Definition: Token.h:151