Private</a></li>
<li><a href="#hl_earlyexit">Use Early Exits and 'continue' to Simplify
Code</a></li>
+ <li><a href="#hl_else_after_return">Don't use "else" after a
+ return</a></li>
<li><a href="#hl_predicateloops">Turn Predicate Loops into Predicate
Functions</a></li>
</ol></li>
<li><a href="#ll_iostream"><tt>#include <iostream></tt> is
<em>forbidden</em></a></li>
<li><a href="#ll_avoidendl">Avoid <tt>std::endl</tt></a></li>
+ <li><a href="#ll_raw_ostream">Use <tt>raw_ostream</tt></a</li>
</ol></li>
<li><a href="#nano">Microscopic Details</a>
declare the symbol. This can lead to problems at link time.</p>
<p>So, the rule for LLVM is to always use the <tt>class</tt> keyword, unless
-<b>all</b> members are public, in which case <tt>struct</tt> is allowed.</p>
+<b>all</b> members are public and the type is a C++ "POD" type, in which case
+<tt>struct</tt> is allowed.</p>
</div>
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="hl_else_after_return">Don't use "else" after a return</a>
+</div>
+
+<div class="doc_text">
+
+<p>For similar reasons above (reduction of indentation and easier reading),
+ please do not use "else" or "else if" after something that interrupts
+ control flow like return, break, continue, goto, etc. For example, this is
+ "bad":</p>
+
+<div class="doc_code">
+<pre>
+ case 'J': {
+ if (Signed) {
+ Type = Context.getsigjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_sigjmp_buf;
+ return QualType();
+ } else {
+ break;
+ }
+ } else {
+ Type = Context.getjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_jmp_buf;
+ return QualType();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+</pre>
+</div>
+
+<p>It is better to write this something like:</p>
+
+<div class="doc_code">
+<pre>
+ case 'J':
+ if (Signed) {
+ Type = Context.getsigjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_sigjmp_buf;
+ return QualType();
+ }
+ } else {
+ Type = Context.getjmp_bufType();
+ if (Type.isNull()) {
+ Error = ASTContext::GE_Missing_jmp_buf;
+ return QualType();
+ }
+ }
+ break;
+</pre>
+</div>
+
+<p>Or better yet (in this case), as:</p>
+
+<div class="doc_code">
+<pre>
+ case 'J':
+ if (Signed)
+ Type = Context.getsigjmp_bufType();
+ else
+ Type = Context.getjmp_bufType();
+
+ if (Type.isNull()) {
+ Error = Signed ? ASTContext::GE_Missing_sigjmp_buf :
+ ASTContext::GE_Missing_jmp_buf;
+ return QualType();
+ }
+ break;
+</pre>
+</div>
+
+<p>The idea is to reduce indentation and the amount of code you have to keep
+ track of when reading the code.</p>
+
+</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<div class="doc_text">
-<p>It is very common to write inline functions that just compute a boolean
+<p>It is very common to write small loops that just compute a boolean
value. There are a number of ways that people commonly write these, but an
example of this sort of thing is:</p>
<p>This sort of code is awkward to write, and is almost always a bad sign.
Instead of this sort of loop, we strongly prefer to use a predicate function
(which may be <a href="#micro_anonns">static</a>) that uses
-<a href="#hl_earlyexit">early exits</a> to compute the predicate. Code like
-this would be preferred:
+<a href="#hl_earlyexit">early exits</a> to compute the predicate. We prefer
+the code to be structured like this:
</p>
forces you to write a comment for it. In this silly example, this doesn't add
much value. However, if the condition is complex, this can make it a lot easier
for the reader to understand the code that queries for this predicate. Instead
-of being faced with the in-line details of we check to see if the BarList
+of being faced with the in-line details of how we check to see if the BarList
contains a foo, we can trust the function name and continue reading with better
locality.</p>
example) is allowed normally, it is just <tt><iostream></tt> that is
causing problems.</p>
-<p>The preferred replacement for stream functionality is the
-<tt>llvm::raw_ostream</tt> class (for writing to output streams of various
-sorts) and the <tt>llvm::MemoryBuffer</tt> API (for reading in files).</p>
+<p>In addition, new code should always
+use <a href="#ll_raw_ostream"><tt>raw_ostream</tt></a> or
+the <tt>llvm::MemoryBuffer</tt> API (for reading in files).</p>
</div>
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="ll_raw_ostream">Use <tt>raw_ostream</tt></a>
+</div>
+
+<div class="doc_text">
+
+<p>LLVM includes a lightweight, simple, and efficient stream implementation
+in <tt>llvm/Support/raw_ostream.h</tt> which provides all of the common features
+of <tt>std::ostream</tt>. All new code should use <tt>raw_ostream</tt> instead
+of <tt>ostream</tt>.</p>
+
+<p>Unlike <tt>std::ostream</tt>, <tt>raw_ostream</tt> is not a template and can
+be forward declared as <tt>class raw_ostream</tt>. Public headers should
+generally not include the <tt>raw_ostream</tt> header, but use forward
+declarations and constant references to <tt>raw_ostream</tt> instances.</p>
+
+</div>
+
+
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="nano">Microscopic Details</a>
<div class="doc_code">
<pre>
-/// SomeCrazyThing - This namespace contains flags for ...
-namespace SomeCrazyThing {
- enum foo {
- /// X - This is the X flag, which is ...
- X = 1,
-
- /// Y - This is the Y flag, which is ...
- Y = 2,
-
- /// Z - This is the Z flag, which is ...
- Z = 4,
-
- /// ALL_FLAGS - This is the union of all flags.
- ALL_FLAGS = 7
- };
+namespace llvm {
+ namespace X86 {
+ /// RelocationType - An enum for the x86 relocation codes. Note that
+ /// the terminology here doesn't follow x86 convention - word means
+ /// 32-bit and dword means 64-bit.
+ enum RelocationType {
+ /// reloc_pcrel_word - PC relative relocation, add the relocated value to
+ /// the value already in memory, after we adjust it for where the PC is.
+ reloc_pcrel_word = 0,
+
+ /// reloc_picrel_word - PIC base relative relocation, add the relocated
+ /// value to the value already in memory, after we adjust it for where the
+ /// PIC base is.
+ reloc_picrel_word = 1,
+
+ /// reloc_absolute_word, reloc_absolute_dword - Absolute relocation, just
+ /// add the relocated value to the value already in memory.
+ reloc_absolute_word = 2,
+ reloc_absolute_dword = 3
+ };
+ }
}
</pre>
</div>
<div class="doc_text">
-<p>A common topic after talking about namespaces is anonymous namespaces.
+<p>After talking about namespaces in general, you may be wondering about
+anonymous namespaces in particular.
Anonymous namespaces are a great language feature that tells the C++ compiler
that the contents of the namespace are only visible within the current
translation unit, allowing more aggressive optimization and eliminating the
of a large C++ file, that you have no immediate way to tell if it is local to
the file. When it is marked static explicitly, this is immediately obvious.
Also, there is no reason to enclose the definition of "operator<" in the
-namespace since it was declared there.
+namespace just because it was declared there.
</p>
</div>