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