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