diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-05 15:40:16 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-05 15:40:16 +0000 |
commit | 5712a9a8be00c5e816ee23b091ea17b0ae42cbce (patch) | |
tree | ef62790acadc736fc75d7819646fb6e91db5dda7 /gcc | |
parent | f4a8fff406a4d226cfdf0d2dd19563e00041a46c (diff) | |
download | ppe42-gcc-5712a9a8be00c5e816ee23b091ea17b0ae42cbce.tar.gz ppe42-gcc-5712a9a8be00c5e816ee23b091ea17b0ae42cbce.zip |
PR c++/19159
* decl2.c (import_export_decl): Use non-COMDAT external linkage
for virtual tables, typeinfo, etc. that will be emitted in only
one translation unit on systems without weak symbols.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97635 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 49 |
2 files changed, 42 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac3c3bcdb99..a2747146878 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-04-05 Mark Mitchell <mark@codesourcery.com> + + PR c++/19159 + * decl2.c (import_export_decl): Use non-COMDAT external linkage + for virtual tables, typeinfo, etc. that will be emitted in only + one translation unit on systems without weak symbols. + 2005-04-04 Mark Mitchell <mark@codesourcery.com> PR c++/20679 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 16c4efe76a2..4a2659b3f21 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1780,29 +1780,43 @@ import_export_decl (tree decl) else if (CLASSTYPE_INTERFACE_KNOWN (type) && CLASSTYPE_INTERFACE_ONLY (type)) import_p = true; - else if (TARGET_WEAK_NOT_IN_ARCHIVE_TOC + else if ((!flag_weak || TARGET_WEAK_NOT_IN_ARCHIVE_TOC) && !CLASSTYPE_USE_TEMPLATE (type) && CLASSTYPE_KEY_METHOD (type) && !DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type))) /* The ABI requires that all virtual tables be emitted with COMDAT linkage. However, on systems where COMDAT symbols don't show up in the table of contents for a static - archive, the linker will report errors about undefined - symbols because it will not see the virtual table - definition. Therefore, in the case that we know that the - virtual table will be emitted in only one translation - unit, we make the virtual table an ordinary definition - with external linkage. */ + archive, or on systems without weak symbols (where we + approximate COMDAT linkage by using internal linkage), the + linker will report errors about undefined symbols because + it will not see the virtual table definition. Therefore, + in the case that we know that the virtual table will be + emitted in only one translation unit, we make the virtual + table an ordinary definition with external linkage. */ DECL_EXTERNAL (decl) = 0; else if (CLASSTYPE_INTERFACE_KNOWN (type)) { /* TYPE is being exported from this translation unit, so DECL - should be defined here. The ABI requires COMDAT - linkage. Normally, we only emit COMDAT things when they - are needed; make sure that we realize that this entity is - indeed needed. */ - comdat_p = true; - mark_needed (decl); + should be defined here. */ + if (!flag_weak && CLASSTYPE_EXPLICIT_INSTANTIATION (type)) + /* If a class is declared in a header with the "extern + template" extension, then it will not be instantiated, + even in translation units that would normally require + it. Often such classes are explicitly instantiated in + one translation unit. Therefore, the explicit + instantiation must be made visible to other translation + units. */ + DECL_EXTERNAL (decl) = 0; + else + { + /* The ABI requires COMDAT linkage. Normally, we only + emit COMDAT things when they are needed; make sure + that we realize that this entity is indeed + needed. */ + comdat_p = true; + mark_needed (decl); + } } else if (!flag_implicit_templates && CLASSTYPE_IMPLICIT_INSTANTIATION (type)) @@ -1830,7 +1844,14 @@ import_export_decl (tree decl) comdat_p = true; if (CLASSTYPE_INTERFACE_KNOWN (type) && !CLASSTYPE_INTERFACE_ONLY (type)) - mark_needed (decl); + { + mark_needed (decl); + if (!flag_weak) + { + comdat_p = false; + DECL_EXTERNAL (decl) = 0; + } + } } } else |