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