Mercurial > hg > CbC > CbC_llvm
view clang/utils/ClangDataFormat.py @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
"""lldb data formatters for clang classes. Usage -- import this file in your ~/.lldbinit by adding this line: command script import /path/to/ClangDataFormat.py After that, instead of getting this: (lldb) p Tok.Loc (clang::SourceLocation) $0 = { (unsigned int) ID = 123582 } you'll get: (lldb) p Tok.Loc (clang::SourceLocation) $4 = "/usr/include/i386/_types.h:37:1" (offset: 123582, file, local) """ import lldb def __lldb_init_module(debugger, internal_dict): debugger.HandleCommand( "type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation" ) debugger.HandleCommand( "type summary add -F ClangDataFormat.QualType_summary clang::QualType" ) def SourceLocation_summary(srcloc, internal_dict): return SourceLocation(srcloc).summary() def QualType_summary(qualty, internal_dict): return QualType(qualty).summary() class SourceLocation(object): def __init__(self, srcloc): self.srcloc = srcloc self.ID = srcloc.GetChildAtIndex(0).GetValueAsUnsigned() self.frame = srcloc.GetFrame() def offset(self): return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned() def isInvalid(self): return self.ID == 0 def isMacro(self): return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned() def isLocal(self, srcmgr_path): return self.frame.EvaluateExpression( "(%s).isLocalSourceLocation(%s)" % (srcmgr_path, getExpressionPath(self.srcloc)) ).GetValueAsUnsigned() def getPrint(self, srcmgr_path): print_str = getValueFromExpression( self.srcloc, ".printToString(%s)" % srcmgr_path ) return print_str.GetSummary() def summary(self): if self.isInvalid(): return "<invalid loc>" srcmgr_path = findObjectExpressionPath("clang::SourceManager", self.frame) if srcmgr_path: 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", ) return "(offset: %d, %s)" % ( self.offset(), "macro" if self.isMacro() else "file", ) class QualType(object): def __init__(self, qualty): self.qualty = qualty def getAsString(self): std_str = getValueFromExpression(self.qualty, ".getAsString()") return std_str.GetSummary() def summary(self): desc = self.getAsString() if desc == '"NULL TYPE"': return "<NULL TYPE>" return desc # Key is a (function address, type name) tuple, value is the expression path for # an object with such a type name from inside that function. FramePathMapCache = {} def findObjectExpressionPath(typename, frame): func_addr = frame.GetFunction().GetStartAddress().GetFileAddress() key = (func_addr, typename) try: return FramePathMapCache[key] except KeyError: # print "CACHE MISS" path = None obj = findObject(typename, frame) if obj: path = getExpressionPath(obj) FramePathMapCache[key] = path return path def findObject(typename, frame): def getTypename(value): # FIXME: lldb should provide something like getBaseType ty = value.GetType() if ty.IsPointerType() or ty.IsReferenceType(): return ty.GetPointeeType().GetName() return ty.GetName() def searchForType(value, searched): tyname = getTypename(value) # print "SEARCH:", getExpressionPath(value), value.GetType().GetName() if tyname == typename: return value ty = value.GetType() if not ( ty.IsPointerType() or ty.IsReferenceType() or # FIXME: lldb should provide something like getCanonicalType tyname.startswith("llvm::IntrusiveRefCntPtr<") or tyname.startswith("llvm::OwningPtr<") ): return None # FIXME: Hashing for SBTypes does not seem to work correctly, uses the typename instead, # and not the canonical one unfortunately. if tyname in searched: return None searched.add(tyname) for i in range(value.GetNumChildren()): child = value.GetChildAtIndex(i, 0, False) found = searchForType(child, searched) if found: return found searched = set() value_list = frame.GetVariables(True, True, True, True) for val in value_list: found = searchForType(val, searched) if found: return found if not found.TypeIsPointerType() else found.Dereference() def getValueFromExpression(val, expr): return val.GetFrame().EvaluateExpression(getExpressionPath(val) + expr) def getExpressionPath(val): stream = lldb.SBStream() val.GetExpressionPath(stream) return stream.GetData()