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