2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2008-02-27 16:28:13 +00:00
|
|
|
/**
|
|
|
|
* A script for GCC-dehydra to analyze the Mozilla codebase and catch
|
|
|
|
* patterns that are incorrect, but which cannot be detected by a compiler. */
|
|
|
|
|
2008-05-01 00:47:27 +00:00
|
|
|
/**
|
|
|
|
* Activate Treehydra outparams analysis if running in Treehydra.
|
|
|
|
*/
|
|
|
|
|
|
|
|
function treehydra_enabled() {
|
|
|
|
return this.hasOwnProperty('TREE_CODE');
|
|
|
|
}
|
|
|
|
|
2008-06-06 19:31:11 +00:00
|
|
|
sys.include_path.push(options.topsrcdir);
|
|
|
|
|
2008-09-03 17:00:13 +00:00
|
|
|
include('string-format.js');
|
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var modules = [];
|
2008-06-06 19:31:11 +00:00
|
|
|
|
|
|
|
function LoadModules(modulelist)
|
|
|
|
{
|
|
|
|
if (modulelist == "")
|
|
|
|
return;
|
|
|
|
|
|
|
|
let modulenames = modulelist.split(',');
|
2015-10-18 16:34:50 +00:00
|
|
|
for (let modulename of modulenames) {
|
2008-06-06 19:31:11 +00:00
|
|
|
let module = { __proto__: this };
|
|
|
|
include(modulename, module);
|
|
|
|
modules.push(module);
|
|
|
|
}
|
2008-05-01 00:47:27 +00:00
|
|
|
}
|
|
|
|
|
2008-06-06 19:31:11 +00:00
|
|
|
LoadModules(options['dehydra-modules']);
|
|
|
|
if (treehydra_enabled())
|
|
|
|
LoadModules(options['treehydra-modules']);
|
|
|
|
|
2008-03-27 18:03:59 +00:00
|
|
|
function process_type(c)
|
2008-02-27 16:28:13 +00:00
|
|
|
{
|
2015-10-18 16:34:50 +00:00
|
|
|
for (let module of modules)
|
2008-06-06 19:31:11 +00:00
|
|
|
if (module.hasOwnProperty('process_type'))
|
|
|
|
module.process_type(c);
|
2008-02-27 16:28:13 +00:00
|
|
|
}
|
|
|
|
|
2008-06-30 16:44:06 +00:00
|
|
|
function hasAttribute(c, attrname)
|
2008-02-27 16:28:13 +00:00
|
|
|
{
|
2008-06-30 16:44:06 +00:00
|
|
|
var attr;
|
2008-02-27 16:28:13 +00:00
|
|
|
|
2008-06-30 16:44:06 +00:00
|
|
|
if (c.attributes === undefined)
|
2008-02-27 16:28:13 +00:00
|
|
|
return false;
|
|
|
|
|
2015-10-18 16:34:50 +00:00
|
|
|
for (var key in c.attributes) {
|
|
|
|
attr = c.attributes[key];
|
2008-06-30 16:44:06 +00:00
|
|
|
if (attr.name == 'user' && attr.value[0] == attrname)
|
|
|
|
return true;
|
2015-10-18 16:34:50 +00:00
|
|
|
}
|
2008-02-27 16:28:13 +00:00
|
|
|
|
2008-06-30 16:44:06 +00:00
|
|
|
return false;
|
2008-02-27 16:28:13 +00:00
|
|
|
}
|
2008-09-03 17:00:13 +00:00
|
|
|
|
2009-09-18 17:26:13 +00:00
|
|
|
// This is useful for detecting method overrides
|
|
|
|
function signaturesMatch(m1, m2)
|
|
|
|
{
|
|
|
|
if (m1.shortName != m2.shortName)
|
|
|
|
return false;
|
2009-09-04 15:21:31 +00:00
|
|
|
|
2009-10-04 18:35:33 +00:00
|
|
|
if ((!!m1.isVirtual) != (!!m2.isVirtual))
|
2009-09-04 15:21:31 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (m1.isStatic != m2.isStatic)
|
|
|
|
return false;
|
2009-09-18 17:26:13 +00:00
|
|
|
|
|
|
|
let p1 = m1.type.parameters;
|
|
|
|
let p2 = m2.type.parameters;
|
2010-08-19 01:06:05 +00:00
|
|
|
|
2009-09-18 17:26:13 +00:00
|
|
|
if (p1.length != p2.length)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (let i = 0; i < p1.length; ++i)
|
2010-08-19 01:06:05 +00:00
|
|
|
if (!params_match(p1[i], p2[i]))
|
2009-09-18 17:26:13 +00:00
|
|
|
return false;
|
2010-08-19 01:06:05 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function params_match(p1, p2)
|
|
|
|
{
|
|
|
|
[p1, p2] = unwrap_types(p1, p2);
|
|
|
|
|
|
|
|
for (let i in p1)
|
|
|
|
if (i == "type" && !types_match(p1.type, p2.type))
|
|
|
|
return false;
|
|
|
|
else if (i != "type" && p1[i] !== p2[i])
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (let i in p2)
|
|
|
|
if (!(i in p1))
|
|
|
|
return false;
|
|
|
|
|
2009-09-18 17:26:13 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-08-19 01:06:05 +00:00
|
|
|
function types_match(t1, t2)
|
|
|
|
{
|
|
|
|
if (!t1 || !t2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
[t1, t2] = unwrap_types(t1, t2);
|
|
|
|
|
|
|
|
return t1 === t2;
|
|
|
|
}
|
|
|
|
|
|
|
|
function unwrap_types(t1, t2)
|
|
|
|
{
|
|
|
|
while (t1.variantOf)
|
|
|
|
t1 = t1.variantOf;
|
|
|
|
|
|
|
|
while (t2.variantOf)
|
|
|
|
t2 = t2.variantOf;
|
|
|
|
|
|
|
|
return [t1, t2];
|
|
|
|
}
|
|
|
|
|
2009-06-25 19:12:19 +00:00
|
|
|
const forward_functions = [
|
|
|
|
'process_type',
|
|
|
|
'process_tree_type',
|
|
|
|
'process_decl',
|
|
|
|
'process_tree_decl',
|
|
|
|
'process_function',
|
|
|
|
'process_tree',
|
|
|
|
'process_cp_pre_genericize',
|
|
|
|
'input_end'
|
|
|
|
];
|
|
|
|
|
|
|
|
function setup_forwarding(n)
|
2008-09-03 17:00:13 +00:00
|
|
|
{
|
2009-06-25 19:12:19 +00:00
|
|
|
this[n] = function() {
|
2015-10-18 16:34:50 +00:00
|
|
|
for (let module of modules) {
|
2009-06-25 19:12:19 +00:00
|
|
|
if (module.hasOwnProperty(n)) {
|
|
|
|
module[n].apply(this, arguments);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-06-06 19:31:11 +00:00
|
|
|
}
|
2008-02-27 16:28:13 +00:00
|
|
|
|
2015-10-18 16:34:50 +00:00
|
|
|
for (let n of forward_functions)
|
2009-06-25 19:12:19 +00:00
|
|
|
setup_forwarding(n);
|