Skip to content

Conversation

@SergejSalnikov
Copy link
Contributor

@SergejSalnikov SergejSalnikov commented Oct 22, 2025

CGDebugInfo used to store SourceLocation which was converted to PresumedLoc multiple times per call.
Now we perform convertion from SourceLocation to PresumedLoc just once, which is more efficient.
It saves at least 2 conversions per call (sometimes 3) which were done in the following methods:
getOrCreateFile, getLineNumber, getColumnNumber.

It's a follow up for #160667

@github-actions
Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo labels Oct 22, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 22, 2025

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-debuginfo

Author: SKill (SergejSalnikov)

Changes

CGDebugInfo used to store SourceLocation which was converted to PresumedLoc multiple times per call.
Now we perform convertion from SourceLocation to PresumedLoc just once and use it, which is more efficient.
It saves at least 2 conversions per single call (sometimes 3) in the following methods:
getOrCreateFile, getLineNumber, getColumnNumber.


Patch is 55.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164608.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+211-178)
  • (modified) clang/lib/CodeGen/CGDebugInfo.h (+34-19)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12e2813ef2ec7..3a68a493fdcde 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -219,17 +219,18 @@ ApplyAtomGroup::~ApplyAtomGroup() {
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
                                        SourceLocation TemporaryLocation)
     : CGF(&CGF) {
-  init(TemporaryLocation);
+  SourceManager &SM = CGF.getContext().getSourceManager();
+  init(SM.getPresumedLoc(SM.getFileLoc(TemporaryLocation)));
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
                                        bool DefaultToEmpty,
-                                       SourceLocation TemporaryLocation)
+                                       const PresumedLoc &TemporaryPLocation)
     : CGF(&CGF) {
-  init(TemporaryLocation, DefaultToEmpty);
+  init(TemporaryPLocation, DefaultToEmpty);
 }
 
