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