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