-void ApplyDebugLocation::init(SourceLocation TemporaryLocation,
+void ApplyDebugLocation::init(const PresumedLoc &TemporaryPLocation,
                               bool DefaultToEmpty) {
   auto *DI = CGF->getDebugInfo();
   if (!DI) {
@@ -242,8 +243,8 @@ void ApplyDebugLocation::init(SourceLocation TemporaryLocation,
   if (OriginalLocation && !DI->CGM.getExpressionLocationsEnabled())
     return;
 
-  if (TemporaryLocation.isValid()) {
-    DI->EmitLocation(CGF->Builder, TemporaryLocation);
+  if (TemporaryPLocation.isValid()) {
+    DI->EmitLocation(CGF->Builder, TemporaryPLocation);
     return;
   }
 
@@ -261,7 +262,8 @@ void ApplyDebugLocation::init(SourceLocation TemporaryLocation,
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E)
     : CGF(&CGF) {
-  init(E->getExprLoc());
+  SourceManager &SM = CGF.getContext().getSourceManager();
+  init(SM.getPresumedLoc(SM.getFileLoc(E->getExprLoc())));
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, llvm::DebugLoc Loc)
@@ -313,12 +315,12 @@ ApplyInlineDebugLocation::~ApplyInlineDebugLocation() {
   DI.EmitLocation(CGF->Builder, SavedLocation);
 }
 
-void CGDebugInfo::setLocation(SourceLocation Loc) {
+void CGDebugInfo::setLocation(const PresumedLoc &PLoc) {
   // If the new location isn't valid return.
-  if (Loc.isInvalid())
+  if (PLoc.isInvalid())
     return;
 
-  CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc);
+  CurPLoc = PLoc;
 
   // If we've changed files in the middle of a lexical scope go ahead
   // and create a new lexical scope with file node if it's different
@@ -326,21 +328,19 @@ void CGDebugInfo::setLocation(SourceLocation Loc) {
   if (LexicalBlockStack.empty())
     return;
 
-  SourceManager &SM = CGM.getContext().getSourceManager();
   auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
-  PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
-  if (PCLoc.isInvalid() || Scope->getFile() == getOrCreateFile(CurLoc))
+  if (CurPLoc.isInvalid() || Scope->getFile() == getOrCreateFile(CurPLoc))
     return;
 
   if (auto *LBF = dyn_cast<llvm::DILexicalBlockFile>(Scope)) {
     LexicalBlockStack.pop_back();
     LexicalBlockStack.emplace_back(DBuilder.createLexicalBlockFile(
-        LBF->getScope(), getOrCreateFile(CurLoc)));
+        LBF->getScope(), getOrCreateFile(CurPLoc)));
   } else if (isa<llvm::DILexicalBlock>(Scope) ||
              isa<llvm::DISubprogram>(Scope)) {
     LexicalBlockStack.pop_back();
     LexicalBlockStack.emplace_back(
-        DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurLoc)));
+        DBuilder.createLexicalBlockFile(Scope, getOrCreateFile(CurPLoc)));
   }
 }
 
@@ -532,20 +532,18 @@ std::optional<StringRef> CGDebugInfo::getSource(const SourceManager &SM,
   return Source;
 }
 
-llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
-  SourceManager &SM = CGM.getContext().getSourceManager();
+llvm::DIFile *CGDebugInfo::getOrCreateFile(const PresumedLoc &PLoc) {
   StringRef FileName;
   FileID FID;
   std::optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo;
 
-  if (Loc.isInvalid()) {
+  if (PLoc.isInvalid()) {
     // The DIFile used by the CU is distinct from the main source file. Call
     // createFile() below for canonicalization if the source file was specified
     // with an absolute path.
     FileName = TheCU->getFile()->getFilename();
     CSInfo = TheCU->getFile()->getChecksum();
   } else {
-    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
     FileName = PLoc.getFilename();
 
     if (FileName.empty()) {
@@ -572,7 +570,8 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
     if (CSKind)
       CSInfo.emplace(*CSKind, Checksum);
   }
-  return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc)));
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  return createFile(FileName, CSInfo, getSource(SM, PLoc.getFileID()));
 }
 
 llvm::DIFile *CGDebugInfo::createFile(
@@ -623,23 +622,20 @@ std::string CGDebugInfo::remapDIPath(StringRef Path) const {
   return P.str().str();
 }
 
-unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) {
-  if (Loc.isInvalid())
+unsigned CGDebugInfo::getLineNumber(const PresumedLoc &PLoc) const {
+  if (PLoc.isInvalid())
     return 0;
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  return SM.getPresumedLoc(Loc).getLine();
+  return PLoc.getLine();
 }
 
-unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) {
+unsigned CGDebugInfo::getColumnNumber(const PresumedLoc & PLoc, bool Force) const {
   // We may not want column information at all.
   if (!Force && !CGM.getCodeGenOpts().DebugColumnInfo)
     return 0;
 
   // If the location is invalid then use the current column.
-  if (Loc.isInvalid() && CurLoc.isInvalid())
-    return 0;
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
+  if (PLoc.isInvalid())
+    PLoc = CurPLoc;
   return PLoc.isValid() ? PLoc.getColumn() : 0;
 }
 
@@ -1392,9 +1388,9 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
   const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
   if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
     return cast<llvm::DICompositeType>(T);
-  llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
-  const unsigned Line =
-      getLineNumber(RD->getLocation().isValid() ? RD->getLocation() : CurLoc);
+  PresumedLoc PLoc = getFileLocation(RD->getLocation());
+  llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
+  const unsigned Line = getLineNumber(PLoc.isValid() ? PLoc : CurPLoc);
   StringRef RDName = getClassName(RD);
 
   uint64_t Size = 0;
@@ -1621,7 +1617,7 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
   auto PP = getPrintingPolicy();
   Ty->getTemplateName().print(OS, PP, TemplateName::Qualified::None);
 
-  SourceLocation Loc = AliasDecl->getLocation();
+  PresumedLoc PLoc = getFileLocation(AliasDecl->getLocation());
 
   if (CGM.getCodeGenOpts().DebugTemplateAlias) {
     auto ArgVector = ::GetTemplateArgs(TD, Ty);
@@ -1641,15 +1637,15 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
       printTemplateArgumentList(OS, Args.Args, PP);
 
     llvm::DIDerivedType *AliasTy = DBuilder.createTemplateAlias(
-        Src, Name, getOrCreateFile(Loc), getLineNumber(Loc),
+        Src, Name, getOrCreateFile(PLoc), getLineNumber(PLoc),
         getDeclContextDescriptor(AliasDecl), CollectTemplateParams(Args, Unit));
     return AliasTy;
   }
 
   printTemplateArgumentList(OS, Ty->template_arguments(), PP,
                             TD->getTemplateParameters());
-  return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
-                                getLineNumber(Loc),
+  return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(PLoc),
+                                getLineNumber(PLoc),
                                 getDeclContextDescriptor(AliasDecl));
 }
 
