blob: 17eba03c2604ed331bb88322e50271998e9b6122 [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"
15#include "clang/Basic/Diagnostic.h"
16#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;
37 Action::ExprResult Alignment;
38 SourceLocation LParenLoc = Tok.getLocation();
39 PP.Lex(Tok);
40 if (Tok.is(tok::numeric_constant)) {
41 Alignment = Actions.ActOnNumericConstant(Tok);
42 if (Alignment.isInvalid)
43 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);
67 if (Alignment.isInvalid)
68 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);
84 if (Alignment.isInvalid)
85 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 }
95 }
96
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();
103 Actions.ActOnPragmaPack(Kind, Name, Alignment.Val, PackLoc,
104 LParenLoc, RParenLoc);
105}
106