blob: 3d5e7164dc775f5a49bf067a34b05cd7dfc796be [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"
Sebastian Redla55e52c2008-11-25 22:21:31 +000015#include "AstGuard.h"
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000016#include "clang/Basic/Diagnostic.h"
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Parse/Action.h"
19using namespace clang;
20
21// #pragma pack(...) comes in the following delicious flavors:
22// pack '(' [integer] ')'
23// pack '(' 'show' ')'
24// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
25void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
26 // FIXME: Should we be expanding macros here? My guess is no.
27 SourceLocation PackLoc = PackTok.getLocation();
28
29 Token Tok;
30 PP.Lex(Tok);
31 if (Tok.isNot(tok::l_paren)) {
32 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_lparen);
33 return;
34 }
35
36 Action::PragmaPackKind Kind = Action::PPK_Default;
37 IdentifierInfo *Name = 0;
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000038 ExprOwner Alignment(Actions);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000039 SourceLocation LParenLoc = Tok.getLocation();
40 PP.Lex(Tok);
41 if (Tok.is(tok::numeric_constant)) {
42 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000043 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000044 return;
45
46 PP.Lex(Tok);
47 } else if (Tok.is(tok::identifier)) {
48 const IdentifierInfo *II = Tok.getIdentifierInfo();
Chris Lattner08631c52008-11-23 21:45:46 +000049 if (II->isStr("show")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000050 Kind = Action::PPK_Show;
51 PP.Lex(Tok);
52 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000053 if (II->isStr("push")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000054 Kind = Action::PPK_Push;
Chris Lattner08631c52008-11-23 21:45:46 +000055 } else if (II->isStr("pop")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000056 Kind = Action::PPK_Pop;
57 } else {
58 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
59 return;
60 }
61 PP.Lex(Tok);
62
63 if (Tok.is(tok::comma)) {
64 PP.Lex(Tok);
65
66 if (Tok.is(tok::numeric_constant)) {
67 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000068 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000069 return;
70
71 PP.Lex(Tok);
72 } else if (Tok.is(tok::identifier)) {
73 Name = Tok.getIdentifierInfo();
74 PP.Lex(Tok);
75
76 if (Tok.is(tok::comma)) {
77 PP.Lex(Tok);
78
79 if (Tok.isNot(tok::numeric_constant)) {
Chris Lattner08631c52008-11-23 21:45:46 +000080 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000081 return;
82 }
83
84 Alignment = Actions.ActOnNumericConstant(Tok);
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000085 if (Alignment.isInvalid())
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000086 return;
87
88 PP.Lex(Tok);
89 }
90 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000091 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000092 return;
93 }
94 }
95 }
Sebastian Redl0e9eabc2008-12-09 13:15:23 +000096 }
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000097
98 if (Tok.isNot(tok::r_paren)) {
99 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
100 return;
101 }
102
103 SourceLocation RParenLoc = Tok.getLocation();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000104 Actions.ActOnPragmaPack(Kind, Name, Alignment.move(), PackLoc,
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000105 LParenLoc, RParenLoc);
106}
107