This is an archive of the discontinued LLVM Phabricator instance.

[lldb][NFC] Make ClangExpressionSourceCode's wrapping logic more consistent
ClosedPublic

Authored by teemperor on May 29 2020, 6:13 AM.

Details

Summary

ClangExpressionSourceCode has different ways to wrap the user expression based on
which context the expression is executed in. For example, if we're in a C++ member
function we put the expression inside a fake member function of a fake class to make the
evaluation possible. Similar things are done for Objective-C instance/static methods.
There is also a default wrapping where we put the expression in a normal function
just to make it possible to execute it.

The way we currently define which kind of wrapping the expression needs is based on
the wrapping_language we keep passing to the ClangExpressionSourceCode
instance. We repurposed the language type enum for that variable to distinguish the
cases above with the following mapping:

  • language = C_plus_plus -> member function wrapping
  • language = ObjC -> instance/static method wrapping (is_static distinguished between those two).
  • language = C -> normal function wrapping
  • all other cases like C_plus_plus11, Haskell etc. make our class a no-op that does mostly nothing.

That mapping is currently not documented and just confusing as the language
is unrelated to the expression language (and in the ClangUserExpression we even pretend
that it *is* the actual language, but luckily never used it for anything). Some of the code
in ClangExpressionSourceCode is also obviously thinking that this is the actual language of
the expression as it checks for non-existent cases such as ObjC_plus_plus which is
not part of the mapping.

This patch makes a new enum to describe the four cases above (with instance/static Objective-C
methods now being their own case). It also make that enum just a member of
ClangExpressionSourceCode instead of having to pass the same value to the class repeatedly.
This gets also rid of all the switch-case-checks for 'unknown' language such as C_plus_plus11 as this
is no longer necessary.

Diff Detail

Event Timeline

teemperor created this revision.May 29 2020, 6:13 AM
labath accepted this revision.May 31 2020, 11:41 PM

Makes sense to me.

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
33–40

If I understand the code correctly, a c++ static member function is wrapped using the "function" approach. I think this is potentially confusing, so it would be good if the comments elaborated on it more (e.g. add "non-static" to the CppMemberFunction description, and explicitly mention static member functions in the "function" description).

This revision is now accepted and ready to land.May 31 2020, 11:41 PM
teemperor updated this revision to Diff 267583.Jun 1 2020, 4:24 AM
  • Clarified that 'Function' is also used for static member functions.
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJun 1 2020, 4:46 AM
shafik added a subscriber: shafik.Jun 1 2020, 6:40 PM
shafik added inline comments.
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
33–40

It might be worth adding that we don't need to find the this for the C++ case unlike a non-static member function. This happens in LookUpLldbClass

shafik added inline comments.Jun 1 2020, 6:52 PM
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
41

I would actually feel better have a separate enumerator for C++ static member functions and just having it fall-through when used. It would be self-documenting.

labath added inline comments.Jun 2 2020, 1:20 AM
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
41

If it doesn't complicate the callers (i.e., they always know, or can easily find out, whether they are dealing with a static member or a non-member), I think that would be great.