On Mon, Aug 26, 2019 at 7:53 PM Richard Smith <rich...@metafoo.co.uk> wrote:
>
> Hi Aaron,
>
> I tried using this script to update a json dump test, and it seems to not 
> really work very well:
>
> 1) it's really inconvenient to invoke; you need to pass in a --clang, copy 
> some options out from two different places in the test file (from the RUN 
> line and from a "--filters" line), and guess how to form the proper command 
> line for the tool
> 2) it generates a file with the wrong name (adding a -json before the 
> extension)
> 3) it doesn't strip out the CHECK lines from the previous run of the tool
> 4) it adds in a bunch of trailing whitespace, causing the file to not match 
> the one in the repository
>
> Have you had a chance to look at making this more usable? I think the 
> approach taken by utils/make-ast-dump-check.sh helps a lot: run the test in 
> its normal configuration to generate the output, and then replace FileCheck 
> with a tool that updates the CHECK lines instead of checking them. (That 
> saves you needing to pass in --clang and --opts, at least, and makes it 
> really easy to update a whole bunch of tests at once by running them all with 
> lit.)

Unfortunately, I've not had the chance to look into improving the
script and the original author of the script has since moved on to
other opportunities as well. I'll see if I can spend some time
improving it, but shell scripting is not my strong suit (I'm
predominately on Windows, so the Python script approach is a bit
easier for me to grok). Does this have to use a shell script, or is
Python still fine?

~Aaron

