+2001-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
+ set.
+ (SET_DECL_LANGUAGE): New macro.
+ * decl.c (duplicate_decls): Use SET_DECL_LANGUAGE.
+ (pushdecl): Likewise.
+ (build_library_fn_1): Likewise.
+ (build_cp_library_fn): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Mark `extern "C"' variables as having C linkage.
+ * decl2.c (grokclassfn): Use SET_DECL_LANGUAGE.
+ * lex.c (retrofit_lang_decl): Likewise.
+ * mangle.c (mangle_decl_string): Don't mangle the names of
+ variables declared with C language linkage.
+ * semantics.c (finish_member_declaration): Use SET_DECL_LANGUAGE.
+
2001-04-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
* semantics.c (simplify_aggr_init_exprs_r): Don't restore
#define DECL_IN_MEMORY_P(NODE) \
(DECL_RTL_SET_P (NODE) && GET_CODE (DECL_RTL (NODE)) == MEM)
-/* For FUNCTION_DECLs: return the language in which this decl
- was declared. */
-#define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language)
+/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
+ declaration. Some entities (like a member function in a local
+ class, or a local variable) do not have linkage at all, and this
+ macro should not be used in those cases.
+
+ Implementation note: A FUNCTION_DECL without DECL_LANG_SPECIFIC was
+ created by language-independent code, and has C linkage. Most
+ VAR_DECLs have C++ linkage, and do not have DECL_LANG_SPECIFIC, but
+ we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage. */
+#define DECL_LANGUAGE(NODE) \
+ (DECL_LANG_SPECIFIC (NODE) \
+ ? DECL_LANG_SPECIFIC(NODE)->decl_flags.language \
+ : (TREE_CODE (NODE) == FUNCTION_DECL \
+ ? lang_c : lang_cplusplus))
+
+/* Set the language linkage for NODE to LANGUAGE. */
+#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
+ (DECL_LANG_SPECIFIC (NODE)->decl_flags.language = LANGUAGE)
/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */
#define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr)
/* Make the old declaration consistent with the new one so
that all remnants of the builtin-ness of this function
will be banished. */
- DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
+ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (newdecl),
int foo () { bar (); }
is OK. */
if (current_lang_depth () == 0)
- DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
+ SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
else
{
cp_error_at ("previous declaration of `%#D' with %L linkage",
if (! types_match)
{
- DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
+ SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
COPY_DECL_ASSEMBLER_NAME (newdecl, olddecl);
SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
}
if (new_defines_function)
/* If defining a function declared with other language
linkage, use the previously declared language linkage. */
- DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl);
+ SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
else if (types_match)
{
/* If redeclaring a builtin function, and not a definition,
if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
{
retrofit_lang_decl (x);
- DECL_LANGUAGE (x) = lang_c;
+ SET_DECL_LANGUAGE (x, lang_c);
}
if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
- DECL_LANGUAGE (fn) = lang_c;
+ SET_DECL_LANGUAGE (fn, lang_c);
return fn;
}
tree fn = build_library_fn_1 (name, operator_code, type);
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
- DECL_LANGUAGE (fn) = lang_cplusplus;
+ SET_DECL_LANGUAGE (fn, lang_cplusplus);
set_mangled_name_for_decl (fn);
return fn;
}
&& ctype == NULL_TREE
/* NULL_TREE means global namespace. */
&& DECL_CONTEXT (decl) == NULL_TREE)
- DECL_LANGUAGE (decl) = lang_c;
+ SET_DECL_LANGUAGE (decl, lang_c);
/* Should probably propagate const out from type to decl I bet (mrs). */
if (staticp)
else
context = NULL_TREE;
- if (processing_template_decl && context)
- /* For global variables, declared in a template, we need the
- full lang_decl. */
+ /* For namespace-scope variables, declared in a template, we
+ need the full lang_decl. The same is true for
+ namespace-scope variables that do not have C++ language
+ linkage. */
+ if (context
+ && (processing_template_decl
+ || current_lang_name != lang_name_cplusplus))
decl = build_lang_decl (VAR_DECL, declarator, type);
else
decl = build_decl (VAR_DECL, declarator, type);
/* 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_LANG_SPECIFIC (t) = ld;
if (current_lang_name == lang_name_cplusplus)
- DECL_LANGUAGE (t) = lang_cplusplus;
+ SET_DECL_LANGUAGE (t, lang_cplusplus);
else if (current_lang_name == lang_name_c)
- DECL_LANGUAGE (t) = lang_c;
+ SET_DECL_LANGUAGE (t, lang_c);
else if (current_lang_name == lang_name_java)
- DECL_LANGUAGE (t) = lang_java;
+ SET_DECL_LANGUAGE (t, lang_java);
else my_friendly_abort (64);
#ifdef GATHER_STATISTICS
if (TREE_CODE (decl) == TYPE_DECL)
write_type (TREE_TYPE (decl));
else if (/* The names of `extern "C"' functions are not mangled. */
- (TREE_CODE (decl) == FUNCTION_DECL
+ (DECL_EXTERN_C_FUNCTION_P (decl)
/* But overloaded operator names *are* mangled. */
- && !DECL_OVERLOADED_OPERATOR_P (decl)
- /* If there's no DECL_LANG_SPECIFIC, it's a function built
- by language-independent code, which never builds
- functions with C++ linkage. */
- && (!DECL_LANG_SPECIFIC (decl)
- || DECL_EXTERN_C_FUNCTION_P (decl)))
+ && !DECL_OVERLOADED_OPERATOR_P (decl))
/* The names of global variables aren't mangled either. */
|| (TREE_CODE (decl) == VAR_DECL
- && CP_DECL_CONTEXT (decl) == global_namespace))
+ && CP_DECL_CONTEXT (decl) == global_namespace)
+ /* And neither are `extern "C"' variables. */
+ || (TREE_CODE (decl) == VAR_DECL
+ && DECL_EXTERN_C_P (decl)))
write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
else
{
A C language linkage is ignored for the names of class members
and the member function type of class member functions. */
if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)
- DECL_LANGUAGE (decl) = lang_cplusplus;
+ SET_DECL_LANGUAGE (decl, lang_cplusplus);
/* Put functions on the TYPE_METHODS list and everything else on the
TYPE_FIELDS list. Note that these are built up in reverse order.
--- /dev/null
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+namespace N {
+ extern "C" int i;
+
+ void f () {
+ i = 3;
+ }
+};
+
+int i;
+
+int main () { N::f (); }