This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++: "unqualified" linkage
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++: "unqualified" linkage
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Sun, 16 Jan 2000 01:54:46 +0100
This patch implements a feature that was requested from the libstdc++
v3 people a long time ago. It adds a new language linkage
"unqualified". The primary application is in cases like
namespace std{
extern "unqualified"{
struct timeval{};
}
}
using std::timeval;
void gettime(timeval& x)
{
}
If std:: is honored, the mangling of gettime would normally change if
the old-style header file is included instead of the C++ conforming
one. See docs/17_intro/DESIGN of libstdc++ v3 for more discussion.
In this patch, "unqualified" linkage is the same as "C" linkage, with
the additional meaning that "unqualified" names used in mangling of
"C++" names are mangled without qualifiers. As a result, gettime is
mangled as gettime__FR7timeval, instead of gettime__FRQ23std7timeval.
Any comments appreciated.
Regards,
Martin
2000-01-16 Martin v. Löwis <loewis@informatik.hu-berlin.de>
* cp-tree.h (lang_name_like_p, lang_like_c_p): New definitions.
(lang_name_unqualified): New definition.
(cp_tree_index): New value CPTI_LANG_NAME_UNQUALIFIED.
(languages): New value lang_unqualified.
* decl2.c (reparse_absdcl_as_casts): Use lang_name_like_c_p.
* pt.c (check_explicit_specialization): Likewise..
(push_template_decl_real): Likewise.
* class.c (push_lang_context): Likewise..
(pop_lang_context): Likewise.
* decl.c (pop_from_top_level): Likewise.
(grokvardecl): Likewise.
(decls_match): Use lang_like_c_p.
(decls_match): Likewise.
(duplicate_decls): Likewise.
(pushdecl): Likewise.
(grokfndecl): Likewise.
(init_decl_processing): Initialize lang_name_unqualified.
* method.c (build_overload_nested_name): Do not emit context if
inside lang_name_unqualified.
(build_qualified_name): Do not emit 'Q' prefix in this case.
* lex.c (retrofit_lang_decl): Set DECL_LANGUAGE to
lang_unqualified if appropriate.
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.232
diff -u -p -r1.232 class.c
--- class.c 2000/01/13 00:35:38 1.232
+++ class.c 2000/01/16 00:19:04
@@ -5345,7 +5345,7 @@ push_lang_context (name)
DECL_IGNORED_P (java_char_type_node) = 0;
DECL_IGNORED_P (java_boolean_type_node) = 0;
}
- else if (name == lang_name_c)
+ else if (lang_name_like_c_p (name))
{
strict_prototype = strict_prototypes_lang_c;
current_lang_name = name;
@@ -5366,7 +5366,7 @@ pop_lang_context ()
if (current_lang_name == lang_name_cplusplus
|| current_lang_name == lang_name_java)
strict_prototype = strict_prototypes_lang_cplusplus;
- else if (current_lang_name == lang_name_c)
+ else if (lang_name_like_c_p (current_lang_name))
strict_prototype = strict_prototypes_lang_c;
}
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.383
diff -u -p -r1.383 cp-tree.h
--- cp-tree.h 2000/01/12 23:27:43 1.383
+++ cp-tree.h 2000/01/16 00:19:10
@@ -490,6 +490,7 @@ enum cp_tree_index
CPTI_LANG_NAME_C,
CPTI_LANG_NAME_CPLUSPLUS,
CPTI_LANG_NAME_JAVA,
+ CPTI_LANG_NAME_UNQUALIFIED,
CPTI_EMPTY_EXCEPT_SPEC,
CPTI_NULL,
@@ -571,6 +572,7 @@ extern tree cp_global_trees[CPTI_MAX];
#define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER]
#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C]
+#define lang_name_unqualified cp_global_trees[CPTI_LANG_NAME_UNQUALIFIED]
#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS]
#define lang_name_java cp_global_trees[CPTI_LANG_NAME_JAVA]
@@ -837,6 +839,16 @@ struct language_function
#define doing_semantic_analysis_p() (!expanding_p)
+/* Non-zero if the name is either "C" or "unqualified". */
+
+#define lang_name_like_c_p(name) \
+ ((name) == lang_name_c || (name) == lang_name_unqualified)
+
+/* Non-zero if the language is either "C" or "unqualified". */
+
+#define lang_like_c_p(lang) \
+ ((lang) == lang_c || (lang) == lang_unqualified)
+
/* Non-zero if we should treat statements as full expressions. In
particular, this variable is no-zero if at the end of a statement
we should destroy any temporaries created during that statement.
@@ -1066,7 +1078,7 @@ enum cplus_tree_code {
};
#undef DEFTREECODE
-enum languages { lang_c, lang_cplusplus, lang_java };
+enum languages { lang_c, lang_cplusplus, lang_java, lang_unqualified };
/* Macros to make error reporting functions' lives easier. */
#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE)))
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.531
diff -u -p -r1.531 decl.c
--- decl.c 2000/01/13 02:04:25 1.531
+++ decl.c 2000/01/16 00:19:25
@@ -2424,7 +2424,7 @@ pop_from_top_level ()
if (current_lang_name == lang_name_cplusplus)
strict_prototype = strict_prototypes_lang_cplusplus;
- else if (current_lang_name == lang_name_c)
+ else if (lang_name_like_c_p (current_lang_name))
strict_prototype = strict_prototypes_lang_c;
/* If we were in the middle of compiling a function, restore our
@@ -2797,8 +2797,8 @@ decls_match (newdecl, olddecl)
tree p2 = TYPE_ARG_TYPES (f2);
if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)
- && ! (DECL_LANGUAGE (newdecl) == lang_c
- && DECL_LANGUAGE (olddecl) == lang_c))
+ && ! (lang_like_c_p (DECL_LANGUAGE (newdecl))
+ && lang_like_c_p (DECL_LANGUAGE (olddecl))))
return 0;
/* When we parse a static member function definition,
@@ -2826,15 +2826,18 @@ decls_match (newdecl, olddecl)
if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
{
- if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c
+ if (! strict_prototypes_lang_c
+ && lang_like_c_p (DECL_LANGUAGE (olddecl))
&& p2 == NULL_TREE)
{
types_match = self_promoting_args_p (p1);
if (p1 == void_list_node)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
- else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c
- && DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE)
+ else if (!strict_prototypes_lang_c
+ && lang_like_c_p (DECL_LANGUAGE (olddecl))
+ && lang_like_c_p (DECL_LANGUAGE (newdecl))
+ && p1 == NULL_TREE)
{
types_match = self_promoting_args_p (p2);
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
@@ -2983,8 +2986,8 @@ duplicate_decls (newdecl, olddecl)
}
else if (!types_match)
{
- if ((DECL_LANGUAGE (newdecl) == lang_c
- && DECL_LANGUAGE (olddecl) == lang_c)
+ if ((lang_like_c_p (DECL_LANGUAGE (newdecl))
+ && lang_like_c_p (DECL_LANGUAGE (olddecl)))
|| compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
{
@@ -3092,8 +3095,8 @@ duplicate_decls (newdecl, olddecl)
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
- if (DECL_LANGUAGE (newdecl) == lang_c
- && DECL_LANGUAGE (olddecl) == lang_c)
+ if (lang_like_c_p (DECL_LANGUAGE (newdecl))
+ && lang_like_c_p (DECL_LANGUAGE (olddecl)))
{
cp_error ("declaration of C function `%#D' conflicts with",
newdecl);
@@ -3694,7 +3697,8 @@ pushdecl (x)
if (duplicate_decls (x, t))
return t;
}
- else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
+ else if (((TREE_CODE (x) == FUNCTION_DECL
+ && lang_like_c_p (DECL_LANGUAGE (x)))
|| DECL_FUNCTION_TEMPLATE_P (x))
&& is_overloaded_fn (t))
/* Don't do anything just yet. */;
@@ -3874,7 +3878,7 @@ pushdecl (x)
an `extern "C"' function, the mangled name and the
ordinary name are the same so we need not do this. */
&& !(TREE_CODE (x) == FUNCTION_DECL &&
- DECL_LANGUAGE (x) == lang_c))
+ lang_like_c_p (DECL_LANGUAGE (x))))
{
if (TREE_CODE (x) == FUNCTION_DECL)
my_friendly_assert
@@ -5960,6 +5964,7 @@ init_decl_processing ()
lang_name_cplusplus = get_identifier ("C++");
lang_name_c = get_identifier ("C");
lang_name_java = get_identifier ("Java");
+ lang_name_unqualified = get_identifier ("unqualified");
/* Let the back-end now how to save and restore language-specific
per-function globals. */
@@ -8463,7 +8468,7 @@ grokfndecl (ctype, type, declarator, ori
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
{
- if (DECL_LANGUAGE (decl) == lang_c)
+ if (lang_like_c_p (DECL_LANGUAGE (decl)))
/* Allow this; it's pretty common in C. */;
else
cp_pedwarn ("non-local function `%#D' uses anonymous type",
@@ -8554,7 +8559,7 @@ grokfndecl (ctype, type, declarator, ori
/* Plain overloading: will not be grok'd by grokclassfn. */
if (! ctype && ! processing_template_decl
- && DECL_LANGUAGE (decl) != lang_c
+ && ! lang_like_c_p (DECL_LANGUAGE (decl))
&& (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
set_mangled_name_for_decl (decl);
@@ -8710,7 +8715,7 @@ grokvardecl (type, declarator, specbits_
set_decl_namespace (decl, context, 0);
context = DECL_CONTEXT (decl);
- if (declarator && context && current_lang_name != lang_name_c)
+ if (declarator && context && ! lang_name_like_c_p (current_lang_name))
DECL_ASSEMBLER_NAME (decl) = build_static_name (context, declarator);
}
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.295
diff -u -p -r1.295 decl2.c
--- decl2.c 2000/01/14 11:51:14 1.295
+++ decl2.c 2000/01/16 00:19:31
@@ -3702,7 +3702,7 @@ reparse_absdcl_as_casts (decl, expr)
}
if (warn_old_style_cast && ! in_system_header
- && current_lang_name != lang_name_c)
+ && !lang_name_like_c_p (current_lang_name))
warning ("use of old-style cast");
return expr;
Index: lex.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/lex.c,v
retrieving revision 1.173
diff -u -p -r1.173 lex.c
--- lex.c 2000/01/12 05:22:42 1.173
+++ lex.c 2000/01/16 00:19:35
@@ -4735,6 +4735,8 @@ retrofit_lang_decl (t)
DECL_LANGUAGE (t) = lang_cplusplus;
else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c;
+ else if (current_lang_name == lang_name_unqualified)
+ DECL_LANGUAGE (t) = lang_unqualified;
else if (current_lang_name == lang_name_java)
DECL_LANGUAGE (t) = lang_java;
else my_friendly_abort (64);
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.131
diff -u -p -r1.131 method.c
--- method.c 2000/01/14 23:42:10 1.131
+++ method.c 2000/01/16 00:19:38
@@ -435,21 +435,23 @@ build_overload_nested_name (decl)
context = CP_DECL_CONTEXT (decl);
- /* try to issue a K type, and if we can't continue the normal path */
- if (!(ktypelist && issue_ktype (context)))
- {
- /* For a template type parameter, we want to output an 'Xn'
- rather than 'T' or some such. */
- if (TREE_CODE (context) == TEMPLATE_TYPE_PARM
- || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM)
- build_mangled_name_for_type (context);
- else
- {
- if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
- context = TYPE_NAME (context);
- build_overload_nested_name (context);
- }
- }
+ /* If we are inside extern "unqualifed", ignore any context. */
+ if (current_lang_name != lang_name_unqualified)
+ /* try to issue a K type, and if we can't continue the normal path */
+ if (!(ktypelist && context && issue_ktype (context)))
+ {
+ /* For a template type parameter, we want to output an 'Xn'
+ rather than 'T' or some such. */
+ if (TREE_CODE (context) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM)
+ build_mangled_name_for_type (context);
+ else
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
+ context = TYPE_NAME (context);
+ build_overload_nested_name (context);
+ }
+ }
if (TREE_CODE (decl) == FUNCTION_DECL)
{
@@ -1068,7 +1070,9 @@ build_qualified_name (decl)
}
}
- if (i > 1)
+ /* If we are inside extern "unqualified", don't put qualified names
+ out there. */
+ if (i > 1 && current_lang_name != lang_name_unqualified)
{
OB_PUTC ('Q');
build_underscore_int (i);
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.392
diff -u -p -r1.392 pt.c
--- pt.c 2000/01/14 05:45:52 1.392
+++ pt.c 2000/01/16 00:19:47
@@ -1288,7 +1288,7 @@ check_explicit_specialization (declarato
("default argument specified in explicit specialization");
break;
}
- if (current_lang_name == lang_name_c)
+ if (lang_name_like_c_p (current_lang_name))
cp_error ("template specialization with C linkage");
}
@@ -2369,7 +2369,7 @@ push_template_decl_real (decl, is_friend
if (primary)
{
- if (current_lang_name == lang_name_c)
+ if (lang_name_like_c_p (current_lang_name))
cp_error ("template with C linkage");
else if (TREE_CODE (decl) == TYPE_DECL
&& ANON_AGGRNAME_P (DECL_NAME (decl)))