LLDB is currently always activating C++ when parsing expressions as LLDB itself is using C++ features
when creating the final AST that will be codegen'd (specifically, references to variables, namespaces
and using declarations are used).
This is causing problems for users that have variables in non-C++ programs (e.g. plain C or Objective-C)
that have names which are keywords in C++. Expressions referencing those variables fail to parse
as LLDB's Clang parser thinks those identifiers are C++ keywords and not identifiers that may belong
to a declaration.
We can't just disable C++ in the expression parser for those situations as replacing the functionality of the
injected C++ code isn't trivial. So this patch is just disabling most keywords that are exclusive to C++ in
LLDB's Clang parser when we are in a non-C++ expression. There are a few keywords we can't disable for now:
- using as that's currently used in some situations to inject variables into the expression function.
- __null as that's used by LLDB to define NULL/Nil/nil.
Getting rid of these last two keywords is possible but is a large enough change that this will be handled in
follow up patches.
Note that this only changes the keyword status of those tokens but this patch does not remove any C++
functionality from the expression parser. The type system still follows C++ rules and so does the rest
of the expression parser.
There is another small change that gives the hardcoded macro definitions in LLDB a higher precedence
than the macros imported from the Objective-C modules. The reason for this is that the Objective-C
modules in LLDB are actually parsed in Objective-C++ mode and they end up providing the C++ definitions
of certain system macros (like NULL being defined as nullptr). So we have to move the LLDB definition
forward and surround the definition from the module with an #ifdef to make sure that we use the correct
LLDB definition that doesn't reference C++ keywords. Or to give an example, this is how the expression
source code changes:
Before:
#define NULL (nullptr) // injected module definition #ifndef NULL #define NULL (__null) // hardcoded LLDB definition #endif
After:
#ifndef NULL #define NULL (__null) // hardcoded LLDB definition #endif #ifndef NULL #define NULL (nullptr) // injected module definition #endif
Fixes rdar://10356912
I was looking at isCPlusPlusKeyword() and C++14 nor C++17 added any keywords. If note that function does use either of those.
I was also wondering, b/c it was not obvious after looking at this for a bit, if shared keywords like 'register' (although that is deprecated) also get clobbered.