>
> On Wed, 19 Jun 2019 at 08:21, Aaron Ballman via cfe-commits 
> <cfe-commits@lists.llvm.org> wrote:
>>
>> Author: aaronballman
>> Date: Wed Jun 19 08:25:24 2019
>> New Revision: 363820
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=363820&view=rev
>> Log:
>> Add a script to help generate expected test output for dumping the AST to 
>> JSON.
>>
>> Patch by Abhishek Bhaskar.
>>
>> Added:
>>     cfe/trunk/test/AST/gen_ast_dump_json_test.py
>>
>> Added: cfe/trunk/test/AST/gen_ast_dump_json_test.py
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/AST/gen_ast_dump_json_test.py?rev=363820&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/AST/gen_ast_dump_json_test.py (added)
>> +++ cfe/trunk/test/AST/gen_ast_dump_json_test.py Wed Jun 19 08:25:24 2019
>> @@ -0,0 +1,137 @@
>> +#!/usr/bin/env python
>> +
>> +from collections import OrderedDict
>> +from sets import Set
>> +from shutil import copyfile
>> +import argparse
>> +import json
>> +import os
>> +import pprint
>> +import re
>> +import subprocess
>> +
>> +def normalize(dict_var):
>> +    for k, v in dict_var.items():
>> +        if isinstance(v, OrderedDict):
>> +            normalize(v)
>> +        elif isinstance(v, list):
>> +            for e in v:
>> +                if isinstance(e, OrderedDict):
>> +                    normalize(e)
>> +        elif type(v) is unicode:
>> +            st = v.encode('utf-8')
>> +            if re.match(r"0x[0-9A-Fa-f]+", v):
>> +                dict_var[k] = u'0x{{.*}}'
>> +            elif os.path.isfile(v):
>> +                dict_var[k] = u'{{.*}}'
>> +            else:
>> +                splits = (v.split(u' '))
>> +                out_splits = []
>> +                for split in splits:
>> +                    inner_splits = split.rsplit(u':',2)
>> +                    if os.path.isfile(inner_splits[0]):
>> +                        out_splits.append(
>> +                            u'{{.*}}:%s:%s'
>> +                            %(inner_splits[1],
>> +                              inner_splits[2]))
>> +                        continue
>> +                    out_splits.append(split)
>> +
>> +                dict_var[k] = ' '.join(out_splits)
>> +
>> +def filter_json(dict_var, filters, out):
>> +    for k, v in dict_var.items():
>> +        if type(v) is unicode:
>> +            st = v.encode('utf-8')
>> +            if st in filters:
>> +                out.append(dict_var)
>> +                break
>> +        elif isinstance(v, OrderedDict):
>> +            filter_json(v, filters, out)
>> +        elif isinstance(v, list):
>> +            for e in v:
>> +                if isinstance(e, OrderedDict):
>> +                    filter_json(e, filters, out)
>> +
>> +def main():
>> +    parser = argparse.ArgumentParser()
>> +    parser.add_argument("--clang", help="The clang binary (could be a 
>> relative or absolute path)",
>> +                        action="store", required=True)
>> +    parser.add_argument("--opts", help="other options",
>> +                        action="store", default='', type=str)
>> +    parser.add_argument("--source", help="the source file. Command used to 
>> generate the json will be of the format <clang> -cc1 -ast-dump=json <opts> 
>> <source>",
>> +                        action="store", required=True)
>> +    parser.add_argument("--filters", help="comma separated list of AST 
>> filters. Ex: --filters=TypedefDecl,BuiltinType",
>> +                        action="store", default='')
>> +
>> +    args = parser.parse_args()
>> +
>> +    if not args.source:
>> +        print("Specify the source file to give to clang.")
>> +        return -1
>> +
>> +    clang_binary = os.path.abspath(args.clang)
>> +    if not os.path.isfile(clang_binary):
>> +        print("clang binary specified not present.")
>> +        return -1
>> +
>> +    options = args.opts.split(' ')
>> +    filters = Set(args.filters.split(',')) if args.filters else Set([])
>> +
>> +    cmd = [clang_binary, "-cc1"]
>> +    cmd.extend(options)
>> +
>> +    using_ast_dump_filter = 'ast-dump-filter' in args.opts
>> +
>> +    cmd.extend(["-ast-dump=json", args.source])
>> +
>> +    try:
>> +        json_str = subprocess.check_output(cmd)
>> +    except Exception as ex:
>> +        print("The clang command failed with %s" % ex)
>> +        return -1
>> +
>> +    out_asts = []
>> +    if using_ast_dump_filter:
>> +        splits = re.split('Dumping .*:\n', json_str)
>> +        if len(splits) > 1:
>> +            for split in splits[1:]:
>> +                j = json.loads(split.decode('utf-8'), 
>> object_pairs_hook=OrderedDict)
>> +                normalize(j)
>> +                out_asts.append(j)
>> +    else:
>> +        j = json.loads(json_str.decode('utf-8'), 
>> object_pairs_hook=OrderedDict)
>> +        normalize(j)
>> +
>> +        if len(filters) == 0:
>> +            out_asts.append(j)
>> +        else:
>> +            #assert using_ast_dump_filter is False,\
>> +            #    "Does not support using compiler's ast-dump-filter "\
>> +            #    "and the tool's filter option at the same time yet."
>> +
>> +            filter_json(j, filters, out_asts)
>> +
>> +    partition = args.source.rpartition('.')
>> +    dest_path = '%s-json%s%s' % (partition[0], partition[1], partition[2])
>> +
>> +    print("Writing json appended source file to %s." %(dest_path))
>> +    copyfile(args.source, dest_path)
>> +    with open(dest_path, "a") as f:
>> +        for out_ast in out_asts:
>> +            append_str = json.dumps(out_ast, indent=1, ensure_ascii=False)
>> +            out_str = '\n\n'
>> +            index = 0
>> +            for append_line in append_str.splitlines()[2:]:
>> +                if index == 0:
>> +                    out_str += '// CHECK: %s\n' %(append_line)
>> +                    index += 1
>> +                else:
>> +                    out_str += '// CHECK-NEXT: %s\n' %(append_line)
>> +
>> +            f.write(out_str)
>> +
>> +    return 0
>> +
>> +if __name__ == '__main__':
>> +    main()
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to