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