isExternCContext() is returning false for functions in C files
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
It looks like MSVC also accepts
// foo.c static void foo(); #pragma alloc_text("hello", foo) void foo() {}
and
// foo.cpp extern "C" { static void foo(); #pragma alloc_text("hello", foo) void foo() {} }
Do you know of a way I can check whether a function is coming from c or c++? isExternC() returns false for the static case
Hmm, it looks like MSVC is accepting:
extern "C" { static void foo(); } static int foo(); #pragma alloc_text("s", foo) static void foo() {}
Ignoring the pragma alloc_text, it looks like GCC compiles the following foo with C linkage vs LLVM which compiles with C++ linkage (foo's name is mangled):
extern "C" { static int foo(); } static int foo(); static int foo() { return 3; } int bar() { return foo(); }
Ignoring the pragma alloc_text, it looks like GCC compiles the following foo with C linkage vs LLVM which compiles with C++ linkage (foo's name is mangled):
The mangled name shouldn't matter since it has internal linkage. I tried dropping the static, and then foo doesn't seem to get mangled: https://godbolt.org/z/arzW5TbYz
Oh I see, that makes sense. We aren't accepting https://godbolt.org/z/9Yej9vhYd. Do you know of a way to get the NamedDecl with extern "C" instead of the second declaration?
Oh I see, that makes sense. We aren't accepting https://godbolt.org/z/9Yej9vhYd. Do you know of a way to get the NamedDecl with extern "C" instead of the second declaration?
I'm not sure I understand the question, but it seems the current code is checking isExternCContext(). I think instead you want to check FunctionDecl::isExternC().
I tried the following:
FunctionDecl *FD = ND->getAsFunction(); DeclContext *DC = ND->getDeclContext(); DEBUG_WITH_TYPE("foo", llvm::dbgs() << "[FOO] DC->isExternCContext() : " << DC->isExternCContext() << "\n"); DEBUG_WITH_TYPE("foo", llvm::dbgs() << "[FOO] FD->isExternC() : " << FD->isExternC() << "\n"); DEBUG_WITH_TYPE("foo", llvm::dbgs() << "[FOO] FD->isInExternCContext() : " << FD->isInExternCContext() << "\n"); llvm::dbgs() << "[FOO] "; ND->dump(); if (getLangOpts().CPlusPlus && !DC->isExternCContext()) { Diag(Loc, diag::err_pragma_alloc_text_c_linkage); return; }
and I'm getting the following output:
[FOO] DC->isExternCContext() : 0 [FOO] FD->isExternC() : 0 [FOO] FD->isInExternCContext() : 0 [FOO] FunctionDecl 0x10ec0250 prev 0x10ec0148 <foo.cpp:4:1, col:17> col:13 foo 'void ()' static
The C file is:
1 extern "C" { 2 static void foo(); 3 } 4 static void foo(); 5 #pragma alloc_text("s", foo) 6 static void foo() {}