Fix for GitHub issue #98 and #167

Two fixes needed:
  - when searching for a base class, we need to look in the root scope
    if the base class isn't found in the scope hierarchy
  - the classes in the root scope need to be stored in an ordered
    list, not a map, to ensure they are elaborated in the order they
    were declared. Without this, the compiler may try elaborating an
    extended class before its base class is known about.

(cherry picked from commit 87cddf33dc)
This commit is contained in:
Martin Whitaker 2017-10-08 20:45:07 +01:00
parent 1f7588d3a4
commit a18fe22d32
4 changed files with 16 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -509,8 +509,10 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
netclass_t*use_base_class = 0;
if (base_class) {
ivl_assert(*pclass, scope);
use_base_class = scope->find_class(base_class->name);
if (scope)
use_base_class = scope->find_class(base_class->name);
if (use_base_class == 0)
use_base_class = des->find_class(base_class->name);
if (use_base_class == 0) {
cerr << pclass->get_fileline() << ": error: "
<< "Base class " << base_class->name
@ -605,13 +607,9 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
void elaborate_rootscope_classes(Design*des)
{
if (pform_classes.empty())
return;
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
; cur != pform_classes.end() ; ++ cur) {
blend_class_constructors(cur->second);
elaborate_scope_class(des, 0, cur->second);
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
blend_class_constructors(pform_classes[idx]);
elaborate_scope_class(des, 0, pform_classes[idx]);
}
}

View File

@ -1,5 +1,5 @@
const char COPYRIGHT[] =
"Copyright (c) 1998-2015 Stephen Williams (steve@icarus.com)";
"Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)";
/*
* This source code is free software; you can redistribute it
@ -1037,9 +1037,8 @@ int main(int argc, char*argv[])
pform_dump(out, cur->second);
}
out << "PFORM DUMP $ROOT CLASSES:" << endl;
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
; cur != pform_classes.end() ; ++ cur) {
pform_dump(out, cur->second);
for (size_t idx = 0 ; idx < pform_classes.size() ; idx += 1) {
pform_dump(out, pform_classes[idx]);
}
out << "PFORM DUMP PACKAGES:" << endl;
for (map<perm_string,PPackage*>::iterator pac = pform_packages.begin()

View File

@ -1,7 +1,7 @@
#ifndef IVL_parse_api_H
#define IVL_parse_api_H
/*
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -45,7 +45,7 @@ extern std::map<perm_string,PUdp*> pform_primitives;
extern std::map<perm_string,data_type_t*> pform_typedefs;
extern std::set<enum_type_t*> pform_enum_sets;
extern std::map<perm_string,PTaskFunc*> pform_tasks;
extern std::map<perm_string,PClass*> pform_classes;
extern std::vector<PClass*> pform_classes;
extern std::map<perm_string,PPackage*> pform_packages;
extern void pform_dump(std::ostream&out, const PClass*pac);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2016 Stephen Williams (steve@icarus.com)
* Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -71,7 +71,7 @@ set<enum_type_t*>pform_enum_sets;
/*
* Class definitions in the $root scope go here.
*/
map<perm_string,PClass*> pform_classes;
vector<PClass*> pform_classes;
/*
* Task and function definitions in the $root scope go here.
@ -467,7 +467,7 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name,
/* If no scope was found then this is being defined in the
* compilation unit scope. */
if (scopex == 0) {
pform_classes[name] = class_scope;
pform_classes.push_back(class_scope);
lexical_scope = class_scope;
return class_scope;
}