@@ -406,14 +406,34 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
406406 /* DontDefer=*/ true , ForDefinition);
407407 }
408408
409+ // Already emitted.
410+ if (!funcOp.isDeclaration ())
411+ return ;
412+
413+ setFunctionLinkage (gd, funcOp);
414+ setGVProperties (funcOp, funcDecl);
415+ assert (!cir::MissingFeatures::opFuncMaybeHandleStaticInExternC ());
416+ maybeSetTrivialComdat (*funcDecl, funcOp);
417+ assert (!cir::MissingFeatures::setLLVMFunctionFEnvAttributes ());
418+
409419 CIRGenFunction cgf (*this , builder);
410420 curCGF = &cgf;
411421 {
412422 mlir::OpBuilder::InsertionGuard guard (builder);
413423 cgf.generateCode (gd, funcOp, funcType);
414424 }
415425 curCGF = nullptr ;
426+
427+ setNonAliasAttributes (gd, funcOp);
416428 assert (!cir::MissingFeatures::opFuncAttributesForDefinition ());
429+
430+ if (const ConstructorAttr *ca = funcDecl->getAttr <ConstructorAttr>())
431+ errorNYI (funcDecl->getSourceRange (), " constructor attribute" );
432+ if (const DestructorAttr *da = funcDecl->getAttr <DestructorAttr>())
433+ errorNYI (funcDecl->getSourceRange (), " destructor attribute" );
434+
435+ if (funcDecl->getAttr <AnnotateAttr>())
436+ errorNYI (funcDecl->getSourceRange (), " deferredAnnotations" );
417437}
418438
419439mlir::Operation *CIRGenModule::getGlobalValue (StringRef name) {
@@ -855,10 +875,12 @@ static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d) {
855875void CIRGenModule::maybeSetTrivialComdat (const Decl &d, mlir::Operation *op) {
856876 if (!shouldBeInCOMDAT (*this , d))
857877 return ;
858- if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op))
878+ if (auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
859879 globalOp.setComdat (true );
860-
861- assert (!cir::MissingFeatures::opFuncSetComdat ());
880+ } else {
881+ auto funcOp = cast<cir::FuncOp>(op);
882+ funcOp.setComdat (true );
883+ }
862884}
863885
864886void CIRGenModule::updateCompletedType (const TagDecl *td) {
@@ -1028,6 +1050,17 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
10281050 return getCIRLinkageForDeclarator (vd, linkage, isConstant);
10291051}
10301052
1053+ cir::GlobalLinkageKind CIRGenModule::getFunctionLinkage (GlobalDecl gd) {
1054+ const auto *fd = cast<FunctionDecl>(gd.getDecl ());
1055+
1056+ GVALinkage linkage = astContext.GetGVALinkageForFunction (fd);
1057+
1058+ if (const auto *dtor = dyn_cast<CXXDestructorDecl>(fd))
1059+ errorNYI (fd->getSourceRange (), " getFunctionLinkage: CXXDestructorDecl" );
1060+
1061+ return getCIRLinkageForDeclarator (fd, linkage, /* IsConstantVariable=*/ false );
1062+ }
1063+
10311064static cir::GlobalOp
10321065generateStringLiteral (mlir::Location loc, mlir::TypedAttr c,
10331066 cir::GlobalLinkageKind lt, CIRGenModule &cgm,
@@ -1534,6 +1567,27 @@ void CIRGenModule::setGVPropertiesAux(mlir::Operation *op,
15341567 assert (!cir::MissingFeatures::opGlobalPartition ());
15351568}
15361569
1570+ void CIRGenModule::setFunctionAttributes (GlobalDecl globalDecl,
1571+ cir::FuncOp func,
1572+ bool isIncompleteFunction,
1573+ bool isThunk) {
1574+ // NOTE(cir): Original CodeGen checks if this is an intrinsic. In CIR we
1575+ // represent them in dedicated ops. The correct attributes are ensured during
1576+ // translation to LLVM. Thus, we don't need to check for them here.
1577+
1578+ assert (!cir::MissingFeatures::setFunctionAttributes ());
1579+ assert (!cir::MissingFeatures::setTargetAttributes ());
1580+
1581+ // TODO(cir): This needs a lot of work to better match CodeGen. That
1582+ // ultimately ends up in setGlobalVisibility, which already has the linkage of
1583+ // the LLVM GV (corresponding to our FuncOp) computed, so it doesn't have to
1584+ // recompute it here. This is a minimal fix for now.
1585+ if (!isLocalLinkage (getFunctionLinkage (globalDecl))) {
1586+ const Decl *decl = globalDecl.getDecl ();
1587+ func.setGlobalVisibilityAttr (getGlobalVisibilityAttrFromDecl (decl));
1588+ }
1589+ }
1590+
15371591cir::FuncOp CIRGenModule::getOrCreateCIRFunction (
15381592 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
15391593 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
@@ -1576,8 +1630,9 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
15761630 // If there are two attempts to define the same mangled name, issue an
15771631 // error.
15781632 auto fn = cast<cir::FuncOp>(entry);
1579- assert ((!isForDefinition || !fn || !fn.isDeclaration ()) &&
1580- " Duplicate function definition" );
1633+ if (isForDefinition && fn && !fn.isDeclaration ()) {
1634+ errorNYI (d->getSourceRange (), " Duplicate function definition" );
1635+ }
15811636 if (fn && fn.getFunctionType () == funcType) {
15821637 return fn;
15831638 }
@@ -1598,6 +1653,9 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
15981653 invalidLoc ? theModule->getLoc () : getLoc (funcDecl->getSourceRange ()),
15991654 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
16001655
1656+ if (d)
1657+ setFunctionAttributes (gd, funcOp, /* isIncompleteFunction=*/ false , isThunk);
1658+
16011659 // 'dontDefer' actually means don't move this to the deferredDeclsToEmit list.
16021660 if (dontDefer) {
16031661 // TODO(cir): This assertion will need an additional condition when we
@@ -1668,6 +1726,20 @@ CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
16681726
16691727 func = builder.create <cir::FuncOp>(loc, name, funcType);
16701728
1729+ assert (!cir::MissingFeatures::opFuncAstDeclAttr ());
1730+ assert (!cir::MissingFeatures::opFuncNoProto ());
1731+
1732+ assert (func.isDeclaration () && " expected empty body" );
1733+
1734+ // A declaration gets private visibility by default, but external linkage
1735+ // as the default linkage.
1736+ func.setLinkageAttr (cir::GlobalLinkageKindAttr::get (
1737+ &getMLIRContext (), cir::GlobalLinkageKind::ExternalLinkage));
1738+ mlir::SymbolTable::setSymbolVisibility (
1739+ func, mlir::SymbolTable::Visibility::Private);
1740+
1741+ assert (!cir::MissingFeatures::opFuncExtraAttrs ());
1742+
16711743 if (!cgf)
16721744 theModule.push_back (func);
16731745 }
0 commit comments