[lldb-dev] Supporting new source languages

Greg Clayton gclayton at apple.com
Thu Jan 16 12:59:42 PST 2014

On Jan 16, 2014, at 12:45 PM, Carlo Kok <ck at remobjects.com> wrote:

> On Thu, 16 Jan 2014 19:34:58 +0100, Greg Clayton <gclayton at apple.com> wrote:
>> To follow up:
>> ClangASTType should really be renamed CompilerType. And then everyone can place their types into this class and all type inspection will just work.
>> Each new language that doesn't use clang for its compiler would need a new expression parser that will need to know how to play with the CompilerType. We will probably need to add accessors to ClangASTType like:
>> bool ClangASTType::IsClangType() const;
>> bool ClangASTType::IsJuliaType() const;
>> bool ClangASTType::IsRustType() const;
>> Then the expression parsers would need to make sure to check any types they find via lookups to make sure the ClangASTType is the correct type.
> Given all of these pretty much use DWARF, and even if they used something like CodeView, it would be the same idea. Wouldn't it make sense for the "caller side" of LLDB to have access to the debug data structures, and remote symbol lists, and build "expressions" from that that lldb turns into IR and runs?
> Not sure if it's feasible to do that but at the moment it seems the clang evaluator works by:
> setting up a dummy .c file with the expression embedded inside it. Compile that to IR with clang for the right triple. JIT that. Transfer it to the "other side", evaluate it, then get back the result.
> Maybe it would be cleaner to have the evaluator be able to explore the dwarf debug info, build a simple expression tree from that, and get back the result?
> Just an idea anyway. I've been trying to see how to fit my (pascal) language into lldb, but due to the way it's designed (the compiler), it's not feasible to compile a single expression/method into IR and transfer it over (Besides that, it's written in another language than c++).

That means creating your own expression parser that won't be language compliant, and is the whole reason we are generating clang AST types from DWARF: to avoid having top write an expression parser when the compiler is the best expression parser we could ever have.

Things we can do in our expression parser that other debuggers can't:
- create expression local variables ("int i = 12; int j = 23; i+j")
- use flow control (if/then/else, while, do/while, switch, etc)
- create types and use them in the expression ("struct foo { int x; float y; }; foo = { 123, 2.3 }; foo")
- much much more!

So the one great thing we can do, is just re-compile clang and we get all the new language features (C++11, etc) for free. If we maintain a separate expression parser that isn't in the compiler, then you do all this work manually. We also use the clang expression parser to avoid running into errors when calling functions as it is very complex to figure out which arguments go where in expressions. When we call a function in the JIT, we give clang a structure in memory that contains all arguments and let it call the function correctly. So there is way too much stuff we would need to re-code, so the hard fight to translate DWARF into compiler types ends up being well worth it on the long run.


More information about the lldb-dev mailing list