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