diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-11-09 22:59:01 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-11-09 22:59:01 +0000 |
commit | e9d417d9fcefc50dfb75388cdc641cf8894cdd71 (patch) | |
tree | deb114d98b3a4cbfad70c36b3ecd45ce71769192 /utils | |
parent | 762d15d5dccf818bd88c80e957390e31e41b9277 (diff) |
Add lldb data formatters for clang classes, starting with SourceLocation.
When installed, 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)
This depends on r167629.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167640 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/ClangDataFormat.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/utils/ClangDataFormat.py b/utils/ClangDataFormat.py new file mode 100644 index 0000000000..6e8f5aa186 --- /dev/null +++ b/utils/ClangDataFormat.py @@ -0,0 +1,116 @@ +"""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) +""" + +import lldb + +def __lldb_init_module(debugger, internal_dict): + debugger.HandleCommand("type summary add -F ClangDataFormat.SourceLocation_summary clang::SourceLocation") + +def SourceLocation_summary(srcloc, internal_dict): + return SourceLocation(srcloc).summary() + +class SourceLocation(object): + def __init__(self, srcloc): + self.srcloc = srcloc + + def offset(self): + return getValueFromExpression(self.srcloc, ".getOffset()").GetValueAsUnsigned() + + def isMacro(self): + return getValueFromExpression(self.srcloc, ".isMacroID()").GetValueAsUnsigned() + + def getPrint(self, srcmgr_path): + print_str = getValueFromExpression(self.srcloc, ".printToString(%s)" % srcmgr_path) + return print_str.GetSummary() + + def summary(self): + desc = "(offset: %d, %s)" % (self.offset(), "macro" if self.isMacro() else "file") + srcmgr_path = findObjectExpressionPath("clang::SourceManager", lldb.frame) + if srcmgr_path: + desc = self.getPrint(srcmgr_path) + " " + desc + 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 findSourceManager(frame): + return findObject("clang::SourceManager", SourceManager_Paths, frame) + +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 lldb.frame.EvaluateExpression(getExpressionPath(val) + expr) + +def getExpressionPath(val): + stream = lldb.SBStream() + val.GetExpressionPath(stream) + return stream.GetData() |