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