Clang Project

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