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