llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h
Andy Kaylor 58b91d10a4
[CIR][NFC] Upstream LValueBaseInfo handling (#134928)
Previous implementations that used the cir::LValue class omitted hanling
of the LValueBaseInfo class, which tracks information about the basis
for the LValue's alignment. As more code was upstreamed from the
incubator, we were accumulating technical debt by adding more places
where this wasn't handled correctly. This change puts the interfaces in
place to track this information.

The information being tracked isn't used yet, so no functional change is
intended. The tracking is being added now because it will become more
difficult to add it as more features are implemented.
2025-04-09 15:27:50 -07:00

191 lines
6.8 KiB
C++

//===--- CIRGenModule.h - Per-Module state for CIR gen ----------*- 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
//
//===----------------------------------------------------------------------===//
//
// This is the internal per-translation-unit state used for CIR translation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#include "CIRGenBuilder.h"
#include "CIRGenTypeCache.h"
#include "CIRGenTypes.h"
#include "CIRGenValue.h"
#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/TargetParser/Triple.h"
namespace clang {
class ASTContext;
class CodeGenOptions;
class Decl;
class GlobalDecl;
class LangOptions;
class TargetInfo;
class VarDecl;
namespace CIRGen {
enum ForDefinition_t : bool { NotForDefinition = false, ForDefinition = true };
/// This class organizes the cross-function state that is used while generating
/// CIR code.
class CIRGenModule : public CIRGenTypeCache {
CIRGenModule(CIRGenModule &) = delete;
CIRGenModule &operator=(CIRGenModule &) = delete;
public:
CIRGenModule(mlir::MLIRContext &mlirContext, clang::ASTContext &astContext,
const clang::CodeGenOptions &cgo,
clang::DiagnosticsEngine &diags);
~CIRGenModule() = default;
private:
CIRGenBuilderTy builder;
/// Hold Clang AST information.
clang::ASTContext &astContext;
const clang::LangOptions &langOpts;
const clang::CodeGenOptions &codeGenOpts;
/// A "module" matches a c/cpp source file: containing a list of functions.
mlir::ModuleOp theModule;
clang::DiagnosticsEngine &diags;
const clang::TargetInfo ⌖
CIRGenTypes genTypes;
public:
mlir::ModuleOp getModule() const { return theModule; }
CIRGenBuilderTy &getBuilder() { return builder; }
clang::ASTContext &getASTContext() const { return astContext; }
const clang::CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
CIRGenTypes &getTypes() { return genTypes; }
const clang::LangOptions &getLangOpts() const { return langOpts; }
mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); }
/// Helpers to convert the presumed location of Clang's SourceLocation to an
/// MLIR Location.
mlir::Location getLoc(clang::SourceLocation cLoc);
mlir::Location getLoc(clang::SourceRange cRange);
/// FIXME: this could likely be a common helper and not necessarily related
/// with codegen.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t,
LValueBaseInfo *baseInfo);
void emitTopLevelDecl(clang::Decl *decl);
bool verifyModule() const;
/// Return the address of the given function. If funcType is non-null, then
/// this function will use the specified type if it has to create it.
// TODO: this is a bit weird as `GetAddr` given we give back a FuncOp?
cir::FuncOp
getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType = nullptr,
bool forVTable = false, bool dontDefer = false,
ForDefinition_t isForDefinition = NotForDefinition);
/// Emit code for a single global function or variable declaration. Forward
/// declarations are emitted lazily.
void emitGlobal(clang::GlobalDecl gd);
mlir::Type convertType(clang::QualType type);
void emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op = nullptr);
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
void emitGlobalVarDefinition(const clang::VarDecl *vd,
bool isTentative = false);
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd);
/// Return the result of value-initializing the given type, i.e. a null
/// expression of the given type.
mlir::Value emitNullConstant(QualType t, mlir::Location loc);
cir::FuncOp
getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType,
clang::GlobalDecl gd, bool forVTable,
bool dontDefer = false, bool isThunk = false,
ForDefinition_t isForDefinition = NotForDefinition,
mlir::ArrayAttr extraAttrs = {});
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name,
cir::FuncType funcType,
const clang::FunctionDecl *funcDecl);
mlir::IntegerAttr getSize(CharUnits size) {
return builder.getSizeFromCharUnits(&getMLIRContext(), size);
}
const llvm::Triple &getTriple() const { return target.getTriple(); }
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
GVALinkage linkage,
bool isConstantVariable);
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd,
bool isConstant);
/// Helpers to emit "not yet implemented" error diagnostics
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
template <typename T>
DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature,
const T &name) {
unsigned diagID =
diags.getCustomDiagID(DiagnosticsEngine::Error,
"ClangIR code gen Not Yet Implemented: %0: %1");
return diags.Report(loc, diagID) << feature << name;
}
DiagnosticBuilder errorNYI(mlir::Location loc, llvm::StringRef feature) {
// TODO: Convert the location to a SourceLocation
unsigned diagID = diags.getCustomDiagID(
DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
return diags.Report(diagID) << feature;
}
DiagnosticBuilder errorNYI(llvm::StringRef feature) {
// TODO: Make a default location? currSrcLoc?
unsigned diagID = diags.getCustomDiagID(
DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
return diags.Report(diagID) << feature;
}
DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
template <typename T>
DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature,
const T &name) {
return errorNYI(loc.getBegin(), feature, name) << loc;
}
};
} // namespace CIRGen
} // namespace clang
#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H