]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp
MFV r294800: 6385 Fix unlocking order in zfs_zget
[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 "RAIIObjectsForParser.h"
15 #include "clang/AST/ASTContext.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/Sema/LoopHint.h"
21 #include "clang/Sema/Scope.h"
22 #include "llvm/ADT/StringSwitch.h"
23 using namespace clang;
24
25 namespace {
26
27 struct PragmaAlignHandler : public PragmaHandler {
28   explicit PragmaAlignHandler() : PragmaHandler("align") {}
29   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
30                     Token &FirstToken) override;
31 };
32
33 struct PragmaGCCVisibilityHandler : public PragmaHandler {
34   explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
35   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
36                     Token &FirstToken) override;
37 };
38
39 struct PragmaOptionsHandler : public PragmaHandler {
40   explicit PragmaOptionsHandler() : PragmaHandler("options") {}
41   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
42                     Token &FirstToken) override;
43 };
44
45 struct PragmaPackHandler : public PragmaHandler {
46   explicit PragmaPackHandler() : PragmaHandler("pack") {}
47   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
48                     Token &FirstToken) override;
49 };
50
51 struct PragmaMSStructHandler : public PragmaHandler {
52   explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
53   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
54                     Token &FirstToken) override;
55 };
56
57 struct PragmaUnusedHandler : public PragmaHandler {
58   PragmaUnusedHandler() : PragmaHandler("unused") {}
59   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
60                     Token &FirstToken) override;
61 };
62
63 struct PragmaWeakHandler : public PragmaHandler {
64   explicit PragmaWeakHandler() : PragmaHandler("weak") {}
65   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
66                     Token &FirstToken) override;
67 };
68
69 struct PragmaRedefineExtnameHandler : public PragmaHandler {
70   explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
71   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
72                     Token &FirstToken) override;
73 };
74
75 struct PragmaOpenCLExtensionHandler : public PragmaHandler {
76   PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
77   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
78                     Token &FirstToken) override;
79 };
80
81
82 struct PragmaFPContractHandler : public PragmaHandler {
83   PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
84   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
85                     Token &FirstToken) override;
86 };
87
88 struct PragmaNoOpenMPHandler : public PragmaHandler {
89   PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
90   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
91                     Token &FirstToken) override;
92 };
93
94 struct PragmaOpenMPHandler : public PragmaHandler {
95   PragmaOpenMPHandler() : PragmaHandler("omp") { }
96   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
97                     Token &FirstToken) override;
98 };
99
100 /// PragmaCommentHandler - "\#pragma comment ...".
101 struct PragmaCommentHandler : public PragmaHandler {
102   PragmaCommentHandler(Sema &Actions)
103     : PragmaHandler("comment"), Actions(Actions) {}
104   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
105                     Token &FirstToken) override;
106 private:
107   Sema &Actions;
108 };
109
110 struct PragmaDetectMismatchHandler : public PragmaHandler {
111   PragmaDetectMismatchHandler(Sema &Actions)
112     : PragmaHandler("detect_mismatch"), Actions(Actions) {}
113   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
114                     Token &FirstToken) override;
115 private:
116   Sema &Actions;
117 };
118
119 struct PragmaMSPointersToMembers : public PragmaHandler {
120   explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
121   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
122                     Token &FirstToken) override;
123 };
124
125 struct PragmaMSVtorDisp : public PragmaHandler {
126   explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
127   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
128                     Token &FirstToken) override;
129 };
130
131 struct PragmaMSPragma : public PragmaHandler {
132   explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
133   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
134                     Token &FirstToken) override;
135 };
136
137 /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
138 struct PragmaOptimizeHandler : public PragmaHandler {
139   PragmaOptimizeHandler(Sema &S)
140     : PragmaHandler("optimize"), Actions(S) {}
141   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
142                     Token &FirstToken) override;
143 private:
144   Sema &Actions;
145 };
146
147 struct PragmaLoopHintHandler : public PragmaHandler {
148   PragmaLoopHintHandler() : PragmaHandler("loop") {}
149   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
150                     Token &FirstToken) override;
151 };
152
153 struct PragmaUnrollHintHandler : public PragmaHandler {
154   PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
155   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
156                     Token &FirstToken) override;
157 };
158
159 }  // end namespace
160
161 void Parser::initializePragmaHandlers() {
162   AlignHandler.reset(new PragmaAlignHandler());
163   PP.AddPragmaHandler(AlignHandler.get());
164
165   GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
166   PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
167
168   OptionsHandler.reset(new PragmaOptionsHandler());
169   PP.AddPragmaHandler(OptionsHandler.get());
170
171   PackHandler.reset(new PragmaPackHandler());
172   PP.AddPragmaHandler(PackHandler.get());
173
174   MSStructHandler.reset(new PragmaMSStructHandler());
175   PP.AddPragmaHandler(MSStructHandler.get());
176
177   UnusedHandler.reset(new PragmaUnusedHandler());
178   PP.AddPragmaHandler(UnusedHandler.get());
179
180   WeakHandler.reset(new PragmaWeakHandler());
181   PP.AddPragmaHandler(WeakHandler.get());
182
183   RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
184   PP.AddPragmaHandler(RedefineExtnameHandler.get());
185
186   FPContractHandler.reset(new PragmaFPContractHandler());
187   PP.AddPragmaHandler("STDC", FPContractHandler.get());
188
189   if (getLangOpts().OpenCL) {
190     OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
191     PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
192
193     PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
194   }
195   if (getLangOpts().OpenMP)
196     OpenMPHandler.reset(new PragmaOpenMPHandler());
197   else
198     OpenMPHandler.reset(new PragmaNoOpenMPHandler());
199   PP.AddPragmaHandler(OpenMPHandler.get());
200
201   if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
202     MSCommentHandler.reset(new PragmaCommentHandler(Actions));
203     PP.AddPragmaHandler(MSCommentHandler.get());
204   }
205
206   if (getLangOpts().MicrosoftExt) {
207     MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
208     PP.AddPragmaHandler(MSDetectMismatchHandler.get());
209     MSPointersToMembers.reset(new PragmaMSPointersToMembers());
210     PP.AddPragmaHandler(MSPointersToMembers.get());
211     MSVtorDisp.reset(new PragmaMSVtorDisp());
212     PP.AddPragmaHandler(MSVtorDisp.get());
213     MSInitSeg.reset(new PragmaMSPragma("init_seg"));
214     PP.AddPragmaHandler(MSInitSeg.get());
215     MSDataSeg.reset(new PragmaMSPragma("data_seg"));
216     PP.AddPragmaHandler(MSDataSeg.get());
217     MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
218     PP.AddPragmaHandler(MSBSSSeg.get());
219     MSConstSeg.reset(new PragmaMSPragma("const_seg"));
220     PP.AddPragmaHandler(MSConstSeg.get());
221     MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
222     PP.AddPragmaHandler(MSCodeSeg.get());
223     MSSection.reset(new PragmaMSPragma("section"));
224     PP.AddPragmaHandler(MSSection.get());
225   }
226
227   OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
228   PP.AddPragmaHandler("clang", OptimizeHandler.get());
229
230   LoopHintHandler.reset(new PragmaLoopHintHandler());
231   PP.AddPragmaHandler("clang", LoopHintHandler.get());
232
233   UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
234   PP.AddPragmaHandler(UnrollHintHandler.get());
235
236   NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
237   PP.AddPragmaHandler(NoUnrollHintHandler.get());
238 }
239
240 void Parser::resetPragmaHandlers() {
241   // Remove the pragma handlers we installed.
242   PP.RemovePragmaHandler(AlignHandler.get());
243   AlignHandler.reset();
244   PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
245   GCCVisibilityHandler.reset();
246   PP.RemovePragmaHandler(OptionsHandler.get());
247   OptionsHandler.reset();
248   PP.RemovePragmaHandler(PackHandler.get());
249   PackHandler.reset();
250   PP.RemovePragmaHandler(MSStructHandler.get());
251   MSStructHandler.reset();
252   PP.RemovePragmaHandler(UnusedHandler.get());
253   UnusedHandler.reset();
254   PP.RemovePragmaHandler(WeakHandler.get());
255   WeakHandler.reset();
256   PP.RemovePragmaHandler(RedefineExtnameHandler.get());
257   RedefineExtnameHandler.reset();
258
259   if (getLangOpts().OpenCL) {
260     PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
261     OpenCLExtensionHandler.reset();
262     PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
263   }
264   PP.RemovePragmaHandler(OpenMPHandler.get());
265   OpenMPHandler.reset();
266
267   if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) {
268     PP.RemovePragmaHandler(MSCommentHandler.get());
269     MSCommentHandler.reset();
270   }
271
272   if (getLangOpts().MicrosoftExt) {
273     PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
274     MSDetectMismatchHandler.reset();
275     PP.RemovePragmaHandler(MSPointersToMembers.get());
276     MSPointersToMembers.reset();
277     PP.RemovePragmaHandler(MSVtorDisp.get());
278     MSVtorDisp.reset();
279     PP.RemovePragmaHandler(MSInitSeg.get());
280     MSInitSeg.reset();
281     PP.RemovePragmaHandler(MSDataSeg.get());
282     MSDataSeg.reset();
283     PP.RemovePragmaHandler(MSBSSSeg.get());
284     MSBSSSeg.reset();
285     PP.RemovePragmaHandler(MSConstSeg.get());
286     MSConstSeg.reset();
287     PP.RemovePragmaHandler(MSCodeSeg.get());
288     MSCodeSeg.reset();
289     PP.RemovePragmaHandler(MSSection.get());
290     MSSection.reset();
291   }
292
293   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
294   FPContractHandler.reset();
295
296   PP.RemovePragmaHandler("clang", OptimizeHandler.get());
297   OptimizeHandler.reset();
298
299   PP.RemovePragmaHandler("clang", LoopHintHandler.get());
300   LoopHintHandler.reset();
301
302   PP.RemovePragmaHandler(UnrollHintHandler.get());
303   UnrollHintHandler.reset();
304
305   PP.RemovePragmaHandler(NoUnrollHintHandler.get());
306   NoUnrollHintHandler.reset();
307 }
308
309 /// \brief Handle the annotation token produced for #pragma unused(...)
310 ///
311 /// Each annot_pragma_unused is followed by the argument token so e.g.
312 /// "#pragma unused(x,y)" becomes:
313 /// annot_pragma_unused 'x' annot_pragma_unused 'y'
314 void Parser::HandlePragmaUnused() {
315   assert(Tok.is(tok::annot_pragma_unused));
316   SourceLocation UnusedLoc = ConsumeToken();
317   Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
318   ConsumeToken(); // The argument token.
319 }
320
321 void Parser::HandlePragmaVisibility() {
322   assert(Tok.is(tok::annot_pragma_vis));
323   const IdentifierInfo *VisType =
324     static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
325   SourceLocation VisLoc = ConsumeToken();
326   Actions.ActOnPragmaVisibility(VisType, VisLoc);
327 }
328
329 struct PragmaPackInfo {
330   Sema::PragmaPackKind Kind;
331   IdentifierInfo *Name;
332   Token Alignment;
333   SourceLocation LParenLoc;
334   SourceLocation RParenLoc;
335 };
336
337 void Parser::HandlePragmaPack() {
338   assert(Tok.is(tok::annot_pragma_pack));
339   PragmaPackInfo *Info =
340     static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
341   SourceLocation PragmaLoc = ConsumeToken();
342   ExprResult Alignment;
343   if (Info->Alignment.is(tok::numeric_constant)) {
344     Alignment = Actions.ActOnNumericConstant(Info->Alignment);
345     if (Alignment.isInvalid())
346       return;
347   }
348   Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
349                           Info->LParenLoc, Info->RParenLoc);
350 }
351
352 void Parser::HandlePragmaMSStruct() {
353   assert(Tok.is(tok::annot_pragma_msstruct));
354   Sema::PragmaMSStructKind Kind =
355     static_cast<Sema::PragmaMSStructKind>(
356     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
357   Actions.ActOnPragmaMSStruct(Kind);
358   ConsumeToken(); // The annotation token.
359 }
360
361 void Parser::HandlePragmaAlign() {
362   assert(Tok.is(tok::annot_pragma_align));
363   Sema::PragmaOptionsAlignKind Kind =
364     static_cast<Sema::PragmaOptionsAlignKind>(
365     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
366   SourceLocation PragmaLoc = ConsumeToken();
367   Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
368 }
369
370 void Parser::HandlePragmaWeak() {
371   assert(Tok.is(tok::annot_pragma_weak));
372   SourceLocation PragmaLoc = ConsumeToken();
373   Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
374                             Tok.getLocation());
375   ConsumeToken(); // The weak name.
376 }
377
378 void Parser::HandlePragmaWeakAlias() {
379   assert(Tok.is(tok::annot_pragma_weakalias));
380   SourceLocation PragmaLoc = ConsumeToken();
381   IdentifierInfo *WeakName = Tok.getIdentifierInfo();
382   SourceLocation WeakNameLoc = Tok.getLocation();
383   ConsumeToken();
384   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
385   SourceLocation AliasNameLoc = Tok.getLocation();
386   ConsumeToken();
387   Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
388                                WeakNameLoc, AliasNameLoc);
389
390 }
391
392 void Parser::HandlePragmaRedefineExtname() {
393   assert(Tok.is(tok::annot_pragma_redefine_extname));
394   SourceLocation RedefLoc = ConsumeToken();
395   IdentifierInfo *RedefName = Tok.getIdentifierInfo();
396   SourceLocation RedefNameLoc = Tok.getLocation();
397   ConsumeToken();
398   IdentifierInfo *AliasName = Tok.getIdentifierInfo();
399   SourceLocation AliasNameLoc = Tok.getLocation();
400   ConsumeToken();
401   Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
402                                      RedefNameLoc, AliasNameLoc);
403 }
404
405 void Parser::HandlePragmaFPContract() {
406   assert(Tok.is(tok::annot_pragma_fp_contract));
407   tok::OnOffSwitch OOS =
408     static_cast<tok::OnOffSwitch>(
409     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
410   Actions.ActOnPragmaFPContract(OOS);
411   ConsumeToken(); // The annotation token.
412 }
413
414 StmtResult Parser::HandlePragmaCaptured()
415 {
416   assert(Tok.is(tok::annot_pragma_captured));
417   ConsumeToken();
418
419   if (Tok.isNot(tok::l_brace)) {
420     PP.Diag(Tok, diag::err_expected) << tok::l_brace;
421     return StmtError();
422   }
423
424   SourceLocation Loc = Tok.getLocation();
425
426   ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope);
427   Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
428                                    /*NumParams=*/1);
429
430   StmtResult R = ParseCompoundStatement();
431   CapturedRegionScope.Exit();
432
433   if (R.isInvalid()) {
434     Actions.ActOnCapturedRegionError();
435     return StmtError();
436   }
437
438   return Actions.ActOnCapturedRegionEnd(R.get());
439 }
440
441 namespace {
442   typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
443 }
444
445 void Parser::HandlePragmaOpenCLExtension() {
446   assert(Tok.is(tok::annot_pragma_opencl_extension));
447   OpenCLExtData data =
448       OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
449   unsigned state = data.getInt();
450   IdentifierInfo *ename = data.getPointer();
451   SourceLocation NameLoc = Tok.getLocation();
452   ConsumeToken(); // The annotation token.
453
454   OpenCLOptions &f = Actions.getOpenCLOptions();
455   // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
456   // overriding all previously issued extension directives, but only if the
457   // behavior is set to disable."
458   if (state == 0 && ename->isStr("all")) {
459 #define OPENCLEXT(nm)   f.nm = 0;
460 #include "clang/Basic/OpenCLExtensions.def"
461   }
462 #define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
463 #include "clang/Basic/OpenCLExtensions.def"
464   else {
465     PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
466     return;
467   }
468 }
469
470 void Parser::HandlePragmaMSPointersToMembers() {
471   assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
472   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
473       static_cast<LangOptions::PragmaMSPointersToMembersKind>(
474           reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
475   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
476   Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
477 }
478
479 void Parser::HandlePragmaMSVtorDisp() {
480   assert(Tok.is(tok::annot_pragma_ms_vtordisp));
481   uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
482   Sema::PragmaVtorDispKind Kind =
483       static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
484   MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
485   SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
486   Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
487 }
488
489 void Parser::HandlePragmaMSPragma() {
490   assert(Tok.is(tok::annot_pragma_ms_pragma));
491   // Grab the tokens out of the annotation and enter them into the stream.
492   auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
493   PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
494   SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
495   assert(Tok.isAnyIdentifier());
496   StringRef PragmaName = Tok.getIdentifierInfo()->getName();
497   PP.Lex(Tok); // pragma kind
498
499   // Figure out which #pragma we're dealing with.  The switch has no default
500   // because lex shouldn't emit the annotation token for unrecognized pragmas.
501   typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
502   PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
503     .Case("data_seg", &Parser::HandlePragmaMSSegment)
504     .Case("bss_seg", &Parser::HandlePragmaMSSegment)
505     .Case("const_seg", &Parser::HandlePragmaMSSegment)
506     .Case("code_seg", &Parser::HandlePragmaMSSegment)
507     .Case("section", &Parser::HandlePragmaMSSection)
508     .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
509
510   if (!(this->*Handler)(PragmaName, PragmaLocation)) {
511     // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
512     // until eof (really end of line) to prevent follow-on errors.
513     while (Tok.isNot(tok::eof))
514       PP.Lex(Tok);
515     PP.Lex(Tok);
516   }
517 }
518
519 bool Parser::HandlePragmaMSSection(StringRef PragmaName,
520                                    SourceLocation PragmaLocation) {
521   if (Tok.isNot(tok::l_paren)) {
522     PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
523     return false;
524   }
525   PP.Lex(Tok); // (
526   // Parsing code for pragma section
527   if (Tok.isNot(tok::string_literal)) {
528     PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
529         << PragmaName;
530     return false;
531   }
532   ExprResult StringResult = ParseStringLiteralExpression();
533   if (StringResult.isInvalid())
534     return false; // Already diagnosed.
535   StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
536   if (SegmentName->getCharByteWidth() != 1) {
537     PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
538         << PragmaName;
539     return false;
540   }
541   int SectionFlags = ASTContext::PSF_Read;
542   bool SectionFlagsAreDefault = true;
543   while (Tok.is(tok::comma)) {
544     PP.Lex(Tok); // ,
545     // Ignore "long" and "short".
546     // They are undocumented, but widely used, section attributes which appear
547     // to do nothing.
548     if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
549       PP.Lex(Tok); // long/short
550       continue;
551     }
552
553     if (!Tok.isAnyIdentifier()) {
554       PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
555           << PragmaName;
556       return false;
557     }
558     ASTContext::PragmaSectionFlag Flag =
559       llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
560       Tok.getIdentifierInfo()->getName())
561       .Case("read", ASTContext::PSF_Read)
562       .Case("write", ASTContext::PSF_Write)
563       .Case("execute", ASTContext::PSF_Execute)
564       .Case("shared", ASTContext::PSF_Invalid)
565       .Case("nopage", ASTContext::PSF_Invalid)
566       .Case("nocache", ASTContext::PSF_Invalid)
567       .Case("discard", ASTContext::PSF_Invalid)
568       .Case("remove", ASTContext::PSF_Invalid)
569       .Default(ASTContext::PSF_None);
570     if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
571       PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
572                                   ? diag::warn_pragma_invalid_specific_action
573                                   : diag::warn_pragma_unsupported_action)
574           << PragmaName << Tok.getIdentifierInfo()->getName();
575       return false;
576     }
577     SectionFlags |= Flag;
578     SectionFlagsAreDefault = false;
579     PP.Lex(Tok); // Identifier
580   }
581   // If no section attributes are specified, the section will be marked as
582   // read/write.
583   if (SectionFlagsAreDefault)
584     SectionFlags |= ASTContext::PSF_Write;
585   if (Tok.isNot(tok::r_paren)) {
586     PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
587     return false;
588   }
589   PP.Lex(Tok); // )
590   if (Tok.isNot(tok::eof)) {
591     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
592         << PragmaName;
593     return false;
594   }
595   PP.Lex(Tok); // eof
596   Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
597   return true;
598 }
599
600 bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
601                                    SourceLocation PragmaLocation) {
602   if (Tok.isNot(tok::l_paren)) {
603     PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
604     return false;
605   }
606   PP.Lex(Tok); // (
607   Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
608   StringRef SlotLabel;
609   if (Tok.isAnyIdentifier()) {
610     StringRef PushPop = Tok.getIdentifierInfo()->getName();
611     if (PushPop == "push")
612       Action = Sema::PSK_Push;
613     else if (PushPop == "pop")
614       Action = Sema::PSK_Pop;
615     else {
616       PP.Diag(PragmaLocation,
617               diag::warn_pragma_expected_section_push_pop_or_name)
618           << PragmaName;
619       return false;
620     }
621     if (Action != Sema::PSK_Reset) {
622       PP.Lex(Tok); // push | pop
623       if (Tok.is(tok::comma)) {
624         PP.Lex(Tok); // ,
625         // If we've got a comma, we either need a label or a string.
626         if (Tok.isAnyIdentifier()) {
627           SlotLabel = Tok.getIdentifierInfo()->getName();
628           PP.Lex(Tok); // identifier
629           if (Tok.is(tok::comma))
630             PP.Lex(Tok);
631           else if (Tok.isNot(tok::r_paren)) {
632             PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
633                 << PragmaName;
634             return false;
635           }
636         }
637       } else if (Tok.isNot(tok::r_paren)) {
638         PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
639         return false;
640       }
641     }
642   }
643   // Grab the string literal for our section name.
644   StringLiteral *SegmentName = nullptr;
645   if (Tok.isNot(tok::r_paren)) {
646     if (Tok.isNot(tok::string_literal)) {
647       unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
648           diag::warn_pragma_expected_section_name :
649           diag::warn_pragma_expected_section_label_or_name :
650           diag::warn_pragma_expected_section_push_pop_or_name;
651       PP.Diag(PragmaLocation, DiagID) << PragmaName;
652       return false;
653     }
654     ExprResult StringResult = ParseStringLiteralExpression();
655     if (StringResult.isInvalid())
656       return false; // Already diagnosed.
657     SegmentName = cast<StringLiteral>(StringResult.get());
658     if (SegmentName->getCharByteWidth() != 1) {
659       PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
660           << PragmaName;
661       return false;
662     }
663     // Setting section "" has no effect
664     if (SegmentName->getLength())
665       Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
666   }
667   if (Tok.isNot(tok::r_paren)) {
668     PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
669     return false;
670   }
671   PP.Lex(Tok); // )
672   if (Tok.isNot(tok::eof)) {
673     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
674         << PragmaName;
675     return false;
676   }
677   PP.Lex(Tok); // eof
678   Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
679                            SegmentName, PragmaName);
680   return true;
681 }
682
683 // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
684 bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
685                                    SourceLocation PragmaLocation) {
686   if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
687     PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
688     return false;
689   }
690
691   if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
692                        PragmaName))
693     return false;
694
695   // Parse either the known section names or the string section name.
696   StringLiteral *SegmentName = nullptr;
697   if (Tok.isAnyIdentifier()) {
698     auto *II = Tok.getIdentifierInfo();
699     StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
700                             .Case("compiler", "\".CRT$XCC\"")
701                             .Case("lib", "\".CRT$XCL\"")
702                             .Case("user", "\".CRT$XCU\"")
703                             .Default("");
704
705     if (!Section.empty()) {
706       // Pretend the user wrote the appropriate string literal here.
707       Token Toks[1];
708       Toks[0].startToken();
709       Toks[0].setKind(tok::string_literal);
710       Toks[0].setLocation(Tok.getLocation());
711       Toks[0].setLiteralData(Section.data());
712       Toks[0].setLength(Section.size());
713       SegmentName =
714           cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
715       PP.Lex(Tok);
716     }
717   } else if (Tok.is(tok::string_literal)) {
718     ExprResult StringResult = ParseStringLiteralExpression();
719     if (StringResult.isInvalid())
720       return false;
721     SegmentName = cast<StringLiteral>(StringResult.get());
722     if (SegmentName->getCharByteWidth() != 1) {
723       PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
724           << PragmaName;
725       return false;
726     }
727     // FIXME: Add support for the '[, func-name]' part of the pragma.
728   }
729
730   if (!SegmentName) {
731     PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
732     return false;
733   }
734
735   if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
736                        PragmaName) ||
737       ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
738                        PragmaName))
739     return false;
740
741   Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
742   return true;
743 }
744
745 struct PragmaLoopHintInfo {
746   Token PragmaName;
747   Token Option;
748   Token *Toks;
749   size_t TokSize;
750   PragmaLoopHintInfo() : Toks(nullptr), TokSize(0) {}
751 };
752
753 static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
754   std::string PragmaString;
755   if (PragmaName.getIdentifierInfo()->getName() == "loop") {
756     PragmaString = "clang loop ";
757     PragmaString += Option.getIdentifierInfo()->getName();
758   } else {
759     assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
760            "Unexpected pragma name");
761     PragmaString = "unroll";
762   }
763   return PragmaString;
764 }
765
766 bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
767   assert(Tok.is(tok::annot_pragma_loop_hint));
768   PragmaLoopHintInfo *Info =
769       static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
770
771   IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
772   Hint.PragmaNameLoc = IdentifierLoc::create(
773       Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
774
775   // It is possible that the loop hint has no option identifier, such as
776   // #pragma unroll(4).
777   IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
778                                    ? Info->Option.getIdentifierInfo()
779                                    : nullptr;
780   Hint.OptionLoc = IdentifierLoc::create(
781       Actions.Context, Info->Option.getLocation(), OptionInfo);
782
783   Token *Toks = Info->Toks;
784   size_t TokSize = Info->TokSize;
785
786   // Return a valid hint if pragma unroll or nounroll were specified
787   // without an argument.
788   bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
789   bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
790   if (TokSize == 0 && (PragmaUnroll || PragmaNoUnroll)) {
791     ConsumeToken(); // The annotation token.
792     Hint.Range = Info->PragmaName.getLocation();
793     return true;
794   }
795
796   // The constant expression is always followed by an eof token, which increases
797   // the TokSize by 1.
798   assert(TokSize > 0 &&
799          "PragmaLoopHintInfo::Toks must contain at least one token.");
800
801   // If no option is specified the argument is assumed to be a constant expr.
802   bool OptionUnroll = false;
803   bool StateOption = false;
804   if (OptionInfo) { // Pragma Unroll does not specify an option.
805     OptionUnroll = OptionInfo->isStr("unroll");
806     StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
807                       .Case("vectorize", true)
808                       .Case("interleave", true)
809                       .Case("unroll", true)
810                       .Default(false);
811   }
812
813   // Verify loop hint has an argument.
814   if (Toks[0].is(tok::eof)) {
815     ConsumeToken(); // The annotation token.
816     Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
817         << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll;
818     return false;
819   }
820
821   // Validate the argument.
822   if (StateOption) {
823     ConsumeToken(); // The annotation token.
824     SourceLocation StateLoc = Toks[0].getLocation();
825     IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
826     if (!StateInfo ||
827         ((OptionUnroll ? !StateInfo->isStr("full")
828                        : !StateInfo->isStr("enable") &&
829                              !StateInfo->isStr("assume_safety")) &&
830          !StateInfo->isStr("disable"))) {
831       Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
832           << /*FullKeyword=*/OptionUnroll;
833       return false;
834     }
835     if (TokSize > 2)
836       Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
837           << PragmaLoopHintString(Info->PragmaName, Info->Option);
838     Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
839   } else {
840     // Enter constant expression including eof terminator into token stream.
841     PP.EnterTokenStream(Toks, TokSize, /*DisableMacroExpansion=*/false,
842                         /*OwnsTokens=*/false);
843     ConsumeToken(); // The annotation token.
844
845     ExprResult R = ParseConstantExpression();
846
847     // Tokens following an error in an ill-formed constant expression will
848     // remain in the token stream and must be removed.
849     if (Tok.isNot(tok::eof)) {
850       Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
851           << PragmaLoopHintString(Info->PragmaName, Info->Option);
852       while (Tok.isNot(tok::eof))
853         ConsumeAnyToken();
854     }
855
856     ConsumeToken(); // Consume the constant expression eof terminator.
857
858     if (R.isInvalid() ||
859         Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
860       return false;
861
862     // Argument is a constant expression with an integer type.
863     Hint.ValueExpr = R.get();
864   }
865
866   Hint.Range = SourceRange(Info->PragmaName.getLocation(),
867                            Info->Toks[TokSize - 1].getLocation());
868   return true;
869 }
870
871 // #pragma GCC visibility comes in two variants:
872 //   'push' '(' [visibility] ')'
873 //   'pop'
874 void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, 
875                                               PragmaIntroducerKind Introducer,
876                                               Token &VisTok) {
877   SourceLocation VisLoc = VisTok.getLocation();
878
879   Token Tok;
880   PP.LexUnexpandedToken(Tok);
881
882   const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
883
884   const IdentifierInfo *VisType;
885   if (PushPop && PushPop->isStr("pop")) {
886     VisType = nullptr;
887   } else if (PushPop && PushPop->isStr("push")) {
888     PP.LexUnexpandedToken(Tok);
889     if (Tok.isNot(tok::l_paren)) {
890       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
891         << "visibility";
892       return;
893     }
894     PP.LexUnexpandedToken(Tok);
895     VisType = Tok.getIdentifierInfo();
896     if (!VisType) {
897       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
898         << "visibility";
899       return;
900     }
901     PP.LexUnexpandedToken(Tok);
902     if (Tok.isNot(tok::r_paren)) {
903       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
904         << "visibility";
905       return;
906     }
907   } else {
908     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
909       << "visibility";
910     return;
911   }
912   SourceLocation EndLoc = Tok.getLocation();
913   PP.LexUnexpandedToken(Tok);
914   if (Tok.isNot(tok::eod)) {
915     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
916       << "visibility";
917     return;
918   }
919
920   Token *Toks = new Token[1];
921   Toks[0].startToken();
922   Toks[0].setKind(tok::annot_pragma_vis);
923   Toks[0].setLocation(VisLoc);
924   Toks[0].setAnnotationEndLoc(EndLoc);
925   Toks[0].setAnnotationValue(
926                           const_cast<void*>(static_cast<const void*>(VisType)));
927   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
928                       /*OwnsTokens=*/true);
929 }
930
931 // #pragma pack(...) comes in the following delicious flavors:
932 //   pack '(' [integer] ')'
933 //   pack '(' 'show' ')'
934 //   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
935 void PragmaPackHandler::HandlePragma(Preprocessor &PP, 
936                                      PragmaIntroducerKind Introducer,
937                                      Token &PackTok) {
938   SourceLocation PackLoc = PackTok.getLocation();
939
940   Token Tok;
941   PP.Lex(Tok);
942   if (Tok.isNot(tok::l_paren)) {
943     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
944     return;
945   }
946
947   Sema::PragmaPackKind Kind = Sema::PPK_Default;
948   IdentifierInfo *Name = nullptr;
949   Token Alignment;
950   Alignment.startToken();
951   SourceLocation LParenLoc = Tok.getLocation();
952   PP.Lex(Tok);
953   if (Tok.is(tok::numeric_constant)) {
954     Alignment = Tok;
955
956     PP.Lex(Tok);
957
958     // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
959     // the push/pop stack.
960     // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
961     if (PP.getLangOpts().ApplePragmaPack)
962       Kind = Sema::PPK_Push;
963   } else if (Tok.is(tok::identifier)) {
964     const IdentifierInfo *II = Tok.getIdentifierInfo();
965     if (II->isStr("show")) {
966       Kind = Sema::PPK_Show;
967       PP.Lex(Tok);
968     } else {
969       if (II->isStr("push")) {
970         Kind = Sema::PPK_Push;
971       } else if (II->isStr("pop")) {
972         Kind = Sema::PPK_Pop;
973       } else {
974         PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
975         return;
976       }
977       PP.Lex(Tok);
978
979       if (Tok.is(tok::comma)) {
980         PP.Lex(Tok);
981
982         if (Tok.is(tok::numeric_constant)) {
983           Alignment = Tok;
984
985           PP.Lex(Tok);
986         } else if (Tok.is(tok::identifier)) {
987           Name = Tok.getIdentifierInfo();
988           PP.Lex(Tok);
989
990           if (Tok.is(tok::comma)) {
991             PP.Lex(Tok);
992
993             if (Tok.isNot(tok::numeric_constant)) {
994               PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
995               return;
996             }
997
998             Alignment = Tok;
999
1000             PP.Lex(Tok);
1001           }
1002         } else {
1003           PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1004           return;
1005         }
1006       }
1007     }
1008   } else if (PP.getLangOpts().ApplePragmaPack) {
1009     // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1010     // the push/pop stack.
1011     // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1012     Kind = Sema::PPK_Pop;
1013   }
1014
1015   if (Tok.isNot(tok::r_paren)) {
1016     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1017     return;
1018   }
1019
1020   SourceLocation RParenLoc = Tok.getLocation();
1021   PP.Lex(Tok);
1022   if (Tok.isNot(tok::eod)) {
1023     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1024     return;
1025   }
1026
1027   PragmaPackInfo *Info = 
1028     (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
1029       sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
1030   new (Info) PragmaPackInfo();
1031   Info->Kind = Kind;
1032   Info->Name = Name;
1033   Info->Alignment = Alignment;
1034   Info->LParenLoc = LParenLoc;
1035   Info->RParenLoc = RParenLoc;
1036
1037   Token *Toks = 
1038     (Token*) PP.getPreprocessorAllocator().Allocate(
1039       sizeof(Token) * 1, llvm::alignOf<Token>());
1040   new (Toks) Token();
1041   Toks[0].startToken();
1042   Toks[0].setKind(tok::annot_pragma_pack);
1043   Toks[0].setLocation(PackLoc);
1044   Toks[0].setAnnotationEndLoc(RParenLoc);
1045   Toks[0].setAnnotationValue(static_cast<void*>(Info));
1046   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1047                       /*OwnsTokens=*/false);
1048 }
1049
1050 // #pragma ms_struct on
1051 // #pragma ms_struct off
1052 void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, 
1053                                          PragmaIntroducerKind Introducer,
1054                                          Token &MSStructTok) {
1055   Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
1056   
1057   Token Tok;
1058   PP.Lex(Tok);
1059   if (Tok.isNot(tok::identifier)) {
1060     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1061     return;
1062   }
1063   SourceLocation EndLoc = Tok.getLocation();
1064   const IdentifierInfo *II = Tok.getIdentifierInfo();
1065   if (II->isStr("on")) {
1066     Kind = Sema::PMSST_ON;
1067     PP.Lex(Tok);
1068   }
1069   else if (II->isStr("off") || II->isStr("reset"))
1070     PP.Lex(Tok);
1071   else {
1072     PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1073     return;
1074   }
1075   
1076   if (Tok.isNot(tok::eod)) {
1077     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1078       << "ms_struct";
1079     return;
1080   }
1081
1082   Token *Toks =
1083     (Token*) PP.getPreprocessorAllocator().Allocate(
1084       sizeof(Token) * 1, llvm::alignOf<Token>());
1085   new (Toks) Token();
1086   Toks[0].startToken();
1087   Toks[0].setKind(tok::annot_pragma_msstruct);
1088   Toks[0].setLocation(MSStructTok.getLocation());
1089   Toks[0].setAnnotationEndLoc(EndLoc);
1090   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1091                              static_cast<uintptr_t>(Kind)));
1092   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1093                       /*OwnsTokens=*/false);
1094 }
1095
1096 // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1097 // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1098 static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1099                              bool IsOptions) {
1100   Token Tok;
1101
1102   if (IsOptions) {
1103     PP.Lex(Tok);
1104     if (Tok.isNot(tok::identifier) ||
1105         !Tok.getIdentifierInfo()->isStr("align")) {
1106       PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1107       return;
1108     }
1109   }
1110
1111   PP.Lex(Tok);
1112   if (Tok.isNot(tok::equal)) {
1113     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1114       << IsOptions;
1115     return;
1116   }
1117
1118   PP.Lex(Tok);
1119   if (Tok.isNot(tok::identifier)) {
1120     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1121       << (IsOptions ? "options" : "align");
1122     return;
1123   }
1124
1125   Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1126   const IdentifierInfo *II = Tok.getIdentifierInfo();
1127   if (II->isStr("native"))
1128     Kind = Sema::POAK_Native;
1129   else if (II->isStr("natural"))
1130     Kind = Sema::POAK_Natural;
1131   else if (II->isStr("packed"))
1132     Kind = Sema::POAK_Packed;
1133   else if (II->isStr("power"))
1134     Kind = Sema::POAK_Power;
1135   else if (II->isStr("mac68k"))
1136     Kind = Sema::POAK_Mac68k;
1137   else if (II->isStr("reset"))
1138     Kind = Sema::POAK_Reset;
1139   else {
1140     PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1141       << IsOptions;
1142     return;
1143   }
1144
1145   SourceLocation EndLoc = Tok.getLocation();
1146   PP.Lex(Tok);
1147   if (Tok.isNot(tok::eod)) {
1148     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1149       << (IsOptions ? "options" : "align");
1150     return;
1151   }
1152
1153   Token *Toks =
1154     (Token*) PP.getPreprocessorAllocator().Allocate(
1155       sizeof(Token) * 1, llvm::alignOf<Token>());
1156   new (Toks) Token();
1157   Toks[0].startToken();
1158   Toks[0].setKind(tok::annot_pragma_align);
1159   Toks[0].setLocation(FirstTok.getLocation());
1160   Toks[0].setAnnotationEndLoc(EndLoc);
1161   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1162                              static_cast<uintptr_t>(Kind)));
1163   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1164                       /*OwnsTokens=*/false);
1165 }
1166
1167 void PragmaAlignHandler::HandlePragma(Preprocessor &PP, 
1168                                       PragmaIntroducerKind Introducer,
1169                                       Token &AlignTok) {
1170   ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1171 }
1172
1173 void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, 
1174                                         PragmaIntroducerKind Introducer,
1175                                         Token &OptionsTok) {
1176   ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1177 }
1178
1179 // #pragma unused(identifier)
1180 void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, 
1181                                        PragmaIntroducerKind Introducer,
1182                                        Token &UnusedTok) {
1183   // FIXME: Should we be expanding macros here? My guess is no.
1184   SourceLocation UnusedLoc = UnusedTok.getLocation();
1185
1186   // Lex the left '('.
1187   Token Tok;
1188   PP.Lex(Tok);
1189   if (Tok.isNot(tok::l_paren)) {
1190     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1191     return;
1192   }
1193
1194   // Lex the declaration reference(s).
1195   SmallVector<Token, 5> Identifiers;
1196   SourceLocation RParenLoc;
1197   bool LexID = true;
1198
1199   while (true) {
1200     PP.Lex(Tok);
1201
1202     if (LexID) {
1203       if (Tok.is(tok::identifier)) {
1204         Identifiers.push_back(Tok);
1205         LexID = false;
1206         continue;
1207       }
1208
1209       // Illegal token!
1210       PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1211       return;
1212     }
1213
1214     // We are execting a ')' or a ','.
1215     if (Tok.is(tok::comma)) {
1216       LexID = true;
1217       continue;
1218     }
1219
1220     if (Tok.is(tok::r_paren)) {
1221       RParenLoc = Tok.getLocation();
1222       break;
1223     }
1224
1225     // Illegal token!
1226     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1227     return;
1228   }
1229
1230   PP.Lex(Tok);
1231   if (Tok.isNot(tok::eod)) {
1232     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1233         "unused";
1234     return;
1235   }
1236
1237   // Verify that we have a location for the right parenthesis.
1238   assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1239   assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1240
1241   // For each identifier token, insert into the token stream a
1242   // annot_pragma_unused token followed by the identifier token.
1243   // This allows us to cache a "#pragma unused" that occurs inside an inline
1244   // C++ member function.
1245
1246   Token *Toks = 
1247     (Token*) PP.getPreprocessorAllocator().Allocate(
1248       sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
1249   for (unsigned i=0; i != Identifiers.size(); i++) {
1250     Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1251     pragmaUnusedTok.startToken();
1252     pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1253     pragmaUnusedTok.setLocation(UnusedLoc);
1254     idTok = Identifiers[i];
1255   }
1256   PP.EnterTokenStream(Toks, 2*Identifiers.size(),
1257                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1258 }
1259
1260 // #pragma weak identifier
1261 // #pragma weak identifier '=' identifier
1262 void PragmaWeakHandler::HandlePragma(Preprocessor &PP, 
1263                                      PragmaIntroducerKind Introducer,
1264                                      Token &WeakTok) {
1265   SourceLocation WeakLoc = WeakTok.getLocation();
1266
1267   Token Tok;
1268   PP.Lex(Tok);
1269   if (Tok.isNot(tok::identifier)) {
1270     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
1271     return;
1272   }
1273
1274   Token WeakName = Tok;
1275   bool HasAlias = false;
1276   Token AliasName;
1277
1278   PP.Lex(Tok);
1279   if (Tok.is(tok::equal)) {
1280     HasAlias = true;
1281     PP.Lex(Tok);
1282     if (Tok.isNot(tok::identifier)) {
1283       PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1284           << "weak";
1285       return;
1286     }
1287     AliasName = Tok;
1288     PP.Lex(Tok);
1289   }
1290
1291   if (Tok.isNot(tok::eod)) {
1292     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
1293     return;
1294   }
1295
1296   if (HasAlias) {
1297     Token *Toks = 
1298       (Token*) PP.getPreprocessorAllocator().Allocate(
1299         sizeof(Token) * 3, llvm::alignOf<Token>());
1300     Token &pragmaUnusedTok = Toks[0];
1301     pragmaUnusedTok.startToken();
1302     pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
1303     pragmaUnusedTok.setLocation(WeakLoc);
1304     pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
1305     Toks[1] = WeakName;
1306     Toks[2] = AliasName;
1307     PP.EnterTokenStream(Toks, 3,
1308                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1309   } else {
1310     Token *Toks = 
1311       (Token*) PP.getPreprocessorAllocator().Allocate(
1312         sizeof(Token) * 2, llvm::alignOf<Token>());
1313     Token &pragmaUnusedTok = Toks[0];
1314     pragmaUnusedTok.startToken();
1315     pragmaUnusedTok.setKind(tok::annot_pragma_weak);
1316     pragmaUnusedTok.setLocation(WeakLoc);
1317     pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
1318     Toks[1] = WeakName;
1319     PP.EnterTokenStream(Toks, 2,
1320                         /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1321   }
1322 }
1323
1324 // #pragma redefine_extname identifier identifier
1325 void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, 
1326                                                PragmaIntroducerKind Introducer,
1327                                                 Token &RedefToken) {
1328   SourceLocation RedefLoc = RedefToken.getLocation();
1329
1330   Token Tok;
1331   PP.Lex(Tok);
1332   if (Tok.isNot(tok::identifier)) {
1333     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1334       "redefine_extname";
1335     return;
1336   }
1337
1338   Token RedefName = Tok;
1339   PP.Lex(Tok);
1340
1341   if (Tok.isNot(tok::identifier)) {
1342     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1343         << "redefine_extname";
1344     return;
1345   }
1346
1347   Token AliasName = Tok;
1348   PP.Lex(Tok);
1349
1350   if (Tok.isNot(tok::eod)) {
1351     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1352       "redefine_extname";
1353     return;
1354   }
1355
1356   Token *Toks = 
1357     (Token*) PP.getPreprocessorAllocator().Allocate(
1358       sizeof(Token) * 3, llvm::alignOf<Token>());
1359   Token &pragmaRedefTok = Toks[0];
1360   pragmaRedefTok.startToken();
1361   pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
1362   pragmaRedefTok.setLocation(RedefLoc);
1363   pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
1364   Toks[1] = RedefName;
1365   Toks[2] = AliasName;
1366   PP.EnterTokenStream(Toks, 3,
1367                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
1368 }
1369
1370
1371 void
1372 PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 
1373                                       PragmaIntroducerKind Introducer,
1374                                       Token &Tok) {
1375   tok::OnOffSwitch OOS;
1376   if (PP.LexOnOffSwitch(OOS))
1377     return;
1378
1379   Token *Toks =
1380     (Token*) PP.getPreprocessorAllocator().Allocate(
1381       sizeof(Token) * 1, llvm::alignOf<Token>());
1382   new (Toks) Token();
1383   Toks[0].startToken();
1384   Toks[0].setKind(tok::annot_pragma_fp_contract);
1385   Toks[0].setLocation(Tok.getLocation());
1386   Toks[0].setAnnotationEndLoc(Tok.getLocation());
1387   Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1388                              static_cast<uintptr_t>(OOS)));
1389   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1390                       /*OwnsTokens=*/false);
1391 }
1392
1393 void 
1394 PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, 
1395                                            PragmaIntroducerKind Introducer,
1396                                            Token &Tok) {
1397   PP.LexUnexpandedToken(Tok);
1398   if (Tok.isNot(tok::identifier)) {
1399     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
1400       "OPENCL";
1401     return;
1402   }
1403   IdentifierInfo *ename = Tok.getIdentifierInfo();
1404   SourceLocation NameLoc = Tok.getLocation();
1405
1406   PP.Lex(Tok);
1407   if (Tok.isNot(tok::colon)) {
1408     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
1409     return;
1410   }
1411
1412   PP.Lex(Tok);
1413   if (Tok.isNot(tok::identifier)) {
1414     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1415     return;
1416   }
1417   IdentifierInfo *op = Tok.getIdentifierInfo();
1418
1419   unsigned state;
1420   if (op->isStr("enable")) {
1421     state = 1;
1422   } else if (op->isStr("disable")) {
1423     state = 0;
1424   } else {
1425     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
1426     return;
1427   }
1428   SourceLocation StateLoc = Tok.getLocation();
1429
1430   PP.Lex(Tok);
1431   if (Tok.isNot(tok::eod)) {
1432     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1433       "OPENCL EXTENSION";
1434     return;
1435   }
1436
1437   OpenCLExtData data(ename, state);
1438   Token *Toks =
1439     (Token*) PP.getPreprocessorAllocator().Allocate(
1440       sizeof(Token) * 1, llvm::alignOf<Token>());
1441   new (Toks) Token();
1442   Toks[0].startToken();
1443   Toks[0].setKind(tok::annot_pragma_opencl_extension);
1444   Toks[0].setLocation(NameLoc);
1445   Toks[0].setAnnotationValue(data.getOpaqueValue());
1446   Toks[0].setAnnotationEndLoc(StateLoc);
1447   PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
1448                       /*OwnsTokens=*/false);
1449
1450   if (PP.getPPCallbacks())
1451     PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, 
1452                                                StateLoc, state);
1453 }
1454
1455 /// \brief Handle '#pragma omp ...' when OpenMP is disabled.
1456 ///
1457 void
1458 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
1459                                     PragmaIntroducerKind Introducer,
1460                                     Token &FirstTok) {
1461   if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
1462                                      FirstTok.getLocation())) {
1463     PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
1464     PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
1465                                     diag::Severity::Ignored, SourceLocation());
1466   }
1467   PP.DiscardUntilEndOfDirective();
1468 }
1469
1470 /// \brief Handle '#pragma omp ...' when OpenMP is enabled.
1471 ///
1472 void
1473 PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
1474                                   PragmaIntroducerKind Introducer,
1475                                   Token &FirstTok) {
1476   SmallVector<Token, 16> Pragma;
1477   Token Tok;
1478   Tok.startToken();
1479   Tok.setKind(tok::annot_pragma_openmp);
1480   Tok.setLocation(FirstTok.getLocation());
1481
1482   while (Tok.isNot(tok::eod)) {
1483     Pragma.push_back(Tok);
1484     PP.Lex(Tok);
1485   }
1486   SourceLocation EodLoc = Tok.getLocation();
1487   Tok.startToken();
1488   Tok.setKind(tok::annot_pragma_openmp_end);
1489   Tok.setLocation(EodLoc);
1490   Pragma.push_back(Tok);
1491
1492   Token *Toks = new Token[Pragma.size()];
1493   std::copy(Pragma.begin(), Pragma.end(), Toks);
1494   PP.EnterTokenStream(Toks, Pragma.size(),
1495                       /*DisableMacroExpansion=*/false, /*OwnsTokens=*/true);
1496 }
1497
1498 /// \brief Handle '#pragma pointers_to_members'
1499 // The grammar for this pragma is as follows:
1500 //
1501 // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
1502 //
1503 // #pragma pointers_to_members '(' 'best_case' ')'
1504 // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
1505 // #pragma pointers_to_members '(' inheritance-model ')'
1506 void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
1507                                              PragmaIntroducerKind Introducer,
1508                                              Token &Tok) {
1509   SourceLocation PointersToMembersLoc = Tok.getLocation();
1510   PP.Lex(Tok);
1511   if (Tok.isNot(tok::l_paren)) {
1512     PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
1513       << "pointers_to_members";
1514     return;
1515   }
1516   PP.Lex(Tok);
1517   const IdentifierInfo *Arg = Tok.getIdentifierInfo();
1518   if (!Arg) {
1519     PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1520       << "pointers_to_members";
1521     return;
1522   }
1523   PP.Lex(Tok);
1524
1525   LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
1526   if (Arg->isStr("best_case")) {
1527     RepresentationMethod = LangOptions::PPTMK_BestCase;
1528   } else {
1529     if (Arg->isStr("full_generality")) {
1530       if (Tok.is(tok::comma)) {
1531         PP.Lex(Tok);
1532
1533         Arg = Tok.getIdentifierInfo();
1534         if (!Arg) {
1535           PP.Diag(Tok.getLocation(),
1536                   diag::err_pragma_pointers_to_members_unknown_kind)
1537               << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
1538           return;
1539         }
1540         PP.Lex(Tok);
1541       } else if (Tok.is(tok::r_paren)) {
1542         // #pragma pointers_to_members(full_generality) implicitly specifies
1543         // virtual_inheritance.
1544         Arg = nullptr;
1545         RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1546       } else {
1547         PP.Diag(Tok.getLocation(), diag::err_expected_punc)
1548             << "full_generality";
1549         return;
1550       }
1551     }
1552
1553     if (Arg) {
1554       if (Arg->isStr("single_inheritance")) {
1555         RepresentationMethod =
1556             LangOptions::PPTMK_FullGeneralitySingleInheritance;
1557       } else if (Arg->isStr("multiple_inheritance")) {
1558         RepresentationMethod =
1559             LangOptions::PPTMK_FullGeneralityMultipleInheritance;
1560       } else if (Arg->isStr("virtual_inheritance")) {
1561         RepresentationMethod =
1562             LangOptions::PPTMK_FullGeneralityVirtualInheritance;
1563       } else {
1564         PP.Diag(Tok.getLocation(),
1565                 diag::err_pragma_pointers_to_members_unknown_kind)
1566             << Arg << /*HasPointerDeclaration*/ 1;
1567         return;
1568       }
1569     }
1570   }
1571
1572   if (Tok.isNot(tok::r_paren)) {
1573     PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
1574         << (Arg ? Arg->getName() : "full_generality");
1575     return;
1576   }
1577
1578   SourceLocation EndLoc = Tok.getLocation();
1579   PP.Lex(Tok);
1580   if (Tok.isNot(tok::eod)) {
1581     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1582       << "pointers_to_members";
1583     return;
1584   }
1585
1586   Token AnnotTok;
1587   AnnotTok.startToken();
1588   AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
1589   AnnotTok.setLocation(PointersToMembersLoc);
1590   AnnotTok.setAnnotationEndLoc(EndLoc);
1591   AnnotTok.setAnnotationValue(
1592       reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
1593   PP.EnterToken(AnnotTok);
1594 }
1595
1596 /// \brief Handle '#pragma vtordisp'
1597 // The grammar for this pragma is as follows:
1598 //
1599 // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
1600 //
1601 // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
1602 // #pragma vtordisp '(' 'pop' ')'
1603 // #pragma vtordisp '(' ')'
1604 void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
1605                                     PragmaIntroducerKind Introducer,
1606                                     Token &Tok) {
1607   SourceLocation VtorDispLoc = Tok.getLocation();
1608   PP.Lex(Tok);
1609   if (Tok.isNot(tok::l_paren)) {
1610     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
1611     return;
1612   }
1613   PP.Lex(Tok);
1614
1615   Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
1616   const IdentifierInfo *II = Tok.getIdentifierInfo();
1617   if (II) {
1618     if (II->isStr("push")) {
1619       // #pragma vtordisp(push, mode)
1620       PP.Lex(Tok);
1621       if (Tok.isNot(tok::comma)) {
1622         PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
1623         return;
1624       }
1625       PP.Lex(Tok);
1626       Kind = Sema::PVDK_Push;
1627       // not push, could be on/off
1628     } else if (II->isStr("pop")) {
1629       // #pragma vtordisp(pop)
1630       PP.Lex(Tok);
1631       Kind = Sema::PVDK_Pop;
1632     }
1633     // not push or pop, could be on/off
1634   } else {
1635     if (Tok.is(tok::r_paren)) {
1636       // #pragma vtordisp()
1637       Kind = Sema::PVDK_Reset;
1638     }
1639   }
1640
1641
1642   uint64_t Value = 0;
1643   if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
1644     const IdentifierInfo *II = Tok.getIdentifierInfo();
1645     if (II && II->isStr("off")) {
1646       PP.Lex(Tok);
1647       Value = 0;
1648     } else if (II && II->isStr("on")) {
1649       PP.Lex(Tok);
1650       Value = 1;
1651     } else if (Tok.is(tok::numeric_constant) &&
1652                PP.parseSimpleIntegerLiteral(Tok, Value)) {
1653       if (Value > 2) {
1654         PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
1655             << 0 << 2 << "vtordisp";
1656         return;
1657       }
1658     } else {
1659       PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1660           << "vtordisp";
1661       return;
1662     }
1663   }
1664
1665   // Finish the pragma: ')' $
1666   if (Tok.isNot(tok::r_paren)) {
1667     PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
1668     return;
1669   }
1670   SourceLocation EndLoc = Tok.getLocation();
1671   PP.Lex(Tok);
1672   if (Tok.isNot(tok::eod)) {
1673     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1674         << "vtordisp";
1675     return;
1676   }
1677
1678   // Enter the annotation.
1679   Token AnnotTok;
1680   AnnotTok.startToken();
1681   AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
1682   AnnotTok.setLocation(VtorDispLoc);
1683   AnnotTok.setAnnotationEndLoc(EndLoc);
1684   AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
1685       static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
1686   PP.EnterToken(AnnotTok);
1687 }
1688
1689 /// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting
1690 /// an annotation token.
1691 void PragmaMSPragma::HandlePragma(Preprocessor &PP,
1692                                   PragmaIntroducerKind Introducer,
1693                                   Token &Tok) {
1694   Token EoF, AnnotTok;
1695   EoF.startToken();
1696   EoF.setKind(tok::eof);
1697   AnnotTok.startToken();
1698   AnnotTok.setKind(tok::annot_pragma_ms_pragma);
1699   AnnotTok.setLocation(Tok.getLocation());
1700   AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1701   SmallVector<Token, 8> TokenVector;
1702   // Suck up all of the tokens before the eod.
1703   for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
1704     TokenVector.push_back(Tok);
1705     AnnotTok.setAnnotationEndLoc(Tok.getLocation());
1706   }
1707   // Add a sentinal EoF token to the end of the list.
1708   TokenVector.push_back(EoF);
1709   // We must allocate this array with new because EnterTokenStream is going to
1710   // delete it later.
1711   Token *TokenArray = new Token[TokenVector.size()];
1712   std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
1713   auto Value = new (PP.getPreprocessorAllocator())
1714       std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
1715   AnnotTok.setAnnotationValue(Value);
1716   PP.EnterToken(AnnotTok);
1717 }
1718
1719 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
1720 ///
1721 /// The syntax is:
1722 /// \code
1723 ///   #pragma detect_mismatch("name", "value")
1724 /// \endcode
1725 /// Where 'name' and 'value' are quoted strings.  The values are embedded in
1726 /// the object file and passed along to the linker.  If the linker detects a
1727 /// mismatch in the object file's values for the given name, a LNK2038 error
1728 /// is emitted.  See MSDN for more details.
1729 void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
1730                                                PragmaIntroducerKind Introducer,
1731                                                Token &Tok) {
1732   SourceLocation CommentLoc = Tok.getLocation();
1733   PP.Lex(Tok);
1734   if (Tok.isNot(tok::l_paren)) {
1735     PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
1736     return;
1737   }
1738
1739   // Read the name to embed, which must be a string literal.
1740   std::string NameString;
1741   if (!PP.LexStringLiteral(Tok, NameString,
1742                            "pragma detect_mismatch",
1743                            /*MacroExpansion=*/true))
1744     return;
1745
1746   // Read the comma followed by a second string literal.
1747   std::string ValueString;
1748   if (Tok.isNot(tok::comma)) {
1749     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1750     return;
1751   }
1752
1753   if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
1754                            /*MacroExpansion=*/true))
1755     return;
1756
1757   if (Tok.isNot(tok::r_paren)) {
1758     PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1759     return;
1760   }
1761   PP.Lex(Tok);  // Eat the r_paren.
1762
1763   if (Tok.isNot(tok::eod)) {
1764     PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
1765     return;
1766   }
1767
1768   // If the pragma is lexically sound, notify any interested PPCallbacks.
1769   if (PP.getPPCallbacks())
1770     PP.getPPCallbacks()->PragmaDetectMismatch(CommentLoc, NameString,
1771                                               ValueString);
1772
1773   Actions.ActOnPragmaDetectMismatch(NameString, ValueString);
1774 }
1775
1776 /// \brief Handle the microsoft \#pragma comment extension.
1777 ///
1778 /// The syntax is:
1779 /// \code
1780 ///   #pragma comment(linker, "foo")
1781 /// \endcode
1782 /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
1783 /// "foo" is a string, which is fully macro expanded, and permits string
1784 /// concatenation, embedded escape characters etc.  See MSDN for more details.
1785 void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
1786                                         PragmaIntroducerKind Introducer,
1787                                         Token &Tok) {
1788   SourceLocation CommentLoc = Tok.getLocation();
1789   PP.Lex(Tok);
1790   if (Tok.isNot(tok::l_paren)) {
1791     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1792     return;
1793   }
1794
1795   // Read the identifier.
1796   PP.Lex(Tok);
1797   if (Tok.isNot(tok::identifier)) {
1798     PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
1799     return;
1800   }
1801
1802   // Verify that this is one of the 5 whitelisted options.
1803   IdentifierInfo *II = Tok.getIdentifierInfo();
1804   Sema::PragmaMSCommentKind Kind =
1805     llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName())
1806     .Case("linker",   Sema::PCK_Linker)
1807     .Case("lib",      Sema::PCK_Lib)
1808     .Case("compiler", Sema::PCK_Compiler)
1809     .Case("exestr",   Sema::PCK_ExeStr)
1810     .Case("user",     Sema::PCK_User)
1811     .Default(Sema::PCK_Unknown);
1812   if (Kind == Sema::PCK_Unknown) {
1813     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
1814     return;
1815   }
1816
1817   // On PS4, issue a warning about any pragma comments other than
1818   // #pragma comment lib.
1819   if (PP.getTargetInfo().getTriple().isPS4() && Kind != Sema::PCK_Lib) {
1820     PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
1821       << II->getName();
1822     return;
1823   }
1824
1825   // Read the optional string if present.
1826   PP.Lex(Tok);
1827   std::string ArgumentString;
1828   if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
1829                                                  "pragma comment",
1830                                                  /*MacroExpansion=*/true))
1831     return;
1832
1833   // FIXME: warn that 'exestr' is deprecated.
1834   // FIXME: If the kind is "compiler" warn if the string is present (it is
1835   // ignored).
1836   // The MSDN docs say that "lib" and "linker" require a string and have a short
1837   // whitelist of linker options they support, but in practice MSVC doesn't
1838   // issue a diagnostic.  Therefore neither does clang.
1839
1840   if (Tok.isNot(tok::r_paren)) {
1841     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1842     return;
1843   }
1844   PP.Lex(Tok);  // eat the r_paren.
1845
1846   if (Tok.isNot(tok::eod)) {
1847     PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
1848     return;
1849   }
1850
1851   // If the pragma is lexically sound, notify any interested PPCallbacks.
1852   if (PP.getPPCallbacks())
1853     PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
1854
1855   Actions.ActOnPragmaMSComment(Kind, ArgumentString);
1856 }
1857
1858 // #pragma clang optimize off
1859 // #pragma clang optimize on
1860 void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, 
1861                                         PragmaIntroducerKind Introducer,
1862                                         Token &FirstToken) {
1863   Token Tok;
1864   PP.Lex(Tok);
1865   if (Tok.is(tok::eod)) {
1866     PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
1867         << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
1868     return;
1869   }
1870   if (Tok.isNot(tok::identifier)) {
1871     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1872       << PP.getSpelling(Tok);
1873     return;
1874   }
1875   const IdentifierInfo *II = Tok.getIdentifierInfo();
1876   // The only accepted values are 'on' or 'off'.
1877   bool IsOn = false;
1878   if (II->isStr("on")) {
1879     IsOn = true;
1880   } else if (!II->isStr("off")) {
1881     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
1882       << PP.getSpelling(Tok);
1883     return;
1884   }
1885   PP.Lex(Tok);
1886   
1887   if (Tok.isNot(tok::eod)) {
1888     PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
1889       << PP.getSpelling(Tok);
1890     return;
1891   }
1892
1893   Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
1894 }
1895
1896 /// \brief Parses loop or unroll pragma hint value and fills in Info.
1897 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
1898                                Token Option, bool ValueInParens,
1899                                PragmaLoopHintInfo &Info) {
1900   SmallVector<Token, 1> ValueList;
1901   int OpenParens = ValueInParens ? 1 : 0;
1902   // Read constant expression.
1903   while (Tok.isNot(tok::eod)) {
1904     if (Tok.is(tok::l_paren))
1905       OpenParens++;
1906     else if (Tok.is(tok::r_paren)) {
1907       OpenParens--;
1908       if (OpenParens == 0 && ValueInParens)
1909         break;
1910     }
1911
1912     ValueList.push_back(Tok);
1913     PP.Lex(Tok);
1914   }
1915
1916   if (ValueInParens) {
1917     // Read ')'
1918     if (Tok.isNot(tok::r_paren)) {
1919       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
1920       return true;
1921     }
1922     PP.Lex(Tok);
1923   }
1924
1925   Token EOFTok;
1926   EOFTok.startToken();
1927   EOFTok.setKind(tok::eof);
1928   EOFTok.setLocation(Tok.getLocation());
1929   ValueList.push_back(EOFTok); // Terminates expression for parsing.
1930
1931   Token *TokenArray = (Token *)PP.getPreprocessorAllocator().Allocate(
1932       ValueList.size() * sizeof(Token), llvm::alignOf<Token>());
1933   std::copy(ValueList.begin(), ValueList.end(), TokenArray);
1934   Info.Toks = TokenArray;
1935   Info.TokSize = ValueList.size();
1936
1937   Info.PragmaName = PragmaName;
1938   Info.Option = Option;
1939   return false;
1940 }
1941
1942 /// \brief Handle the \#pragma clang loop directive.
1943 ///  #pragma clang 'loop' loop-hints
1944 ///
1945 ///  loop-hints:
1946 ///    loop-hint loop-hints[opt]
1947 ///
1948 ///  loop-hint:
1949 ///    'vectorize' '(' loop-hint-keyword ')'
1950 ///    'interleave' '(' loop-hint-keyword ')'
1951 ///    'unroll' '(' unroll-hint-keyword ')'
1952 ///    'vectorize_width' '(' loop-hint-value ')'
1953 ///    'interleave_count' '(' loop-hint-value ')'
1954 ///    'unroll_count' '(' loop-hint-value ')'
1955 ///
1956 ///  loop-hint-keyword:
1957 ///    'enable'
1958 ///    'disable'
1959 ///    'assume_safety'
1960 ///
1961 ///  unroll-hint-keyword:
1962 ///    'full'
1963 ///    'disable'
1964 ///
1965 ///  loop-hint-value:
1966 ///    constant-expression
1967 ///
1968 /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
1969 /// try vectorizing the instructions of the loop it precedes. Specifying
1970 /// interleave(enable) or interleave_count(_value_) instructs llvm to try
1971 /// interleaving multiple iterations of the loop it precedes. The width of the
1972 /// vector instructions is specified by vectorize_width() and the number of
1973 /// interleaved loop iterations is specified by interleave_count(). Specifying a
1974 /// value of 1 effectively disables vectorization/interleaving, even if it is
1975 /// possible and profitable, and 0 is invalid. The loop vectorizer currently
1976 /// only works on inner loops.
1977 ///
1978 /// The unroll and unroll_count directives control the concatenation
1979 /// unroller. Specifying unroll(full) instructs llvm to try to
1980 /// unroll the loop completely, and unroll(disable) disables unrolling
1981 /// for the loop. Specifying unroll_count(_value_) instructs llvm to
1982 /// try to unroll the loop the number of times indicated by the value.
1983 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
1984                                          PragmaIntroducerKind Introducer,
1985                                          Token &Tok) {
1986   // Incoming token is "loop" from "#pragma clang loop".
1987   Token PragmaName = Tok;
1988   SmallVector<Token, 1> TokenList;
1989
1990   // Lex the optimization option and verify it is an identifier.
1991   PP.Lex(Tok);
1992   if (Tok.isNot(tok::identifier)) {
1993     PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
1994         << /*MissingOption=*/true << "";
1995     return;
1996   }
1997
1998   while (Tok.is(tok::identifier)) {
1999     Token Option = Tok;
2000     IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2001
2002     bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2003                            .Case("vectorize", true)
2004                            .Case("interleave", true)
2005                            .Case("unroll", true)
2006                            .Case("vectorize_width", true)
2007                            .Case("interleave_count", true)
2008                            .Case("unroll_count", true)
2009                            .Default(false);
2010     if (!OptionValid) {
2011       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2012           << /*MissingOption=*/false << OptionInfo;
2013       return;
2014     }
2015     PP.Lex(Tok);
2016
2017     // Read '('
2018     if (Tok.isNot(tok::l_paren)) {
2019       PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2020       return;
2021     }
2022     PP.Lex(Tok);
2023
2024     auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2025     if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2026                            *Info))
2027       return;
2028
2029     // Generate the loop hint token.
2030     Token LoopHintTok;
2031     LoopHintTok.startToken();
2032     LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2033     LoopHintTok.setLocation(PragmaName.getLocation());
2034     LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2035     LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2036     TokenList.push_back(LoopHintTok);
2037   }
2038
2039   if (Tok.isNot(tok::eod)) {
2040     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2041         << "clang loop";
2042     return;
2043   }
2044
2045   Token *TokenArray = new Token[TokenList.size()];
2046   std::copy(TokenList.begin(), TokenList.end(), TokenArray);
2047
2048   PP.EnterTokenStream(TokenArray, TokenList.size(),
2049                       /*DisableMacroExpansion=*/false,
2050                       /*OwnsTokens=*/true);
2051 }
2052
2053 /// \brief Handle the loop unroll optimization pragmas.
2054 ///  #pragma unroll
2055 ///  #pragma unroll unroll-hint-value
2056 ///  #pragma unroll '(' unroll-hint-value ')'
2057 ///  #pragma nounroll
2058 ///
2059 ///  unroll-hint-value:
2060 ///    constant-expression
2061 ///
2062 /// Loop unrolling hints can be specified with '#pragma unroll' or
2063 /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2064 /// contained in parentheses. With no argument the directive instructs llvm to
2065 /// try to unroll the loop completely. A positive integer argument can be
2066 /// specified to indicate the number of times the loop should be unrolled.  To
2067 /// maximize compatibility with other compilers the unroll count argument can be
2068 /// specified with or without parentheses.  Specifying, '#pragma nounroll'
2069 /// disables unrolling of the loop.
2070 void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2071                                            PragmaIntroducerKind Introducer,
2072                                            Token &Tok) {
2073   // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2074   // "#pragma nounroll".
2075   Token PragmaName = Tok;
2076   PP.Lex(Tok);
2077   auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2078   if (Tok.is(tok::eod)) {
2079     // nounroll or unroll pragma without an argument.
2080     Info->PragmaName = PragmaName;
2081     Info->Option.startToken();
2082   } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
2083     PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2084         << "nounroll";
2085     return;
2086   } else {
2087     // Unroll pragma with an argument: "#pragma unroll N" or
2088     // "#pragma unroll(N)".
2089     // Read '(' if it exists.
2090     bool ValueInParens = Tok.is(tok::l_paren);
2091     if (ValueInParens)
2092       PP.Lex(Tok);
2093
2094     Token Option;
2095     Option.startToken();
2096     if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2097       return;
2098
2099     // In CUDA, the argument to '#pragma unroll' should not be contained in
2100     // parentheses.
2101     if (PP.getLangOpts().CUDA && ValueInParens)
2102       PP.Diag(Info->Toks[0].getLocation(),
2103               diag::warn_pragma_unroll_cuda_value_in_parens);
2104
2105     if (Tok.isNot(tok::eod)) {
2106       PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2107           << "unroll";
2108       return;
2109     }
2110   }
2111
2112   // Generate the hint token.
2113   Token *TokenArray = new Token[1];
2114   TokenArray[0].startToken();
2115   TokenArray[0].setKind(tok::annot_pragma_loop_hint);
2116   TokenArray[0].setLocation(PragmaName.getLocation());
2117   TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
2118   TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
2119   PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
2120                       /*OwnsTokens=*/true);
2121 }