forked from OSchip/llvm-project
[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
This commit is contained in:
parent
317291e340
commit
2c2344e327
|
@ -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 <typename T, typename... ArgTypes>
|
||||
static T *create(BumpVectorContext &C, ArgTypes... Args) {
|
||||
auto *CC = C.getAllocator().Allocate<T>();
|
||||
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) {
|
||||
|
|
|
@ -48,15 +48,13 @@ const ConstructionContext *ConstructionContext::createFromLayers(
|
|||
if (const Stmt *S = TopLayer->getTriggerStmt()) {
|
||||
if (const auto *DS = dyn_cast<DeclStmt>(S)) {
|
||||
assert(TopLayer->isLast());
|
||||
auto *CC =
|
||||
C.getAllocator().Allocate<SimpleVariableConstructionContext>();
|
||||
return new (CC) SimpleVariableConstructionContext(DS);
|
||||
} else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
|
||||
return create<SimpleVariableConstructionContext>(C, DS);
|
||||
}
|
||||
if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
|
||||
assert(TopLayer->isLast());
|
||||
auto *CC =
|
||||
C.getAllocator().Allocate<NewAllocatedObjectConstructionContext>();
|
||||
return new (CC) NewAllocatedObjectConstructionContext(NE);
|
||||
} else if (const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(S)) {
|
||||
return create<NewAllocatedObjectConstructionContext>(C, NE);
|
||||
}
|
||||
if (const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(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<TemporaryObjectConstructionContext>();
|
||||
return new (CC) TemporaryObjectConstructionContext(BTE, MTE);
|
||||
return create<TemporaryObjectConstructionContext>(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<ReturnStmt>(ParentLayer->getTriggerStmt())) {
|
||||
assert(!RS->getRetValue()->getType().getCanonicalType()
|
||||
->getAsCXXRecordDecl()->hasTrivialDestructor());
|
||||
auto *CC =
|
||||
C.getAllocator()
|
||||
.Allocate<
|
||||
CXX17ElidedCopyReturnedValueConstructionContext>();
|
||||
return new (CC)
|
||||
CXX17ElidedCopyReturnedValueConstructionContext(RS, BTE);
|
||||
return create<CXX17ElidedCopyReturnedValueConstructionContext>(C,
|
||||
RS, BTE);
|
||||
}
|
||||
if (auto *DS = dyn_cast<DeclStmt>(ParentLayer->getTriggerStmt())) {
|
||||
assert(!cast<VarDecl>(DS->getSingleDecl())->getType()
|
||||
.getCanonicalType()->getAsCXXRecordDecl()
|
||||
->hasTrivialDestructor());
|
||||
auto *CC =
|
||||
C.getAllocator()
|
||||
.Allocate<CXX17ElidedCopyVariableConstructionContext>();
|
||||
return new (CC) CXX17ElidedCopyVariableConstructionContext(DS, BTE);
|
||||
return create<CXX17ElidedCopyVariableConstructionContext>(C, DS, BTE);
|
||||
}
|
||||
llvm_unreachable("Unexpected construction context with destructor!");
|
||||
}
|
||||
// A temporary object that doesn't require materialization.
|
||||
auto *CC =
|
||||
C.getAllocator().Allocate<TemporaryObjectConstructionContext>();
|
||||
return new (CC)
|
||||
TemporaryObjectConstructionContext(BTE, /*MTE=*/nullptr);
|
||||
} else if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(S)) {
|
||||
return create<TemporaryObjectConstructionContext>(C, BTE, /*MTE=*/nullptr);
|
||||
}
|
||||
if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(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<TemporaryObjectConstructionContext>();
|
||||
return new (CC) TemporaryObjectConstructionContext(nullptr, MTE);
|
||||
} else if (const auto *RS = dyn_cast<ReturnStmt>(S)) {
|
||||
assert(TopLayer->isLast());
|
||||
auto *CC =
|
||||
C.getAllocator().Allocate<SimpleReturnedValueConstructionContext>();
|
||||
return new (CC) SimpleReturnedValueConstructionContext(RS);
|
||||
return create<TemporaryObjectConstructionContext>(C, nullptr, MTE);
|
||||
}
|
||||
if (const auto *RS = dyn_cast<ReturnStmt>(S)) {
|
||||
assert(TopLayer->isLast());
|
||||
return create<SimpleReturnedValueConstructionContext>(C, RS);
|
||||
}
|
||||
llvm_unreachable("Unexpected construction context with statement!");
|
||||
} else if (const CXXCtorInitializer *I = TopLayer->getTriggerInit()) {
|
||||
assert(TopLayer->isLast());
|
||||
auto *CC =
|
||||
C.getAllocator().Allocate<ConstructorInitializerConstructionContext>();
|
||||
return new (CC) ConstructorInitializerConstructionContext(I);
|
||||
return create<ConstructorInitializerConstructionContext>(C, I);
|
||||
}
|
||||
llvm_unreachable("Unexpected construction context!");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue