Page MenuHomePhabricator

Ignore generated @import statements in the expression evaluator to fix import-std-module tests on macOS
Needs ReviewPublic

Authored by teemperor on May 5 2019, 4:55 AM.

Details

Summary

The ClangModulesDeclVendor is currently interpreting all injected @import statements in our expression
wrapper as modules that the user has explicitly requested to be persistently loaded. As we inject
@import statements with our std module prototype, the ClangModulesDeclVendor will start compiling
and loading unrelated C++ modules because it thinks the user has requested that it should load them. As
the ClangModulesDeclVendor is lacking the setup to compile these modules (e.g. it lacks the include paths),
it will then actually just fail to compile them and cause the whole expression evaluation to fail. This causes
these tests to fail on systems that enable the ClangModulesDeclVendor (such as macOS).

This patch fixes this by preventing the ClangModulesDeclVendor from interpreting @import statements
in the wrapper source code. This is done by defining a macro directly before the actual user expression and
letting the preprocessor callbacks ignore import statements until we hit that macro.

This patch also enables most of the import-std-module/ tests to make sure this patch is working as
intended. I didn't enable the sysroot test here as it still fails (due to another issue which will be a separate patch).

Diff Detail

Event Timeline

teemperor created this revision.May 5 2019, 4:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 5 2019, 4:55 AM

A slightly more elegant solution might be to inject a #line directive that changes to a different source file for the code that the user entered. I've been long wanting to make expr -g more palatable to end users by hiding the LLDB-injected code in a separate source file by default. If that turns out to be too much work, feel free to land this version.

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
111

///

141

Just to make sure I'm understanding:

expr @import Foo will still work, but it will import Foo into the expression rather than into the context from which we ASTImport definitions?

To clarify:

I'd like expr -g to write out one temporary file (lldb-expr.mm) that only contains the code the user typed and in the expression. The expression should say

@implementation $__lldb_objc_class ($__lldb_category) 
+(void)%s:(void *)$__lldb_arg {
#line "/tmp/lldb-expr.mm" 1
  blah();
#line "/tmp/hidden.mm" 8
}

and then we set a breakpoint at /tmp/lldb-expr.mm:1.