blob: 01496b31f75f4864d7f7f245883284f434c075d8 [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"
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000016#include "clang/Lex/Preprocessor.h"
17#include "clang/Parse/Action.h"
18using namespace clang;
19
20// #pragma pack(...) comes in the following delicious flavors:
21// pack '(' [integer] ')'
22// pack '(' 'show' ')'
23// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
24void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
25 // FIXME: Should we be expanding macros here? My guess is no.
26 SourceLocation PackLoc = PackTok.getLocation();
27
28 Token Tok;
29 PP.Lex(Tok);
30 if (Tok.isNot(tok::l_paren)) {
31 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_lparen);
32 return;
33 }
34
35 Action::PragmaPackKind Kind = Action::PPK_Default;
36 IdentifierInfo *Name = 0;
Sebastian Redl15faa7f2008-12-09 20:22:58 +000037 Action::OwningExprResult Alignment(Actions);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000038 SourceLocation LParenLoc = Tok.getLocation();
39 PP.Lex(Tok);
40 if (Tok.is(tok::numeric_constant)) {
41 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000042 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000043 return;
44
45 PP.Lex(Tok);
46 } else if (Tok.is(tok::identifier)) {
47 const IdentifierInfo *II = Tok.getIdentifierInfo();
Chris Lattner08631c52008-11-23 21:45:46 +000048 if (II->isStr("show")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000049 Kind = Action::PPK_Show;
50 PP.Lex(Tok);
51 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000052 if (II->isStr("push")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000053 Kind = Action::PPK_Push;
Chris Lattner08631c52008-11-23 21:45:46 +000054 } else if (II->isStr("pop")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000055 Kind = Action::PPK_Pop;
56 } else {
57 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
58 return;
59 }
60 PP.Lex(Tok);
61
62 if (Tok.is(tok::comma)) {
63 PP.Lex(Tok);
64
65 if (Tok.is(tok::numeric_constant)) {
66 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000067 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000068 return;
69
70 PP.Lex(Tok);
71 } else if (Tok.is(tok::identifier)) {
72 Name = Tok.getIdentifierInfo();
73 PP.Lex(Tok);
74
75 if (Tok.is(tok::comma)) {
76 PP.Lex(Tok);
77
78 if (Tok.isNot(tok::numeric_constant)) {
Chris Lattner08631c52008-11-23 21:45:46 +000079 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000080 return;
81 }
82
83 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000084 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000085 return;
86
87 PP.Lex(Tok);
88 }
89 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000090 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000091 return;
92 }
93 }
94 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000095 }
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000096
97 if (Tok.isNot(tok::r_paren)) {
98 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
99 return;
100 }
101
102 SourceLocation RParenLoc = Tok.getLocation();
Sebastian Redleffa8d12008-12-10 00:02:53 +0000103 Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000104 LParenLoc, RParenLoc);
105}
106