//===--- ConstantEmitter.h - IR constant emission ---------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// A helper class for emitting expressions and values as llvm::Constants
// and as initializers for global variables.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
#define LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H

#include "CodeGenFunction.h"
#include "CodeGenModule.h"

namespace clang {
namespace CodeGen {

class ConstantEmitter {
public:
  CodeGenModule &CGM;
  CodeGenFunction *const CGF;

private:
  bool Abstract = false;

  /// Whether non-abstract components of the emitter have been initialized.
  bool InitializedNonAbstract = false;

  /// Whether the emitter has been finalized.
  bool Finalized = false;

  /// Whether the constant-emission failed.
  bool Failed = false;

  /// Whether we're in a constant context.
  bool InConstantContext = false;

  /// The AST address space where this (non-abstract) initializer is going.
  /// Used for generating appropriate placeholders.
  LangAS DestAddressSpace = LangAS::Default;

  llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4>
    PlaceholderAddresses;

public:
  ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr)
    : CGM(CGM), CGF(CGF) {}

  /// Initialize this emission in the context of the given function.
  /// Use this if the expression might contain contextual references like
  /// block addresses or PredefinedExprs.
  ConstantEmitter(CodeGenFunction &CGF)
    : CGM(CGF.CGM), CGF(&CGF) {}

  ConstantEmitter(const ConstantEmitter &other) = delete;
  ConstantEmitter &operator=(const ConstantEmitter &other) = delete;

  ~ConstantEmitter();

  /// Is the current emission context abstract?
  bool isAbstract() const {
    return Abstract;
  }

  bool isInConstantContext() const { return InConstantContext; }
  void setInConstantContext(bool var) { InConstantContext = var; }

  /// Try to emit the initiaizer of the given declaration as an abstract
  /// constant.  If this succeeds, the emission must be finalized.
  llvm::Constant *tryEmitForInitializer(const VarDecl &D);
  llvm::Constant *tryEmitForInitializer(const Expr *E, LangAS destAddrSpace,
                                        QualType destType);
  llvm::Constant *emitForInitializer(const APValue &value, LangAS destAddrSpace,
                                     QualType destType);

  void finalize(llvm::GlobalVariable *global);

  // All of the "abstract" emission methods below permit the emission to
  // be immediately discarded without finalizing anything.  Therefore, they
  // must also promise not to do anything that will, in the future, require
  // finalization:
  //
  //   - using the CGF (if present) for anything other than establishing
  //     semantic context; for example, an expression with ignored
  //     side-effects must not be emitted as an abstract expression
  //
  //   - doing anything that would not be safe to duplicate within an
  //     initializer or to propagate to another context; for example,
  //     side effects, or emitting an initialization that requires a
  //     reference to its current location.

  /// Try to emit the initializer of the given declaration as an abstract
  /// constant.
  llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);

  /// Emit the result of the given expression as an abstract constant,
  /// asserting that it succeeded.  This is only safe to do when the
  /// expression is known to be a constant expression with either a fairly
  /// simple type or a known simple form.
  llvm::Constant *emitAbstract(const Expr *E, QualType T);
  llvm::Constant *
  emitAbstract(SourceLocation loc, const APValue &value, QualType T,
               bool EnablePtrAuthFunctionTypeDiscrimination = true);

  /// Try to emit the result of the given expression as an abstract constant.
  llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
  llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);

  llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
  llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);

  llvm::Constant *tryEmitConstantSignedPointer(llvm::Constant *Ptr,
                                               PointerAuthQualifier Auth);

  llvm::Constant *tryEmitConstantExpr(const ConstantExpr *CE);

  llvm::Constant *emitNullForMemory(QualType T) {
    return emitNullForMemory(CGM, T);
  }
  llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
    return emitForMemory(CGM, C, T);
  }

  static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
  static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
                                       QualType T);

  // These are private helper routines of the constant emitter that
  // can't actually be private because things are split out into helper
  // functions and classes.

  llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);

  llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
  llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);

  llvm::Constant *
  tryEmitPrivate(const APValue &value, QualType T,
                 bool EnablePtrAuthFunctionTypeDiscrimination = true);
  llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);

  /// Get the address of the current location.  This is a constant
  /// that will resolve, after finalization, to the address of the
  /// 'signal' value that is registered with the emitter later.
  llvm::GlobalValue *getCurrentAddrPrivate();

  /// Register a 'signal' value with the emitter to inform it where to
  /// resolve a placeholder.  The signal value must be unique in the
  /// initializer; it might, for example, be the address of a global that
  /// refers to the current-address value in its own initializer.
  ///
  /// Uses of the placeholder must be properly anchored before finalizing
  /// the emitter, e.g. by being installed as the initializer of a global
  /// variable.  That is, it must be possible to replaceAllUsesWith
  /// the placeholder with the proper address of the signal.
  void registerCurrentAddrPrivate(llvm::Constant *signal,
                                  llvm::GlobalValue *placeholder);

private:
  void initializeNonAbstract(LangAS destAS) {
    assert(!InitializedNonAbstract);
    InitializedNonAbstract = true;
    DestAddressSpace = destAS;
  }
  llvm::Constant *markIfFailed(llvm::Constant *init) {
    if (!init)
      Failed = true;
    return init;
  }

  struct AbstractState {
    bool OldValue;
    size_t OldPlaceholdersSize;
  };
  AbstractState pushAbstract() {
    AbstractState saved = { Abstract, PlaceholderAddresses.size() };
    Abstract = true;
    return saved;
  }
  llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState save);
};

}
}

#endif
