| 272 | } |
| 273 | |
| 274 | uint32_t DebugInfoManager::BuildDebugInlinedAtChain( |
| 275 | uint32_t callee_inlined_at, DebugInlinedAtContext* inlined_at_ctx) { |
| 276 | if (inlined_at_ctx->GetScopeOfCallInstruction().GetLexicalScope() == |
| 277 | kNoDebugScope) |
| 278 | return kNoInlinedAt; |
| 279 | |
| 280 | // Reuse the already generated DebugInlinedAt chain if exists. |
| 281 | uint32_t already_generated_chain_head_id = |
| 282 | inlined_at_ctx->GetDebugInlinedAtChain(callee_inlined_at); |
| 283 | if (already_generated_chain_head_id != kNoInlinedAt) { |
| 284 | return already_generated_chain_head_id; |
| 285 | } |
| 286 | |
| 287 | const uint32_t new_dbg_inlined_at_id = |
| 288 | CreateDebugInlinedAt(inlined_at_ctx->GetLineOfCallInstruction(), |
| 289 | inlined_at_ctx->GetScopeOfCallInstruction()); |
| 290 | if (new_dbg_inlined_at_id == kNoInlinedAt) return kNoInlinedAt; |
| 291 | |
| 292 | if (callee_inlined_at == kNoInlinedAt) { |
| 293 | inlined_at_ctx->SetDebugInlinedAtChain(kNoInlinedAt, new_dbg_inlined_at_id); |
| 294 | return new_dbg_inlined_at_id; |
| 295 | } |
| 296 | |
| 297 | uint32_t chain_head_id = kNoInlinedAt; |
| 298 | uint32_t chain_iter_id = callee_inlined_at; |
| 299 | Instruction* last_inlined_at_in_chain = nullptr; |
| 300 | do { |
| 301 | Instruction* new_inlined_at_in_chain = CloneDebugInlinedAt( |
| 302 | chain_iter_id, /* insert_before */ last_inlined_at_in_chain); |
| 303 | assert(new_inlined_at_in_chain != nullptr); |
| 304 | |
| 305 | // Set DebugInlinedAt of the new scope as the head of the chain. |
| 306 | if (chain_head_id == kNoInlinedAt) |
| 307 | chain_head_id = new_inlined_at_in_chain->result_id(); |
| 308 | |
| 309 | // Previous DebugInlinedAt of the chain must point to the new |
| 310 | // DebugInlinedAt as its Inlined operand to build a recursive |
| 311 | // chain. |
| 312 | if (last_inlined_at_in_chain != nullptr) { |
| 313 | SetInlinedOperand(last_inlined_at_in_chain, |
| 314 | new_inlined_at_in_chain->result_id()); |
| 315 | } |
| 316 | last_inlined_at_in_chain = new_inlined_at_in_chain; |
| 317 | |
| 318 | chain_iter_id = GetInlinedOperand(new_inlined_at_in_chain); |
| 319 | } while (chain_iter_id != kNoInlinedAt); |
| 320 | |
| 321 | // Put |new_dbg_inlined_at_id| into the end of the chain. |
| 322 | SetInlinedOperand(last_inlined_at_in_chain, new_dbg_inlined_at_id); |
| 323 | |
| 324 | // Keep the new chain information that will be reused it. |
| 325 | inlined_at_ctx->SetDebugInlinedAtChain(callee_inlined_at, chain_head_id); |
| 326 | return chain_head_id; |
| 327 | } |
| 328 | |
| 329 | Instruction* DebugInfoManager::GetDebugOperationWithDeref() { |
| 330 | if (deref_operation_ != nullptr) return deref_operation_; |
no test coverage detected