This is the mail archive of the dwarf2@corp.sgi.com mailing list for the dwarf2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Rewrite of 991110.1 namespace proposal


$Revision: 1.8 $
$Date: 2000/06/08 17:27:56 $

The following is a rewrite of Jason's proposal.
Jason has reviewed various versions of this
and his corrections and ideas have been incorporated.
Any mistakes are mine...
davea@sgi.com


 991110.1      B     I  J. Merrill   C++   Namespace support

=== BACKGROUND

The C++ feature of 'namespace' was invented after the 1993
dwarf2 specification was completed, so currently dwarf2 has
no means of representing C++ namespace information.

This proposes a way of adding namespace support.

This proposal reflects input from the Feb 22, 2000 meeting.

====  OVERVIEW 
Use a new tag DW_TAG_namespace to represent
a namespace declaration.  DW_TAG_namespace can be nested.

Add to an existing namespace with a
DW_TAG_namespace with a new attribute DW_AT_extension pointing to the
previous extension (the previous
extension might be the base namespace declaration).

Specify a using-directive with a new tag DW_TAG_imported_module,
with a DW_AT_import attribute 
referring to DW_TAG_namespace of the previous extension
of this namespace (which might be the base namespace declaration).

Specify a using-declaration with the 
existing tag DW_TAG_imported_declaration, 
with a DW_AT_import attribute 
referring to the declaration being imported
(that imported declaration cannot, by C++ rules, be
a DW_TAG_namespace, ISO C++1998 7.3.3,3.4.1).

Namespace-aliases use the existing tag DW_TAG_imported_declaration
and DW_TAG_imported_declaration has DW_AT_name to
signify this is a namespace alias, not a using-declaration..
The DW_TAG_imported_declaration has a DW_AT_import referring to the 
DW_TAG_namespace of the extension
of this namespace (which might be the base namespace declaration)
it refers to.

Namespaces also affect .debug_pubnames, so one paragraph
in the pubnames discussion is altered. See below.

General comment:
Because namespace std is ubiquitous
namespace std is a prime candidate for a comdat approach
so as to avoid the otherwise-natural bloat in
duplicating namespace std information in every compilation unit.
Because namespace std is extended by many headers, 
and those headers are not always #included in the same order in
a compilation unit using comdat may be difficult for the
implementation?

There is no mention that duplication/bloat problem below, as
the comdat stuff has not been approved.
But serious bloat could result from this...

===== Document changes, referring to May 5 draft page numbers:

page 6
Figure 1:  add
	DW_TAG_namespace
	DW_TAG_imported_module

page 9:
Figure 2: add
	DW_AT_extension  "refers from namespace extension back to 
                          previous extension
			  or back to base namespace declaration"

Page 103
Figure 15: add
	DW_TAG_namespace  0x39 (or next available value)
	DW_TAG_imported_module 0x40

Page 106
Figure 17: add
	DW_AT_extension 0x52 (or next available value)

Page 127(approx)
Appendix 1, add
	DW_TAG_namespace DECL
			DW_AT_name
			DW_AT_extension
	DW_TAG_imported_module   DECL
			DW_AT_import


For the main discussion, create a new section (5.15 seems
to be the next appropriate number) in the 'type entries'
chapter.

Section 5.15  "Namespaces"

(italics:) 
C++ has the notion of a namespace, which
is a way to implement name hiding, so that
names of unrelated things do not accidentally clash in the
global space when an application is linked together. 

(normal type:)
Namespace entries may contain declarations
and may also
contain declarations which 
are also object or function definitions.

If a type, variable, or function declared
in a namespace is defined outside 
of the  body of the namespace declaration,
the type, variable, or function has a DW_AT_specification
attribute, whose value is a reference to the debugging information
entry representing the declaration of the type, variable or function.  

Types, variables, or functions with a DW_AT_specification
attribute do not need to  duplicate information 
provided by the declaration entry referenced by the
specification attribute.

The tag DW_TAG_namespace is used to represent
a namespace.  A namespace extension is represented
by a DW_TAG_namespace with
a DW_AT_extension attribute referring to the previous
extension (if there is no previous extension, the 
DW_AT_extension refers to the base DW_TAG_namespace declaration).
A namespace extension does not need to duplicate
information in a previous extension of the namespace nor
need it duplicate information in the base DW_TAG_namespace
(so a DW_AT_name attribute need only be attached
directly to the base DW_TAG_namespace, for a namespace with a name).


The tag DW_TAG_imported_declaration 
is used to represent a namespace-alias.
It contains a DW_AT_name giving the alias name.
It contains a DW_AT_import referring to the applicable
namespace extension
(if there is no namespace extension, the
DW_AT_import refers to the base DW_TAG_namespace declaration).
It contains a DW_AT_name giving the alias name.

