Merge mozilla-b2g34 to 2.1s. a=merge
[gecko.git] / config / static-checking.js
blob9e59741ba11878bc5874fe218bca7a7a612c66fe
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /**
6  * A script for GCC-dehydra to analyze the Mozilla codebase and catch
7  * patterns that are incorrect, but which cannot be detected by a compiler. */
9 /**
10  * Activate Treehydra outparams analysis if running in Treehydra.
11  */
13 function treehydra_enabled() {
14   return this.hasOwnProperty('TREE_CODE');
17 sys.include_path.push(options.topsrcdir);
19 include('string-format.js');
21 let modules = [];
23 function LoadModules(modulelist)
25   if (modulelist == "")
26     return;
28   let modulenames = modulelist.split(',');
29   for each (let modulename in modulenames) {
30     let module = { __proto__: this };
31     include(modulename, module);
32     modules.push(module);
33   }
36 LoadModules(options['dehydra-modules']);
37 if (treehydra_enabled())
38   LoadModules(options['treehydra-modules']);
40 function process_type(c)
42   for each (let module in modules)
43     if (module.hasOwnProperty('process_type'))
44       module.process_type(c);
47 function hasAttribute(c, attrname)
49   var attr;
51   if (c.attributes === undefined)
52     return false;
54   for each (attr in c.attributes)
55     if (attr.name == 'user' && attr.value[0] == attrname)
56       return true;
58   return false;
61 // This is useful for detecting method overrides
62 function signaturesMatch(m1, m2)
64   if (m1.shortName != m2.shortName)
65     return false;
67   if ((!!m1.isVirtual) != (!!m2.isVirtual))
68     return false;
69   
70   if (m1.isStatic != m2.isStatic)
71     return false;
72   
73   let p1 = m1.type.parameters;
74   let p2 = m2.type.parameters;
76   if (p1.length != p2.length)
77     return false;
78   
79   for (let i = 0; i < p1.length; ++i)
80     if (!params_match(p1[i], p2[i]))
81       return false;
83   return true;
86 function params_match(p1, p2)
88   [p1, p2] = unwrap_types(p1, p2);
90   for (let i in p1)
91     if (i == "type" && !types_match(p1.type, p2.type))
92       return false;
93     else if (i != "type" && p1[i] !== p2[i])
94       return false;
96   for (let i in p2)
97     if (!(i in p1))
98       return false;
100   return true;
103 function types_match(t1, t2)
105   if (!t1 || !t2)
106     return false;
108   [t1, t2] = unwrap_types(t1, t2);
110   return t1 === t2;
113 function unwrap_types(t1, t2)
115   while (t1.variantOf)
116     t1 = t1.variantOf;
118   while (t2.variantOf)
119     t2 = t2.variantOf;
121   return [t1, t2];
124 const forward_functions = [
125   'process_type',
126   'process_tree_type',
127   'process_decl',
128   'process_tree_decl',
129   'process_function',
130   'process_tree',
131   'process_cp_pre_genericize',
132   'input_end'
135 function setup_forwarding(n)
137   this[n] = function() {
138     for each (let module in modules) {
139       if (module.hasOwnProperty(n)) {
140         module[n].apply(this, arguments);
141       }
142     }
143   }
146 for each (let n in forward_functions)
147   setup_forwarding(n);