//===- ConstructionContext.cpp - CFG constructor information --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the ConstructionContext class and its sub-classes,
// which represent various different ways of constructing C++ objects
// with the additional information the users may want to know about
// the constructor.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/ConstructionContext.h"
#include "clang/AST/ExprObjC.h"

using namespace clang;

const ConstructionContextLayer *
ConstructionContextLayer::create(BumpVectorContext &C,
                                 const ConstructionContextItem &Item,
                                 const ConstructionContextLayer *Parent) {
  ConstructionContextLayer *CC =
      C.getAllocator().Allocate<ConstructionContextLayer>();
  return new (CC) ConstructionContextLayer(Item, Parent);
}

bool ConstructionContextLayer::isStrictlyMoreSpecificThan(
    const ConstructionContextLayer *Other) const {
  const ConstructionContextLayer *Self = this;
  while (true) {
    if (!Other)
      return Self;
    if (!Self || !(Self->Item == Other->Item))
      return false;
    Self = Self->getParent();
    Other = Other->getParent();
  }
  llvm_unreachable("The above loop can only be terminated via return!");
}

const ConstructionContext *
ConstructionContext::createMaterializedTemporaryFromLayers(
    BumpVectorContext &C, const MaterializeTemporaryExpr *MTE,
    const CXXBindTemporaryExpr *BTE,
    const ConstructionContextLayer *ParentLayer) {
  assert(MTE);

  // If the object requires destruction and is not lifetime-extended,
  // then it must have a BTE within its MTE, otherwise it shouldn't.
  // FIXME: This should be an assertion.
  if (!BTE && !(MTE->getType().getCanonicalType()->getAsCXXRecordDecl()
                    ->hasTrivialDestructor() ||
                MTE->getStorageDuration() != SD_FullExpression)) {
    return nullptr;
  }

  // If the temporary is lifetime-extended, don't save the BTE,
  // because we don't need a temporary destructor, but an automatic
  // destructor.
  if (MTE->getStorageDuration() != SD_FullExpression) {
    BTE = nullptr;
  }

  // Handle pre-C++17 copy and move elision.
  const CXXConstructExpr *ElidedCE = nullptr;
  const ConstructionContext *ElidedCC = nullptr;
  if (ParentLayer) {
    const ConstructionContextItem &ElidedItem = ParentLayer->getItem();
    assert(ElidedItem.getKind() ==
           ConstructionContextItem::ElidableConstructorKind);
    ElidedCE = cast<CXXConstructExpr>(ElidedItem.getStmt());
    assert(ElidedCE->isElidable());
    // We're creating a construction context that might have already
    // been created elsewhere. Maybe we should unique our construction
    // contexts. That's what we often do, but in this case it's unlikely
    // to bring any benefits.
    ElidedCC = createFromLayers(C, ParentLayer->getParent());
    if (!ElidedCC) {
      // We may fail to create the elided construction context.
      // In this case, skip copy elision entirely.
      return create<SimpleTemporaryObjectConstructionContext>(C, BTE, MTE);
    }
    return create<ElidedTemporaryObjectConstructionContext>(
        C, BTE, MTE, ElidedCE, ElidedCC);
  }

  // This is a normal temporary.
  assert(!ParentLayer);
  return create<SimpleTemporaryObjectConstructionContext>(C, BTE, MTE);
}

