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