Issue 87588
Summary libtooling: behaviour of `__COUNT__` diverges from calling `clang` manually
Labels clang
Assignees
Reporter giulianobelinassi
    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
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to