ParsePragma.cpp revision 360784
1//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the language specific #pragma handlers.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/Basic/PragmaKinds.h"
15#include "clang/Basic/TargetInfo.h"
16#include "clang/Lex/Preprocessor.h"
17#include "clang/Parse/LoopHint.h"
18#include "clang/Parse/ParseDiagnostic.h"
19#include "clang/Parse/Parser.h"
20#include "clang/Parse/RAIIObjectsForParser.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, PragmaIntroducer Introducer,
30                    Token &FirstToken) override;
31};
32
33struct PragmaGCCVisibilityHandler : public PragmaHandler {
34  explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
35  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
36                    Token &FirstToken) override;
37};
38
39struct PragmaOptionsHandler : public PragmaHandler {
40  explicit PragmaOptionsHandler() : PragmaHandler("options") {}
41  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
42                    Token &FirstToken) override;
43};
44
45struct PragmaPackHandler : public PragmaHandler {
46  explicit PragmaPackHandler() : PragmaHandler("pack") {}
47  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
48                    Token &FirstToken) override;
49};
50
51struct PragmaClangSectionHandler : public PragmaHandler {
52  explicit PragmaClangSectionHandler(Sema &S)
53             : PragmaHandler("section"), Actions(S) {}
54  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
55                    Token &FirstToken) override;
56
57private:
58  Sema &Actions;
59};
60
61struct PragmaMSStructHandler : public PragmaHandler {
62  explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
63  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
64                    Token &FirstToken) override;
65};
66
67struct PragmaUnusedHandler : public PragmaHandler {
68  PragmaUnusedHandler() : PragmaHandler("unused") {}
69  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
70                    Token &FirstToken) override;
71};
72
73struct PragmaWeakHandler : public PragmaHandler {
74  explicit PragmaWeakHandler() : PragmaHandler("weak") {}
75  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
76                    Token &FirstToken) override;
77};
78
79struct PragmaRedefineExtnameHandler : public PragmaHandler {
80  explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
81  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
82                    Token &FirstToken) override;
83};
84
85struct PragmaOpenCLExtensionHandler : public PragmaHandler {
86  PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
87  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
88                    Token &FirstToken) override;
89};
90
91
92struct PragmaFPContractHandler : public PragmaHandler {
93  PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
94  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
95                    Token &FirstToken) override;
96};
97
98// Pragma STDC implementations.
99
100/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
101struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
102  PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
103
104  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
105                    Token &Tok) override {
106    tok::OnOffSwitch OOS;
107    if (PP.LexOnOffSwitch(OOS))
108     return;
109    if (OOS == tok::OOS_ON) {
110      PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
111    }
112
113    MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
114                                1);
115    Toks[0].startToken();
116    Toks[0].setKind(tok::annot_pragma_fenv_access);
117    Toks[0].setLocation(Tok.getLocation());
118    Toks[0].setAnnotationEndLoc(Tok.getLocation());
119    Toks[0].setAnnotationValue(reinterpret_cast<void*>(
120                               static_cast<uintptr_t>(OOS)));
121    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
122                        /*IsReinject=*/false);
123  }
124};
125
126/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
127struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
128  PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
129
130  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
131                    Token &Tok) override {
132    tok::OnOffSwitch OOS;
133    PP.LexOnOffSwitch(OOS);
134  }
135};
136
137/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
138struct PragmaSTDC_UnknownHandler : public PragmaHandler {
139  PragmaSTDC_UnknownHandler() = default;
140
141  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
142                    Token &UnknownTok) override {
143    // C99 6.10.6p2, unknown forms are not allowed.
144    PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
145  }
146};
147
148struct PragmaFPHandler : public PragmaHandler {
149  PragmaFPHandler() : PragmaHandler("fp") {}
150  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
151                    Token &FirstToken) override;
152};
153
154struct PragmaNoOpenMPHandler : public PragmaHandler {
155  PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
156  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
157                    Token &FirstToken) override;
158};
159
160struct PragmaOpenMPHandler : public PragmaHandler {
161  PragmaOpenMPHandler() : PragmaHandler("omp") { }
162  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
163                    Token &FirstToken) override;
164};
165
166/// PragmaCommentHandler - "\#pragma comment ...".
167struct PragmaCommentHandler : public PragmaHandler {
168  PragmaCommentHandler(Sema &Actions)
169    : PragmaHandler("comment"), Actions(Actions) {}
170  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
171                    Token &FirstToken) override;
172
173private:
174  Sema &Actions;
175};
176
177struct PragmaDetectMismatchHandler : public PragmaHandler {
178  PragmaDetectMismatchHandler(Sema &Actions)
179    : PragmaHandler("detect_mismatch"), Actions(Actions) {}
180  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
181                    Token &FirstToken) override;
182
183private:
184  Sema &Actions;
185};
186
187struct PragmaMSPointersToMembers : public PragmaHandler {
188  explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
189  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
190                    Token &FirstToken) override;
191};
192
193struct PragmaMSVtorDisp : public PragmaHandler {
194  explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
195  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
196                    Token &FirstToken) override;
197};
198
199struct PragmaMSPragma : public PragmaHandler {
200  explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
201  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
202                    Token &FirstToken) override;
203};
204
205/// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
206struct PragmaOptimizeHandler : public PragmaHandler {
207  PragmaOptimizeHandler(Sema &S)
208    : PragmaHandler("optimize"), Actions(S) {}
209  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
210                    Token &FirstToken) override;
211
212private:
213  Sema &Actions;
214};
215
216struct PragmaLoopHintHandler : public PragmaHandler {
217  PragmaLoopHintHandler() : PragmaHandler("loop") {}
218  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
219                    Token &FirstToken) override;
220};
221
222struct PragmaUnrollHintHandler : public PragmaHandler {
223  PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
224  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
225                    Token &FirstToken) override;
226};
227
228struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
229  PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
230};
231
232struct PragmaMSIntrinsicHandler : public PragmaHandler {
233  PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
234  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
235                    Token &FirstToken) override;
236};
237
238struct PragmaMSOptimizeHandler : public PragmaHandler {
239  PragmaMSOptimizeHandler() : PragmaHandler("optimize") {}
240  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
241                    Token &FirstToken) override;
242};
243
244struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
245  PragmaForceCUDAHostDeviceHandler(Sema &Actions)
246      : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
247  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
248                    Token &FirstToken) override;
249
250private:
251  Sema &Actions;
252};
253
254/// PragmaAttributeHandler - "\#pragma clang attribute ...".
255struct PragmaAttributeHandler : public PragmaHandler {
256  PragmaAttributeHandler(AttributeFactory &AttrFactory)
257      : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
258  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
259                    Token &FirstToken) override;
260
261  /// A pool of attributes that were parsed in \#pragma clang attribute.
262  ParsedAttributes AttributesForPragmaAttribute;
263};
264
265}  // end namespace
266
267void Parser::initializePragmaHandlers() {
268  AlignHandler = std::make_unique<PragmaAlignHandler>();
269  PP.AddPragmaHandler(AlignHandler.get());
270
271  GCCVisibilityHandler = std::make_unique<PragmaGCCVisibilityHandler>();
272  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
273
274  OptionsHandler = std::make_unique<PragmaOptionsHandler>();
275  PP.AddPragmaHandler(OptionsHandler.get());
276
277  PackHandler = std::make_unique<PragmaPackHandler>();
278  PP.AddPragmaHandler(PackHandler.get());
279
280  MSStructHandler = std::make_unique<PragmaMSStructHandler>();
281  PP.AddPragmaHandler(MSStructHandler.get());
282
283  UnusedHandler = std::make_unique<PragmaUnusedHandler>();
284  PP.AddPragmaHandler(UnusedHandler.get());
285
286  WeakHandler = std::make_unique<PragmaWeakHandler>();
287  PP.AddPragmaHandler(WeakHandler.get());
288
289  RedefineExtnameHandler = std::make_unique<PragmaRedefineExtnameHandler>();
290  PP.AddPragmaHandler(RedefineExtnameHandler.get());
291
292  FPContractHandler = std::make_unique<PragmaFPContractHandler>();
293  PP.AddPragmaHandler("STDC", FPContractHandler.get());
294
295  STDCFENVHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
296  PP.AddPragmaHandler("STDC", STDCFENVHandler.get());
297
298  STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
299  PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get());
300
301  STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
302  PP.AddPragmaHandler("STDC", STDCUnknownHandler.get());
303
304  PCSectionHandler = std::make_unique<PragmaClangSectionHandler>(Actions);
305  PP.AddPragmaHandler("clang", PCSectionHandler.get());
306
307  if (getLangOpts().OpenCL) {
308    OpenCLExtensionHandler = std::make_unique<PragmaOpenCLExtensionHandler>();
309    PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
310
311    PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
312  }
313  if (getLangOpts().OpenMP)
314    OpenMPHandler = std::make_unique<PragmaOpenMPHandler>();
315  else
316    OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
317  PP.AddPragmaHandler(OpenMPHandler.get());
318
319  if (getLangOpts().MicrosoftExt ||
320      getTargetInfo().getTriple().isOSBinFormatELF()) {
321    MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
322    PP.AddPragmaHandler(MSCommentHandler.get());
323  }
324
325  if (getLangOpts().MicrosoftExt) {
326    MSDetectMismatchHandler =
327        std::make_unique<PragmaDetectMismatchHandler>(Actions);
328    PP.AddPragmaHandler(MSDetectMismatchHandler.get());
329    MSPointersToMembers = std::make_unique<PragmaMSPointersToMembers>();
330    PP.AddPragmaHandler(MSPointersToMembers.get());
331    MSVtorDisp = std::make_unique<PragmaMSVtorDisp>();
332    PP.AddPragmaHandler(MSVtorDisp.get());
333    MSInitSeg = std::make_unique<PragmaMSPragma>("init_seg");
334    PP.AddPragmaHandler(MSInitSeg.get());
335    MSDataSeg = std::make_unique<PragmaMSPragma>("data_seg");
336    PP.AddPragmaHandler(MSDataSeg.get());
337    MSBSSSeg = std::make_unique<PragmaMSPragma>("bss_seg");
338    PP.AddPragmaHandler(MSBSSSeg.get());
339    MSConstSeg = std::make_unique<PragmaMSPragma>("const_seg");
340    PP.AddPragmaHandler(MSConstSeg.get());
341    MSCodeSeg = std::make_unique<PragmaMSPragma>("code_seg");
342    PP.AddPragmaHandler(MSCodeSeg.get());
343    MSSection = std::make_unique<PragmaMSPragma>("section");
344    PP.AddPragmaHandler(MSSection.get());
345    MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
346    PP.AddPragmaHandler(MSRuntimeChecks.get());
347    MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
348    PP.AddPragmaHandler(MSIntrinsic.get());
349    MSOptimize = std::make_unique<PragmaMSOptimizeHandler>();
350    PP.AddPragmaHandler(MSOptimize.get());
351  }
352
353  if (getLangOpts().CUDA) {
354    CUDAForceHostDeviceHandler =
355        std::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
356    PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
357  }
358
359  OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
360  PP.AddPragmaHandler("clang", OptimizeHandler.get());
361
362  LoopHintHandler = std::make_unique<PragmaLoopHintHandler>();
363  PP.AddPragmaHandler("clang", LoopHintHandler.get());
364
365  UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("unroll");
366  PP.AddPragmaHandler(UnrollHintHandler.get());
367
368  NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("nounroll");
369  PP.AddPragmaHandler(NoUnrollHintHandler.get());
370
371  UnrollAndJamHintHandler =
372      std::make_unique<PragmaUnrollHintHandler>("unroll_and_jam");
373  PP.AddPragmaHandler(UnrollAndJamHintHandler.get());
374
375  NoUnrollAndJamHintHandler =
376      std::make_unique<PragmaUnrollHintHandler>("nounroll_and_jam");
377  PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
378
379  FPHandler = std::make_unique<PragmaFPHandler>();
380  PP.AddPragmaHandler("clang", FPHandler.get());
381
382  AttributePragmaHandler =
383      std::make_unique<PragmaAttributeHandler>(AttrFactory);
384  PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
385}
386
387void Parser::resetPragmaHandlers() {
388  // Remove the pragma handlers we installed.
389  PP.RemovePragmaHandler(AlignHandler.get());
390  AlignHandler.reset();
391  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
392  GCCVisibilityHandler.reset();
393  PP.RemovePragmaHandler(OptionsHandler.get());
394  OptionsHandler.reset();
395  PP.RemovePragmaHandler(PackHandler.get());
396  PackHandler.reset();
397  PP.RemovePragmaHandler(MSStructHandler.get());
398  MSStructHandler.reset();
399  PP.RemovePragmaHandler(UnusedHandler.get());
400  UnusedHandler.reset();
401  PP.RemovePragmaHandler(WeakHandler.get());
402  WeakHandler.reset();
403  PP.RemovePragmaHandler(RedefineExtnameHandler.get());
404  RedefineExtnameHandler.reset();
405
406  if (getLangOpts().OpenCL) {
407    PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
408    OpenCLExtensionHandler.reset();
409    PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
410  }
411  PP.RemovePragmaHandler(OpenMPHandler.get());
412  OpenMPHandler.reset();
413
414  if (getLangOpts().MicrosoftExt ||
415      getTargetInfo().getTriple().isOSBinFormatELF()) {
416    PP.RemovePragmaHandler(MSCommentHandler.get());
417    MSCommentHandler.reset();
418  }
419
420  PP.RemovePragmaHandler("clang", PCSectionHandler.get());
421  PCSectionHandler.reset();
422
423  if (getLangOpts().MicrosoftExt) {
424    PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
425    MSDetectMismatchHandler.reset();
426    PP.RemovePragmaHandler(MSPointersToMembers.get());
427    MSPointersToMembers.reset();
428    PP.RemovePragmaHandler(MSVtorDisp.get());
429    MSVtorDisp.reset();
430    PP.RemovePragmaHandler(MSInitSeg.get());
431    MSInitSeg.reset();
432    PP.RemovePragmaHandler(MSDataSeg.get());
433    MSDataSeg.reset();
434    PP.RemovePragmaHandler(MSBSSSeg.get());
435    MSBSSSeg.reset();
436    PP.RemovePragmaHandler(MSConstSeg.get());
437    MSConstSeg.reset();
438    PP.RemovePragmaHandler(MSCodeSeg.get());
439    MSCodeSeg.reset();
440    PP.RemovePragmaHandler(MSSection.get());
441    MSSection.reset();
442    PP.RemovePragmaHandler(MSRuntimeChecks.get());
443    MSRuntimeChecks.reset();
444    PP.RemovePragmaHandler(MSIntrinsic.get());
445    MSIntrinsic.reset();
446    PP.RemovePragmaHandler(MSOptimize.get());
447    MSOptimize.reset();
448  }
449
450  if (getLangOpts().CUDA) {
451    PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
452    CUDAForceHostDeviceHandler.reset();
453  }
454
455  PP.RemovePragmaHandler("STDC", FPContractHandler.get());
456  FPContractHandler.reset();
457
458  PP.RemovePragmaHandler("STDC", STDCFENVHandler.get());
459  STDCFENVHandler.reset();
460
461  PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get());
462  STDCCXLIMITHandler.reset();
463
464  PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
465  STDCUnknownHandler.reset();
466
467  PP.RemovePragmaHandler("clang", OptimizeHandler.get());
468  OptimizeHandler.reset();
469
470  PP.RemovePragmaHandler("clang", LoopHintHandler.get());
471  LoopHintHandler.reset();
472
473  PP.RemovePragmaHandler(UnrollHintHandler.get());
474  UnrollHintHandler.reset();
475
476  PP.RemovePragmaHandler(NoUnrollHintHandler.get());
477  NoUnrollHintHandler.reset();
478
479  PP.RemovePragmaHandler(UnrollAndJamHintHandler.get());
480  UnrollAndJamHintHandler.reset();
481
482  PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
483  NoUnrollAndJamHintHandler.reset();
484
485  PP.RemovePragmaHandler("clang", FPHandler.get());
486  FPHandler.reset();
487
488  PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
489  AttributePragmaHandler.reset();
490}
491
492/// Handle the annotation token produced for #pragma unused(...)
493///
494/// Each annot_pragma_unused is followed by the argument token so e.g.
495/// "#pragma unused(x,y)" becomes:
496/// annot_pragma_unused 'x' annot_pragma_unused 'y'
497void Parser::HandlePragmaUnused() {
498  assert(Tok.is(tok::annot_pragma_unused));
499  SourceLocation UnusedLoc = ConsumeAnnotationToken();
500  Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
501  ConsumeToken(); // The argument token.
502}
503
504void Parser::HandlePragmaVisibility() {
505  assert(Tok.is(tok::annot_pragma_vis));
506  const IdentifierInfo *VisType =
507    static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
508  SourceLocation VisLoc = ConsumeAnnotationToken();
509  Actions.ActOnPragmaVisibility(VisType, VisLoc);
510}
511
512namespace {
513struct PragmaPackInfo {
514  Sema::PragmaMsStackAction Action;
515  StringRef SlotLabel;
516  Token Alignment;
517};
518} // end anonymous namespace
519
520void Parser::HandlePragmaPack() {
521  assert(Tok.is(tok::annot_pragma_pack));
522  PragmaPackInfo *Info =
523    static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
524  SourceLocation PragmaLoc = Tok.getLocation();
525  ExprResult Alignment;
526  if (Info->Alignment.is(tok::numeric_constant)) {
527    Alignment = Actions.ActOnNumericConstant(Info->Alignment);
528    if (Alignment.isInvalid()) {
529      ConsumeAnnotationToken();
530      return;
531    }
532  }
533  Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
534                          Alignment.get());
535  // Consume the token after processing the pragma to enable pragma-specific
536  // #include warnings.
537  ConsumeAnnotationToken();
538}
539
540void Parser::HandlePragmaMSStruct() {
541  assert(Tok.is(tok::annot_pragma_msstruct));
542  PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
543      reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
544  Actions.ActOnPragmaMSStruct(Kind);
545  ConsumeAnnotationToken();
546}
547
548void Parser::HandlePragmaAlign() {
549  assert(Tok.is(tok::annot_pragma_align));
550  Sema::PragmaOptionsAlignKind Kind =
551    static_cast<Sema::PragmaOptionsAlignKind>(
552    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
553  Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
554  // Consume the token after processing the pragma to enable pragma-specific
555  // #include warnings.
556  ConsumeAnnotationToken();
557}
558
559void Parser::HandlePragmaDump() {
560  assert(Tok.is(tok::annot_pragma_dump));
561  IdentifierInfo *II =
562      reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
563  Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
564  ConsumeAnnotationToken();
565}
566
567void Parser::HandlePragmaWeak() {
568  assert(Tok.is(tok::annot_pragma_weak));
569  SourceLocation PragmaLoc = ConsumeAnnotationToken();
570  Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
571                            Tok.getLocation());
572  ConsumeToken(); // The weak name.
573}
574
575void Parser::HandlePragmaWeakAlias() {
576  assert(Tok.is(tok::annot_pragma_weakalias));
577  SourceLocation PragmaLoc = ConsumeAnnotationToken();
578  IdentifierInfo *WeakName = Tok.getIdentifierInfo();
579  SourceLocation WeakNameLoc = Tok.getLocation();
580  ConsumeToken();
581  IdentifierInfo *AliasName = Tok.getIdentifierInfo();
582  SourceLocation AliasNameLoc = Tok.getLocation();
583  ConsumeToken();
584  Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
585                               WeakNameLoc, AliasNameLoc);
586
587}
588
589void Parser::HandlePragmaRedefineExtname() {
590  assert(Tok.is(tok::annot_pragma_redefine_extname));
591  SourceLocation RedefLoc = ConsumeAnnotationToken();
592  IdentifierInfo *RedefName = Tok.getIdentifierInfo();
593  SourceLocation RedefNameLoc = Tok.getLocation();
594  ConsumeToken();
595  IdentifierInfo *AliasName = Tok.getIdentifierInfo();
596  SourceLocation AliasNameLoc = Tok.getLocation();
597  ConsumeToken();
598  Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
599                                     RedefNameLoc, AliasNameLoc);
600}
601
602void Parser::HandlePragmaFPContract() {
603  assert(Tok.is(tok::annot_pragma_fp_contract));
604  tok::OnOffSwitch OOS =
605    static_cast<tok::OnOffSwitch>(
606    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
607
608  LangOptions::FPContractModeKind FPC;
609  switch (OOS) {
610  case tok::OOS_ON:
611    FPC = LangOptions::FPC_On;
612    break;
613  case tok::OOS_OFF:
614    FPC = LangOptions::FPC_Off;
615    break;
616  case tok::OOS_DEFAULT:
617    FPC = getLangOpts().getDefaultFPContractMode();
618    break;
619  }
620
621  Actions.ActOnPragmaFPContract(FPC);
622  ConsumeAnnotationToken();
623}
624
625void Parser::HandlePragmaFEnvAccess() {
626  assert(Tok.is(tok::annot_pragma_fenv_access));
627  tok::OnOffSwitch OOS =
628    static_cast<tok::OnOffSwitch>(
629    reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
630
631  LangOptions::FEnvAccessModeKind FPC;
632  switch (OOS) {
633  case tok::OOS_ON:
634    FPC = LangOptions::FEA_On;
635    break;
636  case tok::OOS_OFF:
637    FPC = LangOptions::FEA_Off;
638    break;
639  case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
640    FPC = LangOptions::FEA_Off;
641    break;
642  }
643
644  Actions.ActOnPragmaFEnvAccess(FPC);
645  ConsumeAnnotationToken();
646}
647
648
649StmtResult Parser::HandlePragmaCaptured()
650{
651  assert(Tok.is(tok::annot_pragma_captured));
652  ConsumeAnnotationToken();
653
654  if (Tok.isNot(tok::l_brace)) {
655    PP.Diag(Tok, diag::err_expected) << tok::l_brace;
656    return StmtError();
657  }
658
659  SourceLocation Loc = Tok.getLocation();
660
661  ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope |
662                                           Scope::CompoundStmtScope);
663  Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
664                                   /*NumParams=*/1);
665
666  StmtResult R = ParseCompoundStatement();
667  CapturedRegionScope.Exit();
668
669  if (R.isInvalid()) {
670    Actions.ActOnCapturedRegionError();
671    return StmtError();
672  }
673
674  return Actions.ActOnCapturedRegionEnd(R.get());
675}
676
677namespace {
678  enum OpenCLExtState : char {
679    Disable, Enable, Begin, End
680  };
681  typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
682}
683
684void Parser::HandlePragmaOpenCLExtension() {
685  assert(Tok.is(tok::annot_pragma_opencl_extension));
686  OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
687  auto State = Data->second;
688  auto Ident = Data->first;
689  SourceLocation NameLoc = Tok.getLocation();
690  ConsumeAnnotationToken();
691
692  auto &Opt = Actions.getOpenCLOptions();
693  auto Name = Ident->getName();
694  // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
695  // overriding all previously issued extension directives, but only if the
696  // behavior is set to disable."
697  if (Name == "all") {
698    if (State == Disable) {
699      Opt.disableAll();
700      Opt.enableSupportedCore(getLangOpts());
701    } else {
702      PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
703    }
704  } else if (State == Begin) {
705    if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
706      Opt.support(Name);
707    }
708    Actions.setCurrentOpenCLExtension(Name);
709  } else if (State == End) {
710    if (Name != Actions.getCurrentOpenCLExtension())
711      PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
712    Actions.setCurrentOpenCLExtension("");
713  } else if (!Opt.isKnown(Name))
714    PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
715  else if (Opt.isSupportedExtension(Name, getLangOpts()))
716    Opt.enable(Name, State == Enable);
717  else if (Opt.isSupportedCore(Name, getLangOpts()))
718    PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
719  else
720    PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
721}
722
723void Parser::HandlePragmaMSPointersToMembers() {
724  assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
725  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
726      static_cast<LangOptions::PragmaMSPointersToMembersKind>(
727          reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
728  SourceLocation PragmaLoc = ConsumeAnnotationToken();
729  Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
730}
731
732void Parser::HandlePragmaMSVtorDisp() {
733  assert(Tok.is(tok::annot_pragma_ms_vtordisp));
734  uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
735  Sema::PragmaMsStackAction Action =
736      static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
737  MSVtorDispMode Mode = MSVtorDispMode(Value & 0xFFFF);
738  SourceLocation PragmaLoc = ConsumeAnnotationToken();
739  Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
740}
741
742void Parser::HandlePragmaMSPragma() {
743  assert(Tok.is(tok::annot_pragma_ms_pragma));
744  // Grab the tokens out of the annotation and enter them into the stream.
745  auto TheTokens =
746      (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
747  PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true,
748                      /*IsReinject=*/true);
749  SourceLocation PragmaLocation = ConsumeAnnotationToken();
750  assert(Tok.isAnyIdentifier());
751  StringRef PragmaName = Tok.getIdentifierInfo()->getName();
752  PP.Lex(Tok); // pragma kind
753
754  // Figure out which #pragma we're dealing with.  The switch has no default
755  // because lex shouldn't emit the annotation token for unrecognized pragmas.
756  typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
757  PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
758    .Case("data_seg", &Parser::HandlePragmaMSSegment)
759    .Case("bss_seg", &Parser::HandlePragmaMSSegment)
760    .Case("const_seg", &Parser::HandlePragmaMSSegment)
761    .Case("code_seg", &Parser::HandlePragmaMSSegment)
762    .Case("section", &Parser::HandlePragmaMSSection)
763    .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
764
765  if (!(this->*Handler)(PragmaName, PragmaLocation)) {
766    // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
767    // until eof (really end of line) to prevent follow-on errors.
768    while (Tok.isNot(tok::eof))
769      PP.Lex(Tok);
770    PP.Lex(Tok);
771  }
772}
773
774bool Parser::HandlePragmaMSSection(StringRef PragmaName,
775                                   SourceLocation PragmaLocation) {
776  if (Tok.isNot(tok::l_paren)) {
777    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
778    return false;
779  }
780  PP.Lex(Tok); // (
781  // Parsing code for pragma section
782  if (Tok.isNot(tok::string_literal)) {
783    PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
784        << PragmaName;
785    return false;
786  }
787  ExprResult StringResult = ParseStringLiteralExpression();
788  if (StringResult.isInvalid())
789    return false; // Already diagnosed.
790  StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
791  if (SegmentName->getCharByteWidth() != 1) {
792    PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
793        << PragmaName;
794    return false;
795  }
796  int SectionFlags = ASTContext::PSF_Read;
797  bool SectionFlagsAreDefault = true;
798  while (Tok.is(tok::comma)) {
799    PP.Lex(Tok); // ,
800    // Ignore "long" and "short".
801    // They are undocumented, but widely used, section attributes which appear
802    // to do nothing.
803    if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
804      PP.Lex(Tok); // long/short
805      continue;
806    }
807
808    if (!Tok.isAnyIdentifier()) {
809      PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
810          << PragmaName;
811      return false;
812    }
813    ASTContext::PragmaSectionFlag Flag =
814      llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
815      Tok.getIdentifierInfo()->getName())
816      .Case("read", ASTContext::PSF_Read)
817      .Case("write", ASTContext::PSF_Write)
818      .Case("execute", ASTContext::PSF_Execute)
819      .Case("shared", ASTContext::PSF_Invalid)
820      .Case("nopage", ASTContext::PSF_Invalid)
821      .Case("nocache", ASTContext::PSF_Invalid)
822      .Case("discard", ASTContext::PSF_Invalid)
823      .Case("remove", ASTContext::PSF_Invalid)
824      .Default(ASTContext::PSF_None);
825    if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
826      PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
827                                  ? diag::warn_pragma_invalid_specific_action
828                                  : diag::warn_pragma_unsupported_action)
829          << PragmaName << Tok.getIdentifierInfo()->getName();
830      return false;
831    }
832    SectionFlags |= Flag;
833    SectionFlagsAreDefault = false;
834    PP.Lex(Tok); // Identifier
835  }
836  // If no section attributes are specified, the section will be marked as
837  // read/write.
838  if (SectionFlagsAreDefault)
839    SectionFlags |= ASTContext::PSF_Write;
840  if (Tok.isNot(tok::r_paren)) {
841    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
842    return false;
843  }
844  PP.Lex(Tok); // )
845  if (Tok.isNot(tok::eof)) {
846    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
847        << PragmaName;
848    return false;
849  }
850  PP.Lex(Tok); // eof
851  Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
852  return true;
853}
854
855bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
856                                   SourceLocation PragmaLocation) {
857  if (Tok.isNot(tok::l_paren)) {
858    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
859    return false;
860  }
861  PP.Lex(Tok); // (
862  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
863  StringRef SlotLabel;
864  if (Tok.isAnyIdentifier()) {
865    StringRef PushPop = Tok.getIdentifierInfo()->getName();
866    if (PushPop == "push")
867      Action = Sema::PSK_Push;
868    else if (PushPop == "pop")
869      Action = Sema::PSK_Pop;
870    else {
871      PP.Diag(PragmaLocation,
872              diag::warn_pragma_expected_section_push_pop_or_name)
873          << PragmaName;
874      return false;
875    }
876    if (Action != Sema::PSK_Reset) {
877      PP.Lex(Tok); // push | pop
878      if (Tok.is(tok::comma)) {
879        PP.Lex(Tok); // ,
880        // If we've got a comma, we either need a label or a string.
881        if (Tok.isAnyIdentifier()) {
882          SlotLabel = Tok.getIdentifierInfo()->getName();
883          PP.Lex(Tok); // identifier
884          if (Tok.is(tok::comma))
885            PP.Lex(Tok);
886          else if (Tok.isNot(tok::r_paren)) {
887            PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
888                << PragmaName;
889            return false;
890          }
891        }
892      } else if (Tok.isNot(tok::r_paren)) {
893        PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
894        return false;
895      }
896    }
897  }
898  // Grab the string literal for our section name.
899  StringLiteral *SegmentName = nullptr;
900  if (Tok.isNot(tok::r_paren)) {
901    if (Tok.isNot(tok::string_literal)) {
902      unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
903          diag::warn_pragma_expected_section_name :
904          diag::warn_pragma_expected_section_label_or_name :
905          diag::warn_pragma_expected_section_push_pop_or_name;
906      PP.Diag(PragmaLocation, DiagID) << PragmaName;
907      return false;
908    }
909    ExprResult StringResult = ParseStringLiteralExpression();
910    if (StringResult.isInvalid())
911      return false; // Already diagnosed.
912    SegmentName = cast<StringLiteral>(StringResult.get());
913    if (SegmentName->getCharByteWidth() != 1) {
914      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
915          << PragmaName;
916      return false;
917    }
918    // Setting section "" has no effect
919    if (SegmentName->getLength())
920      Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
921  }
922  if (Tok.isNot(tok::r_paren)) {
923    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
924    return false;
925  }
926  PP.Lex(Tok); // )
927  if (Tok.isNot(tok::eof)) {
928    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
929        << PragmaName;
930    return false;
931  }
932  PP.Lex(Tok); // eof
933  Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
934                           SegmentName, PragmaName);
935  return true;
936}
937
938// #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
939bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
940                                   SourceLocation PragmaLocation) {
941  if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
942    PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
943    return false;
944  }
945
946  if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
947                       PragmaName))
948    return false;
949
950  // Parse either the known section names or the string section name.
951  StringLiteral *SegmentName = nullptr;
952  if (Tok.isAnyIdentifier()) {
953    auto *II = Tok.getIdentifierInfo();
954    StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
955                            .Case("compiler", "\".CRT$XCC\"")
956                            .Case("lib", "\".CRT$XCL\"")
957                            .Case("user", "\".CRT$XCU\"")
958                            .Default("");
959
960    if (!Section.empty()) {
961      // Pretend the user wrote the appropriate string literal here.
962      Token Toks[1];
963      Toks[0].startToken();
964      Toks[0].setKind(tok::string_literal);
965      Toks[0].setLocation(Tok.getLocation());
966      Toks[0].setLiteralData(Section.data());
967      Toks[0].setLength(Section.size());
968      SegmentName =
969          cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
970      PP.Lex(Tok);
971    }
972  } else if (Tok.is(tok::string_literal)) {
973    ExprResult StringResult = ParseStringLiteralExpression();
974    if (StringResult.isInvalid())
975      return false;
976    SegmentName = cast<StringLiteral>(StringResult.get());
977    if (SegmentName->getCharByteWidth() != 1) {
978      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
979          << PragmaName;
980      return false;
981    }
982    // FIXME: Add support for the '[, func-name]' part of the pragma.
983  }
984
985  if (!SegmentName) {
986    PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
987    return false;
988  }
989
990  if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
991                       PragmaName) ||
992      ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
993                       PragmaName))
994    return false;
995
996  Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
997  return true;
998}
999
1000namespace {
1001struct PragmaLoopHintInfo {
1002  Token PragmaName;
1003  Token Option;
1004  ArrayRef<Token> Toks;
1005};
1006} // end anonymous namespace
1007
1008static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
1009  StringRef Str = PragmaName.getIdentifierInfo()->getName();
1010  std::string ClangLoopStr = (llvm::Twine("clang loop ") + Str).str();
1011  return llvm::StringSwitch<StringRef>(Str)
1012      .Case("loop", ClangLoopStr)
1013      .Case("unroll_and_jam", Str)
1014      .Case("unroll", Str)
1015      .Default("");
1016}
1017
1018bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
1019  assert(Tok.is(tok::annot_pragma_loop_hint));
1020  PragmaLoopHintInfo *Info =
1021      static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
1022
1023  IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1024  Hint.PragmaNameLoc = IdentifierLoc::create(
1025      Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1026
1027  // It is possible that the loop hint has no option identifier, such as
1028  // #pragma unroll(4).
1029  IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
1030                                   ? Info->Option.getIdentifierInfo()
1031                                   : nullptr;
1032  Hint.OptionLoc = IdentifierLoc::create(
1033      Actions.Context, Info->Option.getLocation(), OptionInfo);
1034
1035  llvm::ArrayRef<Token> Toks = Info->Toks;
1036
1037  // Return a valid hint if pragma unroll or nounroll were specified
1038  // without an argument.
1039  auto IsLoopHint = llvm::StringSwitch<bool>(PragmaNameInfo->getName())
1040                        .Cases("unroll", "nounroll", "unroll_and_jam",
1041                               "nounroll_and_jam", true)
1042                        .Default(false);
1043
1044  if (Toks.empty() && IsLoopHint) {
1045    ConsumeAnnotationToken();
1046    Hint.Range = Info->PragmaName.getLocation();
1047    return true;
1048  }
1049
1050  // The constant expression is always followed by an eof token, which increases
1051  // the TokSize by 1.
1052  assert(!Toks.empty() &&
1053         "PragmaLoopHintInfo::Toks must contain at least one token.");
1054
1055  // If no option is specified the argument is assumed to be a constant expr.
1056  bool OptionUnroll = false;
1057  bool OptionUnrollAndJam = false;
1058  bool OptionDistribute = false;
1059  bool OptionPipelineDisabled = false;
1060  bool StateOption = false;
1061  if (OptionInfo) { // Pragma Unroll does not specify an option.
1062    OptionUnroll = OptionInfo->isStr("unroll");
1063    OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
1064    OptionDistribute = OptionInfo->isStr("distribute");
1065    OptionPipelineDisabled = OptionInfo->isStr("pipeline");
1066    StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1067                      .Case("vectorize", true)
1068                      .Case("interleave", true)
1069                      .Case("vectorize_predicate", true)
1070                      .Default(false) ||
1071                  OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1072                  OptionPipelineDisabled;
1073  }
1074
1075  bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1076                         !OptionDistribute && !OptionPipelineDisabled;
1077  // Verify loop hint has an argument.
1078  if (Toks[0].is(tok::eof)) {
1079    ConsumeAnnotationToken();
1080    Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1081        << /*StateArgument=*/StateOption
1082        << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1083        << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1084    return false;
1085  }
1086
1087  // Validate the argument.
1088  if (StateOption) {
1089    ConsumeAnnotationToken();
1090    SourceLocation StateLoc = Toks[0].getLocation();
1091    IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1092
1093    bool Valid = StateInfo &&
1094                 llvm::StringSwitch<bool>(StateInfo->getName())
1095                     .Case("disable", true)
1096                     .Case("enable", !OptionPipelineDisabled)
1097                     .Case("full", OptionUnroll || OptionUnrollAndJam)
1098                     .Case("assume_safety", AssumeSafetyArg)
1099                     .Default(false);
1100    if (!Valid) {
1101      if (OptionPipelineDisabled) {
1102        Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1103      } else {
1104        Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1105            << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1106            << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1107      }
1108      return false;
1109    }
1110    if (Toks.size() > 2)
1111      Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1112          << PragmaLoopHintString(Info->PragmaName, Info->Option);
1113    Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1114  } else {
1115    // Enter constant expression including eof terminator into token stream.
1116    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
1117                        /*IsReinject=*/false);
1118    ConsumeAnnotationToken();
1119
1120    ExprResult R = ParseConstantExpression();
1121
1122    // Tokens following an error in an ill-formed constant expression will
1123    // remain in the token stream and must be removed.
1124    if (Tok.isNot(tok::eof)) {
1125      Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1126          << PragmaLoopHintString(Info->PragmaName, Info->Option);
1127      while (Tok.isNot(tok::eof))
1128        ConsumeAnyToken();
1129    }
1130
1131    ConsumeToken(); // Consume the constant expression eof terminator.
1132
1133    if (R.isInvalid() ||
1134        Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
1135      return false;
1136
1137    // Argument is a constant expression with an integer type.
1138    Hint.ValueExpr = R.get();
1139  }
1140
1141  Hint.Range = SourceRange(Info->PragmaName.getLocation(),
1142                           Info->Toks.back().getLocation());
1143  return true;
1144}
1145
1146namespace {
1147struct PragmaAttributeInfo {
1148  enum ActionType { Push, Pop, Attribute };
1149  ParsedAttributes &Attributes;
1150  ActionType Action;
1151  const IdentifierInfo *Namespace = nullptr;
1152  ArrayRef<Token> Tokens;
1153
1154  PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1155};
1156
1157#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1158
1159} // end anonymous namespace
1160
1161static StringRef getIdentifier(const Token &Tok) {
1162  if (Tok.is(tok::identifier))
1163    return Tok.getIdentifierInfo()->getName();
1164  const char *S = tok::getKeywordSpelling(Tok.getKind());
1165  if (!S)
1166    return "";
1167  return S;
1168}
1169
1170static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
1171  using namespace attr;
1172  switch (Rule) {
1173#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)                           \
1174  case Value:                                                                  \
1175    return IsAbstract;
1176#include "clang/Basic/AttrSubMatchRulesList.inc"
1177  }
1178  llvm_unreachable("Invalid attribute subject match rule");
1179  return false;
1180}
1181
1182static void diagnoseExpectedAttributeSubjectSubRule(
1183    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1184    SourceLocation SubRuleLoc) {
1185  auto Diagnostic =
1186      PRef.Diag(SubRuleLoc,
1187                diag::err_pragma_attribute_expected_subject_sub_identifier)
1188      << PrimaryRuleName;
1189  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1190    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1191  else
1192    Diagnostic << /*SubRulesSupported=*/0;
1193}
1194
1195static void diagnoseUnknownAttributeSubjectSubRule(
1196    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1197    StringRef SubRuleName, SourceLocation SubRuleLoc) {
1198
1199  auto Diagnostic =
1200      PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1201      << SubRuleName << PrimaryRuleName;
1202  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1203    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1204  else
1205    Diagnostic << /*SubRulesSupported=*/0;
1206}
1207
1208bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1209    attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
1210    SourceLocation &LastMatchRuleEndLoc) {
1211  bool IsAny = false;
1212  BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
1213  if (getIdentifier(Tok) == "any") {
1214    AnyLoc = ConsumeToken();
1215    IsAny = true;
1216    if (AnyParens.expectAndConsume())
1217      return true;
1218  }
1219
1220  do {
1221    // Parse the subject matcher rule.
1222    StringRef Name = getIdentifier(Tok);
1223    if (Name.empty()) {
1224      Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1225      return true;
1226    }
1227    std::pair<Optional<attr::SubjectMatchRule>,
1228              Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
1229        Rule = isAttributeSubjectMatchRule(Name);
1230    if (!Rule.first) {
1231      Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1232      return true;
1233    }
1234    attr::SubjectMatchRule PrimaryRule = *Rule.first;
1235    SourceLocation RuleLoc = ConsumeToken();
1236
1237    BalancedDelimiterTracker Parens(*this, tok::l_paren);
1238    if (isAbstractAttrMatcherRule(PrimaryRule)) {
1239      if (Parens.expectAndConsume())
1240        return true;
1241    } else if (Parens.consumeOpen()) {
1242      if (!SubjectMatchRules
1243               .insert(
1244                   std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1245               .second)
1246        Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1247            << Name
1248            << FixItHint::CreateRemoval(SourceRange(
1249                   RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1250      LastMatchRuleEndLoc = RuleLoc;
1251      continue;
1252    }
1253
1254    // Parse the sub-rules.
1255    StringRef SubRuleName = getIdentifier(Tok);
1256    if (SubRuleName.empty()) {
1257      diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1258                                              Tok.getLocation());
1259      return true;
1260    }
1261    attr::SubjectMatchRule SubRule;
1262    if (SubRuleName == "unless") {
1263      SourceLocation SubRuleLoc = ConsumeToken();
1264      BalancedDelimiterTracker Parens(*this, tok::l_paren);
1265      if (Parens.expectAndConsume())
1266        return true;
1267      SubRuleName = getIdentifier(Tok);
1268      if (SubRuleName.empty()) {
1269        diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1270                                                SubRuleLoc);
1271        return true;
1272      }
1273      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
1274      if (!SubRuleOrNone) {
1275        std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1276        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1277                                               SubRuleUnlessName, SubRuleLoc);
1278        return true;
1279      }
1280      SubRule = *SubRuleOrNone;
1281      ConsumeToken();
1282      if (Parens.consumeClose())
1283        return true;
1284    } else {
1285      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
1286      if (!SubRuleOrNone) {
1287        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1288                                               SubRuleName, Tok.getLocation());
1289        return true;
1290      }
1291      SubRule = *SubRuleOrNone;
1292      ConsumeToken();
1293    }
1294    SourceLocation RuleEndLoc = Tok.getLocation();
1295    LastMatchRuleEndLoc = RuleEndLoc;
1296    if (Parens.consumeClose())
1297      return true;
1298    if (!SubjectMatchRules
1299             .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1300             .second) {
1301      Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1302          << attr::getSubjectMatchRuleSpelling(SubRule)
1303          << FixItHint::CreateRemoval(SourceRange(
1304                 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1305      continue;
1306    }
1307  } while (IsAny && TryConsumeToken(tok::comma));
1308
1309  if (IsAny)
1310    if (AnyParens.consumeClose())
1311      return true;
1312
1313  return false;
1314}
1315
1316namespace {
1317
1318/// Describes the stage at which attribute subject rule parsing was interrupted.
1319enum class MissingAttributeSubjectRulesRecoveryPoint {
1320  Comma,
1321  ApplyTo,
1322  Equals,
1323  Any,
1324  None,
1325};
1326
1327MissingAttributeSubjectRulesRecoveryPoint
1328getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1329  if (const auto *II = Tok.getIdentifierInfo()) {
1330    if (II->isStr("apply_to"))
1331      return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1332    if (II->isStr("any"))
1333      return MissingAttributeSubjectRulesRecoveryPoint::Any;
1334  }
1335  if (Tok.is(tok::equal))
1336    return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1337  return MissingAttributeSubjectRulesRecoveryPoint::None;
1338}
1339
1340/// Creates a diagnostic for the attribute subject rule parsing diagnostic that
1341/// suggests the possible attribute subject rules in a fix-it together with
1342/// any other missing tokens.
1343DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1344    unsigned DiagID, ParsedAttr &Attribute,
1345    MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
1346  SourceLocation Loc = PRef.getEndOfPreviousToken();
1347  if (Loc.isInvalid())
1348    Loc = PRef.getCurToken().getLocation();
1349  auto Diagnostic = PRef.Diag(Loc, DiagID);
1350  std::string FixIt;
1351  MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1352      getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1353  if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1354    FixIt = ", ";
1355  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1356      EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1357    FixIt += "apply_to";
1358  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1359      EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1360    FixIt += " = ";
1361  SourceRange FixItRange(Loc);
1362  if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1363    // Gather the subject match rules that are supported by the attribute.
1364    SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
1365    Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
1366    if (SubjectMatchRuleSet.empty()) {
1367      // FIXME: We can emit a "fix-it" with a subject list placeholder when
1368      // placeholders will be supported by the fix-its.
1369      return Diagnostic;
1370    }
1371    FixIt += "any(";
1372    bool NeedsComma = false;
1373    for (const auto &I : SubjectMatchRuleSet) {
1374      // Ensure that the missing rule is reported in the fix-it only when it's
1375      // supported in the current language mode.
1376      if (!I.second)
1377        continue;
1378      if (NeedsComma)
1379        FixIt += ", ";
1380      else
1381        NeedsComma = true;
1382      FixIt += attr::getSubjectMatchRuleSpelling(I.first);
1383    }
1384    FixIt += ")";
1385    // Check if we need to remove the range
1386    PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
1387    FixItRange.setEnd(PRef.getCurToken().getLocation());
1388  }
1389  if (FixItRange.getBegin() == FixItRange.getEnd())
1390    Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
1391  else
1392    Diagnostic << FixItHint::CreateReplacement(
1393        CharSourceRange::getCharRange(FixItRange), FixIt);
1394  return Diagnostic;
1395}
1396
1397} // end anonymous namespace
1398
1399void Parser::HandlePragmaAttribute() {
1400  assert(Tok.is(tok::annot_pragma_attribute) &&
1401         "Expected #pragma attribute annotation token");
1402  SourceLocation PragmaLoc = Tok.getLocation();
1403  auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1404  if (Info->Action == PragmaAttributeInfo::Pop) {
1405    ConsumeAnnotationToken();
1406    Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1407    return;
1408  }
1409  // Parse the actual attribute with its arguments.
1410  assert((Info->Action == PragmaAttributeInfo::Push ||
1411          Info->Action == PragmaAttributeInfo::Attribute) &&
1412         "Unexpected #pragma attribute command");
1413
1414  if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1415    ConsumeAnnotationToken();
1416    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1417    return;
1418  }
1419
1420  PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false,
1421                      /*IsReinject=*/false);
1422  ConsumeAnnotationToken();
1423
1424  ParsedAttributes &Attrs = Info->Attributes;
1425  Attrs.clearListOnly();
1426
1427  auto SkipToEnd = [this]() {
1428    SkipUntil(tok::eof, StopBeforeMatch);
1429    ConsumeToken();
1430  };
1431
1432  if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
1433    // Parse the CXX11 style attribute.
1434    ParseCXX11AttributeSpecifier(Attrs);
1435  } else if (Tok.is(tok::kw___attribute)) {
1436    ConsumeToken();
1437    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1438                         "attribute"))
1439      return SkipToEnd();
1440    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1441      return SkipToEnd();
1442
1443    if (Tok.isNot(tok::identifier)) {
1444      Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1445      SkipToEnd();
1446      return;
1447    }
1448    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1449    SourceLocation AttrNameLoc = ConsumeToken();
1450
1451    if (Tok.isNot(tok::l_paren))
1452      Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1453                   ParsedAttr::AS_GNU);
1454    else
1455      ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
1456                            /*ScopeName=*/nullptr,
1457                            /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
1458                            /*Declarator=*/nullptr);
1459
1460    if (ExpectAndConsume(tok::r_paren))
1461      return SkipToEnd();
1462    if (ExpectAndConsume(tok::r_paren))
1463      return SkipToEnd();
1464  } else if (Tok.is(tok::kw___declspec)) {
1465    ParseMicrosoftDeclSpecs(Attrs);
1466  } else {
1467    Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1468    if (Tok.getIdentifierInfo()) {
1469      // If we suspect that this is an attribute suggest the use of
1470      // '__attribute__'.
1471      if (ParsedAttr::getParsedKind(
1472              Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1473              ParsedAttr::AS_GNU) != ParsedAttr::UnknownAttribute) {
1474        SourceLocation InsertStartLoc = Tok.getLocation();
1475        ConsumeToken();
1476        if (Tok.is(tok::l_paren)) {
1477          ConsumeAnyToken();
1478          SkipUntil(tok::r_paren, StopBeforeMatch);
1479          if (Tok.isNot(tok::r_paren))
1480            return SkipToEnd();
1481        }
1482        Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1483            << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1484            << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1485      }
1486    }
1487    SkipToEnd();
1488    return;
1489  }
1490
1491  if (Attrs.empty() || Attrs.begin()->isInvalid()) {
1492    SkipToEnd();
1493    return;
1494  }
1495
1496  // Ensure that we don't have more than one attribute.
1497  if (Attrs.size() > 1) {
1498    SourceLocation Loc = Attrs[1].getLoc();
1499    Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1500    SkipToEnd();
1501    return;
1502  }
1503
1504  ParsedAttr &Attribute = *Attrs.begin();
1505  if (!Attribute.isSupportedByPragmaAttribute()) {
1506    Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1507        << Attribute;
1508    SkipToEnd();
1509    return;
1510  }
1511
1512  // Parse the subject-list.
1513  if (!TryConsumeToken(tok::comma)) {
1514    createExpectedAttributeSubjectRulesTokenDiagnostic(
1515        diag::err_expected, Attribute,
1516        MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
1517        << tok::comma;
1518    SkipToEnd();
1519    return;
1520  }
1521
1522  if (Tok.isNot(tok::identifier)) {
1523    createExpectedAttributeSubjectRulesTokenDiagnostic(
1524        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1525        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1526    SkipToEnd();
1527    return;
1528  }
1529  const IdentifierInfo *II = Tok.getIdentifierInfo();
1530  if (!II->isStr("apply_to")) {
1531    createExpectedAttributeSubjectRulesTokenDiagnostic(
1532        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1533        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1534    SkipToEnd();
1535    return;
1536  }
1537  ConsumeToken();
1538
1539  if (!TryConsumeToken(tok::equal)) {
1540    createExpectedAttributeSubjectRulesTokenDiagnostic(
1541        diag::err_expected, Attribute,
1542        MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1543        << tok::equal;
1544    SkipToEnd();
1545    return;
1546  }
1547
1548  attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1549  SourceLocation AnyLoc, LastMatchRuleEndLoc;
1550  if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1551                                              LastMatchRuleEndLoc)) {
1552    SkipToEnd();
1553    return;
1554  }
1555
1556  // Tokens following an ill-formed attribute will remain in the token stream
1557  // and must be removed.
1558  if (Tok.isNot(tok::eof)) {
1559    Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1560    SkipToEnd();
1561    return;
1562  }
1563
1564  // Consume the eof terminator token.
1565  ConsumeToken();
1566
1567  // Handle a mixed push/attribute by desurging to a push, then an attribute.
1568  if (Info->Action == PragmaAttributeInfo::Push)
1569    Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1570
1571  Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1572                                        std::move(SubjectMatchRules));
1573}
1574
1575// #pragma GCC visibility comes in two variants:
1576//   'push' '(' [visibility] ')'
1577//   'pop'
1578void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1579                                              PragmaIntroducer Introducer,
1580                                              Token &VisTok) {
1581  SourceLocation VisLoc = VisTok.getLocation();
1582
1583  Token Tok;
1584  PP.LexUnexpandedToken(Tok);
1585
1586  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1587
1588  const IdentifierInfo *VisType;
1589  if (PushPop && PushPop->isStr("pop")) {
1590    VisType = nullptr;
1591  } else if (PushPop && PushPop->isStr("push")) {
1592    PP.LexUnexpandedToken(Tok);
1593    if (Tok.isNot(tok::l_paren)) {
1594      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1595        << "visibility";
1596      return;
1597    }
1598    PP.LexUnexpandedToken(Tok);
1599    VisType = Tok.getIdentifierInfo();
1600    if (!VisType) {
1601      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1602        << "visibility";
1603      return;
1604    }
1605    PP.LexUnexpandedToken(Tok);
1606    if (Tok.isNot(tok::r_paren)) {
1607      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1608        << "visibility";
1609      return;
1610    }
1611  } else {
1612    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1613      << "visibility";
1614    return;
1615  }
1616  SourceLocation EndLoc = Tok.getLocation();
1617  PP.LexUnexpandedToken(Tok);
1618  if (Tok.isNot(tok::eod)) {
1619    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1620      << "visibility";
1621    return;
1622  }
1623
1624  auto Toks = std::make_unique<Token[]>(1);
1625  Toks[0].startToken();
1626  Toks[0].setKind(tok::annot_pragma_vis);
1627  Toks[0].setLocation(VisLoc);
1628  Toks[0].setAnnotationEndLoc(EndLoc);
1629  Toks[0].setAnnotationValue(
1630      const_cast<void *>(static_cast<const void *>(VisType)));
1631  PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true,
1632                      /*IsReinject=*/false);
1633}
1634
1635// #pragma pack(...) comes in the following delicious flavors:
1636//   pack '(' [integer] ')'
1637//   pack '(' 'show' ')'
1638//   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1639void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1640                                     PragmaIntroducer Introducer,
1641                                     Token &PackTok) {
1642  SourceLocation PackLoc = PackTok.getLocation();
1643
1644  Token Tok;
1645  PP.Lex(Tok);
1646  if (Tok.isNot(tok::l_paren)) {
1647    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1648    return;
1649  }
1650
1651  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1652  StringRef SlotLabel;
1653  Token Alignment;
1654  Alignment.startToken();
1655  PP.Lex(Tok);
1656  if (Tok.is(tok::numeric_constant)) {
1657    Alignment = Tok;
1658
1659    PP.Lex(Tok);
1660
1661    // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1662    // the push/pop stack.
1663    // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1664    Action =
1665        PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1666  } else if (Tok.is(tok::identifier)) {
1667    const IdentifierInfo *II = Tok.getIdentifierInfo();
1668    if (II->isStr("show")) {
1669      Action = Sema::PSK_Show;
1670      PP.Lex(Tok);
1671    } else {
1672      if (II->isStr("push")) {
1673        Action = Sema::PSK_Push;
1674      } else if (II->isStr("pop")) {
1675        Action = Sema::PSK_Pop;
1676      } else {
1677        PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1678        return;
1679      }
1680      PP.Lex(Tok);
1681
1682      if (Tok.is(tok::comma)) {
1683        PP.Lex(Tok);
1684
1685        if (Tok.is(tok::numeric_constant)) {
1686          Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1687          Alignment = Tok;
1688
1689          PP.Lex(Tok);
1690        } else if (Tok.is(tok::identifier)) {
1691          SlotLabel = Tok.getIdentifierInfo()->getName();
1692          PP.Lex(Tok);
1693
1694          if (Tok.is(tok::comma)) {
1695            PP.Lex(Tok);
1696
1697            if (Tok.isNot(tok::numeric_constant)) {
1698              PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1699              return;
1700            }
1701
1702            Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1703            Alignment = Tok;
1704
1705            PP.Lex(Tok);
1706          }
1707        } else {
1708          PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1709          return;
1710        }
1711      }
1712    }
1713  } else if (PP.getLangOpts().ApplePragmaPack) {
1714    // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1715    // the push/pop stack.
1716    // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1717    Action = Sema::PSK_Pop;
1718  }
1719
1720  if (Tok.isNot(tok::r_paren)) {
1721    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1722    return;
1723  }
1724
1725  SourceLocation RParenLoc = Tok.getLocation();
1726  PP.Lex(Tok);
1727  if (Tok.isNot(tok::eod)) {
1728    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1729    return;
1730  }
1731
1732  PragmaPackInfo *Info =
1733      PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1734  Info->Action = Action;
1735  Info->SlotLabel = SlotLabel;
1736  Info->Alignment = Alignment;
1737
1738  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1739                              1);
1740  Toks[0].startToken();
1741  Toks[0].setKind(tok::annot_pragma_pack);
1742  Toks[0].setLocation(PackLoc);
1743  Toks[0].setAnnotationEndLoc(RParenLoc);
1744  Toks[0].setAnnotationValue(static_cast<void*>(Info));
1745  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1746                      /*IsReinject=*/false);
1747}
1748
1749// #pragma ms_struct on
1750// #pragma ms_struct off
1751void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1752                                         PragmaIntroducer Introducer,
1753                                         Token &MSStructTok) {
1754  PragmaMSStructKind Kind = PMSST_OFF;
1755
1756  Token Tok;
1757  PP.Lex(Tok);
1758  if (Tok.isNot(tok::identifier)) {
1759    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1760    return;
1761  }
1762  SourceLocation EndLoc = Tok.getLocation();
1763  const IdentifierInfo *II = Tok.getIdentifierInfo();
1764  if (II->isStr("on")) {
1765    Kind = PMSST_ON;
1766    PP.Lex(Tok);
1767  }
1768  else if (II->isStr("off") || II->isStr("reset"))
1769    PP.Lex(Tok);
1770  else {
1771    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1772    return;
1773  }
1774
1775  if (Tok.isNot(tok::eod)) {
1776    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1777      << "ms_struct";
1778    return;
1779  }
1780
1781  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1782                              1);
1783  Toks[0].startToken();
1784  Toks[0].setKind(tok::annot_pragma_msstruct);
1785  Toks[0].setLocation(MSStructTok.getLocation());
1786  Toks[0].setAnnotationEndLoc(EndLoc);
1787  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1788                             static_cast<uintptr_t>(Kind)));
1789  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1790                      /*IsReinject=*/false);
1791}
1792
1793// #pragma clang section bss="abc" data="" rodata="def" text="" relro=""
1794void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
1795                                             PragmaIntroducer Introducer,
1796                                             Token &FirstToken) {
1797
1798  Token Tok;
1799  auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1800
1801  PP.Lex(Tok); // eat 'section'
1802  while (Tok.isNot(tok::eod)) {
1803    if (Tok.isNot(tok::identifier)) {
1804      PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1805      return;
1806    }
1807
1808    const IdentifierInfo *SecType = Tok.getIdentifierInfo();
1809    if (SecType->isStr("bss"))
1810      SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1811    else if (SecType->isStr("data"))
1812      SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1813    else if (SecType->isStr("rodata"))
1814      SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1815    else if (SecType->isStr("relro"))
1816      SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
1817    else if (SecType->isStr("text"))
1818      SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1819    else {
1820      PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1821      return;
1822    }
1823
1824    PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
1825    if (Tok.isNot(tok::equal)) {
1826      PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1827      return;
1828    }
1829
1830    std::string SecName;
1831    if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
1832      return;
1833
1834    Actions.ActOnPragmaClangSection(Tok.getLocation(),
1835      (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1836                       Sema::PragmaClangSectionAction::PCSA_Clear),
1837       SecKind, SecName);
1838  }
1839}
1840
1841// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1842// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1843static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1844                             bool IsOptions) {
1845  Token Tok;
1846
1847  if (IsOptions) {
1848    PP.Lex(Tok);
1849    if (Tok.isNot(tok::identifier) ||
1850        !Tok.getIdentifierInfo()->isStr("align")) {
1851      PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1852      return;
1853    }
1854  }
1855
1856  PP.Lex(Tok);
1857  if (Tok.isNot(tok::equal)) {
1858    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1859      << IsOptions;
1860    return;
1861  }
1862
1863  PP.Lex(Tok);
1864  if (Tok.isNot(tok::identifier)) {
1865    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1866      << (IsOptions ? "options" : "align");
1867    return;
1868  }
1869
1870  Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1871  const IdentifierInfo *II = Tok.getIdentifierInfo();
1872  if (II->isStr("native"))
1873    Kind = Sema::POAK_Native;
1874  else if (II->isStr("natural"))
1875    Kind = Sema::POAK_Natural;
1876  else if (II->isStr("packed"))
1877    Kind = Sema::POAK_Packed;
1878  else if (II->isStr("power"))
1879    Kind = Sema::POAK_Power;
1880  else if (II->isStr("mac68k"))
1881    Kind = Sema::POAK_Mac68k;
1882  else if (II->isStr("reset"))
1883    Kind = Sema::POAK_Reset;
1884  else {
1885    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1886      << IsOptions;
1887    return;
1888  }
1889
1890  SourceLocation EndLoc = Tok.getLocation();
1891  PP.Lex(Tok);
1892  if (Tok.isNot(tok::eod)) {
1893    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1894      << (IsOptions ? "options" : "align");
1895    return;
1896  }
1897
1898  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1899                              1);
1900  Toks[0].startToken();
1901  Toks[0].setKind(tok::annot_pragma_align);
1902  Toks[0].setLocation(FirstTok.getLocation());
1903  Toks[0].setAnnotationEndLoc(EndLoc);
1904  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1905                             static_cast<uintptr_t>(Kind)));
1906  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1907                      /*IsReinject=*/false);
1908}
1909
1910void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1911                                      PragmaIntroducer Introducer,
1912                                      Token &AlignTok) {
1913  ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1914}
1915
1916void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1917                                        PragmaIntroducer Introducer,
1918                                        Token &OptionsTok) {
1919  ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1920}
1921
1922// #pragma unused(identifier)
1923void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1924                                       PragmaIntroducer Introducer,
1925                                       Token &UnusedTok) {
1926  // FIXME: Should we be expanding macros here? My guess is no.
1927  SourceLocation UnusedLoc = UnusedTok.getLocation();
1928
1929  // Lex the left '('.
1930  Token Tok;
1931  PP.Lex(Tok);
1932  if (Tok.isNot(tok::l_paren)) {
1933    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1934    return;
1935  }
1936
1937  // Lex the declaration reference(s).
1938  SmallVector<Token, 5> Identifiers;
1939  SourceLocation RParenLoc;
1940  bool LexID = true;
1941
1942  while (true) {
1943    PP.Lex(Tok);
1944
1945    if (LexID) {
1946      if (Tok.is(tok::identifier)) {
1947        Identifiers.push_back(Tok);
1948        LexID = false;
1949        continue;
1950      }
1951
1952      // Illegal token!
1953      PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1954      return;
1955    }
1956
1957    // We are execting a ')' or a ','.
1958    if (Tok.is(tok::comma)) {
1959      LexID = true;
1960      continue;
1961    }
1962
1963    if (Tok.is(tok::r_paren)) {
1964      RParenLoc = Tok.getLocation();
1965      break;
1966    }
1967
1968    // Illegal token!
1969    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1970    return;
1971  }
1972
1973  PP.Lex(Tok);
1974  if (Tok.isNot(tok::eod)) {
1975    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1976        "unused";
1977    return;
1978  }
1979
1980  // Verify that we have a location for the right parenthesis.
1981  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
1982  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
1983
1984  // For each identifier token, insert into the token stream a
1985  // annot_pragma_unused token followed by the identifier token.
1986  // This allows us to cache a "#pragma unused" that occurs inside an inline
1987  // C++ member function.
1988
1989  MutableArrayRef<Token> Toks(
1990      PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1991      2 * Identifiers.size());
1992  for (unsigned i=0; i != Identifiers.size(); i++) {
1993    Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1994    pragmaUnusedTok.startToken();
1995    pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1996    pragmaUnusedTok.setLocation(UnusedLoc);
1997    idTok = Identifiers[i];
1998  }
1999  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2000                      /*IsReinject=*/false);
2001}
2002
2003// #pragma weak identifier
2004// #pragma weak identifier '=' identifier
2005void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
2006                                     PragmaIntroducer Introducer,
2007                                     Token &WeakTok) {
2008  SourceLocation WeakLoc = WeakTok.getLocation();
2009
2010  Token Tok;
2011  PP.Lex(Tok);
2012  if (Tok.isNot(tok::identifier)) {
2013    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
2014    return;
2015  }
2016
2017  Token WeakName = Tok;
2018  bool HasAlias = false;
2019  Token AliasName;
2020
2021  PP.Lex(Tok);
2022  if (Tok.is(tok::equal)) {
2023    HasAlias = true;
2024    PP.Lex(Tok);
2025    if (Tok.isNot(tok::identifier)) {
2026      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2027          << "weak";
2028      return;
2029    }
2030    AliasName = Tok;
2031    PP.Lex(Tok);
2032  }
2033
2034  if (Tok.isNot(tok::eod)) {
2035    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
2036    return;
2037  }
2038
2039  if (HasAlias) {
2040    MutableArrayRef<Token> Toks(
2041        PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
2042    Token &pragmaUnusedTok = Toks[0];
2043    pragmaUnusedTok.startToken();
2044    pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
2045    pragmaUnusedTok.setLocation(WeakLoc);
2046    pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
2047    Toks[1] = WeakName;
2048    Toks[2] = AliasName;
2049    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2050                        /*IsReinject=*/false);
2051  } else {
2052    MutableArrayRef<Token> Toks(
2053        PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
2054    Token &pragmaUnusedTok = Toks[0];
2055    pragmaUnusedTok.startToken();
2056    pragmaUnusedTok.setKind(tok::annot_pragma_weak);
2057    pragmaUnusedTok.setLocation(WeakLoc);
2058    pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
2059    Toks[1] = WeakName;
2060    PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2061                        /*IsReinject=*/false);
2062  }
2063}
2064
2065// #pragma redefine_extname identifier identifier
2066void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
2067                                                PragmaIntroducer Introducer,
2068                                                Token &RedefToken) {
2069  SourceLocation RedefLoc = RedefToken.getLocation();
2070
2071  Token Tok;
2072  PP.Lex(Tok);
2073  if (Tok.isNot(tok::identifier)) {
2074    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2075      "redefine_extname";
2076    return;
2077  }
2078
2079  Token RedefName = Tok;
2080  PP.Lex(Tok);
2081
2082  if (Tok.isNot(tok::identifier)) {
2083    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2084        << "redefine_extname";
2085    return;
2086  }
2087
2088  Token AliasName = Tok;
2089  PP.Lex(Tok);
2090
2091  if (Tok.isNot(tok::eod)) {
2092    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2093      "redefine_extname";
2094    return;
2095  }
2096
2097  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
2098                              3);
2099  Token &pragmaRedefTok = Toks[0];
2100  pragmaRedefTok.startToken();
2101  pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2102  pragmaRedefTok.setLocation(RedefLoc);
2103  pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
2104  Toks[1] = RedefName;
2105  Toks[2] = AliasName;
2106  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2107                      /*IsReinject=*/false);
2108}
2109
2110void PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2111                                           PragmaIntroducer Introducer,
2112                                           Token &Tok) {
2113  tok::OnOffSwitch OOS;
2114  if (PP.LexOnOffSwitch(OOS))
2115    return;
2116
2117  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2118                              1);
2119  Toks[0].startToken();
2120  Toks[0].setKind(tok::annot_pragma_fp_contract);
2121  Toks[0].setLocation(Tok.getLocation());
2122  Toks[0].setAnnotationEndLoc(Tok.getLocation());
2123  Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2124                             static_cast<uintptr_t>(OOS)));
2125  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2126                      /*IsReinject=*/false);
2127}
2128
2129void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2130                                                PragmaIntroducer Introducer,
2131                                                Token &Tok) {
2132  PP.LexUnexpandedToken(Tok);
2133  if (Tok.isNot(tok::identifier)) {
2134    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2135      "OPENCL";
2136    return;
2137  }
2138  IdentifierInfo *Ext = Tok.getIdentifierInfo();
2139  SourceLocation NameLoc = Tok.getLocation();
2140
2141  PP.Lex(Tok);
2142  if (Tok.isNot(tok::colon)) {
2143    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2144    return;
2145  }
2146
2147  PP.Lex(Tok);
2148  if (Tok.isNot(tok::identifier)) {
2149    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2150    return;
2151  }
2152  IdentifierInfo *Pred = Tok.getIdentifierInfo();
2153
2154  OpenCLExtState State;
2155  if (Pred->isStr("enable")) {
2156    State = Enable;
2157  } else if (Pred->isStr("disable")) {
2158    State = Disable;
2159  } else if (Pred->isStr("begin"))
2160    State = Begin;
2161  else if (Pred->isStr("end"))
2162    State = End;
2163  else {
2164    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2165      << Ext->isStr("all");
2166    return;
2167  }
2168  SourceLocation StateLoc = Tok.getLocation();
2169
2170  PP.Lex(Tok);
2171  if (Tok.isNot(tok::eod)) {
2172    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2173      "OPENCL EXTENSION";
2174    return;
2175  }
2176
2177  auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
2178  Info->first = Ext;
2179  Info->second = State;
2180  MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2181                              1);
2182  Toks[0].startToken();
2183  Toks[0].setKind(tok::annot_pragma_opencl_extension);
2184  Toks[0].setLocation(NameLoc);
2185  Toks[0].setAnnotationValue(static_cast<void*>(Info));
2186  Toks[0].setAnnotationEndLoc(StateLoc);
2187  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2188                      /*IsReinject=*/false);
2189
2190  if (PP.getPPCallbacks())
2191    PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
2192                                               StateLoc, State);
2193}
2194
2195/// Handle '#pragma omp ...' when OpenMP is disabled.
2196///
2197void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
2198                                         PragmaIntroducer Introducer,
2199                                         Token &FirstTok) {
2200  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
2201                                     FirstTok.getLocation())) {
2202    PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
2203    PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
2204                                    diag::Severity::Ignored, SourceLocation());
2205  }
2206  PP.DiscardUntilEndOfDirective();
2207}
2208
2209/// Handle '#pragma omp ...' when OpenMP is enabled.
2210///
2211void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
2212                                       PragmaIntroducer Introducer,
2213                                       Token &FirstTok) {
2214  SmallVector<Token, 16> Pragma;
2215  Token Tok;
2216  Tok.startToken();
2217  Tok.setKind(tok::annot_pragma_openmp);
2218  Tok.setLocation(Introducer.Loc);
2219
2220  while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
2221    Pragma.push_back(Tok);
2222    PP.Lex(Tok);
2223    if (Tok.is(tok::annot_pragma_openmp)) {
2224      PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2225      unsigned InnerPragmaCnt = 1;
2226      while (InnerPragmaCnt != 0) {
2227        PP.Lex(Tok);
2228        if (Tok.is(tok::annot_pragma_openmp))
2229          ++InnerPragmaCnt;
2230        else if (Tok.is(tok::annot_pragma_openmp_end))
2231          --InnerPragmaCnt;
2232      }
2233      PP.Lex(Tok);
2234    }
2235  }
2236  SourceLocation EodLoc = Tok.getLocation();
2237  Tok.startToken();
2238  Tok.setKind(tok::annot_pragma_openmp_end);
2239  Tok.setLocation(EodLoc);
2240  Pragma.push_back(Tok);
2241
2242  auto Toks = std::make_unique<Token[]>(Pragma.size());
2243  std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2244  PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2245                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2246}
2247
2248/// Handle '#pragma pointers_to_members'
2249// The grammar for this pragma is as follows:
2250//
2251// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2252//
2253// #pragma pointers_to_members '(' 'best_case' ')'
2254// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2255// #pragma pointers_to_members '(' inheritance-model ')'
2256void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2257                                             PragmaIntroducer Introducer,
2258                                             Token &Tok) {
2259  SourceLocation PointersToMembersLoc = Tok.getLocation();
2260  PP.Lex(Tok);
2261  if (Tok.isNot(tok::l_paren)) {
2262    PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2263      << "pointers_to_members";
2264    return;
2265  }
2266  PP.Lex(Tok);
2267  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2268  if (!Arg) {
2269    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2270      << "pointers_to_members";
2271    return;
2272  }
2273  PP.Lex(Tok);
2274
2275  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2276  if (Arg->isStr("best_case")) {
2277    RepresentationMethod = LangOptions::PPTMK_BestCase;
2278  } else {
2279    if (Arg->isStr("full_generality")) {
2280      if (Tok.is(tok::comma)) {
2281        PP.Lex(Tok);
2282
2283        Arg = Tok.getIdentifierInfo();
2284        if (!Arg) {
2285          PP.Diag(Tok.getLocation(),
2286                  diag::err_pragma_pointers_to_members_unknown_kind)
2287              << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2288          return;
2289        }
2290        PP.Lex(Tok);
2291      } else if (Tok.is(tok::r_paren)) {
2292        // #pragma pointers_to_members(full_generality) implicitly specifies
2293        // virtual_inheritance.
2294        Arg = nullptr;
2295        RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2296      } else {
2297        PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2298            << "full_generality";
2299        return;
2300      }
2301    }
2302
2303    if (Arg) {
2304      if (Arg->isStr("single_inheritance")) {
2305        RepresentationMethod =
2306            LangOptions::PPTMK_FullGeneralitySingleInheritance;
2307      } else if (Arg->isStr("multiple_inheritance")) {
2308        RepresentationMethod =
2309            LangOptions::PPTMK_FullGeneralityMultipleInheritance;
2310      } else if (Arg->isStr("virtual_inheritance")) {
2311        RepresentationMethod =
2312            LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2313      } else {
2314        PP.Diag(Tok.getLocation(),
2315                diag::err_pragma_pointers_to_members_unknown_kind)
2316            << Arg << /*HasPointerDeclaration*/ 1;
2317        return;
2318      }
2319    }
2320  }
2321
2322  if (Tok.isNot(tok::r_paren)) {
2323    PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2324        << (Arg ? Arg->getName() : "full_generality");
2325    return;
2326  }
2327
2328  SourceLocation EndLoc = Tok.getLocation();
2329  PP.Lex(Tok);
2330  if (Tok.isNot(tok::eod)) {
2331    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2332      << "pointers_to_members";
2333    return;
2334  }
2335
2336  Token AnnotTok;
2337  AnnotTok.startToken();
2338  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2339  AnnotTok.setLocation(PointersToMembersLoc);
2340  AnnotTok.setAnnotationEndLoc(EndLoc);
2341  AnnotTok.setAnnotationValue(
2342      reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2343  PP.EnterToken(AnnotTok, /*IsReinject=*/true);
2344}
2345
2346/// Handle '#pragma vtordisp'
2347// The grammar for this pragma is as follows:
2348//
2349// <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2350//
2351// #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2352// #pragma vtordisp '(' 'pop' ')'
2353// #pragma vtordisp '(' ')'
2354void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2355                                    PragmaIntroducer Introducer, Token &Tok) {
2356  SourceLocation VtorDispLoc = Tok.getLocation();
2357  PP.Lex(Tok);
2358  if (Tok.isNot(tok::l_paren)) {
2359    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2360    return;
2361  }
2362  PP.Lex(Tok);
2363
2364  Sema::PragmaMsStackAction Action = Sema::PSK_Set;
2365  const IdentifierInfo *II = Tok.getIdentifierInfo();
2366  if (II) {
2367    if (II->isStr("push")) {
2368      // #pragma vtordisp(push, mode)
2369      PP.Lex(Tok);
2370      if (Tok.isNot(tok::comma)) {
2371        PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2372        return;
2373      }
2374      PP.Lex(Tok);
2375      Action = Sema::PSK_Push_Set;
2376      // not push, could be on/off
2377    } else if (II->isStr("pop")) {
2378      // #pragma vtordisp(pop)
2379      PP.Lex(Tok);
2380      Action = Sema::PSK_Pop;
2381    }
2382    // not push or pop, could be on/off
2383  } else {
2384    if (Tok.is(tok::r_paren)) {
2385      // #pragma vtordisp()
2386      Action = Sema::PSK_Reset;
2387    }
2388  }
2389
2390
2391  uint64_t Value = 0;
2392  if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
2393    const IdentifierInfo *II = Tok.getIdentifierInfo();
2394    if (II && II->isStr("off")) {
2395      PP.Lex(Tok);
2396      Value = 0;
2397    } else if (II && II->isStr("on")) {
2398      PP.Lex(Tok);
2399      Value = 1;
2400    } else if (Tok.is(tok::numeric_constant) &&
2401               PP.parseSimpleIntegerLiteral(Tok, Value)) {
2402      if (Value > 2) {
2403        PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2404            << 0 << 2 << "vtordisp";
2405        return;
2406      }
2407    } else {
2408      PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2409          << "vtordisp";
2410      return;
2411    }
2412  }
2413
2414  // Finish the pragma: ')' $
2415  if (Tok.isNot(tok::r_paren)) {
2416    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2417    return;
2418  }
2419  SourceLocation EndLoc = Tok.getLocation();
2420  PP.Lex(Tok);
2421  if (Tok.isNot(tok::eod)) {
2422    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2423        << "vtordisp";
2424    return;
2425  }
2426
2427  // Enter the annotation.
2428  Token AnnotTok;
2429  AnnotTok.startToken();
2430  AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2431  AnnotTok.setLocation(VtorDispLoc);
2432  AnnotTok.setAnnotationEndLoc(EndLoc);
2433  AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2434      static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2435  PP.EnterToken(AnnotTok, /*IsReinject=*/false);
2436}
2437
2438/// Handle all MS pragmas.  Simply forwards the tokens after inserting
2439/// an annotation token.
2440void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2441                                  PragmaIntroducer Introducer, Token &Tok) {
2442  Token EoF, AnnotTok;
2443  EoF.startToken();
2444  EoF.setKind(tok::eof);
2445  AnnotTok.startToken();
2446  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2447  AnnotTok.setLocation(Tok.getLocation());
2448  AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2449  SmallVector<Token, 8> TokenVector;
2450  // Suck up all of the tokens before the eod.
2451  for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2452    TokenVector.push_back(Tok);
2453    AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2454  }
2455  // Add a sentinel EoF token to the end of the list.
2456  TokenVector.push_back(EoF);
2457  // We must allocate this array with new because EnterTokenStream is going to
2458  // delete it later.
2459  auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2460  std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2461  auto Value = new (PP.getPreprocessorAllocator())
2462      std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2463                                                  TokenVector.size());
2464  AnnotTok.setAnnotationValue(Value);
2465  PP.EnterToken(AnnotTok, /*IsReinject*/ false);
2466}
2467
2468/// Handle the Microsoft \#pragma detect_mismatch extension.
2469///
2470/// The syntax is:
2471/// \code
2472///   #pragma detect_mismatch("name", "value")
2473/// \endcode
2474/// Where 'name' and 'value' are quoted strings.  The values are embedded in
2475/// the object file and passed along to the linker.  If the linker detects a
2476/// mismatch in the object file's values for the given name, a LNK2038 error
2477/// is emitted.  See MSDN for more details.
2478void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2479                                               PragmaIntroducer Introducer,
2480                                               Token &Tok) {
2481  SourceLocation DetectMismatchLoc = Tok.getLocation();
2482  PP.Lex(Tok);
2483  if (Tok.isNot(tok::l_paren)) {
2484    PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2485    return;
2486  }
2487
2488  // Read the name to embed, which must be a string literal.
2489  std::string NameString;
2490  if (!PP.LexStringLiteral(Tok, NameString,
2491                           "pragma detect_mismatch",
2492                           /*AllowMacroExpansion=*/true))
2493    return;
2494
2495  // Read the comma followed by a second string literal.
2496  std::string ValueString;
2497  if (Tok.isNot(tok::comma)) {
2498    PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2499    return;
2500  }
2501
2502  if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2503                           /*AllowMacroExpansion=*/true))
2504    return;
2505
2506  if (Tok.isNot(tok::r_paren)) {
2507    PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2508    return;
2509  }
2510  PP.Lex(Tok);  // Eat the r_paren.
2511
2512  if (Tok.isNot(tok::eod)) {
2513    PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2514    return;
2515  }
2516
2517  // If the pragma is lexically sound, notify any interested PPCallbacks.
2518  if (PP.getPPCallbacks())
2519    PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2520                                              ValueString);
2521
2522  Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2523}
2524
2525/// Handle the microsoft \#pragma comment extension.
2526///
2527/// The syntax is:
2528/// \code
2529///   #pragma comment(linker, "foo")
2530/// \endcode
2531/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2532/// "foo" is a string, which is fully macro expanded, and permits string
2533/// concatenation, embedded escape characters etc.  See MSDN for more details.
2534void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2535                                        PragmaIntroducer Introducer,
2536                                        Token &Tok) {
2537  SourceLocation CommentLoc = Tok.getLocation();
2538  PP.Lex(Tok);
2539  if (Tok.isNot(tok::l_paren)) {
2540    PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2541    return;
2542  }
2543
2544  // Read the identifier.
2545  PP.Lex(Tok);
2546  if (Tok.isNot(tok::identifier)) {
2547    PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2548    return;
2549  }
2550
2551  // Verify that this is one of the 5 whitelisted options.
2552  IdentifierInfo *II = Tok.getIdentifierInfo();
2553  PragmaMSCommentKind Kind =
2554    llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2555    .Case("linker",   PCK_Linker)
2556    .Case("lib",      PCK_Lib)
2557    .Case("compiler", PCK_Compiler)
2558    .Case("exestr",   PCK_ExeStr)
2559    .Case("user",     PCK_User)
2560    .Default(PCK_Unknown);
2561  if (Kind == PCK_Unknown) {
2562    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2563    return;
2564  }
2565
2566  if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
2567    PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2568        << II->getName();
2569    return;
2570  }
2571
2572  // On PS4, issue a warning about any pragma comments other than
2573  // #pragma comment lib.
2574  if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
2575    PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2576      << II->getName();
2577    return;
2578  }
2579
2580  // Read the optional string if present.
2581  PP.Lex(Tok);
2582  std::string ArgumentString;
2583  if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2584                                                 "pragma comment",
2585                                                 /*AllowMacroExpansion=*/true))
2586    return;
2587
2588  // FIXME: warn that 'exestr' is deprecated.
2589  // FIXME: If the kind is "compiler" warn if the string is present (it is
2590  // ignored).
2591  // The MSDN docs say that "lib" and "linker" require a string and have a short
2592  // whitelist of linker options they support, but in practice MSVC doesn't
2593  // issue a diagnostic.  Therefore neither does clang.
2594
2595  if (Tok.isNot(tok::r_paren)) {
2596    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2597    return;
2598  }
2599  PP.Lex(Tok);  // eat the r_paren.
2600
2601  if (Tok.isNot(tok::eod)) {
2602    PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2603    return;
2604  }
2605
2606  // If the pragma is lexically sound, notify any interested PPCallbacks.
2607  if (PP.getPPCallbacks())
2608    PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2609
2610  Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2611}
2612
2613// #pragma clang optimize off
2614// #pragma clang optimize on
2615void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2616                                         PragmaIntroducer Introducer,
2617                                         Token &FirstToken) {
2618  Token Tok;
2619  PP.Lex(Tok);
2620  if (Tok.is(tok::eod)) {
2621    PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2622        << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
2623    return;
2624  }
2625  if (Tok.isNot(tok::identifier)) {
2626    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2627      << PP.getSpelling(Tok);
2628    return;
2629  }
2630  const IdentifierInfo *II = Tok.getIdentifierInfo();
2631  // The only accepted values are 'on' or 'off'.
2632  bool IsOn = false;
2633  if (II->isStr("on")) {
2634    IsOn = true;
2635  } else if (!II->isStr("off")) {
2636    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2637      << PP.getSpelling(Tok);
2638    return;
2639  }
2640  PP.Lex(Tok);
2641
2642  if (Tok.isNot(tok::eod)) {
2643    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
2644      << PP.getSpelling(Tok);
2645    return;
2646  }
2647
2648  Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
2649}
2650
2651namespace {
2652/// Used as the annotation value for tok::annot_pragma_fp.
2653struct TokFPAnnotValue {
2654  enum FlagKinds { Contract };
2655  enum FlagValues { On, Off, Fast };
2656
2657  FlagKinds FlagKind;
2658  FlagValues FlagValue;
2659};
2660} // end anonymous namespace
2661
2662void PragmaFPHandler::HandlePragma(Preprocessor &PP,
2663                                   PragmaIntroducer Introducer, Token &Tok) {
2664  // fp
2665  Token PragmaName = Tok;
2666  SmallVector<Token, 1> TokenList;
2667
2668  PP.Lex(Tok);
2669  if (Tok.isNot(tok::identifier)) {
2670    PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2671        << /*MissingOption=*/true << "";
2672    return;
2673  }
2674
2675  while (Tok.is(tok::identifier)) {
2676    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2677
2678    auto FlagKind =
2679        llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2680            OptionInfo->getName())
2681            .Case("contract", TokFPAnnotValue::Contract)
2682            .Default(None);
2683    if (!FlagKind) {
2684      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2685          << /*MissingOption=*/false << OptionInfo;
2686      return;
2687    }
2688    PP.Lex(Tok);
2689
2690    // Read '('
2691    if (Tok.isNot(tok::l_paren)) {
2692      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2693      return;
2694    }
2695    PP.Lex(Tok);
2696
2697    if (Tok.isNot(tok::identifier)) {
2698      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2699          << PP.getSpelling(Tok) << OptionInfo->getName();
2700      return;
2701    }
2702    const IdentifierInfo *II = Tok.getIdentifierInfo();
2703
2704    auto FlagValue =
2705        llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2706            II->getName())
2707            .Case("on", TokFPAnnotValue::On)
2708            .Case("off", TokFPAnnotValue::Off)
2709            .Case("fast", TokFPAnnotValue::Fast)
2710            .Default(llvm::None);
2711
2712    if (!FlagValue) {
2713      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2714          << PP.getSpelling(Tok) << OptionInfo->getName();
2715      return;
2716    }
2717    PP.Lex(Tok);
2718
2719    // Read ')'
2720    if (Tok.isNot(tok::r_paren)) {
2721      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2722      return;
2723    }
2724    PP.Lex(Tok);
2725
2726    auto *AnnotValue = new (PP.getPreprocessorAllocator())
2727        TokFPAnnotValue{*FlagKind, *FlagValue};
2728    // Generate the loop hint token.
2729    Token FPTok;
2730    FPTok.startToken();
2731    FPTok.setKind(tok::annot_pragma_fp);
2732    FPTok.setLocation(PragmaName.getLocation());
2733    FPTok.setAnnotationEndLoc(PragmaName.getLocation());
2734    FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
2735    TokenList.push_back(FPTok);
2736  }
2737
2738  if (Tok.isNot(tok::eod)) {
2739    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2740        << "clang fp";
2741    return;
2742  }
2743
2744  auto TokenArray = std::make_unique<Token[]>(TokenList.size());
2745  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2746
2747  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2748                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2749}
2750
2751void Parser::HandlePragmaFP() {
2752  assert(Tok.is(tok::annot_pragma_fp));
2753  auto *AnnotValue =
2754      reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
2755
2756  LangOptions::FPContractModeKind FPC;
2757  switch (AnnotValue->FlagValue) {
2758  case TokFPAnnotValue::On:
2759    FPC = LangOptions::FPC_On;
2760    break;
2761  case TokFPAnnotValue::Fast:
2762    FPC = LangOptions::FPC_Fast;
2763    break;
2764  case TokFPAnnotValue::Off:
2765    FPC = LangOptions::FPC_Off;
2766    break;
2767  }
2768
2769  Actions.ActOnPragmaFPContract(FPC);
2770  ConsumeAnnotationToken();
2771}
2772
2773/// Parses loop or unroll pragma hint value and fills in Info.
2774static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
2775                               Token Option, bool ValueInParens,
2776                               PragmaLoopHintInfo &Info) {
2777  SmallVector<Token, 1> ValueList;
2778  int OpenParens = ValueInParens ? 1 : 0;
2779  // Read constant expression.
2780  while (Tok.isNot(tok::eod)) {
2781    if (Tok.is(tok::l_paren))
2782      OpenParens++;
2783    else if (Tok.is(tok::r_paren)) {
2784      OpenParens--;
2785      if (OpenParens == 0 && ValueInParens)
2786        break;
2787    }
2788
2789    ValueList.push_back(Tok);
2790    PP.Lex(Tok);
2791  }
2792
2793  if (ValueInParens) {
2794    // Read ')'
2795    if (Tok.isNot(tok::r_paren)) {
2796      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2797      return true;
2798    }
2799    PP.Lex(Tok);
2800  }
2801
2802  Token EOFTok;
2803  EOFTok.startToken();
2804  EOFTok.setKind(tok::eof);
2805  EOFTok.setLocation(Tok.getLocation());
2806  ValueList.push_back(EOFTok); // Terminates expression for parsing.
2807
2808  Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
2809
2810  Info.PragmaName = PragmaName;
2811  Info.Option = Option;
2812  return false;
2813}
2814
2815/// Handle the \#pragma clang loop directive.
2816///  #pragma clang 'loop' loop-hints
2817///
2818///  loop-hints:
2819///    loop-hint loop-hints[opt]
2820///
2821///  loop-hint:
2822///    'vectorize' '(' loop-hint-keyword ')'
2823///    'interleave' '(' loop-hint-keyword ')'
2824///    'unroll' '(' unroll-hint-keyword ')'
2825///    'vectorize_predicate' '(' loop-hint-keyword ')'
2826///    'vectorize_width' '(' loop-hint-value ')'
2827///    'interleave_count' '(' loop-hint-value ')'
2828///    'unroll_count' '(' loop-hint-value ')'
2829///    'pipeline' '(' disable ')'
2830///    'pipeline_initiation_interval' '(' loop-hint-value ')'
2831///
2832///  loop-hint-keyword:
2833///    'enable'
2834///    'disable'
2835///    'assume_safety'
2836///
2837///  unroll-hint-keyword:
2838///    'enable'
2839///    'disable'
2840///    'full'
2841///
2842///  loop-hint-value:
2843///    constant-expression
2844///
2845/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2846/// try vectorizing the instructions of the loop it precedes. Specifying
2847/// interleave(enable) or interleave_count(_value_) instructs llvm to try
2848/// interleaving multiple iterations of the loop it precedes. The width of the
2849/// vector instructions is specified by vectorize_width() and the number of
2850/// interleaved loop iterations is specified by interleave_count(). Specifying a
2851/// value of 1 effectively disables vectorization/interleaving, even if it is
2852/// possible and profitable, and 0 is invalid. The loop vectorizer currently
2853/// only works on inner loops.
2854///
2855/// The unroll and unroll_count directives control the concatenation
2856/// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2857/// completely if the trip count is known at compile time and unroll partially
2858/// if the trip count is not known.  Specifying unroll(full) is similar to
2859/// unroll(enable) but will unroll the loop only if the trip count is known at
2860/// compile time.  Specifying unroll(disable) disables unrolling for the
2861/// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2862/// loop the number of times indicated by the value.
2863void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2864                                         PragmaIntroducer Introducer,
2865                                         Token &Tok) {
2866  // Incoming token is "loop" from "#pragma clang loop".
2867  Token PragmaName = Tok;
2868  SmallVector<Token, 1> TokenList;
2869
2870  // Lex the optimization option and verify it is an identifier.
2871  PP.Lex(Tok);
2872  if (Tok.isNot(tok::identifier)) {
2873    PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2874        << /*MissingOption=*/true << "";
2875    return;
2876  }
2877
2878  while (Tok.is(tok::identifier)) {
2879    Token Option = Tok;
2880    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2881
2882    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2883                           .Case("vectorize", true)
2884                           .Case("interleave", true)
2885                           .Case("unroll", true)
2886                           .Case("distribute", true)
2887                           .Case("vectorize_predicate", true)
2888                           .Case("vectorize_width", true)
2889                           .Case("interleave_count", true)
2890                           .Case("unroll_count", true)
2891                           .Case("pipeline", true)
2892                           .Case("pipeline_initiation_interval", true)
2893                           .Default(false);
2894    if (!OptionValid) {
2895      PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2896          << /*MissingOption=*/false << OptionInfo;
2897      return;
2898    }
2899    PP.Lex(Tok);
2900
2901    // Read '('
2902    if (Tok.isNot(tok::l_paren)) {
2903      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2904      return;
2905    }
2906    PP.Lex(Tok);
2907
2908    auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2909    if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2910                           *Info))
2911      return;
2912
2913    // Generate the loop hint token.
2914    Token LoopHintTok;
2915    LoopHintTok.startToken();
2916    LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2917    LoopHintTok.setLocation(PragmaName.getLocation());
2918    LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2919    LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2920    TokenList.push_back(LoopHintTok);
2921  }
2922
2923  if (Tok.isNot(tok::eod)) {
2924    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2925        << "clang loop";
2926    return;
2927  }
2928
2929  auto TokenArray = std::make_unique<Token[]>(TokenList.size());
2930  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2931
2932  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2933                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2934}
2935
2936/// Handle the loop unroll optimization pragmas.
2937///  #pragma unroll
2938///  #pragma unroll unroll-hint-value
2939///  #pragma unroll '(' unroll-hint-value ')'
2940///  #pragma nounroll
2941///  #pragma unroll_and_jam
2942///  #pragma unroll_and_jam unroll-hint-value
2943///  #pragma unroll_and_jam '(' unroll-hint-value ')'
2944///  #pragma nounroll_and_jam
2945///
2946///  unroll-hint-value:
2947///    constant-expression
2948///
2949/// Loop unrolling hints can be specified with '#pragma unroll' or
2950/// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2951/// contained in parentheses. With no argument the directive instructs llvm to
2952/// try to unroll the loop completely. A positive integer argument can be
2953/// specified to indicate the number of times the loop should be unrolled.  To
2954/// maximize compatibility with other compilers the unroll count argument can be
2955/// specified with or without parentheses.  Specifying, '#pragma nounroll'
2956/// disables unrolling of the loop.
2957void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2958                                           PragmaIntroducer Introducer,
2959                                           Token &Tok) {
2960  // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2961  // "#pragma nounroll".
2962  Token PragmaName = Tok;
2963  PP.Lex(Tok);
2964  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2965  if (Tok.is(tok::eod)) {
2966    // nounroll or unroll pragma without an argument.
2967    Info->PragmaName = PragmaName;
2968    Info->Option.startToken();
2969  } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" ||
2970             PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam") {
2971    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2972        << PragmaName.getIdentifierInfo()->getName();
2973    return;
2974  } else {
2975    // Unroll pragma with an argument: "#pragma unroll N" or
2976    // "#pragma unroll(N)".
2977    // Read '(' if it exists.
2978    bool ValueInParens = Tok.is(tok::l_paren);
2979    if (ValueInParens)
2980      PP.Lex(Tok);
2981
2982    Token Option;
2983    Option.startToken();
2984    if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2985      return;
2986
2987    // In CUDA, the argument to '#pragma unroll' should not be contained in
2988    // parentheses.
2989    if (PP.getLangOpts().CUDA && ValueInParens)
2990      PP.Diag(Info->Toks[0].getLocation(),
2991              diag::warn_pragma_unroll_cuda_value_in_parens);
2992
2993    if (Tok.isNot(tok::eod)) {
2994      PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2995          << "unroll";
2996      return;
2997    }
2998  }
2999
3000  // Generate the hint token.
3001  auto TokenArray = std::make_unique<Token[]>(1);
3002  TokenArray[0].startToken();
3003  TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3004  TokenArray[0].setLocation(PragmaName.getLocation());
3005  TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
3006  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3007  PP.EnterTokenStream(std::move(TokenArray), 1,
3008                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3009}
3010
3011/// Handle the Microsoft \#pragma intrinsic extension.
3012///
3013/// The syntax is:
3014/// \code
3015///  #pragma intrinsic(memset)
3016///  #pragma intrinsic(strlen, memcpy)
3017/// \endcode
3018///
3019/// Pragma intrisic tells the compiler to use a builtin version of the
3020/// function. Clang does it anyway, so the pragma doesn't really do anything.
3021/// Anyway, we emit a warning if the function specified in \#pragma intrinsic
3022/// isn't an intrinsic in clang and suggest to include intrin.h.
3023void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
3024                                            PragmaIntroducer Introducer,
3025                                            Token &Tok) {
3026  PP.Lex(Tok);
3027
3028  if (Tok.isNot(tok::l_paren)) {
3029    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
3030        << "intrinsic";
3031    return;
3032  }
3033  PP.Lex(Tok);
3034
3035  bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3036
3037  while (Tok.is(tok::identifier)) {
3038    IdentifierInfo *II = Tok.getIdentifierInfo();
3039    if (!II->getBuiltinID())
3040      PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3041          << II << SuggestIntrinH;
3042
3043    PP.Lex(Tok);
3044    if (Tok.isNot(tok::comma))
3045      break;
3046    PP.Lex(Tok);
3047  }
3048
3049  if (Tok.isNot(tok::r_paren)) {
3050    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
3051        << "intrinsic";
3052    return;
3053  }
3054  PP.Lex(Tok);
3055
3056  if (Tok.isNot(tok::eod))
3057    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3058        << "intrinsic";
3059}
3060
3061// #pragma optimize("gsty", on|off)
3062void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
3063                                           PragmaIntroducer Introducer,
3064                                           Token &Tok) {
3065  SourceLocation StartLoc = Tok.getLocation();
3066  PP.Lex(Tok);
3067
3068  if (Tok.isNot(tok::l_paren)) {
3069    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
3070    return;
3071  }
3072  PP.Lex(Tok);
3073
3074  if (Tok.isNot(tok::string_literal)) {
3075    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
3076    return;
3077  }
3078  // We could syntax check the string but it's probably not worth the effort.
3079  PP.Lex(Tok);
3080
3081  if (Tok.isNot(tok::comma)) {
3082    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
3083    return;
3084  }
3085  PP.Lex(Tok);
3086
3087  if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
3088    PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
3089        << "optimize" << /*Expected=*/true << "'on' or 'off'";
3090    return;
3091  }
3092  IdentifierInfo *II = Tok.getIdentifierInfo();
3093  if (!II || (!II->isStr("on") && !II->isStr("off"))) {
3094    PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
3095        << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
3096        << "'on' or 'off'";
3097    return;
3098  }
3099  PP.Lex(Tok);
3100
3101  if (Tok.isNot(tok::r_paren)) {
3102    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
3103    return;
3104  }
3105  PP.Lex(Tok);
3106
3107  if (Tok.isNot(tok::eod)) {
3108    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3109        << "optimize";
3110    return;
3111  }
3112  PP.Diag(StartLoc, diag::warn_pragma_optimize);
3113}
3114
3115void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3116    Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) {
3117  Token FirstTok = Tok;
3118
3119  PP.Lex(Tok);
3120  IdentifierInfo *Info = Tok.getIdentifierInfo();
3121  if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
3122    PP.Diag(FirstTok.getLocation(),
3123            diag::warn_pragma_force_cuda_host_device_bad_arg);
3124    return;
3125  }
3126
3127  if (Info->isStr("begin"))
3128    Actions.PushForceCUDAHostDevice();
3129  else if (!Actions.PopForceCUDAHostDevice())
3130    PP.Diag(FirstTok.getLocation(),
3131            diag::err_pragma_cannot_end_force_cuda_host_device);
3132
3133  PP.Lex(Tok);
3134  if (!Tok.is(tok::eod))
3135    PP.Diag(FirstTok.getLocation(),
3136            diag::warn_pragma_force_cuda_host_device_bad_arg);
3137}
3138
3139/// Handle the #pragma clang attribute directive.
3140///
3141/// The syntax is:
3142/// \code
3143///  #pragma clang attribute push (attribute, subject-set)
3144///  #pragma clang attribute push
3145///  #pragma clang attribute (attribute, subject-set)
3146///  #pragma clang attribute pop
3147/// \endcode
3148///
3149/// There are also 'namespace' variants of push and pop directives. The bare
3150/// '#pragma clang attribute (attribute, subject-set)' version doesn't require a
3151/// namespace, since it always applies attributes to the most recently pushed
3152/// group, regardless of namespace.
3153/// \code
3154///  #pragma clang attribute namespace.push (attribute, subject-set)
3155///  #pragma clang attribute namespace.push
3156///  #pragma clang attribute namespace.pop
3157/// \endcode
3158///
3159/// The subject-set clause defines the set of declarations which receive the
3160/// attribute. Its exact syntax is described in the LanguageExtensions document
3161/// in Clang's documentation.
3162///
3163/// This directive instructs the compiler to begin/finish applying the specified
3164/// attribute to the set of attribute-specific declarations in the active range
3165/// of the pragma.
3166void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3167                                          PragmaIntroducer Introducer,
3168                                          Token &FirstToken) {
3169  Token Tok;
3170  PP.Lex(Tok);
3171  auto *Info = new (PP.getPreprocessorAllocator())
3172      PragmaAttributeInfo(AttributesForPragmaAttribute);
3173
3174  // Parse the optional namespace followed by a period.
3175  if (Tok.is(tok::identifier)) {
3176    IdentifierInfo *II = Tok.getIdentifierInfo();
3177    if (!II->isStr("push") && !II->isStr("pop")) {
3178      Info->Namespace = II;
3179      PP.Lex(Tok);
3180
3181      if (!Tok.is(tok::period)) {
3182        PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
3183            << II;
3184        return;
3185      }
3186      PP.Lex(Tok);
3187    }
3188  }
3189
3190  if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
3191    PP.Diag(Tok.getLocation(),
3192            diag::err_pragma_attribute_expected_push_pop_paren);
3193    return;
3194  }
3195
3196  // Determine what action this pragma clang attribute represents.
3197  if (Tok.is(tok::l_paren)) {
3198    if (Info->Namespace) {
3199      PP.Diag(Tok.getLocation(),
3200              diag::err_pragma_attribute_namespace_on_attribute);
3201      PP.Diag(Tok.getLocation(),
3202              diag::note_pragma_attribute_namespace_on_attribute);
3203      return;
3204    }
3205    Info->Action = PragmaAttributeInfo::Attribute;
3206  } else {
3207    const IdentifierInfo *II = Tok.getIdentifierInfo();
3208    if (II->isStr("push"))
3209      Info->Action = PragmaAttributeInfo::Push;
3210    else if (II->isStr("pop"))
3211      Info->Action = PragmaAttributeInfo::Pop;
3212    else {
3213      PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
3214          << PP.getSpelling(Tok);
3215      return;
3216    }
3217
3218    PP.Lex(Tok);
3219  }
3220
3221  // Parse the actual attribute.
3222  if ((Info->Action == PragmaAttributeInfo::Push && Tok.isNot(tok::eod)) ||
3223      Info->Action == PragmaAttributeInfo::Attribute) {
3224    if (Tok.isNot(tok::l_paren)) {
3225      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3226      return;
3227    }
3228    PP.Lex(Tok);
3229
3230    // Lex the attribute tokens.
3231    SmallVector<Token, 16> AttributeTokens;
3232    int OpenParens = 1;
3233    while (Tok.isNot(tok::eod)) {
3234      if (Tok.is(tok::l_paren))
3235        OpenParens++;
3236      else if (Tok.is(tok::r_paren)) {
3237        OpenParens--;
3238        if (OpenParens == 0)
3239          break;
3240      }
3241
3242      AttributeTokens.push_back(Tok);
3243      PP.Lex(Tok);
3244    }
3245
3246    if (AttributeTokens.empty()) {
3247      PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
3248      return;
3249    }
3250    if (Tok.isNot(tok::r_paren)) {
3251      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3252      return;
3253    }
3254    SourceLocation EndLoc = Tok.getLocation();
3255    PP.Lex(Tok);
3256
3257    // Terminate the attribute for parsing.
3258    Token EOFTok;
3259    EOFTok.startToken();
3260    EOFTok.setKind(tok::eof);
3261    EOFTok.setLocation(EndLoc);
3262    AttributeTokens.push_back(EOFTok);
3263
3264    Info->Tokens =
3265        llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
3266  }
3267
3268  if (Tok.isNot(tok::eod))
3269    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3270        << "clang attribute";
3271
3272  // Generate the annotated pragma token.
3273  auto TokenArray = std::make_unique<Token[]>(1);
3274  TokenArray[0].startToken();
3275  TokenArray[0].setKind(tok::annot_pragma_attribute);
3276  TokenArray[0].setLocation(FirstToken.getLocation());
3277  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
3278  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3279  PP.EnterTokenStream(std::move(TokenArray), 1,
3280                      /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3281}
3282