diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-15 06:01:05 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-15 06:01:05 +0000 |
commit | 5077c3876beeaed32280af88244e8050078619a8 (patch) | |
tree | a33c75c7ad2eedc6e0cbd811555fab85c81971fc /include/clang | |
parent | f805a6cc00b27ff0bcfc7f821e5d286c32a769ec (diff) |
Implement semantic analysis and an AST representation for the named
return value optimization. Sema marks return statements with their
NRVO candidates (which may or may not end up using the NRVO), then, at
the end of a function body, computes and marks those variables that
can be allocated into the return slot.
I've checked this locally with some debugging statements (not
committed), but there won't be any tests until CodeGen comes along.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103865 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 19 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 18 |
2 files changed, 34 insertions, 3 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 7b2300bc4e..a7c947afe6 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -519,6 +519,10 @@ private: /// or an Objective-C @catch statement. bool ExceptionVar : 1; + /// \brief Whether this local variable could be allocated in the return + /// slot of its function, enabling the named return value optimization (NRVO). + bool NRVOVariable : 1; + friend class StmtIteratorBase; protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -526,7 +530,7 @@ protected: StorageClass SCAsWritten) : DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(), ThreadSpecified(false), HasCXXDirectInit(false), - DeclaredInCondition(false), ExceptionVar(false) { + DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) { SClass = SC; SClassAsWritten = SCAsWritten; } @@ -869,6 +873,19 @@ public: } void setExceptionVariable(bool EV) { ExceptionVar = EV; } + /// \brief Determine whether this local variable can be used with the named + /// return value optimization (NRVO). + /// + /// The named return value optimization (NRVO) works by marking certain + /// non-volatile local variables of class type as NRVO objects. These + /// locals can be allocated within the return slot of their containing + /// function, in which case there is no need to copy the object to the + /// return slot when returning from the function. Within the function body, + /// each return that returns the NRVO object will have this variable as its + /// NRVO candidate. + bool isNRVOVariable() const { return NRVOVariable; } + void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; } + /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member /// from which it was instantiated. diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index bae6da00f5..f95c35a126 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1096,9 +1096,15 @@ public: class ReturnStmt : public Stmt { Stmt *RetExpr; SourceLocation RetLoc; + const VarDecl *NRVOCandidate; + public: - ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass), - RetExpr((Stmt*) E), RetLoc(RL) {} + ReturnStmt(SourceLocation RL) + : Stmt(ReturnStmtClass), RetExpr(0), NRVOCandidate(0) { } + + ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) + : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), + NRVOCandidate(NRVOCandidate) {} /// \brief Build an empty return expression. explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } @@ -1110,6 +1116,14 @@ public: SourceLocation getReturnLoc() const { return RetLoc; } void setReturnLoc(SourceLocation L) { RetLoc = L; } + /// \brief Retrieve the variable that might be used for the named return + /// value optimization. + /// + /// The optimization itself can only be performed if the variable is + /// also marked as an NRVO object. + const VarDecl *getNRVOCandidate() const { return NRVOCandidate; } + void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; } + virtual SourceRange getSourceRange() const; static bool classof(const Stmt *T) { |