[cfe-commits] r60782 - in /cfe/trunk: include/clang/Parse/Action.h include/clang/Parse/Ownership.h lib/Parse/AstGuard.h lib/Parse/Parser.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Tue Dec 9 11:36:22 PST 2008
Author: cornedbee
Date: Tue Dec 9 13:36:21 2008
New Revision: 60782
URL: http://llvm.org/viewvc/llvm-project?rev=60782&view=rev
Log:
Lay the groundwork for converting the entire parser-sema chain to smart pointers.
Added:
cfe/trunk/include/clang/Parse/Ownership.h
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/Parse/AstGuard.h
cfe/trunk/lib/Parse/Parser.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=60782&r1=60781&r2=60782&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Dec 9 13:36:21 2008
@@ -17,6 +17,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Parse/AccessSpecifier.h"
+#include "clang/Parse/Ownership.h"
namespace clang {
// Semantic.
@@ -49,15 +50,15 @@
/// isCurrentClassName(), which must be specified in order for the
/// parse to complete accurately. The MinimalAction class does this
/// bare-minimum of tracking to implement this functionality.
-class Action {
+class Action : public ActionBase {
public:
/// Out-of-line virtual destructor to provide home for this class.
virtual ~Action();
-
+
// Types - Though these don't actually enforce strong typing, they document
// what types are required to be identical for the actions.
- typedef void ExprTy;
- typedef void StmtTy;
+ typedef ActionBase::ExprTy ExprTy;
+ typedef ActionBase::StmtTy StmtTy;
typedef void DeclTy;
typedef void TypeTy;
typedef void AttrTy;
@@ -65,26 +66,6 @@
typedef void MemInitTy;
typedef void CXXScopeTy;
- /// ActionResult - This structure is used while parsing/acting on expressions,
- /// stmts, etc. It encapsulates both the object returned by the action, plus
- /// a sense of whether or not it is valid.
- template<unsigned UID>
- struct ActionResult {
- void *Val;
- bool isInvalid;
-
- ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
- template<typename ActualExprTy>
- ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
- ActionResult(const DiagnosticBuilder &) : Val(0), isInvalid(true) {}
-
- const ActionResult &operator=(void *RHS) {
- Val = RHS;
- isInvalid = false;
- return *this;
- }
- };
-
/// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
/// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
/// allowing for failure.
@@ -94,12 +75,20 @@
typedef ActionResult<3> BaseResult;
typedef ActionResult<4> MemInitResult;
- /// Deletion callbacks - Since the parser doesn't know the concrete types of
- /// the AST nodes being generated, it must do callbacks to delete objects when
- /// recovering from errors.
- virtual void DeleteExpr(ExprTy *E) {}
- virtual void DeleteStmt(StmtTy *E) {}
-
+ /// Same, but with ownership.
+ typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
+ typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
+ // Note that these will replace ExprResult and StmtResult when the transition
+ // is complete.
+
+ /// Single expressions or statements as arguments.
+ typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
+ typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
+
+ /// Multiple expressions or statements as arguments.
+ typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
+ typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
+
/// Statistics.
virtual void PrintStats() const {}
//===--------------------------------------------------------------------===//
Added: cfe/trunk/include/clang/Parse/Ownership.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Ownership.h?rev=60782&view=auto
==============================================================================
--- cfe/trunk/include/clang/Parse/Ownership.h (added)
+++ cfe/trunk/include/clang/Parse/Ownership.h Tue Dec 9 13:36:21 2008
@@ -0,0 +1,374 @@
+//===--- Ownership.h - Parser Ownership Helpers -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains classes for managing ownership of Stmt and Expr nodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_OWNERSHIP_H
+#define LLVM_CLANG_PARSE_OWNERSHIP_H
+
+namespace clang
+{
+ class DiagnosticBuilder;
+
+ /// ActionBase - A small part split from Action because of the horrible
+ /// definition order dependencies between Action and the smart pointers.
+ class ActionBase {
+ public:
+ /// Out-of-line virtual destructor to provide home for this class.
+ virtual ~ActionBase();
+
+ // Types - Though these don't actually enforce strong typing, they document
+ // what types are required to be identical for the actions.
+ typedef void ExprTy;
+ typedef void StmtTy;
+
+ /// ActionResult - This structure is used while parsing/acting on
+ /// expressions, stmts, etc. It encapsulates both the object returned by
+ /// the action, plus a sense of whether or not it is valid.
+ template<unsigned UID>
+ struct ActionResult {
+ void *Val;
+ bool isInvalid;
+
+ ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
+ template<typename ActualExprTy>
+ ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
+ ActionResult(const DiagnosticBuilder &) : Val(0), isInvalid(true) {}
+
+ const ActionResult &operator=(void *RHS) {
+ Val = RHS;
+ isInvalid = false;
+ return *this;
+ }
+ };
+
+ /// Deletion callbacks - Since the parser doesn't know the concrete types of
+ /// the AST nodes being generated, it must do callbacks to delete objects
+ /// when recovering from errors. These are in ActionBase because the smart
+ /// pointers need access to them.
+ virtual void DeleteExpr(ExprTy *E) {}
+ virtual void DeleteStmt(StmtTy *E) {}
+ };
+
+ /// ASTDestroyer - The type of an AST node destruction function pointer.
+ typedef void (ActionBase::*ASTDestroyer)(void *);
+
+ /// For the transition phase: translate from an ASTDestroyer to its
+ /// ActionResult UID.
+ template <ASTDestroyer Destroyer> struct DestroyerToUID;
+ template <> struct DestroyerToUID<&ActionBase::DeleteExpr> {
+ static const unsigned UID = 0;
+ };
+ template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
+ static const unsigned UID = 1;
+ };
+
+ /// ASTOwningResult - A moveable smart pointer for AST nodes that also
+ /// has an extra flag to indicate an additional success status.
+ template <ASTDestroyer Destroyer> class ASTOwningResult;
+
+ /// ASTOwningPtr - A moveable smart pointer for AST nodes.
+ template <ASTDestroyer Destroyer> class ASTOwningPtr;
+
+ /// ASTMultiPtr - A moveable smart pointer to multiple AST nodes. Only owns
+ /// the individual pointers, not the array holding them.
+ template <ASTDestroyer Destroyer> class ASTMultiPtr;
+
+ /// Move emulation helper for ASTOwningResult
+ template <ASTDestroyer Destroyer>
+ class ASTResultMover
+ {
+ ASTOwningResult<Destroyer> &Moved;
+
+ public:
+ ASTResultMover(ASTOwningResult<Destroyer> &moved) : Moved(moved) {}
+
+ ASTOwningResult<Destroyer> * operator ->() { return &Moved; }
+
+ // For the transition phase.
+ operator void*();
+
+ // For the transition phase.
+ operator ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID>();
+ };
+
+ /// Move emulation helper for ASTOwningPtr
+ template <ASTDestroyer Destroyer>
+ class ASTPtrMover
+ {
+ ASTOwningPtr<Destroyer> &Moved;
+
+ public:
+ ASTPtrMover(ASTOwningPtr<Destroyer> &moved) : Moved(moved) {}
+
+ ASTOwningPtr<Destroyer> * operator ->() { return &Moved; }
+
+ operator void*();
+ };
+
+ /// Move emulation helper for ASTMultiPtr
+ template <ASTDestroyer Destroyer>
+ class ASTMultiMover
+ {
+ ASTMultiPtr<Destroyer> &Moved;
+
+ public:
+ ASTMultiMover(ASTMultiPtr<Destroyer> &moved) : Moved(moved) {}
+
+ /// Reset the moved object's internal structures.
+ void release();
+ };
+
+ template <ASTDestroyer Destroyer>
+ class ASTOwningResult
+ {
+ ActionBase *Actions;
+ void *Node;
+ bool Invalid;
+
+ friend class ASTResultMover<Destroyer>;
+ friend class ASTOwningPtr<Destroyer>;
+
+ ASTOwningResult(const ASTOwningResult&); // DO NOT IMPLEMENT
+ ASTOwningResult& operator =(const ASTOwningResult&); // DO NOT IMPLEMENT
+
+ void destroy() {
+ if (Node) {
+ assert(Actions && "Owning pointer without Action owns node.");
+ (Actions->*Destroyer)(Node);
+ }
+ }
+
+ void * take() {
+ if (Invalid)
+ return 0;
+ return Node;
+ }
+
+ public:
+ // For convenience and compatibility.
+ ASTOwningResult(bool invalid = false)
+ : Actions(0), Node(0), Invalid(invalid) {}
+ // Same
+ ASTOwningResult(const DiagnosticBuilder &)
+ : Actions(0), Node(0), Invalid(true) {}
+ explicit ASTOwningResult(ActionBase &actions, bool invalid = false)
+ : Actions(&actions), Node(0), Invalid(invalid) {}
+ ASTOwningResult(ActionBase &actions, void *node)
+ : Actions(&actions), Node(node), Invalid(false) {}
+ /// Move from another owning result
+ ASTOwningResult(ASTResultMover<Destroyer> mover)
+ : Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {}
+ /// Move from an owning pointer
+ ASTOwningResult(ASTPtrMover<Destroyer> mover);
+
+ /// Move assignment from another owning result
+ ASTOwningResult & operator =(ASTResultMover<Destroyer> mover) {
+ Actions = mover->Actions;
+ Node = mover->take();
+ Invalid = mover->Invalid;
+ return *this;
+ }
+
+ /// Move assignment from an owning ptr
+ ASTOwningResult & operator =(ASTPtrMover<Destroyer> mover);
+
+ /// Assignment from a raw pointer. Takes ownership - beware!
+ ASTOwningResult & operator =(void *raw)
+ {
+ assert((!raw || Actions) &&
+ "Cannot have raw assignment when there's no Action");
+ Node = raw;
+ Invalid = false;
+ return *this;
+ }
+
+ /// Assignment from an ActionResult. Takes ownership - beware!
+ ASTOwningResult & operator =(
+ const ActionBase::ActionResult<DestroyerToUID<Destroyer>::UID> &res) {
+ assert((!res.Val || Actions) &&
+ "Cannot assign from ActionResult when there's no Action");
+ Node = res.Val;
+ Invalid = res.isInvalid;
+ return *this;
+ }
+
+ /// Access to the raw pointer.
+ void * get() const { return Node; }
+
+ bool isInvalid() const { return Invalid; }
+
+ /// Does this point to a usable AST node? To be usable, the node must be
+ /// valid and non-null.
+ bool isUsable() const { return !Invalid && Node; }
+
+ /// Move hook
+ ASTResultMover<Destroyer> move() {
+ return ASTResultMover<Destroyer>(*this);
+ }
+ };
+
+ template <ASTDestroyer Destroyer>
+ class ASTOwningPtr
+ {
+ ActionBase *Actions;
+ void *Node;
+
+ friend class ASTPtrMover<Destroyer>;
+ friend class ASTOwningResult<Destroyer>;
+
+ ASTOwningPtr(const ASTOwningPtr&); // DO NOT IMPLEMENT
+ ASTOwningPtr& operator =(const ASTOwningPtr&); // DO NOT IMPLEMENT
+
+ void destroy() {
+ if (Node) {
+ assert(Actions && "Owning pointer without Action owns node.");
+ (Actions->*Destroyer)(Node);
+ }
+ }
+
+ public:
+ explicit ASTOwningPtr(ActionBase &actions)
+ : Actions(&actions), Node(0) {}
+ ASTOwningPtr(ActionBase &actions, void *node)
+ : Actions(&actions), Node(node) {}
+ /// Move from another owning pointer
+ ASTOwningPtr(ASTPtrMover<Destroyer> mover)
+ : Actions(mover->Actions), Node(mover->take()) {}
+ /// Move from an owning result
+ ASTOwningPtr(ASTResultMover<Destroyer> mover);
+
+ /// Move assignment from another owning pointer
+ ASTOwningPtr & operator =(ASTPtrMover<Destroyer> mover) {
+ Actions = mover->Actions;
+ Node = mover->take();
+ return *this;
+ }
+
+ /// Move assignment from an owning result
+ ASTOwningPtr & operator =(ASTResultMover<Destroyer> mover);
+
+ /// Assignment from a raw pointer. Takes ownership - beware!
+ ASTOwningPtr & operator =(void *raw)
+ {
+ assert((Actions || !raw) && "Cannot assign non-null raw without Action");
+ Node = raw;
+ return *this;
+ }
+
+ /// Access to the raw pointer.
+ void * get() const { return Node; }
+
+ /// Move hook
+ ASTPtrMover<Destroyer> move() {
+ return ASTPtrMover<Destroyer>(*this);
+ }
+ };
+
+ template <ASTDestroyer Destroyer>
+ class ASTMultiPtr
+ {
+ ActionBase &Actions;
+ void **Nodes;
+ unsigned Count;
+
+ friend class ASTMultiMover<Destroyer>;
+
+ ASTMultiPtr(const ASTMultiPtr&); // DO NOT IMPLEMENT
+ // Reference member prevents copy assignment.
+
+ void destroy() {
+ assert((Count == 0 || Nodes) && "No nodes when count is not zero.");
+ for (unsigned i = 0; i < Count; ++i) {
+ if (Nodes[i])
+ (Actions.*Destroyer)(Nodes[i]);
+ }
+ }
+
+ public:
+ explicit ASTMultiPtr(ActionBase &actions)
+ : Actions(actions), Nodes(0), Count(0) {}
+ ASTMultiPtr(ActionBase &actions, void **nodes, unsigned count)
+ : Actions(actions), Nodes(nodes), Count(count) {}
+ /// Move constructor
+ ASTMultiPtr(ASTMultiMover<Destroyer> mover)
+ : Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) {
+ mover->Nodes = 0;
+ mover->Count = 0;
+ }
+
+ /// Move assignment
+ ASTMultiPtr & operator =(ASTMultiMover<Destroyer> mover) {
+ Actions = mover->Actions;
+ Nodes = mover->Nodes;
+ Count = mover->Count;
+ mover.release();
+ return *this;
+ }
+
+ /// Access to the raw pointers.
+ void ** get() const { return Nodes; }
+
+ /// Access to the count.
+ unsigned size() const { return Count; }
+
+ /// Move hook
+ ASTMultiMover<Destroyer> move() {
+ return ASTMultiMover<Destroyer>(*this);
+ }
+ };
+
+ // Out-of-line implementations due to definition dependencies
+
+ template <ASTDestroyer Destroyer> inline
+ ASTResultMover<Destroyer>::operator void*() {
+ return Moved.take();
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTPtrMover<Destroyer>::operator void*() {
+ return Moved.take();
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ void ASTMultiMover<Destroyer>::release() {
+ Moved.Nodes = 0;
+ Moved.Count = 0;
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningResult<Destroyer>::ASTOwningResult(ASTPtrMover<Destroyer> mover)
+ : Actions(mover->Actions), Node(mover->take()), Invalid(false) {}
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningResult<Destroyer> &
+ ASTOwningResult<Destroyer>::operator =(ASTPtrMover<Destroyer> mover) {
+ Actions = mover->Actions;
+ Node = mover->take();
+ Invalid = false;
+ return *this;
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningPtr<Destroyer>::ASTOwningPtr(ASTResultMover<Destroyer> mover)
+ : Actions(mover->Actions), Node(mover->take()) {
+ }
+
+ template <ASTDestroyer Destroyer> inline
+ ASTOwningPtr<Destroyer> &
+ ASTOwningPtr<Destroyer>::operator =(ASTResultMover<Destroyer> mover) {
+ Actions = mover->Actions;
+ Node = mover->take();
+ return *this;
+ }
+}
+
+#endif
Modified: cfe/trunk/lib/Parse/AstGuard.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AstGuard.h?rev=60782&r1=60781&r2=60782&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/AstGuard.h (original)
+++ cfe/trunk/lib/Parse/AstGuard.h Tue Dec 9 13:36:21 2008
@@ -19,11 +19,11 @@
namespace clang
{
- template <void (Action::*Destroyer)(void*)>
+ template <void (ActionBase::*Destroyer)(void*)>
class ASTOwner;
- typedef ASTOwner<&Action::DeleteStmt> StmtOwner;
- typedef ASTOwner<&Action::DeleteExpr> ExprOwner;
+ typedef ASTOwner<&ActionBase::DeleteStmt> StmtOwner;
+ typedef ASTOwner<&ActionBase::DeleteExpr> ExprOwner;
/// Some trickery to switch between an ActionResult and an ASTOwner
template <typename Owner> struct ResultOfOwner;
@@ -36,7 +36,7 @@
/// Move emulation helper for ASTOwner. Implicitly convertible to ActionResult
/// and void*, which means ASTOwner::move() can be used universally.
- template <void (Action::*Destroyer)(void*)>
+ template <void (ActionBase::*Destroyer)(void*)>
class ASTMove {
ASTOwner<Destroyer> &Moved;
@@ -62,7 +62,7 @@
};
/// RAII owning pointer for StmtTys and ExprTys. Simple move emulation.
- template <void (Action::*Destroyer)(void*)>
+ template <void (ActionBase::*Destroyer)(void*)>
class ASTOwner {
typedef typename ResultOfOwner<ASTOwner>::type Result;
@@ -136,7 +136,7 @@
/// automatically freeing them on destruction unless it's been disowned.
/// Instantiated for statements and expressions (Action::DeleteStmt and
/// Action::DeleteExpr).
- template <void (Action::*Destroyer)(void*), unsigned N>
+ template <void (ActionBase::*Destroyer)(void*), unsigned N>
class ASTVector : public llvm::SmallVector<void*, N> {
private:
Action &Actions;
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=60782&r1=60781&r2=60782&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Dec 9 13:36:21 2008
@@ -39,6 +39,9 @@
}
/// Out-of-line virtual destructor to provide home for Action class.
+ActionBase::~ActionBase() {}
+
+/// Out-of-line virtual destructor to provide home for Action class.
Action::~Action() {}
More information about the cfe-commits
mailing list