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