blob: 46225c8e79109bdc5e28cc24429d4768e4cdb8ad [file] [log] [blame]
Daniel Dunbar921b9682008-10-04 19:21:03 +00001//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the language specific #pragma handlers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ParsePragma.h"
Chris Lattner60f36222009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Ted Kremenekfd14fad2009-03-23 22:28:25 +000016#include "clang/Parse/Parser.h"
John McCall8b0666c2010-08-20 18:27:03 +000017#include "clang/Lex/Preprocessor.h"
Daniel Dunbar921b9682008-10-04 19:21:03 +000018using namespace clang;
19
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +000020/// \brief Handle the annotation token produced for #pragma unused(...)
21///
22/// Each annot_pragma_unused is followed by the argument token so e.g.
23/// "#pragma unused(x,y)" becomes:
24/// annot_pragma_unused 'x' annot_pragma_unused 'y'
25void Parser::HandlePragmaUnused() {
26 assert(Tok.is(tok::annot_pragma_unused));
27 SourceLocation UnusedLoc = ConsumeToken();
28 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
29 ConsumeToken(); // The argument token.
30}
Eli Friedman570024a2010-08-05 06:57:20 +000031
32// #pragma GCC visibility comes in two variants:
33// 'push' '(' [visibility] ')'
34// 'pop'
Douglas Gregorc7d65762010-09-09 22:45:38 +000035void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
36 PragmaIntroducerKind Introducer,
37 Token &VisTok) {
Eli Friedman570024a2010-08-05 06:57:20 +000038 SourceLocation VisLoc = VisTok.getLocation();
39
40 Token Tok;
41 PP.Lex(Tok);
42
43 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
44
45 bool IsPush;
46 const IdentifierInfo *VisType;
47 if (PushPop && PushPop->isStr("pop")) {
48 IsPush = false;
49 VisType = 0;
50 } else if (PushPop && PushPop->isStr("push")) {
51 IsPush = true;
52 PP.Lex(Tok);
53 if (Tok.isNot(tok::l_paren)) {
54 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
55 << "visibility";
56 return;
57 }
58 PP.Lex(Tok);
59 VisType = Tok.getIdentifierInfo();
60 if (!VisType) {
61 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
62 << "visibility";
63 return;
64 }
65 PP.Lex(Tok);
66 if (Tok.isNot(tok::r_paren)) {
67 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
68 << "visibility";
69 return;
70 }
71 } else {
72 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
73 << "visibility";
74 return;
75 }
76 PP.Lex(Tok);
Peter Collingbourne2f1e36b2011-02-28 02:37:51 +000077 if (Tok.isNot(tok::eod)) {
Eli Friedman570024a2010-08-05 06:57:20 +000078 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
79 << "visibility";
80 return;
81 }
82
83 Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc);
84}
85
Daniel Dunbar921b9682008-10-04 19:21:03 +000086// #pragma pack(...) comes in the following delicious flavors:
87// pack '(' [integer] ')'
88// pack '(' 'show' ')'
89// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
Douglas Gregorc7d65762010-09-09 22:45:38 +000090void PragmaPackHandler::HandlePragma(Preprocessor &PP,
91 PragmaIntroducerKind Introducer,
92 Token &PackTok) {
Daniel Dunbar921b9682008-10-04 19:21:03 +000093 SourceLocation PackLoc = PackTok.getLocation();
94
95 Token Tok;
96 PP.Lex(Tok);
97 if (Tok.isNot(tok::l_paren)) {
Ted Kremenekfd14fad2009-03-23 22:28:25 +000098 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
Daniel Dunbar921b9682008-10-04 19:21:03 +000099 return;
100 }
101
John McCallfaf5fb42010-08-26 23:41:50 +0000102 Sema::PragmaPackKind Kind = Sema::PPK_Default;
Daniel Dunbar921b9682008-10-04 19:21:03 +0000103 IdentifierInfo *Name = 0;
John McCalldadc5752010-08-24 06:29:42 +0000104 ExprResult Alignment;
Daniel Dunbar921b9682008-10-04 19:21:03 +0000105 SourceLocation LParenLoc = Tok.getLocation();
Mike Stump11289f42009-09-09 15:08:12 +0000106 PP.Lex(Tok);
Daniel Dunbar921b9682008-10-04 19:21:03 +0000107 if (Tok.is(tok::numeric_constant)) {
108 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl17f2c7d2008-12-09 13:15:23 +0000109 if (Alignment.isInvalid())
Daniel Dunbar921b9682008-10-04 19:21:03 +0000110 return;
111
112 PP.Lex(Tok);
113 } else if (Tok.is(tok::identifier)) {
114 const IdentifierInfo *II = Tok.getIdentifierInfo();
Chris Lattnere3d20d92008-11-23 21:45:46 +0000115 if (II->isStr("show")) {
John McCallfaf5fb42010-08-26 23:41:50 +0000116 Kind = Sema::PPK_Show;
Daniel Dunbar921b9682008-10-04 19:21:03 +0000117 PP.Lex(Tok);
118 } else {
Chris Lattnere3d20d92008-11-23 21:45:46 +0000119 if (II->isStr("push")) {
John McCallfaf5fb42010-08-26 23:41:50 +0000120 Kind = Sema::PPK_Push;
Chris Lattnere3d20d92008-11-23 21:45:46 +0000121 } else if (II->isStr("pop")) {
John McCallfaf5fb42010-08-26 23:41:50 +0000122 Kind = Sema::PPK_Pop;
Daniel Dunbar921b9682008-10-04 19:21:03 +0000123 } else {
124 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
125 return;
Mike Stump11289f42009-09-09 15:08:12 +0000126 }
Daniel Dunbar921b9682008-10-04 19:21:03 +0000127 PP.Lex(Tok);
Mike Stump11289f42009-09-09 15:08:12 +0000128
Daniel Dunbar921b9682008-10-04 19:21:03 +0000129 if (Tok.is(tok::comma)) {
130 PP.Lex(Tok);
Mike Stump11289f42009-09-09 15:08:12 +0000131
Daniel Dunbar921b9682008-10-04 19:21:03 +0000132 if (Tok.is(tok::numeric_constant)) {
133 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl17f2c7d2008-12-09 13:15:23 +0000134 if (Alignment.isInvalid())
Daniel Dunbar921b9682008-10-04 19:21:03 +0000135 return;
136
137 PP.Lex(Tok);
138 } else if (Tok.is(tok::identifier)) {
139 Name = Tok.getIdentifierInfo();
140 PP.Lex(Tok);
Mike Stump11289f42009-09-09 15:08:12 +0000141
Daniel Dunbar921b9682008-10-04 19:21:03 +0000142 if (Tok.is(tok::comma)) {
143 PP.Lex(Tok);
Mike Stump11289f42009-09-09 15:08:12 +0000144
Daniel Dunbar921b9682008-10-04 19:21:03 +0000145 if (Tok.isNot(tok::numeric_constant)) {
Chris Lattnere3d20d92008-11-23 21:45:46 +0000146 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbar921b9682008-10-04 19:21:03 +0000147 return;
148 }
Mike Stump11289f42009-09-09 15:08:12 +0000149
Daniel Dunbar921b9682008-10-04 19:21:03 +0000150 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl17f2c7d2008-12-09 13:15:23 +0000151 if (Alignment.isInvalid())
Daniel Dunbar921b9682008-10-04 19:21:03 +0000152 return;
153
154 PP.Lex(Tok);
155 }
156 } else {
Chris Lattnere3d20d92008-11-23 21:45:46 +0000157 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbar921b9682008-10-04 19:21:03 +0000158 return;
159 }
160 }
161 }
Sebastian Redl17f2c7d2008-12-09 13:15:23 +0000162 }
Daniel Dunbar921b9682008-10-04 19:21:03 +0000163
164 if (Tok.isNot(tok::r_paren)) {
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000165 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
Daniel Dunbar921b9682008-10-04 19:21:03 +0000166 return;
167 }
168
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000169 SourceLocation RParenLoc = Tok.getLocation();
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000170 PP.Lex(Tok);
Peter Collingbourne2f1e36b2011-02-28 02:37:51 +0000171 if (Tok.isNot(tok::eod)) {
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000172 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
173 return;
174 }
175
Sebastian Redld9f7b1c2008-12-10 00:02:53 +0000176 Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
Daniel Dunbar921b9682008-10-04 19:21:03 +0000177 LParenLoc, RParenLoc);
178}
179
Fariborz Jahanian743dda42011-04-25 18:49:15 +0000180// #pragma ms_struct on
181// #pragma ms_struct off
182void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
183 PragmaIntroducerKind Introducer,
184 Token &MSStructTok) {
185 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
186
187 Token Tok;
188 PP.Lex(Tok);
189 if (Tok.isNot(tok::identifier)) {
190 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
191 return;
192 }
193 const IdentifierInfo *II = Tok.getIdentifierInfo();
194 if (II->isStr("on")) {
195 Kind = Sema::PMSST_ON;
196 PP.Lex(Tok);
197 }
198 else if (II->isStr("off") || II->isStr("reset"))
199 PP.Lex(Tok);
200 else {
201 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
202 return;
203 }
204
205 if (Tok.isNot(tok::eod)) {
206 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "ms_struct";
207 return;
208 }
209 Actions.ActOnPragmaMSStruct(Kind);
210}
211
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000212// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
213// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
John McCallfaf5fb42010-08-26 23:41:50 +0000214static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000215 bool IsOptions) {
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000216 Token Tok;
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000217
218 if (IsOptions) {
219 PP.Lex(Tok);
220 if (Tok.isNot(tok::identifier) ||
221 !Tok.getIdentifierInfo()->isStr("align")) {
222 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
223 return;
224 }
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000225 }
Daniel Dunbar663e8092010-05-27 18:42:09 +0000226
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000227 PP.Lex(Tok);
228 if (Tok.isNot(tok::equal)) {
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000229 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
230 << IsOptions;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000231 return;
232 }
233
234 PP.Lex(Tok);
235 if (Tok.isNot(tok::identifier)) {
236 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000237 << (IsOptions ? "options" : "align");
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000238 return;
239 }
240
John McCallfaf5fb42010-08-26 23:41:50 +0000241 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000242 const IdentifierInfo *II = Tok.getIdentifierInfo();
Daniel Dunbar663e8092010-05-27 18:42:09 +0000243 if (II->isStr("native"))
John McCallfaf5fb42010-08-26 23:41:50 +0000244 Kind = Sema::POAK_Native;
Daniel Dunbar663e8092010-05-27 18:42:09 +0000245 else if (II->isStr("natural"))
John McCallfaf5fb42010-08-26 23:41:50 +0000246 Kind = Sema::POAK_Natural;
Daniel Dunbar9c84d4a2010-05-27 18:42:17 +0000247 else if (II->isStr("packed"))
John McCallfaf5fb42010-08-26 23:41:50 +0000248 Kind = Sema::POAK_Packed;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000249 else if (II->isStr("power"))
John McCallfaf5fb42010-08-26 23:41:50 +0000250 Kind = Sema::POAK_Power;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000251 else if (II->isStr("mac68k"))
John McCallfaf5fb42010-08-26 23:41:50 +0000252 Kind = Sema::POAK_Mac68k;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000253 else if (II->isStr("reset"))
John McCallfaf5fb42010-08-26 23:41:50 +0000254 Kind = Sema::POAK_Reset;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000255 else {
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000256 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
257 << IsOptions;
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000258 return;
259 }
260
261 SourceLocation KindLoc = Tok.getLocation();
262 PP.Lex(Tok);
Peter Collingbourne2f1e36b2011-02-28 02:37:51 +0000263 if (Tok.isNot(tok::eod)) {
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000264 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000265 << (IsOptions ? "options" : "align");
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000266 return;
267 }
268
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000269 Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
270}
271
Douglas Gregorc7d65762010-09-09 22:45:38 +0000272void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
273 PragmaIntroducerKind Introducer,
274 Token &AlignTok) {
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000275 ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
276}
277
Douglas Gregorc7d65762010-09-09 22:45:38 +0000278void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
279 PragmaIntroducerKind Introducer,
280 Token &OptionsTok) {
Daniel Dunbarcb82acb2010-07-31 19:17:07 +0000281 ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
Daniel Dunbar75c9be72010-05-26 23:29:06 +0000282}
283
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000284// #pragma unused(identifier)
Douglas Gregorc7d65762010-09-09 22:45:38 +0000285void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
286 PragmaIntroducerKind Introducer,
287 Token &UnusedTok) {
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000288 // FIXME: Should we be expanding macros here? My guess is no.
289 SourceLocation UnusedLoc = UnusedTok.getLocation();
Mike Stump11289f42009-09-09 15:08:12 +0000290
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000291 // Lex the left '('.
292 Token Tok;
293 PP.Lex(Tok);
294 if (Tok.isNot(tok::l_paren)) {
295 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
296 return;
297 }
298 SourceLocation LParenLoc = Tok.getLocation();
Mike Stump11289f42009-09-09 15:08:12 +0000299
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000300 // Lex the declaration reference(s).
Ted Kremenekfb50bf52009-08-03 23:24:57 +0000301 llvm::SmallVector<Token, 5> Identifiers;
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000302 SourceLocation RParenLoc;
303 bool LexID = true;
Mike Stump11289f42009-09-09 15:08:12 +0000304
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000305 while (true) {
306 PP.Lex(Tok);
Mike Stump11289f42009-09-09 15:08:12 +0000307
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000308 if (LexID) {
Mike Stump11289f42009-09-09 15:08:12 +0000309 if (Tok.is(tok::identifier)) {
Ted Kremenekfb50bf52009-08-03 23:24:57 +0000310 Identifiers.push_back(Tok);
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000311 LexID = false;
312 continue;
313 }
314
Ted Kremenekfb50bf52009-08-03 23:24:57 +0000315 // Illegal token!
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000316 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
317 return;
318 }
Mike Stump11289f42009-09-09 15:08:12 +0000319
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000320 // We are execting a ')' or a ','.
321 if (Tok.is(tok::comma)) {
322 LexID = true;
323 continue;
324 }
Mike Stump11289f42009-09-09 15:08:12 +0000325
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000326 if (Tok.is(tok::r_paren)) {
327 RParenLoc = Tok.getLocation();
328 break;
329 }
Mike Stump11289f42009-09-09 15:08:12 +0000330
Ted Kremenekfb50bf52009-08-03 23:24:57 +0000331 // Illegal token!
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000332 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
333 return;
334 }
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000335
336 PP.Lex(Tok);
Peter Collingbourne2f1e36b2011-02-28 02:37:51 +0000337 if (Tok.isNot(tok::eod)) {
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000338 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
339 "unused";
340 return;
341 }
342
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000343 // Verify that we have a location for the right parenthesis.
344 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
Ted Kremenekfb50bf52009-08-03 23:24:57 +0000345 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000346
Argyrios Kyrtzidisee569622011-01-17 18:58:44 +0000347 // For each identifier token, insert into the token stream a
348 // annot_pragma_unused token followed by the identifier token.
349 // This allows us to cache a "#pragma unused" that occurs inside an inline
350 // C++ member function.
351
352 Token *Toks = new Token[2*Identifiers.size()];
353 for (unsigned i=0; i != Identifiers.size(); i++) {
354 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
355 pragmaUnusedTok.startToken();
356 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
357 pragmaUnusedTok.setLocation(UnusedLoc);
358 idTok = Identifiers[i];
359 }
360 PP.EnterTokenStream(Toks, 2*Identifiers.size(), /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
Ted Kremenekfd14fad2009-03-23 22:28:25 +0000361}
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000362
363// #pragma weak identifier
364// #pragma weak identifier '=' identifier
Douglas Gregorc7d65762010-09-09 22:45:38 +0000365void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
366 PragmaIntroducerKind Introducer,
367 Token &WeakTok) {
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000368 // FIXME: Should we be expanding macros here? My guess is no.
369 SourceLocation WeakLoc = WeakTok.getLocation();
370
371 Token Tok;
372 PP.Lex(Tok);
373 if (Tok.isNot(tok::identifier)) {
374 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
375 return;
376 }
377
378 IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
379 SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
380
381 PP.Lex(Tok);
382 if (Tok.is(tok::equal)) {
383 PP.Lex(Tok);
384 if (Tok.isNot(tok::identifier)) {
Mike Stump11289f42009-09-09 15:08:12 +0000385 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000386 << "weak";
387 return;
388 }
389 AliasName = Tok.getIdentifierInfo();
390 AliasNameLoc = Tok.getLocation();
391 PP.Lex(Tok);
392 }
393
Peter Collingbourne2f1e36b2011-02-28 02:37:51 +0000394 if (Tok.isNot(tok::eod)) {
Eli Friedmanf5867dd2009-06-05 00:49:58 +0000395 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
396 return;
397 }
398
399 if (AliasName) {
400 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
401 AliasNameLoc);
402 } else {
403 Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
404 }
405}
Peter Collingbourne564c0fa2011-02-14 01:42:35 +0000406
407void
408PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
409 PragmaIntroducerKind Introducer,
410 Token &Tok) {
411 tok::OnOffSwitch OOS;
412 if (PP.LexOnOffSwitch(OOS))
413 return;
414
415 Actions.ActOnPragmaFPContract(OOS);
416}
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +0000417
418void
419PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
420 PragmaIntroducerKind Introducer,
421 Token &Tok) {
Tanya Lattneree840b82011-04-14 23:35:31 +0000422 PP.LexUnexpandedToken(Tok);
Peter Collingbourne7ce13fc2011-02-14 01:42:53 +0000423 if (Tok.isNot(tok::identifier)) {
424 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
425 "OPENCL";
426 return;
427 }
428 IdentifierInfo *ename = Tok.getIdentifierInfo();
429 SourceLocation NameLoc = Tok.getLocation();
430
431 PP.Lex(Tok);
432 if (Tok.isNot(tok::colon)) {
433 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
434 return;
435 }
436
437 PP.Lex(Tok);
438 if (Tok.isNot(tok::identifier)) {
439 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
440 return;
441 }
442 IdentifierInfo *op = Tok.getIdentifierInfo();
443
444 unsigned state;
445 if (op->isStr("enable")) {
446 state = 1;
447 } else if (op->isStr("disable")) {
448 state = 0;
449 } else {
450 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
451 return;
452 }
453
454 OpenCLOptions &f = Actions.getOpenCLOptions();
455 if (ename->isStr("all")) {
456#define OPENCLEXT(nm) f.nm = state;
457#include "clang/Basic/OpenCLExtensions.def"
458 }
459#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
460#include "clang/Basic/OpenCLExtensions.def"
461 else {
462 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
463 return;
464 }
465}
466