about summary refs log tree commit diff
path: root/src/rustllvm/RustWrapper.cpp
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-11 06:26:05 -0700
committerbors <bors@rust-lang.org>2013-09-11 06:26:05 -0700
commit67ed30cd5eab9af1976a994c50d146a3dbeccad4 (patch)
treee626482c9b04d7ed291a4f52e82fcfa87adaad6b /src/rustllvm/RustWrapper.cpp
parentd14bd0879d7357598f4f7f49dae6661559e10745 (diff)
parenteb32ec13f1d870e5b85b03b353b659b59a7481bb (diff)
downloadrust-67ed30cd5eab9af1976a994c50d146a3dbeccad4.tar.gz
rust-67ed30cd5eab9af1976a994c50d146a3dbeccad4.zip
auto merge of #9097 : michaelwoerister/rust/namespaces, r=jdm
Who would have thought that namespaces are such a can of worms `:P` This is mostly because of some GDB idiosyncrasies (does not use namespace information but linkage-name attributes for displaying items contained in namespaces, also cannot handle functions lexically nested within functions), monomorphization, and information about external items only available from metadata.

This pull request tries to tackle the problem anyway:
* The `DW_AT_linkage_name` for functions is generated just to make GDB display a proper namespace-enabled function name. To this end, a pseudo-mangled name is generated, not corresponding to the real linkage name. This approach shows some success and could be extended to make GDB also show proper parameter types.
* As GDB won't accept subprogram DIEs nested within other subprogram DIEs, the `debuginfo` module now generates a *companion namespace* for each functions (iff needed). A function `fn abc()` will get a companion namespace with name `abc()`, which contains all items (modules, types, functions) declared within the functions scope. The real, proper solution, in my opinion, would be to faithfully reflect the program's lexical structure within DWARF (which allows arbitrary nesting of DIEs, afaik), but I am not sure LLVM's source level debugging implementation would like that and I am pretty sure GDB won't support this in the foreseeable future.
* Monomorphization leads to functions and companion namespaces like `somelib::some_func<int, float>()::some_other_function<bool, bool, bool>()`, which I think is the desired behaviour. There is some design space here, however. Maybe you people prefer `somelib::some_func()::some_other_function<bool, bool, bool>()` or `somelib::some_func()::some_other_function::<int, float, bool, bool, bool>()`.

The solution will work for now but there are a few things on my 'far future wish list':
* A real specification somewhere, what language constructs are mapped to what DWARF structures.
* Proper tests that directly compare the generated DWARF information to the expected results (possibly using something like [pyelftools](https://github.com/eliben/pyelftools) or llvm-dwarfdump)
* A unified implementation for crate-local and crate-external items (which would possibly involve beefing up `ast_map::path` and metadata a bit)

Any comments are welcome!

Closes #1541
Closes #1542 (there might be other issues with function name prettiness, but this specific issue should be fixed)
Closes #7715 (source locations for structs and enums are now read correctly from the AST)
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
-rw-r--r--src/rustllvm/RustWrapper.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 226a7c34304..22288a27624 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -727,9 +727,9 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
     LLVMValueRef Scope,
     const char* Name,
     LLVMValueRef Ty,
-    LLVMValueRef File = 0,
-    unsigned LineNo = 0,
-    unsigned ColumnNo = 0)
+    LLVMValueRef File,
+    unsigned LineNo,
+    unsigned ColumnNo)
 {
     return wrap(Builder->createTemplateTypeParameter(
       unwrapDI<DIDescriptor>(Scope),
@@ -775,3 +775,17 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateComplexVariable(
         ArgNo
     ));
 }
+
+extern "C" LLVMValueRef LLVMDIBuilderCreateNameSpace(
+    DIBuilderRef Builder,
+    LLVMValueRef Scope,
+    const char* Name,
+    LLVMValueRef File,
+    unsigned LineNo)
+{
+    return wrap(Builder->createNameSpace(
+        unwrapDI<DIDescriptor>(Scope),
+        Name,
+        unwrapDI<DIFile>(File),
+        LineNo));
+}