1515bc8c1Sserge-sans-paille#!/usr/bin/env python 2fe9d1ee9SGreg Clayton 3fe9d1ee9SGreg Claytonimport lldb 4fe9d1ee9SGreg Claytonimport shlex 5fe9d1ee9SGreg Clayton 6b9c1b51eSKate Stone 7fe9d1ee9SGreg Clayton@lldb.command("shadow") 8296f166aSGreg Claytondef check_shadow_command(debugger, command, exe_ctx, result, dict): 9*2238dcc3SJonas Devlieghere """Check the currently selected stack frame for shadowed variables""" 10296f166aSGreg Clayton process = exe_ctx.GetProcess() 11296f166aSGreg Clayton state = process.GetState() 12296f166aSGreg Clayton if state != lldb.eStateStopped: 13*2238dcc3SJonas Devlieghere print( 14*2238dcc3SJonas Devlieghere "process must be stopped, state is %s" 15*2238dcc3SJonas Devlieghere % lldb.SBDebugger.StateAsCString(state), 16*2238dcc3SJonas Devlieghere file=result, 17*2238dcc3SJonas Devlieghere ) 18fe9d1ee9SGreg Clayton return 19296f166aSGreg Clayton frame = exe_ctx.GetFrame() 20fe9d1ee9SGreg Clayton if not frame: 21525cd59fSSerge Guelton print("invalid frame", file=result) 22fe9d1ee9SGreg Clayton return 23fe9d1ee9SGreg Clayton # Parse command line args 24fe9d1ee9SGreg Clayton command_args = shlex.split(command) 25fe9d1ee9SGreg Clayton # TODO: add support for using arguments that are passed to this command... 26fe9d1ee9SGreg Clayton 27fe9d1ee9SGreg Clayton # Make a dictionary of variable name to "SBBlock and SBValue" 28296f166aSGreg Clayton shadow_dict = {} 29fe9d1ee9SGreg Clayton 30296f166aSGreg Clayton num_shadowed_variables = 0 31fe9d1ee9SGreg Clayton # Get the deepest most block from the current frame 32fe9d1ee9SGreg Clayton block = frame.GetBlock() 33fe9d1ee9SGreg Clayton # Iterate through the block and all of its parents 34fe9d1ee9SGreg Clayton while block.IsValid(): 35fe9d1ee9SGreg Clayton # Get block variables from the current block only 36fe9d1ee9SGreg Clayton block_vars = block.GetVariables(frame, True, True, True, 0) 37fe9d1ee9SGreg Clayton # Iterate through all variables in the current block 38fe9d1ee9SGreg Clayton for block_var in block_vars: 39fe9d1ee9SGreg Clayton # Since we can have multiple shadowed variables, we our variable 40fe9d1ee9SGreg Clayton # name dictionary to have an array or "block + variable" pairs so 41fe9d1ee9SGreg Clayton # We can correctly print out all shadowed variables and whow which 42fe9d1ee9SGreg Clayton # blocks they come from 43296f166aSGreg Clayton block_var_name = block_var.GetName() 44296f166aSGreg Clayton if block_var_name in shadow_dict: 45296f166aSGreg Clayton shadow_dict[block_var_name].append(block_var) 46fe9d1ee9SGreg Clayton else: 47296f166aSGreg Clayton shadow_dict[block_var_name] = [block_var] 48fe9d1ee9SGreg Clayton # Get the parent block and continue 49fe9d1ee9SGreg Clayton block = block.GetParent() 50fe9d1ee9SGreg Clayton 51296f166aSGreg Clayton num_shadowed_variables = 0 52296f166aSGreg Clayton if shadow_dict: 53296f166aSGreg Clayton for name in shadow_dict.keys(): 54296f166aSGreg Clayton shadow_vars = shadow_dict[name] 55296f166aSGreg Clayton if len(shadow_vars) > 1: 56525cd59fSSerge Guelton print('"%s" is shadowed by the following declarations:' % (name)) 57296f166aSGreg Clayton num_shadowed_variables += 1 58296f166aSGreg Clayton for shadow_var in shadow_vars: 59525cd59fSSerge Guelton print(str(shadow_var.GetDeclaration()), file=result) 60296f166aSGreg Clayton if num_shadowed_variables == 0: 61*2238dcc3SJonas Devlieghere print("no variables are shadowed", file=result) 62