This aligns the behavior with the standard call as well as the LLVM verifier.
Could we have tests for user-visible error messages?
Using textual attribute names makes it feel like JSON. We can just have op.callee() or op.calleeAttr() if the attribute object is necessary.
Also, this seems to accept nested symbol references without verifying them.