ParsePragma.cpp revision aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0
1fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
2fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
3fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//                     The LLVM Compiler Infrastructure
4fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
5fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// This file is distributed under the University of Illinois Open Source
6fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// License. See LICENSE.TXT for details.
7fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
8fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//===----------------------------------------------------------------------===//
9fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
10fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// This file implements the language specific #pragma handlers.
11fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//
12fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//===----------------------------------------------------------------------===//
13fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
14fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar#include "ParsePragma.h"
15500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
16fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar#include "clang/Lex/Preprocessor.h"
17fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar#include "clang/Parse/Action.h"
184726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek#include "clang/Parse/Parser.h"
19fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbarusing namespace clang;
20fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
21aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
22aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman// #pragma GCC visibility comes in two variants:
23aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman//   'push' '(' [visibility] ')'
24aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman//   'pop'
25aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) {
26aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  SourceLocation VisLoc = VisTok.getLocation();
27aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
28aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  Token Tok;
29aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  PP.Lex(Tok);
30aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
31aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
32aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
33aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  bool IsPush;
34aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  const IdentifierInfo *VisType;
35aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  if (PushPop && PushPop->isStr("pop")) {
36aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    IsPush = false;
37aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    VisType = 0;
38aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  } else if (PushPop && PushPop->isStr("push")) {
39aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    IsPush = true;
40aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Lex(Tok);
41aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (Tok.isNot(tok::l_paren)) {
42aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
43aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
44aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
45aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
46aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Lex(Tok);
47aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    VisType = Tok.getIdentifierInfo();
48aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (!VisType) {
49aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
50aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
51aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
52aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
53aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Lex(Tok);
54aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (Tok.isNot(tok::r_paren)) {
55aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
56aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
57aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
58aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
59aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  } else {
60aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
61aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      << "visibility";
62aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    return;
63aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  }
64aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  PP.Lex(Tok);
65aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  if (Tok.isNot(tok::eom)) {
66aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
67aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      << "visibility";
68aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    return;
69aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  }
70aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
71aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc);
72aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman}
73aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
74fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// #pragma pack(...) comes in the following delicious flavors:
75fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' [integer] ')'
76fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' 'show' ')'
77fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
78fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbarvoid PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
79fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  SourceLocation PackLoc = PackTok.getLocation();
80fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
81fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  Token Tok;
82fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  PP.Lex(Tok);
83fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.isNot(tok::l_paren)) {
844726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
85fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    return;
86fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  }
87fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
88fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  Action::PragmaPackKind Kind = Action::PPK_Default;
89fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  IdentifierInfo *Name = 0;
9015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  Action::OwningExprResult Alignment(Actions);
91fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  SourceLocation LParenLoc = Tok.getLocation();
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PP.Lex(Tok);
93fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.is(tok::numeric_constant)) {
94fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    Alignment = Actions.ActOnNumericConstant(Tok);
950e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Alignment.isInvalid())
96fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      return;
97fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
98fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    PP.Lex(Tok);
99fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  } else if (Tok.is(tok::identifier)) {
100fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    const IdentifierInfo *II = Tok.getIdentifierInfo();
10108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    if (II->isStr("show")) {
102fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      Kind = Action::PPK_Show;
103fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      PP.Lex(Tok);
104fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    } else {
10508631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      if (II->isStr("push")) {
106fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        Kind = Action::PPK_Push;
10708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      } else if (II->isStr("pop")) {
108fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        Kind = Action::PPK_Pop;
109fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      } else {
110fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
111fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        return;
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
113fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      PP.Lex(Tok);
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
115fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      if (Tok.is(tok::comma)) {
116fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        PP.Lex(Tok);
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        if (Tok.is(tok::numeric_constant)) {
119fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          Alignment = Actions.ActOnNumericConstant(Tok);
1200e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl          if (Alignment.isInvalid())
121fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            return;
122fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
123fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          PP.Lex(Tok);
124fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        } else if (Tok.is(tok::identifier)) {
125fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          Name = Tok.getIdentifierInfo();
126fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          PP.Lex(Tok);
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
128fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          if (Tok.is(tok::comma)) {
129fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            PP.Lex(Tok);
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
131fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            if (Tok.isNot(tok::numeric_constant)) {
13208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner              PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
133fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar              return;
134fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            }
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            Alignment = Actions.ActOnNumericConstant(Tok);
1370e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl            if (Alignment.isInvalid())
138fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar              return;
139fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
140fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            PP.Lex(Tok);
141fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          }
142fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        } else {
14308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner          PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
144fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          return;
145fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        }
146fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      }
147fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    }
1480e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  }
149fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
150fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.isNot(tok::r_paren)) {
1514726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
152fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    return;
153fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  }
154fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
155861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  SourceLocation RParenLoc = Tok.getLocation();
1569991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
1579991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.isNot(tok::eom)) {
1589991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1599991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
1609991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
1619991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
162effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl  Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
163fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar                          LParenLoc, RParenLoc);
164fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar}
165fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
166cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
167cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
168cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbarstatic void ParseAlignPragma(Action &Actions, Preprocessor &PP, Token &FirstTok,
169cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar                             bool IsOptions) {
170861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  Token Tok;
171cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
172cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  if (IsOptions) {
173cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Lex(Tok);
174cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    if (Tok.isNot(tok::identifier) ||
175cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar        !Tok.getIdentifierInfo()->isStr("align")) {
176cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
177cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      return;
178cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    }
179861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
180638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar
181861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
182861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  if (Tok.isNot(tok::equal)) {
183cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
184cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << IsOptions;
185861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
186861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
187861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
188861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
189861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  if (Tok.isNot(tok::identifier)) {
190861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
191cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << (IsOptions ? "options" : "align");
192861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
193861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
194861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
195861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  Action::PragmaOptionsAlignKind Kind = Action::POAK_Natural;
196861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  const IdentifierInfo *II = Tok.getIdentifierInfo();
197638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar  if (II->isStr("native"))
198638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar    Kind = Action::POAK_Native;
199638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar  else if (II->isStr("natural"))
200861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    Kind = Action::POAK_Natural;
2016f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar  else if (II->isStr("packed"))
2026f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar    Kind = Action::POAK_Packed;
203861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("power"))
204861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    Kind = Action::POAK_Power;
205861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("mac68k"))
206861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    Kind = Action::POAK_Mac68k;
207861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("reset"))
208861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    Kind = Action::POAK_Reset;
209861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else {
210cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
211cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << IsOptions;
212861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
213861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
214861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
215861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  SourceLocation KindLoc = Tok.getLocation();
216861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
217861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  if (Tok.isNot(tok::eom)) {
218861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
219cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << (IsOptions ? "options" : "align");
220861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
221861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
222861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
223cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
224cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar}
225cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
226cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbarvoid PragmaAlignHandler::HandlePragma(Preprocessor &PP, Token &AlignTok) {
227cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
228cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar}
229cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
230cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbarvoid PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) {
231cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
232861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar}
233861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
2344726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek// #pragma unused(identifier)
2354726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenekvoid PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) {
2364726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // FIXME: Should we be expanding macros here? My guess is no.
2374726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  SourceLocation UnusedLoc = UnusedTok.getLocation();
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2394726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Lex the left '('.
2404726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  Token Tok;
2414726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  PP.Lex(Tok);
2424726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  if (Tok.isNot(tok::l_paren)) {
2434726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
2444726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    return;
2454726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  }
2464726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  SourceLocation LParenLoc = Tok.getLocation();
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2484726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Lex the declaration reference(s).
2497a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek  llvm::SmallVector<Token, 5> Identifiers;
2504726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  SourceLocation RParenLoc;
2514726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  bool LexID = true;
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2534726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  while (true) {
2544726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Lex(Tok);
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2564726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (LexID) {
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (Tok.is(tok::identifier)) {
2587a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek        Identifiers.push_back(Tok);
2594726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek        LexID = false;
2604726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek        continue;
2614726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      }
2624726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek
2637a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek      // Illegal token!
2644726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
2654726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      return;
2664726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
2671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2684726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    // We are execting a ')' or a ','.
2694726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (Tok.is(tok::comma)) {
2704726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      LexID = true;
2714726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      continue;
2724726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2744726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (Tok.is(tok::r_paren)) {
2754726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      RParenLoc = Tok.getLocation();
2764726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      break;
2774726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2797a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek    // Illegal token!
2804726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
2814726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    return;
2824726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  }
2839991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
2849991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
2859991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.isNot(tok::eom)) {
2869991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2879991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman        "unused";
2889991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
2899991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
2909991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
2914726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Verify that we have a location for the right parenthesis.
2924726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
2937a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
2944726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Perform the action to handle the pragma.
2967a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek  Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
29723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor                            parser.getCurScope(), UnusedLoc, LParenLoc, RParenLoc);
2984726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek}
2999991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3009991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman// #pragma weak identifier
3019991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman// #pragma weak identifier '=' identifier
3029991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedmanvoid PragmaWeakHandler::HandlePragma(Preprocessor &PP, Token &WeakTok) {
3039991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  // FIXME: Should we be expanding macros here? My guess is no.
3049991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  SourceLocation WeakLoc = WeakTok.getLocation();
3059991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3069991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  Token Tok;
3079991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
3089991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.isNot(tok::identifier)) {
3099991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
3109991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
3119991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
3129991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3139991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
3149991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
3159991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3169991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
3179991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.is(tok::equal)) {
3189991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Lex(Tok);
3199991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    if (Tok.isNot(tok::identifier)) {
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
3219991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman          << "weak";
3229991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman      return;
3239991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    }
3249991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    AliasName = Tok.getIdentifierInfo();
3259991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    AliasNameLoc = Tok.getLocation();
3269991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Lex(Tok);
3279991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
3289991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3299991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.isNot(tok::eom)) {
3309991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
3319991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
3329991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
3339991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3349991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (AliasName) {
3359991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
3369991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman                                 AliasNameLoc);
3379991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  } else {
3389991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
3399991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
3409991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman}
341