@@ -1690,7 +1686,7 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
 
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  PresumedLoc PLoc = getFileLocation(Ty->getDecl()->getLocation());
 
   uint32_t Align = getDeclAlignIfRequired(Ty->getDecl(), CGM.getContext());
   // Typedefs are derived from some other type.
@@ -1702,7 +1698,7 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
     Flags = getAccessFlag(Ty->getDecl()->getAccess(), cast<RecordDecl>(DC));
 
   return DBuilder.createTypedef(Underlying, Ty->getDecl()->getName(),
-                                getOrCreateFile(Loc), getLineNumber(Loc),
+                                getOrCreateFile(PLoc), getLineNumber(PLoc),
                                 getDeclContextDescriptor(Ty->getDecl()), Align,
                                 Flags, Annotations);
 }
@@ -1824,13 +1820,13 @@ CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
   QualType Ty = BitFieldDecl->getType();
   if (BitFieldDecl->hasAttr<PreferredTypeAttr>())
     Ty = BitFieldDecl->getAttr<PreferredTypeAttr>()->getType();
-  SourceLocation Loc = BitFieldDecl->getLocation();
-  llvm::DIFile *VUnit = getOrCreateFile(Loc);
+  PresumedLoc PLoc = getFileLocation(BitFieldDecl->getLocation());
+  llvm::DIFile *VUnit = getOrCreateFile(PLoc);
   llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
 
   // Get the location for the field.
-  llvm::DIFile *File = getOrCreateFile(Loc);
-  unsigned Line = getLineNumber(Loc);
+  llvm::DIFile *File = getOrCreateFile(PLoc);
+  unsigned Line = getLineNumber(PLoc);
 
   const CGBitFieldInfo &BitFieldInfo =
       CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
@@ -1902,13 +1898,13 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
     return nullptr;
 
   QualType Ty = PreviousBitfield->getType();
-  SourceLocation Loc = PreviousBitfield->getLocation();
-  llvm::DIFile *VUnit = getOrCreateFile(Loc);
+  PresumedLoc PLoc = getFileLocation(PreviousBitfield->getLocation());
+  llvm::DIFile *VUnit = getOrCreateFile(PLoc);
   llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
   llvm::DIScope *RecordTy = BitFieldDI->getScope();
 
-  llvm::DIFile *File = getOrCreateFile(Loc);
-  unsigned Line = getLineNumber(Loc);
+  llvm::DIFile *File = getOrCreateFile(PLoc);
+  unsigned Line = getLineNumber(PLoc);
 
   uint64_t StorageOffsetInBits =
       cast<llvm::ConstantInt>(BitFieldDI->getStorageOffsetInBits())
@@ -1924,14 +1920,14 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
 }
 
 llvm::DIType *CGDebugInfo::createFieldType(
-    StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS,
+    StringRef name, QualType type, const PresumedLoc &PLoc, AccessSpecifier AS,
     uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
     llvm::DIScope *scope, const RecordDecl *RD, llvm::DINodeArray Annotations) {
   llvm::DIType *debugType = getOrCreateType(type, tunit);
 
   // Get the location for the field.
-  llvm::DIFile *file = getOrCreateFile(loc);
-  const unsigned line = getLineNumber(loc.isValid() ? loc : CurLoc);
+  llvm::DIFile *file = getOrCreateFile(PLoc);
+  const unsigned line = getLineNumber(PLoc.isValid() ? PLoc : CurPLoc);
 
   uint64_t SizeInBits = 0;
   auto Align = AlignInBits;
@@ -2021,10 +2017,11 @@ void CGDebugInfo::CollectRecordLambdaFields(
       continue;
     }
 
-    llvm::DIFile *VUnit = getOrCreateFile(Loc);
+    PresumedLoc PLoc = getFileLocation(Loc);
+    llvm::DIFile *VUnit = getOrCreateFile(PLoc);
 
     elements.push_back(createFieldType(
-        GetLambdaCaptureName(Capture), Field->getType(), Loc,
+        GetLambdaCaptureName(Capture), Field->getType(), PLoc,
         Field->getAccess(), FieldOffset, Align, VUnit, RecordTy, CXXDecl));
   }
 }
