std::pair<Value *, bool> ESTreeIRGen::declareVariableOrGlobalProperty(
    Function *inFunc,
    VarDecl::Kind declKind,
    Identifier name) {
  Value *found = nameTable_.lookup(name);

  // If the variable is already declared in this scope, do not create a
  // second instance.
  if (found) {
    if (auto *var = llvh::dyn_cast<Variable>(found)) {
      if (var->getParent()->getFunction() == inFunc)
        return {found, false};
    } else {
      assert(
          llvh::isa<GlobalObjectProperty>(found) &&
          "Invalid value found in name table");
      if (inFunc->isGlobalScope())
        return {found, false};
    }
  }

  // Create a property if global scope, variable otherwise.
  Value *res;
  if (inFunc->isGlobalScope() && declKind == VarDecl::Kind::Var) {
    res = Builder.createGlobalObjectProperty(name, true);
  } else {
    Variable::DeclKind vdc;
    if (declKind == VarDecl::Kind::Let)
      vdc = Variable::DeclKind::Let;
    else if (declKind == VarDecl::Kind::Const)
      vdc = Variable::DeclKind::Const;
    else {
      assert(declKind == VarDecl::Kind::Var);
      vdc = Variable::DeclKind::Var;
    }

    auto *var = Builder.createVariable(inFunc->getFunctionScope(), vdc, name);

    // For "let" and "const" create the related TDZ flag.
    if (Variable::declKindNeedsTDZ(vdc) &&
        Mod->getContext().getCodeGenerationSettings().enableTDZ) {
      llvh::SmallString<32> strBuf{"tdz$"};
      strBuf.append(name.str());

      auto *related = Builder.createVariable(
          var->getParent(),
          Variable::DeclKind::Var,
          genAnonymousLabelName(strBuf));
      var->setRelatedVariable(related);
      related->setRelatedVariable(var);
    }

    res = var;
  }

  // Register the variable in the scoped hash table.
  nameTable_.insert(name, res);
  return {res, true};
}
std::pair<Value *, bool> ESTreeIRGen::declareVariableOrGlobalProperty(
    Function *inFunc,
    VarDecl::Kind declKind,
    Identifier name) {
  Value *found = nameTable_.lookup(name);

   
   
  if (found) {
    if (auto *var = llvh::dyn_cast<Variable>(found)) {
      if (var->getParent()->getFunction() == inFunc)
        return {found, false};
    } else {
      assert(
          llvh::isa<GlobalObjectProperty>(found) &&
          "Invalid value found in name table");
      if (inFunc->isGlobalScope())
        return {found, false};
    }
  }

   
  Value *res;
  if (inFunc->isGlobalScope() && declKind == VarDecl::Kind::Var) {
    res = Builder.createGlobalObjectProperty(name, true);
  } else {
    Variable::DeclKind vdc;
    if (declKind == VarDecl::Kind::Let)
      vdc = Variable::DeclKind::Let;
    else if (declKind == VarDecl::Kind::Const)
      vdc = Variable::DeclKind::Const;
    else {
      assert(declKind == VarDecl::Kind::Var);
      vdc = Variable::DeclKind::Var;
    }

    auto *var = Builder.createVariable(inFunc->getFunctionScope(), vdc, name);

     
    if (Variable::declKindNeedsTDZ(vdc) &&
        Mod->getContext().getCodeGenerationSettings().enableTDZ) {
      llvh::SmallString<32> strBuf{"tdz$"};
      strBuf.append(name.str());

      auto *related = Builder.createVariable(
          var->getParent(),
          Variable::DeclKind::Var,
          genAnonymousLabelName(strBuf));
      var->setRelatedVariable(related);
      related->setRelatedVariable(var);
    }

    res = var;
  }

   
  nameTable_.insert(name, res);
  return {res, true};
}