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