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