From: Sebastian Redl Date: Thu, 22 Jan 2009 17:31:11 +0000 (+0000) Subject: Add a switch that allows disabling the smart pointers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07c487e5f73c3e6ea47a03b674a4a0f753adf90f;p=clang Add a switch that allows disabling the smart pointers. Uncomment the define in Ownership.h to disable the smart pointers. Disabled, the smart pointers no longer contain a pointer to the action, and no longer have special destruction or copying semantics. They are, compiler willing, raw pointers or ActionResult equivalents. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62767 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h index a04b81879e..2144481c3d 100644 --- a/include/clang/Parse/Ownership.h +++ b/include/clang/Parse/Ownership.h @@ -102,6 +102,9 @@ // move_* functions, which help the compiler out with some explicit // conversions. +// Flip this switch to measure performance impact of the smart pointers. +//#define DISABLE_SMART_POINTERS + namespace clang { // Basic @@ -178,6 +181,7 @@ namespace clang /// the individual pointers, not the array holding them. template class ASTMultiPtr; +#if !defined(DISABLE_SMART_POINTERS) namespace moving { /// Move emulation helper for ASTOwningResult. NEVER EVER use this class /// directly if you don't know what you're doing. @@ -221,13 +225,17 @@ namespace clang void release(); }; } +#endif template class ASTOwningPtr { +#if !defined(DISABLE_SMART_POINTERS) ActionBase *Actions; +#endif void *Node; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTPtrMover; ASTOwningPtr(ASTOwningPtr&); // DO NOT IMPLEMENT @@ -239,8 +247,10 @@ namespace clang (Actions->*Destroyer)(Node); } } +#endif public: +#if !defined(DISABLE_SMART_POINTERS) explicit ASTOwningPtr(ActionBase &actions) : Actions(&actions), Node(0) {} ASTOwningPtr(ActionBase &actions, void *node) @@ -257,21 +267,35 @@ namespace clang } /// Assignment from a raw pointer. Takes ownership - beware! - ASTOwningPtr & operator =(void *raw) - { + ASTOwningPtr & operator =(void *raw) { assert((Actions || !raw) && "Cannot assign non-null raw without Action"); Node = raw; return *this; } +#else // Different set if smart pointers are disabled + explicit ASTOwningPtr(ActionBase &) : Node(0) {} + ASTOwningPtr(ActionBase &, void *node) : Node(node) {} + // Normal copying operators are defined implicitly. + explicit ASTOwningPtr(void *ptr) : Node(ptr) {} + + ASTOwningPtr & operator =(void *raw) { + Node = raw; + return *this; + } +#endif /// Access to the raw pointer. void * get() const { return Node; } /// Release the raw pointer. void * take() { +#if !defined(DISABLE_SMART_POINTERS) void *tmp = Node; Node = 0; return tmp; +#else + return Node; +#endif } /// Alias for interface familiarity with unique_ptr. @@ -279,13 +303,12 @@ namespace clang return take(); } - /// Get the Action associated with the node. - ActionBase* getActions() const { return Actions; } - +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTPtrMover() { return moving::ASTPtrMover(*this); } +#endif }; template @@ -294,10 +317,12 @@ namespace clang ASTOwningPtr Ptr; bool Invalid; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTResultMover; ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT +#endif public: typedef ActionBase::ActionResult::UID> DumbResult; @@ -308,6 +333,7 @@ namespace clang : Ptr(actions, node), Invalid(false) {} ASTOwningResult(ActionBase &actions, const DumbResult &res) : Ptr(actions, res.Val), Invalid(res.isInvalid) {} +#if !defined(DISABLE_SMART_POINTERS) /// Move from another owning result ASTOwningResult(moving::ASTResultMover mover) : Ptr(moving::ASTPtrMover(mover->Ptr)), @@ -315,7 +341,13 @@ namespace clang /// Move from an owning pointer ASTOwningResult(moving::ASTPtrMover mover) : Ptr(mover), Invalid(false) {} +#else + // Normal copying semantics are defined implicitly. + // The fake movers need this: + explicit ASTOwningResult(void *ptr) : Ptr(ptr), Invalid(false) {} +#endif +#if !defined(DISABLE_SMART_POINTERS) /// Move assignment from another owning result ASTOwningResult & operator =(moving::ASTResultMover mover) { Ptr = move(mover->Ptr); @@ -329,6 +361,7 @@ namespace clang Invalid = false; return *this; } +#endif /// Assignment from a raw pointer. Takes ownership - beware! ASTOwningResult & operator =(void *raw) @@ -371,9 +404,7 @@ namespace clang return Ptr.take(); } - /// Get the Action associated with the node. - ActionBase* getActions() const { return Ptr.getActions(); } - +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTResultMover() { return moving::ASTResultMover(*this); @@ -383,15 +414,19 @@ namespace clang moving::ASTPtrMover ptr_move() { return moving::ASTPtrMover(Ptr); } +#endif }; template class ASTMultiPtr { +#if !defined(DISABLE_SMART_POINTERS) ActionBase &Actions; +#endif void **Nodes; unsigned Count; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTMultiMover; ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT @@ -404,8 +439,10 @@ namespace clang (Actions.*Destroyer)(Nodes[i]); } } +#endif public: +#if !defined(DISABLE_SMART_POINTERS) explicit ASTMultiPtr(ActionBase &actions) : Actions(actions), Nodes(0), Count(0) {} ASTMultiPtr(ActionBase &actions, void **nodes, unsigned count) @@ -415,7 +452,16 @@ namespace clang : Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) { mover.release(); } +#else + // Normal copying implicitly defined + explicit ASTMultiPtr(ActionBase &) : Nodes(0), Count(0) {} + ASTMultiPtr(ActionBase &, void **nodes, unsigned count) + : Nodes(nodes), Count(count) {} + // Fake mover in Parse/AstGuard.h needs this: + ASTMultiPtr(void **nodes, unsigned count) : Nodes(nodes), Count(count) {} +#endif +#if !defined(DISABLE_SMART_POINTERS) /// Move assignment ASTMultiPtr & operator =(moving::ASTMultiMover mover) { destroy(); @@ -424,6 +470,7 @@ namespace clang mover.release(); return *this; } +#endif /// Access to the raw pointers. void ** get() const { return Nodes; } @@ -432,18 +479,26 @@ namespace clang unsigned size() const { return Count; } void ** release() { +#if !defined(DISABLE_SMART_POINTERS) void **tmp = Nodes; Nodes = 0; Count = 0; return tmp; +#else + return Nodes; +#endif } +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTMultiMover() { return moving::ASTMultiMover(*this); } +#endif }; +#if !defined(DISABLE_SMART_POINTERS) + // Out-of-line implementations due to definition dependencies template inline @@ -481,6 +536,36 @@ namespace clang return ASTOwningResult(moving::ASTPtrMover(ptr)); } +#else + + // These versions are hopefully no-ops. + template inline + ASTOwningResult& move(ASTOwningResult &ptr) { + return ptr; + } + + template inline + ASTOwningPtr& move(ASTOwningPtr &ptr) { + return ptr; + } + + template inline + ASTMultiPtr& move(ASTMultiPtr &ptr) { + return ptr; + } + + template inline + ASTOwningPtr move_arg(ASTOwningResult &ptr) { + return ASTOwningPtr(ptr.take()); + } + + template inline + ASTOwningResult move_res(ASTOwningPtr &ptr) { + return ASTOwningResult(ptr.get()); + } + +#endif + } #endif diff --git a/lib/Parse/AstGuard.h b/lib/Parse/AstGuard.h index d755ea76c9..602fea51dc 100644 --- a/lib/Parse/AstGuard.h +++ b/lib/Parse/AstGuard.h @@ -26,6 +26,7 @@ namespace clang template class ASTVector : public llvm::SmallVector { private: +#if !defined(DISABLE_SMART_POINTERS) Action &Actions; bool Owns; @@ -40,18 +41,27 @@ namespace clang ASTVector(const ASTVector&); // DO NOT IMPLEMENT // Reference member prevents copy assignment. +#endif public: +#if !defined(DISABLE_SMART_POINTERS) ASTVector(Action &actions) : Actions(actions), Owns(true) {} ~ASTVector() { destroy(); } +#else + ASTVector(Action &) {} +#endif void **take() { +#if !defined(DISABLE_SMART_POINTERS) Owns = false; +#endif return &(*this)[0]; } +#if !defined(DISABLE_SMART_POINTERS) Action &getActions() const { return Actions; } +#endif }; /// A SmallVector of statements, with stack size 32 (as that is the only one @@ -62,7 +72,11 @@ namespace clang template inline ASTMultiPtr move_arg(ASTVector &vec) { +#if !defined(DISABLE_SMART_POINTERS) return ASTMultiPtr(vec.getActions(), vec.take(), vec.size()); +#else + return ASTMultiPtr(vec.take(), vec.size()); +#endif } }