[clang] [clang] Improve efficiency of CGDebugInfo by using PresumedLoc. (PR #164441)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 21 08:18:39 PDT 2025


https://github.com/SergejSalnikov created https://github.com/llvm/llvm-project/pull/164441

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`.

>From e702d33b094698a4e488f67ff6b4a289fb3578c4 Mon Sep 17 00:00:00 2001
From: skill <skill at google.com>
Date: Tue, 21 Oct 2025 16:49:06 +0200
Subject: [PATCH] [clang] Improve efficiency of CGDebugInfo by using
 PresumedLoc.

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.
---
 clang/lib/CodeGen/CGDebugInfo.cpp | 387 ++++++++++++++++--------------
 clang/lib/CodeGen/CGDebugInfo.h   |  45 ++--
 2 files changed, 236 insertions(+), 196 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12e2813ef2ec7..736b388dd209d 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(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(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())
+  if (PLoc.isInvalid() && CurPLoc.isInvalid())
     return 0;
-  SourceManager &SM = CGM.getContext().getSourceManager();
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc);
   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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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, getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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(getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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 = getPresumedLoc(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->FindPropertyImplIvarDecl(Field->getIdentifier())) {
         if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
-          SourceLocation Loc = PD->getLocation();
-          llvm::DIFile *PUnit = getOrCreateFile(Loc);
-          unsigned PLine = getLineNumber(Loc);
+          PresumedLoc PLoc = getPresumedLoc(PD->getLocation());
+          llvm::DIFile *PUnit = getOrCreateFile(PLoc);
+          unsigned PLine = getLineNumber(PLoc);
           ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
           ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
           PropertyNode = DBuilder.createObjCProperty(
@@ -3838,11 +3843,12 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
     // FwdDecl with the second and then replace the second with
     // complete type.
     llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
-    llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
+    PresumedLoc PLoc = getPresumedLoc(ED->getLocation());
+    llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
     llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
 
-    unsigned Line = getLineNumber(ED->getLocation());
+    unsigned Line = getLineNumber(PLoc);
     StringRef EDName = ED->getName();
     llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
@@ -3875,8 +3881,9 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
   // Return a CompositeType for the enum itself.
   llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators);
 
-  llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
-  unsigned Line = getLineNumber(ED->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(ED->getLocation());
+  llvm::DIFile *DefUnit = getOrCreateFile(PLoc);
+  unsigned Line = getLineNumber(PLoc);
   llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
   llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
   return DBuilder.createEnumerationType(
@@ -3887,15 +3894,17 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
 llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent,
                                         unsigned MType, SourceLocation LineLoc,
                                         StringRef Name, StringRef Value) {
-  unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);
+  unsigned Line =
+      LineLoc.isInvalid() ? 0 : getLineNumber(getPresumedLoc(LineLoc));
   return DBuilder.createMacro(Parent, Line, MType, Name, Value);
 }
 
 llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
                                                     SourceLocation LineLoc,
                                                     SourceLocation FileLoc) {
-  llvm::DIFile *FName = getOrCreateFile(FileLoc);
-  unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc);
+  llvm::DIFile *FName = getOrCreateFile(getPresumedLoc(FileLoc));
+  unsigned Line =
+      LineLoc.isInvalid() ? 0 : getLineNumber(getPresumedLoc(LineLoc));
   return DBuilder.createTempMacroFile(Parent, Line, FName);
 }
 
@@ -4218,12 +4227,12 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 
   // Get overall information about the record type for the debug info.
   StringRef RDName = getClassName(RD);
-  const SourceLocation Loc = RD->getLocation();
+  PresumedLoc PLoc = getPresumedLoc(RD->getLocation());
   llvm::DIFile *DefUnit = nullptr;
   unsigned Line = 0;
-  if (Loc.isValid()) {
-    DefUnit = getOrCreateFile(Loc);
-    Line = getLineNumber(Loc);
+  if (PLoc.isValid()) {
+    DefUnit = getOrCreateFile(PLoc);
+    Line = getLineNumber(PLoc);
   }
 
   llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
@@ -4332,7 +4341,8 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
         break;
     }
     CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
-    ContainingType = getOrCreateType(T, getOrCreateFile(RD->getLocation()));
+    PresumedLoc PLoc = getPresumedLoc(RD->getLocation());
+    ContainingType = getOrCreateType(T, getOrCreateFile(PLoc));
   } else if (RD->isDynamicClass())
     ContainingType = RealDecl;
 
@@ -4403,10 +4413,11 @@ void CGDebugInfo::collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit,
                                       StringRef &Name, StringRef &LinkageName,
                                       llvm::MDTuple *&TemplateParameters,
                                       llvm::DIScope *&VDContext) {
-  Unit = getOrCreateFile(VD->getLocation());
-  LineNo = getLineNumber(VD->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
+  Unit = getOrCreateFile(PLoc);
+  LineNo = getLineNumber(PLoc);
 
-  setLocation(VD->getLocation());
+  setLocation(PLoc);
 
   T = VD->getType();
   if (T->isIncompleteArrayType()) {
@@ -4459,10 +4470,10 @@ llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
   StringRef Name, LinkageName;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
-  SourceLocation Loc = GD.getDecl()->getLocation();
-  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  PresumedLoc PLoc = getPresumedLoc(GD.getDecl()->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   llvm::DIScope *DContext = Unit;
-  unsigned Line = getLineNumber(Loc);
+  unsigned Line = getLineNumber(PLoc);
   collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
                            Flags);
   auto *FD = cast<FunctionDecl>(GD.getDecl());
@@ -4514,10 +4525,10 @@ llvm::DIGlobalVariable *
 CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) {
   QualType T;
   StringRef Name, LinkageName;
-  SourceLocation Loc = VD->getLocation();
-  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   llvm::DIScope *DContext = Unit;
-  unsigned Line = getLineNumber(Loc);
+  unsigned Line = getLineNumber(PLoc);
   llvm::MDTuple *TemplateParameters = nullptr;
 
   collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, TemplateParameters,
@@ -4540,7 +4551,8 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
   // in unlimited debug info)
   if (const auto *TD = dyn_cast<TypeDecl>(D)) {
     QualType Ty = CGM.getContext().getTypeDeclType(TD);
-    return getOrCreateType(Ty, getOrCreateFile(TD->getLocation()));
+    PresumedLoc PLoc = getPresumedLoc(TD->getLocation());
+    return getOrCreateType(Ty, getOrCreateFile(PLoc));
   }
   auto I = DeclCache.find(D->getCanonicalDecl());
 
@@ -4586,7 +4598,8 @@ llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) {
   auto MI = SPCache.find(FD->getCanonicalDecl());
   if (MI == SPCache.end()) {
     if (const auto *MD = dyn_cast<CXXMethodDecl>(FD->getCanonicalDecl())) {
-      return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()),
+      PresumedLoc PLoc = getPresumedLoc(MD->getLocation());
+      return CreateCXXMemberFunction(MD, getOrCreateFile(PLoc),
                                      cast<llvm::DICompositeType>(S));
     }
   }
@@ -4748,10 +4761,11 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
 
   const Decl *D = GD.getDecl();
   bool HasDecl = (D != nullptr);
+  PresumedLoc PLoc = getPresumedLoc(Loc);
 
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
-  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   llvm::DIScope *FDContext = Unit;
   llvm::DINodeArray TParamsArray;
   bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
@@ -4800,7 +4814,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
       isa<VarDecl>(D) || isa<CapturedDecl>(D)) {
     Flags |= llvm::DINode::FlagArtificial;
     // Artificial functions should not silently reuse CurLoc.
-    CurLoc = SourceLocation();
+    CurPLoc = PresumedLoc();
   }
 
   if (CurFuncIsThunk)
@@ -4815,8 +4829,8 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
   llvm::DISubprogram::DISPFlags SPFlagsForDef =
       SPFlags | llvm::DISubprogram::SPFlagDefinition;
 
-  const unsigned LineNo = getLineNumber(Loc.isValid() ? Loc : CurLoc);
-  unsigned ScopeLine = getLineNumber(ScopeLoc);
+  const unsigned LineNo = getLineNumber(PLoc.isValid() ? PLoc : CurPLoc);
+  unsigned ScopeLine = getLineNumber(getPresumedLoc(ScopeLoc));
   llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
   llvm::DISubprogram *Decl = nullptr;
   llvm::DINodeArray Annotations = nullptr;
@@ -4864,8 +4878,10 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
     return GetName(D, true);
   });
 
+  PresumedLoc PLoc = getPresumedLoc(Loc);
+
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
-  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   bool IsDeclForCallSite = Fn ? true : false;
   llvm::DIScope *FDContext =
       IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
@@ -4885,10 +4901,10 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
   if (D->isImplicit()) {
     Flags |= llvm::DINode::FlagArtificial;
     // Artificial functions without a location should not silently reuse CurLoc.
-    if (Loc.isInvalid())
-      CurLoc = SourceLocation();
+    if (PLoc.isInvalid())
+      CurPLoc = PLoc;
   }
-  unsigned LineNo = getLineNumber(Loc);
+  unsigned LineNo = getLineNumber(PLoc);
   unsigned ScopeLine = 0;
   llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
   if (CGM.getCodeGenOpts().OptimizationLevel != 0)
@@ -4970,25 +4986,34 @@ void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
 }
 
 void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
+  EmitLocation(Builder, getPresumedLoc(Loc));
+}
+
+void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, const PresumedLoc &PLoc) {
   // Update our current location
-  setLocation(Loc);
+  setLocation(PLoc);
 
-  if (CurLoc.isInvalid() || CurLoc.isMacroID() || LexicalBlockStack.empty())
+  if (CurPLoc.isInvalid() || LexicalBlockStack.empty())
     return;
 
   llvm::MDNode *Scope = LexicalBlockStack.back();
   Builder.SetCurrentDebugLocation(
-      llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurLoc),
-                            getColumnNumber(CurLoc), Scope, CurInlinedAt));
+      llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(CurPLoc),
+                            getColumnNumber(CurPLoc), Scope, CurInlinedAt));
 }
 
-void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
+void CGDebugInfo::CreateLexicalBlock(const PresumedLoc &PLoc) {
   llvm::MDNode *Back = nullptr;
   if (!LexicalBlockStack.empty())
     Back = LexicalBlockStack.back().get();
   LexicalBlockStack.emplace_back(DBuilder.createLexicalBlock(
-      cast<llvm::DIScope>(Back), getOrCreateFile(CurLoc), getLineNumber(CurLoc),
-      getColumnNumber(CurLoc)));
+      cast<llvm::DIScope>(Back), getOrCreateFile(CurPLoc), getLineNumber(CurPLoc),
+      getColumnNumber(CurPLoc)));
+}
+
+PresumedLoc CGDebugInfo::getPresumedLoc(SourceLocation Loc) const {
+  const SourceManager &SM = CGM.getContext().getSourceManager();
+  return SM.getPresumedLoc(Loc);
 }
 
 void CGDebugInfo::AppendAddressSpaceXDeref(
@@ -5007,18 +5032,19 @@ void CGDebugInfo::AppendAddressSpaceXDeref(
 void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder,
                                         SourceLocation Loc) {
   // Set our current location.
-  setLocation(Loc);
+  PresumedLoc PLoc = getPresumedLoc(Loc);
+  setLocation(PLoc);
 
   // Emit a line table change for the current location inside the new scope.
   Builder.SetCurrentDebugLocation(llvm::DILocation::get(
-      CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc),
+      CGM.getLLVMContext(), getLineNumber(PLoc), getColumnNumber(PLoc),
       LexicalBlockStack.back(), CurInlinedAt));
 
   if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
     return;
 
   // Create a new lexical block and push it on the stack.
-  CreateLexicalBlock(Loc);
+  CreateLexicalBlock(PLoc);
 }
 
 void CGDebugInfo::EmitLexicalBlockEnd(CGBuilderTy &Builder,
@@ -5042,7 +5068,7 @@ void CGDebugInfo::EmitFunctionEnd(CGBuilderTy &Builder, llvm::Function *Fn) {
   // Pop all regions for this function.
   while (LexicalBlockStack.size() != RCount) {
     // Provide an entry in the line table for the end of the block.
-    EmitLocation(Builder, CurLoc);
+    EmitLocation(Builder, CurPLoc);
     LexicalBlockStack.pop_back();
   }
   FnBeginRegionCount.pop_back();
@@ -5059,7 +5085,8 @@ CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD,
   uint64_t FieldSize, FieldOffset;
   uint32_t FieldAlign;
 
-  llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   QualType Type = VD->getType();
 
   FieldOffset = 0;
@@ -5135,8 +5162,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
   const bool VarIsArtificial = IsArtificial(VD);
 
   llvm::DIFile *Unit = nullptr;
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
   if (!VarIsArtificial)
-    Unit = getOrCreateFile(VD->getLocation());
+    Unit = getOrCreateFile(PLoc);
   llvm::DIType *Ty;
   uint64_t XOffset = 0;
   if (VD->hasAttr<BlocksAttr>())
@@ -5153,8 +5181,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
   unsigned Line = 0;
   unsigned Column = 0;
   if (!VarIsArtificial) {
-    Line = getLineNumber(VD->getLocation());
-    Column = getColumnNumber(VD->getLocation());
+    Line = getLineNumber(PLoc);
+    Column = getColumnNumber(PLoc);
   }
   SmallVector<uint64_t, 13> Expr;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
@@ -5320,7 +5348,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
   if (isa<DeclRefExpr>(BD->getBinding()))
     return nullptr;
 
-  llvm::DIFile *Unit = getOrCreateFile(BD->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(BD->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   llvm::DIType *Ty = getOrCreateType(BD->getType(), Unit);
 
   // If there is no debug info for this type then do not emit debug info
@@ -5343,8 +5372,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD,
     Expr.push_back(llvm::dwarf::DW_OP_deref);
   }
 
-  unsigned Line = getLineNumber(BD->getLocation());
-  unsigned Column = getColumnNumber(BD->getLocation());
+  unsigned Line = getLineNumber(PLoc);
+  unsigned Column = getColumnNumber(PLoc);
   StringRef Name = BD->getName();
   auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
   // Create the descriptor for the variable.
@@ -5438,11 +5467,12 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
     return;
 
   auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
-  llvm::DIFile *Unit = getOrCreateFile(D->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(D->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
 
   // Get location information.
-  unsigned Line = getLineNumber(D->getLocation());
-  unsigned Column = getColumnNumber(D->getLocation());
+  unsigned Line = getLineNumber(PLoc);
+  unsigned Column = getColumnNumber(PLoc);
 
   StringRef Name = D->getName();
 
@@ -5481,7 +5511,8 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
   bool isByRef = VD->hasAttr<BlocksAttr>();
 
   uint64_t XOffset = 0;
-  llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   llvm::DIType *Ty;
   if (isByRef)
     Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
@@ -5495,9 +5526,8 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
       Ty = CreateSelfType(VD->getType(), Ty);
 
   // Get location information.
-  const unsigned Line =
-      getLineNumber(VD->getLocation().isValid() ? VD->getLocation() : CurLoc);
-  unsigned Column = getColumnNumber(VD->getLocation());
+  const unsigned Line = getLineNumber(PLoc.isValid() ? PLoc : CurPLoc);
+  unsigned Column = getColumnNumber(PLoc);
 
   const llvm::DataLayout &target = CGM.getDataLayout();
 
@@ -5558,32 +5588,33 @@ bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {
 } // namespace
 
 void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
-    const CGBlockInfo &Block, const ASTContext &Context, SourceLocation Loc,
-    const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
+    const CGBlockInfo &Block, const ASTContext &Context,
+    const PresumedLoc &PLoc, const llvm::StructLayout &BlockLayout,
+    llvm::DIFile *Unit,
     SmallVectorImpl<llvm::Metadata *> &Fields) {
   // Blocks in OpenCL have unique constraints which make the standard fields
   // redundant while requiring size and align fields for enqueue_kernel. See
   // initializeForBlockHeader in CGBlocks.cpp
   if (CGM.getLangOpts().OpenCL) {
-    Fields.push_back(createFieldType("__size", Context.IntTy, Loc, AS_public,
+    Fields.push_back(createFieldType("__size", Context.IntTy, PLoc, AS_public,
                                      BlockLayout.getElementOffsetInBits(0),
                                      Unit, Unit));
-    Fields.push_back(createFieldType("__align", Context.IntTy, Loc, AS_public,
+    Fields.push_back(createFieldType("__align", Context.IntTy, PLoc, AS_public,
                                      BlockLayout.getElementOffsetInBits(1),
                                      Unit, Unit));
   } else {
-    Fields.push_back(createFieldType("__isa", Context.VoidPtrTy, Loc, AS_public,
+    Fields.push_back(createFieldType("__isa", Context.VoidPtrTy, PLoc, AS_public,
                                      BlockLayout.getElementOffsetInBits(0),
                                      Unit, Unit));
-    Fields.push_back(createFieldType("__flags", Context.IntTy, Loc, AS_public,
+    Fields.push_back(createFieldType("__flags", Context.IntTy, PLoc, AS_public,
                                      BlockLayout.getElementOffsetInBits(1),
                                      Unit, Unit));
     Fields.push_back(
-        createFieldType("__reserved", Context.IntTy, Loc, AS_public,
+        createFieldType("__reserved", Context.IntTy, PLoc, AS_public,
                         BlockLayout.getElementOffsetInBits(2), Unit, Unit));
     auto *FnTy = Block.getBlockExpr()->getFunctionType();
     auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
-    Fields.push_back(createFieldType("__FuncPtr", FnPtrType, Loc, AS_public,
+    Fields.push_back(createFieldType("__FuncPtr", FnPtrType, PLoc, AS_public,
                                      BlockLayout.getElementOffsetInBits(3),
                                      Unit, Unit));
     Fields.push_back(createFieldType(
@@ -5591,7 +5622,7 @@ void CGDebugInfo::collectDefaultFieldsForBlockLiteralDeclare(
         Context.getPointerType(Block.NeedsCopyDispose
                                    ? Context.getBlockDescriptorExtendedType()
                                    : Context.getBlockDescriptorType()),
-        Loc, AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
+        PLoc, AS_public, BlockLayout.getElementOffsetInBits(4), Unit, Unit));
   }
 }
 
@@ -5605,10 +5636,10 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
   const BlockDecl *blockDecl = block.getBlockDecl();
 
   // Collect some general information about the block's location.
-  SourceLocation loc = blockDecl->getCaretLocation();
-  llvm::DIFile *tunit = getOrCreateFile(loc);
-  unsigned line = getLineNumber(loc);
-  unsigned column = getColumnNumber(loc);
+  PresumedLoc PLoc = getPresumedLoc(blockDecl->getCaretLocation());
+  llvm::DIFile *tunit = getOrCreateFile(PLoc);
+  unsigned line = getLineNumber(PLoc);
+  unsigned column = getColumnNumber(PLoc);
 
   // Build the debug-info type for the block literal.
   getDeclContextDescriptor(blockDecl);
@@ -5617,7 +5648,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
       CGM.getDataLayout().getStructLayout(block.StructureType);
 
   SmallVector<llvm::Metadata *, 16> fields;
-  collectDefaultFieldsForBlockLiteralDeclare(block, C, loc, *blockLayout, tunit,
+  collectDefaultFieldsForBlockLiteralDeclare(block, C, PLoc, *blockLayout, tunit,
                                              fields);
 
   // We want to sort the captures by offset, not because DWARF
@@ -5667,7 +5698,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
       else
         llvm_unreachable("unexpected block declcontext");
 
-      fields.push_back(createFieldType("this", type, loc, AS_public,
+      fields.push_back(createFieldType("this", type, PLoc, AS_public,
                                        offsetInBits, tunit, tunit));
       continue;
     }
@@ -5689,7 +5720,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
                                             llvm::DINode::FlagZero, fieldType);
     } else {
       auto Align = getDeclAlignIfRequired(variable, CGM.getContext());
-      fieldType = createFieldType(name, variable->getType(), loc, AS_public,
+      fieldType = createFieldType(name, variable->getType(), PLoc, AS_public,
                                   offsetInBits, Align, tunit, tunit);
     }
     fields.push_back(fieldType);
@@ -6076,8 +6107,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
   });
 
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
+  PresumedLoc PLoc = getPresumedLoc(VD->getLocation());
   // Create the descriptor for the variable.
-  llvm::DIFile *Unit = getOrCreateFile(VD->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   StringRef Name = VD->getName();
   llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit);
 
@@ -6135,8 +6167,8 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
     }
 
   GV.reset(DBuilder.createGlobalVariableExpression(
-      DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
-      true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
+      DContext, Name, StringRef(), Unit, getLineNumber(PLoc), Ty, true, true,
+      InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
       TemplateParameters, Align));
 }
 
@@ -6147,15 +6179,16 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
     return;
 
   auto Align = getDeclAlignIfRequired(D, CGM.getContext());
-  llvm::DIFile *Unit = getOrCreateFile(D->getLocation());
+  PresumedLoc PLoc = getPresumedLoc(D->getLocation());
+  llvm::DIFile *Unit = getOrCreateFile(PLoc);
   StringRef Name = D->getName();
   llvm::DIType *Ty = getOrCreateType(D->getType(), Unit);
 
   llvm::DIScope *DContext = getDeclContextDescriptor(D);
   llvm::DIGlobalVariableExpression *GVE =
       DBuilder.createGlobalVariableExpression(
-          DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()),
-          Ty, false, false, nullptr, nullptr, nullptr, Align);
+          DContext, Name, StringRef(), Unit, getLineNumber(PLoc), Ty, false,
+          false, nullptr, nullptr, nullptr, Align);
   Var->addDebugInfo(GVE);
 }
 
@@ -6232,10 +6265,10 @@ void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV,
     return;
 
   llvm::DIScope *DContext = getDeclContextDescriptor(D);
-  auto Loc = D->getLocation();
+  PresumedLoc PLoc = getPresumedLoc(D->getLocation());
 
   llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration(
-      DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName());
+      DContext, DI, getOrCreateFile(PLoc), getLineNumber(PLoc), D->getName());
 
   // Record this DIE in the cache for nested declaration reference.
   ImportedDeclCache[GD.getCanonicalDecl().getDecl()].reset(ImportDI);
@@ -6243,16 +6276,15 @@ void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV,
 
 void CGDebugInfo::AddStringLiteralDebugInfo(llvm::GlobalVariable *GV,
                                             const StringLiteral *S) {
-  SourceLocation Loc = S->getStrTokenLoc(0);
-  PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
+  PresumedLoc PLoc = getPresumedLoc(S->getStrTokenLoc(0));
   if (!PLoc.isValid())
     return;
 
-  llvm::DIFile *File = getOrCreateFile(Loc);
+  llvm::DIFile *File = getOrCreateFile(PLoc);
   llvm::DIGlobalVariableExpression *Debug =
       DBuilder.createGlobalVariableExpression(
-          nullptr, StringRef(), StringRef(), getOrCreateFile(Loc),
-          getLineNumber(Loc), getOrCreateType(S->getType(), File), true);
+          nullptr, StringRef(), StringRef(), File, getLineNumber(PLoc),
+          getOrCreateType(S->getType(), File), true);
   GV->addDebugInfo(Debug);
 }
 
@@ -6269,22 +6301,22 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {
   const NamespaceDecl *NSDecl = UD.getNominatedNamespace();
   if (!NSDecl->isAnonymousNamespace() ||
       CGM.getCodeGenOpts().DebugExplicitImport) {
-    auto Loc = UD.getLocation();
-    if (!Loc.isValid())
-      Loc = CurLoc;
+    PresumedLoc PLoc = getPresumedLoc(UD.getLocation());
+    if (!PLoc.isValid())
+      PLoc = CurPLoc;
     DBuilder.createImportedModule(
         getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
-        getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
+        getOrCreateNamespace(NSDecl), getOrCreateFile(PLoc), getLineNumber(PLoc));
   }
 }
 
 void CGDebugInfo::EmitUsingShadowDecl(const UsingShadowDecl &USD) {
   if (llvm::DINode *Target =
           getDeclarationOrDefinition(USD.getUnderlyingDecl())) {
-    auto Loc = USD.getLocation();
+    PresumedLoc PLoc = getPresumedLoc(USD.getLocation());
     DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target,
-        getOrCreateFile(Loc), getLineNumber(Loc));
+        getOrCreateFile(PLoc), getLineNumber(PLoc));
   }
 }
 
@@ -6329,7 +6361,7 @@ void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) {
     return;
   if (Module *M = ID.getImportedModule()) {
     auto Info = ASTSourceDescriptor(*M);
-    auto Loc = ID.getLocation();
+    auto Loc = getPresumedLoc(ID.getLocation());
     DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
         getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
@@ -6345,19 +6377,19 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
   if (VH)
     return cast<llvm::DIImportedEntity>(VH);
   llvm::DIImportedEntity *R;
-  auto Loc = NA.getLocation();
+  auto PLoc = getPresumedLoc(NA.getLocation());
   if (const auto *Underlying =
           dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace()))
     // This could cache & dedup here rather than relying on metadata deduping.
     R = DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
-        EmitNamespaceAlias(*Underlying), getOrCreateFile(Loc),
-        getLineNumber(Loc), NA.getName());
+        EmitNamespaceAlias(*Underlying), getOrCreateFile(PLoc),
+        getLineNumber(PLoc), NA.getName());
   else
     R = DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
         getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
-        getOrCreateFile(Loc), getLineNumber(Loc), NA.getName());
+        getOrCreateFile(PLoc), getLineNumber(PLoc), NA.getName());
   VH.reset(R);
   return R;
 }
@@ -6477,9 +6509,10 @@ llvm::DebugLoc CGDebugInfo::SourceLocToDebugLoc(SourceLocation Loc) {
   if (LexicalBlockStack.empty())
     return llvm::DebugLoc();
 
+  PresumedLoc PLoc = getPresumedLoc(Loc);
   llvm::MDNode *Scope = LexicalBlockStack.back();
-  return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc),
-                               getColumnNumber(Loc), Scope);
+  return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(PLoc),
+                               getColumnNumber(PLoc), Scope);
 }
 
 llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const {
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 78c3eb9c5792e..faf04a77e326c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -68,7 +68,7 @@ class CGDebugInfo {
   llvm::DICompileUnit *TheCU = nullptr;
   ModuleMap *ClangModuleMap = nullptr;
   ASTSourceDescriptor PCHDescriptor;
-  SourceLocation CurLoc;
+  PresumedLoc CurPLoc;
   llvm::MDNode *CurInlinedAt = nullptr;
   llvm::DIType *VTablePtrType = nullptr;
   llvm::DIType *ClassTy = nullptr;
@@ -346,18 +346,18 @@ class CGDebugInfo {
   llvm::DINodeArray CollectBTFDeclTagAnnotations(const Decl *D);
 
   llvm::DIType *createFieldType(StringRef name, QualType type,
-                                SourceLocation loc, AccessSpecifier AS,
+                                const PresumedLoc &PLoc, AccessSpecifier AS,
                                 uint64_t offsetInBits, uint32_t AlignInBits,
                                 llvm::DIFile *tunit, llvm::DIScope *scope,
                                 const RecordDecl *RD = nullptr,
                                 llvm::DINodeArray Annotations = nullptr);
 
   llvm::DIType *createFieldType(StringRef name, QualType type,
-                                SourceLocation loc, AccessSpecifier AS,
+                                const PresumedLoc &PLoc, AccessSpecifier AS,
                                 uint64_t offsetInBits, llvm::DIFile *tunit,
                                 llvm::DIScope *scope,
                                 const RecordDecl *RD = nullptr) {
-    return createFieldType(name, type, loc, AS, offsetInBits, 0, tunit, scope,
+    return createFieldType(name, type, PLoc, AS, offsetInBits, 0, tunit, scope,
                            RD);
   }
 
@@ -406,7 +406,9 @@ class CGDebugInfo {
   /// @}
 
   /// Create a new lexical block node and push it on the stack.
-  void CreateLexicalBlock(SourceLocation Loc);
+  void CreateLexicalBlock(const PresumedLoc &PLoc);
+
+  PresumedLoc getPresumedLoc(SourceLocation Loc) const;
 
   /// If target-specific LLVM \p AddressSpace directly maps to target-specific
   /// DWARF address space, appends extended dereferencing mechanism to complex
@@ -429,9 +431,9 @@ class CGDebugInfo {
   /// A helper function to collect debug info for the default fields of a
   /// block.
   void collectDefaultFieldsForBlockLiteralDeclare(
-      const CGBlockInfo &Block, const ASTContext &Context, SourceLocation Loc,
-      const llvm::StructLayout &BlockLayout, llvm::DIFile *Unit,
-      SmallVectorImpl<llvm::Metadata *> &Fields);
+      const CGBlockInfo &Block, const ASTContext &Context,
+      const PresumedLoc &PLoc, const llvm::StructLayout &BlockLayout,
+      llvm::DIFile *Unit, SmallVectorImpl<llvm::Metadata *> &Fields);
 
 public:
   CGDebugInfo(CodeGenModule &CGM);
@@ -465,11 +467,11 @@ class CGDebugInfo {
 
   /// Update the current source location. If \arg loc is invalid it is
   /// ignored.
-  void setLocation(SourceLocation Loc);
+  void setLocation(const PresumedLoc &PLoc);
 
   /// Return the current source location. This does not necessarily correspond
   /// to the IRBuilder's current DebugLoc.
-  SourceLocation getLocation() const { return CurLoc; }
+  const PresumedLoc &getLocation() const { return CurPLoc; }
 
   /// Update the current inline scope. All subsequent calls to \p EmitLocation
   /// will create a location with this inlinedAt field.
@@ -486,6 +488,11 @@ class CGDebugInfo {
   /// location will be reused.
   void EmitLocation(CGBuilderTy &Builder, SourceLocation Loc);
 
+  /// Emit metadata to indicate a change in line/column information in
+  /// the source file. If the location is invalid, the previous
+  /// location will be reused.
+  void EmitLocation(CGBuilderTy &Builder, const PresumedLoc &Loc);
+
   QualType getFunctionType(const FunctionDecl *FD, QualType RetTy,
                            const SmallVectorImpl<const VarDecl *> &Args);
 
@@ -743,7 +750,7 @@ class CGDebugInfo {
 
   /// Convenience function to get the file debug info descriptor for the input
   /// location.
-  llvm::DIFile *getOrCreateFile(SourceLocation Loc);
+  llvm::DIFile *getOrCreateFile(const PresumedLoc &PLoc);
 
   /// Create a file debug info descriptor for a source file.
   llvm::DIFile *
@@ -862,12 +869,12 @@ class CGDebugInfo {
 
   /// Get line number for the location. If location is invalid
   /// then use current location.
-  unsigned getLineNumber(SourceLocation Loc);
+  unsigned getLineNumber(const PresumedLoc &PLoc) const;
 
   /// Get column number for the location. If location is
   /// invalid then use current location.
   /// \param Force  Assume DebugColumnInfo option is true.
-  unsigned getColumnNumber(SourceLocation Loc, bool Force = false);
+  unsigned getColumnNumber(const PresumedLoc &PLoc, bool Force = false) const;
 
   /// Collect various properties of a FunctionDecl.
   /// \param GD  A GlobalDecl whose getDecl() must return a FunctionDecl.
@@ -910,9 +917,9 @@ class CGDebugInfo {
 /// location or preferred location of the specified Expr.
 class ApplyDebugLocation {
 private:
-  void init(SourceLocation TemporaryLocation, bool DefaultToEmpty = false);
+  void init(const PresumedLoc &TemporaryLocation, bool DefaultToEmpty = false);
   ApplyDebugLocation(CodeGenFunction &CGF, bool DefaultToEmpty,
-                     SourceLocation TemporaryLocation);
+                     const PresumedLoc &TemporaryLocation);
 
   llvm::DebugLoc OriginalLocation;
   CodeGenFunction *CGF;
@@ -949,7 +956,7 @@ class ApplyDebugLocation {
   /// SourceLocation to CGDebugInfo::setLocation() will result in the
   /// last valid location being reused.
   static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF) {
-    return ApplyDebugLocation(CGF, false, SourceLocation());
+    return ApplyDebugLocation(CGF, false, PresumedLoc());
   }
   /// Apply TemporaryLocation if it is valid. Otherwise switch
   /// to an artificial debug location that has a valid scope, but no
@@ -957,7 +964,7 @@ class ApplyDebugLocation {
   static ApplyDebugLocation
   CreateDefaultArtificial(CodeGenFunction &CGF,
                           SourceLocation TemporaryLocation) {
-    return ApplyDebugLocation(CGF, false, TemporaryLocation);
+    return ApplyDebugLocation(CGF, TemporaryLocation);
   }
 
   /// Set the IRBuilder to not attach debug locations.  Note that
@@ -966,13 +973,13 @@ class ApplyDebugLocation {
   /// all instructions that do not have a location at the beginning of
   /// a function are counted towards to function prologue.
   static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF) {
-    return ApplyDebugLocation(CGF, true, SourceLocation());
+    return ApplyDebugLocation(CGF, true, PresumedLoc());
   }
 };
 
 /// A scoped helper to set the current debug location to an inlined location.
 class ApplyInlineDebugLocation {
-  SourceLocation SavedLocation;
+  PresumedLoc SavedLocation;
   CodeGenFunction *CGF;
 
 public:



More information about the cfe-commits mailing list