blob: fbdb123bdabe1eecedc3efe6d482a637ad623b3c [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();
48 if (II == &PP.getIdentifierTable().get("show")) {
49 Kind = Action::PPK_Show;
50 PP.Lex(Tok);
51 } else {
52 if (II == &PP.getIdentifierTable().get("push")) {
53 Kind = Action::PPK_Push;
54 } else if (II == &PP.getIdentifierTable().get("pop")) {
55 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)) {
79 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed,
80 II->getName());
81 return;
82 }
83
84 Alignment = Actions.ActOnNumericConstant(Tok);
85 if (Alignment.isInvalid)
86 return;
87
88 PP.Lex(Tok);
89 }
90 } else {
91 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed,
92 II->getName());
93 return;
94 }
95 }
96 }
97 }
98
99 if (Tok.isNot(tok::r_paren)) {
100 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
101 return;
102 }
103
104 SourceLocation RParenLoc = Tok.getLocation();
105 Actions.ActOnPragmaPack(Kind, Name, Alignment.Val, PackLoc,
106 LParenLoc, RParenLoc);
107}
108