The goal is for lld to be eventually accepted by the LLVM community and become the standard linker used with clang. Therefore, the lld source code structure and style is following the LLVM Coding Standards with the exceptions noted below. The execptions are to solve real world problems such as disambiguation and avoiding bugs.
Like the LLVM convention, lld uses camel case for names, and capital
letters to begin the name of a type (e.g. Atom
,
Reference
). But, unlike
LLVM the lld convention is to begin non-type identifiers with a lower case
letter, so they are easily distiguished (e.g. Foo
is a type
and foo
is a variable). Here are some concrete examples of
the problem with variables and types being named the same:
Xxx Yyy(Zzz); // ambiguous LLVM conventionIs that a function prototype? Or a local variable whose object constructor takes one argument?
Xxx yyy(Zzz); // function prototype in lld conventionAnd a local variable would look like:
Xxx yyy(zzz); // local object in lld convention
Aaa(Bbb) // ambiguous LLVM conventionIs that a function call? Or casting Bbb to type Aaa?
aaa(bbb) // function call in lld conventionAnd a cast would look like:
Aaa(bbb) // cast in lld convention
Writer writer; // possible only in lld convention Atom atom; // possible only in lld convention
extern void log(const char*);with lots of clients callling it. Then decide you need to dynamically switch the log function, so you change the interface to:
extern void (*log)(const char*);And all clients still compile. But, according to the LLVM conventions, you need to rename
log
to Log
(which means changing all clients) because
log is now a variable instead of a function.
Like the LLVM convention, lld uses camel case for variable names. But to
disambiguate data members (aka instance variables, aka ivars) from local (stack)
variables, lld adds a leading underscore to instance variable names
(e.g. _file
, _stringsMaxOffset
are ivars). Think
of the leading underbar as short hand for "this->
".
It is important to quickly disambiguate ivars from local variables to understand the lifetime, scope, and what else might be using the variable.
Count = expression // ambiguous LLVM conventionIt is not obvious if Count is a local (stack) variable or an ivar. So you don't now if this is a temporary calculated value, or if the value will persist (in the object) after this method returns.
_count = expression // ivar assignment, lld convention count = expression // local var assignment, lld convention
auto_ptr<>
to help with this.)
class Foo { int Flags; Foo(int Flags) : Flags(Flags) { } };The lld convention does not have these shadowing issues. The same class in lld conventions would be:
class Foo { int _flags; Foo(int flags) : _flags(flags) { } };
I did some web searching to see what other C++ conventions are documented. I found no other conventions in which type names and variable names could collide as can happen with the LLVM conventions. Here are some which are generally similar (camel case) to LLVM's conventions (e.g. not GNU or unix-like all lower case conventions).