aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2001-04-19 22:49:48 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2001-04-19 22:49:48 +0000
commit5d2ed28c27166bc105ec9fe3a9a18af5c1409010 (patch)
treebe41a31f61cfc5955ed9ac031129b966e6b6e950
parent45936a85bc20fdfa776dbd17069c941806b45420 (diff)
downloadgcc-5d2ed28c27166bc105ec9fe3a9a18af5c1409010.zip
gcc-5d2ed28c27166bc105ec9fe3a9a18af5c1409010.tar.gz
gcc-5d2ed28c27166bc105ec9fe3a9a18af5c1409010.tar.bz2
cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is set.
* 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. From-SVN: r41430
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h21
-rw-r--r--gcc/cp/decl.c26
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/lex.c6
-rw-r--r--gcc/cp/mangle.c14
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/linkage7.C14
8 files changed, 75 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 37f3227..8d84a8b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a30623a..b1359a1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1919,9 +1919,24 @@ struct lang_decl
#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)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb6b8a3..b72cf4f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3203,7 +3203,7 @@ duplicate_decls (newdecl, olddecl)
/* 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),
@@ -3362,7 +3362,7 @@ duplicate_decls (newdecl, olddecl)
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",
@@ -3676,7 +3676,7 @@ duplicate_decls (newdecl, olddecl)
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));
}
@@ -3691,7 +3691,7 @@ duplicate_decls (newdecl, olddecl)
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,
@@ -3980,7 +3980,7 @@ pushdecl (x)
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))
@@ -6727,7 +6727,7 @@ build_library_fn_1 (name, operator_code, type)
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;
}
@@ -6754,7 +6754,7 @@ build_cp_library_fn (name, operator_code, type)
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;
}
@@ -8759,7 +8759,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
&& 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)
@@ -9031,9 +9031,13 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace)
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);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index f8524cb..42df4e7 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1008,7 +1008,7 @@ grokclassfn (ctype, function, flags, quals)
/* 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)
{
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 5120f20..cb6a4d9 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -1509,11 +1509,11 @@ retrofit_lang_decl (t)
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
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 18f99a10..7b6857d 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2085,17 +2085,15 @@ mangle_decl_string (decl)
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
{
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 87dd778..2141e5c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1910,7 +1910,7 @@ finish_member_declaration (decl)
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.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage7.C b/gcc/testsuite/g++.old-deja/g++.other/linkage7.C
new file mode 100644
index 0000000..207a632
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/linkage7.C
@@ -0,0 +1,14 @@
+// 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 (); }