Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
213799 views
//==-- CIRGenFunctionInfo.h - Representation of fn argument/return types ---==//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// Defines CIRGenFunctionInfo and associated types used in representing the9// CIR source types and ABI-coerced types for function arguments and10// return values.11//12//===----------------------------------------------------------------------===//1314#ifndef LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H15#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H1617#include "clang/AST/CanonicalType.h"18#include "clang/CIR/MissingFeatures.h"19#include "llvm/ADT/FoldingSet.h"20#include "llvm/Support/TrailingObjects.h"2122namespace clang::CIRGen {2324/// A class for recording the number of arguments that a function signature25/// requires.26class RequiredArgs {27/// The number of required arguments, or ~0 if the signature does not permit28/// optional arguments.29unsigned numRequired;3031public:32enum All_t { All };3334RequiredArgs(All_t _) : numRequired(~0U) {}35explicit RequiredArgs(unsigned n) : numRequired(n) { assert(n != ~0U); }3637unsigned getOpaqueData() const { return numRequired; }3839bool allowsOptionalArgs() const { return numRequired != ~0U; }4041/// Compute the arguments required by the given formal prototype, given that42/// there may be some additional, non-formal arguments in play.43///44/// If FD is not null, this will consider pass_object_size params in FD.45static RequiredArgs46getFromProtoWithExtraSlots(const clang::FunctionProtoType *prototype,47unsigned additional) {48if (!prototype->isVariadic())49return All;5051if (prototype->hasExtParameterInfos())52llvm_unreachable("NYI");5354return RequiredArgs(prototype->getNumParams() + additional);55}5657static RequiredArgs58getFromProtoWithExtraSlots(clang::CanQual<clang::FunctionProtoType> prototype,59unsigned additional) {60return getFromProtoWithExtraSlots(prototype.getTypePtr(), additional);61}6263unsigned getNumRequiredArgs() const {64assert(allowsOptionalArgs());65return numRequired;66}67};6869// The TrailingObjects for this class contain the function return type in the70// first CanQualType slot, followed by the argument types.71class CIRGenFunctionInfo final72: public llvm::FoldingSetNode,73private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {74RequiredArgs required;7576unsigned numArgs;7778CanQualType *getArgTypes() { return getTrailingObjects(); }79const CanQualType *getArgTypes() const { return getTrailingObjects(); }8081CIRGenFunctionInfo() : required(RequiredArgs::All) {}8283public:84static CIRGenFunctionInfo *create(CanQualType resultType,85llvm::ArrayRef<CanQualType> argTypes,86RequiredArgs required);8788void operator delete(void *p) { ::operator delete(p); }8990// Friending class TrailingObjects is apparantly not good enough for MSVC, so91// these have to be public.92friend class TrailingObjects;9394using const_arg_iterator = const CanQualType *;95using arg_iterator = CanQualType *;9697// This function has to be CamelCase because llvm::FoldingSet requires so.98// NOLINTNEXTLINE(readability-identifier-naming)99static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required,100CanQualType resultType,101llvm::ArrayRef<CanQualType> argTypes) {102id.AddBoolean(required.getOpaqueData());103resultType.Profile(id);104for (const CanQualType &arg : argTypes)105arg.Profile(id);106}107108// NOLINTNEXTLINE(readability-identifier-naming)109void Profile(llvm::FoldingSetNodeID &id) {110// If the Profile functions get out of sync, we can end up with incorrect111// function signatures, so we call the static Profile function here rather112// than duplicating the logic.113Profile(id, required, getReturnType(), arguments());114}115116llvm::ArrayRef<CanQualType> arguments() const {117return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);118}119120llvm::ArrayRef<CanQualType> requiredArguments() const {121return llvm::ArrayRef<CanQualType>(argTypesBegin(), getNumRequiredArgs());122}123124CanQualType getReturnType() const { return getArgTypes()[0]; }125126const_arg_iterator argTypesBegin() const { return getArgTypes() + 1; }127const_arg_iterator argTypesEnd() const { return getArgTypes() + 1 + numArgs; }128arg_iterator argTypesBegin() { return getArgTypes() + 1; }129arg_iterator argTypesEnd() { return getArgTypes() + 1 + numArgs; }130131unsigned argTypeSize() const { return numArgs; }132133llvm::MutableArrayRef<CanQualType> argTypes() {134return llvm::MutableArrayRef<CanQualType>(argTypesBegin(), numArgs);135}136llvm::ArrayRef<CanQualType> argTypes() const {137return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);138}139140bool isVariadic() const { return required.allowsOptionalArgs(); }141RequiredArgs getRequiredArgs() const { return required; }142unsigned getNumRequiredArgs() const {143return isVariadic() ? getRequiredArgs().getNumRequiredArgs()144: argTypeSize();145}146};147148} // namespace clang::CIRGen149150#endif151152153