clang  8.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 StateOption = false;
1061  if (OptionInfo) { // Pragma Unroll does not specify an option.
1062  OptionUnroll = OptionInfo->isStr("unroll");
1063  OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
1064  OptionDistribute = OptionInfo->isStr("distribute");
1065  StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1066  .Case("vectorize", true)
1067  .Case("interleave", true)
1068  .Default(false) ||
1069  OptionUnroll || OptionUnrollAndJam || OptionDistribute;
1070  }
1071 
1072  bool AssumeSafetyArg =
1073  !OptionUnroll && !OptionUnrollAndJam && !OptionDistribute;
1074  // Verify loop hint has an argument.
1075  if (Toks[0].is(tok::eof)) {
1076  ConsumeAnnotationToken();
1077  Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1078  << /*StateArgument=*/StateOption
1079  << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1080  << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1081  return false;
1082  }
1083 
1084  // Validate the argument.
1085  if (StateOption) {
1086  ConsumeAnnotationToken();
1087  SourceLocation StateLoc = Toks[0].getLocation();
1088  IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1089 
1090  bool Valid =
1091  StateInfo && llvm::StringSwitch<bool>(StateInfo->getName())
1092  .Cases("enable", "disable", true)
1093  .Case("full", OptionUnroll || OptionUnrollAndJam)
1094  .Case("assume_safety", AssumeSafetyArg)
1095  .Default(false);
1096  if (!Valid) {
1097  Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1098  << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1099  << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1100  return false;
1101  }
1102  if (Toks.size() > 2)
1103  Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1104  << PragmaLoopHintString(Info->PragmaName, Info->Option);
1105  Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1106  } else {
1107  // Enter constant expression including eof terminator into token stream.
1108  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false);
1109  ConsumeAnnotationToken();
1110 
1111  ExprResult R = ParseConstantExpression();
1112 
1113  // Tokens following an error in an ill-formed constant expression will
1114  // remain in the token stream and must be removed.
1115  if (Tok.isNot(tok::eof)) {
1116  Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1117  << PragmaLoopHintString(Info->PragmaName, Info->Option);
1118  while (Tok.isNot(tok::eof))
1119  ConsumeAnyToken();
1120  }
1121 
1122  ConsumeToken(); // Consume the constant expression eof terminator.
1123 
1124  if (R.isInvalid() ||
1125  Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
1126  return false;
1127 
1128  // Argument is a constant expression with an integer type.
1129  Hint.ValueExpr = R.get();
1130  }
1131 
1132  Hint.Range = SourceRange(Info->PragmaName.getLocation(),
1133  Info->Toks.back().getLocation());
1134  return true;
1135 }
1136 
1137 namespace {
1138 struct PragmaAttributeInfo {
1139  enum ActionType { Push, Pop, Attribute };
1140  ParsedAttributes &Attributes;
1141  ActionType Action;
1142  ArrayRef<Token> Tokens;
1143 
1144  PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1145 };
1146 
1147 #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1148 
1149 } // end anonymous namespace
1150 
1151 static StringRef getIdentifier(const Token &Tok) {
1152  if (Tok.is(tok::identifier))
1153  return Tok.getIdentifierInfo()->getName();
1154  const char *S = tok::getKeywordSpelling(Tok.getKind());
1155  if (!S)
1156  return "";
1157  return S;
1158 }
1159 
1161  using namespace attr;
1162  switch (Rule) {
1163 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1164  case Value: \
1165  return IsAbstract;
1166 #include "clang/Basic/AttrSubMatchRulesList.inc"
1167  }
1168  llvm_unreachable("Invalid attribute subject match rule");
1169  return false;
1170 }
1171 
1173  Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1174  SourceLocation SubRuleLoc) {
1175  auto Diagnostic =
1176  PRef.Diag(SubRuleLoc,
1177  diag::err_pragma_attribute_expected_subject_sub_identifier)
1178  << PrimaryRuleName;
1179  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1180  Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1181  else
1182  Diagnostic << /*SubRulesSupported=*/0;
1183 }
1184 
1186  Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1187  StringRef SubRuleName, SourceLocation SubRuleLoc) {
1188 
1189  auto Diagnostic =
1190  PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1191  << SubRuleName << PrimaryRuleName;
1192  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1193  Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1194  else
1195  Diagnostic << /*SubRulesSupported=*/0;
1196 }
1197 
1198 bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1199  attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
1200  SourceLocation &LastMatchRuleEndLoc) {
1201  bool IsAny = false;
1202  BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
1203  if (getIdentifier(Tok) == "any") {
1204  AnyLoc = ConsumeToken();
1205  IsAny = true;
1206  if (AnyParens.expectAndConsume())
1207  return true;
1208  }
1209 
1210  do {
1211  // Parse the subject matcher rule.
1212  StringRef Name = getIdentifier(Tok);
1213  if (Name.empty()) {
1214  Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1215  return true;
1216  }
1217  std::pair<Optional<attr::SubjectMatchRule>,
1218  Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
1219  Rule = isAttributeSubjectMatchRule(Name);
1220  if (!Rule.first) {
1221  Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1222  return true;
1223  }
1224  attr::SubjectMatchRule PrimaryRule = *Rule.first;
1225  SourceLocation RuleLoc = ConsumeToken();
1226 
1227  BalancedDelimiterTracker Parens(*this, tok::l_paren);
1228  if (isAbstractAttrMatcherRule(PrimaryRule)) {
1229  if (Parens.expectAndConsume())
1230  return true;
1231  } else if (Parens.consumeOpen()) {
1232  if (!SubjectMatchRules
1233  .insert(
1234  std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1235  .second)
1236  Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1237  << Name
1239  RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1240  LastMatchRuleEndLoc = RuleLoc;
1241  continue;
1242  }
1243 
1244  // Parse the sub-rules.
1245  StringRef SubRuleName = getIdentifier(Tok);
1246  if (SubRuleName.empty()) {
1247  diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1248  Tok.getLocation());
1249  return true;
1250  }
1251  attr::SubjectMatchRule SubRule;
1252  if (SubRuleName == "unless") {
1253  SourceLocation SubRuleLoc = ConsumeToken();
1254  BalancedDelimiterTracker Parens(*this, tok::l_paren);
1255  if (Parens.expectAndConsume())
1256  return true;
1257  SubRuleName = getIdentifier(Tok);
1258  if (SubRuleName.empty()) {
1259  diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1260  SubRuleLoc);
1261  return true;
1262  }
1263  auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
1264  if (!SubRuleOrNone) {
1265  std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1266  diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1267  SubRuleUnlessName, SubRuleLoc);
1268  return true;
1269  }
1270  SubRule = *SubRuleOrNone;
1271  ConsumeToken();
1272  if (Parens.consumeClose())
1273  return true;
1274  } else {
1275  auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
1276  if (!SubRuleOrNone) {
1277  diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1278  SubRuleName, Tok.getLocation());
1279  return true;
1280  }
1281  SubRule = *SubRuleOrNone;
1282  ConsumeToken();
1283  }
1284  SourceLocation RuleEndLoc = Tok.getLocation();
1285  LastMatchRuleEndLoc = RuleEndLoc;
1286  if (Parens.consumeClose())
1287  return true;
1288  if (!SubjectMatchRules
1289  .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1290  .second) {
1291  Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1294  RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1295  continue;
1296  }
1297  } while (IsAny && TryConsumeToken(tok::comma));
1298 
1299  if (IsAny)
1300  if (AnyParens.consumeClose())
1301  return true;
1302 
1303  return false;
1304 }
1305 
1306 namespace {
1307 
1308 /// Describes the stage at which attribute subject rule parsing was interrupted.
1310  Comma,
1311  ApplyTo,
1312  Equals,
1313  Any,
1314  None,
1315 };
1316 
1318 getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1319  if (const auto *II = Tok.getIdentifierInfo()) {
1320  if (II->isStr("apply_to"))
1321  return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1322  if (II->isStr("any"))
1323  return MissingAttributeSubjectRulesRecoveryPoint::Any;
1324  }
1325  if (Tok.is(tok::equal))
1326  return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1328 }
1329 
1330 /// Creates a diagnostic for the attribute subject rule parsing diagnostic that
1331 /// suggests the possible attribute subject rules in a fix-it together with
1332 /// any other missing tokens.
1333 DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1334  unsigned DiagID, ParsedAttr &Attribute,
1337  if (Loc.isInvalid())
1338  Loc = PRef.getCurToken().getLocation();
1339  auto Diagnostic = PRef.Diag(Loc, DiagID);
1340  std::string FixIt;
1342  getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1344  FixIt = ", ";
1345  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1346  EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1347  FixIt += "apply_to";
1348  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1349  EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1350  FixIt += " = ";
1351  SourceRange FixItRange(Loc);
1353  // Gather the subject match rules that are supported by the attribute.
1355  Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
1356  if (SubjectMatchRuleSet.empty()) {
1357  // FIXME: We can emit a "fix-it" with a subject list placeholder when
1358  // placeholders will be supported by the fix-its.
1359  return Diagnostic;
1360  }
1361  FixIt += "any(";
1362  bool NeedsComma = false;
1363  for (const auto &I : SubjectMatchRuleSet) {
1364  // Ensure that the missing rule is reported in the fix-it only when it's
1365  // supported in the current language mode.
1366  if (!I.second)
1367  continue;
1368  if (NeedsComma)
1369  FixIt += ", ";
1370  else
1371  NeedsComma = true;
1372  FixIt += attr::getSubjectMatchRuleSpelling(I.first);
1373  }
1374  FixIt += ")";
1375  // Check if we need to remove the range
1377  FixItRange.setEnd(PRef.getCurToken().getLocation());
1378  }
1379  if (FixItRange.getBegin() == FixItRange.getEnd())
1381  else
1383  CharSourceRange::getCharRange(FixItRange), FixIt);
1384  return Diagnostic;
1385 }
1386 
1387 } // end anonymous namespace
1388 
1389 void Parser::HandlePragmaAttribute() {
1390  assert(Tok.is(tok::annot_pragma_attribute) &&
1391  "Expected #pragma attribute annotation token");
1392  SourceLocation PragmaLoc = Tok.getLocation();
1393  auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1394  if (Info->Action == PragmaAttributeInfo::Pop) {
1395  ConsumeAnnotationToken();
1396  Actions.ActOnPragmaAttributePop(PragmaLoc);
1397  return;
1398  }
1399  // Parse the actual attribute with its arguments.
1400  assert((Info->Action == PragmaAttributeInfo::Push ||
1401  Info->Action == PragmaAttributeInfo::Attribute) &&
1402  "Unexpected #pragma attribute command");
1403 
1404  if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1405  ConsumeAnnotationToken();
1406  Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
1407  return;
1408  }
1409 
1410  PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
1411  ConsumeAnnotationToken();
1412 
1413  ParsedAttributes &Attrs = Info->Attributes;
1414  Attrs.clearListOnly();
1415 
1416  auto SkipToEnd = [this]() {
1417  SkipUntil(tok::eof, StopBeforeMatch);
1418  ConsumeToken();
1419  };
1420 
1421  if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
1422  // Parse the CXX11 style attribute.
1423  ParseCXX11AttributeSpecifier(Attrs);
1424  } else if (Tok.is(tok::kw___attribute)) {
1425  ConsumeToken();
1426  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1427  "attribute"))
1428  return SkipToEnd();
1429  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1430  return SkipToEnd();
1431 
1432  if (Tok.isNot(tok::identifier)) {
1433  Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1434  SkipToEnd();
1435  return;
1436  }
1437  IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1438  SourceLocation AttrNameLoc = ConsumeToken();
1439 
1440  if (Tok.isNot(tok::l_paren))
1441  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1443  else
1444  ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
1445  /*ScopeName=*/nullptr,
1446  /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
1447  /*Declarator=*/nullptr);
1448 
1449  if (ExpectAndConsume(tok::r_paren))
1450  return SkipToEnd();
1451  if (ExpectAndConsume(tok::r_paren))
1452  return SkipToEnd();
1453  } else if (Tok.is(tok::kw___declspec)) {
1454  ParseMicrosoftDeclSpecs(Attrs);
1455  } else {
1456  Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1457  if (Tok.getIdentifierInfo()) {
1458  // If we suspect that this is an attribute suggest the use of
1459  // '__attribute__'.
1460  if (ParsedAttr::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1461  ParsedAttr::AS_GNU) !=
1463  SourceLocation InsertStartLoc = Tok.getLocation();
1464  ConsumeToken();
1465  if (Tok.is(tok::l_paren)) {
1466  ConsumeAnyToken();
1467  SkipUntil(tok::r_paren, StopBeforeMatch);
1468  if (Tok.isNot(tok::r_paren))
1469  return SkipToEnd();
1470  }
1471  Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1472  << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1473  << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1474  }
1475  }
1476  SkipToEnd();
1477  return;
1478  }
1479 
1480  if (Attrs.empty() || Attrs.begin()->isInvalid()) {
1481  SkipToEnd();
1482  return;
1483  }
1484 
1485  // Ensure that we don't have more than one attribute.
1486  if (Attrs.size() > 1) {
1487  SourceLocation Loc = Attrs[1].getLoc();
1488  Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1489  SkipToEnd();
1490  return;
1491  }
1492 
1493  ParsedAttr &Attribute = *Attrs.begin();
1494  if (!Attribute.isSupportedByPragmaAttribute()) {
1495  Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1496  << Attribute.getName();
1497  SkipToEnd();
1498  return;
1499  }
1500 
1501  // Parse the subject-list.
1502  if (!TryConsumeToken(tok::comma)) {
1503  createExpectedAttributeSubjectRulesTokenDiagnostic(
1504  diag::err_expected, Attribute,
1506  << tok::comma;
1507  SkipToEnd();
1508  return;
1509  }
1510 
1511  if (Tok.isNot(tok::identifier)) {
1512  createExpectedAttributeSubjectRulesTokenDiagnostic(
1513  diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1514  MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1515  SkipToEnd();
1516  return;
1517  }
1518  const IdentifierInfo *II = Tok.getIdentifierInfo();
1519  if (!II->isStr("apply_to")) {
1520  createExpectedAttributeSubjectRulesTokenDiagnostic(
1521  diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1522  MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1523  SkipToEnd();
1524  return;
1525  }
1526  ConsumeToken();
1527 
1528  if (!TryConsumeToken(tok::equal)) {
1529  createExpectedAttributeSubjectRulesTokenDiagnostic(
1530  diag::err_expected, Attribute,
1531  MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1532  << tok::equal;
1533  SkipToEnd();
1534  return;
1535  }
1536 
1537  attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1538  SourceLocation AnyLoc, LastMatchRuleEndLoc;
1539  if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1540  LastMatchRuleEndLoc)) {
1541  SkipToEnd();
1542  return;
1543  }
1544 
1545  // Tokens following an ill-formed attribute will remain in the token stream
1546  // and must be removed.
1547  if (Tok.isNot(tok::eof)) {
1548  Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1549  SkipToEnd();
1550  return;
1551  }
1552 
1553  // Consume the eof terminator token.
1554  ConsumeToken();
1555 
1556  // Handle a mixed push/attribute by desurging to a push, then an attribute.
1557  if (Info->Action == PragmaAttributeInfo::Push)
1558  Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc);
1559 
1560  Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1561  std::move(SubjectMatchRules));
1562 }
1563 
1564 // #pragma GCC visibility comes in two variants:
1565 // 'push' '(' [visibility] ')'
1566 // 'pop'
1567 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1568  PragmaIntroducerKind Introducer,
1569  Token &VisTok) {
1570  SourceLocation VisLoc = VisTok.getLocation();
1571 
1572  Token Tok;
1573  PP.LexUnexpandedToken(Tok);
1574 
1575  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1576 
1577  const IdentifierInfo *VisType;
1578  if (PushPop && PushPop->isStr("pop")) {
1579  VisType = nullptr;
1580  } else if (PushPop && PushPop->isStr("push")) {
1581  PP.LexUnexpandedToken(Tok);
1582  if (Tok.isNot(tok::l_paren)) {
1583  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1584  << "visibility";
1585  return;
1586  }
1587  PP.LexUnexpandedToken(Tok);
1588  VisType = Tok.getIdentifierInfo();
1589  if (!VisType) {
1590  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1591  << "visibility";
1592  return;
1593  }
1594  PP.LexUnexpandedToken(Tok);
1595  if (Tok.isNot(tok::r_paren)) {
1596  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1597  << "visibility";
1598  return;
1599  }
1600  } else {
1601  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1602  << "visibility";
1603  return;
1604  }
1605  SourceLocation EndLoc = Tok.getLocation();
1606  PP.LexUnexpandedToken(Tok);
1607  if (Tok.isNot(tok::eod)) {
1608  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1609  << "visibility";
1610  return;
1611  }
1612 
1613  auto Toks = llvm::make_unique<Token[]>(1);
1614  Toks[0].startToken();
1615  Toks[0].setKind(tok::annot_pragma_vis);
1616  Toks[0].setLocation(VisLoc);
1617  Toks[0].setAnnotationEndLoc(EndLoc);
1618  Toks[0].setAnnotationValue(
1619  const_cast<void*>(static_cast<const void*>(VisType)));
1620  PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true);
1621 }
1622 
1623 // #pragma pack(...) comes in the following delicious flavors:
1624 // pack '(' [integer] ')'
1625 // pack '(' 'show' ')'
1626 // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1627 void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1628  PragmaIntroducerKind Introducer,
1629  Token &PackTok) {
1630  SourceLocation PackLoc = PackTok.getLocation();
1631 
1632  Token Tok;
1633  PP.Lex(Tok);
1634  if (Tok.isNot(tok::l_paren)) {
1635  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1636  return;
1637  }
1638 
1640  StringRef SlotLabel;
1641  Token Alignment;
1642  Alignment.startToken();
1643  PP.Lex(Tok);
1644  if (Tok.is(tok::numeric_constant)) {
1645  Alignment = Tok;
1646 
1647  PP.Lex(Tok);
1648 
1649  // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1650  // the push/pop stack.
1651  // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1652  Action =
1653  PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1654  } else if (Tok.is(tok::identifier)) {
1655  const IdentifierInfo *II = Tok.getIdentifierInfo();
1656  if (II->isStr("show")) {
1657  Action = Sema::PSK_Show;
1658  PP.Lex(Tok);
1659  } else {
1660  if (II->isStr("push")) {
1661  Action = Sema::PSK_Push;
1662  } else if (II->isStr("pop")) {
1663  Action = Sema::PSK_Pop;
1664  } else {
1665  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1666  return;
1667  }
1668  PP.Lex(Tok);
1669 
1670  if (Tok.is(tok::comma)) {
1671  PP.Lex(Tok);
1672 
1673  if (Tok.is(tok::numeric_constant)) {
1674  Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1675  Alignment = Tok;
1676 
1677  PP.Lex(Tok);
1678  } else if (Tok.is(tok::identifier)) {
1679  SlotLabel = Tok.getIdentifierInfo()->getName();
1680  PP.Lex(Tok);
1681 
1682  if (Tok.is(tok::comma)) {
1683  PP.Lex(Tok);
1684 
1685  if (Tok.isNot(tok::numeric_constant)) {
1686  PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1687  return;
1688  }
1689 
1690  Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1691  Alignment = Tok;
1692 
1693  PP.Lex(Tok);
1694  }
1695  } else {
1696  PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1697  return;
1698  }
1699  }
1700  }
1701  } else if (PP.getLangOpts().ApplePragmaPack) {
1702  // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1703  // the push/pop stack.
1704  // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1705  Action = Sema::PSK_Pop;
1706  }
1707 
1708  if (Tok.isNot(tok::r_paren)) {
1709  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1710  return;
1711  }
1712 
1713  SourceLocation RParenLoc = Tok.getLocation();
1714  PP.Lex(Tok);
1715  if (Tok.isNot(tok::eod)) {
1716  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1717  return;
1718  }
1719 
1720  PragmaPackInfo *Info =
1721  PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1722  Info->Action = Action;
1723  Info->SlotLabel = SlotLabel;
1724  Info->Alignment = Alignment;
1725 
1726  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1727  1);
1728  Toks[0].startToken();
1729  Toks[0].setKind(tok::annot_pragma_pack);
1730  Toks[0].setLocation(PackLoc);
1731  Toks[0].setAnnotationEndLoc(RParenLoc);
1732  Toks[0].setAnnotationValue(static_cast<void*>(Info));
1733  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1734 }
1735 
1736 // #pragma ms_struct on
1737 // #pragma ms_struct off
1738 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1739  PragmaIntroducerKind Introducer,
1740  Token &MSStructTok) {
1742 
1743  Token Tok;
1744  PP.Lex(Tok);
1745  if (Tok.isNot(tok::identifier)) {
1746  PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1747  return;
1748  }
1749  SourceLocation EndLoc = Tok.getLocation();
1750  const IdentifierInfo *II = Tok.getIdentifierInfo();
1751  if (II->isStr("on")) {
1752  Kind = PMSST_ON;
1753  PP.Lex(Tok);
1754  }
1755  else if (II->isStr("off") || II->isStr("reset"))
1756  PP.Lex(Tok);
1757  else {
1758  PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1759  return;
1760  }
1761 
1762  if (Tok.isNot(tok::eod)) {
1763  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1764  << "ms_struct";
1765  return;
1766  }
1767 
1768  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1769  1);
1770  Toks[0].startToken();
1771  Toks[0].setKind(tok::annot_pragma_msstruct);
1772  Toks[0].setLocation(MSStructTok.getLocation());
1773  Toks[0].setAnnotationEndLoc(EndLoc);
1774  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1775  static_cast<uintptr_t>(Kind)));
1776  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1777 }
1778 
1779 // #pragma clang section bss="abc" data="" rodata="def" text=""
1780 void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
1781  PragmaIntroducerKind Introducer, Token &FirstToken) {
1782 
1783  Token Tok;
1784  auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1785 
1786  PP.Lex(Tok); // eat 'section'
1787  while (Tok.isNot(tok::eod)) {
1788  if (Tok.isNot(tok::identifier)) {
1789  PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1790  return;
1791  }
1792 
1793  const IdentifierInfo *SecType = Tok.getIdentifierInfo();
1794  if (SecType->isStr("bss"))
1795  SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1796  else if (SecType->isStr("data"))
1797  SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1798  else if (SecType->isStr("rodata"))
1799  SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1800  else if (SecType->isStr("text"))
1801  SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1802  else {
1803  PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1804  return;
1805  }
1806 
1807  PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
1808  if (Tok.isNot(tok::equal)) {
1809  PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1810  return;
1811  }
1812 
1813  std::string SecName;
1814  if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
1815  return;
1816 
1817  Actions.ActOnPragmaClangSection(Tok.getLocation(),
1818  (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1819  Sema::PragmaClangSectionAction::PCSA_Clear),
1820  SecKind, SecName);
1821  }
1822 }
1823 
1824 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1825 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1826 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1827  bool IsOptions) {
1828  Token Tok;
1829 
1830  if (IsOptions) {
1831  PP.Lex(Tok);
1832  if (Tok.isNot(tok::identifier) ||
1833  !Tok.getIdentifierInfo()->isStr("align")) {
1834  PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1835  return;
1836  }
1837  }
1838 
1839  PP.Lex(Tok);
1840  if (Tok.isNot(tok::equal)) {
1841  PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1842  << IsOptions;
1843  return;
1844  }
1845 
1846  PP.Lex(Tok);
1847  if (Tok.isNot(tok::identifier)) {
1848  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1849  << (IsOptions ? "options" : "align");
1850  return;
1851  }
1852 
1854  const IdentifierInfo *II = Tok.getIdentifierInfo();
1855  if (II->isStr("native"))
1856  Kind = Sema::POAK_Native;
1857  else if (II->isStr("natural"))
1858  Kind = Sema::POAK_Natural;
1859  else if (II->isStr("packed"))
1860  Kind = Sema::POAK_Packed;
1861  else if (II->isStr("power"))
1862  Kind = Sema::POAK_Power;
1863  else if (II->isStr("mac68k"))
1864  Kind = Sema::POAK_Mac68k;
1865  else if (II->isStr("reset"))
1866  Kind = Sema::POAK_Reset;
1867  else {
1868  PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1869  << IsOptions;
1870  return;
1871  }
1872 
1873  SourceLocation EndLoc = Tok.getLocation();
1874  PP.Lex(Tok);
1875  if (Tok.isNot(tok::eod)) {
1876  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1877  << (IsOptions ? "options" : "align");
1878  return;
1879  }
1880 
1881  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1882  1);
1883  Toks[0].startToken();
1884  Toks[0].setKind(tok::annot_pragma_align);
1885  Toks[0].setLocation(FirstTok.getLocation());
1886  Toks[0].setAnnotationEndLoc(EndLoc);
1887  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1888  static_cast<uintptr_t>(Kind)));
1889  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1890 }
1891 
1892 void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1893  PragmaIntroducerKind Introducer,
1894  Token &AlignTok) {
1895  ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1896 }
1897 
1898 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1899  PragmaIntroducerKind Introducer,
1900  Token &OptionsTok) {
1901  ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1902 }
1903 
1904 // #pragma unused(identifier)
1905 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1906  PragmaIntroducerKind Introducer,
1907  Token &UnusedTok) {
1908  // FIXME: Should we be expanding macros here? My guess is no.
1909  SourceLocation UnusedLoc = UnusedTok.getLocation();
1910 
1911  // Lex the left '('.
1912  Token Tok;
1913  PP.Lex(Tok);
1914  if (Tok.isNot(tok::l_paren)) {
1915  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1916  return;
1917  }
1918 
1919  // Lex the declaration reference(s).
1920  SmallVector<Token, 5> Identifiers;
1921  SourceLocation RParenLoc;
1922  bool LexID = true;
1923 
1924  while (true) {
1925  PP.Lex(Tok);
1926 
1927  if (LexID) {
1928  if (Tok.is(tok::identifier)) {
1929  Identifiers.push_back(Tok);
1930  LexID = false;
1931  continue;
1932  }
1933 
1934  // Illegal token!
1935  PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1936  return;
1937  }
1938 
1939  // We are execting a ')' or a ','.
1940  if (Tok.is(tok::comma)) {
1941  LexID = true;
1942  continue;
1943  }
1944 
1945  if (Tok.is(tok::r_paren)) {
1946  RParenLoc = Tok.getLocation();
1947  break;
1948  }
1949 
1950  // Illegal token!
1951  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1952  return;
1953  }
1954 
1955  PP.Lex(Tok);
1956  if (Tok.isNot(tok::eod)) {
1957  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1958  "unused";
1959  return;
1960  }
1961 
1962  // Verify that we have a location for the right parenthesis.
1963  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1964  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1965 
1966  // For each identifier token, insert into the token stream a
1967  // annot_pragma_unused token followed by the identifier token.
1968  // This allows us to cache a "#pragma unused" that occurs inside an inline
1969  // C++ member function.
1970 
1972  PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1973  2 * Identifiers.size());
1974  for (unsigned i=0; i != Identifiers.size(); i++) {
1975  Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1976  pragmaUnusedTok.startToken();
1977  pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1978  pragmaUnusedTok.setLocation(UnusedLoc);
1979  idTok = Identifiers[i];
1980  }
1981  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
1982 }
1983 
1984 // #pragma weak identifier
1985 // #pragma weak identifier '=' identifier
1986 void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
1987  PragmaIntroducerKind Introducer,
1988  Token &WeakTok) {
1989  SourceLocation WeakLoc = WeakTok.getLocation();
1990 
1991  Token Tok;
1992  PP.Lex(Tok);
1993  if (Tok.isNot(tok::identifier)) {
1994  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1995  return;
1996  }
1997 
1998  Token WeakName = Tok;
1999  bool HasAlias = false;
2000  Token AliasName;
2001 
2002  PP.Lex(Tok);
2003  if (Tok.is(tok::equal)) {
2004  HasAlias = true;
2005  PP.Lex(Tok);
2006  if (Tok.isNot(tok::identifier)) {
2007  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2008  << "weak";
2009  return;
2010  }
2011  AliasName = Tok;
2012  PP.Lex(Tok);
2013  }
2014 
2015  if (Tok.isNot(tok::eod)) {
2016  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
2017  return;
2018  }
2019 
2020  if (HasAlias) {
2022  PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
2023  Token &pragmaUnusedTok = Toks[0];
2024  pragmaUnusedTok.startToken();
2025  pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
2026  pragmaUnusedTok.setLocation(WeakLoc);
2027  pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
2028  Toks[1] = WeakName;
2029  Toks[2] = AliasName;
2030  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2031  } else {
2033  PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
2034  Token &pragmaUnusedTok = Toks[0];
2035  pragmaUnusedTok.startToken();
2036  pragmaUnusedTok.setKind(tok::annot_pragma_weak);
2037  pragmaUnusedTok.setLocation(WeakLoc);
2038  pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
2039  Toks[1] = WeakName;
2040  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2041  }
2042 }
2043 
2044 // #pragma redefine_extname identifier identifier
2045 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
2046  PragmaIntroducerKind Introducer,
2047  Token &RedefToken) {
2048  SourceLocation RedefLoc = RedefToken.getLocation();
2049 
2050  Token Tok;
2051  PP.Lex(Tok);
2052  if (Tok.isNot(tok::identifier)) {
2053  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2054  "redefine_extname";
2055  return;
2056  }
2057 
2058  Token RedefName = Tok;
2059  PP.Lex(Tok);
2060 
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 AliasName = Tok;
2068  PP.Lex(Tok);
2069 
2070  if (Tok.isNot(tok::eod)) {
2071  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2072  "redefine_extname";
2073  return;
2074  }
2075 
2076  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
2077  3);
2078  Token &pragmaRedefTok = Toks[0];
2079  pragmaRedefTok.startToken();
2080  pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2081  pragmaRedefTok.setLocation(RedefLoc);
2082  pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
2083  Toks[1] = RedefName;
2084  Toks[2] = AliasName;
2085  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2086 }
2087 
2088 
2089 void
2090 PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2091  PragmaIntroducerKind Introducer,
2092  Token &Tok) {
2093  tok::OnOffSwitch OOS;
2094  if (PP.LexOnOffSwitch(OOS))
2095  return;
2096 
2097  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2098  1);
2099  Toks[0].startToken();
2100  Toks[0].setKind(tok::annot_pragma_fp_contract);
2101  Toks[0].setLocation(Tok.getLocation());
2102  Toks[0].setAnnotationEndLoc(Tok.getLocation());
2103  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2104  static_cast<uintptr_t>(OOS)));
2105  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2106 }
2107 
2108 void
2109 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2110  PragmaIntroducerKind Introducer,
2111  Token &Tok) {
2112  PP.LexUnexpandedToken(Tok);
2113  if (Tok.isNot(tok::identifier)) {
2114  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2115  "OPENCL";
2116  return;
2117  }
2118  IdentifierInfo *Ext = Tok.getIdentifierInfo();
2119  SourceLocation NameLoc = Tok.getLocation();
2120 
2121  PP.Lex(Tok);
2122  if (Tok.isNot(tok::colon)) {
2123  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2124  return;
2125  }
2126 
2127  PP.Lex(Tok);
2128  if (Tok.isNot(tok::identifier)) {
2129  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2130  return;
2131  }
2132  IdentifierInfo *Pred = Tok.getIdentifierInfo();
2133 
2135  if (Pred->isStr("enable")) {
2136  State = Enable;
2137  } else if (Pred->isStr("disable")) {
2138  State = Disable;
2139  } else if (Pred->isStr("begin"))
2140  State = Begin;
2141  else if (Pred->isStr("end"))
2142  State = End;
2143  else {
2144  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2145  << Ext->isStr("all");
2146  return;
2147  }
2148  SourceLocation StateLoc = Tok.getLocation();
2149 
2150  PP.Lex(Tok);
2151  if (Tok.isNot(tok::eod)) {
2152  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2153  "OPENCL EXTENSION";
2154  return;
2155  }
2156 
2157  auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
2158  Info->first = Ext;
2159  Info->second = State;
2160  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2161  1);
2162  Toks[0].startToken();
2163  Toks[0].setKind(tok::annot_pragma_opencl_extension);
2164  Toks[0].setLocation(NameLoc);
2165  Toks[0].setAnnotationValue(static_cast<void*>(Info));
2166  Toks[0].setAnnotationEndLoc(StateLoc);
2167  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
2168 
2169  if (PP.getPPCallbacks())
2170  PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
2171  StateLoc, State);
2172 }
2173 
2174 /// Handle '#pragma omp ...' when OpenMP is disabled.
2175 ///
2176 void
2177 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
2178  PragmaIntroducerKind Introducer,
2179  Token &FirstTok) {
2180  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
2181  FirstTok.getLocation())) {
2182  PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
2183  PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
2185  }
2187 }
2188 
2189 /// Handle '#pragma omp ...' when OpenMP is enabled.
2190 ///
2191 void
2192 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
2193  PragmaIntroducerKind Introducer,
2194  Token &FirstTok) {
2196  Token Tok;
2197  Tok.startToken();
2198  Tok.setKind(tok::annot_pragma_openmp);
2199  Tok.setLocation(FirstTok.getLocation());
2200 
2201  while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
2202  Pragma.push_back(Tok);
2203  PP.Lex(Tok);
2204  if (Tok.is(tok::annot_pragma_openmp)) {
2205  PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2206  unsigned InnerPragmaCnt = 1;
2207  while (InnerPragmaCnt != 0) {
2208  PP.Lex(Tok);
2209  if (Tok.is(tok::annot_pragma_openmp))
2210  ++InnerPragmaCnt;
2211  else if (Tok.is(tok::annot_pragma_openmp_end))
2212  --InnerPragmaCnt;
2213  }
2214  PP.Lex(Tok);
2215  }
2216  }
2217  SourceLocation EodLoc = Tok.getLocation();
2218  Tok.startToken();
2219  Tok.setKind(tok::annot_pragma_openmp_end);
2220  Tok.setLocation(EodLoc);
2221  Pragma.push_back(Tok);
2222 
2223  auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2224  std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2225  PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2226  /*DisableMacroExpansion=*/false);
2227 }
2228 
2229 /// Handle '#pragma pointers_to_members'
2230 // The grammar for this pragma is as follows:
2231 //
2232 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2233 //
2234 // #pragma pointers_to_members '(' 'best_case' ')'
2235 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2236 // #pragma pointers_to_members '(' inheritance-model ')'
2237 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2238  PragmaIntroducerKind Introducer,
2239  Token &Tok) {
2240  SourceLocation PointersToMembersLoc = Tok.getLocation();
2241  PP.Lex(Tok);
2242  if (Tok.isNot(tok::l_paren)) {
2243  PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2244  << "pointers_to_members";
2245  return;
2246  }
2247  PP.Lex(Tok);
2248  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2249  if (!Arg) {
2250  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2251  << "pointers_to_members";
2252  return;
2253  }
2254  PP.Lex(Tok);
2255 
2256  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2257  if (Arg->isStr("best_case")) {
2258  RepresentationMethod = LangOptions::PPTMK_BestCase;
2259  } else {
2260  if (Arg->isStr("full_generality")) {
2261  if (Tok.is(tok::comma)) {
2262  PP.Lex(Tok);
2263 
2264  Arg = Tok.getIdentifierInfo();
2265  if (!Arg) {
2266  PP.Diag(Tok.getLocation(),
2267  diag::err_pragma_pointers_to_members_unknown_kind)
2268  << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2269  return;
2270  }
2271  PP.Lex(Tok);
2272  } else if (Tok.is(tok::r_paren)) {
2273  // #pragma pointers_to_members(full_generality) implicitly specifies
2274  // virtual_inheritance.
2275  Arg = nullptr;
2277  } else {
2278  PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2279  << "full_generality";
2280  return;
2281  }
2282  }
2283 
2284  if (Arg) {
2285  if (Arg->isStr("single_inheritance")) {
2286  RepresentationMethod =
2288  } else if (Arg->isStr("multiple_inheritance")) {
2289  RepresentationMethod =
2291  } else if (Arg->isStr("virtual_inheritance")) {
2292  RepresentationMethod =
2294  } else {
2295  PP.Diag(Tok.getLocation(),
2296  diag::err_pragma_pointers_to_members_unknown_kind)
2297  << Arg << /*HasPointerDeclaration*/ 1;
2298  return;
2299  }
2300  }
2301  }
2302 
2303  if (Tok.isNot(tok::r_paren)) {
2304  PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2305  << (Arg ? Arg->getName() : "full_generality");
2306  return;
2307  }
2308 
2309  SourceLocation EndLoc = Tok.getLocation();
2310  PP.Lex(Tok);
2311  if (Tok.isNot(tok::eod)) {
2312  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2313  << "pointers_to_members";
2314  return;
2315  }
2316 
2317  Token AnnotTok;
2318  AnnotTok.startToken();
2319  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2320  AnnotTok.setLocation(PointersToMembersLoc);
2321  AnnotTok.setAnnotationEndLoc(EndLoc);
2322  AnnotTok.setAnnotationValue(
2323  reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2324  PP.EnterToken(AnnotTok);
2325 }
2326 
2327 /// Handle '#pragma vtordisp'
2328 // The grammar for this pragma is as follows:
2329 //
2330 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2331 //
2332 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2333 // #pragma vtordisp '(' 'pop' ')'
2334 // #pragma vtordisp '(' ')'
2335 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2336  PragmaIntroducerKind Introducer,
2337  Token &Tok) {
2338  SourceLocation VtorDispLoc = Tok.getLocation();
2339  PP.Lex(Tok);
2340  if (Tok.isNot(tok::l_paren)) {
2341  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2342  return;
2343  }
2344  PP.Lex(Tok);
2345 
2347  const IdentifierInfo *II = Tok.getIdentifierInfo();
2348  if (II) {
2349  if (II->isStr("push")) {
2350  // #pragma vtordisp(push, mode)
2351  PP.Lex(Tok);
2352  if (Tok.isNot(tok::comma)) {
2353  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2354  return;
2355  }
2356  PP.Lex(Tok);
2357  Action = Sema::PSK_Push_Set;
2358  // not push, could be on/off
2359  } else if (II->isStr("pop")) {
2360  // #pragma vtordisp(pop)
2361  PP.Lex(Tok);
2362  Action = Sema::PSK_Pop;
2363  }
2364  // not push or pop, could be on/off
2365  } else {
2366  if (Tok.is(tok::r_paren)) {
2367  // #pragma vtordisp()
2368  Action = Sema::PSK_Reset;
2369  }
2370  }
2371 
2372 
2373  uint64_t Value = 0;
2374  if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
2375  const IdentifierInfo *II = Tok.getIdentifierInfo();
2376  if (II && II->isStr("off")) {
2377  PP.Lex(Tok);
2378  Value = 0;
2379  } else if (II && II->isStr("on")) {
2380  PP.Lex(Tok);
2381  Value = 1;
2382  } else if (Tok.is(tok::numeric_constant) &&
2383  PP.parseSimpleIntegerLiteral(Tok, Value)) {
2384  if (Value > 2) {
2385  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2386  << 0 << 2 << "vtordisp";
2387  return;
2388  }
2389  } else {
2390  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2391  << "vtordisp";
2392  return;
2393  }
2394  }
2395 
2396  // Finish the pragma: ')' $
2397  if (Tok.isNot(tok::r_paren)) {
2398  PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2399  return;
2400  }
2401  SourceLocation EndLoc = Tok.getLocation();
2402  PP.Lex(Tok);
2403  if (Tok.isNot(tok::eod)) {
2404  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2405  << "vtordisp";
2406  return;
2407  }
2408 
2409  // Enter the annotation.
2410  Token AnnotTok;
2411  AnnotTok.startToken();
2412  AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2413  AnnotTok.setLocation(VtorDispLoc);
2414  AnnotTok.setAnnotationEndLoc(EndLoc);
2415  AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2416  static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2417  PP.EnterToken(AnnotTok);
2418 }
2419 
2420 /// Handle all MS pragmas. Simply forwards the tokens after inserting
2421 /// an annotation token.
2422 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2423  PragmaIntroducerKind Introducer,
2424  Token &Tok) {
2425  Token EoF, AnnotTok;
2426  EoF.startToken();
2427  EoF.setKind(tok::eof);
2428  AnnotTok.startToken();
2429  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2430  AnnotTok.setLocation(Tok.getLocation());
2431  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2432  SmallVector<Token, 8> TokenVector;
2433  // Suck up all of the tokens before the eod.
2434  for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2435  TokenVector.push_back(Tok);
2436  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2437  }
2438  // Add a sentinel EoF token to the end of the list.
2439  TokenVector.push_back(EoF);
2440  // We must allocate this array with new because EnterTokenStream is going to
2441  // delete it later.
2442  auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2443  std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2444  auto Value = new (PP.getPreprocessorAllocator())
2445  std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2446  TokenVector.size());
2447  AnnotTok.setAnnotationValue(Value);
2448  PP.EnterToken(AnnotTok);
2449 }
2450 
2451 /// Handle the Microsoft \#pragma detect_mismatch extension.
2452 ///
2453 /// The syntax is:
2454 /// \code
2455 /// #pragma detect_mismatch("name", "value")
2456 /// \endcode
2457 /// Where 'name' and 'value' are quoted strings. The values are embedded in
2458 /// the object file and passed along to the linker. If the linker detects a
2459 /// mismatch in the object file's values for the given name, a LNK2038 error
2460 /// is emitted. See MSDN for more details.
2461 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2462  PragmaIntroducerKind Introducer,
2463  Token &Tok) {
2464  SourceLocation DetectMismatchLoc = Tok.getLocation();
2465  PP.Lex(Tok);
2466  if (Tok.isNot(tok::l_paren)) {
2467  PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2468  return;
2469  }
2470 
2471  // Read the name to embed, which must be a string literal.
2472  std::string NameString;
2473  if (!PP.LexStringLiteral(Tok, NameString,
2474  "pragma detect_mismatch",
2475  /*MacroExpansion=*/true))
2476  return;
2477 
2478  // Read the comma followed by a second string literal.
2479  std::string ValueString;
2480  if (Tok.isNot(tok::comma)) {
2481  PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2482  return;
2483  }
2484 
2485  if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2486  /*MacroExpansion=*/true))
2487  return;
2488 
2489  if (Tok.isNot(tok::r_paren)) {
2490  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2491  return;
2492  }
2493  PP.Lex(Tok); // Eat the r_paren.
2494 
2495  if (Tok.isNot(tok::eod)) {
2496  PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2497  return;
2498  }
2499 
2500  // If the pragma is lexically sound, notify any interested PPCallbacks.
2501  if (PP.getPPCallbacks())
2502  PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2503  ValueString);
2504 
2505  Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2506 }
2507 
2508 /// Handle the microsoft \#pragma comment extension.
2509 ///
2510 /// The syntax is:
2511 /// \code
2512 /// #pragma comment(linker, "foo")
2513 /// \endcode
2514 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2515 /// "foo" is a string, which is fully macro expanded, and permits string
2516 /// concatenation, embedded escape characters etc. See MSDN for more details.
2517 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2518  PragmaIntroducerKind Introducer,
2519  Token &Tok) {
2520  SourceLocation CommentLoc = Tok.getLocation();
2521  PP.Lex(Tok);
2522  if (Tok.isNot(tok::l_paren)) {
2523  PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2524  return;
2525  }
2526 
2527  // Read the identifier.
2528  PP.Lex(Tok);
2529  if (Tok.isNot(tok::identifier)) {
2530  PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2531  return;
2532  }
2533 
2534  // Verify that this is one of the 5 whitelisted options.
2535  IdentifierInfo *II = Tok.getIdentifierInfo();
2536  PragmaMSCommentKind Kind =
2537  llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2538  .Case("linker", PCK_Linker)
2539  .Case("lib", PCK_Lib)
2540  .Case("compiler", PCK_Compiler)
2541  .Case("exestr", PCK_ExeStr)
2542  .Case("user", PCK_User)
2543  .Default(PCK_Unknown);
2544  if (Kind == PCK_Unknown) {
2545  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2546  return;
2547  }
2548 
2549  if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
2550  PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2551  << II->getName();
2552  return;
2553  }
2554 
2555  // On PS4, issue a warning about any pragma comments other than
2556  // #pragma comment lib.
2557  if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
2558  PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2559  << II->getName();
2560  return;
2561  }
2562 
2563  // Read the optional string if present.
2564  PP.Lex(Tok);
2565  std::string ArgumentString;
2566  if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2567  "pragma comment",
2568  /*MacroExpansion=*/true))
2569  return;
2570 
2571  // FIXME: warn that 'exestr' is deprecated.
2572  // FIXME: If the kind is "compiler" warn if the string is present (it is
2573  // ignored).
2574  // The MSDN docs say that "lib" and "linker" require a string and have a short
2575  // whitelist of linker options they support, but in practice MSVC doesn't
2576  // issue a diagnostic. Therefore neither does clang.
2577 
2578  if (Tok.isNot(tok::r_paren)) {
2579  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2580  return;
2581  }
2582  PP.Lex(Tok); // eat the r_paren.
2583 
2584  if (Tok.isNot(tok::eod)) {
2585  PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2586  return;
2587  }
2588 
2589  // If the pragma is lexically sound, notify any interested PPCallbacks.
2590  if (PP.getPPCallbacks())
2591  PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2592 
2593  Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2594 }
2595 
2596 // #pragma clang optimize off
2597 // #pragma clang optimize on
2598 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2599  PragmaIntroducerKind Introducer,
2600  Token &FirstToken) {
2601  Token Tok;
2602  PP.Lex(Tok);
2603  if (Tok.is(tok::eod)) {
2604  PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2605  << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
2606  return;
2607  }
2608  if (Tok.isNot(tok::identifier)) {
2609  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2610  << PP.getSpelling(Tok);
2611  return;
2612  }
2613  const IdentifierInfo *II = Tok.getIdentifierInfo();
2614  // The only accepted values are 'on' or 'off'.
2615  bool IsOn = false;
2616  if (II->isStr("on")) {
2617  IsOn = true;
2618  } else if (!II->isStr("off")) {
2619  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2620  << PP.getSpelling(Tok);
2621  return;
2622  }
2623  PP.Lex(Tok);
2624 
2625  if (Tok.isNot(tok::eod)) {
2626  PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
2627  << PP.getSpelling(Tok);
2628  return;
2629  }
2630 
2631  Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
2632 }
2633 
2634 namespace {
2635 /// Used as the annotation value for tok::annot_pragma_fp.
2636 struct TokFPAnnotValue {
2637  enum FlagKinds { Contract };
2638  enum FlagValues { On, Off, Fast };
2639 
2640  FlagKinds FlagKind;
2641  FlagValues FlagValue;
2642 };
2643 } // end anonymous namespace
2644 
2645 void PragmaFPHandler::HandlePragma(Preprocessor &PP,
2646  PragmaIntroducerKind Introducer,
2647  Token &Tok) {
2648  // fp
2649  Token PragmaName = Tok;
2650  SmallVector<Token, 1> TokenList;
2651 
2652  PP.Lex(Tok);
2653  if (Tok.isNot(tok::identifier)) {
2654  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2655  << /*MissingOption=*/true << "";
2656  return;
2657  }
2658 
2659  while (Tok.is(tok::identifier)) {
2660  IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2661 
2662  auto FlagKind =
2663  llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2664  OptionInfo->getName())
2665  .Case("contract", TokFPAnnotValue::Contract)
2666  .Default(None);
2667  if (!FlagKind) {
2668  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2669  << /*MissingOption=*/false << OptionInfo;
2670  return;
2671  }
2672  PP.Lex(Tok);
2673 
2674  // Read '('
2675  if (Tok.isNot(tok::l_paren)) {
2676  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2677  return;
2678  }
2679  PP.Lex(Tok);
2680 
2681  if (Tok.isNot(tok::identifier)) {
2682  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2683  << PP.getSpelling(Tok) << OptionInfo->getName();
2684  return;
2685  }
2686  const IdentifierInfo *II = Tok.getIdentifierInfo();
2687 
2688  auto FlagValue =
2689  llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2690  II->getName())
2691  .Case("on", TokFPAnnotValue::On)
2692  .Case("off", TokFPAnnotValue::Off)
2693  .Case("fast", TokFPAnnotValue::Fast)
2694  .Default(llvm::None);
2695 
2696  if (!FlagValue) {
2697  PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2698  << PP.getSpelling(Tok) << OptionInfo->getName();
2699  return;
2700  }
2701  PP.Lex(Tok);
2702 
2703  // Read ')'
2704  if (Tok.isNot(tok::r_paren)) {
2705  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2706  return;
2707  }
2708  PP.Lex(Tok);
2709 
2710  auto *AnnotValue = new (PP.getPreprocessorAllocator())
2711  TokFPAnnotValue{*FlagKind, *FlagValue};
2712  // Generate the loop hint token.
2713  Token FPTok;
2714  FPTok.startToken();
2715  FPTok.setKind(tok::annot_pragma_fp);
2716  FPTok.setLocation(PragmaName.getLocation());
2717  FPTok.setAnnotationEndLoc(PragmaName.getLocation());
2718  FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
2719  TokenList.push_back(FPTok);
2720  }
2721 
2722  if (Tok.isNot(tok::eod)) {
2723  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2724  << "clang fp";
2725  return;
2726  }
2727 
2728  auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2729  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2730 
2731  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2732  /*DisableMacroExpansion=*/false);
2733 }
2734 
2735 void Parser::HandlePragmaFP() {
2736  assert(Tok.is(tok::annot_pragma_fp));
2737  auto *AnnotValue =
2738  reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
2739 
2741  switch (AnnotValue->FlagValue) {
2742  case TokFPAnnotValue::On:
2743  FPC = LangOptions::FPC_On;
2744  break;
2745  case TokFPAnnotValue::Fast:
2746  FPC = LangOptions::FPC_Fast;
2747  break;
2748  case TokFPAnnotValue::Off:
2749  FPC = LangOptions::FPC_Off;
2750  break;
2751  }
2752 
2753  Actions.ActOnPragmaFPContract(FPC);
2754  ConsumeAnnotationToken();
2755 }
2756 
2757 /// Parses loop or unroll pragma hint value and fills in Info.
2758 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
2759  Token Option, bool ValueInParens,
2760  PragmaLoopHintInfo &Info) {
2762  int OpenParens = ValueInParens ? 1 : 0;
2763  // Read constant expression.
2764  while (Tok.isNot(tok::eod)) {
2765  if (Tok.is(tok::l_paren))
2766  OpenParens++;
2767  else if (Tok.is(tok::r_paren)) {
2768  OpenParens--;
2769  if (OpenParens == 0 && ValueInParens)
2770  break;
2771  }
2772 
2773  ValueList.push_back(Tok);
2774  PP.Lex(Tok);
2775  }
2776 
2777  if (ValueInParens) {
2778  // Read ')'
2779  if (Tok.isNot(tok::r_paren)) {
2780  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2781  return true;
2782  }
2783  PP.Lex(Tok);
2784  }
2785 
2786  Token EOFTok;
2787  EOFTok.startToken();
2788  EOFTok.setKind(tok::eof);
2789  EOFTok.setLocation(Tok.getLocation());
2790  ValueList.push_back(EOFTok); // Terminates expression for parsing.
2791 
2792  Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
2793 
2794  Info.PragmaName = PragmaName;
2795  Info.Option = Option;
2796  return false;
2797 }
2798 
2799 /// Handle the \#pragma clang loop directive.
2800 /// #pragma clang 'loop' loop-hints
2801 ///
2802 /// loop-hints:
2803 /// loop-hint loop-hints[opt]
2804 ///
2805 /// loop-hint:
2806 /// 'vectorize' '(' loop-hint-keyword ')'
2807 /// 'interleave' '(' loop-hint-keyword ')'
2808 /// 'unroll' '(' unroll-hint-keyword ')'
2809 /// 'vectorize_width' '(' loop-hint-value ')'
2810 /// 'interleave_count' '(' loop-hint-value ')'
2811 /// 'unroll_count' '(' loop-hint-value ')'
2812 ///
2813 /// loop-hint-keyword:
2814 /// 'enable'
2815 /// 'disable'
2816 /// 'assume_safety'
2817 ///
2818 /// unroll-hint-keyword:
2819 /// 'enable'
2820 /// 'disable'
2821 /// 'full'
2822 ///
2823 /// loop-hint-value:
2824 /// constant-expression
2825 ///
2826 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2827 /// try vectorizing the instructions of the loop it precedes. Specifying
2828 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
2829 /// interleaving multiple iterations of the loop it precedes. The width of the
2830 /// vector instructions is specified by vectorize_width() and the number of
2831 /// interleaved loop iterations is specified by interleave_count(). Specifying a
2832 /// value of 1 effectively disables vectorization/interleaving, even if it is
2833 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
2834 /// only works on inner loops.
2835 ///
2836 /// The unroll and unroll_count directives control the concatenation
2837 /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2838 /// completely if the trip count is known at compile time and unroll partially
2839 /// if the trip count is not known. Specifying unroll(full) is similar to
2840 /// unroll(enable) but will unroll the loop only if the trip count is known at
2841 /// compile time. Specifying unroll(disable) disables unrolling for the
2842 /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2843 /// loop the number of times indicated by the value.
2844 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2845  PragmaIntroducerKind Introducer,
2846  Token &Tok) {
2847  // Incoming token is "loop" from "#pragma clang loop".
2848  Token PragmaName = Tok;
2849  SmallVector<Token, 1> TokenList;
2850 
2851  // Lex the optimization option and verify it is an identifier.
2852  PP.Lex(Tok);
2853  if (Tok.isNot(tok::identifier)) {
2854  PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2855  << /*MissingOption=*/true << "";
2856  return;
2857  }
2858 
2859  while (Tok.is(tok::identifier)) {
2860  Token Option = Tok;
2861  IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2862 
2863  bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2864  .Case("vectorize", true)
2865  .Case("interleave", true)
2866  .Case("unroll", true)
2867  .Case("distribute", true)
2868  .Case("vectorize_width", true)
2869  .Case("interleave_count", true)
2870  .Case("unroll_count", true)
2871  .Default(false);
2872  if (!OptionValid) {
2873  PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2874  << /*MissingOption=*/false << OptionInfo;
2875  return;
2876  }
2877  PP.Lex(Tok);
2878 
2879  // Read '('
2880  if (Tok.isNot(tok::l_paren)) {
2881  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2882  return;
2883  }
2884  PP.Lex(Tok);
2885 
2886  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2887  if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2888  *Info))
2889  return;
2890 
2891  // Generate the loop hint token.
2892  Token LoopHintTok;
2893  LoopHintTok.startToken();
2894  LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2895  LoopHintTok.setLocation(PragmaName.getLocation());
2896  LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2897  LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2898  TokenList.push_back(LoopHintTok);
2899  }
2900 
2901  if (Tok.isNot(tok::eod)) {
2902  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2903  << "clang loop";
2904  return;
2905  }
2906 
2907  auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2908  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2909 
2910  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2911  /*DisableMacroExpansion=*/false);
2912 }
2913 
2914 /// Handle the loop unroll optimization pragmas.
2915 /// #pragma unroll
2916 /// #pragma unroll unroll-hint-value
2917 /// #pragma unroll '(' unroll-hint-value ')'
2918 /// #pragma nounroll
2919 /// #pragma unroll_and_jam
2920 /// #pragma unroll_and_jam unroll-hint-value
2921 /// #pragma unroll_and_jam '(' unroll-hint-value ')'
2922 /// #pragma nounroll_and_jam
2923 ///
2924 /// unroll-hint-value:
2925 /// constant-expression
2926 ///
2927 /// Loop unrolling hints can be specified with '#pragma unroll' or
2928 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2929 /// contained in parentheses. With no argument the directive instructs llvm to
2930 /// try to unroll the loop completely. A positive integer argument can be
2931 /// specified to indicate the number of times the loop should be unrolled. To
2932 /// maximize compatibility with other compilers the unroll count argument can be
2933 /// specified with or without parentheses. Specifying, '#pragma nounroll'
2934 /// disables unrolling of the loop.
2935 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2936  PragmaIntroducerKind Introducer,
2937  Token &Tok) {
2938  // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2939  // "#pragma nounroll".
2940  Token PragmaName = Tok;
2941  PP.Lex(Tok);
2942  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2943  if (Tok.is(tok::eod)) {
2944  // nounroll or unroll pragma without an argument.
2945  Info->PragmaName = PragmaName;
2946  Info->Option.startToken();
2947  } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" ||
2948  PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam") {
2949  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2950  << PragmaName.getIdentifierInfo()->getName();
2951  return;
2952  } else {
2953  // Unroll pragma with an argument: "#pragma unroll N" or
2954  // "#pragma unroll(N)".
2955  // Read '(' if it exists.
2956  bool ValueInParens = Tok.is(tok::l_paren);
2957  if (ValueInParens)
2958  PP.Lex(Tok);
2959 
2960  Token Option;
2961  Option.startToken();
2962  if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2963  return;
2964 
2965  // In CUDA, the argument to '#pragma unroll' should not be contained in
2966  // parentheses.
2967  if (PP.getLangOpts().CUDA && ValueInParens)
2968  PP.Diag(Info->Toks[0].getLocation(),
2969  diag::warn_pragma_unroll_cuda_value_in_parens);
2970 
2971  if (Tok.isNot(tok::eod)) {
2972  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2973  << "unroll";
2974  return;
2975  }
2976  }
2977 
2978  // Generate the hint token.
2979  auto TokenArray = llvm::make_unique<Token[]>(1);
2980  TokenArray[0].startToken();
2981  TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2982  TokenArray[0].setLocation(PragmaName.getLocation());
2983  TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2984  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2985  PP.EnterTokenStream(std::move(TokenArray), 1,
2986  /*DisableMacroExpansion=*/false);
2987 }
2988 
2989 /// Handle the Microsoft \#pragma intrinsic extension.
2990 ///
2991 /// The syntax is:
2992 /// \code
2993 /// #pragma intrinsic(memset)
2994 /// #pragma intrinsic(strlen, memcpy)
2995 /// \endcode
2996 ///
2997 /// Pragma intrisic tells the compiler to use a builtin version of the
2998 /// function. Clang does it anyway, so the pragma doesn't really do anything.
2999 /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
3000 /// isn't an intrinsic in clang and suggest to include intrin.h.
3001 void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
3002  PragmaIntroducerKind Introducer,
3003  Token &Tok) {
3004  PP.Lex(Tok);
3005 
3006  if (Tok.isNot(tok::l_paren)) {
3007  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
3008  << "intrinsic";
3009  return;
3010  }
3011  PP.Lex(Tok);
3012 
3013  bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3014 
3015  while (Tok.is(tok::identifier)) {
3016  IdentifierInfo *II = Tok.getIdentifierInfo();
3017  if (!II->getBuiltinID())
3018  PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3019  << II << SuggestIntrinH;
3020 
3021  PP.Lex(Tok);
3022  if (Tok.isNot(tok::comma))
3023  break;
3024  PP.Lex(Tok);
3025  }
3026 
3027  if (Tok.isNot(tok::r_paren)) {
3028  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
3029  << "intrinsic";
3030  return;
3031  }
3032  PP.Lex(Tok);
3033 
3034  if (Tok.isNot(tok::eod))
3035  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3036  << "intrinsic";
3037 }
3038 
3039 // #pragma optimize("gsty", on|off)
3040 void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
3041  PragmaIntroducerKind Introducer,
3042  Token &Tok) {
3043  SourceLocation StartLoc = Tok.getLocation();
3044  PP.Lex(Tok);
3045 
3046  if (Tok.isNot(tok::l_paren)) {
3047  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
3048  return;
3049  }
3050  PP.Lex(Tok);
3051 
3052  if (Tok.isNot(tok::string_literal)) {
3053  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
3054  return;
3055  }
3056  // We could syntax check the string but it's probably not worth the effort.
3057  PP.Lex(Tok);
3058 
3059  if (Tok.isNot(tok::comma)) {
3060  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
3061  return;
3062  }
3063  PP.Lex(Tok);
3064 
3065  if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
3066  PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
3067  << "optimize" << /*Expected=*/true << "'on' or 'off'";
3068  return;
3069  }
3070  IdentifierInfo *II = Tok.getIdentifierInfo();
3071  if (!II || (!II->isStr("on") && !II->isStr("off"))) {
3072  PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
3073  << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
3074  << "'on' or 'off'";
3075  return;
3076  }
3077  PP.Lex(Tok);
3078 
3079  if (Tok.isNot(tok::r_paren)) {
3080  PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
3081  return;
3082  }
3083  PP.Lex(Tok);
3084 
3085  if (Tok.isNot(tok::eod)) {
3086  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3087  << "optimize";
3088  return;
3089  }
3090  PP.Diag(StartLoc, diag::warn_pragma_optimize);
3091 }
3092 
3093 void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3094  Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) {
3095  Token FirstTok = Tok;
3096 
3097  PP.Lex(Tok);
3098  IdentifierInfo *Info = Tok.getIdentifierInfo();
3099  if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
3100  PP.Diag(FirstTok.getLocation(),
3101  diag::warn_pragma_force_cuda_host_device_bad_arg);
3102  return;
3103  }
3104 
3105  if (Info->isStr("begin"))
3106  Actions.PushForceCUDAHostDevice();
3107  else if (!Actions.PopForceCUDAHostDevice())
3108  PP.Diag(FirstTok.getLocation(),
3109  diag::err_pragma_cannot_end_force_cuda_host_device);
3110 
3111  PP.Lex(Tok);
3112  if (!Tok.is(tok::eod))
3113  PP.Diag(FirstTok.getLocation(),
3114  diag::warn_pragma_force_cuda_host_device_bad_arg);
3115 }
3116 
3117 /// Handle the #pragma clang attribute directive.
3118 ///
3119 /// The syntax is:
3120 /// \code
3121 /// #pragma clang attribute push(attribute, subject-set)
3122 /// #pragma clang attribute push
3123 /// #pragma clang attribute (attribute, subject-set)
3124 /// #pragma clang attribute pop
3125 /// \endcode
3126 ///
3127 /// The subject-set clause defines the set of declarations which receive the
3128 /// attribute. Its exact syntax is described in the LanguageExtensions document
3129 /// in Clang's documentation.
3130 ///
3131 /// This directive instructs the compiler to begin/finish applying the specified
3132 /// attribute to the set of attribute-specific declarations in the active range
3133 /// of the pragma.
3134 void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3135  PragmaIntroducerKind Introducer,
3136  Token &FirstToken) {
3137  Token Tok;
3138  PP.Lex(Tok);
3139  auto *Info = new (PP.getPreprocessorAllocator())
3140  PragmaAttributeInfo(AttributesForPragmaAttribute);
3141 
3142  if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
3143  PP.Diag(Tok.getLocation(),
3144  diag::err_pragma_attribute_expected_push_pop_paren);
3145  return;
3146  }
3147 
3148  // Determine what action this pragma clang attribute represents.
3149  if (Tok.is(tok::l_paren))
3150  Info->Action = PragmaAttributeInfo::Attribute;
3151  else {
3152  const IdentifierInfo *II = Tok.getIdentifierInfo();
3153  if (II->isStr("push"))
3154  Info->Action = PragmaAttributeInfo::Push;
3155  else if (II->isStr("pop"))
3156  Info->Action = PragmaAttributeInfo::Pop;
3157  else {
3158  PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
3159  << PP.getSpelling(Tok);
3160  return;
3161  }
3162 
3163  PP.Lex(Tok);
3164  }
3165 
3166  // Parse the actual attribute.
3167  if ((Info->Action == PragmaAttributeInfo::Push && Tok.isNot(tok::eod)) ||
3168  Info->Action == PragmaAttributeInfo::Attribute) {
3169  if (Tok.isNot(tok::l_paren)) {
3170  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3171  return;
3172  }
3173  PP.Lex(Tok);
3174 
3175  // Lex the attribute tokens.
3176  SmallVector<Token, 16> AttributeTokens;
3177  int OpenParens = 1;
3178  while (Tok.isNot(tok::eod)) {
3179  if (Tok.is(tok::l_paren))
3180  OpenParens++;
3181  else if (Tok.is(tok::r_paren)) {
3182  OpenParens--;
3183  if (OpenParens == 0)
3184  break;
3185  }
3186 
3187  AttributeTokens.push_back(Tok);
3188  PP.Lex(Tok);
3189  }
3190 
3191  if (AttributeTokens.empty()) {
3192  PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
3193  return;
3194  }
3195  if (Tok.isNot(tok::r_paren)) {
3196  PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3197  return;
3198  }
3199  SourceLocation EndLoc = Tok.getLocation();
3200  PP.Lex(Tok);
3201 
3202  // Terminate the attribute for parsing.
3203  Token EOFTok;
3204  EOFTok.startToken();
3205  EOFTok.setKind(tok::eof);
3206  EOFTok.setLocation(EndLoc);
3207  AttributeTokens.push_back(EOFTok);
3208 
3209  Info->Tokens =
3210  llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
3211  }
3212 
3213  if (Tok.isNot(tok::eod))
3214  PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3215  << "clang attribute";
3216 
3217  // Generate the annotated pragma token.
3218  auto TokenArray = llvm::make_unique<Token[]>(1);
3219  TokenArray[0].startToken();
3220  TokenArray[0].setKind(tok::annot_pragma_attribute);
3221  TokenArray[0].setLocation(FirstToken.getLocation());
3222  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
3223  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3224  PP.EnterTokenStream(std::move(TokenArray), 1,
3225  /*DisableMacroExpansion=*/false);
3226 }
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:457
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:8334
This indicates that the scope corresponds to a function, which means that labels are set here...
Definition: Scope.h:47
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:57
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
Definition: ParsedAttr.cpp:29
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:268
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
IdentifierLoc * OptionLoc
Definition: LoopHint.h:31
IdentifierLoc * StateLoc
Definition: LoopHint.h:34
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
Definition: Token.h:107
attribute((...))
Definition: ParsedAttr.h: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:1050
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:1690
const LangOptions & getLangOpts() const
Definition: Preprocessor.h:815
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:1689
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:1040
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:372
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:130
PragmaMSCommentKind
Definition: PragmaKinds.h:15
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
bool isInvalid() const
Definition: Ownership.h:170
SourceLocation getEnd() const
PPCallbacks * getPPCallbacks() const
Definition: Preprocessor.h: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:366
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:383
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:59
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:1313
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1577
Defines the clang::TargetInfo interface.
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:242
void DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:816
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:1032
SourceLocation getEndLoc() const
Definition: Token.h:151