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