* cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Apr 2001 22:49:48 +0000 (22:49 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Apr 2001 22:49:48 +0000 (22:49 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41430 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/lex.c
gcc/cp/mangle.c
gcc/cp/semantics.c
gcc/testsuite/g++.old-deja/g++.other/linkage7.C [new file with mode: 0644]

index 37f3227..8d84a8b 100644 (file)
@@ -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
index a30623a..b1359a1 100644 (file)
@@ -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)
index fb6b8a3..b72cf4f 100644 (file)
@@ -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);
index f8524cb..42df4e7 100644 (file)
@@ -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)
     {
index 5120f20..cb6a4d9 100644 (file)
@@ -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
index 18f99a1..7b6857d 100644 (file)
@@ -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
     {
index 87dd778..2141e5c 100644 (file)
@@ -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 (file)
index 0000000..207a632
--- /dev/null
@@ -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 (); }