Here’s a trivial program. I stop in the main, and try calling foo("hi"). It fails. Apparently it can’t convert a char* to a std::string the way you can in normal C++ code. Is that expected?
#include <iostream>
#include <string>
using namespace std;
void foo(const string &s) { cout << "foo: " << s << endl; }
int main(int argc, char *argv[]) {
cout << "test\n"; // break here
}
LLDB console:
(lldb) p foo("hi")
error: <user expression 0>:1:1: no matching function for call to 'foo'
1 | foo("hi")
| ^~~
note: candidate function not viable: no known conversion from 'const char[3]' to 'const std::string' (aka 'const std::basic_string<char>') for 1st argument
It doesn’t recognize the using std:
(lldb) p foo(string("hi"))
error: <user expression 6>:1:5: use of undeclared identifier 'string'
1 | foo(string("hi"))
If I use std::, it still fails. Any ideas?
(lldb) p foo(std::string("hi"))
error: <user expression 7>:1:5: no matching conversion for functional-style cast from 'const char[3]' to 'std::string' (aka 'std::basic_string<char>')
1 | foo(std::string("hi"))
| ^~~~~~~~~~~~~~~~
note: candidate constructor not viable: no known conversion from 'const char[3]' to 'std::initializer_list<char>' for 1st argument
note: candidate constructor not viable: no known conversion from 'const char[3]' to 'nullptr_t' (aka 'std::nullptr_t') for 1st argument
note: candidate constructor not viable: no known conversion from 'const char[3]' to 'std::basic_string<char>' for 1st argument
note: candidate constructor not viable: no known conversion from 'const char[3]' to 'const std::basic_string<char>' for 1st argument
note: candidate constructor not viable: no known conversion from 'const char[3]' to 'const std::basic_string<char>::allocator_type' (aka 'const std::allocator<char>') for 1st argument
note: candidate constructor not viable: requires 0 arguments, but 1 was provided
... and on and on ...
Another try:
(lldb) p foo((const char*)"hi")
error: <user expression 8>:1:1: no matching function for call to 'foo'
1 | foo((const char*)"hi")
| ^~~
note: candidate function not viable: no known conversion from 'const char *' to 'const std::string' (aka 'const std::basic_string<char>') for 1st argument
Looks like you ran into a couple of subtleties of the expression evaluator:
Your call to foo("hi") is failing because you don’t have debug-info for the basic_string(char const*) constructor, so LLDB can’t provide the embedded Clang instance with the correct CXXConstructorDecl. So we need up claiming there is no conversion from const char[3] to std::string.
That being said, even if we instantiate the std::string constructor explicitly in the source, we still don’t get the debug-info we need for expression evaluation. I’ll have to look into why that’s happening. You could work around it for now by running settings set target.import-std-module true before running the expression (which means we will get the decls we need from the std module instead of debug-info).
using namespace declarations aren’t honoured by LLDB’s expression evaluator at the moment. So you have to fully qualify the namespace.
Calling std::string("hi") won’t work because the expression evaluator currently doesn’t support leaving out default function parameters. Even if it did, the rest of the errors still point at missing debug-info.
But turns out LLDB doesn’t actually construct a CXXConstructorDecl from it. There is a comment in DWARFASTParserClang::ParseSubroutine that explains why:
// Check for templatized class member functions. If we had any
// DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
// the DW_TAG_subprogram DIE, then we can't let this become a method in
// a class. Why? Because templatized functions are only emitted if one
// of the templatized methods is used in the current compile unit and
// we will end up with classes that may or may not include these member
// functions and this means one class won't match another class
// definition and it affects our ability to use a class in the clang
// expression parser. So for the greater good, we currently must not
// allow any template member functions in a class definition.
if (is_cxx_method && has_template_params) {
ignore_containing_context = true;
is_cxx_method = false;
}