
This change adds support for bitfields CIR records can now contain bit fields. I’ve updated the `CIRGenBitFieldInfo` comment, which originally came from the incubator and was identical to the one in OGCodeGen, to better reflect the current implementation. Support for bitfields in unions big-endian architectures and `get` and `set` operations remains unimplemented and will be addressed in a future patch.
96 lines
4.0 KiB
C++
96 lines
4.0 KiB
C++
//===---- TargetInfo.h - Encapsulate target details -------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// These classes wrap the information about a call or function definition used
|
|
// to handle ABI compliancy.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_LIB_CIR_TARGETINFO_H
|
|
#define LLVM_CLANG_LIB_CIR_TARGETINFO_H
|
|
|
|
#include "ABIInfo.h"
|
|
#include "CIRGenTypes.h"
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
namespace clang::CIRGen {
|
|
|
|
/// isEmptyFieldForLayout - Return true if the field is "empty", that is,
|
|
/// either a zero-width bit-field or an isEmptyRecordForLayout.
|
|
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd);
|
|
|
|
/// isEmptyRecordForLayout - Return true if a structure contains only empty
|
|
/// base classes (per isEmptyRecordForLayout) and fields (per
|
|
/// isEmptyFieldForLayout). Note, C++ record fields are considered empty
|
|
/// if the [[no_unique_address]] attribute would have made them empty.
|
|
bool isEmptyRecordForLayout(const ASTContext &context, QualType t);
|
|
|
|
class TargetCIRGenInfo {
|
|
std::unique_ptr<ABIInfo> info;
|
|
|
|
public:
|
|
TargetCIRGenInfo(std::unique_ptr<ABIInfo> info) : info(std::move(info)) {}
|
|
|
|
virtual ~TargetCIRGenInfo() = default;
|
|
|
|
/// Returns ABI info helper for the target.
|
|
const ABIInfo &getABIInfo() const { return *info; }
|
|
|
|
/// Determine whether a call to an unprototyped functions under
|
|
/// the given calling convention should use the variadic
|
|
/// convention or the non-variadic convention.
|
|
///
|
|
/// There's a good reason to make a platform's variadic calling
|
|
/// convention be different from its non-variadic calling
|
|
/// convention: the non-variadic arguments can be passed in
|
|
/// registers (better for performance), and the variadic arguments
|
|
/// can be passed on the stack (also better for performance). If
|
|
/// this is done, however, unprototyped functions *must* use the
|
|
/// non-variadic convention, because C99 states that a call
|
|
/// through an unprototyped function type must succeed if the
|
|
/// function was defined with a non-variadic prototype with
|
|
/// compatible parameters. Therefore, splitting the conventions
|
|
/// makes it impossible to call a variadic function through an
|
|
/// unprototyped type. Since function prototypes came out in the
|
|
/// late 1970s, this is probably an acceptable trade-off.
|
|
/// Nonetheless, not all platforms are willing to make it, and in
|
|
/// particularly x86-64 bends over backwards to make the
|
|
/// conventions compatible.
|
|
///
|
|
/// The default is false. This is correct whenever:
|
|
/// - the conventions are exactly the same, because it does not
|
|
/// matter and the resulting IR will be somewhat prettier in
|
|
/// certain cases; or
|
|
/// - the conventions are substantively different in how they pass
|
|
/// arguments, because in this case using the variadic convention
|
|
/// will lead to C99 violations.
|
|
///
|
|
/// However, some platforms make the conventions identical except
|
|
/// for passing additional out-of-band information to a variadic
|
|
/// function: for example, x86-64 passes the number of SSE
|
|
/// arguments in %al. On these platforms, it is desirable to
|
|
/// call unprototyped functions using the variadic convention so
|
|
/// that unprototyped calls to varargs functions still succeed.
|
|
///
|
|
/// Relatedly, platforms which pass the fixed arguments to this:
|
|
/// A foo(B, C, D);
|
|
/// differently than they would pass them to this:
|
|
/// A foo(B, C, D, ...);
|
|
/// may need to adjust the debugger-support code in Sema to do the
|
|
/// right thing when calling a function with no know signature.
|
|
virtual bool isNoProtoCallVariadic(const FunctionNoProtoType *fnType) const;
|
|
};
|
|
|
|
std::unique_ptr<TargetCIRGenInfo> createX8664TargetCIRGenInfo(CIRGenTypes &cgt);
|
|
|
|
} // namespace clang::CIRGen
|
|
|
|
#endif // LLVM_CLANG_LIB_CIR_TARGETINFO_H
|