@@ -213,13 +213,18 @@ CIRGenModule::getAddrOfGlobal(GlobalDecl gd, ForDefinition_t isForDefinition) {
213213 }
214214
215215 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);
218221 }
219222
220223 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);
223228 }
224229
225230 return getAddrOfGlobalVar (cast<VarDecl>(d), /* ty=*/ nullptr , isForDefinition)
@@ -1275,11 +1280,6 @@ bool CIRGenModule::mustBeEmitted(const ValueDecl *global) {
12751280 vd->getType ().isConstQualified ())))
12761281 return true ;
12771282
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-
12831283 return getASTContext ().DeclMustBeEmitted (global);
12841284}
12851285
@@ -1523,6 +1523,56 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
15231523 cir::FuncOp funcOp = createCIRFunction (
15241524 invalidLoc ? theModule->getLoc () : getLoc (funcDecl->getSourceRange ()),
15251525 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+
15261576 return funcOp;
15271577}
15281578
0 commit comments