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