1*700637cbSDimitry Andric //===--- CIRGenModule.h - Per-Module state for CIR gen ----------*- C++ -*-===// 2*700637cbSDimitry Andric // 3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*700637cbSDimitry Andric // 7*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 8*700637cbSDimitry Andric // 9*700637cbSDimitry Andric // This is the internal per-translation-unit state used for CIR translation. 10*700637cbSDimitry Andric // 11*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric #ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H 14*700637cbSDimitry Andric #define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H 15*700637cbSDimitry Andric 16*700637cbSDimitry Andric #include "CIRGenBuilder.h" 17*700637cbSDimitry Andric #include "CIRGenCall.h" 18*700637cbSDimitry Andric #include "CIRGenTypeCache.h" 19*700637cbSDimitry Andric #include "CIRGenTypes.h" 20*700637cbSDimitry Andric #include "CIRGenValue.h" 21*700637cbSDimitry Andric 22*700637cbSDimitry Andric #include "clang/AST/CharUnits.h" 23*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRDataLayout.h" 24*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIRDialect.h" 25*700637cbSDimitry Andric 26*700637cbSDimitry Andric #include "TargetInfo.h" 27*700637cbSDimitry Andric #include "mlir/IR/Builders.h" 28*700637cbSDimitry Andric #include "mlir/IR/BuiltinOps.h" 29*700637cbSDimitry Andric #include "mlir/IR/MLIRContext.h" 30*700637cbSDimitry Andric #include "clang/AST/Decl.h" 31*700637cbSDimitry Andric #include "clang/Basic/SourceManager.h" 32*700637cbSDimitry Andric #include "clang/Basic/TargetInfo.h" 33*700637cbSDimitry Andric #include "clang/CIR/Dialect/IR/CIROpsEnums.h" 34*700637cbSDimitry Andric #include "llvm/ADT/StringRef.h" 35*700637cbSDimitry Andric #include "llvm/TargetParser/Triple.h" 36*700637cbSDimitry Andric 37*700637cbSDimitry Andric namespace clang { 38*700637cbSDimitry Andric class ASTContext; 39*700637cbSDimitry Andric class CodeGenOptions; 40*700637cbSDimitry Andric class Decl; 41*700637cbSDimitry Andric class GlobalDecl; 42*700637cbSDimitry Andric class LangOptions; 43*700637cbSDimitry Andric class TargetInfo; 44*700637cbSDimitry Andric class VarDecl; 45*700637cbSDimitry Andric 46*700637cbSDimitry Andric namespace CIRGen { 47*700637cbSDimitry Andric 48*700637cbSDimitry Andric class CIRGenFunction; 49*700637cbSDimitry Andric class CIRGenCXXABI; 50*700637cbSDimitry Andric 51*700637cbSDimitry Andric enum ForDefinition_t : bool { NotForDefinition = false, ForDefinition = true }; 52*700637cbSDimitry Andric 53*700637cbSDimitry Andric /// This class organizes the cross-function state that is used while generating 54*700637cbSDimitry Andric /// CIR code. 55*700637cbSDimitry Andric class CIRGenModule : public CIRGenTypeCache { 56*700637cbSDimitry Andric CIRGenModule(CIRGenModule &) = delete; 57*700637cbSDimitry Andric CIRGenModule &operator=(CIRGenModule &) = delete; 58*700637cbSDimitry Andric 59*700637cbSDimitry Andric public: 60*700637cbSDimitry Andric CIRGenModule(mlir::MLIRContext &mlirContext, clang::ASTContext &astContext, 61*700637cbSDimitry Andric const clang::CodeGenOptions &cgo, 62*700637cbSDimitry Andric clang::DiagnosticsEngine &diags); 63*700637cbSDimitry Andric 64*700637cbSDimitry Andric ~CIRGenModule(); 65*700637cbSDimitry Andric 66*700637cbSDimitry Andric private: 67*700637cbSDimitry Andric mutable std::unique_ptr<TargetCIRGenInfo> theTargetCIRGenInfo; 68*700637cbSDimitry Andric 69*700637cbSDimitry Andric CIRGenBuilderTy builder; 70*700637cbSDimitry Andric 71*700637cbSDimitry Andric /// Hold Clang AST information. 72*700637cbSDimitry Andric clang::ASTContext &astContext; 73*700637cbSDimitry Andric 74*700637cbSDimitry Andric const clang::LangOptions &langOpts; 75*700637cbSDimitry Andric 76*700637cbSDimitry Andric const clang::CodeGenOptions &codeGenOpts; 77*700637cbSDimitry Andric 78*700637cbSDimitry Andric /// A "module" matches a c/cpp source file: containing a list of functions. 79*700637cbSDimitry Andric mlir::ModuleOp theModule; 80*700637cbSDimitry Andric 81*700637cbSDimitry Andric clang::DiagnosticsEngine &diags; 82*700637cbSDimitry Andric 83*700637cbSDimitry Andric const clang::TargetInfo ⌖ 84*700637cbSDimitry Andric 85*700637cbSDimitry Andric std::unique_ptr<CIRGenCXXABI> abi; 86*700637cbSDimitry Andric 87*700637cbSDimitry Andric CIRGenTypes genTypes; 88*700637cbSDimitry Andric 89*700637cbSDimitry Andric /// Per-function codegen information. Updated everytime emitCIR is called 90*700637cbSDimitry Andric /// for FunctionDecls's. 91*700637cbSDimitry Andric CIRGenFunction *curCGF = nullptr; 92*700637cbSDimitry Andric 93*700637cbSDimitry Andric public: getModule()94*700637cbSDimitry Andric mlir::ModuleOp getModule() const { return theModule; } getBuilder()95*700637cbSDimitry Andric CIRGenBuilderTy &getBuilder() { return builder; } getASTContext()96*700637cbSDimitry Andric clang::ASTContext &getASTContext() const { return astContext; } getTarget()97*700637cbSDimitry Andric const clang::TargetInfo &getTarget() const { return target; } getCodeGenOpts()98*700637cbSDimitry Andric const clang::CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; } getTypes()99*700637cbSDimitry Andric CIRGenTypes &getTypes() { return genTypes; } getLangOpts()100*700637cbSDimitry Andric const clang::LangOptions &getLangOpts() const { return langOpts; } 101*700637cbSDimitry Andric getCXXABI()102*700637cbSDimitry Andric CIRGenCXXABI &getCXXABI() const { return *abi; } getMLIRContext()103*700637cbSDimitry Andric mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); } 104*700637cbSDimitry Andric getDataLayout()105*700637cbSDimitry Andric const cir::CIRDataLayout getDataLayout() const { 106*700637cbSDimitry Andric // FIXME(cir): instead of creating a CIRDataLayout every time, set it as an 107*700637cbSDimitry Andric // attribute for the CIRModule class. 108*700637cbSDimitry Andric return cir::CIRDataLayout(theModule); 109*700637cbSDimitry Andric } 110*700637cbSDimitry Andric 111*700637cbSDimitry Andric /// ------- 112*700637cbSDimitry Andric /// Handling globals 113*700637cbSDimitry Andric /// ------- 114*700637cbSDimitry Andric 115*700637cbSDimitry Andric mlir::Operation *lastGlobalOp = nullptr; 116*700637cbSDimitry Andric 117*700637cbSDimitry Andric llvm::DenseMap<const Decl *, cir::GlobalOp> staticLocalDeclMap; 118*700637cbSDimitry Andric 119*700637cbSDimitry Andric mlir::Operation *getGlobalValue(llvm::StringRef ref); 120*700637cbSDimitry Andric getStaticLocalDeclAddress(const VarDecl * d)121*700637cbSDimitry Andric cir::GlobalOp getStaticLocalDeclAddress(const VarDecl *d) { 122*700637cbSDimitry Andric return staticLocalDeclMap[d]; 123*700637cbSDimitry Andric } 124*700637cbSDimitry Andric setStaticLocalDeclAddress(const VarDecl * d,cir::GlobalOp c)125*700637cbSDimitry Andric void setStaticLocalDeclAddress(const VarDecl *d, cir::GlobalOp c) { 126*700637cbSDimitry Andric staticLocalDeclMap[d] = c; 127*700637cbSDimitry Andric } 128*700637cbSDimitry Andric 129*700637cbSDimitry Andric cir::GlobalOp getOrCreateStaticVarDecl(const VarDecl &d, 130*700637cbSDimitry Andric cir::GlobalLinkageKind linkage); 131*700637cbSDimitry Andric 132*700637cbSDimitry Andric /// If the specified mangled name is not in the module, create and return an 133*700637cbSDimitry Andric /// mlir::GlobalOp value 134*700637cbSDimitry Andric cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, 135*700637cbSDimitry Andric LangAS langAS, const VarDecl *d, 136*700637cbSDimitry Andric ForDefinition_t isForDefinition); 137*700637cbSDimitry Andric 138*700637cbSDimitry Andric cir::GlobalOp getOrCreateCIRGlobal(const VarDecl *d, mlir::Type ty, 139*700637cbSDimitry Andric ForDefinition_t isForDefinition); 140*700637cbSDimitry Andric 141*700637cbSDimitry Andric static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, 142*700637cbSDimitry Andric llvm::StringRef name, mlir::Type t, 143*700637cbSDimitry Andric mlir::Operation *insertPoint = nullptr); 144*700637cbSDimitry Andric 145*700637cbSDimitry Andric llvm::StringMap<unsigned> cgGlobalNames; 146*700637cbSDimitry Andric std::string getUniqueGlobalName(const std::string &baseName); 147*700637cbSDimitry Andric 148*700637cbSDimitry Andric /// Return the mlir::Value for the address of the given global variable. 149*700637cbSDimitry Andric /// If Ty is non-null and if the global doesn't exist, then it will be created 150*700637cbSDimitry Andric /// with the specified type instead of whatever the normal requested type 151*700637cbSDimitry Andric /// would be. If IsForDefinition is true, it is guaranteed that an actual 152*700637cbSDimitry Andric /// global with type Ty will be returned, not conversion of a variable with 153*700637cbSDimitry Andric /// the same mangled name but some other type. 154*700637cbSDimitry Andric mlir::Value 155*700637cbSDimitry Andric getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty = {}, 156*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition); 157*700637cbSDimitry Andric 158*700637cbSDimitry Andric CharUnits computeNonVirtualBaseClassOffset( 159*700637cbSDimitry Andric const CXXRecordDecl *derivedClass, 160*700637cbSDimitry Andric llvm::iterator_range<CastExpr::path_const_iterator> path); 161*700637cbSDimitry Andric 162*700637cbSDimitry Andric /// Get the CIR attributes and calling convention to use for a particular 163*700637cbSDimitry Andric /// function type. 164*700637cbSDimitry Andric /// 165*700637cbSDimitry Andric /// \param calleeInfo - The callee information these attributes are being 166*700637cbSDimitry Andric /// constructed for. If valid, the attributes applied to this decl may 167*700637cbSDimitry Andric /// contribute to the function attributes and calling convention. 168*700637cbSDimitry Andric void constructAttributeList(CIRGenCalleeInfo calleeInfo, 169*700637cbSDimitry Andric mlir::NamedAttrList &attrs); 170*700637cbSDimitry Andric 171*700637cbSDimitry Andric /// Return a constant array for the given string. 172*700637cbSDimitry Andric mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e); 173*700637cbSDimitry Andric 174*700637cbSDimitry Andric /// Return a global symbol reference to a constant array for the given string 175*700637cbSDimitry Andric /// literal. 176*700637cbSDimitry Andric cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, 177*700637cbSDimitry Andric llvm::StringRef name = ".str"); 178*700637cbSDimitry Andric 179*700637cbSDimitry Andric /// Set attributes which are common to any form of a global definition (alias, 180*700637cbSDimitry Andric /// Objective-C method, function, global variable). 181*700637cbSDimitry Andric /// 182*700637cbSDimitry Andric /// NOTE: This should only be called for definitions. 183*700637cbSDimitry Andric void setCommonAttributes(GlobalDecl gd, mlir::Operation *op); 184*700637cbSDimitry Andric 185*700637cbSDimitry Andric const TargetCIRGenInfo &getTargetCIRGenInfo(); 186*700637cbSDimitry Andric 187*700637cbSDimitry Andric /// Helpers to convert the presumed location of Clang's SourceLocation to an 188*700637cbSDimitry Andric /// MLIR Location. 189*700637cbSDimitry Andric mlir::Location getLoc(clang::SourceLocation cLoc); 190*700637cbSDimitry Andric mlir::Location getLoc(clang::SourceRange cRange); 191*700637cbSDimitry Andric 192*700637cbSDimitry Andric /// Return the best known alignment for an unknown pointer to a 193*700637cbSDimitry Andric /// particular class. 194*700637cbSDimitry Andric clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd); 195*700637cbSDimitry Andric 196*700637cbSDimitry Andric /// FIXME: this could likely be a common helper and not necessarily related 197*700637cbSDimitry Andric /// with codegen. 198*700637cbSDimitry Andric clang::CharUnits getNaturalTypeAlignment(clang::QualType t, 199*700637cbSDimitry Andric LValueBaseInfo *baseInfo); 200*700637cbSDimitry Andric 201*700637cbSDimitry Andric cir::FuncOp 202*700637cbSDimitry Andric getAddrOfCXXStructor(clang::GlobalDecl gd, 203*700637cbSDimitry Andric const CIRGenFunctionInfo *fnInfo = nullptr, 204*700637cbSDimitry Andric cir::FuncType fnType = nullptr, bool dontDefer = false, 205*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition) { 206*700637cbSDimitry Andric return getAddrAndTypeOfCXXStructor(gd, fnInfo, fnType, dontDefer, 207*700637cbSDimitry Andric isForDefinition) 208*700637cbSDimitry Andric .second; 209*700637cbSDimitry Andric } 210*700637cbSDimitry Andric 211*700637cbSDimitry Andric std::pair<cir::FuncType, cir::FuncOp> getAddrAndTypeOfCXXStructor( 212*700637cbSDimitry Andric clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo = nullptr, 213*700637cbSDimitry Andric cir::FuncType fnType = nullptr, bool dontDefer = false, 214*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition); 215*700637cbSDimitry Andric 216*700637cbSDimitry Andric /// This contains all the decls which have definitions but which are deferred 217*700637cbSDimitry Andric /// for emission and therefore should only be output if they are actually 218*700637cbSDimitry Andric /// used. If a decl is in this, then it is known to have not been referenced 219*700637cbSDimitry Andric /// yet. 220*700637cbSDimitry Andric std::map<llvm::StringRef, clang::GlobalDecl> deferredDecls; 221*700637cbSDimitry Andric 222*700637cbSDimitry Andric // This is a list of deferred decls which we have seen that *are* actually 223*700637cbSDimitry Andric // referenced. These get code generated when the module is done. 224*700637cbSDimitry Andric std::vector<clang::GlobalDecl> deferredDeclsToEmit; addDeferredDeclToEmit(clang::GlobalDecl GD)225*700637cbSDimitry Andric void addDeferredDeclToEmit(clang::GlobalDecl GD) { 226*700637cbSDimitry Andric deferredDeclsToEmit.emplace_back(GD); 227*700637cbSDimitry Andric } 228*700637cbSDimitry Andric 229*700637cbSDimitry Andric void emitTopLevelDecl(clang::Decl *decl); 230*700637cbSDimitry Andric 231*700637cbSDimitry Andric /// Determine whether the definition must be emitted; if this returns \c 232*700637cbSDimitry Andric /// false, the definition can be emitted lazily if it's used. 233*700637cbSDimitry Andric bool mustBeEmitted(const clang::ValueDecl *d); 234*700637cbSDimitry Andric 235*700637cbSDimitry Andric /// Determine whether the definition can be emitted eagerly, or should be 236*700637cbSDimitry Andric /// delayed until the end of the translation unit. This is relevant for 237*700637cbSDimitry Andric /// definitions whose linkage can change, e.g. implicit function 238*700637cbSDimitry Andric /// instantiations which may later be explicitly instantiated. 239*700637cbSDimitry Andric bool mayBeEmittedEagerly(const clang::ValueDecl *d); 240*700637cbSDimitry Andric 241*700637cbSDimitry Andric bool verifyModule() const; 242*700637cbSDimitry Andric 243*700637cbSDimitry Andric /// Return the address of the given function. If funcType is non-null, then 244*700637cbSDimitry Andric /// this function will use the specified type if it has to create it. 245*700637cbSDimitry Andric // TODO: this is a bit weird as `GetAddr` given we give back a FuncOp? 246*700637cbSDimitry Andric cir::FuncOp 247*700637cbSDimitry Andric getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType = nullptr, 248*700637cbSDimitry Andric bool forVTable = false, bool dontDefer = false, 249*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition); 250*700637cbSDimitry Andric 251*700637cbSDimitry Andric mlir::Operation * 252*700637cbSDimitry Andric getAddrOfGlobal(clang::GlobalDecl gd, 253*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition); 254*700637cbSDimitry Andric 255*700637cbSDimitry Andric /// Emit code for a single global function or variable declaration. Forward 256*700637cbSDimitry Andric /// declarations are emitted lazily. 257*700637cbSDimitry Andric void emitGlobal(clang::GlobalDecl gd); 258*700637cbSDimitry Andric 259*700637cbSDimitry Andric void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, 260*700637cbSDimitry Andric GlobalDecl aliasGD, cir::FuncOp aliasee, 261*700637cbSDimitry Andric cir::GlobalLinkageKind linkage); 262*700637cbSDimitry Andric 263*700637cbSDimitry Andric mlir::Type convertType(clang::QualType type); 264*700637cbSDimitry Andric 265*700637cbSDimitry Andric /// Set the visibility for the given global. 266*700637cbSDimitry Andric void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const; 267*700637cbSDimitry Andric void setDSOLocal(mlir::Operation *op) const; 268*700637cbSDimitry Andric void setDSOLocal(cir::CIRGlobalValueInterface gv) const; 269*700637cbSDimitry Andric 270*700637cbSDimitry Andric /// Set visibility, dllimport/dllexport and dso_local. 271*700637cbSDimitry Andric /// This must be called after dllimport/dllexport is set. 272*700637cbSDimitry Andric void setGVProperties(mlir::Operation *op, const NamedDecl *d) const; 273*700637cbSDimitry Andric void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const; 274*700637cbSDimitry Andric 275*700637cbSDimitry Andric /// Set function attributes for a function declaration. 276*700637cbSDimitry Andric void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, 277*700637cbSDimitry Andric bool isIncompleteFunction, bool isThunk); 278*700637cbSDimitry Andric 279*700637cbSDimitry Andric void emitGlobalDefinition(clang::GlobalDecl gd, 280*700637cbSDimitry Andric mlir::Operation *op = nullptr); 281*700637cbSDimitry Andric void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op); 282*700637cbSDimitry Andric void emitGlobalVarDefinition(const clang::VarDecl *vd, 283*700637cbSDimitry Andric bool isTentative = false); 284*700637cbSDimitry Andric 285*700637cbSDimitry Andric void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd); 286*700637cbSDimitry Andric 287*700637cbSDimitry Andric // C++ related functions. 288*700637cbSDimitry Andric void emitDeclContext(const DeclContext *dc); 289*700637cbSDimitry Andric 290*700637cbSDimitry Andric /// Return the result of value-initializing the given type, i.e. a null 291*700637cbSDimitry Andric /// expression of the given type. 292*700637cbSDimitry Andric mlir::Value emitNullConstant(QualType t, mlir::Location loc); 293*700637cbSDimitry Andric 294*700637cbSDimitry Andric llvm::StringRef getMangledName(clang::GlobalDecl gd); 295*700637cbSDimitry Andric 296*700637cbSDimitry Andric void emitTentativeDefinition(const VarDecl *d); 297*700637cbSDimitry Andric 298*700637cbSDimitry Andric // Make sure that this type is translated. 299*700637cbSDimitry Andric void updateCompletedType(const clang::TagDecl *td); 300*700637cbSDimitry Andric 301*700637cbSDimitry Andric // Produce code for this constructor/destructor. This method doesn't try to 302*700637cbSDimitry Andric // apply any ABI rules about which other constructors/destructors are needed 303*700637cbSDimitry Andric // or if they are alias to each other. 304*700637cbSDimitry Andric cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd); 305*700637cbSDimitry Andric 306*700637cbSDimitry Andric bool supportsCOMDAT() const; 307*700637cbSDimitry Andric void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op); 308*700637cbSDimitry Andric 309*700637cbSDimitry Andric static void setInitializer(cir::GlobalOp &op, mlir::Attribute value); 310*700637cbSDimitry Andric 311*700637cbSDimitry Andric cir::FuncOp 312*700637cbSDimitry Andric getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, 313*700637cbSDimitry Andric clang::GlobalDecl gd, bool forVTable, 314*700637cbSDimitry Andric bool dontDefer = false, bool isThunk = false, 315*700637cbSDimitry Andric ForDefinition_t isForDefinition = NotForDefinition, 316*700637cbSDimitry Andric mlir::ArrayAttr extraAttrs = {}); 317*700637cbSDimitry Andric 318*700637cbSDimitry Andric cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, 319*700637cbSDimitry Andric cir::FuncType funcType, 320*700637cbSDimitry Andric const clang::FunctionDecl *funcDecl); 321*700637cbSDimitry Andric 322*700637cbSDimitry Andric /// Given a builtin id for a function like "__builtin_fabsf", return a 323*700637cbSDimitry Andric /// Function* for "fabsf". 324*700637cbSDimitry Andric cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID); 325*700637cbSDimitry Andric getSize(CharUnits size)326*700637cbSDimitry Andric mlir::IntegerAttr getSize(CharUnits size) { 327*700637cbSDimitry Andric return builder.getSizeFromCharUnits(size); 328*700637cbSDimitry Andric } 329*700637cbSDimitry Andric 330*700637cbSDimitry Andric /// Emit any needed decls for which code generation was deferred. 331*700637cbSDimitry Andric void emitDeferred(); 332*700637cbSDimitry Andric 333*700637cbSDimitry Andric /// Helper for `emitDeferred` to apply actual codegen. 334*700637cbSDimitry Andric void emitGlobalDecl(const clang::GlobalDecl &d); 335*700637cbSDimitry Andric getTriple()336*700637cbSDimitry Andric const llvm::Triple &getTriple() const { return target.getTriple(); } 337*700637cbSDimitry Andric 338*700637cbSDimitry Andric // Finalize CIR code generation. 339*700637cbSDimitry Andric void release(); 340*700637cbSDimitry Andric 341*700637cbSDimitry Andric /// ------- 342*700637cbSDimitry Andric /// Visibility and Linkage 343*700637cbSDimitry Andric /// ------- 344*700637cbSDimitry Andric 345*700637cbSDimitry Andric static mlir::SymbolTable::Visibility 346*700637cbSDimitry Andric getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK); 347*700637cbSDimitry Andric static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility( 348*700637cbSDimitry Andric clang::VisibilityAttr::VisibilityType visibility); 349*700637cbSDimitry Andric cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl); 350*700637cbSDimitry Andric static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op); 351*700637cbSDimitry Andric cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd); 352*700637cbSDimitry Andric cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, 353*700637cbSDimitry Andric GVALinkage linkage, 354*700637cbSDimitry Andric bool isConstantVariable); setFunctionLinkage(GlobalDecl gd,cir::FuncOp f)355*700637cbSDimitry Andric void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f) { 356*700637cbSDimitry Andric cir::GlobalLinkageKind l = getFunctionLinkage(gd); 357*700637cbSDimitry Andric f.setLinkageAttr(cir::GlobalLinkageKindAttr::get(&getMLIRContext(), l)); 358*700637cbSDimitry Andric mlir::SymbolTable::setSymbolVisibility(f, 359*700637cbSDimitry Andric getMLIRVisibilityFromCIRLinkage(l)); 360*700637cbSDimitry Andric } 361*700637cbSDimitry Andric 362*700637cbSDimitry Andric cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, 363*700637cbSDimitry Andric bool isConstant); 364*700637cbSDimitry Andric 365*700637cbSDimitry Andric void addReplacement(llvm::StringRef name, mlir::Operation *op); 366*700637cbSDimitry Andric 367*700637cbSDimitry Andric /// Helpers to emit "not yet implemented" error diagnostics 368*700637cbSDimitry Andric DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef); 369*700637cbSDimitry Andric 370*700637cbSDimitry Andric template <typename T> errorNYI(SourceLocation loc,llvm::StringRef feature,const T & name)371*700637cbSDimitry Andric DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature, 372*700637cbSDimitry Andric const T &name) { 373*700637cbSDimitry Andric unsigned diagID = 374*700637cbSDimitry Andric diags.getCustomDiagID(DiagnosticsEngine::Error, 375*700637cbSDimitry Andric "ClangIR code gen Not Yet Implemented: %0: %1"); 376*700637cbSDimitry Andric return diags.Report(loc, diagID) << feature << name; 377*700637cbSDimitry Andric } 378*700637cbSDimitry Andric errorNYI(mlir::Location loc,llvm::StringRef feature)379*700637cbSDimitry Andric DiagnosticBuilder errorNYI(mlir::Location loc, llvm::StringRef feature) { 380*700637cbSDimitry Andric // TODO: Convert the location to a SourceLocation 381*700637cbSDimitry Andric unsigned diagID = diags.getCustomDiagID( 382*700637cbSDimitry Andric DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0"); 383*700637cbSDimitry Andric return diags.Report(diagID) << feature; 384*700637cbSDimitry Andric } 385*700637cbSDimitry Andric errorNYI(llvm::StringRef feature)386*700637cbSDimitry Andric DiagnosticBuilder errorNYI(llvm::StringRef feature) const { 387*700637cbSDimitry Andric // TODO: Make a default location? currSrcLoc? 388*700637cbSDimitry Andric unsigned diagID = diags.getCustomDiagID( 389*700637cbSDimitry Andric DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0"); 390*700637cbSDimitry Andric return diags.Report(diagID) << feature; 391*700637cbSDimitry Andric } 392*700637cbSDimitry Andric 393*700637cbSDimitry Andric DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef); 394*700637cbSDimitry Andric 395*700637cbSDimitry Andric template <typename T> errorNYI(SourceRange loc,llvm::StringRef feature,const T & name)396*700637cbSDimitry Andric DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature, 397*700637cbSDimitry Andric const T &name) { 398*700637cbSDimitry Andric return errorNYI(loc.getBegin(), feature, name) << loc; 399*700637cbSDimitry Andric } 400*700637cbSDimitry Andric 401*700637cbSDimitry Andric private: 402*700637cbSDimitry Andric // An ordered map of canonical GlobalDecls to their mangled names. 403*700637cbSDimitry Andric llvm::MapVector<clang::GlobalDecl, llvm::StringRef> mangledDeclNames; 404*700637cbSDimitry Andric llvm::StringMap<clang::GlobalDecl, llvm::BumpPtrAllocator> manglings; 405*700637cbSDimitry Andric 406*700637cbSDimitry Andric // FIXME: should we use llvm::TrackingVH<mlir::Operation> here? 407*700637cbSDimitry Andric typedef llvm::StringMap<mlir::Operation *> ReplacementsTy; 408*700637cbSDimitry Andric ReplacementsTy replacements; 409*700637cbSDimitry Andric /// Call replaceAllUsesWith on all pairs in replacements. 410*700637cbSDimitry Andric void applyReplacements(); 411*700637cbSDimitry Andric 412*700637cbSDimitry Andric /// A helper function to replace all uses of OldF to NewF that replace 413*700637cbSDimitry Andric /// the type of pointer arguments. This is not needed to tradtional 414*700637cbSDimitry Andric /// pipeline since LLVM has opaque pointers but CIR not. 415*700637cbSDimitry Andric void replacePointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF); 416*700637cbSDimitry Andric 417*700637cbSDimitry Andric void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op); 418*700637cbSDimitry Andric }; 419*700637cbSDimitry Andric } // namespace CIRGen 420*700637cbSDimitry Andric 421*700637cbSDimitry Andric } // namespace clang 422*700637cbSDimitry Andric 423*700637cbSDimitry Andric #endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H 424