-1

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!

  • 1
    The alternative to `#define LLVM_EXTERNAL_VISIBILITY // <-------------- THIS` would be `#error Need to define external visibility attribute for this platform`. – Eljay Oct 22 '22 at 16:32
  • I see, thanks. However, that would be useful only if we wanted to force only one possible setup for compilation (since the other one would fail), right? With the "empty" define, instead, we define two possible setups(?) – Alessandro Bertulli Oct 23 '22 at 16:58
  • 1
    There could be as many possible setups are there are platforms that the software intends to support and control with the visibility semantic. – Eljay Oct 23 '22 at 17:48

1 Answers1

1

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.

topal
  • 151
  • 6