xref: /openbsd-src/gnu/llvm/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py (revision a9ac8606c53d55cee9c3a39778b249c51df111ef)
1*a9ac8606Spatrick#!/usr/bin/env python3
2*a9ac8606Spatrick# -*- coding: utf-8 -*-
3*a9ac8606Spatrick
4*a9ac8606Spatrickimport os
5*a9ac8606Spatrickimport sys
6*a9ac8606Spatrickimport json
7*a9ac8606Spatrickimport filecmp
8*a9ac8606Spatrickimport shutil
9*a9ac8606Spatrickimport argparse
10*a9ac8606Spatrick
11*a9ac8606Spatrickclass Generator(object):
12*a9ac8606Spatrick
13*a9ac8606Spatrick    implementationContent = ''
14*a9ac8606Spatrick
15*a9ac8606Spatrick    RefClades = {"DeclarationNameInfo",
16*a9ac8606Spatrick        "NestedNameSpecifierLoc",
17*a9ac8606Spatrick        "TemplateArgumentLoc",
18*a9ac8606Spatrick        "TypeLoc"}
19*a9ac8606Spatrick
20*a9ac8606Spatrick    def __init__(self, templateClasses):
21*a9ac8606Spatrick        self.templateClasses = templateClasses
22*a9ac8606Spatrick
23*a9ac8606Spatrick    def GeneratePrologue(self):
24*a9ac8606Spatrick
25*a9ac8606Spatrick        self.implementationContent += \
26*a9ac8606Spatrick            """
27*a9ac8606Spatrick/*===- Generated file -------------------------------------------*- C++ -*-===*\
28*a9ac8606Spatrick|*                                                                            *|
29*a9ac8606Spatrick|* Introspection of available AST node SourceLocations                        *|
30*a9ac8606Spatrick|*                                                                            *|
31*a9ac8606Spatrick|* Automatically generated file, do not edit!                                 *|
32*a9ac8606Spatrick|*                                                                            *|
33*a9ac8606Spatrick\*===----------------------------------------------------------------------===*/
34*a9ac8606Spatrick
35*a9ac8606Spatricknamespace clang {
36*a9ac8606Spatricknamespace tooling {
37*a9ac8606Spatrick
38*a9ac8606Spatrickusing LocationAndString = SourceLocationMap::value_type;
39*a9ac8606Spatrickusing RangeAndString = SourceRangeMap::value_type;
40*a9ac8606Spatrick
41*a9ac8606Spatrickbool NodeIntrospection::hasIntrospectionSupport() { return true; }
42*a9ac8606Spatrick
43*a9ac8606Spatrickstruct RecursionPopper
44*a9ac8606Spatrick{
45*a9ac8606Spatrick    RecursionPopper(std::vector<clang::TypeLoc> &TypeLocRecursionGuard)
46*a9ac8606Spatrick    :  TLRG(TypeLocRecursionGuard)
47*a9ac8606Spatrick    {
48*a9ac8606Spatrick
49*a9ac8606Spatrick    }
50*a9ac8606Spatrick
51*a9ac8606Spatrick    ~RecursionPopper()
52*a9ac8606Spatrick    {
53*a9ac8606Spatrick    TLRG.pop_back();
54*a9ac8606Spatrick    }
55*a9ac8606Spatrick
56*a9ac8606Spatrickprivate:
57*a9ac8606Spatrickstd::vector<clang::TypeLoc> &TLRG;
58*a9ac8606Spatrick};
59*a9ac8606Spatrick"""
60*a9ac8606Spatrick
61*a9ac8606Spatrick    def GenerateBaseGetLocationsDeclaration(self, CladeName):
62*a9ac8606Spatrick        InstanceDecoration = "*"
63*a9ac8606Spatrick        if CladeName in self.RefClades:
64*a9ac8606Spatrick            InstanceDecoration = "&"
65*a9ac8606Spatrick
66*a9ac8606Spatrick        self.implementationContent += \
67*a9ac8606Spatrick            """
68*a9ac8606Spatrickvoid GetLocationsImpl(SharedLocationCall const& Prefix,
69*a9ac8606Spatrick    clang::{0} const {1}Object, SourceLocationMap &Locs,
70*a9ac8606Spatrick    SourceRangeMap &Rngs,
71*a9ac8606Spatrick    std::vector<clang::TypeLoc> &TypeLocRecursionGuard);
72*a9ac8606Spatrick""".format(CladeName, InstanceDecoration)
73*a9ac8606Spatrick
74*a9ac8606Spatrick    def GenerateSrcLocMethod(self,
75*a9ac8606Spatrick            ClassName, ClassData, CreateLocalRecursionGuard):
76*a9ac8606Spatrick
77*a9ac8606Spatrick        NormalClassName = ClassName
78*a9ac8606Spatrick        RecursionGuardParam = ('' if CreateLocalRecursionGuard else \
79*a9ac8606Spatrick            ', std::vector<clang::TypeLoc>& TypeLocRecursionGuard')
80*a9ac8606Spatrick
81*a9ac8606Spatrick        if "templateParms" in ClassData:
82*a9ac8606Spatrick            TemplatePreamble = "template <typename "
83*a9ac8606Spatrick            ClassName += "<"
84*a9ac8606Spatrick            First = True
85*a9ac8606Spatrick            for TA in ClassData["templateParms"]:
86*a9ac8606Spatrick                if not First:
87*a9ac8606Spatrick                    ClassName += ", "
88*a9ac8606Spatrick                    TemplatePreamble += ", typename "
89*a9ac8606Spatrick
90*a9ac8606Spatrick                First = False
91*a9ac8606Spatrick                ClassName += TA
92*a9ac8606Spatrick                TemplatePreamble += TA
93*a9ac8606Spatrick
94*a9ac8606Spatrick            ClassName += ">"
95*a9ac8606Spatrick            TemplatePreamble += ">\n";
96*a9ac8606Spatrick            self.implementationContent += TemplatePreamble
97*a9ac8606Spatrick
98*a9ac8606Spatrick        self.implementationContent += \
99*a9ac8606Spatrick            """
100*a9ac8606Spatrickstatic void GetLocations{0}(SharedLocationCall const& Prefix,
101*a9ac8606Spatrick    clang::{1} const &Object,
102*a9ac8606Spatrick    SourceLocationMap &Locs, SourceRangeMap &Rngs {2})
103*a9ac8606Spatrick{{
104*a9ac8606Spatrick""".format(NormalClassName, ClassName, RecursionGuardParam)
105*a9ac8606Spatrick
106*a9ac8606Spatrick        if 'sourceLocations' in ClassData:
107*a9ac8606Spatrick            for locName in ClassData['sourceLocations']:
108*a9ac8606Spatrick                self.implementationContent += \
109*a9ac8606Spatrick                    """
110*a9ac8606Spatrick  Locs.insert(LocationAndString(Object.{0}(),
111*a9ac8606Spatrick    llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}")));
112*a9ac8606Spatrick""".format(locName)
113*a9ac8606Spatrick
114*a9ac8606Spatrick            self.implementationContent += '\n'
115*a9ac8606Spatrick
116*a9ac8606Spatrick        if 'sourceRanges' in ClassData:
117*a9ac8606Spatrick            for rngName in ClassData['sourceRanges']:
118*a9ac8606Spatrick                self.implementationContent += \
119*a9ac8606Spatrick                    """
120*a9ac8606Spatrick  Rngs.insert(RangeAndString(Object.{0}(),
121*a9ac8606Spatrick    llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}")));
122*a9ac8606Spatrick""".format(rngName)
123*a9ac8606Spatrick
124*a9ac8606Spatrick            self.implementationContent += '\n'
125*a9ac8606Spatrick
126*a9ac8606Spatrick        if 'typeLocs' in ClassData or 'typeSourceInfos' in ClassData \
127*a9ac8606Spatrick                or 'nestedNameLocs' in ClassData \
128*a9ac8606Spatrick                or 'declNameInfos' in ClassData:
129*a9ac8606Spatrick            if CreateLocalRecursionGuard:
130*a9ac8606Spatrick                self.implementationContent += \
131*a9ac8606Spatrick                    'std::vector<clang::TypeLoc> TypeLocRecursionGuard;\n'
132*a9ac8606Spatrick
133*a9ac8606Spatrick            self.implementationContent += '\n'
134*a9ac8606Spatrick
135*a9ac8606Spatrick            if 'typeLocs' in ClassData:
136*a9ac8606Spatrick                for typeLoc in ClassData['typeLocs']:
137*a9ac8606Spatrick
138*a9ac8606Spatrick                    self.implementationContent += \
139*a9ac8606Spatrick                        """
140*a9ac8606Spatrick              if (Object.{0}()) {{
141*a9ac8606Spatrick                GetLocationsImpl(
142*a9ac8606Spatrick                    llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"),
143*a9ac8606Spatrick                    Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
144*a9ac8606Spatrick                }}
145*a9ac8606Spatrick              """.format(typeLoc)
146*a9ac8606Spatrick
147*a9ac8606Spatrick            self.implementationContent += '\n'
148*a9ac8606Spatrick            if 'typeSourceInfos' in ClassData:
149*a9ac8606Spatrick                for tsi in ClassData['typeSourceInfos']:
150*a9ac8606Spatrick                    self.implementationContent += \
151*a9ac8606Spatrick                        """
152*a9ac8606Spatrick              if (Object.{0}()) {{
153*a9ac8606Spatrick                GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>(
154*a9ac8606Spatrick                    llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}",
155*a9ac8606Spatrick                        LocationCall::ReturnsPointer), "getTypeLoc"),
156*a9ac8606Spatrick                    Object.{0}()->getTypeLoc(), Locs, Rngs, TypeLocRecursionGuard);
157*a9ac8606Spatrick                    }}
158*a9ac8606Spatrick              """.format(tsi)
159*a9ac8606Spatrick
160*a9ac8606Spatrick                self.implementationContent += '\n'
161*a9ac8606Spatrick
162*a9ac8606Spatrick            if 'nestedNameLocs' in ClassData:
163*a9ac8606Spatrick                for NN in ClassData['nestedNameLocs']:
164*a9ac8606Spatrick                    self.implementationContent += \
165*a9ac8606Spatrick                        """
166*a9ac8606Spatrick              if (Object.{0}())
167*a9ac8606Spatrick                GetLocationsImpl(
168*a9ac8606Spatrick                    llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"),
169*a9ac8606Spatrick                    Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
170*a9ac8606Spatrick              """.format(NN)
171*a9ac8606Spatrick
172*a9ac8606Spatrick            if 'declNameInfos' in ClassData:
173*a9ac8606Spatrick                for declName in ClassData['declNameInfos']:
174*a9ac8606Spatrick
175*a9ac8606Spatrick                    self.implementationContent += \
176*a9ac8606Spatrick                        """
177*a9ac8606Spatrick                      GetLocationsImpl(
178*a9ac8606Spatrick                          llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"),
179*a9ac8606Spatrick                          Object.{0}(), Locs, Rngs, TypeLocRecursionGuard);
180*a9ac8606Spatrick                      """.format(declName)
181*a9ac8606Spatrick
182*a9ac8606Spatrick        self.implementationContent += '}\n'
183*a9ac8606Spatrick
184*a9ac8606Spatrick    def GenerateFiles(self, OutputFile):
185*a9ac8606Spatrick        with open(os.path.join(os.getcwd(),
186*a9ac8606Spatrick                  OutputFile), 'w') as f:
187*a9ac8606Spatrick            f.write(self.implementationContent)
188*a9ac8606Spatrick
189*a9ac8606Spatrick    def GenerateBaseGetLocationsFunction(self, ASTClassNames,
190*a9ac8606Spatrick            ClassEntries, CladeName, InheritanceMap,
191*a9ac8606Spatrick            CreateLocalRecursionGuard):
192*a9ac8606Spatrick
193*a9ac8606Spatrick        MethodReturnType = 'NodeLocationAccessors'
194*a9ac8606Spatrick        InstanceDecoration = "*"
195*a9ac8606Spatrick        if CladeName in self.RefClades:
196*a9ac8606Spatrick            InstanceDecoration = "&"
197*a9ac8606Spatrick
198*a9ac8606Spatrick        Signature = \
199*a9ac8606Spatrick            'GetLocations(clang::{0} const {1}Object)'.format(
200*a9ac8606Spatrick                CladeName, InstanceDecoration)
201*a9ac8606Spatrick        ImplSignature = \
202*a9ac8606Spatrick            """
203*a9ac8606Spatrick    GetLocationsImpl(SharedLocationCall const& Prefix,
204*a9ac8606Spatrick        clang::{0} const {1}Object, SourceLocationMap &Locs,
205*a9ac8606Spatrick        SourceRangeMap &Rngs,
206*a9ac8606Spatrick        std::vector<clang::TypeLoc> &TypeLocRecursionGuard)
207*a9ac8606Spatrick    """.format(CladeName, InstanceDecoration)
208*a9ac8606Spatrick
209*a9ac8606Spatrick        self.implementationContent += 'void {0} {{ '.format(ImplSignature)
210*a9ac8606Spatrick
211*a9ac8606Spatrick        if CladeName == "TypeLoc":
212*a9ac8606Spatrick            self.implementationContent += 'if (Object.isNull()) return;'
213*a9ac8606Spatrick
214*a9ac8606Spatrick            self.implementationContent += \
215*a9ac8606Spatrick                """
216*a9ac8606Spatrick            if (llvm::find(TypeLocRecursionGuard, Object) != TypeLocRecursionGuard.end())
217*a9ac8606Spatrick              return;
218*a9ac8606Spatrick            TypeLocRecursionGuard.push_back(Object);
219*a9ac8606Spatrick            RecursionPopper RAII(TypeLocRecursionGuard);
220*a9ac8606Spatrick                """
221*a9ac8606Spatrick
222*a9ac8606Spatrick        RecursionGuardParam = ''
223*a9ac8606Spatrick        if not CreateLocalRecursionGuard:
224*a9ac8606Spatrick            RecursionGuardParam = ', TypeLocRecursionGuard'
225*a9ac8606Spatrick
226*a9ac8606Spatrick        ArgPrefix = '*'
227*a9ac8606Spatrick        if CladeName in self.RefClades:
228*a9ac8606Spatrick            ArgPrefix = ''
229*a9ac8606Spatrick        self.implementationContent += \
230*a9ac8606Spatrick            'GetLocations{0}(Prefix, {1}Object, Locs, Rngs {2});'.format(
231*a9ac8606Spatrick                CladeName, ArgPrefix, RecursionGuardParam)
232*a9ac8606Spatrick
233*a9ac8606Spatrick        if CladeName == "TypeLoc":
234*a9ac8606Spatrick            self.implementationContent += \
235*a9ac8606Spatrick                '''
236*a9ac8606Spatrick        if (auto QTL = Object.getAs<clang::QualifiedTypeLoc>()) {
237*a9ac8606Spatrick            auto Dequalified = QTL.getNextTypeLoc();
238*a9ac8606Spatrick            return GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getNextTypeLoc"),
239*a9ac8606Spatrick                                Dequalified,
240*a9ac8606Spatrick                                Locs,
241*a9ac8606Spatrick                                Rngs,
242*a9ac8606Spatrick                                TypeLocRecursionGuard);
243*a9ac8606Spatrick        }'''
244*a9ac8606Spatrick
245*a9ac8606Spatrick        for ASTClassName in ASTClassNames:
246*a9ac8606Spatrick            if ASTClassName in self.templateClasses:
247*a9ac8606Spatrick                continue
248*a9ac8606Spatrick            if ASTClassName == CladeName:
249*a9ac8606Spatrick                continue
250*a9ac8606Spatrick            if CladeName != "TypeLoc":
251*a9ac8606Spatrick                self.implementationContent += \
252*a9ac8606Spatrick                """
253*a9ac8606Spatrickif (auto Derived = llvm::dyn_cast<clang::{0}>(Object)) {{
254*a9ac8606Spatrick  GetLocations{0}(Prefix, *Derived, Locs, Rngs {1});
255*a9ac8606Spatrick}}
256*a9ac8606Spatrick""".format(ASTClassName, RecursionGuardParam)
257*a9ac8606Spatrick                continue
258*a9ac8606Spatrick
259*a9ac8606Spatrick            self.GenerateBaseTypeLocVisit(ASTClassName, ClassEntries,
260*a9ac8606Spatrick                RecursionGuardParam, InheritanceMap)
261*a9ac8606Spatrick
262*a9ac8606Spatrick        self.implementationContent += '}'
263*a9ac8606Spatrick
264*a9ac8606Spatrick        self.implementationContent += \
265*a9ac8606Spatrick            """
266*a9ac8606Spatrick{0} NodeIntrospection::{1} {{
267*a9ac8606Spatrick  NodeLocationAccessors Result;
268*a9ac8606Spatrick  SharedLocationCall Prefix;
269*a9ac8606Spatrick  std::vector<clang::TypeLoc> TypeLocRecursionGuard;
270*a9ac8606Spatrick
271*a9ac8606Spatrick  GetLocationsImpl(Prefix, Object, Result.LocationAccessors,
272*a9ac8606Spatrick                   Result.RangeAccessors, TypeLocRecursionGuard);
273*a9ac8606Spatrick""".format(MethodReturnType, Signature)
274*a9ac8606Spatrick
275*a9ac8606Spatrick        self.implementationContent += 'return Result; }'
276*a9ac8606Spatrick
277*a9ac8606Spatrick    def GenerateBaseTypeLocVisit(self, ASTClassName, ClassEntries,
278*a9ac8606Spatrick            RecursionGuardParam, InheritanceMap):
279*a9ac8606Spatrick        CallPrefix = 'Prefix'
280*a9ac8606Spatrick        if ASTClassName != 'TypeLoc':
281*a9ac8606Spatrick            CallPrefix = \
282*a9ac8606Spatrick                '''llvm::makeIntrusiveRefCnt<LocationCall>(Prefix,
283*a9ac8606Spatrick                    "getAs<clang::{0}>", LocationCall::IsCast)
284*a9ac8606Spatrick                '''.format(ASTClassName)
285*a9ac8606Spatrick
286*a9ac8606Spatrick        if ASTClassName in ClassEntries:
287*a9ac8606Spatrick
288*a9ac8606Spatrick            self.implementationContent += \
289*a9ac8606Spatrick            """
290*a9ac8606Spatrick            if (auto ConcreteTL = Object.getAs<clang::{0}>())
291*a9ac8606Spatrick              GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3});
292*a9ac8606Spatrick            """.format(ASTClassName, ASTClassName,
293*a9ac8606Spatrick                       CallPrefix, RecursionGuardParam)
294*a9ac8606Spatrick
295*a9ac8606Spatrick        if ASTClassName in InheritanceMap:
296*a9ac8606Spatrick            for baseTemplate in self.templateClasses:
297*a9ac8606Spatrick                if baseTemplate in InheritanceMap[ASTClassName]:
298*a9ac8606Spatrick                    self.implementationContent += \
299*a9ac8606Spatrick                    """
300*a9ac8606Spatrick    if (auto ConcreteTL = Object.getAs<clang::{0}>())
301*a9ac8606Spatrick      GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3});
302*a9ac8606Spatrick    """.format(InheritanceMap[ASTClassName], baseTemplate,
303*a9ac8606Spatrick            CallPrefix, RecursionGuardParam)
304*a9ac8606Spatrick
305*a9ac8606Spatrick
306*a9ac8606Spatrick    def GenerateDynNodeVisitor(self, CladeNames):
307*a9ac8606Spatrick        MethodReturnType = 'NodeLocationAccessors'
308*a9ac8606Spatrick
309*a9ac8606Spatrick        Signature = \
310*a9ac8606Spatrick            'GetLocations(clang::DynTypedNode const &Node)'
311*a9ac8606Spatrick
312*a9ac8606Spatrick        self.implementationContent += MethodReturnType \
313*a9ac8606Spatrick            + ' NodeIntrospection::' + Signature + '{'
314*a9ac8606Spatrick
315*a9ac8606Spatrick        for CladeName in CladeNames:
316*a9ac8606Spatrick            if CladeName == "DeclarationNameInfo":
317*a9ac8606Spatrick                continue
318*a9ac8606Spatrick            self.implementationContent += \
319*a9ac8606Spatrick                """
320*a9ac8606Spatrick    if (const auto *N = Node.get<{0}>())
321*a9ac8606Spatrick    """.format(CladeName)
322*a9ac8606Spatrick            ArgPrefix = ""
323*a9ac8606Spatrick            if CladeName in self.RefClades:
324*a9ac8606Spatrick                ArgPrefix = "*"
325*a9ac8606Spatrick            self.implementationContent += \
326*a9ac8606Spatrick            """
327*a9ac8606Spatrick      return GetLocations({0}const_cast<{1} *>(N));""".format(ArgPrefix, CladeName)
328*a9ac8606Spatrick
329*a9ac8606Spatrick        self.implementationContent += '\nreturn {}; }'
330*a9ac8606Spatrick
331*a9ac8606Spatrick    def GenerateEpilogue(self):
332*a9ac8606Spatrick
333*a9ac8606Spatrick        self.implementationContent += '''
334*a9ac8606Spatrick  }
335*a9ac8606Spatrick}
336*a9ac8606Spatrick'''
337*a9ac8606Spatrick
338*a9ac8606Spatrickdef main():
339*a9ac8606Spatrick
340*a9ac8606Spatrick    parser = argparse.ArgumentParser()
341*a9ac8606Spatrick    parser.add_argument('--json-input-path',
342*a9ac8606Spatrick                      help='Read API description from FILE', metavar='FILE')
343*a9ac8606Spatrick    parser.add_argument('--output-file', help='Generate output in FILEPATH',
344*a9ac8606Spatrick                      metavar='FILEPATH')
345*a9ac8606Spatrick    parser.add_argument('--use-empty-implementation',
346*a9ac8606Spatrick                      help='Generate empty implementation',
347*a9ac8606Spatrick                      action="store", type=int)
348*a9ac8606Spatrick    parser.add_argument('--empty-implementation',
349*a9ac8606Spatrick                      help='Copy empty implementation from FILEPATH',
350*a9ac8606Spatrick                      action="store", metavar='FILEPATH')
351*a9ac8606Spatrick
352*a9ac8606Spatrick    options = parser.parse_args()
353*a9ac8606Spatrick
354*a9ac8606Spatrick    use_empty_implementation = options.use_empty_implementation
355*a9ac8606Spatrick
356*a9ac8606Spatrick    if (not use_empty_implementation
357*a9ac8606Spatrick            and not os.path.exists(options.json_input_path)):
358*a9ac8606Spatrick        use_empty_implementation = True
359*a9ac8606Spatrick
360*a9ac8606Spatrick    if not use_empty_implementation:
361*a9ac8606Spatrick        with open(options.json_input_path) as f:
362*a9ac8606Spatrick            jsonData = json.load(f)
363*a9ac8606Spatrick
364*a9ac8606Spatrick        if not 'classesInClade' in jsonData or not jsonData["classesInClade"]:
365*a9ac8606Spatrick            use_empty_implementation = True
366*a9ac8606Spatrick
367*a9ac8606Spatrick    if use_empty_implementation:
368*a9ac8606Spatrick        if not os.path.exists(options.output_file) or \
369*a9ac8606Spatrick                not filecmp.cmp(options.empty_implementation, options.output_file):
370*a9ac8606Spatrick            shutil.copyfile(options.empty_implementation, options.output_file)
371*a9ac8606Spatrick        sys.exit(0)
372*a9ac8606Spatrick
373*a9ac8606Spatrick    templateClasses = []
374*a9ac8606Spatrick    for (ClassName, ClassAccessors) in jsonData['classEntries'].items():
375*a9ac8606Spatrick        if "templateParms" in ClassAccessors:
376*a9ac8606Spatrick            templateClasses.append(ClassName)
377*a9ac8606Spatrick
378*a9ac8606Spatrick    g = Generator(templateClasses)
379*a9ac8606Spatrick
380*a9ac8606Spatrick    g.GeneratePrologue()
381*a9ac8606Spatrick
382*a9ac8606Spatrick    for (CladeName, ClassNameData) in jsonData['classesInClade'].items():
383*a9ac8606Spatrick        g.GenerateBaseGetLocationsDeclaration(CladeName)
384*a9ac8606Spatrick
385*a9ac8606Spatrick    def getCladeName(ClassName):
386*a9ac8606Spatrick      for (CladeName, ClassNameData) in jsonData['classesInClade'].items():
387*a9ac8606Spatrick        if ClassName in ClassNameData:
388*a9ac8606Spatrick          return CladeName
389*a9ac8606Spatrick
390*a9ac8606Spatrick    for (ClassName, ClassAccessors) in jsonData['classEntries'].items():
391*a9ac8606Spatrick        cladeName = getCladeName(ClassName)
392*a9ac8606Spatrick        g.GenerateSrcLocMethod(
393*a9ac8606Spatrick            ClassName, ClassAccessors,
394*a9ac8606Spatrick            cladeName not in Generator.RefClades)
395*a9ac8606Spatrick
396*a9ac8606Spatrick    for (CladeName, ClassNameData) in jsonData['classesInClade'].items():
397*a9ac8606Spatrick        g.GenerateBaseGetLocationsFunction(
398*a9ac8606Spatrick            ClassNameData,
399*a9ac8606Spatrick            jsonData['classEntries'],
400*a9ac8606Spatrick            CladeName,
401*a9ac8606Spatrick            jsonData["classInheritance"],
402*a9ac8606Spatrick            CladeName not in Generator.RefClades)
403*a9ac8606Spatrick
404*a9ac8606Spatrick    g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys())
405*a9ac8606Spatrick
406*a9ac8606Spatrick    g.GenerateEpilogue()
407*a9ac8606Spatrick
408*a9ac8606Spatrick    g.GenerateFiles(options.output_file)
409*a9ac8606Spatrick
410*a9ac8606Spatrickif __name__ == '__main__':
411*a9ac8606Spatrick    main()
412