@@ -66,6 +66,9 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
6666  void  handleGlobalOp (fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
6767                      mlir::LLVM::DIScopeAttr scope,
6868                      mlir::SymbolTable *symbolTable);
69+   void  handleFuncOp (mlir::func::FuncOp funcOp, mlir::LLVM::DIFileAttr fileAttr,
70+                     mlir::LLVM::DICompileUnitAttr cuAttr,
71+                     mlir::SymbolTable *symbolTable);
6972};
7073
7174static  uint32_t  getLineFromLoc (mlir::Location loc) {
@@ -207,11 +210,112 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
207210  globalOp->setLoc (builder.getFusedLoc ({globalOp->getLoc ()}, gvAttr));
208211}
209212
213+ void  AddDebugInfoPass::handleFuncOp (mlir::func::FuncOp funcOp,
214+                                     mlir::LLVM::DIFileAttr fileAttr,
215+                                     mlir::LLVM::DICompileUnitAttr cuAttr,
216+                                     mlir::SymbolTable *symbolTable) {
217+   mlir::Location l = funcOp->getLoc ();
218+   //  If fused location has already been created then nothing to do
219+   //  Otherwise, create a fused location.
220+   if  (debugInfoIsAlreadySet (l))
221+     return ;
222+ 
223+   mlir::ModuleOp module  = getOperation ();
224+   mlir::MLIRContext *context = &getContext ();
225+   mlir::OpBuilder builder (context);
226+   llvm::StringRef fileName (fileAttr.getName ());
227+   llvm::StringRef filePath (fileAttr.getDirectory ());
228+   unsigned  int  CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
229+                         ? llvm::dwarf::getCallingConvention (" DW_CC_program" 
230+                         : llvm::dwarf::getCallingConvention (" DW_CC_normal" 
231+ 
232+   if  (auto  funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
233+     fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
234+     filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
235+   }
236+ 
237+   mlir::StringAttr fullName = mlir::StringAttr::get (context, funcOp.getName ());
238+   mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
239+   mlir::StringAttr funcName =
240+       (attr) ? mlir::cast<mlir::StringAttr>(attr)
241+              : mlir::StringAttr::get (context, funcOp.getName ());
242+ 
243+   auto  result = fir::NameUniquer::deconstruct (funcName);
244+   funcName = mlir::StringAttr::get (context, result.second .name );
245+ 
246+   llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
247+   fir::DebugTypeGenerator typeGen (module );
248+   for  (auto  resTy : funcOp.getResultTypes ()) {
249+     auto  tyAttr = typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
250+     types.push_back (tyAttr);
251+   }
252+   for  (auto  inTy : funcOp.getArgumentTypes ()) {
253+     auto  tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
254+                                       cuAttr, funcOp.getLoc ());
255+     types.push_back (tyAttr);
256+   }
257+ 
258+   mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
259+       mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
260+   mlir::LLVM::DIFileAttr funcFileAttr =
261+       mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
262+ 
263+   //  Only definitions need a distinct identifier and a compilation unit.
264+   mlir::DistinctAttr id;
265+   mlir::LLVM::DIScopeAttr Scope = fileAttr;
266+   mlir::LLVM::DICompileUnitAttr compilationUnit;
267+   mlir::LLVM::DISubprogramFlags subprogramFlags =
268+       mlir::LLVM::DISubprogramFlags{};
269+   if  (isOptimized)
270+     subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
271+   if  (!funcOp.isExternal ()) {
272+     id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
273+     compilationUnit = cuAttr;
274+     subprogramFlags =
275+         subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
276+   }
277+   unsigned  line = getLineFromLoc (l);
278+   if  (fir::isInternalProcedure (funcOp)) {
279+     //  For contained functions, the scope is the parent subroutine.
280+     mlir::SymbolRefAttr sym = mlir::cast<mlir::SymbolRefAttr>(
281+         funcOp->getAttr (fir::getHostSymbolAttrName ()));
282+     if  (sym) {
283+       if  (auto  func =
284+               symbolTable->lookup <mlir::func::FuncOp>(sym.getLeafReference ())) {
285+         //  Make sure that parent is processed.
286+         handleFuncOp (func, fileAttr, cuAttr, symbolTable);
287+         if  (auto  fusedLoc =
288+                 mlir::dyn_cast_if_present<mlir::FusedLoc>(func.getLoc ())) {
289+           if  (auto  spAttr =
290+                   mlir::dyn_cast_if_present<mlir::LLVM::DISubprogramAttr>(
291+                       fusedLoc.getMetadata ()))
292+             Scope = spAttr;
293+         }
294+       }
295+     }
296+   } else  if  (!result.second .modules .empty ()) {
297+     Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
298+                                   line - 1 , false );
299+   }
300+ 
301+   auto  spAttr = mlir::LLVM::DISubprogramAttr::get (
302+       context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
303+       line, line, subprogramFlags, subTypeAttr);
304+   funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
305+ 
306+   //  Don't process variables if user asked for line tables only.
307+   if  (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
308+     return ;
309+ 
310+   funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
311+     handleDeclareOp (declOp, fileAttr, spAttr, typeGen, symbolTable);
312+   });
313+ }
314+ 
210315void  AddDebugInfoPass::runOnOperation () {
211316  mlir::ModuleOp module  = getOperation ();
212317  mlir::MLIRContext *context = &getContext ();
213318  mlir::SymbolTable symbolTable (module );
214-   mlir::OpBuilder builder (context);
215319  llvm::StringRef fileName;
216320  std::string filePath;
217321  //  We need 2 type of file paths here.
@@ -248,80 +352,7 @@ void AddDebugInfoPass::runOnOperation() {
248352      isOptimized, debugLevel);
249353
250354  module .walk ([&](mlir::func::FuncOp funcOp) {
251-     mlir::Location l = funcOp->getLoc ();
252-     //  If fused location has already been created then nothing to do
253-     //  Otherwise, create a fused location.
254-     if  (debugInfoIsAlreadySet (l))
255-       return ;
256- 
257-     unsigned  int  CC = (funcOp.getName () == fir::NameUniquer::doProgramEntry ())
258-                           ? llvm::dwarf::getCallingConvention (" DW_CC_program" 
259-                           : llvm::dwarf::getCallingConvention (" DW_CC_normal" 
260- 
261-     if  (auto  funcLoc = mlir::dyn_cast<mlir::FileLineColLoc>(l)) {
262-       fileName = llvm::sys::path::filename (funcLoc.getFilename ().getValue ());
263-       filePath = llvm::sys::path::parent_path (funcLoc.getFilename ().getValue ());
264-     }
265- 
266-     mlir::StringAttr fullName =
267-         mlir::StringAttr::get (context, funcOp.getName ());
268-     mlir::Attribute attr = funcOp->getAttr (fir::getInternalFuncNameAttrName ());
269-     mlir::StringAttr funcName =
270-         (attr) ? mlir::cast<mlir::StringAttr>(attr)
271-                : mlir::StringAttr::get (context, funcOp.getName ());
272- 
273-     auto  result = fir::NameUniquer::deconstruct (funcName);
274-     funcName = mlir::StringAttr::get (context, result.second .name );
275- 
276-     llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
277-     fir::DebugTypeGenerator typeGen (module );
278-     for  (auto  resTy : funcOp.getResultTypes ()) {
279-       auto  tyAttr =
280-           typeGen.convertType (resTy, fileAttr, cuAttr, funcOp.getLoc ());
281-       types.push_back (tyAttr);
282-     }
283-     for  (auto  inTy : funcOp.getArgumentTypes ()) {
284-       auto  tyAttr = typeGen.convertType (fir::unwrapRefType (inTy), fileAttr,
285-                                         cuAttr, funcOp.getLoc ());
286-       types.push_back (tyAttr);
287-     }
288- 
289-     mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
290-         mlir::LLVM::DISubroutineTypeAttr::get (context, CC, types);
291-     mlir::LLVM::DIFileAttr funcFileAttr =
292-         mlir::LLVM::DIFileAttr::get (context, fileName, filePath);
293- 
294-     //  Only definitions need a distinct identifier and a compilation unit.
295-     mlir::DistinctAttr id;
296-     mlir::LLVM::DIScopeAttr Scope = fileAttr;
297-     mlir::LLVM::DICompileUnitAttr compilationUnit;
298-     mlir::LLVM::DISubprogramFlags subprogramFlags =
299-         mlir::LLVM::DISubprogramFlags{};
300-     if  (isOptimized)
301-       subprogramFlags = mlir::LLVM::DISubprogramFlags::Optimized;
302-     if  (!funcOp.isExternal ()) {
303-       id = mlir::DistinctAttr::create (mlir::UnitAttr::get (context));
304-       compilationUnit = cuAttr;
305-       subprogramFlags =
306-           subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
307-     }
308-     unsigned  line = getLineFromLoc (l);
309-     if  (!result.second .modules .empty ())
310-       Scope = getOrCreateModuleAttr (result.second .modules [0 ], fileAttr, cuAttr,
311-                                     line - 1 , false );
312- 
313-     auto  spAttr = mlir::LLVM::DISubprogramAttr::get (
314-         context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
315-         line, line, subprogramFlags, subTypeAttr);
316-     funcOp->setLoc (builder.getFusedLoc ({funcOp->getLoc ()}, spAttr));
317- 
318-     //  Don't process variables if user asked for line tables only.
319-     if  (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly)
320-       return ;
321- 
322-     funcOp.walk ([&](fir::cg::XDeclareOp declOp) {
323-       handleDeclareOp (declOp, fileAttr, spAttr, typeGen, &symbolTable);
324-     });
355+     handleFuncOp (funcOp, fileAttr, cuAttr, &symbolTable);
325356  });
326357  //  Process any global which was not processed through DeclareOp.
327358  if  (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
0 commit comments