Path: blob/main/contrib/llvm-project/llvm/lib/IR/DebugLoc.cpp
35233 views
//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/IR/DebugLoc.h"9#include "llvm/Config/llvm-config.h"10#include "llvm/IR/DebugInfo.h"11using namespace llvm;1213//===----------------------------------------------------------------------===//14// DebugLoc Implementation15//===----------------------------------------------------------------------===//16DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}17DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}1819DILocation *DebugLoc::get() const {20return cast_or_null<DILocation>(Loc.get());21}2223unsigned DebugLoc::getLine() const {24assert(get() && "Expected valid DebugLoc");25return get()->getLine();26}2728unsigned DebugLoc::getCol() const {29assert(get() && "Expected valid DebugLoc");30return get()->getColumn();31}3233MDNode *DebugLoc::getScope() const {34assert(get() && "Expected valid DebugLoc");35return get()->getScope();36}3738DILocation *DebugLoc::getInlinedAt() const {39assert(get() && "Expected valid DebugLoc");40return get()->getInlinedAt();41}4243MDNode *DebugLoc::getInlinedAtScope() const {44return cast<DILocation>(Loc)->getInlinedAtScope();45}4647DebugLoc DebugLoc::getFnDebugLoc() const {48// FIXME: Add a method on \a DILocation that does this work.49const MDNode *Scope = getInlinedAtScope();50if (auto *SP = getDISubprogram(Scope))51return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);5253return DebugLoc();54}5556bool DebugLoc::isImplicitCode() const {57if (DILocation *Loc = get()) {58return Loc->isImplicitCode();59}60return true;61}6263void DebugLoc::setImplicitCode(bool ImplicitCode) {64if (DILocation *Loc = get()) {65Loc->setImplicitCode(ImplicitCode);66}67}6869DebugLoc DebugLoc::replaceInlinedAtSubprogram(70const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx,71DenseMap<const MDNode *, MDNode *> &Cache) {72SmallVector<DILocation *> LocChain;73DILocation *CachedResult = nullptr;7475// Collect the inline chain, stopping if we find a location that has already76// been processed.77for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) {78if (auto It = Cache.find(Loc); It != Cache.end()) {79CachedResult = cast<DILocation>(It->second);80break;81}82LocChain.push_back(Loc);83}8485DILocation *UpdatedLoc = CachedResult;86if (!UpdatedLoc) {87// If no cache hits, then back() is the end of the inline chain, that is,88// the DILocation whose scope ends in the Subprogram to be replaced.89DILocation *LocToUpdate = LocChain.pop_back_val();90DIScope *NewScope = DILocalScope::cloneScopeForSubprogram(91*LocToUpdate->getScope(), NewSP, Ctx, Cache);92UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(),93LocToUpdate->getColumn(), NewScope);94Cache[LocToUpdate] = UpdatedLoc;95}9697// Recreate the location chain, bottom-up, starting at the new scope (or a98// cached result).99for (const DILocation *LocToUpdate : reverse(LocChain)) {100UpdatedLoc =101DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(),102LocToUpdate->getScope(), UpdatedLoc);103Cache[LocToUpdate] = UpdatedLoc;104}105106return UpdatedLoc;107}108109DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,110LLVMContext &Ctx,111DenseMap<const MDNode *, MDNode *> &Cache) {112SmallVector<DILocation *, 3> InlinedAtLocations;113DILocation *Last = InlinedAt;114DILocation *CurInlinedAt = DL;115116// Gather all the inlined-at nodes.117while (DILocation *IA = CurInlinedAt->getInlinedAt()) {118// Skip any we've already built nodes for.119if (auto *Found = Cache[IA]) {120Last = cast<DILocation>(Found);121break;122}123124InlinedAtLocations.push_back(IA);125CurInlinedAt = IA;126}127128// Starting from the top, rebuild the nodes to point to the new inlined-at129// location (then rebuilding the rest of the chain behind it) and update the130// map of already-constructed inlined-at nodes.131for (const DILocation *MD : reverse(InlinedAtLocations))132Cache[MD] = Last = DILocation::getDistinct(133Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);134135return Last;136}137138#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)139LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }140#endif141142void DebugLoc::print(raw_ostream &OS) const {143if (!Loc)144return;145146// Print source line info.147auto *Scope = cast<DIScope>(getScope());148OS << Scope->getFilename();149OS << ':' << getLine();150if (getCol() != 0)151OS << ':' << getCol();152153if (DebugLoc InlinedAtDL = getInlinedAt()) {154OS << " @[ ";155InlinedAtDL.print(OS);156OS << " ]";157}158}159160161