#include "ggc.h"
#include "timevar.h"
#include "cpplib.h"
+#include "target.h"
extern cpp_reader *parse_in;
/* This structure contains information about the initializations
static int compare_options PARAMS ((const PTR, const PTR));
static tree get_guard_bits PARAMS ((tree));
-extern int current_class_depth;
-
-/* A list of virtual function tables we must make sure to write out. */
-tree pending_vtables;
-
/* A list of static class variables. This is needed, because a
static class variable can be declared inside the class without
an initializer, and then initialized, staticly, outside the class. */
/* The :: namespace. */
tree global_namespace;
-
-/* The stack for namespaces of current declarations. */
-
-static tree decl_namespace_list;
-
\f
/* C (and C++) language-specific option variables. */
int warn_nonvdtor;
-/* Non-zero means warn when a function is declared extern and later inline. */
-
-int warn_extern_inline;
-
/* Non-zero means warn when the compiler will reorder code. */
int warn_reorder;
#endif
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
-/* Nonzero means that labels can be used as first-class objects */
-
-int flag_labels_ok;
-
/* Nonzero means allow Microsoft extensions without a pedwarn. */
int flag_ms_extensions;
int flag_rtti = 1;
-/* Nonzero if we wish to output cross-referencing information
- for the GNU class browser. */
-
-extern int flag_gnu_xref;
-
/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
objects. */
int flag_check_new;
-/* Nonnull if we want to dump class heirarchies. */
-
-const char *flag_dump_class_layout;
-
/* Nonzero if we want the new ISO rules for pushing a new scope for `for'
initialization variables.
0: Old rules, set by -fno-for-scope.
/* Nonzero to not ignore namespace std. */
-int flag_honor_std = ENABLE_STD_NAMESPACE;
+int flag_honor_std = 1;
-/* Nonzero if we should expand functions calls inline at the tree
- level, rather than at the RTL level. */
+/* 0 if we should not perform inlining.
+ 1 if we should expand functions calls inline at the tree level.
+ 2 if we should consider *all* functions to be inline
+ candidates. */
int flag_inline_trees = 0;
{"gnu-keywords", &flag_no_gnu_keywords, 0},
{"handle-exceptions", &flag_exceptions, 1},
{"honor-std", &flag_honor_std, 1},
- {"huge-objects", &flag_huge_objects, 1},
{"implement-inlines", &flag_implement_inlines, 1},
{"implicit-inline-templates", &flag_implicit_inline_templates, 1},
{"implicit-templates", &flag_implicit_templates, 1},
- {"labels-ok", &flag_labels_ok, 1},
{"ms-extensions", &flag_ms_extensions, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0},
{"operator-names", &flag_operator_names, 1},
{"repo", &flag_use_repository, 1},
{"rtti", &flag_rtti, 1},
{"stats", &flag_detailed_statistics, 1},
- {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
{"vtable-gc", &flag_vtable_gc, 1},
- {"vtable-thunks", &flag_vtable_thunks, 1},
- {"weak", &flag_weak, 1},
- {"xref", &flag_gnu_xref, 1}
+ {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
+ {"weak", &flag_weak, 1}
};
/* The list of `-f' options that we no longer support. The `-f'
"cond-mismatch",
"enum-int-equiv",
"guiding-decls",
+ "huge-objects",
+ "labels-ok",
+ "new-abi",
"nonnull-objects",
"squangle",
"strict-prototype",
"this-is-variable",
+ "vtable-thunks",
+ "xref"
};
/* Compare two option strings, pointed two by P1 and P2, for use with
warning ("-fname-mangling-version is no longer supported");
return 1;
}
- else if ((option_value
- = skip_leading_substring (p, "dump-translation-unit=")))
- {
- if (!*option_value)
- error ("no file specified with -fdump-translation-unit");
- else
- flag_dump_translation_unit = option_value;
- }
- else if ((option_value
- = skip_leading_substring (p, "dump-class-layout=")))
- {
- if (!*option_value)
- error ("no file specified with -fdump-class-layout");
- else
- flag_dump_class_layout = option_value;
- }
- else if (!strcmp (p, "dump-class-layout"))
- flag_dump_class_layout = ""; /* empty string for stderr */
+ else if (dump_switch_p (p))
+ ;
else
{
int found = 0;
warn_parentheses = setting;
else if (!strcmp (p, "non-virtual-dtor"))
warn_nonvdtor = setting;
- else if (!strcmp (p, "extern-inline"))
- warn_extern_inline = setting;
else if (!strcmp (p, "reorder"))
warn_reorder = setting;
else if (!strcmp (p, "synth"))
/* Even within an `extern "C"' block, members get C++ linkage. See
[dcl.link] for details. */
- DECL_LANGUAGE (function) = lang_cplusplus;
+ SET_DECL_LANGUAGE (function, lang_cplusplus);
if (fn_name == NULL_TREE)
{
DECL_ARGUMENTS (function) = last_function_parms;
DECL_CONTEXT (function) = ctype;
+ if (flags == DTOR_FLAG)
+ DECL_DESTRUCTOR_P (function) = 1;
+
if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
maybe_retrofit_in_chrg (function);
if (flags == DTOR_FLAG)
{
DECL_DESTRUCTOR_P (function) = 1;
- set_mangled_name_for_decl (function);
TYPE_HAS_DESTRUCTOR (ctype) = 1;
}
- else
- set_mangled_name_for_decl (function);
}
/* Work on the expr used by alignof (this is only called by the parser). */
fndecls = OVL_NEXT (fndecls))
{
fndecl = OVL_CURRENT (fndecls);
- /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or
- for a for member function of a template class, is
- not mangled, so the check below does not work
- correctly in that case. Since mangled destructor
- names do not include the type of the arguments,
- we can't use this short-cut for them, either.
- (It's not legal to declare arguments for a
- destructor, but some people try.) */
- if (!DECL_DESTRUCTOR_P (function)
- && (DECL_ASSEMBLER_NAME (function)
- != DECL_NAME (function))
- && (DECL_ASSEMBLER_NAME (fndecl)
- != DECL_NAME (fndecl))
- && (DECL_ASSEMBLER_NAME (function)
- == DECL_ASSEMBLER_NAME (fndecl)))
- return fndecl;
/* We cannot simply call decls_match because this
doesn't work for static member functions that are
tree asmspec_tree;
int flags;
{
- const char *asmspec = 0;
-
- if (asmspec_tree)
- asmspec = TREE_STRING_POINTER (asmspec_tree);
-
my_friendly_assert (TREE_PUBLIC (decl), 0);
DECL_CONTEXT (decl) = current_class_type;
/* We cannot call pushdecl here, because that would fill in the
- decl of our TREE_CHAIN. Instead, we modify cp_finish_decl to do
+ TREE_CHAIN of our decl. Instead, we modify cp_finish_decl to do
the right thing, namely, to put this decl out straight away. */
/* current_class_type can be NULL_TREE in case of error. */
- if (!asmspec && current_class_type)
- {
- DECL_INITIAL (decl) = error_mark_node;
- DECL_ASSEMBLER_NAME (decl) = mangle_decl (decl);
- }
+ if (!asmspec_tree && current_class_type)
+ DECL_INITIAL (decl) = error_mark_node;
+
if (! processing_template_decl)
{
if (!pending_statics)
if (CLASS_TYPE_P (TREE_TYPE (value)))
CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
- /* Now that we've updated the context, we need to remangle the
- name for this TYPE_DECL. */
- DECL_ASSEMBLER_NAME (value) = DECL_NAME (value);
- if (!uses_template_parms (value))
- DECL_ASSEMBLER_NAME (value) = mangle_type (TREE_TYPE (value));
-
if (processing_template_decl)
value = push_template_decl (value);
{
/* This must override the asm specifier which was placed
by grokclassfn. Lay this out fresh. */
- DECL_RTL (value) = NULL_RTX;
- DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec);
+ SET_DECL_RTL (value, NULL_RTX);
+ SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec));
}
cp_finish_decl (value, init, asmspec_tree, flags);
if (TREE_CODE (type) == FUNCTION_TYPE)
cp_error ("initializer specified for non-member function `%D'", decl);
-#if 0
- /* We'll check for this in finish_struct_1. */
- else if (DECL_VINDEX (decl) == NULL_TREE)
- cp_error ("initializer specified for non-virtual member function `%D'", decl);
-#endif
else if (integer_zerop (init))
{
-#if 0
- /* Mark this function as being "defined". */
- DECL_INITIAL (decl) = error_mark_node;
- /* pure virtual destructors must be defined. */
- /* pure virtual needs to be defined (as abort) only when put in
- vtbl. For wellformed call, it should be itself. pr4737 */
- if (!DECL_DESTRUCTOR_P (decl)))
- {
- /* Give this node rtl from `abort'. */
- DECL_RTL (decl) = DECL_RTL (abort_fndecl);
- }
-#endif
DECL_PURE_VIRTUAL_P (decl) = 1;
if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
{
if (TREE_CODE (decl) == TEMPLATE_DECL)
decl = DECL_TEMPLATE_RESULT (decl);
- decl_attributes (decl, attributes, prefix_attributes);
+ decl_attributes (decl, chainon (attributes, prefix_attributes));
if (TREE_CODE (decl) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));
return main_decl;
}
-/* Finish off the processing of a UNION_TYPE structure.
- If there are static members, then all members are
- static, and must be laid out together. If the
- union is an anonymous union, we arrange for that
- as well. PUBLIC_P is nonzero if this union is
- not declared static. */
+/* Finish off the processing of a UNION_TYPE structure. If the union is an
+ anonymous union, then all members must be laid out together. PUBLIC_P
+ is nonzero if this union is not declared static. */
void
finish_anon_union (anon_union_decl)
int static_p = TREE_STATIC (anon_union_decl);
int external_p = DECL_EXTERNAL (anon_union_decl);
+ /* The VAR_DECL's context is the same as the TYPE's context. */
+ DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
+
if (TYPE_FIELDS (type) == NULL_TREE)
return;
if (static_p)
{
make_decl_rtl (main_decl, 0);
- DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+ COPY_DECL_RTL (main_decl, anon_union_decl);
expand_anon_union_decl (anon_union_decl,
NULL_TREE,
DECL_ANON_UNION_ELEMS (anon_union_decl));
if (TREE_CODE (fnaddr) != ADDR_EXPR)
/* This entry is an offset: a virtual base class offset, a
- virtual call offset, and RTTI offset, etc. */
+ virtual call offset, an RTTI offset, etc. */
continue;
fn = TREE_OPERAND (fnaddr, 0);
we know all the thunks we'll need when we emit a virtual
function, so we emit the thunks there instead. */
if (DECL_THUNK_P (fn))
- use_thunk (fn, THUNK_GENERATE_WITH_VTABLE_P (fn));
+ use_thunk (fn, /*emit_p=*/0);
mark_used (fn);
}
}
after a weak one is an error. Also, not making explicit
instantiations one_only means that we can end up with two copies of
some template instantiations. */
- if (! supports_one_only ())
+ if (! flag_weak)
return;
/* We can't set DECL_COMDAT on functions, or finish_file will think
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE
- && ! DECL_THIS_INLINE (method)
- && ! DECL_PURE_VIRTUAL_P (method))
+ && ! DECL_DECLARED_INLINE_P (method)
+ && (! DECL_PURE_VIRTUAL_P (method)
+#if 0
+ /* This would be nice, but we didn't think of it in time. */
+ || DECL_DESTRUCTOR_P (method)
+#endif
+ ))
return method;
return NULL_TREE;
else if (CLASSTYPE_INTERFACE_KNOWN (type))
{
TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
+ DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
DECL_INTERFACE_KNOWN (decl) = 1;
}
else
if (CLASSTYPE_INTERFACE_ONLY (ctype))
return;
-#ifdef VALID_MACHINE_TYPE_ATTRIBUTE
- /* FIXME this should really use some sort of target-independent macro. */
- if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
+ if ((*targetm.valid_type_attribute) (ctype,
+ TYPE_ATTRIBUTES (ctype),
+ get_identifier ("dllimport"),
+ NULL_TREE)
+ && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
import_export = -1;
- else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
+ else if ((*targetm.valid_type_attribute) (ctype,
+ TYPE_ATTRIBUTES (ctype),
+ get_identifier ("dllexport"),
+ NULL_TREE)
+ && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
import_export = 1;
-#endif
/* If we got -fno-implicit-templates, we import template classes that
weren't explicitly instantiated. */
if (import_export)
{
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
- CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0);
CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
}
}
if (flag_weak)
comdat_linkage (vars);
- rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
+ rest_of_decl_compilation (vars, NULL, 1, 1);
if (flag_vtable_gc)
output_vtable_inherit (vars);
if ((DECL_IMPLICIT_INSTANTIATION (decl)
|| DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
&& (flag_implicit_templates
- || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl))))
+ || (flag_implicit_inline_templates
+ && DECL_DECLARED_INLINE_P (decl))))
{
if (!TREE_PUBLIC (decl))
/* Templates are allowed to have internal linkage. See
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
- tree ctype = DECL_CONTEXT (decl);
- import_export_class (ctype);
- if (CLASSTYPE_INTERFACE_KNOWN (ctype)
- && ! DECL_THIS_INLINE (decl))
+ if (!DECL_DECLARED_INLINE_P (decl))
{
- DECL_NOT_REALLY_EXTERN (decl)
- = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
- || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
- && !DECL_VINDEX (decl)));
-
- /* Always make artificials weak. */
- if (DECL_ARTIFICIAL (decl) && flag_weak)
- comdat_linkage (decl);
- else
- maybe_make_one_only (decl);
+ tree ctype = DECL_CONTEXT (decl);
+ import_export_class (ctype);
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+ {
+ DECL_NOT_REALLY_EXTERN (decl)
+ = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
+ || (DECL_DECLARED_INLINE_P (decl)
+ && ! flag_implement_inlines
+ && !DECL_VINDEX (decl)));
+
+ /* Always make artificials weak. */
+ if (DECL_ARTIFICIAL (decl) && flag_weak)
+ comdat_linkage (decl);
+ else
+ maybe_make_one_only (decl);
+ }
}
else
comdat_linkage (decl);
}
- else if (DECL_TINFO_FN_P (decl))
+ else if (tinfo_decl_p (decl, 0))
{
tree ctype = TREE_TYPE (DECL_NAME (decl));
{
DECL_NOT_REALLY_EXTERN (decl)
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
- || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines
+ || (DECL_DECLARED_INLINE_P (decl)
+ && ! flag_implement_inlines
&& !DECL_VINDEX (decl)));
/* Always make artificials weak. */
linker sorts in increasing order. */
MAX_INIT_PRIORITY - initp);
named_section (NULL_TREE, buf, 0);
- assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname),
+ assemble_integer (XEXP (DECL_RTL (fn), 0),
POINTER_SIZE / BITS_PER_UNIT, 1);
}
#endif
my_friendly_assert (initp, 20000629);
guard_cond = get_guard_cond (guard);
}
- /* Under the old ABI, e do initializations only if the GUARD is
- zero, i.e., if we are the first to initialize the variable.
- We do destructions only if the GUARD is one, i.e., if we are
- the last to destroy the variable. */
+ /* If we don't have __cxa_atexit, then we will be running
+ destructors from .fini sections, or their equivalents. So,
+ we need to know how many times we've tried to initialize this
+ object. We do initializations only if the GUARD is zero,
+ i.e., if we are the first to initialize the variable. We do
+ destructions only if the GUARD is one, i.e., if we are the
+ last to destroy the variable. */
else if (initp)
guard_cond
= cp_build_binary_op (EQ_EXPR,
finish_if_stmt_cond (cond, guard_if_stmt);
- /* Under the new ABI, we have not already set the GUARD, so we must
- do so now. */
- if (guard && initp)
+ /* If we're using __cxa_atexit, we have not already set the GUARD,
+ so we must do so now. */
+ if (guard && initp && flag_use_cxa_atexit)
finish_expr_stmt (set_guard (guard));
return guard_if_stmt;
}
}
- /* Mark all functions that might deal with exception-handling as
- referenced. */
- mark_all_runtime_matches ();
-
/* We lie to the back-end, pretending that some functions are
not defined when they really are. This keeps these functions
from being put out unnecessarily. But, we must stop lying
/* The entire file is now complete. If requested, dump everything
to a file. */
- if (flag_dump_translation_unit)
- dump_node_to_file (global_namespace, flag_dump_translation_unit);
+ {
+ int flags;
+ FILE *stream = dump_begin (TDI_all, &flags);
+ if (stream)
+ {
+ dump_node (global_namespace, flags & ~TDF_SLIM, stream);
+ dump_end (TDI_all, stream);
+ }
+ }
+
/* If there's some tool that wants to examine the entire translation
unit, let it do so now. */
if (back_end_hook)
finish_decl_parsing (decl)
tree decl;
{
- extern int current_class_depth;
-
switch (TREE_CODE (decl))
{
case IDENTIFIER_NODE:
if (!old)
/* No old declaration at all. */
goto complain;
+ /* A template can be explicitly specialized in any namespace. */
+ if (processing_explicit_instantiation)
+ return;
if (!is_overloaded_fn (decl))
/* Don't compare non-function decls with decls_match here,
since it can't check for the correct constness at this
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == fake_std_node)
{
- if (namespace_bindings_p ()
- && current_namespace == global_namespace)
- /* There's no need for a using declaration at all, here,
- since `std' is the same as `::'. We can't just pass this
- on because we'll complain later about declaring something
- in the same scope as a using declaration with the same
- name. We return NULL_TREE which indicates to the caller
- that there's no need to do any further processing. */
- return NULL_TREE;
-
*scope = global_namespace;
*name = TREE_OPERAND (decl, 1);
}
A using-declaration for a class member shall be a
member-declaration. */
- if (TREE_CODE (*scope) != NAMESPACE_DECL)
+ if (!processing_template_decl
+ && TREE_CODE (*scope) != NAMESPACE_DECL)
{
if (TYPE_P (*scope))
cp_error ("`%T' is not a namespace", *scope);
{
tree old_fn = OVL_CURRENT (tmp1);
- if (!OVL_USED (tmp1)
- && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ if (new_fn == old_fn)
+ /* The function already exists in the current namespace. */
+ break;
+ else if (OVL_USED (tmp1))
+ continue; /* this is a using decl */
+ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
{
- if (!(DECL_EXTERN_C_P (new_fn)
- && DECL_EXTERN_C_P (old_fn)))
- /* There was already a non-using declaration in
- this scope with the same parameter types. */
- cp_error ("`%D' is already declared in this scope",
- name);
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. If both
+ are the same extern "C" functions, that's ok. */
+ if (!decls_match (new_fn, old_fn))
+ cp_error ("`%D' is already declared in this scope", name);
break;
}
- else if (duplicate_decls (new_fn, old_fn))
- /* We're re-using something we already used
- before. We don't need to add it again. */
- break;
}
/* If we broke out of the loop, there's no reason to add
if (decl == NULL_TREE)
return;
+ if (building_stmt_tree ()
+ && at_function_scope_p ())
+ add_decl_stmt (decl);
+
oldval = lookup_name_current_level (name);
oldtype = lookup_type_current_level (name);
{
if (namespace == fake_std_node)
return;
+ if (building_stmt_tree ())
+ add_stmt (build_stmt (USING_STMT, namespace));
+
/* using namespace A::B::C; */
if (TREE_CODE (namespace) == SCOPE_REF)
namespace = TREE_OPERAND (namespace, 1);
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
{
/* Lookup in lexer did not find a namespace. */
- cp_error ("namespace `%T' undeclared", namespace);
+ if (!processing_template_decl)
+ cp_error ("namespace `%T' undeclared", namespace);
return;
}
if (TREE_CODE (namespace) != NAMESPACE_DECL)
{
- cp_error ("`%T' is not a namespace", namespace);
+ if (!processing_template_decl)
+ cp_error ("`%T' is not a namespace", namespace);
return;
}
namespace = ORIGINAL_NAMESPACE (namespace);
void
init_decl2 ()
{
- ggc_add_tree_root (&decl_namespace_list, 1);
ggc_add_tree_varray_root (&deferred_fns, 1);
ggc_add_tree_varray_root (&pending_statics, 1);
ggc_add_tree_varray_root (&ssdf_decls, 1);
ggc_add_tree_root (&ssdf_decl, 1);
ggc_add_tree_root (&priority_decl, 1);
ggc_add_tree_root (&initialize_p_decl, 1);
- ggc_add_tree_root (&pending_vtables, 1);
}