1*515bc8c1Sserge-sans-paille#!/usr/bin/env python 2525cd59fSSerge Gueltonfrom __future__ import print_function 3fe9d1ee9SGreg Clayton 4fe9d1ee9SGreg Claytonimport lldb 5fe9d1ee9SGreg Claytonimport shlex 6fe9d1ee9SGreg Clayton 7b9c1b51eSKate Stone 8fe9d1ee9SGreg Clayton@lldb.command("shadow") 9296f166aSGreg Claytondef check_shadow_command(debugger, command, exe_ctx, result, dict): 10296f166aSGreg Clayton '''Check the currently selected stack frame for shadowed variables''' 11296f166aSGreg Clayton process = exe_ctx.GetProcess() 12296f166aSGreg Clayton state = process.GetState() 13296f166aSGreg Clayton if state != lldb.eStateStopped: 14525cd59fSSerge Guelton print("process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString( 15525cd59fSSerge Guelton state), file=result) 16fe9d1ee9SGreg Clayton return 17296f166aSGreg Clayton frame = exe_ctx.GetFrame() 18fe9d1ee9SGreg Clayton if not frame: 19525cd59fSSerge Guelton print("invalid frame", file=result) 20fe9d1ee9SGreg Clayton return 21fe9d1ee9SGreg Clayton # Parse command line args 22fe9d1ee9SGreg Clayton command_args = shlex.split(command) 23fe9d1ee9SGreg Clayton # TODO: add support for using arguments that are passed to this command... 24fe9d1ee9SGreg Clayton 25fe9d1ee9SGreg Clayton # Make a dictionary of variable name to "SBBlock and SBValue" 26296f166aSGreg Clayton shadow_dict = {} 27fe9d1ee9SGreg Clayton 28296f166aSGreg Clayton num_shadowed_variables = 0 29fe9d1ee9SGreg Clayton # Get the deepest most block from the current frame 30fe9d1ee9SGreg Clayton block = frame.GetBlock() 31fe9d1ee9SGreg Clayton # Iterate through the block and all of its parents 32fe9d1ee9SGreg Clayton while block.IsValid(): 33fe9d1ee9SGreg Clayton # Get block variables from the current block only 34fe9d1ee9SGreg Clayton block_vars = block.GetVariables(frame, True, True, True, 0) 35fe9d1ee9SGreg Clayton # Iterate through all variables in the current block 36fe9d1ee9SGreg Clayton for block_var in block_vars: 37fe9d1ee9SGreg Clayton # Since we can have multiple shadowed variables, we our variable 38fe9d1ee9SGreg Clayton # name dictionary to have an array or "block + variable" pairs so 39fe9d1ee9SGreg Clayton # We can correctly print out all shadowed variables and whow which 40fe9d1ee9SGreg Clayton # blocks they come from 41296f166aSGreg Clayton block_var_name = block_var.GetName() 42296f166aSGreg Clayton if block_var_name in shadow_dict: 43296f166aSGreg Clayton shadow_dict[block_var_name].append(block_var) 44fe9d1ee9SGreg Clayton else: 45296f166aSGreg Clayton shadow_dict[block_var_name] = [block_var] 46fe9d1ee9SGreg Clayton # Get the parent block and continue 47fe9d1ee9SGreg Clayton block = block.GetParent() 48fe9d1ee9SGreg Clayton 49296f166aSGreg Clayton num_shadowed_variables = 0 50296f166aSGreg Clayton if shadow_dict: 51296f166aSGreg Clayton for name in shadow_dict.keys(): 52296f166aSGreg Clayton shadow_vars = shadow_dict[name] 53296f166aSGreg Clayton if len(shadow_vars) > 1: 54525cd59fSSerge Guelton print('"%s" is shadowed by the following declarations:' % (name)) 55296f166aSGreg Clayton num_shadowed_variables += 1 56296f166aSGreg Clayton for shadow_var in shadow_vars: 57525cd59fSSerge Guelton print(str(shadow_var.GetDeclaration()), file=result) 58296f166aSGreg Clayton if num_shadowed_variables == 0: 59525cd59fSSerge Guelton print('no variables are shadowed', file=result) 60