1f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer"""
2dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesLLDB Formatters for LLVM data types.
3dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesLoad into LLDB with 'command script import /path/to/lldbDataFormatters.py'
5f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer"""
6f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
7dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesdef __lldb_init_module(debugger, internal_dict):
8dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    debugger.HandleCommand('type category define -e llvm -l c++')
9dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    debugger.HandleCommand('type synthetic add -w llvm '
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           '-l lldbDataFormatters.SmallVectorSynthProvider '
11dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           '-x "^llvm::SmallVectorImpl<.+>$"')
12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    debugger.HandleCommand('type synthetic add -w llvm '
13dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           '-l lldbDataFormatters.SmallVectorSynthProvider '
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           '-x "^llvm::SmallVector<.+,.+>$"')
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    debugger.HandleCommand('type synthetic add -w llvm '
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           '-l lldbDataFormatters.ArrayRefSynthProvider '
1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                           '-x "^llvm::ArrayRef<.+>$"')
18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    debugger.HandleCommand('type summary add -w llvm '
19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           '-F lldbDataFormatters.OptionalSummaryProvider '
20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                           '-x "^llvm::Optional<.+>$"')
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
22f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer# Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl
23f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramerclass SmallVectorSynthProvider:
24f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer    def __init__(self, valobj, dict):
25f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        self.valobj = valobj;
26f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        self.update() # initialize this provider
27f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
28f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer    def num_children(self):
29f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        begin = self.begin.GetValueAsUnsigned(0)
30f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        end = self.end.GetValueAsUnsigned(0)
31f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        return (end - begin)/self.type_size
32f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
33f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer    def get_child_index(self, name):
34f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        try:
35f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer            return int(name.lstrip('[').rstrip(']'))
36f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        except:
37f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer            return -1;
38f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
39f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer    def get_child_at_index(self, index):
40f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        # Do bounds checking.
41f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        if index < 0:
42f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer            return None
43f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        if index >= self.num_children():
44f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer            return None;
45f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
46f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        offset = index * self.type_size
47f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        return self.begin.CreateChildAtOffset('['+str(index)+']',
48f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer                                              offset, self.data_type)
49f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer
50f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer    def update(self):
51f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        self.begin = self.valobj.GetChildMemberWithName('BeginX')
52f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        self.end = self.valobj.GetChildMemberWithName('EndX')
5379949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        the_type = self.valobj.GetType()
5479949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        # If this is a reference type we have to dereference it to get to the
5579949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        # template parameter.
5679949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        if the_type.IsReferenceType():
5779949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer            the_type = the_type.GetDereferencedType()
5879949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer
5979949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        self.data_type = the_type.GetTemplateArgumentType(0)
60f61f22a5d1fffc6b83679f5b666f4afb787f6ae5Benjamin Kramer        self.type_size = self.data_type.GetByteSize()
6179949597b281f0fd757bc11178e39887d0ba9735Benjamin Kramer        assert self.type_size != 0
6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass ArrayRefSynthProvider:
6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    """ Provider for llvm::ArrayRef """
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def __init__(self, valobj, dict):
6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.valobj = valobj;
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.update() # initialize this provider
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def num_children(self):
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return self.length
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def get_child_index(self, name):
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        try:
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return int(name.lstrip('[').rstrip(']'))
7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        except:
7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return -1;
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def get_child_at_index(self, index):
7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if index < 0 or index >= self.num_children():
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return None;
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        offset = index * self.type_size
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return self.data.CreateChildAtOffset('[' + str(index) + ']',
8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             offset, self.data_type)
8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    def update(self):
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.data = self.valobj.GetChildMemberWithName('Data')
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        length_obj = self.valobj.GetChildMemberWithName('Length')
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.length = length_obj.GetValueAsUnsigned(0)
8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.data_type = self.data.GetType().GetPointeeType()
9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        self.type_size = self.data_type.GetByteSize()
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        assert self.type_size != 0
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesdef OptionalSummaryProvider(valobj, internal_dict):
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if not valobj.GetChildMemberWithName('hasVal').GetValueAsUnsigned(0):
95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return 'None'
96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    underlying_type = valobj.GetType().GetTemplateArgumentType(0)
97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    storage = valobj.GetChildMemberWithName('storage')
98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return str(storage.Cast(underlying_type))
99