A using-declaration is represented with
the tag DW_TAG_imported_declaration.
It contains a DW_AT_import attribute
referring to the declaration being imported
It contains no DW_AT_name attribute, distinguishing this
from a namespace-alias.
(italics)
  That imported declaration cannot, by C++ rules, be
  a DW_TAG_namespace, ISO/IEC 14222:1998 7.3.3,3.4.1.

A using-directive is represented with the 
tag DW_TAG_imported_module,
with a DW_AT_import attribute
referring to DW_TAG_namespace of the previous extension
of this namespace (which might be the base namespace declaration).

The global namespace (the namespace referred to by "::f", 
for example) is not explicitly represented in dwarf with
a DW_TAG_namespace (thus mirroring the situation in C++ source).
Global items are simply declared 
with no reference to a namespace, and that is how they should appear
in dwarf.

The compilation-unit-specific "unnamed namespace"
(ISO/IEC 14222:1998 7.3.1.1)
is represented by a DW_TAG_namespace with no DW_AT_name
attribute in the base namespace declaration (and therefore
no DW_AT_name in any namespace extension  of this namespace either).


(italics:)
A compiler emitting namespace
information may choose to explicitly show namespace
extensions, or to simply show the final namespace
declaration of a compilation unit: 
this is a quality-of-implementation issue
and no specific requirements are imposed.
If only the final namespace is shown it is impossible
to interpret using-declaration references in 
exactly the manner defined by the C++ standard: see
ISO/IEC 14222:1998, 7.3.2, paragraph number 9.

(italics:)
A simple emission of all namespace declaration information
in all compilation units could result in a significant
increase in the size of the debug information and
significant duplication of information
across compilation units.
C++ namespace std, for example, is large
and will probably be referred to in 
every C++ compilation unit.

(normal text:)


C++ example:
namespace {
  int i;
}

namespace A {
  namespace B {
    int j;
    int myfunc(int a);
    int myfunc2(int a) { return a +2;}
  }
}

namespace Y {
	using A::B::j; // using declaration
	int foo;
}

using A::B::j;         // using-declaration

namespace Foo = A::B;  // namespace-alias

using namespace Foo;   // using-directive


namespace A {
  namespace B {
    using namespace Y; // using-directive
    int k;
  }
}

int Foo::myfunc(int a)
{
	i = 3;
	j = 4;
	return myfunc2(3) + j +i + a + 2;
}



A representation of the above, offsets represented
only where necessary:

0x0   DW_TAG_basetype
	DW_AT_name "int"
	...
0x6   DW_TAG_namespace
        <no AT_name>
        DW_TAG_variable
          DW_AT_name "i"
	  DW_AT_type  0x0
	  DW_AT_location ...
	  ...


0x10: DW_TAG_namespace
      DW_AT_name "A"
0x20:  DW_TAG_namespace
         DW_AT_name "B"
0x30:     DW_TAG_variable
            DW_AT_name "j"
	    DW_AT_type 0x0
	    DW_AT_location ...
	    ...
0x34:     DW_TAG_subprogram
	    DW_AT_name "myfunc"
	    DW_AT_type   0x0
	    ...
          DW_TAG_subprogram
	    DW_AT_name "myfunc2"
	    DW_AT_low_pc   ...
	    DW_AT_high_pc  ...
	    DW_AT_type   0x0
	    ...
	        

0x40: DW_TAG_namespace
        DW_AT_name "Y"
          DW_TAG_imported_declaration // using-declaration
              DW_AT_import 0x30
	  DW_TAG_variable
            DW_AT_name "foo";
	    DW_AT_type  0x0
	    DW_AT_location ...
	    ...

      DW_TAG_imported_declaration // using-declaration
        DW_AT_import 0x30

      DW_TAG_imported_declaration // namespace alias
	DW_AT_name  "Foo"
        DW_AT_import 0x20

      DW_TAG_imported_module      // using-directive
        DW_AT_import 0x20

      DW_TAG_namespace
        DW_AT_extension 0x10
        DW_TAG_namespace
          DW_AT_extension 0x20
	  DW_TAG_imported_module  // using-directive
	    DW_AT_import 0x40
          DW_TAG_variable
            DW_AT_name "k"
	    DW_AT_type 0x0
	    DW_AT_location ...
	    ...

0x60  DW_TAG_subprogram
	DW_AT_name  "myfunc"
	DW_AT_specification 0x34
	DW_AT_low_pc ...
	DW_AT_high_pc ...
	...

==========section 6.1.1, Lookup By Name

Change the last paragraph to:

In the case of the name of a function member or static data
member of a C++ structure, class, or union, or
of the name of a member of a namespace, the name
represented in the .debug_pubnames section is not the
simple name given by the DW_AT_name attribute of the referenced
debugging entry, but rather the fully namespace-and-class qualified
name of the debugging entry.
Names in an unnamed-namespace declaration never appear
in the .debug_pubnames section as such names are effectively
private to a compilation unit.



===========end

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]