@@ -2035,10 +2032,11 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy,
   // Create the descriptor for the static variable, with or without
   // constant initializers.
   Var = Var->getCanonicalDecl();
-  llvm::DIFile *VUnit = getOrCreateFile(Var->getLocation());
+  PresumedLoc PLoc = getFileLocation(Var->getLocation());
+  llvm::DIFile *VUnit = getOrCreateFile(PLoc);
   llvm::DIType *VTy = getOrCreateType(Var->getType(), VUnit);
 
-  unsigned LineNumber = getLineNumber(Var->getLocation());
+  unsigned LineNumber = getLineNumber(PLoc);
   StringRef VName = Var->getName();
 
   // FIXME: to avoid complications with type merging we should
@@ -2086,9 +2084,9 @@ void CGDebugInfo::CollectRecordNormalField(
   } else {
     auto Align = getDeclAlignIfRequired(field, CGM.getContext());
     llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(field);
-    FieldType =
-        createFieldType(name, type, field->getLocation(), field->getAccess(),
-                        OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
+    FieldType = createFieldType(
+        name, type, getFileLocation(field->getLocation()), field->getAccess(),
+        OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
   }
 
   elements.push_back(FieldType);
@@ -2102,8 +2100,8 @@ void CGDebugInfo::CollectRecordNestedType(
   // instead?
   if (isa<InjectedClassNameType>(Ty))
     return;
-  SourceLocation Loc = TD->getLocation();
-  if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc)))
+  PresumedLoc PLoc = getFileLocation(TD->getLocation());
+  if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(PLoc)))
     elements.push_back(nestedType);
 }
 
@@ -2306,8 +2304,9 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
   llvm::DIFile *MethodDefUnit = nullptr;
   unsigned MethodLine = 0;
   if (!Method->isImplicit()) {
-    MethodDefUnit = getOrCreateFile(Method->getLocation());
-    MethodLine = getLineNumber(Method->getLocation());
+    PresumedLoc PLoc = getFileLocation(Method->getLocation());
+    MethodDefUnit = getOrCreateFile(PLoc);
+    MethodLine = getLineNumber(PLoc);
   }
 
   // Collect virtual method info.
@@ -2758,7 +2757,6 @@ void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable,
 
   ASTContext &Context = CGM.getContext();
   StringRef SymbolName = "_vtable$";
-  SourceLocation Loc;
   QualType VoidPtr = Context.getPointerType(Context.VoidTy);
 
   // We deal with two different contexts:
@@ -2770,7 +2768,8 @@ void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable,
   // placed inside the scope of the C++ class/structure.
   llvm::DIScope *DContext = getContextDescriptor(RD, TheCU);
   auto *Ctxt = cast<llvm::DICompositeType>(DContext);
-  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  PresumedLoc InvalidPLoc = PresumedLoc();
+  llvm::DIFile *Unit = getOrCreateFile(InvalidPLoc);
   llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit);
   llvm::DINode::DIFlags Flags = getAccessFlag(AccessSpecifier::AS_private, RD) |
                                 llvm::DINode::FlagArtificial;
@@ -2907,7 +2906,8 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
 llvm::DIType *CGDebugInfo::getOrCreateRecordType(QualType RTy,
                                                  SourceLocation Loc) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
-  llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc));
+  PresumedLoc PLoc = getFileLocation(Loc);
+  llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(PLoc));
   return T;
 }
 
@@ -2920,7 +2920,8 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D,
                                                      SourceLocation Loc) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
   assert(!D.isNull() && "null type");
-  llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc));
+  PresumedLoc PLoc = getFileLocation(Loc);
+  llvm::DIType *T = getOrCreateType(D, getOrCreateFile(PLoc));
   assert(T && "could not create debug info for type");
 
   RetainedTypes.push_back(D.getAsOpaquePtr());
@@ -2937,7 +2938,7 @@ void CGDebugInfo::addHeapAllocSiteMetadata(llvm::CallBase *CI,
   if (AllocatedTy->isVoidType())
     node = llvm::MDNode::get(CGM.getLLVMContext(), {});
   else
-    node = getOrCreateType(AllocatedTy, getOrCreateFile(Loc));
+    node = getOrCreateType(AllocatedTy, getOrCreateFile(getFileLocation(Loc)));
 
   CI->setMetadata("heapallocsite", node);
 }
@@ -3170,8 +3171,9 @@ std::pair<llvm::DIType *, llvm::DIType *>
 CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
   RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf();
 
