It is sometimes necessary for the C++ Compiler to create temporäre Objekte. They are used during:
- Reference initialization.
- Evaluation of expressions including standard type conversions.
- Argument passing.
- Funktion returns.
- Evaluation of the throw expression.
For non-trivial classes, the creation and destruction of temporary objects can be expensive in terms of processing time and memory usage. In this case, you should minimize their introduction. The C++ compiler does eliminate some temporary objects, but it cannot eliminate all of them.
It’s not always easy to detect where temporäre Objekte are introduced, as Herb Sutter explains in his sample. The compiler has this information, but is it possible to get from the compiler the places where temporary objects are introduced? And if not, is it easy to modify it to report them?
In our case, we will use Clang: it is very flexible and provides many ways to customize its behavior. Indeed, a major design concept of Clang is its use of a library-based architecture. In this design, various parts of the front end can be cleanly divided into separate libraries, which can then be mixed and matched for different needs and uses. In addition, the library-based approach encourages good interfaces and makes it easier for new developers to get involved (because they only need to understand small pieces of the big picture).
The Clang Compiler has three phases:
- The front end, which parses source code, checks it for errors, and builds a language-specific Abstract Syntax Tree (AST) to represent the input code.
- The optimizer: its goal is to perform some optimizations on the AST generated by the front end.
- The back end, which generates the final code to be executed by the machine; it depends on the target.

In our case, we will focus on the front-end phase. The goal is to obtain the Abstract Syntax Tree (AST) for a source file and check whether it reports any useful information about temporary objects.
Let’s explore the AST of this minimal Quellcode:

To generate the AST, we can execute the Clang front end parser using the -cc1 switch.
clang -cc1 -ast-dump test.cpp
Here’s the AST generated for the GetTest Funktion:

In this AST, two pieces of information are related to temporäre Objekte: nrvo and elidable.
Named Return Value Optimization is a compiler optimization technique that involves eliminating the temporary object created to hold a function’s return value. NRVO eliminates the copy constructor and destructor of a stack-based return value. This optimizes out the redundant copy constructor and destructor calls and thus improves overall performance. For more details, you can refer to its wiki page.
Copy elision is a compiler optimization technique that eliminates unnecessary copying of objects. For more details, you can refer to its wiki page.
It’s interesting that Clang tells us where an NRVO is applied, but it doesn’t explicitly report where temporary objects are created. Let’s go inside the AST dumper source code and try to report them.
How does ASTDumper work?
The compiler parses a program and represents the parsed program as an abstract syntax tree (AST). The AST has many different kinds of nodes, such as Assignment, Variable Reference, and Arithmetic Expression nodes. After generating the AST, Clang invokes some front end actions that traverse it and perform some processing; ASTDumpAction is one of them, and it dumps the AST to the console.
ASTDumper is declared like this
class ASTDumper
: public ConstDeclVisitor, public ConstStmtVisitor,
public ConstCommentVisitor
The visitor pattern is the recommended pattern when we need to traverse a structure and apply specific processing to each node of that structure.
Here are some Methoden invoked when the AST is traversed; each one is related to a specific AST node.
void VisitNamespaceDecl(const NamespaceDecl *D);
void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
void VisitTypeAliasDecl(const TypeAliasDecl *D);
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
void VisitCXXRecordDecl(const CXXRecordDecl *D);
void VisitStaticAssertDecl(const StaticAssertDecl *D);
Hacking the Clang AST dumper
Our goal is to report the temporary objects that are created, so we need to track object creation and identify which AST node is involved in constructing each object.
In Clang, VisitCXXConstructExpr is invoked when a C++ Objekt must be created; here’s its implementation:

Wie wir sehen können, there’s no test for whether the created object is temporary or not, but the good news is that CXXConstructExpr has the IsTemporaryObject method, which determines whether the result of this expression is a temporary object of the given class type.
Let’s change the implementation to add another condition:

Here’s the new AST produced after the modification:

After adding a few lines of code, the ASTDumper now explicitly reports where temporäre Objekte are created.
Fazit
LLVM/Clang is not just a compiler; it is also a powerful infrastructure for developing your own C/C++/Objective-C tools. Its architecture is relatively easy to understand, and it can be customized to suit your needs. Don’t hesitate to download the Clang source code, make a few modifications, and rebuild it—this can be especially helpful for students who want to learn how compilers work.
