@@ -213,13 +213,18 @@ CIRGenModule::getAddrOfGlobal(GlobalDecl gd, ForDefinition_t isForDefinition) {
213
213
}
214
214
215
215
if (isa<CXXMethodDecl>(d)) {
216
- errorNYI (d->getSourceRange (), " getAddrOfGlobal: C++ method decl" );
217
- return nullptr ;
216
+ const CIRGenFunctionInfo &fi =
217
+ getTypes ().arrangeCXXMethodDeclaration (cast<CXXMethodDecl>(d));
218
+ cir::FuncType ty = getTypes ().getFunctionType (fi);
219
+ return getAddrOfFunction (gd, ty, /* ForVTable=*/ false , /* DontDefer=*/ false ,
220
+ isForDefinition);
218
221
}
219
222
220
223
if (isa<FunctionDecl>(d)) {
221
- errorNYI (d->getSourceRange (), " getAddrOfGlobal: function decl" );
222
- return nullptr ;
224
+ const CIRGenFunctionInfo &fi = getTypes ().arrangeGlobalDeclaration (gd);
225
+ cir::FuncType ty = getTypes ().getFunctionType (fi);
226
+ return getAddrOfFunction (gd, ty, /* ForVTable=*/ false , /* DontDefer=*/ false ,
227
+ isForDefinition);
223
228
}
224
229
225
230
return getAddrOfGlobalVar (cast<VarDecl>(d), /* ty=*/ nullptr , isForDefinition)
@@ -1275,11 +1280,6 @@ bool CIRGenModule::mustBeEmitted(const ValueDecl *global) {
1275
1280
vd->getType ().isConstQualified ())))
1276
1281
return true ;
1277
1282
1278
- // TODO(cir): We do want to defer function decls, but it's not implemented.
1279
- assert (!cir::MissingFeatures::deferredFuncDecls ());
1280
- if (isa<FunctionDecl>(global))
1281
- return true ;
1282
-
1283
1283
return getASTContext ().DeclMustBeEmitted (global);
1284
1284
}
1285
1285
@@ -1523,6 +1523,56 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
1523
1523
cir::FuncOp funcOp = createCIRFunction (
1524
1524
invalidLoc ? theModule->getLoc () : getLoc (funcDecl->getSourceRange ()),
1525
1525
mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
1526
+
1527
+ // 'dontDefer' actually means don't move this to the deferredDeclsToEmit list.
1528
+ if (dontDefer) {
1529
+ // TODO(cir): This assertion will need an additional condition when we
1530
+ // support incomplete functions.
1531
+ assert (funcOp.getFunctionType () == funcType);
1532
+ return funcOp;
1533
+ }
1534
+
1535
+ // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
1536
+ // each other bottoming out wiht the base dtor. Therefore we emit non-base
1537
+ // dtors on usage, even if there is no dtor definition in the TU.
1538
+ if (isa_and_nonnull<CXXDestructorDecl>(d))
1539
+ errorNYI (d->getSourceRange (), " getOrCreateCIRFunction: dtor" );
1540
+
1541
+ // This is the first use or definition of a mangled name. If there is a
1542
+ // deferred decl with this name, remember that we need to emit it at the end
1543
+ // of the file.
1544
+ auto ddi = deferredDecls.find (mangledName);
1545
+ if (ddi != deferredDecls.end ()) {
1546
+ // Move the potentially referenced deferred decl to the
1547
+ // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
1548
+ // don't need it anymore).
1549
+ addDeferredDeclToEmit (ddi->second );
1550
+ deferredDecls.erase (ddi);
1551
+
1552
+ // Otherwise, there are cases we have to worry about where we're using a
1553
+ // declaration for which we must emit a definition but where we might not
1554
+ // find a top-level definition.
1555
+ // - member functions defined inline in their classes
1556
+ // - friend functions defined inline in some class
1557
+ // - special member functions with implicit definitions
1558
+ // If we ever change our AST traversal to walk into class methods, this
1559
+ // will be unnecessary.
1560
+ //
1561
+ // We also don't emit a definition for a function if it's going to be an
1562
+ // entry in a vtable, unless it's already marked as used.
1563
+ } else if (getLangOpts ().CPlusPlus && d) {
1564
+ // Look for a declaration that's lexically in a record.
1565
+ for (const auto *fd = cast<FunctionDecl>(d)->getMostRecentDecl (); fd;
1566
+ fd = fd->getPreviousDecl ()) {
1567
+ if (isa<CXXRecordDecl>(fd->getLexicalDeclContext ())) {
1568
+ if (fd->doesThisDeclarationHaveABody ()) {
1569
+ addDeferredDeclToEmit (gd.getWithDecl (fd));
1570
+ break ;
1571
+ }
1572
+ }
1573
+ }
1574
+ }
1575
+
1526
1576
return funcOp;
1527
1577
}
1528
1578
0 commit comments