+  PresumedLoc PLoc = getFileLocation(RD->getLocation());
   // Get overall information about the record type for the debug info.
-  llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
+  llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
 
   // Records and classes and unions can all be recursive.  To handle them, we
   // first generate a debug descriptor for the struct as a forward declaration.
@@ -3239,12 +3241,12 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty,
 llvm::DIType *CGDebugInfo::CreateType(const ObjCTypeParamType *Ty,
                                       llvm::DIFile *Unit) {
   // Ignore protocols.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  PresumedLoc PLoc = getFileLocation(Ty->getDecl()->getLocation());
 
   // Use Typedefs to represent ObjCTypeParamType.
   return DBuilder.createTypedef(
       getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
-      Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
+      Ty->getDecl()->getName(), getOrCreateFile(PLoc), getLineNumber(PLoc),
       getDeclContextDescriptor(Ty->getDecl()));
 }
 
@@ -3290,9 +3292,10 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
         llvm::dwarf::DW_TAG_structure_type, ID->getName(),
         getDeclContextDescriptor(ID), Unit, 0, RuntimeLang);
 
+  PresumedLoc PLoc = getFileLocation(ID->getLocation());
   // Get overall information about the record type for the debug info.
-  llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());
-  unsigned Line = getLineNumber(ID->getLocation());
+  llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
+  unsigned Line = getLineNumber(PLoc);
 
   // If this is just a forward declaration return a special forward-declaration
   // debug type since we won't be able to lay out the entire type.
@@ -3413,8 +3416,9 @@ llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
 llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
                                                 llvm::DIFile *Unit) {
   ObjCInterfaceDecl *ID = Ty->getDecl();
-  llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());
-  unsigned Line = getLineNumber(ID->getLocation());
+  PresumedLoc PLoc = getFileLocation(ID->getLocation());
+  llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
+  unsigned Line = getLineNumber(PLoc);
 
   unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName();
 
@@ -3455,9 +3459,9 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
 
   // Create entries for all of the properties.
   auto AddProperty = [&](const ObjCPropertyDecl *PD) {
-    SourceLocation Loc = PD->getLocation();
-    llvm::DIFile *PUnit = getOrCreateFile(Loc);
-    unsigned PLine = getLineNumber(Loc);
+    PresumedLoc PLoc = getFileLocation(PD->getLocation());
+    llvm::DIFile *PUnit = getOrCreateFile(PLoc);
+    unsigned PLine = getLineNumber(PLoc);
     ObjCMethodDecl *Getter = PD->getGetterMethodDecl();
     ObjCMethodDecl *Setter = PD->getSetterMethodDecl();
     llvm::MDNode *PropertyNode = DBuilder.createObjCProperty(
@@ -3509,9 +3513,10 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
     if (FieldName.empty())
       continue;
 
+    PresumedLoc PLoc = getFileLocation(Field->getLocation());
     // Get the location for the field.
-    llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation());
-    unsigned FieldLine = getLineNumber(Field->getLocation());
+    llvm::DIFile *FieldDefUnit = getOrCreateFile(PLoc);
+    unsigned FieldLine = getLineNumber(PLoc);
     QualType FType = Field->getType();
     uint64_t FieldSize = 0;
     uint32_t FieldAlign = 0;
@@ -3556,9 +3561,9 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
       if (ObjCPropertyImplDecl *PImpD =
               ImpD...
[truncated]

@SergejSalnikov
Copy link
Contributor Author

@Michael137 , I'd like to do a few follow-ups for #163982 and improve code efficiency and do some readability cleanups. Would you mind reviewing those as well?

@github-actions
Copy link

github-actions bot commented Oct 30, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@SergejSalnikov
Copy link
Contributor Author

+@OCHyams for visibility

@SergejSalnikov
Copy link
Contributor Author

@Michael137, would you be the right person to review this change?

@Michael137
Copy link
Member

Michael137 commented Nov 5, 2025

Do you have numbers on how much this "improves efficiency"?

@SergejSalnikov
Copy link
Contributor Author

No. Unfortunately I do not have any numbers. But doing multiple expansion calls for the same location seems inefficient.

The PR simply replaces SourceLocation with PresumedLoc so readability wise the code should be equivalent. But in fact we don't really need SourceLocation as we consume the data from PresumedLoc object. What is the point in storing SourceLocation then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants