Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h
213799 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// These classes wrap the information about a call or function9// definition used to handle ABI compliancy.10//11//===----------------------------------------------------------------------===//1213#ifndef CLANG_LIB_CODEGEN_CIRGENCALL_H14#define CLANG_LIB_CODEGEN_CIRGENCALL_H1516#include "CIRGenValue.h"17#include "mlir/IR/Operation.h"18#include "clang/AST/GlobalDecl.h"19#include "llvm/ADT/SmallVector.h"2021namespace clang::CIRGen {2223class CIRGenFunction;2425/// Abstract information about a function or function prototype.26class CIRGenCalleeInfo {27const clang::FunctionProtoType *calleeProtoTy;28clang::GlobalDecl calleeDecl;2930public:31explicit CIRGenCalleeInfo() : calleeProtoTy(nullptr), calleeDecl() {}32CIRGenCalleeInfo(const clang::FunctionProtoType *calleeProtoTy,33clang::GlobalDecl calleeDecl)34: calleeProtoTy(calleeProtoTy), calleeDecl(calleeDecl) {}35CIRGenCalleeInfo(clang::GlobalDecl calleeDecl)36: calleeProtoTy(nullptr), calleeDecl(calleeDecl) {}3738const clang::FunctionProtoType *getCalleeFunctionProtoType() const {39return calleeProtoTy;40}41clang::GlobalDecl getCalleeDecl() const { return calleeDecl; }42};4344class CIRGenCallee {45enum class SpecialKind : uintptr_t {46Invalid,47Builtin,4849Last = Builtin,50};5152struct BuiltinInfoStorage {53const clang::FunctionDecl *decl;54unsigned id;55};5657SpecialKind kindOrFunctionPtr;5859union {60CIRGenCalleeInfo abstractInfo;61BuiltinInfoStorage builtinInfo;62};6364explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {}6566public:67CIRGenCallee() : kindOrFunctionPtr(SpecialKind::Invalid) {}6869CIRGenCallee(const CIRGenCalleeInfo &abstractInfo, mlir::Operation *funcPtr)70: kindOrFunctionPtr(SpecialKind(reinterpret_cast<uintptr_t>(funcPtr))),71abstractInfo(abstractInfo) {72assert(funcPtr && "configuring callee without function pointer");73}7475static CIRGenCallee76forDirect(mlir::Operation *funcPtr,77const CIRGenCalleeInfo &abstractInfo = CIRGenCalleeInfo()) {78return CIRGenCallee(abstractInfo, funcPtr);79}8081bool isBuiltin() const { return kindOrFunctionPtr == SpecialKind::Builtin; }8283const clang::FunctionDecl *getBuiltinDecl() const {84assert(isBuiltin());85return builtinInfo.decl;86}87unsigned getBuiltinID() const {88assert(isBuiltin());89return builtinInfo.id;90}9192static CIRGenCallee forBuiltin(unsigned builtinID,93const clang::FunctionDecl *builtinDecl) {94CIRGenCallee result(SpecialKind::Builtin);95result.builtinInfo.decl = builtinDecl;96result.builtinInfo.id = builtinID;97return result;98}99100bool isOrdinary() const {101return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);102}103104/// If this is a delayed callee computation of some sort, prepare a concrete105/// callee106CIRGenCallee prepareConcreteCallee(CIRGenFunction &cgf) const;107108CIRGenCalleeInfo getAbstractInfo() const {109assert(!cir::MissingFeatures::opCallVirtual());110assert(isOrdinary());111return abstractInfo;112}113114mlir::Operation *getFunctionPointer() const {115assert(isOrdinary());116return reinterpret_cast<mlir::Operation *>(kindOrFunctionPtr);117}118};119120/// Type for representing both the decl and type of parameters to a function.121/// The decl must be either a ParmVarDecl or ImplicitParamDecl.122class FunctionArgList : public llvm::SmallVector<const clang::VarDecl *, 16> {};123124struct CallArg {125private:126union {127RValue rv;128LValue lv; // This argument is semantically a load from this l-value129};130bool hasLV;131132/// A data-flow flag to make sure getRValue and/or copyInto are not133/// called twice for duplicated IR emission.134mutable bool isUsed;135136public:137clang::QualType ty;138139CallArg(RValue rv, clang::QualType ty)140: rv(rv), hasLV(false), isUsed(false), ty(ty) {}141142CallArg(LValue lv, clang::QualType ty)143: lv(lv), hasLV(true), isUsed(false), ty(ty) {}144145bool hasLValue() const { return hasLV; }146147LValue getKnownLValue() const {148assert(hasLV && !isUsed);149return lv;150}151152RValue getKnownRValue() const {153assert(!hasLV && !isUsed);154return rv;155}156157bool isAggregate() const { return hasLV || rv.isAggregate(); }158};159160class CallArgList : public llvm::SmallVector<CallArg, 8> {161public:162void add(RValue rvalue, clang::QualType type) { emplace_back(rvalue, type); }163164void addUncopiedAggregate(LValue lvalue, clang::QualType type) {165emplace_back(lvalue, type);166}167168/// Add all the arguments from another CallArgList to this one. After doing169/// this, the old CallArgList retains its list of arguments, but must not170/// be used to emit a call.171void addFrom(const CallArgList &other) {172insert(end(), other.begin(), other.end());173// Classic codegen has handling for these here. We may not need it here for174// CIR, but if not we should implement equivalent handling in lowering.175assert(!cir::MissingFeatures::writebacks());176assert(!cir::MissingFeatures::cleanupsToDeactivate());177assert(!cir::MissingFeatures::stackBase());178}179};180181/// Contains the address where the return value of a function can be stored, and182/// whether the address is volatile or not.183class ReturnValueSlot {184Address addr = Address::invalid();185186public:187ReturnValueSlot() = default;188ReturnValueSlot(Address addr) : addr(addr) {}189190Address getValue() const { return addr; }191};192193} // namespace clang::CIRGen194195#endif // CLANG_LIB_CODEGEN_CIRGENCALL_H196197198