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