|
| 1 | +# Adding Programming Language Support |
| 2 | + |
| 3 | +LLDB has been architected to make it straightforward to add support for a |
| 4 | +programming language. Only a small enum in core LLDB needs to be modified to |
| 5 | +make LLDB aware of a new programming language. Everything else can be supplied |
| 6 | +in derived classes that need not even be present in the core LLDB repository. |
| 7 | +This makes it convenient for developers adding language support in downstream |
| 8 | +repositories since it practically eliminates the potential for merge conflicts. |
| 9 | + |
| 10 | +The basic steps are: |
| 11 | +* Add the language to the `LanguageType` enum. |
| 12 | +* Add a `TypeSystem` for the language. |
| 13 | +* Add expression evaluation support. |
| 14 | + |
| 15 | +Additionally, you may want to create a `Language` and `LanguageRuntime` plugin |
| 16 | +for your language, which enables support for advanced features like dynamic |
| 17 | +typing and data formatting. |
| 18 | + |
| 19 | +## Add the Language to the LanguageType enum |
| 20 | + |
| 21 | +The `LanguageType` enum |
| 22 | +(see [lldb-enumerations.h](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/lldb-enumerations.h)) |
| 23 | +contains a list of every language known to LLDB. It is the one place where |
| 24 | +support for a language must live that will need to merge cleanly with upstream |
| 25 | +LLDB if you are developing your language support in a separate branch. When |
| 26 | +adding support for a language previously unknown to LLDB, start by adding an |
| 27 | +enumeration entry to `LanguageType`. |
| 28 | + |
| 29 | +## Add a TypeSystem for the Language |
| 30 | + |
| 31 | +Both [Module](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Core/Module.h) |
| 32 | +and [Target](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Target/Target.h) |
| 33 | +support the retrieval of a `TypeSystem` instance via `GetTypeSystemForLanguage()`. |
| 34 | +For `Module`, this method is directly on the `Module` instance. For `Target`, |
| 35 | +this is retrieved indirectly via the `TypeSystemMap` for the `Target` instance. |
| 36 | + |
| 37 | +The `TypeSystem` instance returned by the `Target` is expected to be capable of |
| 38 | +evaluating expressions, while the `TypeSystem` instance returned by the `Module` |
| 39 | +is not. If you want to support expression evaluation for your language, you could |
| 40 | +consider one of the following approaches: |
| 41 | +* Implement a single `TypeSystem` class that supports evaluation when given an |
| 42 | + optional `Target`, implementing all the expression evaluation methods on the |
| 43 | + `TypeSystem`. |
| 44 | +* Create multiple `TypeSystem` classes, one for evaluation and one for static |
| 45 | + `Module` usage. |
| 46 | + |
| 47 | +For clang and Swift, the latter approach was chosen. Primarily to make it |
| 48 | +clearer that evaluation with the static `Module`-returned `TypeSystem` instances |
| 49 | +make no sense, and have them error out on those calls. But either approach is |
| 50 | +fine. |
| 51 | + |
| 52 | +# Creating Types |
| 53 | + |
| 54 | +Your `TypeSystem` will need an approach for creating types based on a set of |
| 55 | +`Module`s. If your type info is going to come from DWARF info, you will want to |
| 56 | +subclass [DWARFASTParser](https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h). |
| 57 | + |
| 58 | + |
| 59 | +# Add Expression Evaluation Support |
| 60 | + |
| 61 | +Expression Evaluation support is enabled by implementing the relevant methods on |
| 62 | +a `TypeSystem`-derived class. Search for `Expression` in the |
| 63 | +[TypeSystem header](https://github.com/llvm/llvm-project/blob/main/lldb/include/lldb/Symbol/TypeSystem.h) |
| 64 | +to find the methods to implement. |
| 65 | + |
| 66 | +# Type Completion |
| 67 | + |
| 68 | +There are three levels of type completion, each requiring more type information: |
| 69 | +1. Pointer size: When you have a forward decl or a reference, and that's all you |
| 70 | + need. At this stage, the pointer size is all you need. |
| 71 | +2. Layout info: You need the size of an instance of the type, but you still don't |
| 72 | + need to know all the guts of the type. |
| 73 | +3. Full type info: Here you need everything, because you're playing with |
| 74 | + internals of it, such as modifying a member variable. |
| 75 | + |
| 76 | +Ensure you never complete more of a type than is needed for a given situation. |
| 77 | +This will keep your type system from doing more work than necessary. |
| 78 | + |
| 79 | +# Language and LanguageRuntime Plugins |
| 80 | + |
| 81 | +If you followed the steps outlined above, you already have taught LLDB a great |
| 82 | +deal about your language. If your language's runtime model and fundamental data |
| 83 | +types don't differ much from the C model, you are pretty much done. |
| 84 | + |
| 85 | +However it is likely that your language offers its own data types for things |
| 86 | +like strings and arrays, and probably has a notion of dynamic types, where the |
| 87 | +effective type of a variable can only be known at runtime. |
| 88 | + |
| 89 | +These tasks are covered by two plugins: |
| 90 | +* a `LanguageRuntime` plugin, which provides LLDB with a dynamic view of your |
| 91 | + language; this plugin answers questions that require a live process to acquire |
| 92 | + information (for example dynamic type resolution). |
| 93 | +* a `Language` plugin, which provides LLDB with a static view of your language; |
| 94 | + questions that are statically knowable and do not require a process are |
| 95 | + answered by this plugin (for example data formatters). |
0 commit comments