/* Separate lexical analyzer for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This file is the lexical analyzer for GNU C++. */
}
/* A mapping from tree codes to operator name information. */
-operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE];
+operator_name_info_t operator_name_info[(int) MAX_TREE_CODES];
/* Similar, but for assignment operators. */
-operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
+operator_name_info_t assignment_operator_name_info[(int) MAX_TREE_CODES];
/* Initialize data structures that keep track of operator names. */
= "(round %=)";
}
-/* The reserved keyword table. */
-struct resword
-{
- const char *const word;
- ENUM_BITFIELD(rid) const rid : 16;
- const unsigned int disable : 16;
-};
-
-/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is
- _true_. */
-#define D_EXT 0x01 /* GCC extension */
-#define D_ASM 0x02 /* in C99, but has a switch to turn it off */
-#define D_OBJC 0x04 /* Objective C++ only */
-#define D_CXX0X 0x08 /* C++0x only */
-
-CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
-
-static const struct resword reswords[] =
-{
- { "_Complex", RID_COMPLEX, 0 },
- { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
- { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
- { "__alignof", RID_ALIGNOF, 0 },
- { "__alignof__", RID_ALIGNOF, 0 },
- { "__asm", RID_ASM, 0 },
- { "__asm__", RID_ASM, 0 },
- { "__attribute", RID_ATTRIBUTE, 0 },
- { "__attribute__", RID_ATTRIBUTE, 0 },
- { "__builtin_offsetof", RID_OFFSETOF, 0 },
- { "__builtin_va_arg", RID_VA_ARG, 0 },
- { "__complex", RID_COMPLEX, 0 },
- { "__complex__", RID_COMPLEX, 0 },
- { "__const", RID_CONST, 0 },
- { "__const__", RID_CONST, 0 },
- { "__extension__", RID_EXTENSION, 0 },
- { "__func__", RID_C99_FUNCTION_NAME, 0 },
- { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, 0 },
- { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, 0 },
- { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, 0 },
- { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, 0 },
- { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, 0 },
- { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, 0 },
- { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, 0 },
- { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, 0 },
- { "__is_abstract", RID_IS_ABSTRACT, 0 },
- { "__is_base_of", RID_IS_BASE_OF, 0 },
- { "__is_class", RID_IS_CLASS, 0 },
- { "__is_convertible_to", RID_IS_CONVERTIBLE_TO, 0 },
- { "__is_empty", RID_IS_EMPTY, 0 },
- { "__is_enum", RID_IS_ENUM, 0 },
- { "__is_pod", RID_IS_POD, 0 },
- { "__is_polymorphic", RID_IS_POLYMORPHIC, 0 },
- { "__is_union", RID_IS_UNION, 0 },
- { "__imag", RID_IMAGPART, 0 },
- { "__imag__", RID_IMAGPART, 0 },
- { "__inline", RID_INLINE, 0 },
- { "__inline__", RID_INLINE, 0 },
- { "__label__", RID_LABEL, 0 },
- { "__null", RID_NULL, 0 },
- { "__real", RID_REALPART, 0 },
- { "__real__", RID_REALPART, 0 },
- { "__restrict", RID_RESTRICT, 0 },
- { "__restrict__", RID_RESTRICT, 0 },
- { "__signed", RID_SIGNED, 0 },
- { "__signed__", RID_SIGNED, 0 },
- { "__thread", RID_THREAD, 0 },
- { "__typeof", RID_TYPEOF, 0 },
- { "__typeof__", RID_TYPEOF, 0 },
- { "__volatile", RID_VOLATILE, 0 },
- { "__volatile__", RID_VOLATILE, 0 },
- { "asm", RID_ASM, D_ASM },
- { "auto", RID_AUTO, 0 },
- { "bool", RID_BOOL, 0 },
- { "break", RID_BREAK, 0 },
- { "case", RID_CASE, 0 },
- { "catch", RID_CATCH, 0 },
- { "char", RID_CHAR, 0 },
- { "class", RID_CLASS, 0 },
- { "const", RID_CONST, 0 },
- { "const_cast", RID_CONSTCAST, 0 },
- { "continue", RID_CONTINUE, 0 },
- { "default", RID_DEFAULT, 0 },
- { "delete", RID_DELETE, 0 },
- { "do", RID_DO, 0 },
- { "double", RID_DOUBLE, 0 },
- { "dynamic_cast", RID_DYNCAST, 0 },
- { "else", RID_ELSE, 0 },
- { "enum", RID_ENUM, 0 },
- { "explicit", RID_EXPLICIT, 0 },
- { "export", RID_EXPORT, 0 },
- { "extern", RID_EXTERN, 0 },
- { "false", RID_FALSE, 0 },
- { "float", RID_FLOAT, 0 },
- { "for", RID_FOR, 0 },
- { "friend", RID_FRIEND, 0 },
- { "goto", RID_GOTO, 0 },
- { "if", RID_IF, 0 },
- { "inline", RID_INLINE, 0 },
- { "int", RID_INT, 0 },
- { "long", RID_LONG, 0 },
- { "mutable", RID_MUTABLE, 0 },
- { "namespace", RID_NAMESPACE, 0 },
- { "new", RID_NEW, 0 },
- { "operator", RID_OPERATOR, 0 },
- { "private", RID_PRIVATE, 0 },
- { "protected", RID_PROTECTED, 0 },
- { "public", RID_PUBLIC, 0 },
- { "register", RID_REGISTER, 0 },
- { "reinterpret_cast", RID_REINTCAST, 0 },
- { "return", RID_RETURN, 0 },
- { "short", RID_SHORT, 0 },
- { "signed", RID_SIGNED, 0 },
- { "sizeof", RID_SIZEOF, 0 },
- { "static", RID_STATIC, 0 },
- { "static_assert", RID_STATIC_ASSERT, D_CXX0X },
- { "static_cast", RID_STATCAST, 0 },
- { "struct", RID_STRUCT, 0 },
- { "switch", RID_SWITCH, 0 },
- { "template", RID_TEMPLATE, 0 },
- { "this", RID_THIS, 0 },
- { "throw", RID_THROW, 0 },
- { "true", RID_TRUE, 0 },
- { "try", RID_TRY, 0 },
- { "typedef", RID_TYPEDEF, 0 },
- { "typename", RID_TYPENAME, 0 },
- { "typeid", RID_TYPEID, 0 },
- { "typeof", RID_TYPEOF, D_ASM|D_EXT },
- { "union", RID_UNION, 0 },
- { "unsigned", RID_UNSIGNED, 0 },
- { "using", RID_USING, 0 },
- { "virtual", RID_VIRTUAL, 0 },
- { "void", RID_VOID, 0 },
- { "volatile", RID_VOLATILE, 0 },
- { "wchar_t", RID_WCHAR, 0 },
- { "while", RID_WHILE, 0 },
-
- /* The remaining keywords are specific to Objective-C++. NB:
- All of them will remain _disabled_, since they are context-
- sensitive. */
-
- /* These ObjC keywords are recognized only immediately after
- an '@'. NB: The following C++ keywords double as
- ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
- RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH. */
- { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
- { "defs", RID_AT_DEFS, D_OBJC },
- { "encode", RID_AT_ENCODE, D_OBJC },
- { "end", RID_AT_END, D_OBJC },
- { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
- { "interface", RID_AT_INTERFACE, D_OBJC },
- { "protocol", RID_AT_PROTOCOL, D_OBJC },
- { "selector", RID_AT_SELECTOR, D_OBJC },
- { "finally", RID_AT_FINALLY, D_OBJC },
- { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
- /* These are recognized only in protocol-qualifier context. */
- { "bycopy", RID_BYCOPY, D_OBJC },
- { "byref", RID_BYREF, D_OBJC },
- { "in", RID_IN, D_OBJC },
- { "inout", RID_INOUT, D_OBJC },
- { "oneway", RID_ONEWAY, D_OBJC },
- { "out", RID_OUT, D_OBJC },
-};
+/* Initialize the reserved words. */
void
init_reswords (void)
{
unsigned int i;
tree id;
- int mask = ((flag_no_asm ? D_ASM : 0)
- | D_OBJC
- | (flag_no_gnu_keywords ? D_EXT : 0)
- | (flag_cpp0x ? 0 : D_CXX0X));
+ int mask = 0;
+
+ mask |= D_CONLY;
+ if (cxx_dialect != cxx0x)
+ mask |= D_CXX0X;
+ if (flag_no_asm)
+ mask |= D_ASM | D_EXT;
+ if (flag_no_gnu_keywords)
+ mask |= D_EXT;
+ if (!c_dialect_objc())
+ mask |= D_OBJC;
ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
- for (i = 0; i < ARRAY_SIZE (reswords); i++)
+ for (i = 0; i < num_c_common_reswords; i++)
{
- id = get_identifier (reswords[i].word);
- C_RID_CODE (id) = reswords[i].rid;
- ridpointers [(int) reswords[i].rid] = id;
- if (! (reswords[i].disable & mask))
+ id = get_identifier (c_common_reswords[i].word);
+ C_SET_RID_CODE (id, c_common_reswords[i].rid);
+ ridpointers [(int) c_common_reswords[i].rid] = id;
+ if (! (c_common_reswords[i].disable & mask))
C_IS_RESERVED_WORD (id) = 1;
}
}
bool
cxx_init (void)
{
+ location_t saved_loc;
unsigned int i;
static const enum tree_code stmt_codes[] = {
CTOR_INITIALIZER, TRY_BLOCK, HANDLER,
for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
statement_code_p[stmt_codes[i]] = true;
- /* We cannot just assign to input_filename because it has already
- been initialized and will be used later as an N_BINCL for stabs+
- debugging. */
-#ifdef USE_MAPPED_LOCATION
- push_srcloc (BUILTINS_LOCATION);
-#else
- push_srcloc ("<built-in>", 0);
-#endif
+ saved_loc = input_location;
+ input_location = BUILTINS_LOCATION;
init_reswords ();
init_tree ();
if (c_common_init () == false)
{
- pop_srcloc();
+ input_location = saved_loc;
return false;
}
init_repo ();
- pop_srcloc();
+ input_location = saved_loc;
return true;
}
\f
else if (fname == 0)
filename = lbasename (input_filename);
else
- filename = ggc_strdup (TREE_STRING_POINTER (fname));
+ filename = TREE_STRING_POINTER (fname);
finfo = get_fileinfo (input_filename);
}
else
{
- filename = ggc_strdup (TREE_STRING_POINTER (fname));
-#if 0
- /* We currently cannot give this diagnostic, as we reach this point
- only after cpplib has scanned the entire translation unit, so
- cpp_included always returns true. A plausible fix is to compare
- the current source-location cookie with the first source-location
- cookie (if any) of the filename, but this requires completing the
- --enable-mapped-location project first. See PR 17577. */
- if (cpp_included (parse_in, filename))
+ filename = TREE_STRING_POINTER (fname);
+ if (cpp_included_before (parse_in, filename, input_location))
warning (0, "#pragma implementation for %qs appears after "
"file is included", filename);
-#endif
}
for (; ifiles; ifiles = ifiles->next)
if (ifiles == 0)
{
ifiles = XNEW (struct impl_files);
- ifiles->filename = filename;
+ ifiles->filename = xstrdup (filename);
ifiles->next = impl_file_chain;
impl_file_chain = ifiles;
}
Note that we have the exact wording of the following message in
the manual (trouble.texi, node "Name lookup"), so they need to
be kept in synch. */
- pedwarn ("there are no arguments to %qD that depend on a template "
- "parameter, so a declaration of %qD must be available",
- name, name);
+ permerror ("there are no arguments to %qD that depend on a template "
+ "parameter, so a declaration of %qD must be available",
+ name, name);
if (!flag_permissive)
{
static bool hint;
if (!hint)
{
- error ("(if you use %<-fpermissive%>, G++ will accept your "
+ inform ("(if you use %<-fpermissive%>, G++ will accept your "
"code, but allowing the use of an undeclared name is "
"deprecated)");
hint = true;
tree t = make_node (code);
/* Create lang_type structure. */
- if (IS_AGGR_TYPE_CODE (code)
+ if (RECORD_OR_UNION_CODE_P (code)
|| code == BOUND_TEMPLATE_TEMPLATE_PARM)
{
struct lang_type *pi = GGC_CNEW (struct lang_type);
}
/* Set up some flags that give proper default behavior. */
- if (IS_AGGR_TYPE_CODE (code))
+ if (RECORD_OR_UNION_CODE_P (code))
{
struct c_fileinfo *finfo = get_fileinfo (input_filename);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
}
tree
-make_aggr_type (enum tree_code code)
+make_class_type (enum tree_code code)
{
tree t = cxx_make_type (code);
+ SET_CLASS_TYPE_P (t, 1);
+ return t;
+}
- if (IS_AGGR_TYPE_CODE (code))
- SET_IS_AGGR_TYPE (t, 1);
+/* Returns true if we are currently in the main source file, or in a
+ template instantiation started from the main source file. */
- return t;
+bool
+in_main_input_context (void)
+{
+ struct tinst_level *tl = outermost_tinst_level();
+
+ if (tl)
+ return strcmp (main_input_filename,
+ LOCATION_FILE (tl->locus)) == 0;
+ else
+ return strcmp (main_input_filename, input_filename) == 0;
}