@@ -365,15 +365,15 @@ unsigned CodeViewDebug::getPointerSizeInBytes() {
365
365
}
366
366
367
367
void CodeViewDebug::recordLocalVariable (LocalVariable &&Var,
368
- const DILocation *InlinedAt ) {
369
- if (InlinedAt) {
368
+ const LexicalScope *LS ) {
369
+ if (const DILocation * InlinedAt = LS-> getInlinedAt () ) {
370
370
// This variable was inlined. Associate it with the InlineSite.
371
371
const DISubprogram *Inlinee = Var.DIVar ->getScope ()->getSubprogram ();
372
372
InlineSite &Site = getInlineSite (InlinedAt, Inlinee);
373
373
Site.InlinedLocals .emplace_back (Var);
374
374
} else {
375
- // This variable goes in the main ProcSym .
376
- CurFn-> Locals .emplace_back (Var);
375
+ // This variable goes into the corresponding lexical scope .
376
+ ScopeVariables[LS] .emplace_back (Var);
377
377
}
378
378
}
379
379
@@ -905,6 +905,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
905
905
OS.EmitLabel (ProcRecordEnd);
906
906
907
907
emitLocalVariableList (FI.Locals );
908
+ emitLexicalBlockList (FI.ChildBlocks , FI);
908
909
909
910
// Emit inlined call site information. Only emit functions inlined directly
910
911
// into the parent function. We'll emit the other sites recursively as part
@@ -1025,7 +1026,7 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
1025
1026
LocalVariable Var;
1026
1027
Var.DIVar = VI.Var ;
1027
1028
Var.DefRanges .emplace_back (std::move (DefRange));
1028
- recordLocalVariable (std::move (Var), VI. Loc -> getInlinedAt () );
1029
+ recordLocalVariable (std::move (Var), Scope );
1029
1030
}
1030
1031
}
1031
1032
@@ -1156,7 +1157,7 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
1156
1157
Var.DIVar = DIVar;
1157
1158
1158
1159
calculateRanges (Var, Ranges);
1159
- recordLocalVariable (std::move (Var), InlinedAt );
1160
+ recordLocalVariable (std::move (Var), Scope );
1160
1161
}
1161
1162
}
1162
1163
@@ -2363,13 +2364,147 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
2363
2364
}
2364
2365
}
2365
2366
2367
+ void CodeViewDebug::emitLexicalBlockList (ArrayRef<LexicalBlock *> Blocks,
2368
+ const FunctionInfo& FI) {
2369
+ for (LexicalBlock *Block : Blocks)
2370
+ emitLexicalBlock (*Block, FI);
2371
+ }
2372
+
2373
+ // / Emit an S_BLOCK32 and S_END record pair delimiting the contents of a
2374
+ // / lexical block scope.
2375
+ void CodeViewDebug::emitLexicalBlock (const LexicalBlock &Block,
2376
+ const FunctionInfo& FI) {
2377
+ MCSymbol *RecordBegin = MMI->getContext ().createTempSymbol (),
2378
+ *RecordEnd = MMI->getContext ().createTempSymbol ();
2379
+
2380
+ // Lexical block symbol record.
2381
+ OS.AddComment (" Record length" );
2382
+ OS.emitAbsoluteSymbolDiff (RecordEnd, RecordBegin, 2 ); // Record Length
2383
+ OS.EmitLabel (RecordBegin);
2384
+ OS.AddComment (" Record kind: S_BLOCK32" );
2385
+ OS.EmitIntValue (SymbolKind::S_BLOCK32, 2 ); // Record Kind
2386
+ OS.AddComment (" PtrParent" );
2387
+ OS.EmitIntValue (0 , 4 ); // PtrParent
2388
+ OS.AddComment (" PtrEnd" );
2389
+ OS.EmitIntValue (0 , 4 ); // PtrEnd
2390
+ OS.AddComment (" Code size" );
2391
+ OS.emitAbsoluteSymbolDiff (Block.End , Block.Begin , 4 ); // Code Size
2392
+ OS.AddComment (" Function section relative address" );
2393
+ OS.EmitCOFFSecRel32 (Block.Begin , /* Offset=*/ 0 ); // Func Offset
2394
+ OS.AddComment (" Function section index" );
2395
+ OS.EmitCOFFSectionIndex (FI.Begin ); // Func Symbol
2396
+ OS.AddComment (" Lexical block name" );
2397
+ emitNullTerminatedSymbolName (OS, Block.Name ); // Name
2398
+ OS.EmitLabel (RecordEnd);
2399
+
2400
+ // Emit variables local to this lexical block.
2401
+ emitLocalVariableList (Block.Locals );
2402
+
2403
+ // Emit lexical blocks contained within this block.
2404
+ emitLexicalBlockList (Block.Children , FI);
2405
+
2406
+ // Close the lexical block scope.
2407
+ OS.AddComment (" Record length" );
2408
+ OS.EmitIntValue (2 , 2 ); // Record Length
2409
+ OS.AddComment (" Record kind: S_END" );
2410
+ OS.EmitIntValue (SymbolKind::S_END, 2 ); // Record Kind
2411
+ }
2412
+
2413
+ // / Convenience routine for collecting lexical block information for a list
2414
+ // / of lexical scopes.
2415
+ void CodeViewDebug::collectLexicalBlockInfo (
2416
+ SmallVectorImpl<LexicalScope *> &Scopes,
2417
+ SmallVectorImpl<LexicalBlock *> &Blocks,
2418
+ SmallVectorImpl<LocalVariable> &Locals) {
2419
+ for (LexicalScope *Scope : Scopes)
2420
+ collectLexicalBlockInfo (*Scope, Blocks, Locals);
2421
+ }
2422
+
2423
+ // / Populate the lexical blocks and local variable lists of the parent with
2424
+ // / information about the specified lexical scope.
2425
+ void CodeViewDebug::collectLexicalBlockInfo (
2426
+ LexicalScope &Scope,
2427
+ SmallVectorImpl<LexicalBlock *> &ParentBlocks,
2428
+ SmallVectorImpl<LocalVariable> &ParentLocals) {
2429
+ if (Scope.isAbstractScope ())
2430
+ return ;
2431
+
2432
+ auto LocalsIter = ScopeVariables.find (&Scope);
2433
+ if (LocalsIter == ScopeVariables.end ()) {
2434
+ // This scope does not contain variables and can be eliminated.
2435
+ collectLexicalBlockInfo (Scope.getChildren (), ParentBlocks, ParentLocals);
2436
+ return ;
2437
+ }
2438
+ SmallVectorImpl<LocalVariable> &Locals = LocalsIter->second ;
2439
+
2440
+ const DILexicalBlock *DILB = dyn_cast<DILexicalBlock>(Scope.getScopeNode ());
2441
+ if (!DILB) {
2442
+ // This scope is not a lexical block and can be eliminated, but keep any
2443
+ // local variables it contains.
2444
+ ParentLocals.append (Locals.begin (), Locals.end ());
2445
+ collectLexicalBlockInfo (Scope.getChildren (), ParentBlocks, ParentLocals);
2446
+ return ;
2447
+ }
2448
+
2449
+ const SmallVectorImpl<InsnRange> &Ranges = Scope.getRanges ();
2450
+ if (Ranges.size () != 1 || !getLabelAfterInsn (Ranges.front ().second )) {
2451
+ // This lexical block scope has too many address ranges to represent in the
2452
+ // current CodeView format or does not have a valid address range.
2453
+ // Eliminate this lexical scope and promote any locals it contains to the
2454
+ // parent scope.
2455
+ //
2456
+ // For lexical scopes with multiple address ranges you may be tempted to
2457
+ // construct a single range covering every instruction where the block is
2458
+ // live and everything in between. Unfortunately, Visual Studio only
2459
+ // displays variables from the first matching lexical block scope. If the
2460
+ // first lexical block contains exception handling code or cold code which
2461
+ // is moved to the bottom of the routine creating a single range covering
2462
+ // nearly the entire routine, then it will hide all other lexical blocks
2463
+ // and the variables they contain.
2464
+ //
2465
+ ParentLocals.append (Locals.begin (), Locals.end ());
2466
+ collectLexicalBlockInfo (Scope.getChildren (), ParentBlocks, ParentLocals);
2467
+ return ;
2468
+ }
2469
+
2470
+ // Create a new CodeView lexical block for this lexical scope. If we've
2471
+ // seen this DILexicalBlock before then the scope tree is malformed and
2472
+ // we can handle this gracefully by not processing it a second time.
2473
+ auto BlockInsertion = CurFn->LexicalBlocks .insert ({DILB, LexicalBlock ()});
2474
+ if (!BlockInsertion.second )
2475
+ return ;
2476
+
2477
+ // Create a lexical block containing the local variables and collect the
2478
+ // the lexical block information for the children.
2479
+ const InsnRange &Range = Ranges.front ();
2480
+ assert (Range.first && Range.second );
2481
+ LexicalBlock &Block = BlockInsertion.first ->second ;
2482
+ Block.Begin = getLabelBeforeInsn (Range.first );
2483
+ Block.End = getLabelAfterInsn (Range.second );
2484
+ assert (Block.Begin && " missing label for scope begin" );
2485
+ assert (Block.End && " missing label for scope end" );
2486
+ Block.Name = DILB->getName ();
2487
+ Block.Locals = std::move (Locals);
2488
+ ParentBlocks.push_back (&Block);
2489
+ collectLexicalBlockInfo (Scope.getChildren (), Block.Children , Block.Locals );
2490
+ }
2491
+
2366
2492
void CodeViewDebug::endFunctionImpl (const MachineFunction *MF) {
2367
2493
const Function &GV = MF->getFunction ();
2368
2494
assert (FnDebugInfo.count (&GV));
2369
2495
assert (CurFn == FnDebugInfo[&GV].get ());
2370
2496
2371
2497
collectVariableInfo (GV.getSubprogram ());
2372
2498
2499
+ // Build the lexical block structure to emit for this routine.
2500
+ if (LexicalScope *CFS = LScopes.getCurrentFunctionScope ())
2501
+ collectLexicalBlockInfo (*CFS, CurFn->ChildBlocks , CurFn->Locals );
2502
+
2503
+ // Clear the scope and variable information from the map which will not be
2504
+ // valid after we have finished processing this routine. This also prepares
2505
+ // the map for the subsequent routine.
2506
+ ScopeVariables.clear ();
2507
+
2373
2508
// Don't emit anything if we don't have any line tables.
2374
2509
if (!CurFn->HaveLineInfo ) {
2375
2510
FnDebugInfo.erase (&GV);
0 commit comments