/* Parse C expressions for cpplib.
- Copyright (C) 1987, 92, 94, 95, 97, 98, 1999, 2000 Free Software Foundation.
+ Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation.
Contributed by Per Bothner, 1994.
This program is free software; you can redistribute it and/or modify it
#include "system.h"
#include "cpplib.h"
#include "cpphash.h"
-#include "defaults.h"
#ifndef MAX_CHAR_TYPE_SIZE
#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
goto invalid_suffix;
op.unsignedp = sufftab[i].u;
- if (CPP_WTRADITIONAL (pfile) && sufftab[i].u)
+ if (CPP_WTRADITIONAL (pfile)
+ && sufftab[i].u
+ && ! cpp_sys_macro_p (pfile))
cpp_warning (pfile, "traditional C rejects the `U' suffix");
- if (CPP_OPTION (pfile, c89) && sufftab[i].l == 2)
- SYNTAX_ERROR ("too many 'l' suffixes in integer constant");
+ if (sufftab[i].l == 2 && CPP_OPTION (pfile, pedantic)
+ && ! CPP_OPTION (pfile, c99))
+ cpp_pedwarn (pfile, "too many 'l' suffixes in integer constant");
}
if (base <= largest_digit)
HOST_WIDEST_INT result = 0;
int num_chars = 0;
int num_bits;
- unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK;
+ unsigned int width = MAX_CHAR_TYPE_SIZE;
+ HOST_WIDEST_INT mask = MAX_CHAR_TYPE_MASK;
int max_chars;
const U_CHAR *ptr = tok->val.str.text;
const U_CHAR *end = ptr + tok->val.str.len;
/* Don't expand macros. */
pfile->state.prevent_expansion++;
- _cpp_get_token (pfile, &token);
+ cpp_get_token (pfile, &token);
if (token.type == CPP_OPEN_PAREN)
{
paren = 1;
- _cpp_get_token (pfile, &token);
+ cpp_get_token (pfile, &token);
}
if (token.type == CPP_NAME)
node = token.val.node;
if (paren)
{
- _cpp_get_token (pfile, &token);
+ cpp_get_token (pfile, &token);
if (token.type != CPP_CLOSE_PAREN)
{
cpp_error (pfile, "missing ')' after \"defined\"");
}
}
else
- cpp_error (pfile, "\"defined\" without an identifier");
+ {
+ cpp_error (pfile, "operator \"defined\" requires an identifier");
+ if (token.flags & NAMED_OP)
+ {
+ cpp_token op;
+
+ op.flags = 0;
+ op.type = token.type;
+ cpp_error (pfile,
+ "(\"%s\" is an alternative token for \"%s\" in C++)",
+ cpp_token_as_text (pfile, &token),
+ cpp_token_as_text (pfile, &op));
+ }
+ }
if (!node)
op.op = CPP_ERROR;
{
struct op op;
- _cpp_get_token (pfile, token);
+ cpp_get_token (pfile, token);
switch (token->type)
{
case CPP_INT:
case CPP_NUMBER:
return parse_number (pfile, token);
+
case CPP_CHAR:
case CPP_WCHAR:
return parse_charconst (pfile, token);
return parse_defined (pfile);
}
- /* Controlling #if expressions cannot contain identifiers (they
- could become macros in the future). */
- pfile->mi_state = MI_FAILED;
-
- op.op = CPP_INT;
- op.unsignedp = 0;
- op.value = 0;
+ else if (CPP_OPTION (pfile, cplusplus)
+ && (token->val.node == pfile->spec_nodes.n_true
+ || token->val.node == pfile->spec_nodes.n_false))
+ {
+ op.op = CPP_INT;
+ op.unsignedp = 0;
+ op.value = (token->val.node == pfile->spec_nodes.n_true);
+
+ /* Warn about use of true or false in #if when pedantic
+ and stdbool.h has not been included. */
+ if (CPP_PEDANTIC (pfile)
+ && ! cpp_defined (pfile, DSC("__bool_true_false_are_defined")))
+ cpp_pedwarn (pfile, "ISO C++ does not permit \"%s\" in #if",
+ token->val.node->name);
+ return op;
+ }
+ else
+ {
+ /* Controlling #if expressions cannot contain identifiers (they
+ could become macros in the future). */
+ pfile->mi_state = MI_FAILED;
- if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
- cpp_warning (pfile, "\"%s\" is not defined", token->val.node->name);
+ op.op = CPP_INT;
+ op.unsignedp = 0;
+ op.value = 0;
- return op;
+ if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
+ cpp_warning (pfile, "\"%s\" is not defined", token->val.node->name);
+ return op;
+ }
case CPP_HASH:
{
/* Fall through. */
default:
- if ((token->type > CPP_EQ && token->type < CPP_PLUS_EQ)
+ if (((int) token->type > (int) CPP_EQ
+ && (int) token->type < (int) CPP_PLUS_EQ)
|| token->type == CPP_EOF)
{
op.op = token->type;