diff options
| author | 2016-09-03 22:46:54 +0000 | |
|---|---|---|
| committer | 2016-09-03 22:46:54 +0000 | |
| commit | b5500b9ca0102f1ccaf32f0e77e96d0739aded9b (patch) | |
| tree | e1b7ebb5a0231f9e6d8d3f6f719582cebd64dc98 /gnu/llvm/tools/clang/utils/ClangDataFormat.py | |
| parent | clarify purpose of src/gnu/ directory. (diff) | |
| download | wireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.tar.xz wireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.zip | |
Use the space freed up by sparc and zaurus to import LLVM.
ok hackroom@
Diffstat (limited to 'gnu/llvm/tools/clang/utils/ClangDataFormat.py')
| -rw-r--r-- | gnu/llvm/tools/clang/utils/ClangDataFormat.py | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/gnu/llvm/tools/clang/utils/ClangDataFormat.py b/gnu/llvm/tools/clang/utils/ClangDataFormat.py new file mode 100644 index 00000000000..38ef76b3253 --- /dev/null +++ b/gnu/llvm/tools/clang/utils/ClangDataFormat.py @@ -0,0 +1,161 @@ +"""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") + debugger.HandleCommand("type summary add -F ClangDataFormat.StringRef_summary llvm::StringRef") + +def SourceLocation_summary(srcloc, internal_dict): + return SourceLocation(srcloc).summary() + +def QualType_summary(qualty, internal_dict): + return QualType(qualty).summary() + +def StringRef_summary(strref, internal_dict): + return StringRef(strref).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 + +class StringRef(object): + def __init__(self, strref): + self.strref = strref + self.Data_value = strref.GetChildAtIndex(0) + self.Length = strref.GetChildAtIndex(1).GetValueAsUnsigned() + + def summary(self): + if self.Length == 0: + return '""' + data = self.Data_value.GetPointeeData(0, self.Length) + error = lldb.SBError() + string = data.ReadRawData(error, 0, data.GetByteSize()) + if error.Fail(): + return None + return '"%s"' % string + + +# 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() |