const ConstructionContext *ConstructionContext::createBoundTemporaryFromLayers(
    BumpVectorContext &C, const CXXBindTemporaryExpr *BTE,
    const ConstructionContextLayer *ParentLayer) {
  if (!ParentLayer) {
    // A temporary object that doesn't require materialization.
    // In particular, it shouldn't require copy elision, because
    // copy/move constructors take a reference, which requires
    // materialization to obtain the glvalue.
    return create<SimpleTemporaryObjectConstructionContext>(C, BTE,
                                                            /*MTE=*/nullptr);
  }

  const ConstructionContextItem &ParentItem = ParentLayer->getItem();
  switch (ParentItem.getKind()) {
  case ConstructionContextItem::VariableKind: {
    const auto *DS = cast<DeclStmt>(ParentItem.getStmt());
    assert(!cast<VarDecl>(DS->getSingleDecl())->getType().getCanonicalType()
                            ->getAsCXXRecordDecl()->hasTrivialDestructor());
    return create<CXX17ElidedCopyVariableConstructionContext>(C, DS, BTE);
  }
  case ConstructionContextItem::NewAllocatorKind: {
    llvm_unreachable("This context does not accept a bound temporary!");
  }
  case ConstructionContextItem::ReturnKind: {
    assert(ParentLayer->isLast());
    const auto *RS = cast<ReturnStmt>(ParentItem.getStmt());
    assert(!RS->getRetValue()->getType().getCanonicalType()
              ->getAsCXXRecordDecl()->hasTrivialDestructor());
    return create<CXX17ElidedCopyReturnedValueConstructionContext>(C, RS,
                                                                   BTE);
  }

  case ConstructionContextItem::MaterializationKind: {
    // No assert. We may have an elidable copy on the grandparent layer.
    const auto *MTE = cast<MaterializeTemporaryExpr>(ParentItem.getStmt());
    return createMaterializedTemporaryFromLayers(C, MTE, BTE,
                                                 ParentLayer->getParent());
  }
  case ConstructionContextItem::TemporaryDestructorKind: {
    llvm_unreachable("Duplicate CXXBindTemporaryExpr in the AST!");
  }
  case ConstructionContextItem::ElidedDestructorKind: {
    llvm_unreachable("Elided destructor items are not produced by the CFG!");
  }
  case ConstructionContextItem::ElidableConstructorKind: {
    llvm_unreachable("Materialization is necessary to put temporary into a "
                     "copy or move constructor!");
  }
  case ConstructionContextItem::ArgumentKind: {
    assert(ParentLayer->isLast());
    const auto *E = cast<Expr>(ParentItem.getStmt());
    assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
           isa<ObjCMessageExpr>(E));
    return create<ArgumentConstructionContext>(C, E, ParentItem.getIndex(),
                                               BTE);
  }
  case ConstructionContextItem::InitializerKind: {
    assert(ParentLayer->isLast());
    const auto *I = ParentItem.getCXXCtorInitializer();
    assert(!I->getAnyMember()->getType().getCanonicalType()
             ->getAsCXXRecordDecl()->hasTrivialDestructor());
    return create<CXX17ElidedCopyConstructorInitializerConstructionContext>(
        C, I, BTE);
  }
  case ConstructionContextItem::LambdaCaptureKind: {
    assert(ParentLayer->isLast());
    const auto *E = cast<LambdaExpr>(ParentItem.getStmt());
    return create<LambdaCaptureConstructionContext>(C, E,
                                                    ParentItem.getIndex());
  }
  } // switch (ParentItem.getKind())

  llvm_unreachable("Unexpected construction context with destructor!");
}

const ConstructionContext *ConstructionContext::createFromLayers(
    BumpVectorContext &C, const ConstructionContextLayer *TopLayer) {
  // Before this point all we've had was a stockpile of arbitrary layers.
  // Now validate that it is shaped as one of the finite amount of expected
  // patterns.
  const ConstructionContextItem &TopItem = TopLayer->getItem();
  switch (TopItem.getKind()) {
  case ConstructionContextItem::VariableKind: {
    assert(TopLayer->isLast());
    const auto *DS = cast<DeclStmt>(TopItem.getStmt());
    return create<SimpleVariableConstructionContext>(C, DS);
  }
  case ConstructionContextItem::NewAllocatorKind: {
    assert(TopLayer->isLast());
    const auto *NE = cast<CXXNewExpr>(TopItem.getStmt());
    return create<NewAllocatedObjectConstructionContext>(C, NE);
  }
  case ConstructionContextItem::ReturnKind: {
    assert(TopLayer->isLast());
    const auto *RS = cast<ReturnStmt>(TopItem.getStmt());
    return create<SimpleReturnedValueConstructionContext>(C, RS);
  }
  case ConstructionContextItem::MaterializationKind: {
    const auto *MTE = cast<MaterializeTemporaryExpr>(TopItem.getStmt());
    return createMaterializedTemporaryFromLayers(C, MTE, /*BTE=*/nullptr,
                                                 TopLayer->getParent());
  }
  case ConstructionContextItem::TemporaryDestructorKind: {
    const auto *BTE = cast<CXXBindTemporaryExpr>(TopItem.getStmt());
    assert(BTE->getType().getCanonicalType()->getAsCXXRecordDecl()
              ->hasNonTrivialDestructor());
    return createBoundTemporaryFromLayers(C, BTE, TopLayer->getParent());
  }
  case ConstructionContextItem::ElidedDestructorKind: {
    llvm_unreachable("Elided destructor items are not produced by the CFG!");
  }
  case ConstructionContextItem::ElidableConstructorKind: {
    llvm_unreachable("The argument needs to be materialized first!");
  }
  case ConstructionContextItem::LambdaCaptureKind: {
    assert(TopLayer->isLast());
    const auto *E = cast<LambdaExpr>(TopItem.getStmt());
    return create<LambdaCaptureConstructionContext>(C, E, TopItem.getIndex());
  }
  case ConstructionContextItem::InitializerKind: {
    assert(TopLayer->isLast());
    const CXXCtorInitializer *I = TopItem.getCXXCtorInitializer();
    return create<SimpleConstructorInitializerConstructionContext>(C, I);
  }
  case ConstructionContextItem::ArgumentKind: {
    assert(TopLayer->isLast());
    const auto *E = cast<Expr>(TopItem.getStmt());
    return create<ArgumentConstructionContext>(C, E, TopItem.getIndex(),
                                               /*BTE=*/nullptr);
  }
  } // switch (TopItem.getKind())
  llvm_unreachable("Unexpected construction context!");
}
