blob: a6e2328d177e0c5eff86cafd4e1f0771fa707e60 [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;
38 Action::ExprResult Alignment;
Sebastian Redla55e52c2008-11-25 22:21:31 +000039 ExprGuard AlignmentGuard(Actions);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000040 SourceLocation LParenLoc = Tok.getLocation();
41 PP.Lex(Tok);
42 if (Tok.is(tok::numeric_constant)) {
43 Alignment = Actions.ActOnNumericConstant(Tok);
44 if (Alignment.isInvalid)
45 return;
Sebastian Redla55e52c2008-11-25 22:21:31 +000046 AlignmentGuard.reset(Alignment);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000047
48 PP.Lex(Tok);
49 } else if (Tok.is(tok::identifier)) {
50 const IdentifierInfo *II = Tok.getIdentifierInfo();
Chris Lattner08631c52008-11-23 21:45:46 +000051 if (II->isStr("show")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000052 Kind = Action::PPK_Show;
53 PP.Lex(Tok);
54 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000055 if (II->isStr("push")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000056 Kind = Action::PPK_Push;
Chris Lattner08631c52008-11-23 21:45:46 +000057 } else if (II->isStr("pop")) {
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000058 Kind = Action::PPK_Pop;
59 } else {
60 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
61 return;
62 }
63 PP.Lex(Tok);
64
65 if (Tok.is(tok::comma)) {
66 PP.Lex(Tok);
67
68 if (Tok.is(tok::numeric_constant)) {
69 Alignment = Actions.ActOnNumericConstant(Tok);
70 if (Alignment.isInvalid)
71 return;
Sebastian Redla55e52c2008-11-25 22:21:31 +000072 AlignmentGuard.reset(Alignment);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000073
74 PP.Lex(Tok);
75 } else if (Tok.is(tok::identifier)) {
76 Name = Tok.getIdentifierInfo();
77 PP.Lex(Tok);
78
79 if (Tok.is(tok::comma)) {
80 PP.Lex(Tok);
81
82 if (Tok.isNot(tok::numeric_constant)) {
Chris Lattner08631c52008-11-23 21:45:46 +000083 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000084 return;
85 }
86
87 Alignment = Actions.ActOnNumericConstant(Tok);
88 if (Alignment.isInvalid)
89 return;
Sebastian Redla55e52c2008-11-25 22:21:31 +000090 AlignmentGuard.reset(Alignment);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000091
92 PP.Lex(Tok);
93 }
94 } else {
Chris Lattner08631c52008-11-23 21:45:46 +000095 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +000096 return;
97 }
98 }
99 }
100 }
101
102 if (Tok.isNot(tok::r_paren)) {
103 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
104 return;
105 }
106
107 SourceLocation RParenLoc = Tok.getLocation();
Sebastian Redla55e52c2008-11-25 22:21:31 +0000108 Actions.ActOnPragmaPack(Kind, Name, AlignmentGuard.take(), PackLoc,
Daniel Dunbarfcdd8fe2008-10-04 19:21:03 +0000109 LParenLoc, RParenLoc);
110}
111