In the LLVM codebase, I see this lines:
class LLVM_EXTERNAL_VISIBILITY Function : public GlobalObject,
public ilist_node<Function> {
My LSP (clangd
) tells me that LLVM_EXTERNAL_VISIBILITY
refers to
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
/// functions, making them private to any shared library they are linked into.
/// On PE/COFF targets, library visibility is the default, so this isn't needed.
///
/// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with
/// this attribute will be made public and visible outside of any shared library
/// they are linked in to.
#if __has_attribute(visibility) && \
(!(defined(_WIN32) || defined(__CYGWIN__)) || \
(defined(__MINGW32__) && defined(__clang__)))
#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
#define LLVM_EXTERNAL_VISIBILITY __attribute__((visibility("default")))
#else
#define LLVM_EXTERNAL_VISIBILITY // <-------------- THIS
#endif
#else
#define LLVM_LIBRARY_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
#endif
I can't figure out the usefulness: why should I #define
an identifier without a value, but using that as if it had one?
One idea is that it acts as a conditional: if something happens, then the preprocessor substitutes some text; if not, it simply doesn't substitute anything, but prevents the compiler from complaining about some undefined LLVM_LIBRARY_VISIBILITY
token. Is this correct?
Moreover, what kind of attributes can be specified there? Something about the linkage of the class?
Thanks!
CodePudding user response:
One idea is that it acts as a conditional: if something happens, then the preprocessor substitutes some text; if not, it simply doesn't substitute anything, but prevents the compiler from complaining about some undefined LLVM_LIBRARY_VISIBILITY token. Is this correct?
Pretty much. Some build environments, it'll have a value. Others not. Seems mainly a matter of portability.
__attribute__((visibility("default")))
refers to the visibility of the symbol it is attached to. The default visibility can be changed at compile time.