brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 4f5754c Raw
152 lines · c
1//==-- CIRGenFunctionInfo.h - Representation of fn argument/return types ---==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Defines CIRGenFunctionInfo and associated types used in representing the10// CIR source types and ABI-coerced types for function arguments and11// return values.12//13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H16#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H17 18#include "clang/AST/CanonicalType.h"19#include "clang/CIR/MissingFeatures.h"20#include "llvm/ADT/FoldingSet.h"21#include "llvm/Support/TrailingObjects.h"22 23namespace clang::CIRGen {24 25/// A class for recording the number of arguments that a function signature26/// requires.27class RequiredArgs {28  /// The number of required arguments, or ~0 if the signature does not permit29  /// optional arguments.30  unsigned numRequired;31 32public:33  enum All_t { All };34 35  RequiredArgs(All_t _) : numRequired(~0U) {}36  explicit RequiredArgs(unsigned n) : numRequired(n) { assert(n != ~0U); }37 38  unsigned getOpaqueData() const { return numRequired; }39 40  bool allowsOptionalArgs() const { return numRequired != ~0U; }41 42  /// Compute the arguments required by the given formal prototype, given that43  /// there may be some additional, non-formal arguments in play.44  ///45  /// If FD is not null, this will consider pass_object_size params in FD.46  static RequiredArgs47  getFromProtoWithExtraSlots(const clang::FunctionProtoType *prototype,48                             unsigned additional) {49    if (!prototype->isVariadic())50      return All;51 52    if (prototype->hasExtParameterInfos())53      llvm_unreachable("NYI");54 55    return RequiredArgs(prototype->getNumParams() + additional);56  }57 58  static RequiredArgs59  getFromProtoWithExtraSlots(clang::CanQual<clang::FunctionProtoType> prototype,60                             unsigned additional) {61    return getFromProtoWithExtraSlots(prototype.getTypePtr(), additional);62  }63 64  unsigned getNumRequiredArgs() const {65    assert(allowsOptionalArgs());66    return numRequired;67  }68};69 70// The TrailingObjects for this class contain the function return type in the71// first CanQualType slot, followed by the argument types.72class CIRGenFunctionInfo final73    : public llvm::FoldingSetNode,74      private llvm::TrailingObjects<CIRGenFunctionInfo, CanQualType> {75  RequiredArgs required;76 77  unsigned numArgs;78 79  CanQualType *getArgTypes() { return getTrailingObjects(); }80  const CanQualType *getArgTypes() const { return getTrailingObjects(); }81 82  CIRGenFunctionInfo() : required(RequiredArgs::All) {}83 84public:85  static CIRGenFunctionInfo *create(CanQualType resultType,86                                    llvm::ArrayRef<CanQualType> argTypes,87                                    RequiredArgs required);88 89  void operator delete(void *p) { ::operator delete(p); }90 91  // Friending class TrailingObjects is apparantly not good enough for MSVC, so92  // these have to be public.93  friend class TrailingObjects;94 95  using const_arg_iterator = const CanQualType *;96  using arg_iterator = CanQualType *;97 98  // This function has to be CamelCase because llvm::FoldingSet requires so.99  // NOLINTNEXTLINE(readability-identifier-naming)100  static void Profile(llvm::FoldingSetNodeID &id, RequiredArgs required,101                      CanQualType resultType,102                      llvm::ArrayRef<CanQualType> argTypes) {103    id.AddBoolean(required.getOpaqueData());104    resultType.Profile(id);105    for (const CanQualType &arg : argTypes)106      arg.Profile(id);107  }108 109  // NOLINTNEXTLINE(readability-identifier-naming)110  void Profile(llvm::FoldingSetNodeID &id) {111    // If the Profile functions get out of sync, we can end up with incorrect112    // function signatures, so we call the static Profile function here rather113    // than duplicating the logic.114    Profile(id, required, getReturnType(), arguments());115  }116 117  llvm::ArrayRef<CanQualType> arguments() const {118    return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);119  }120 121  llvm::ArrayRef<CanQualType> requiredArguments() const {122    return llvm::ArrayRef<CanQualType>(argTypesBegin(), getNumRequiredArgs());123  }124 125  CanQualType getReturnType() const { return getArgTypes()[0]; }126 127  const_arg_iterator argTypesBegin() const { return getArgTypes() + 1; }128  const_arg_iterator argTypesEnd() const { return getArgTypes() + 1 + numArgs; }129  arg_iterator argTypesBegin() { return getArgTypes() + 1; }130  arg_iterator argTypesEnd() { return getArgTypes() + 1 + numArgs; }131 132  unsigned argTypeSize() const { return numArgs; }133 134  llvm::MutableArrayRef<CanQualType> argTypes() {135    return llvm::MutableArrayRef<CanQualType>(argTypesBegin(), numArgs);136  }137  llvm::ArrayRef<CanQualType> argTypes() const {138    return llvm::ArrayRef<CanQualType>(argTypesBegin(), numArgs);139  }140 141  bool isVariadic() const { return required.allowsOptionalArgs(); }142  RequiredArgs getRequiredArgs() const { return required; }143  unsigned getNumRequiredArgs() const {144    return isVariadic() ? getRequiredArgs().getNumRequiredArgs()145                        : argTypeSize();146  }147};148 149} // namespace clang::CIRGen150 151#endif152