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