<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/87588>87588</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
libtooling: behaviour of `__COUNT__` diverges from calling `clang` manually
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
giulianobelinassi
</td>
</tr>
</table>
<pre>
With the following files:
header.h:
```
#define __DEFINE_FUNCTION(i) \
int function_ ## i (void) { return 0; }
#define _DEFINE_FUNCTION(i) __DEFINE_FUNCTION(i)
#define DEFINE_FUNCTION _DEFINE_FUNCTION(__COUNTER__)
DEFINE_FUNCTION;;
```
test.c:
```
#include "header.h"
DEFINE_FUNCTION;
int main()
{
function_0();
return 0;
};
```
compiling with:
```
$ clang++ -O2 -c test.c
```
Results in the input being **accepted**.
------------------------------------------------------------------------------
Now with libtooling, the following reproducer ( `$ clang++ -g llvm-repro.cpp -lclang-cpp -lLLVM`):
```
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
using namespace clang;
using namespace llvm;
static const char *const header =
"#define __DEFINE_FUNCTION(i) \\\n"
" int function_ ## i (void) { return 0; }\n"
"#define _DEFINE_FUNCTION(i) __DEFINE_FUNCTION(i)\n"
"#define DEFINE_FUNCTION _DEFINE_FUNCTION(__COUNTER__)\n"
"DEFINE_FUNCTION;\n";
static const char *const test_file =
"#include \"header.h\"\n"
"DEFINE_FUNCTION;\n"
"int main()\n"
"{\n"
" function_0();\n"
" return 0;\n"
"}\n";
static const std::vector<const char *> clang_args = {"-O2", "-c", "test.c"};
int main(void)
{
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
std::shared_ptr<CompilerInvocation> CInvok;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MFS;
MFS = IntrusiveRefCntPtr<vfs::InMemoryFileSystem>(new vfs::InMemoryFileSystem);
MFS->addFile("test.c", 0, MemoryBuffer::getMemBufferCopy(test_file));
MFS->addFile("header.h", 0, MemoryBuffer::getMemBufferCopy(header));
DiagnosticOptions *diagopts = new DiagnosticOptions();
Diags = CompilerInstance::createDiagnostics(diagopts);
clang::CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CInvok = clang::createInvocation(clang_args, std::move(CIOpts));
FileManager *FileMgr = new FileManager(FileSystemOptions(), MFS);
PCHContainerOps = std::make_shared<PCHContainerOperations>();
auto AST = ASTUnit::LoadFromCompilerInvocation(
CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 1,
TU_Complete, false, false, false);
const DiagnosticsEngine &de = AST->getDiagnostics();
if (AST == nullptr || de.hasErrorOccurred()) {
llvm::outs() << "Rejected.\n";
return 1;
} else {
llvm::outs() << "Accepted.\n";
return 0;
}
}
```
Results in the output always being **rejected**. Notice how it is **exactly** the same code, but one is being compiled through clang, whereas the other is being compiled through libtooling.
I'd say this is undesired behavior and a bug.
```
clang version 18.1.2
Target: x86_64-suse-linux
Thread model: posix
InstalledDir: /usr/bin
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWN1y4joSfhpx0wVl5IDJBRfExLWpnSSnJpndS0pYja09QnJJMpm8_ZZkg41DSM7umaE8-unfT92t1jBrRaEQl2R2R2brEatdqc2yELUUTOktSqE8zWir-fvy38KV4EqEnZZSvwlVwE5ItCRekWhNovZbIuNoJmW3PI_aXzOlMcedUAibzfo-e3i632S_ntLXh-cnQheC0Fsgs7ShBQChHOxqlTuh1QYIjQmNQQChi4MWPFAnd2DQ1UZBROI7IMn6g6ZPFH1mwZB_QHVJ3maTPv96er3_udmcBAyp4jv_uwSKQ-sm-RXIhMplzREIpSeAKf1UTVj30O2ZUIQuOp-SuyO0J1SjluDI10fzyLX-zPJc7yshfTC8CXfl0G8gl0wVhN4RegfjZwrjHFq3L3H8RFtLZ0GoEHNCVbWDLXpFhK4IXbE8x8ohb2aTfgiO_9Y_fclP-i34CVJsndbeb0LTQVYYrIzmdY7Ghyl4l4buFyDlYT8OlJO8qmAsw_64Gf_48a_HwHb7vZBoZWeZ0cqh4oRmq5fXX0q4Xph8yZKGo0TzoKxjKsc-b_jW1run2B5txXJsXToGxnDXe9hFTfhax5zIIdfKOshL5gFaNbMmqoHEp-Sl36wU4ad6btL_uWwM5PwfBeRTSX-9lAxEXcj2luLbWPu02_jaPYT7FB-ztF9owuz7dhwpBvVnCEnygeFyTfpA1C9PH4Suv4GGddznVbw6YO60IXF6jhKJ75vY3jBTWA8S-HAhlI6faUAq9Sk0zrtxW8kaC85V92BoY29Yih-UM7UVB_yJu1S5P5w3aS1YobR1Irf3qhAKvVV-0XaF-uSILZlBvqkCZ5fHB50zD6dnTf30z694_0j_kWrlmFBonis0gd16_vMdO3Dysg9NCQhI72wzeFCPuNfmPRMSX96tw70X_pi9DAX6tQD9RcnX5RG6UPgG14j6991j9jIm8T3j3BOEyOsdKE0h8p9GxF2926FpxBboHnHfrKS6eid0cUotr-ArHf2b_C9paRgHKo64dYHzXIXT8yHNBSt05Zpg9th8oBo0AX1pDdfwemisyw0yh71gJXRxVHZBXntleM40cHZBerQ2fXj2vCfk2oVJZ8kgC9rQDls9-flAPqGLLqk91KcM2OuDP5FW8UVU_aE9MsWKcKmvwrQwJzR724QuujA7x9Yfb_ZyFhaDrAoCO7vYn7hp0vNaan5ycqx2GlYvr0Fm2w40cn9oxjOj9xcKBV2cOm84AuvtHmY_TdtToCm0YPjhjkmLfpCyytUmxIX9p1CtQ09ahd0poWlfz-uvjbdFosMzKcPBRyebwv2hVgKhc45Hz33iFejOg_SSNLHzHUKLWTjbWsrKGSBJSpIUOE5KZu-N0eY5z2vjD6Y92tBQdD51lU_XrlUHJE5JHK6Ln_gfzB3yyfC28rzt_TbtLZJkDSgt9pR8oWHVtsfXNHQNfu_RdBpc7cd17XxDzuQbe7dnfblpXWv7cnjSTuQIpX4D4UDYlgx_s9zJ92YSRFq2R8g1Dwe-rR1ohZ6-Ed68M5CDK42ui_LYT6fwVqJBZhuzXInmClPXtp89GB4ITThY9g6uFNbz14qjFQY5bLFkB6ENMMWBwbY-Zx0-h7xVcEBjhVYwXUymk7Y7eWWmQJ-A8Hsx38xvxra2OJZC1b9bgtIg47DXHKUnq7QV7VYouVIiXwt_KQChWW0NodlWqIEZI76M-W18y0a4nCZTOr2dzpP5qFzG0c00WuTbGYvm82THo12CPL5h02SGMcbJSCxpRG8i_ze6SWbzScLoLOb5nM0XOY9nW3IT4Z4JOfGhN9GmGAlra1wuktliMZJsi9KG_0o4vS4oma1HZhneOtu6sOQmksI620lwwklc9l5T8eqIeG1A7_zrqe2HNxsyj4CLA5oCLeyM3kPOZHh7knnUqJxHsGeqZlK-j2ojl6VzVWgCaEZoVghX1ttJrveEZiGBmn_GldE-agnNgkuW0Cx49d8AAAD__8yl-M0">