forked from OSchip/llvm-project
107 lines
3.1 KiB
C++
107 lines
3.1 KiB
C++
//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the language specific #pragma handlers.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ParsePragma.h"
|
|
#include "clang/Parse/ParseDiagnostic.h"
|
|
#include "clang/Lex/Preprocessor.h"
|
|
#include "clang/Parse/Action.h"
|
|
using namespace clang;
|
|
|
|
// #pragma pack(...) comes in the following delicious flavors:
|
|
// pack '(' [integer] ')'
|
|
// pack '(' 'show' ')'
|
|
// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
|
|
void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) {
|
|
// FIXME: Should we be expanding macros here? My guess is no.
|
|
SourceLocation PackLoc = PackTok.getLocation();
|
|
|
|
Token Tok;
|
|
PP.Lex(Tok);
|
|
if (Tok.isNot(tok::l_paren)) {
|
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_lparen);
|
|
return;
|
|
}
|
|
|
|
Action::PragmaPackKind Kind = Action::PPK_Default;
|
|
IdentifierInfo *Name = 0;
|
|
Action::OwningExprResult Alignment(Actions);
|
|
SourceLocation LParenLoc = Tok.getLocation();
|
|
PP.Lex(Tok);
|
|
if (Tok.is(tok::numeric_constant)) {
|
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
|
if (Alignment.isInvalid())
|
|
return;
|
|
|
|
PP.Lex(Tok);
|
|
} else if (Tok.is(tok::identifier)) {
|
|
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
|
if (II->isStr("show")) {
|
|
Kind = Action::PPK_Show;
|
|
PP.Lex(Tok);
|
|
} else {
|
|
if (II->isStr("push")) {
|
|
Kind = Action::PPK_Push;
|
|
} else if (II->isStr("pop")) {
|
|
Kind = Action::PPK_Pop;
|
|
} else {
|
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
|
|
return;
|
|
}
|
|
PP.Lex(Tok);
|
|
|
|
if (Tok.is(tok::comma)) {
|
|
PP.Lex(Tok);
|
|
|
|
if (Tok.is(tok::numeric_constant)) {
|
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
|
if (Alignment.isInvalid())
|
|
return;
|
|
|
|
PP.Lex(Tok);
|
|
} else if (Tok.is(tok::identifier)) {
|
|
Name = Tok.getIdentifierInfo();
|
|
PP.Lex(Tok);
|
|
|
|
if (Tok.is(tok::comma)) {
|
|
PP.Lex(Tok);
|
|
|
|
if (Tok.isNot(tok::numeric_constant)) {
|
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
|
|
return;
|
|
}
|
|
|
|
Alignment = Actions.ActOnNumericConstant(Tok);
|
|
if (Alignment.isInvalid())
|
|
return;
|
|
|
|
PP.Lex(Tok);
|
|
}
|
|
} else {
|
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Tok.isNot(tok::r_paren)) {
|
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
|
|
return;
|
|
}
|
|
|
|
SourceLocation RParenLoc = Tok.getLocation();
|
|
Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
|
|
LParenLoc, RParenLoc);
|
|
}
|
|
|