blob: 2069d31dd27c23ae2ae160bd04e3d12205db01a0 [file] [log] [blame]
Daniel Dunbarfcdd8fe2008-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 Lattner500d3292009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Ted Kremenek4726d032009-03-23 22:28:25 +000016#include "clang/Parse/Parser.h"
John McCall19510852010-08-20 18:27:03 +000017#include "clang/Lex/Preprocessor.h"
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000018using namespace clang;
19
Argyrios Kyrtzidisb918d0f2011-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 Friedmanaa8b0d12010-08-05 06:57:20 +000031
32// #pragma GCC visibility comes in two variants:
33// 'push' '(' [visibility] ')'
34// 'pop'
Douglas Gregor80c60f72010-09-09 22:45:38 +000035void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
36 PragmaIntroducerKind Introducer,
37 Token &VisTok) {
Eli Friedmanaa8b0d12010-08-05 06:57:20 +000038 SourceLocation VisLoc = VisTok.getLocation();
39
40 Token Tok;
Joerg Sonnenbergere23af2a2011-07-20 01:03:50 +000041 PP.LexUnexpandedToken(Tok);
Eli Friedmanaa8b0d12010-08-05 06:57:20 +000042
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;
Joerg Sonnenbergere23af2a2011-07-20 01:03:50 +000052 PP.LexUnexpandedToken(Tok);
Eli Friedmanaa8b0d12010-08-05 06:57:20 +000053 if (Tok.isNot(tok::l_paren)) {
54 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
55 << "visibility";
56 return;
57 }
Joerg Sonnenbergere23af2a2011-07-20 01:03:50 +000058 PP.LexUnexpandedToken(Tok);
Eli Friedmanaa8b0d12010-08-05 06:57:20 +000059 VisType = Tok.getIdentifierInfo();
60 if (!VisType) {
61 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
62 << "visibility";
63 return;
64 }
Joerg Sonnenbergere23af2a2011-07-20 01:03:50 +000065 PP.LexUnexpandedToken(Tok);
Eli Friedmanaa8b0d12010-08-05 06:57:20 +000066 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 }
Joerg Sonnenbergere23af2a2011-07-20 01:03:50 +000076 PP.LexUnexpandedToken(Tok);
Peter Collingbourne84021552011-02-28 02:37:51 +000077 if (Tok.isNot(tok::eod)) {
Eli Friedmanaa8b0d12010-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 Dunbarfcdd8fe2008-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 Gregor80c60f72010-09-09 22:45:38 +000090void PragmaPackHandler::HandlePragma(Preprocessor &PP,
91 PragmaIntroducerKind Introducer,
92 Token &PackTok) {
Daniel Dunbarfcdd8fe2008-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 Kremenek4726d032009-03-23 22:28:25 +000098 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000099 return;
100 }
101
John McCallf312b1e2010-08-26 23:41:50 +0000102 Sema::PragmaPackKind Kind = Sema::PPK_Default;
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000103 IdentifierInfo *Name = 0;
John McCall60d7b3a2010-08-24 06:29:42 +0000104 ExprResult Alignment;
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000105 SourceLocation LParenLoc = Tok.getLocation();
Mike Stump1eb44332009-09-09 15:08:12 +0000106 PP.Lex(Tok);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000107 if (Tok.is(tok::numeric_constant)) {
108 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000109 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000110 return;
111
112 PP.Lex(Tok);
Eli Friedman19bda3a2011-11-02 01:53:16 +0000113
114 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
115 // the push/pop stack.
116 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
117 if (PP.getLangOptions().ApplePragmaPack)
118 Kind = Sema::PPK_Push;
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000119 } else if (Tok.is(tok::identifier)) {
120 const IdentifierInfo *II = Tok.getIdentifierInfo();
Chris Lattner08631c52008-11-23 21:45:46 +0000121 if (II->isStr("show")) {
John McCallf312b1e2010-08-26 23:41:50 +0000122 Kind = Sema::PPK_Show;
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000123 PP.Lex(Tok);
124 } else {
Chris Lattner08631c52008-11-23 21:45:46 +0000125 if (II->isStr("push")) {
John McCallf312b1e2010-08-26 23:41:50 +0000126 Kind = Sema::PPK_Push;
Chris Lattner08631c52008-11-23 21:45:46 +0000127 } else if (II->isStr("pop")) {
John McCallf312b1e2010-08-26 23:41:50 +0000128 Kind = Sema::PPK_Pop;
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000129 } else {
130 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
131 return;
Mike Stump1eb44332009-09-09 15:08:12 +0000132 }
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000133 PP.Lex(Tok);
Mike Stump1eb44332009-09-09 15:08:12 +0000134
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000135 if (Tok.is(tok::comma)) {
136 PP.Lex(Tok);
Mike Stump1eb44332009-09-09 15:08:12 +0000137
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000138 if (Tok.is(tok::numeric_constant)) {
139 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000140 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000141 return;
142
143 PP.Lex(Tok);
144 } else if (Tok.is(tok::identifier)) {
145 Name = Tok.getIdentifierInfo();
146 PP.Lex(Tok);
Mike Stump1eb44332009-09-09 15:08:12 +0000147
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000148 if (Tok.is(tok::comma)) {
149 PP.Lex(Tok);
Mike Stump1eb44332009-09-09 15:08:12 +0000150
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000151 if (Tok.isNot(tok::numeric_constant)) {
Chris Lattner08631c52008-11-23 21:45:46 +0000152 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000153 return;
154 }
Mike Stump1eb44332009-09-09 15:08:12 +0000155
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000156 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000157 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000158 return;
159
160 PP.Lex(Tok);
161 }
162 } else {
Chris Lattner08631c52008-11-23 21:45:46 +0000163 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000164 return;
165 }
166 }
167 }
Eli Friedman19bda3a2011-11-02 01:53:16 +0000168 } else if (PP.getLangOptions().ApplePragmaPack) {
169 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
170 // the push/pop stack.
171 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
172 Kind = Sema::PPK_Pop;
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000173 }
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000174
175 if (Tok.isNot(tok::r_paren)) {
Ted Kremenek4726d032009-03-23 22:28:25 +0000176 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000177 return;
178 }
179
Daniel Dunbar861800c2010-05-26 23:29:06 +0000180 SourceLocation RParenLoc = Tok.getLocation();
Eli Friedman99914792009-06-05 00:49:58 +0000181 PP.Lex(Tok);
Peter Collingbourne84021552011-02-28 02:37:51 +0000182 if (Tok.isNot(tok::eod)) {
Eli Friedman99914792009-06-05 00:49:58 +0000183 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
184 return;
185 }
186
Sebastian Redleffa8d12008-12-10 00:02:53 +0000187 Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000188 LParenLoc, RParenLoc);
189}
190
Fariborz Jahanian62c92582011-04-25 18:49:15 +0000191// #pragma ms_struct on
192// #pragma ms_struct off
193void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
194 PragmaIntroducerKind Introducer,
195 Token &MSStructTok) {
196 Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
197
198 Token Tok;
199 PP.Lex(Tok);
200 if (Tok.isNot(tok::identifier)) {
201 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
202 return;
203 }
204 const IdentifierInfo *II = Tok.getIdentifierInfo();
205 if (II->isStr("on")) {
206 Kind = Sema::PMSST_ON;
207 PP.Lex(Tok);
208 }
209 else if (II->isStr("off") || II->isStr("reset"))
210 PP.Lex(Tok);
211 else {
212 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
213 return;
214 }
215
216 if (Tok.isNot(tok::eod)) {
217 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "ms_struct";
218 return;
219 }
220 Actions.ActOnPragmaMSStruct(Kind);
221}
222
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000223// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
224// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
John McCallf312b1e2010-08-26 23:41:50 +0000225static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000226 bool IsOptions) {
Daniel Dunbar861800c2010-05-26 23:29:06 +0000227 Token Tok;
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000228
229 if (IsOptions) {
230 PP.Lex(Tok);
231 if (Tok.isNot(tok::identifier) ||
232 !Tok.getIdentifierInfo()->isStr("align")) {
233 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
234 return;
235 }
Daniel Dunbar861800c2010-05-26 23:29:06 +0000236 }
Daniel Dunbar638e7cf2010-05-27 18:42:09 +0000237
Daniel Dunbar861800c2010-05-26 23:29:06 +0000238 PP.Lex(Tok);
239 if (Tok.isNot(tok::equal)) {
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000240 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
241 << IsOptions;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000242 return;
243 }
244
245 PP.Lex(Tok);
246 if (Tok.isNot(tok::identifier)) {
247 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000248 << (IsOptions ? "options" : "align");
Daniel Dunbar861800c2010-05-26 23:29:06 +0000249 return;
250 }
251
John McCallf312b1e2010-08-26 23:41:50 +0000252 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000253 const IdentifierInfo *II = Tok.getIdentifierInfo();
Daniel Dunbar638e7cf2010-05-27 18:42:09 +0000254 if (II->isStr("native"))
John McCallf312b1e2010-08-26 23:41:50 +0000255 Kind = Sema::POAK_Native;
Daniel Dunbar638e7cf2010-05-27 18:42:09 +0000256 else if (II->isStr("natural"))
John McCallf312b1e2010-08-26 23:41:50 +0000257 Kind = Sema::POAK_Natural;
Daniel Dunbar6f739142010-05-27 18:42:17 +0000258 else if (II->isStr("packed"))
John McCallf312b1e2010-08-26 23:41:50 +0000259 Kind = Sema::POAK_Packed;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000260 else if (II->isStr("power"))
John McCallf312b1e2010-08-26 23:41:50 +0000261 Kind = Sema::POAK_Power;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000262 else if (II->isStr("mac68k"))
John McCallf312b1e2010-08-26 23:41:50 +0000263 Kind = Sema::POAK_Mac68k;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000264 else if (II->isStr("reset"))
John McCallf312b1e2010-08-26 23:41:50 +0000265 Kind = Sema::POAK_Reset;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000266 else {
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000267 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
268 << IsOptions;
Daniel Dunbar861800c2010-05-26 23:29:06 +0000269 return;
270 }
271
272 SourceLocation KindLoc = Tok.getLocation();
273 PP.Lex(Tok);
Peter Collingbourne84021552011-02-28 02:37:51 +0000274 if (Tok.isNot(tok::eod)) {
Daniel Dunbar861800c2010-05-26 23:29:06 +0000275 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000276 << (IsOptions ? "options" : "align");
Daniel Dunbar861800c2010-05-26 23:29:06 +0000277 return;
278 }
279
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000280 Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
281}
282
Douglas Gregor80c60f72010-09-09 22:45:38 +0000283void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
284 PragmaIntroducerKind Introducer,
285 Token &AlignTok) {
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000286 ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
287}
288
Douglas Gregor80c60f72010-09-09 22:45:38 +0000289void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
290 PragmaIntroducerKind Introducer,
291 Token &OptionsTok) {
Daniel Dunbarcbb98ed2010-07-31 19:17:07 +0000292 ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
Daniel Dunbar861800c2010-05-26 23:29:06 +0000293}
294
Ted Kremenek4726d032009-03-23 22:28:25 +0000295// #pragma unused(identifier)
Douglas Gregor80c60f72010-09-09 22:45:38 +0000296void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
297 PragmaIntroducerKind Introducer,
298 Token &UnusedTok) {
Ted Kremenek4726d032009-03-23 22:28:25 +0000299 // FIXME: Should we be expanding macros here? My guess is no.
300 SourceLocation UnusedLoc = UnusedTok.getLocation();
Mike Stump1eb44332009-09-09 15:08:12 +0000301
Ted Kremenek4726d032009-03-23 22:28:25 +0000302 // Lex the left '('.
303 Token Tok;
304 PP.Lex(Tok);
305 if (Tok.isNot(tok::l_paren)) {
306 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
307 return;
308 }
Mike Stump1eb44332009-09-09 15:08:12 +0000309
Ted Kremenek4726d032009-03-23 22:28:25 +0000310 // Lex the declaration reference(s).
Chris Lattner5f9e2722011-07-23 10:55:15 +0000311 SmallVector<Token, 5> Identifiers;
Ted Kremenek4726d032009-03-23 22:28:25 +0000312 SourceLocation RParenLoc;
313 bool LexID = true;
Mike Stump1eb44332009-09-09 15:08:12 +0000314
Ted Kremenek4726d032009-03-23 22:28:25 +0000315 while (true) {
316 PP.Lex(Tok);
Mike Stump1eb44332009-09-09 15:08:12 +0000317
Ted Kremenek4726d032009-03-23 22:28:25 +0000318 if (LexID) {
Mike Stump1eb44332009-09-09 15:08:12 +0000319 if (Tok.is(tok::identifier)) {
Ted Kremenek7a02a372009-08-03 23:24:57 +0000320 Identifiers.push_back(Tok);
Ted Kremenek4726d032009-03-23 22:28:25 +0000321 LexID = false;
322 continue;
323 }
324
Ted Kremenek7a02a372009-08-03 23:24:57 +0000325 // Illegal token!
Ted Kremenek4726d032009-03-23 22:28:25 +0000326 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
327 return;
328 }
Mike Stump1eb44332009-09-09 15:08:12 +0000329
Ted Kremenek4726d032009-03-23 22:28:25 +0000330 // We are execting a ')' or a ','.
331 if (Tok.is(tok::comma)) {
332 LexID = true;
333 continue;
334 }
Mike Stump1eb44332009-09-09 15:08:12 +0000335
Ted Kremenek4726d032009-03-23 22:28:25 +0000336 if (Tok.is(tok::r_paren)) {
337 RParenLoc = Tok.getLocation();
338 break;
339 }
Mike Stump1eb44332009-09-09 15:08:12 +0000340
Ted Kremenek7a02a372009-08-03 23:24:57 +0000341 // Illegal token!
Ted Kremenek4726d032009-03-23 22:28:25 +0000342 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
343 return;
344 }
Eli Friedman99914792009-06-05 00:49:58 +0000345
346 PP.Lex(Tok);
Peter Collingbourne84021552011-02-28 02:37:51 +0000347 if (Tok.isNot(tok::eod)) {
Eli Friedman99914792009-06-05 00:49:58 +0000348 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
349 "unused";
350 return;
351 }
352
Ted Kremenek4726d032009-03-23 22:28:25 +0000353 // Verify that we have a location for the right parenthesis.
354 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
Ted Kremenek7a02a372009-08-03 23:24:57 +0000355 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
Ted Kremenek4726d032009-03-23 22:28:25 +0000356
Argyrios Kyrtzidisb918d0f2011-01-17 18:58:44 +0000357 // For each identifier token, insert into the token stream a
358 // annot_pragma_unused token followed by the identifier token.
359 // This allows us to cache a "#pragma unused" that occurs inside an inline
360 // C++ member function.
361
362 Token *Toks = new Token[2*Identifiers.size()];
363 for (unsigned i=0; i != Identifiers.size(); i++) {
364 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
365 pragmaUnusedTok.startToken();
366 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
367 pragmaUnusedTok.setLocation(UnusedLoc);
368 idTok = Identifiers[i];
369 }
370 PP.EnterTokenStream(Toks, 2*Identifiers.size(), /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
Ted Kremenek4726d032009-03-23 22:28:25 +0000371}
Eli Friedman99914792009-06-05 00:49:58 +0000372
373// #pragma weak identifier
374// #pragma weak identifier '=' identifier
Douglas Gregor80c60f72010-09-09 22:45:38 +0000375void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
376 PragmaIntroducerKind Introducer,
377 Token &WeakTok) {
Eli Friedman99914792009-06-05 00:49:58 +0000378 // FIXME: Should we be expanding macros here? My guess is no.
379 SourceLocation WeakLoc = WeakTok.getLocation();
380
381 Token Tok;
382 PP.Lex(Tok);
383 if (Tok.isNot(tok::identifier)) {
384 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
385 return;
386 }
387
388 IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
389 SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
390
391 PP.Lex(Tok);
392 if (Tok.is(tok::equal)) {
393 PP.Lex(Tok);
394 if (Tok.isNot(tok::identifier)) {
Mike Stump1eb44332009-09-09 15:08:12 +0000395 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
Eli Friedman99914792009-06-05 00:49:58 +0000396 << "weak";
397 return;
398 }
399 AliasName = Tok.getIdentifierInfo();
400 AliasNameLoc = Tok.getLocation();
401 PP.Lex(Tok);
402 }
403
Peter Collingbourne84021552011-02-28 02:37:51 +0000404 if (Tok.isNot(tok::eod)) {
Eli Friedman99914792009-06-05 00:49:58 +0000405 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
406 return;
407 }
408
409 if (AliasName) {
410 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
411 AliasNameLoc);
412 } else {
413 Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
414 }
415}
Peter Collingbourne321b8172011-02-14 01:42:35 +0000416
417void
418PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
419 PragmaIntroducerKind Introducer,
420 Token &Tok) {
421 tok::OnOffSwitch OOS;
422 if (PP.LexOnOffSwitch(OOS))
423 return;
424
425 Actions.ActOnPragmaFPContract(OOS);
426}
Peter Collingbournef315fa82011-02-14 01:42:53 +0000427
428void
429PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
430 PragmaIntroducerKind Introducer,
431 Token &Tok) {
Tanya Lattnerb38b6a72011-04-14 23:35:31 +0000432 PP.LexUnexpandedToken(Tok);
Peter Collingbournef315fa82011-02-14 01:42:53 +0000433 if (Tok.isNot(tok::identifier)) {
434 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
435 "OPENCL";
436 return;
437 }
438 IdentifierInfo *ename = Tok.getIdentifierInfo();
439 SourceLocation NameLoc = Tok.getLocation();
440
441 PP.Lex(Tok);
442 if (Tok.isNot(tok::colon)) {
443 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
444 return;
445 }
446
447 PP.Lex(Tok);
448 if (Tok.isNot(tok::identifier)) {
449 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
450 return;
451 }
452 IdentifierInfo *op = Tok.getIdentifierInfo();
453
454 unsigned state;
455 if (op->isStr("enable")) {
456 state = 1;
457 } else if (op->isStr("disable")) {
458 state = 0;
459 } else {
460 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
461 return;
462 }
463
464 OpenCLOptions &f = Actions.getOpenCLOptions();
Peter Collingbourne41c8d6f2011-10-06 03:00:50 +0000465 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
466 // overriding all previously issued extension directives, but only if the
467 // behavior is set to disable."
468 if (state == 0 && ename->isStr("all")) {
469#define OPENCLEXT(nm) f.nm = 0;
Peter Collingbournef315fa82011-02-14 01:42:53 +0000470#include "clang/Basic/OpenCLExtensions.def"
471 }
472#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
473#include "clang/Basic/OpenCLExtensions.def"
474 else {
475 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
476 return;
477 }
478}
479