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