1e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis"""lldb data formatters for clang classes. 2e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 3e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios KyrtzidisUsage 4e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis-- 5e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisimport this file in your ~/.lldbinit by adding this line: 6e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 7e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidiscommand script import /path/to/ClangDataFormat.py 8e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 9e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios KyrtzidisAfter that, instead of getting this: 10e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 11e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis(lldb) p Tok.Loc 12e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis(clang::SourceLocation) $0 = { 13e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis (unsigned int) ID = 123582 14e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis} 15e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 16e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisyou'll get: 17e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 18e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis(lldb) p Tok.Loc 1929a67e8f3adbd433acf271f7be699c50ceb7bdefArgyrios Kyrtzidis(clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local) 20e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis""" 21e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 22e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisimport lldb 23e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 24e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef __lldb_init_module(debugger, internal_dict): 25e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation") 26fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis debugger.HandleCommand("type summary add -F ClangDataFormat.QualType_summary clang::QualType") 271a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis debugger.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef") 28e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 29e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef SourceLocation_summary(srcloc, internal_dict): 30e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return SourceLocation(srcloc).summary() 31e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 32fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidisdef QualType_summary(qualty, internal_dict): 33fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis return QualType(qualty).summary() 34fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis 351a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidisdef StringRef_summary(strref, internal_dict): 361a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis return StringRef(strref).summary() 371a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis 38e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisclass SourceLocation(object): 39e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def __init__(self, srcloc): 40e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis self.srcloc = srcloc 41596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned() 4234983d5f8fbdced8f38d61a933ce32aff3e0886cArgyrios Kyrtzidis self.frame = srcloc.GetFrame() 43e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 44e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def offset(self): 45e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned() 46e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 47596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis def isInvalid(self): 48596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis return self.ID == 0 49596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis 50e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def isMacro(self): 51e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned() 52e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 5329a67e8f3adbd433acf271f7be699c50ceb7bdefArgyrios Kyrtzidis def isLocal(self, srcmgr_path): 5434983d5f8fbdced8f38d61a933ce32aff3e0886cArgyrios Kyrtzidis return self.frame.EvaluateExpression("(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc))).GetValueAsUnsigned() 5529a67e8f3adbd433acf271f7be699c50ceb7bdefArgyrios Kyrtzidis 56e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def getPrint(self, srcmgr_path): 57e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path) 58e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return print_str.GetSummary() 59e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 60e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def summary(self): 61596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis if self.isInvalid(): 62596be9372b79842b74c0654ab3dab33200812e8aArgyrios Kyrtzidis return "<invalid loc>" 6334983d5f8fbdced8f38d61a933ce32aff3e0886cArgyrios Kyrtzidis srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame) 64e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if srcmgr_path: 65fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis return "%s (offset: %d, %s, %s)" % (self.getPrint(srcmgr_path), self.offset(), "macro" if self.isMacro() else "file", "local" if self.isLocal(srcmgr_path) else "loaded") 66fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis return "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file") 67fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis 68fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidisclass QualType(object): 69fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis def __init__(self, qualty): 70fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis self.qualty = qualty 71fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis 72fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis def getAsString(self): 73fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis std_str = getValueFromExpression(self.qualty, ".getAsString()") 74fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis return std_str.GetSummary() 75fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis 76fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis def summary(self): 77fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis desc = self.getAsString() 78fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis if desc == '"NULL TYPE"': 79fc0eb2a77b3b48f4f7f9338b158fa913cda0f774Argyrios Kyrtzidis return "<NULL TYPE>" 80e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return desc 81e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 821a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidisclass StringRef(object): 831a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis def __init__(self, strref): 841a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis self.strref = strref 851a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis self.Data_value = strref.GetChildAtIndex(0) 861a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned() 871a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis 881a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis def summary(self): 891a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis if self.Length == 0: 901a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis return '""' 911a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis data = self.Data_value.GetPointeeData(0, self.Length) 921a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis error = lldb.SBError() 931a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis string = data.ReadRawData(error, 0, data.GetByteSize()) 941a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis if error.Fail(): 951a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis return None 961a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis return '"%s"' % string 971a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis 981a03b262d0f07d4a3091b0a9b7310100d9bd0aa9Argyrios Kyrtzidis 99e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis# Key is a (function address, type name) tuple, value is the expression path for 100e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis# an object with such a type name from inside that function. 101e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios KyrtzidisFramePathMapCache = {} 102e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 103e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef findObjectExpressionPath(typename, frame): 104e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis func_addr = frame.GetFunction().GetStartAddress().GetFileAddress() 105e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis key = (func_addr, typename) 106e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis try: 107e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return FramePathMapCache[key] 108e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis except KeyError: 109e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis #print "CACHE MISS" 110e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis path = None 111e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis obj = findObject(typename, frame) 112e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if obj: 113e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis path = getExpressionPath(obj) 114e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis FramePathMapCache[key] = path 115e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return path 116e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 117e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef findObject(typename, frame): 118e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def getTypename(value): 119e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis # FIXME: lldb should provide something like getBaseType 120e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis ty = value.GetType() 121e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if ty.IsPointerType() or ty.IsReferenceType(): 122e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return ty.GetPointeeType().GetName() 123e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return ty.GetName() 124e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 125e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis def searchForType(value, searched): 126e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis tyname = getTypename(value) 127e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis #print "SEARCH:", getExpressionPath(value), value.GetType().GetName() 128e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if tyname == typename: 129e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return value 130e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis ty = value.GetType() 131e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if not (ty.IsPointerType() or 132e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis ty.IsReferenceType() or 133e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis # FIXME: lldb should provide something like getCanonicalType 134e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis tyname.startswith("llvm::IntrusiveRefCntPtr<") or 135e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis tyname.startswith("llvm::OwningPtr<")): 136e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return None 137e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead, 138e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis # and not the canonical one unfortunately. 139e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if tyname in searched: 140e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return None 141e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis searched.add(tyname) 142e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis for i in range(value.GetNumChildren()): 143e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis child = value.GetChildAtIndex(i, 0, False) 144e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis found = searchForType(child, searched) 145e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if found: 146e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return found 147e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 148e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis searched = set() 149e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis value_list = frame.GetVariables(True, True, True, True) 150e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis for val in value_list: 151e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis found = searchForType(val, searched) 152e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis if found: 153e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return found if not found.TypeIsPointerType() else found.Dereference() 154e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 155e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef getValueFromExpression(val, expr): 15634983d5f8fbdced8f38d61a933ce32aff3e0886cArgyrios Kyrtzidis return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr) 157e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis 158e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidisdef getExpressionPath(val): 159e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis stream = lldb.SBStream() 160e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis val.GetExpressionPath(stream) 161e9d417d9fcefc50dfb75388cdc641cf8894cdd71Argyrios Kyrtzidis return stream.GetData() 162