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