-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[lldb] lldb can't invoke function when param or return value with anonymous namespaces class. #104712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@Michael137 @adrian-prantl Could you please have a look? I found you resolved similar problems recently. Many thanks! |
@llvm/issue-subscribers-lldb Author: None (GithubXxz)
I found that if a function definition with anonymous namespaces class in the parameter or return value.
While debugging with lldb, these functions can't be invoked with errors like
```shell
error: error: function 'xxx' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
```
See the following example: namespace {
class A {
int a;
public:
explicit A(int a) : a{a} {}
int func() { return a + 1; }
};
} // namespace
void *param(A /*a*/) { return nullptr; }
A *returnvalue() { return nullptr; }
int main() {
A a = A{1};
// avoid eliminated by compiler optimization
(void)a.func();
(void)param(a);
(void)returnvalue();
return 0;
}
Debug above program by cli (lldb) target create "bin/lldbAnonymousVariable"
Current executable set to '/Users/zhiqiangz/llvm/llvm-demo/bin/lldbAnonymousVariable' (arm64).
(lldb) b 23
Breakpoint 1: where = lldbAnonymousVariable`main + 76 at lldbAnonymousVariable.cpp:23:3, address = 0x0000000100003efc
(lldb) r
Process 33550 launched: '/Users/zhiqiangz/llvm/llvm-demo/bin/lldbAnonymousVariable' (arm64)
Process 33550 stopped
* thread #<!-- -->1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #<!-- -->0: 0x0000000100003efc lldbAnonymousVariable`main at lldbAnonymousVariable.cpp:23:3
20 (void)param(a);
21 (void)returnvalue();
22
-> 23 return 0;
24 }
(lldb) e param(a)
error: error: function 'param' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
<user expression 0>:1:1: used here
1 | param(a)
| ^
(lldb) e returnvalue()
error: error: function 'returnvalue' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage
<user expression 1>:1:1: used here
1 | returnvalue()
| ^ definitely the exec program contain corresponding symbols, verified by follow command. nm bin/lldbAnonymousVariable | c++filt | rg "param"
0000000100003f58 t param((anonymous namespace)::A)
uname -a
Darwin zhiqiangz-mlt 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:59 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6030 arm64
llvm-config --version
19.0.0git |
Interesting, the error comes from Sema. It looks like The reason it thinks the function is undefined is that it doesn't have a function body at the point we parse it (i.e., But Sema does give us the opportunity to reconcile the |
Thanks for your reply, Michael! |
…inedButUsed While parsing an expression, Clang tries to diagnose usage of decls (with possibly non-external linkage) for which it hasn't been provided with a definition. This is the case, e.g., for functions with parameters that live in an anonymous namespace (those will have `UniqueExternal` linkage). Before diagnosing such situations, Clang calls `ExternalSemaSource::ReadUndefinedButUsed`. The intended use of this API is to extend the set of "used but not defined" decls with additional ones that the external source knows about. However, in LLDB's case, we never provide `FunctionDecl`s with a definition, and instead rely on the expression parser to resolve those symbols by linkage name. Thus, to avoid the Clang parser from erroring out in these situations, this patch implements `ReadUndefinedButUsed` which just removes the "undefined" non-external `FunctionDecl`s that Clang found. Fixes llvm#104712
…inedButUsed (llvm#104817) While parsing an expression, Clang tries to diagnose usage of decls (with possibly non-external linkage) for which it hasn't been provided with a definition. This is the case, e.g., for functions with parameters that live in an anonymous namespace (those will have `UniqueExternal` linkage, this is computed [here in computeTypeLinkageInfo](https://github.com/llvm/llvm-project/blob/ea8bb4d633683f5cbfd82491620be3056f347a02/clang/lib/AST/Type.cpp#L4647-L4653)). Before diagnosing such situations, Clang calls `ExternalSemaSource::ReadUndefinedButUsed`. The intended use of this API is to extend the set of "used but not defined" decls with additional ones that the external source knows about. However, in LLDB's case, we never provide `FunctionDecl`s with a definition, and instead rely on the expression parser to resolve those symbols by linkage name. Thus, to avoid the Clang parser from erroring out in these situations, this patch implements `ReadUndefinedButUsed` which just removes the "undefined" non-external `FunctionDecl`s that Clang found. We also had to add an `ExternalSemaSource` to the `clang::Sema` instance LLDB creates. We previously didn't have any source on `Sema`. Because we add the `ExternalASTSourceWrapper` here, that means we'd also technically be adding the `ClangExpressionDeclMap` as an `ExternalASTSource` to `Sema`, which is fine because `Sema` will only be calling into the `ExternalSemaSource` APIs (though nothing currently strictly enforces this, which is a bit worrying). Note, the decision for whether to put a function into `UndefinedButUsed` is done in [Sema::MarkFunctionReferenced](https://github.com/llvm/llvm-project/blob/ea8bb4d633683f5cbfd82491620be3056f347a02/clang/lib/Sema/SemaExpr.cpp#L18083-L18087). The `UniqueExternal` linkage computation is done in [getLVForNamespaceScopeDecl](https://github.com/llvm/llvm-project/blob/ea8bb4d633683f5cbfd82491620be3056f347a02/clang/lib/AST/Decl.cpp#L821-L833). Fixes llvm#104712 (cherry picked from commit 8056d92)
I found that if a function definition with anonymous namespaces class in the parameter or return value.
While debugging with lldb, these functions can't be invoked with errors like
See the following example:
Debug above program by cli
lldb -- bin/lldbAnonymousVariable
definitely the exec program contain corresponding symbols, verified by follow command.
uname -a Darwin zhiqiangz-mlt 23.3.0 Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:59 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6030 arm64
The text was updated successfully, but these errors were encountered: