ParsePragma.cpp revision 0e9eabca263e8922bec0e2b38c8670eba9a39a1f
1//===--- 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 "AstGuard.h" 16#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 ExprOwner Alignment(Actions); 39 SourceLocation LParenLoc = Tok.getLocation(); 40 PP.Lex(Tok); 41 if (Tok.is(tok::numeric_constant)) { 42 Alignment = Actions.ActOnNumericConstant(Tok); 43 if (Alignment.isInvalid()) 44 return; 45 46 PP.Lex(Tok); 47 } else if (Tok.is(tok::identifier)) { 48 const IdentifierInfo *II = Tok.getIdentifierInfo(); 49 if (II->isStr("show")) { 50 Kind = Action::PPK_Show; 51 PP.Lex(Tok); 52 } else { 53 if (II->isStr("push")) { 54 Kind = Action::PPK_Push; 55 } else if (II->isStr("pop")) { 56 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); 68 if (Alignment.isInvalid()) 69 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)) { 80 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); 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 return; 93 } 94 } 95 } 96 } 97 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(); 104 Actions.ActOnPragmaPack(Kind, Name, Alignment.move(), PackLoc, 105 LParenLoc, RParenLoc); 106} 107 108