opnsense-src/lib/Parse/ParsePragma.cpp

221 lines
6.1 KiB
C++
Raw Normal View History

2009-06-02 13:58:47 -04:00
//===--- 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"
#include "clang/Parse/Parser.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_expected_lparen) << "pack";
return;
}
Action::PragmaPackKind Kind = Action::PPK_Default;
IdentifierInfo *Name = 0;
Action::OwningExprResult Alignment(Actions);
SourceLocation LParenLoc = Tok.getLocation();
2009-10-14 14:03:49 -04:00
PP.Lex(Tok);
2009-06-02 13:58:47 -04:00
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;
2009-10-14 14:03:49 -04:00
}
2009-06-02 13:58:47 -04:00
PP.Lex(Tok);
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
if (Tok.is(tok::comma)) {
PP.Lex(Tok);
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
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);
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
if (Tok.is(tok::comma)) {
PP.Lex(Tok);
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
if (Tok.isNot(tok::numeric_constant)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
return;
}
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
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_expected_rparen) << "pack";
return;
}
2009-06-06 04:21:31 -04:00
PP.Lex(Tok);
if (Tok.isNot(tok::eom)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
return;
}
2009-06-02 13:58:47 -04:00
SourceLocation RParenLoc = Tok.getLocation();
Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
LParenLoc, RParenLoc);
}
// #pragma unused(identifier)
void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) {
// FIXME: Should we be expanding macros here? My guess is no.
SourceLocation UnusedLoc = UnusedTok.getLocation();
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
// Lex the left '('.
Token Tok;
PP.Lex(Tok);
if (Tok.isNot(tok::l_paren)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
return;
}
SourceLocation LParenLoc = Tok.getLocation();
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
// Lex the declaration reference(s).
2009-10-14 14:03:49 -04:00
llvm::SmallVector<Token, 5> Identifiers;
2009-06-02 13:58:47 -04:00
SourceLocation RParenLoc;
bool LexID = true;
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
while (true) {
PP.Lex(Tok);
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
if (LexID) {
2009-10-14 14:03:49 -04:00
if (Tok.is(tok::identifier)) {
Identifiers.push_back(Tok);
2009-06-02 13:58:47 -04:00
LexID = false;
continue;
}
2009-10-14 14:03:49 -04:00
// Illegal token!
2009-06-02 13:58:47 -04:00
PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
return;
}
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
// We are execting a ')' or a ','.
if (Tok.is(tok::comma)) {
LexID = true;
continue;
}
2009-10-14 14:03:49 -04:00
2009-06-02 13:58:47 -04:00
if (Tok.is(tok::r_paren)) {
RParenLoc = Tok.getLocation();
break;
}
2009-10-14 14:03:49 -04:00
// Illegal token!
2009-06-02 13:58:47 -04:00
PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
return;
}
2009-06-06 04:21:31 -04:00
PP.Lex(Tok);
if (Tok.isNot(tok::eom)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
"unused";
return;
}
2009-06-02 13:58:47 -04:00
// Verify that we have a location for the right parenthesis.
assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
2009-10-14 14:03:49 -04:00
assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
2009-06-02 13:58:47 -04:00
2009-10-14 14:03:49 -04:00
// Perform the action to handle the pragma.
Actions.ActOnPragmaUnused(Identifiers.data(), Identifiers.size(),
parser.CurScope, UnusedLoc, LParenLoc, RParenLoc);
2009-06-02 13:58:47 -04:00
}
2009-06-06 04:21:31 -04:00
// #pragma weak identifier
// #pragma weak identifier '=' identifier
void PragmaWeakHandler::HandlePragma(Preprocessor &PP, Token &WeakTok) {
// FIXME: Should we be expanding macros here? My guess is no.
SourceLocation WeakLoc = WeakTok.getLocation();
Token Tok;
PP.Lex(Tok);
if (Tok.isNot(tok::identifier)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
return;
}
IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
PP.Lex(Tok);
if (Tok.is(tok::equal)) {
PP.Lex(Tok);
if (Tok.isNot(tok::identifier)) {
2009-10-14 14:03:49 -04:00
PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2009-06-06 04:21:31 -04:00
<< "weak";
return;
}
AliasName = Tok.getIdentifierInfo();
AliasNameLoc = Tok.getLocation();
PP.Lex(Tok);
}
if (Tok.isNot(tok::eom)) {
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
return;
}
if (AliasName) {
Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
AliasNameLoc);
} else {
Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
}
}