From 2c2344e32779459cb04d3c0eea7d221953af0201 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Thu, 22 Mar 2018 21:40:24 +0000 Subject: [PATCH] [CFG] [analyzer] NFC: Move construction context allocation into a helper method. Improve readability of ConstructionContext::createFromLayers(). Differential Revision: https://reviews.llvm.org/D44725 llvm-svn: 328249 --- clang/include/clang/Analysis/ConstructionContext.h | 36 +++++++++++--- clang/lib/Analysis/ConstructionContext.cpp | 55 ++++++++-------------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Analysis/ConstructionContext.h b/clang/include/clang/Analysis/ConstructionContext.h index 67657c9..0f1f8eb 100644 --- a/clang/include/clang/Analysis/ConstructionContext.h +++ b/clang/include/clang/Analysis/ConstructionContext.h @@ -118,6 +118,14 @@ protected: // via createFromLayers(). explicit ConstructionContext(Kind K) : K(K) {} +private: + // A helper function for constructing an instance into a bump vector context. + template + static T *create(BumpVectorContext &C, ArgTypes... Args) { + auto *CC = C.getAllocator().Allocate(); + return new (CC) T(Args...); + } + public: /// Consume the construction context layer, together with its parent layers, /// and wrap it up into a complete construction context. @@ -153,11 +161,13 @@ public: /// elidable copy-constructor from makeT() into var would also be a simple /// variable constructor handled by this class. class SimpleVariableConstructionContext : public VariableConstructionContext { -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit SimpleVariableConstructionContext(const DeclStmt *DS) : VariableConstructionContext(ConstructionContext::SimpleVariableKind, DS) {} +public: static bool classof(const ConstructionContext *CC) { return CC->getKind() == SimpleVariableKind; } @@ -176,13 +186,15 @@ class CXX17ElidedCopyVariableConstructionContext : public VariableConstructionContext { const CXXBindTemporaryExpr *BTE; -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit CXX17ElidedCopyVariableConstructionContext( const DeclStmt *DS, const CXXBindTemporaryExpr *BTE) : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) { assert(BTE); } +public: const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; } static bool classof(const ConstructionContext *CC) { @@ -195,7 +207,8 @@ public: class ConstructorInitializerConstructionContext : public ConstructionContext { const CXXCtorInitializer *I; -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit ConstructorInitializerConstructionContext( const CXXCtorInitializer *I) : ConstructionContext(ConstructionContext::ConstructorInitializerKind), @@ -203,6 +216,7 @@ public: assert(I); } +public: const CXXCtorInitializer *getCXXCtorInitializer() const { return I; } static bool classof(const ConstructionContext *CC) { @@ -215,13 +229,15 @@ public: class NewAllocatedObjectConstructionContext : public ConstructionContext { const CXXNewExpr *NE; -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE) : ConstructionContext(ConstructionContext::NewAllocatedObjectKind), NE(NE) { assert(NE); } +public: const CXXNewExpr *getCXXNewExpr() const { return NE; } static bool classof(const ConstructionContext *CC) { @@ -237,7 +253,8 @@ class TemporaryObjectConstructionContext : public ConstructionContext { const CXXBindTemporaryExpr *BTE; const MaterializeTemporaryExpr *MTE; -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit TemporaryObjectConstructionContext( const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE) : ConstructionContext(ConstructionContext::TemporaryObjectKind), @@ -248,6 +265,7 @@ public: // nowhere that doesn't have a non-trivial destructor). } +public: /// CXXBindTemporaryExpr here is non-null as long as the temporary has /// a non-trivial destructor. const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { @@ -295,11 +313,13 @@ public: /// MaterializeTemporaryExpr) is normally located in the caller function's AST. class SimpleReturnedValueConstructionContext : public ReturnedValueConstructionContext { -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS) : ReturnedValueConstructionContext( ConstructionContext::SimpleReturnedValueKind, RS) {} +public: static bool classof(const ConstructionContext *CC) { return CC->getKind() == SimpleReturnedValueKind; } @@ -317,7 +337,8 @@ class CXX17ElidedCopyReturnedValueConstructionContext : public ReturnedValueConstructionContext { const CXXBindTemporaryExpr *BTE; -public: + friend class ConstructionContext; // Allows to create<>() itself. + explicit CXX17ElidedCopyReturnedValueConstructionContext( const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE) : ReturnedValueConstructionContext( @@ -326,6 +347,7 @@ public: assert(BTE); } +public: const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; } static bool classof(const ConstructionContext *CC) { diff --git a/clang/lib/Analysis/ConstructionContext.cpp b/clang/lib/Analysis/ConstructionContext.cpp index 68e1cc0..31657df 100644 --- a/clang/lib/Analysis/ConstructionContext.cpp +++ b/clang/lib/Analysis/ConstructionContext.cpp @@ -48,15 +48,13 @@ const ConstructionContext *ConstructionContext::createFromLayers( if (const Stmt *S = TopLayer->getTriggerStmt()) { if (const auto *DS = dyn_cast(S)) { assert(TopLayer->isLast()); - auto *CC = - C.getAllocator().Allocate(); - return new (CC) SimpleVariableConstructionContext(DS); - } else if (const auto *NE = dyn_cast(S)) { + return create(C, DS); + } + if (const auto *NE = dyn_cast(S)) { assert(TopLayer->isLast()); - auto *CC = - C.getAllocator().Allocate(); - return new (CC) NewAllocatedObjectConstructionContext(NE); - } else if (const auto *BTE = dyn_cast(S)) { + return create(C, NE); + } + if (const auto *BTE = dyn_cast(S)) { const MaterializeTemporaryExpr *MTE = nullptr; assert(BTE->getType().getCanonicalType() ->getAsCXXRecordDecl()->hasNonTrivialDestructor()); @@ -68,9 +66,7 @@ const ConstructionContext *ConstructionContext::createFromLayers( ParentLayer->getTriggerStmt()))) { // A temporary object which has both destruction and // materialization info. - auto *CC = - C.getAllocator().Allocate(); - return new (CC) TemporaryObjectConstructionContext(BTE, MTE); + return create(C, BTE, MTE); } // C++17 *requires* elision of the constructor at the return site // and at variable initialization site, while previous standards @@ -78,50 +74,37 @@ const ConstructionContext *ConstructionContext::createFromLayers( if (auto *RS = dyn_cast(ParentLayer->getTriggerStmt())) { assert(!RS->getRetValue()->getType().getCanonicalType() ->getAsCXXRecordDecl()->hasTrivialDestructor()); - auto *CC = - C.getAllocator() - .Allocate< - CXX17ElidedCopyReturnedValueConstructionContext>(); - return new (CC) - CXX17ElidedCopyReturnedValueConstructionContext(RS, BTE); + return create(C, + RS, BTE); } if (auto *DS = dyn_cast(ParentLayer->getTriggerStmt())) { assert(!cast(DS->getSingleDecl())->getType() .getCanonicalType()->getAsCXXRecordDecl() ->hasTrivialDestructor()); - auto *CC = - C.getAllocator() - .Allocate(); - return new (CC) CXX17ElidedCopyVariableConstructionContext(DS, BTE); + return create(C, DS, BTE); } llvm_unreachable("Unexpected construction context with destructor!"); } // A temporary object that doesn't require materialization. - auto *CC = - C.getAllocator().Allocate(); - return new (CC) - TemporaryObjectConstructionContext(BTE, /*MTE=*/nullptr); - } else if (const auto *MTE = dyn_cast(S)) { + return create(C, BTE, /*MTE=*/nullptr); + } + if (const auto *MTE = dyn_cast(S)) { // If the object requires destruction and is not lifetime-extended, // then it must have a BTE within its MTE. assert(MTE->getType().getCanonicalType() ->getAsCXXRecordDecl()->hasTrivialDestructor() || MTE->getStorageDuration() != SD_FullExpression); assert(TopLayer->isLast()); - auto *CC = - C.getAllocator().Allocate(); - return new (CC) TemporaryObjectConstructionContext(nullptr, MTE); - } else if (const auto *RS = dyn_cast(S)) { + return create(C, nullptr, MTE); + } + if (const auto *RS = dyn_cast(S)) { assert(TopLayer->isLast()); - auto *CC = - C.getAllocator().Allocate(); - return new (CC) SimpleReturnedValueConstructionContext(RS); + return create(C, RS); } + llvm_unreachable("Unexpected construction context with statement!"); } else if (const CXXCtorInitializer *I = TopLayer->getTriggerInit()) { assert(TopLayer->isLast()); - auto *CC = - C.getAllocator().Allocate(); - return new (CC) ConstructorInitializerConstructionContext(I); + return create(C, I); } llvm_unreachable("Unexpected construction context!"); } -- 2.7.4