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"
164726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek#include "clang/Parse/Parser.h"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Lex/Preprocessor.h"
18fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbarusing namespace clang;
19fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
20b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis/// \brief Handle the annotation token produced for #pragma unused(...)
21b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis///
22b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis/// Each annot_pragma_unused is followed by the argument token so e.g.
23b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis/// "#pragma unused(x,y)" becomes:
24b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis/// annot_pragma_unused 'x' annot_pragma_unused 'y'
25b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisvoid Parser::HandlePragmaUnused() {
26b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  assert(Tok.is(tok::annot_pragma_unused));
27b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  SourceLocation UnusedLoc = ConsumeToken();
28b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
29b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  ConsumeToken(); // The argument token.
30b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis}
31aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
32426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindolavoid Parser::HandlePragmaVisibility() {
33426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  assert(Tok.is(tok::annot_pragma_vis));
34426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  const IdentifierInfo *VisType =
35426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola    static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
36426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  SourceLocation VisLoc = ConsumeToken();
37426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Actions.ActOnPragmaVisibility(VisType, VisLoc);
38426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola}
39426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola
40aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedmanstruct PragmaPackInfo {
41aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Sema::PragmaPackKind Kind;
42aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  IdentifierInfo *Name;
43aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Expr *Alignment;
44aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  SourceLocation LParenLoc;
45aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  SourceLocation RParenLoc;
46aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman};
47aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
48aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedmanvoid Parser::HandlePragmaPack() {
49aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  assert(Tok.is(tok::annot_pragma_pack));
50aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  PragmaPackInfo *Info =
51aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman    static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
52aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  SourceLocation PragmaLoc = ConsumeToken();
53aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Actions.ActOnPragmaPack(Info->Kind, Info->Name, Info->Alignment, PragmaLoc,
54aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman                          Info->LParenLoc, Info->RParenLoc);
55aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman}
56aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
57aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman// #pragma GCC visibility comes in two variants:
58aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman//   'push' '(' [visibility] ')'
59aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman//   'pop'
6080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
6180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                              PragmaIntroducerKind Introducer,
6280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                              Token &VisTok) {
63aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  SourceLocation VisLoc = VisTok.getLocation();
64aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
65aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  Token Tok;
66e23af2a86ed22c2a11d820820b78353b095e7ae7Joerg Sonnenberger  PP.LexUnexpandedToken(Tok);
67aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
68aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
69aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
70aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  const IdentifierInfo *VisType;
71aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  if (PushPop && PushPop->isStr("pop")) {
72aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    VisType = 0;
73aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  } else if (PushPop && PushPop->isStr("push")) {
74e23af2a86ed22c2a11d820820b78353b095e7ae7Joerg Sonnenberger    PP.LexUnexpandedToken(Tok);
75aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (Tok.isNot(tok::l_paren)) {
76aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
77aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
78aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
79aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
80e23af2a86ed22c2a11d820820b78353b095e7ae7Joerg Sonnenberger    PP.LexUnexpandedToken(Tok);
81aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    VisType = Tok.getIdentifierInfo();
82aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (!VisType) {
83aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
84aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
85aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
86aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
87e23af2a86ed22c2a11d820820b78353b095e7ae7Joerg Sonnenberger    PP.LexUnexpandedToken(Tok);
88aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    if (Tok.isNot(tok::r_paren)) {
89aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
90aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman        << "visibility";
91aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      return;
92aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    }
93aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  } else {
94aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
95aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      << "visibility";
96aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    return;
97aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  }
98e23af2a86ed22c2a11d820820b78353b095e7ae7Joerg Sonnenberger  PP.LexUnexpandedToken(Tok);
9984021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
100aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
101aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman      << "visibility";
102aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman    return;
103aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman  }
104aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
105426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Token *Toks = new Token[1];
106426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Toks[0].startToken();
107426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Toks[0].setKind(tok::annot_pragma_vis);
108426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Toks[0].setLocation(VisLoc);
109426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  Toks[0].setAnnotationValue(
110426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola                          const_cast<void*>(static_cast<const void*>(VisType)));
111426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola  PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
112426fc94ed3bce15b55c43692537e3833388f0352Rafael Espindola                      /*OwnsTokens=*/true);
113aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman}
114aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman
115fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar// #pragma pack(...) comes in the following delicious flavors:
116fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' [integer] ')'
117fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' 'show' ')'
118fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar//   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
11980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaPackHandler::HandlePragma(Preprocessor &PP,
12080c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                     PragmaIntroducerKind Introducer,
12180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                     Token &PackTok) {
122fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  SourceLocation PackLoc = PackTok.getLocation();
123fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
124fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  Token Tok;
125fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  PP.Lex(Tok);
126fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.isNot(tok::l_paren)) {
1274726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
128fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    return;
129fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  }
130fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
131f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::PragmaPackKind Kind = Sema::PPK_Default;
132fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  IdentifierInfo *Name = 0;
13360d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Alignment;
134fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  SourceLocation LParenLoc = Tok.getLocation();
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PP.Lex(Tok);
136fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.is(tok::numeric_constant)) {
137fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    Alignment = Actions.ActOnNumericConstant(Tok);
1380e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl    if (Alignment.isInvalid())
139fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      return;
140fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
141fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    PP.Lex(Tok);
14219bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman
14319bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
14419bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // the push/pop stack.
14519bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (PP.getLangOpts().ApplePragmaPack)
14719bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman      Kind = Sema::PPK_Push;
148fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  } else if (Tok.is(tok::identifier)) {
149fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    const IdentifierInfo *II = Tok.getIdentifierInfo();
15008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    if (II->isStr("show")) {
151f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      Kind = Sema::PPK_Show;
152fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      PP.Lex(Tok);
153fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    } else {
15408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      if (II->isStr("push")) {
155f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        Kind = Sema::PPK_Push;
15608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      } else if (II->isStr("pop")) {
157f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        Kind = Sema::PPK_Pop;
158fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      } else {
159fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
160fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        return;
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
162fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      PP.Lex(Tok);
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
164fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      if (Tok.is(tok::comma)) {
165fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        PP.Lex(Tok);
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
167fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        if (Tok.is(tok::numeric_constant)) {
168fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          Alignment = Actions.ActOnNumericConstant(Tok);
1690e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl          if (Alignment.isInvalid())
170fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            return;
171fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
172fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          PP.Lex(Tok);
173fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        } else if (Tok.is(tok::identifier)) {
174fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          Name = Tok.getIdentifierInfo();
175fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          PP.Lex(Tok);
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
177fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          if (Tok.is(tok::comma)) {
178fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            PP.Lex(Tok);
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
180fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            if (Tok.isNot(tok::numeric_constant)) {
18108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner              PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
182fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar              return;
183fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            }
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            Alignment = Actions.ActOnNumericConstant(Tok);
1860e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl            if (Alignment.isInvalid())
187fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar              return;
188fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
189fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar            PP.Lex(Tok);
190fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          }
191fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        } else {
19208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner          PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
193fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar          return;
194fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar        }
195fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar      }
196fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    }
1974e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  } else if (PP.getLangOpts().ApplePragmaPack) {
19819bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // In MSVC/gcc, #pragma pack() resets the alignment without affecting
19919bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // the push/pop stack.
20019bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
20119bda3ad8b5d37e505214e82fab1d0a0bf00f0fdEli Friedman    Kind = Sema::PPK_Pop;
2020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl  }
203fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
204fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  if (Tok.isNot(tok::r_paren)) {
2054726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
206fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar    return;
207fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar  }
208fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
209861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  SourceLocation RParenLoc = Tok.getLocation();
2109991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
21184021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
2129991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
2139991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
2149991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
2159991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
216b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  PragmaPackInfo *Info =
217b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar    (PragmaPackInfo*) PP.getPreprocessorAllocator().Allocate(
218b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar      sizeof(PragmaPackInfo), llvm::alignOf<PragmaPackInfo>());
219b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  new (Info) PragmaPackInfo();
220aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Info->Kind = Kind;
221aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Info->Name = Name;
222aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Info->Alignment = Alignment.release();
223aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Info->LParenLoc = LParenLoc;
224aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Info->RParenLoc = RParenLoc;
225aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
226b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  Token *Toks =
227b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar    (Token*) PP.getPreprocessorAllocator().Allocate(
228b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar      sizeof(Token) * 1, llvm::alignOf<Token>());
229b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  new (Toks) Token();
230aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Toks[0].startToken();
231aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Toks[0].setKind(tok::annot_pragma_pack);
232aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Toks[0].setLocation(PackLoc);
233aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  Toks[0].setAnnotationValue(static_cast<void*>(Info));
234aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman  PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
235b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar                      /*OwnsTokens=*/false);
236fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar}
237fcdd8fe26de3eee44927600bf1853e21bd90dd84Daniel Dunbar
23862c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian// #pragma ms_struct on
23962c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian// #pragma ms_struct off
24062c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanianvoid PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
24162c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian                                         PragmaIntroducerKind Introducer,
24262c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian                                         Token &MSStructTok) {
24362c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
24462c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian
24562c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  Token Tok;
24662c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  PP.Lex(Tok);
24762c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  if (Tok.isNot(tok::identifier)) {
24862c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
24962c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    return;
25062c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  }
25162c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  const IdentifierInfo *II = Tok.getIdentifierInfo();
25262c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  if (II->isStr("on")) {
25362c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    Kind = Sema::PMSST_ON;
25462c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    PP.Lex(Tok);
25562c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  }
25662c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  else if (II->isStr("off") || II->isStr("reset"))
25762c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    PP.Lex(Tok);
25862c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  else {
25962c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
26062c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    return;
26162c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  }
26262c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian
26362c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  if (Tok.isNot(tok::eod)) {
264b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
265b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar      << "ms_struct";
26662c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian    return;
26762c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  }
26862c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian  Actions.ActOnPragmaMSStruct(Kind);
26962c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian}
27062c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian
271cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
272cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
273f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallstatic void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
274cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar                             bool IsOptions) {
275861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  Token Tok;
276cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
277cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  if (IsOptions) {
278cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Lex(Tok);
279cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    if (Tok.isNot(tok::identifier) ||
280cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar        !Tok.getIdentifierInfo()->isStr("align")) {
281cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
282cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      return;
283cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    }
284861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
285638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar
286861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
287861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  if (Tok.isNot(tok::equal)) {
288cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
289cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << IsOptions;
290861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
291861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
292861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
293861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
294861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  if (Tok.isNot(tok::identifier)) {
295861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
296cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << (IsOptions ? "options" : "align");
297861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
298861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
299861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
300f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
301861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  const IdentifierInfo *II = Tok.getIdentifierInfo();
302638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar  if (II->isStr("native"))
303f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Native;
304638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar  else if (II->isStr("natural"))
305f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Natural;
3066f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar  else if (II->isStr("packed"))
307f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Packed;
308861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("power"))
309f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Power;
310861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("mac68k"))
311f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Mac68k;
312861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else if (II->isStr("reset"))
313f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    Kind = Sema::POAK_Reset;
314861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  else {
315cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
316cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << IsOptions;
317861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
318861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
319861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
320861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  SourceLocation KindLoc = Tok.getLocation();
321861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  PP.Lex(Tok);
32284021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
323861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
324cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar      << (IsOptions ? "options" : "align");
325861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar    return;
326861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar  }
327861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
328cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
329cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar}
330cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
33180c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaAlignHandler::HandlePragma(Preprocessor &PP,
33280c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      PragmaIntroducerKind Introducer,
33380c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                      Token &AlignTok) {
334cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
335cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar}
336cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar
33780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
33880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                        PragmaIntroducerKind Introducer,
33980c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                        Token &OptionsTok) {
340cbb98edd530787c2ac019e437e7c599df8004ba7Daniel Dunbar  ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
341861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar}
342861800c676004eabed5927f0552620d06c80a40aDaniel Dunbar
3434726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek// #pragma unused(identifier)
34480c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
34580c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                       PragmaIntroducerKind Introducer,
34680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                       Token &UnusedTok) {
3474726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // FIXME: Should we be expanding macros here? My guess is no.
3484726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  SourceLocation UnusedLoc = UnusedTok.getLocation();
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3504726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Lex the left '('.
3514726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  Token Tok;
3524726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  PP.Lex(Tok);
3534726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  if (Tok.isNot(tok::l_paren)) {
3544726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
3554726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    return;
3564726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  }
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3584726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Lex the declaration reference(s).
3595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Token, 5> Identifiers;
3604726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  SourceLocation RParenLoc;
3614726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  bool LexID = true;
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3634726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  while (true) {
3644726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Lex(Tok);
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3664726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (LexID) {
3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (Tok.is(tok::identifier)) {
3687a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek        Identifiers.push_back(Tok);
3694726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek        LexID = false;
3704726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek        continue;
3714726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      }
3724726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek
3737a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek      // Illegal token!
3744726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
3754726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      return;
3764726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3784726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    // We are execting a ')' or a ','.
3794726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (Tok.is(tok::comma)) {
3804726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      LexID = true;
3814726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      continue;
3824726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3844726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    if (Tok.is(tok::r_paren)) {
3854726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      RParenLoc = Tok.getLocation();
3864726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek      break;
3874726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    }
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3897a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek    // Illegal token!
3904726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
3914726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek    return;
3924726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  }
3939991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
3949991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
39584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
3969991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
3979991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman        "unused";
3989991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
3999991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
4009991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4014726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  // Verify that we have a location for the right parenthesis.
4024726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek  assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
4037a02a3733cdd2ca672902d869fda4ef2e3f05052Ted Kremenek  assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
4044726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek
405b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  // For each identifier token, insert into the token stream a
406b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  // annot_pragma_unused token followed by the identifier token.
407b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  // This allows us to cache a "#pragma unused" that occurs inside an inline
408b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  // C++ member function.
409b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis
410b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  Token *Toks =
411b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar    (Token*) PP.getPreprocessorAllocator().Allocate(
412b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar      sizeof(Token) * 2 * Identifiers.size(), llvm::alignOf<Token>());
413b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  for (unsigned i=0; i != Identifiers.size(); i++) {
414b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
415b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    pragmaUnusedTok.startToken();
416b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    pragmaUnusedTok.setKind(tok::annot_pragma_unused);
417b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    pragmaUnusedTok.setLocation(UnusedLoc);
418b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis    idTok = Identifiers[i];
419b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis  }
420b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar  PP.EnterTokenStream(Toks, 2*Identifiers.size(),
421b09395569d7d4d56d5c1f9b5c38ba7ac63cf7545Daniel Dunbar                      /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
4224726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek}
4239991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4249991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman// #pragma weak identifier
4259991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman// #pragma weak identifier '=' identifier
42680c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregorvoid PragmaWeakHandler::HandlePragma(Preprocessor &PP,
42780c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                     PragmaIntroducerKind Introducer,
42880c60f72848896f867f6b7e664e7060d9e78f019Douglas Gregor                                     Token &WeakTok) {
4299991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  // FIXME: Should we be expanding macros here? My guess is no.
4309991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  SourceLocation WeakLoc = WeakTok.getLocation();
4319991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4329991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  Token Tok;
4339991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
4349991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.isNot(tok::identifier)) {
4359991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
4369991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
4379991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
4389991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4399991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
4409991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
4419991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4429991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  PP.Lex(Tok);
4439991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (Tok.is(tok::equal)) {
4449991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Lex(Tok);
4459991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    if (Tok.isNot(tok::identifier)) {
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
4479991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman          << "weak";
4489991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman      return;
4499991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    }
4509991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    AliasName = Tok.getIdentifierInfo();
4519991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    AliasNameLoc = Tok.getLocation();
4529991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Lex(Tok);
4539991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
4549991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
45584021556baceb76eedf7d44be8ba71d9b8cfaccePeter Collingbourne  if (Tok.isNot(tok::eod)) {
4569991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
4579991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    return;
4589991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
4599991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman
4609991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  if (AliasName) {
4619991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
4629991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman                                 AliasNameLoc);
4639991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  } else {
4649991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman    Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
4659991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman  }
4669991479ad5dde617168cc1e4b18425cdbbfd9fa9Eli Friedman}
467321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne
4685f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall// #pragma redefine_extname identifier identifier
4695f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnallvoid PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
4705f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall                                               PragmaIntroducerKind Introducer,
4715f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall                                                Token &RedefToken) {
4725f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  SourceLocation RedefLoc = RedefToken.getLocation();
4735f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
4745f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  Token Tok;
4755f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  PP.Lex(Tok);
4765f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  if (Tok.isNot(tok::identifier)) {
4775f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
4785f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall      "redefine_extname";
4795f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    return;
4805f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  }
4815f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
4825f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  IdentifierInfo *RedefName = Tok.getIdentifierInfo(), *AliasName = 0;
4835f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  SourceLocation RedefNameLoc = Tok.getLocation(), AliasNameLoc;
4845f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
4855f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  PP.Lex(Tok);
4865f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  if (Tok.isNot(tok::identifier)) {
4875f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
4885f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall        << "redefine_extname";
4895f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    return;
4905f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  }
4915f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  AliasName = Tok.getIdentifierInfo();
4925f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  AliasNameLoc = Tok.getLocation();
4935f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  PP.Lex(Tok);
4945f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
4955f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  if (Tok.isNot(tok::eod)) {
4965f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
4975f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall      "redefine_extname";
4985f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall    return;
4995f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  }
5005f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
5015f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall  Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
5025f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall      RedefNameLoc, AliasNameLoc);
5035f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall}
5045f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
5055f3c163b7b19a0c7e02509a0984ee1256bca890dDavid Chisnall
506321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbournevoid
507321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter CollingbournePragmaFPContractHandler::HandlePragma(Preprocessor &PP,
508321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne                                      PragmaIntroducerKind Introducer,
509321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne                                      Token &Tok) {
510321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne  tok::OnOffSwitch OOS;
511321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne  if (PP.LexOnOffSwitch(OOS))
512321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne    return;
513321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne
514321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne  Actions.ActOnPragmaFPContract(OOS);
515321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne}
516f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
517f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournevoid
518f315fa81eef1977b3457fd7a7d4639e060fe7278Peter CollingbournePragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
519f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne                                           PragmaIntroducerKind Introducer,
520f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne                                           Token &Tok) {
521b38b6a77ab946ed331f06f6028963d781bac7431Tanya Lattner  PP.LexUnexpandedToken(Tok);
522f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
523f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
524f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne      "OPENCL";
525f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    return;
526f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
527f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  IdentifierInfo *ename = Tok.getIdentifierInfo();
528f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  SourceLocation NameLoc = Tok.getLocation();
529f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
530f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  PP.Lex(Tok);
531f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  if (Tok.isNot(tok::colon)) {
532f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename;
533f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    return;
534f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
535f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
536f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  PP.Lex(Tok);
537f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  if (Tok.isNot(tok::identifier)) {
538f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
539f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    return;
540f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
541f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  IdentifierInfo *op = Tok.getIdentifierInfo();
542f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
543f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  unsigned state;
544f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  if (op->isStr("enable")) {
545f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    state = 1;
546f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  } else if (op->isStr("disable")) {
547f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    state = 0;
548f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  } else {
549f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable);
550f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    return;
551f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
552f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
553f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  OpenCLOptions &f = Actions.getOpenCLOptions();
55441c8d6fe09624ea31f5641dd53b6f0b6368ffcddPeter Collingbourne  // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
55541c8d6fe09624ea31f5641dd53b6f0b6368ffcddPeter Collingbourne  // overriding all previously issued extension directives, but only if the
55641c8d6fe09624ea31f5641dd53b6f0b6368ffcddPeter Collingbourne  // behavior is set to disable."
55741c8d6fe09624ea31f5641dd53b6f0b6368ffcddPeter Collingbourne  if (state == 0 && ename->isStr("all")) {
55841c8d6fe09624ea31f5641dd53b6f0b6368ffcddPeter Collingbourne#define OPENCLEXT(nm)   f.nm = 0;
559f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne#include "clang/Basic/OpenCLExtensions.def"
560f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
561f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
562f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne#include "clang/Basic/OpenCLExtensions.def"
563f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  else {
564f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
565f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne    return;
566f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne  }
567f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne}
568f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne
569