This is an archive of the discontinued LLVM Phabricator instance.

[Lex] Add compatibility with MSVC
AbandonedPublic

Authored by Qfrost911 on Oct 20 2022, 5:38 AM.

Details

Summary

The code below is valid in MSVC, but it is not allowed in clang

printf(__FUNCTION__ "Hello World");

This patch fixes the compatibility with MSVC.

Diff Detail

Event Timeline

Qfrost911 created this revision.Oct 20 2022, 5:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 20 2022, 5:38 AM
Qfrost911 requested review of this revision.Oct 20 2022, 5:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 20 2022, 5:38 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
aaron.ballman added a subscriber: aaron.ballman.

Thank you for the patch! It looks like it's missing test coverage for the changes, can you add some to clang/test/Preprocessor?

One question I have is: if we're going to support __FUNCTION__, shouldn't we also support __FUNCDNAME__ and __FUNCSIG__ as well, as those are also Microsoft predefined macros in the same general space?

clang/include/clang/Lex/Preprocessor.h
153

You should put your declaration on a new line so the line length doesn't exceed 80 columns (it's part of our coding style: https://llvm.org/docs/CodingStandards.html).

clang/lib/Lex/PPMacroExpansion.cpp
340–344

This looks incorrect in a few ways. The first is that you shouldn't use #if _WIN32 for this -- that means the compiler, when compiled for Win32, will have __FUNCTION__ which isn't what you were trying for (you'd want to use the language options to determine if you're compiling for Win32 or not, regardless of what OS the host compiler is running on).

Also, in the #else block you are registering __LINE__ as the identifier for __FUNCTION__, which isn't correct.

However, if we're going to support __FUNCTION__, we should support it on all targets instead of just Windows, so I don't think you need a conditional at all here.

1569–1575

You don't want the #ifdef here either, but also, this looks incorrect compared to the output you get from MSVC. __FUNCTION__ is the unmangled name of the function without any parameter or return type information, and this is printing line information.

I understand you mean, but I can't get function name at macro expedition stage.

I understand you mean, but I can't get function name at macro expedition stage.

Correct! We have a PredefinedExpr AST node type (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/Expr.h#L1968) to handle this, and it seems we already support __FUNCTION__ (and friends): https://godbolt.org/z/cEWh1Prnx. However, we're matching the GCC behavior for printing a member function name instead of following the MSVC behavior when in -fms-compatibility mode, which we might want to consider changing.

The reason your code example in the summary doesn't compile is because a PredefinedExpr is not a string literal, so there is no way to do string concatenation with an adjacent literal. MSVC implements these as actual macros that expand to a string literal, which is not a behavior Clang can easily match.

I understand you mean. I think I can try to solve this problem, if I have enough time.

Thank you very much for your response.

Qfrost911 abandoned this revision.Dec 8 2022, 8:45 PM