-
Notifications
You must be signed in to change notification settings - Fork 13.5k
STR2WSTR(__FUNCTION__) should work in microsoft mode #12161
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
assigned to @nico |
(In xstddef, with _HAS_EXCEPTIONS defined to 0.) |
Stupid -fsyntax-only workaround: change crtdefs.h to #define FUNCTIONW to e.g. _STR2WSTR(FILE) instead. |
A little more information about this since I ran into the same issue, i.e. when including in VS2010: See this link: http://blog.shuva.in/index.php?entry=entry080823-063456 Microsoft's compiler turns FOO_STR2WSTR(FUNCTION) into __LPREFIX(FUNCTION). __LPREFIX isn't a macro, it's a weird compiler intrinsic that does what the "L" prefix is meant to do. This seems to be specifically for handling FUNCTION, because FOO_STR2WSTR(ANYTHING_ELSE) just results in LANYTHING_ELSE. Here's my small test case: // C++ file: int main( int argc, char* argv[] ) { // Preprocessed output from VC10: Maybe Microsoft's preprocessor specifically handles concatenating L ## FUNCTION? |
I did some more testing. It looks like VC does a bunch of stuff to make it appear like FUNCTION is a macro. This isn't just for the case of the "L" prefix. Note that when prefixing with some garbage, "QWERTY", the preprocessor generates a result similar to the "L" case. It doesn't do anything special for strings though. // C++ file: #define __OTHER_PREFIX(str) QWERTY##str #define __STRING_PREFIX(str) "a string" str int main( int argc, char* argv[] ) { // Preprocessed output from VC10: |
So this appears to be something special to do with FUNCTION to make it look like a macro. I would expect this same behavior with FUNCSIG and FUNCDNAME, since they're all supposed to behave like macros, but really are implemented in the compiler and not the preprocessor. The preprocessor specially handles two things: L##FUNCTION, and ##FUNCTION ( representing any token). L##FUNCTION gets turned into __LPREFIX(FUNCTION). Something else, like QWERTY##FUNCTION gets turned into QWERTY__FSTREXP FUNCTION. One other rule is, whenever one of the arguments to the concatenation operator is FUNCTION, a space goes in between them. I think this is reasonable to implement in the preprocessor. I'll have to do some more research into how the "FSTREXP" identifiers get treated in the compiler -- I want to see if they get turned into anything else there. |
Does MSVC compile this program?: void f() { One possible way to make this work would be to have the parser tell the preprocessor about the current function name every time it enters a function, and have the preprocessor handle FUNCTION like FILE (i.e. like a normal string) except expanding it to the current "current function name" it got from the parser. This might get tricky with template functions, where the parameter types aren't known when that function is getting parsed. What does FUNCTION expand to in template functions in msvc? Does msvc support PRETTY_FUNCTION? What does that expand to? |
MSVC does compile that program, and the preprocessed output is the same as the input. MSVC doesn't support PRETTY_FUNCTION. Here's a list of what the preprocessor does support: http://msdn.microsoft.com/library/b0084kay.aspx I think we should handle this in the preprocessor, as the regular FUNCTION and equivalent macros are currently handled. |
It looks like the FSTREXP cases aren't worth compiling: #include const char* const QWERTY = "qwerty"; #define __OTHER_PREFIX(str) QWERTY##str #define __STRING_PREFIX(str) "a string" str int main() { As noted above, OTHER_PREFIX expands to QWERTY__FSTREXP FUNCTION. However, the compiler then complains that it doesn't recognize the identifier "QWERTY__FSTREXP". I'm not sure why the preprocessor emits this, then, maybe it's an internal implementation detail. Given this, I think it's only worth trying to implement the __LPREFIX thing. |
I'm tackling the problem right now. I think easiest way would be to
The ability of MS compilers to paste string literals and predef variables would have to be handled separately. I have a partial implementation of FUNCTIONW (without codegen, only for -fsyntax-only): https://github.com/avakar/clang/tree/bug11789 |
Hi Martin. There has been some patches and discussion regarding this in the list: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120611/058838.html |
If you see my discussion with Richard Smith about my patch, it sounds like he would prefer a very simple patch, rather than emulating the exact behavior of MSVC, which I can understand. Given that, it might make sense to not even bother #defining L__FUNCTION__ to FUNCTIONW or anything like that. Just add a predefined expression L__FUNCTION__ that is the wide string function name, only available in ms compatibility mode. Thoughts? |
Yes, I've seen your original patch submission and found it too complex as well.
It would be sufficient for compatibility's sake, however, there is currently no way to get wchar_t version of FUNCTION and since it will have to be supported for the sake of MS, I'd make it available for non-MS modes as well. And, of course, we wouldn't want it to be called L__FUNCTION__ there. That's why I went with FUNCTIONW and a predefined macro. |
r159060 See http://thread.gmane.org/gmane.comp.compilers.clang.scm/52277 for discussion. |
mentioned in issue llvm/llvm-bugzilla-archive#12477 |
mentioned in issue llvm/llvm-bugzilla-archive#20013 |
Extended Description
#include <stdio.h>
#define _FOO_STR2WSTR(s) L##s
#define FOO_STR2WSTR(s) _FOO_STR2WSTR(s)
int main() {
//const wchar_t* kFoo = L__FUNCTION__; // doesn't work in cl.exe
const wchar_t* kWFoo = FOO_STR2WSTR(FUNCTION); // works in cl
}
Both gcc and clang don't allow this, but cl.exe does. (gcc and clang support it for e.g. FILE.)
This is used in msvc's c++ standard headers.
The text was updated successfully, but these errors were encountered: