currently I’m working on an own small footprint Objective-C Class library completely unrelated to Cocoa. I use clangd [version 8.0.0 (tags/RELEASE_800/final)] from homebrew as the language server in my IDE.
Unfortunately I can’t clangd persuade to accept my own as a constant string class with the flag "-fconstant-string-class=NGStringLiteral". Ignoring the flag it complains: “Incompatible pointer types initializing 'NGStringLiteral *' with an expression of type 'NSString *’”.
To quiet this I declared ’NSString’ as ’NGStringLiteral’ (“typedef NSString NGStringLiteral”). Now clangd warns: “Incompatible pointer types initializing 'NSString *' (aka 'NGStringLiteral *') with an expression of type 'NSString *’”!
That’s annoying - like all the hard-wired Cocoa aka Apple stuff in clang software. Objective-C is an independent general purpose programming language. Not a Cocoa development tool and not an Apple software product. This should be true for clang, too.
So, what can I do (or what can you do) to get rid of - at least - this?
Can you provide a minimal source file that exhibits the problem, and explain how you’re specifying the -fconstant-string-class flag? (It should be in the compile_commands.json or compile_flags.txt file)
It sounds like what you’re describing should work, but I think we need more detail to reproduce the issue.
I cant really speak to the layering between objc the language and the Foundation etc libraries. I’m sympathetic to the frustration but realistically clangd won’t diverge from clang here, so this would be an issue for experts on cfe-dev.
No, compilers (both clang and gcc) work like expected. It’s only clangd that simply ignores the constant-string-class flag (neither in compile_commands.json nor in compile_flags.txt).
NGStringLiteral *test0 = @"Hello world”; // —> “Incompatible pointer types initializing ‘NGStringLiteral *’ with an expression of type 'NSString *’”
A first attempt to mitigate this was:
typedef NGStringLiteral NSString;
NSString *test1 = @"That’s me;)”; // —> “Incompatible pointer types initializing ‘NSString *’ (aka ‘NGStringLiteral *’) with an expression of type 'NSString *’”
Another attempt is subclassing NSString from NGStringLiteral. This quiets clangd, but now the compiler (gcc) complains “warning: initialization from distinct Objective-C type”. But this is another story.
All the above code would be irrelevant if clangd would regard the constant-string-class flag.
str.m:7:18: warning: incompatible pointer types initializing ‘NGStringLiteral *’ with an expression of type ‘NSString *’ [-Wincompatible-pointer-types]
I don’t have any deep understanding here, so I don’t know why these interactions exist, or which option you should choose. I’d guess the latter, though.
And AFAIK this should always be the same between (equal versions of) clang and clangd, so let me know if you can verify differences.
I use “clangd version 8.0.0 (tags/RELEASE_800/final)” from homebrew and run it without command line options through my IDE.
“-fno-constant-cfstrings” will do the trick. I used it formerly with clang and forgot it with clangd since I’m currently using gcc with this project. Sorry for this - my fault!
The next ten days I will be on travel and cannot verify your solution, but I’m sure you’re right. For me this issue is solved. Thanks a lot and sorry for bothering you and clangd-dev with it!