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