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