diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index ed967fd47dc83..48ddfd9d7c609 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -1250,6 +1250,22 @@ class SourceManager : public RefCountedBase { return getSpellingLocSlowCase(Loc); } + /// Given a SourceLocation object, return the refined spelling + /// location referenced by the ID. + /// + /// The key difference to \ref getSpellingLoc is that the source location + /// for macro body is resolved to the expansion site. + /// + /// This is the place where the characters that make up the lexed token + /// can be found. + SourceLocation getRefinedSpellingLoc(SourceLocation Loc) const { + // Handle the non-mapped case inline, defer to out of line code to handle + // expansions. + if (Loc.isFileID()) + return Loc; + return getRefinedSpellingLocSlowCase(Loc); + } + /// Given a SourceLocation object, return the spelling location /// referenced by the ID. /// @@ -1977,6 +1993,7 @@ class SourceManager : public RefCountedBase { SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const; SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; + SourceLocation getRefinedSpellingLocSlowCase(SourceLocation Loc) const; SourceLocation getFileLocSlowCase(SourceLocation Loc) const; FileIDAndOffset diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index d8ec837f0f7b9..6f7a9c4614091 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -915,6 +915,21 @@ SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const { return Loc; } +SourceLocation +SourceManager::getRefinedSpellingLocSlowCase(SourceLocation Loc) const { + do { + const SLocEntry &Entry = getSLocEntry(getFileID(Loc)); + const ExpansionInfo &ExpInfo = Entry.getExpansion(); + if (ExpInfo.isMacroArgExpansion()) { + Loc = ExpInfo.getSpellingLoc().getLocWithOffset(Loc.getOffset() - + Entry.getOffset()); + } else { + Loc = ExpInfo.getExpansionLocStart(); + } + } while (!Loc.isFileID()); + return Loc; +} + SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const { do { if (isMacroArgExpansion(Loc)) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9fe9a13610296..913fb7da3bcaa 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -318,7 +318,8 @@ void CGDebugInfo::setLocation(SourceLocation Loc) { if (Loc.isInvalid()) return; - CurLoc = CGM.getContext().getSourceManager().getExpansionLoc(Loc); + SourceManager &SM = CGM.getContext().getSourceManager(); + CurLoc = SM.getRefinedSpellingLoc(Loc); // 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,7 +327,6 @@ void CGDebugInfo::setLocation(SourceLocation Loc) { if (LexicalBlockStack.empty()) return; - SourceManager &SM = CGM.getContext().getSourceManager(); auto *Scope = cast(LexicalBlockStack.back()); PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc); if (PCLoc.isInvalid() || Scope->getFile() == getOrCreateFile(CurLoc)) @@ -545,6 +545,7 @@ llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) { FileName = TheCU->getFile()->getFilename(); CSInfo = TheCU->getFile()->getChecksum(); } else { + assert(Loc.isFileID()); PresumedLoc PLoc = SM.getPresumedLoc(Loc); FileName = PLoc.getFilename(); @@ -627,6 +628,7 @@ unsigned CGDebugInfo::getLineNumber(SourceLocation Loc) { if (Loc.isInvalid()) return 0; SourceManager &SM = CGM.getContext().getSourceManager(); + assert(Loc.isFileID()); return SM.getPresumedLoc(Loc).getLine(); } @@ -639,6 +641,7 @@ unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) { if (Loc.isInvalid() && CurLoc.isInvalid()) return 0; SourceManager &SM = CGM.getContext().getSourceManager(); + assert(Loc.isFileID()); PresumedLoc PLoc = SM.getPresumedLoc(Loc.isValid() ? Loc : CurLoc); return PLoc.isValid() ? PLoc.getColumn() : 0; } @@ -1329,9 +1332,9 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0))) return cast(T); - llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); - const unsigned Line = - getLineNumber(RD->getLocation().isValid() ? RD->getLocation() : CurLoc); + SourceLocation Loc = getRefinedSpellingLocation(RD->getLocation()); + llvm::DIFile *DefUnit = getOrCreateFile(Loc); + const unsigned Line = getLineNumber(Loc.isValid() ? Loc : CurLoc); StringRef RDName = getClassName(RD); uint64_t Size = 0; @@ -1558,7 +1561,7 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, auto PP = getPrintingPolicy(); Ty->getTemplateName().print(OS, PP, TemplateName::Qualified::None); - SourceLocation Loc = AliasDecl->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(AliasDecl->getLocation()); if (CGM.getCodeGenOpts().DebugTemplateAlias) { auto ArgVector = ::GetTemplateArgs(TD, Ty); @@ -1627,7 +1630,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(); + SourceLocation Loc = getRefinedSpellingLocation(Ty->getDecl()->getLocation()); uint32_t Align = getDeclAlignIfRequired(Ty->getDecl(), CGM.getContext()); // Typedefs are derived from some other type. @@ -1761,7 +1764,7 @@ CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl, QualType Ty = BitFieldDecl->getType(); if (BitFieldDecl->hasAttr()) Ty = BitFieldDecl->getAttr()->getType(); - SourceLocation Loc = BitFieldDecl->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(BitFieldDecl->getLocation()); llvm::DIFile *VUnit = getOrCreateFile(Loc); llvm::DIType *DebugType = getOrCreateType(Ty, VUnit); @@ -1839,7 +1842,8 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded( return nullptr; QualType Ty = PreviousBitfield->getType(); - SourceLocation Loc = PreviousBitfield->getLocation(); + SourceLocation Loc = + getRefinedSpellingLocation(PreviousBitfield->getLocation()); llvm::DIFile *VUnit = getOrCreateFile(Loc); llvm::DIType *DebugType = getOrCreateType(Ty, VUnit); llvm::DIScope *RecordTy = BitFieldDI->getScope(); @@ -1958,6 +1962,7 @@ void CGDebugInfo::CollectRecordLambdaFields( continue; } + Loc = getRefinedSpellingLocation(Loc); llvm::DIFile *VUnit = getOrCreateFile(Loc); elements.push_back(createFieldType( @@ -1972,10 +1977,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()); + SourceLocation Loc = getRefinedSpellingLocation(Var->getLocation()); + llvm::DIFile *VUnit = getOrCreateFile(Loc); llvm::DIType *VTy = getOrCreateType(Var->getType(), VUnit); - unsigned LineNumber = getLineNumber(Var->getLocation()); + unsigned LineNumber = getLineNumber(Loc); StringRef VName = Var->getName(); // FIXME: to avoid complications with type merging we should @@ -2023,9 +2029,10 @@ 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, getRefinedSpellingLocation(field->getLocation()), + field->getAccess(), OffsetInBits, Align, tunit, RecordTy, RD, + Annotations); } elements.push_back(FieldType); @@ -2039,7 +2046,7 @@ void CGDebugInfo::CollectRecordNestedType( // instead? if (isa(Ty)) return; - SourceLocation Loc = TD->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(TD->getLocation()); if (llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateFile(Loc))) elements.push_back(nestedType); } @@ -2243,8 +2250,9 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction( llvm::DIFile *MethodDefUnit = nullptr; unsigned MethodLine = 0; if (!Method->isImplicit()) { - MethodDefUnit = getOrCreateFile(Method->getLocation()); - MethodLine = getLineNumber(Method->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(Method->getLocation()); + MethodDefUnit = getOrCreateFile(Loc); + MethodLine = getLineNumber(Loc); } // Collect virtual method info. @@ -2695,7 +2703,7 @@ void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable, ASTContext &Context = CGM.getContext(); StringRef SymbolName = "_vtable$"; - SourceLocation Loc; + SourceLocation InvalidLoc; QualType VoidPtr = Context.getPointerType(Context.VoidTy); // We deal with two different contexts: @@ -2707,7 +2715,7 @@ void CGDebugInfo::emitVTableSymbol(llvm::GlobalVariable *VTable, // placed inside the scope of the C++ class/structure. llvm::DIScope *DContext = getContextDescriptor(RD, TheCU); auto *Ctxt = cast(DContext); - llvm::DIFile *Unit = getOrCreateFile(Loc); + llvm::DIFile *Unit = getOrCreateFile(InvalidLoc); llvm::DIType *VTy = getOrCreateType(VoidPtr, Unit); llvm::DINode::DIFlags Flags = getAccessFlag(AccessSpecifier::AS_private, RD) | llvm::DINode::FlagArtificial; @@ -2844,6 +2852,7 @@ void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit, llvm::DIType *CGDebugInfo::getOrCreateRecordType(QualType RTy, SourceLocation Loc) { assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); + Loc = getRefinedSpellingLocation(Loc); llvm::DIType *T = getOrCreateType(RTy, getOrCreateFile(Loc)); return T; } @@ -2857,6 +2866,7 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D, SourceLocation Loc) { assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); assert(!D.isNull() && "null type"); + Loc = getRefinedSpellingLocation(Loc); llvm::DIType *T = getOrCreateType(D, getOrCreateFile(Loc)); assert(T && "could not create debug info for type"); @@ -2874,7 +2884,8 @@ 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(getRefinedSpellingLocation(Loc))); CI->setMetadata("heapallocsite", node); } @@ -3107,8 +3118,9 @@ std::pair CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + SourceLocation Loc = getRefinedSpellingLocation(RD->getLocation()); // Get overall information about the record type for the debug info. - llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); + llvm::DIFile *DefUnit = getOrCreateFile(Loc); // 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. @@ -3176,7 +3188,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty, llvm::DIType *CGDebugInfo::CreateType(const ObjCTypeParamType *Ty, llvm::DIFile *Unit) { // Ignore protocols. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(Ty->getDecl()->getLocation()); // Use Typedefs to represent ObjCTypeParamType. return DBuilder.createTypedef( @@ -3227,9 +3239,10 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty, llvm::dwarf::DW_TAG_structure_type, ID->getName(), getDeclContextDescriptor(ID), Unit, 0, RuntimeLang); + SourceLocation Loc = getRefinedSpellingLocation(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(Loc); + unsigned Line = getLineNumber(Loc); // 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. @@ -3350,8 +3363,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()); + SourceLocation Loc = getRefinedSpellingLocation(ID->getLocation()); + llvm::DIFile *DefUnit = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); unsigned RuntimeLang = TheCU->getSourceLanguage().getUnversionedName(); @@ -3446,9 +3460,10 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, if (FieldName.empty()) continue; + SourceLocation Loc = getRefinedSpellingLocation(Field->getLocation()); // Get the location for the field. - llvm::DIFile *FieldDefUnit = getOrCreateFile(Field->getLocation()); - unsigned FieldLine = getLineNumber(Field->getLocation()); + llvm::DIFile *FieldDefUnit = getOrCreateFile(Loc); + unsigned FieldLine = getLineNumber(Loc); QualType FType = Field->getType(); uint64_t FieldSize = 0; uint32_t FieldAlign = 0; @@ -3493,7 +3508,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, if (ObjCPropertyImplDecl *PImpD = ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) { if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) { - SourceLocation Loc = PD->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(PD->getLocation()); llvm::DIFile *PUnit = getOrCreateFile(Loc); unsigned PLine = getLineNumber(Loc); ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl(); @@ -3775,11 +3790,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()); + SourceLocation Loc = getRefinedSpellingLocation(ED->getLocation()); + llvm::DIFile *DefUnit = getOrCreateFile(Loc); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); - unsigned Line = getLineNumber(ED->getLocation()); + unsigned Line = getLineNumber(Loc); StringRef EDName = ED->getName(); llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line, @@ -3812,8 +3828,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()); + SourceLocation Loc = getRefinedSpellingLocation(ED->getLocation()); + llvm::DIFile *DefUnit = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit); return DBuilder.createEnumerationType( @@ -3831,8 +3848,10 @@ llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent, 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(getRefinedSpellingLocation(FileLoc)); + unsigned Line = LineLoc.isInvalid() + ? 0 + : getLineNumber(getRefinedSpellingLocation(LineLoc)); return DBuilder.createTempMacroFile(Parent, Line, FName); } @@ -4155,7 +4174,7 @@ 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(); + const SourceLocation Loc = getRefinedSpellingLocation(RD->getLocation()); llvm::DIFile *DefUnit = nullptr; unsigned Line = 0; if (Loc.isValid()) { @@ -4270,7 +4289,8 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD, break; } CanQualType T = CGM.getContext().getCanonicalTagType(PBase); - ContainingType = getOrCreateType(T, getOrCreateFile(RD->getLocation())); + SourceLocation Loc = getRefinedSpellingLocation(RD->getLocation()); + ContainingType = getOrCreateType(T, getOrCreateFile(Loc)); } else if (RD->isDynamicClass()) ContainingType = RealDecl; @@ -4341,10 +4361,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()); + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); + Unit = getOrCreateFile(Loc); + LineNo = getLineNumber(Loc); - setLocation(VD->getLocation()); + setLocation(Loc); T = VD->getType(); if (T->isIncompleteArrayType()) { @@ -4397,7 +4418,7 @@ 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(); + SourceLocation Loc = getRefinedSpellingLocation(GD.getDecl()->getLocation()); llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIScope *DContext = Unit; unsigned Line = getLineNumber(Loc); @@ -4452,7 +4473,7 @@ llvm::DIGlobalVariable * CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) { QualType T; StringRef Name, LinkageName; - SourceLocation Loc = VD->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIScope *DContext = Unit; unsigned Line = getLineNumber(Loc); @@ -4478,7 +4499,8 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { // in unlimited debug info) if (const auto *TD = dyn_cast(D)) { QualType Ty = CGM.getContext().getTypeDeclType(TD); - return getOrCreateType(Ty, getOrCreateFile(TD->getLocation())); + SourceLocation Loc = getRefinedSpellingLocation(TD->getLocation()); + return getOrCreateType(Ty, getOrCreateFile(Loc)); } auto I = DeclCache.find(D->getCanonicalDecl()); @@ -4524,7 +4546,8 @@ llvm::DISubprogram *CGDebugInfo::getFunctionDeclaration(const Decl *D) { auto MI = SPCache.find(FD->getCanonicalDecl()); if (MI == SPCache.end()) { if (const auto *MD = dyn_cast(FD->getCanonicalDecl())) { - return CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), + SourceLocation Loc = getRefinedSpellingLocation(MD->getLocation()); + return CreateCXXMemberFunction(MD, getOrCreateFile(Loc), cast(S)); } } @@ -4686,6 +4709,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc, const Decl *D = GD.getDecl(); bool HasDecl = (D != nullptr); + Loc = getRefinedSpellingLocation(Loc); llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; @@ -4754,7 +4778,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc, SPFlags | llvm::DISubprogram::SPFlagDefinition; const unsigned LineNo = getLineNumber(Loc.isValid() ? Loc : CurLoc); - unsigned ScopeLine = getLineNumber(ScopeLoc); + unsigned ScopeLine = getLineNumber(getRefinedSpellingLocation(ScopeLoc)); llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit); llvm::DISubprogram *Decl = nullptr; llvm::DINodeArray Annotations = nullptr; @@ -4802,6 +4826,7 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, return GetName(D, true); }); + Loc = getRefinedSpellingLocation(Loc); llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; llvm::DIFile *Unit = getOrCreateFile(Loc); bool IsDeclForCallSite = Fn ? true : false; @@ -4929,6 +4954,11 @@ void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) { getColumnNumber(CurLoc))); } +SourceLocation +CGDebugInfo::getRefinedSpellingLocation(SourceLocation Loc) const { + return CGM.getContext().getSourceManager().getRefinedSpellingLoc(Loc); +} + void CGDebugInfo::AppendAddressSpaceXDeref( unsigned AddressSpace, SmallVectorImpl &Expr) const { std::optional DWARFAddressSpace = @@ -4945,6 +4975,7 @@ void CGDebugInfo::AppendAddressSpaceXDeref( void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc) { // Set our current location. + Loc = getRefinedSpellingLocation(Loc); setLocation(Loc); // Emit a line table change for the current location inside the new scope. @@ -4997,7 +5028,8 @@ CGDebugInfo::EmitTypeForVarWithBlocksAttr(const VarDecl *VD, uint64_t FieldSize, FieldOffset; uint32_t FieldAlign; - llvm::DIFile *Unit = getOrCreateFile(VD->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); QualType Type = VD->getType(); FieldOffset = 0; @@ -5073,8 +5105,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, const bool VarIsArtificial = IsArtificial(VD); llvm::DIFile *Unit = nullptr; + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); if (!VarIsArtificial) - Unit = getOrCreateFile(VD->getLocation()); + Unit = getOrCreateFile(Loc); llvm::DIType *Ty; uint64_t XOffset = 0; if (VD->hasAttr()) @@ -5091,8 +5124,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(Loc); + Column = getColumnNumber(Loc); } SmallVector Expr; llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; @@ -5258,7 +5291,8 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const BindingDecl *BD, if (isa(BD->getBinding())) return nullptr; - llvm::DIFile *Unit = getOrCreateFile(BD->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(BD->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIType *Ty = getOrCreateType(BD->getType(), Unit); // If there is no debug info for this type then do not emit debug info @@ -5281,8 +5315,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(Loc); + unsigned Column = getColumnNumber(Loc); StringRef Name = BD->getName(); auto *Scope = cast(LexicalBlockStack.back()); // Create the descriptor for the variable. @@ -5376,11 +5410,12 @@ void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) { return; auto *Scope = cast(LexicalBlockStack.back()); - llvm::DIFile *Unit = getOrCreateFile(D->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(D->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); // Get location information. - unsigned Line = getLineNumber(D->getLocation()); - unsigned Column = getColumnNumber(D->getLocation()); + unsigned Line = getLineNumber(Loc); + unsigned Column = getColumnNumber(Loc); StringRef Name = D->getName(); @@ -5419,7 +5454,8 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable( bool isByRef = VD->hasAttr(); uint64_t XOffset = 0; - llvm::DIFile *Unit = getOrCreateFile(VD->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIType *Ty; if (isByRef) Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType; @@ -5433,9 +5469,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(Loc.isValid() ? Loc : CurLoc); + unsigned Column = getColumnNumber(Loc); const llvm::DataLayout &target = CGM.getDataLayout(); @@ -5543,7 +5578,8 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, const BlockDecl *blockDecl = block.getBlockDecl(); // Collect some general information about the block's location. - SourceLocation loc = blockDecl->getCaretLocation(); + SourceLocation loc = + getRefinedSpellingLocation(blockDecl->getCaretLocation()); llvm::DIFile *tunit = getOrCreateFile(loc); unsigned line = getLineNumber(loc); unsigned column = getColumnNumber(loc); @@ -6015,8 +6051,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { }); auto Align = getDeclAlignIfRequired(VD, CGM.getContext()); + SourceLocation Loc = getRefinedSpellingLocation(VD->getLocation()); // Create the descriptor for the variable. - llvm::DIFile *Unit = getOrCreateFile(VD->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); StringRef Name = VD->getName(); llvm::DIType *Ty = getOrCreateType(VD->getType(), Unit); @@ -6074,8 +6111,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(Loc), Ty, true, true, + InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD), TemplateParameters, Align)); } @@ -6086,15 +6123,16 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, return; auto Align = getDeclAlignIfRequired(D, CGM.getContext()); - llvm::DIFile *Unit = getOrCreateFile(D->getLocation()); + SourceLocation Loc = getRefinedSpellingLocation(D->getLocation()); + llvm::DIFile *Unit = getOrCreateFile(Loc); 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(Loc), Ty, false, + false, nullptr, nullptr, nullptr, Align); Var->addDebugInfo(GVE); } @@ -6171,7 +6209,7 @@ void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV, return; llvm::DIScope *DContext = getDeclContextDescriptor(D); - auto Loc = D->getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(D->getLocation()); llvm::DIImportedEntity *ImportDI = DBuilder.createImportedDeclaration( DContext, DI, getOrCreateFile(Loc), getLineNumber(Loc), D->getName()); @@ -6182,7 +6220,7 @@ void CGDebugInfo::EmitGlobalAlias(const llvm::GlobalValue *GV, void CGDebugInfo::AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, const StringLiteral *S) { - SourceLocation Loc = S->getStrTokenLoc(0); + SourceLocation Loc = getRefinedSpellingLocation(S->getStrTokenLoc(0)); PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc); if (!PLoc.isValid()) return; @@ -6190,8 +6228,8 @@ void CGDebugInfo::AddStringLiteralDebugInfo(llvm::GlobalVariable *GV, llvm::DIFile *File = getOrCreateFile(Loc); llvm::DIGlobalVariableExpression *Debug = DBuilder.createGlobalVariableExpression( - nullptr, StringRef(), StringRef(), getOrCreateFile(Loc), - getLineNumber(Loc), getOrCreateType(S->getType(), File), true); + nullptr, StringRef(), StringRef(), File, getLineNumber(Loc), + getOrCreateType(S->getType(), File), true); GV->addDebugInfo(Debug); } @@ -6208,7 +6246,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { const NamespaceDecl *NSDecl = UD.getNominatedNamespace(); if (!NSDecl->isAnonymousNamespace() || CGM.getCodeGenOpts().DebugExplicitImport) { - auto Loc = UD.getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(UD.getLocation()); if (!Loc.isValid()) Loc = CurLoc; DBuilder.createImportedModule( @@ -6220,7 +6258,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) { void CGDebugInfo::EmitUsingShadowDecl(const UsingShadowDecl &USD) { if (llvm::DINode *Target = getDeclarationOrDefinition(USD.getUnderlyingDecl())) { - auto Loc = USD.getLocation(); + SourceLocation Loc = getRefinedSpellingLocation(USD.getLocation()); DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast(USD.getDeclContext())), Target, getOrCreateFile(Loc), getLineNumber(Loc)); @@ -6268,7 +6306,7 @@ void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) { return; if (Module *M = ID.getImportedModule()) { auto Info = ASTSourceDescriptor(*M); - auto Loc = ID.getLocation(); + auto Loc = getRefinedSpellingLocation(ID.getLocation()); DBuilder.createImportedDeclaration( getCurrentContextDescriptor(cast(ID.getDeclContext())), getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc), @@ -6284,7 +6322,7 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) { if (VH) return cast(VH); llvm::DIImportedEntity *R; - auto Loc = NA.getLocation(); + auto Loc = getRefinedSpellingLocation(NA.getLocation()); if (const auto *Underlying = dyn_cast(NA.getAliasedNamespace())) // This could cache & dedup here rather than relying on metadata deduping. @@ -6416,6 +6454,7 @@ llvm::DebugLoc CGDebugInfo::SourceLocToDebugLoc(SourceLocation Loc) { if (LexicalBlockStack.empty()) return llvm::DebugLoc(); + Loc = getRefinedSpellingLocation(Loc); llvm::MDNode *Scope = LexicalBlockStack.back(); return llvm::DILocation::get(CGM.getLLVMContext(), getLineNumber(Loc), getColumnNumber(Loc), Scope); diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index 78c3eb9c5792e..206f72e6417b1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -408,6 +408,18 @@ class CGDebugInfo { /// Create a new lexical block node and push it on the stack. void CreateLexicalBlock(SourceLocation Loc); + /// All locations handled by CGDebugInfo are refined locations because this + /// is more suitable for debugging than pure spelling or expansion locations. + /// + /// Refined locations do not point into macro definitions. If a source + /// location is part of a macro argument expansion, its refined location is + /// the spelling location of the argument. If a source location is part of a + /// macro body, its refined location is the expansion location. + /// + /// This allows debuggers to show the macro invocation site or the argument + /// site, but not the macro definition body. + SourceLocation getRefinedSpellingLocation(SourceLocation Loc) const; + /// If target-specific LLVM \p AddressSpace directly maps to target-specific /// DWARF address space, appends extended dereferencing mechanism to complex /// expression \p Expr. Otherwise, does nothing. diff --git a/clang/test/DebugInfo/Generic/macro-info.c b/clang/test/DebugInfo/Generic/macro-info.c new file mode 100644 index 0000000000000..5029c110ee170 --- /dev/null +++ b/clang/test/DebugInfo/Generic/macro-info.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -debug-info-kind=standalone -emit-llvm -o - | FileCheck %s + +#define GLOBAL(num) global##num +#define DECL_GLOBAL(x) int x +#define SAME_ORDER(x, y) x; y +#define SWAP_ORDER(x,y) y; x + +// CHECK: DIGlobalVariable(name: "global",{{.*}} line: [[@LINE+4]] +// CHECK: DIGlobalVariable({{.*}}line: [[@LINE+6]],{{.*}} type: [[TYPEID:![0-9]+]] +SAME_ORDER( + int + GLOBAL // <- global + () = 42, + const char* s() { + return "1234567890"; + } +) +// CHECK: DIGlobalVariable(name: "global3",{{.*}} line: [[@LINE+6]] +// CHECK: DIGlobalVariable(name: "global2",{{.*}} line: [[@LINE+2]] +SWAP_ORDER( + int GLOBAL( // <- global2 + 2) = 43, + DECL_GLOBAL( + GLOBAL( // <- global3 + 3)) = 44 +); + + +// CHECK: DIGlobalVariable(name: "global4",{{.*}} line: [[@LINE+2]] +DECL_GLOBAL( + GLOBAL( // <- global4 + 4));