Fix classes/modules of case-similar names (#5109).

This commit is contained in:
Wilson Snyder 2024-07-14 13:57:16 -04:00
parent 131623de34
commit 0658af90f5
5 changed files with 124 additions and 3 deletions

View File

@ -22,6 +22,7 @@ Verilator 5.027 devel
* Add `--compiler-include` for additional C++ includes (#5139) (#5202). [Bartłomiej Chmiel, Antmicro Ltd.]
* Add `--emit-accessors` (#5182) (#5227). [Ryan Ziegler]
* Fix fusing macro arguments to not ignore whitespace (#5061). [Tudor Timi]
* Fix classes/modules of case-similar names (#5109). [Arkadiusz Kozdra]
* Fix mis-removing $value$plusargs calls (#5127) (#5137). [Seth Pellegrino]
* Fix splitting if statements with impure conditions (#5219). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix unknown conversion on queues (#5220). [Alex Solomatnikov]

View File

@ -35,6 +35,42 @@ EmitCParentModule::EmitCParentModule() {
setAll(v3Global.rootp()->constPoolp()->modp());
}
//######################################################################
// EmitCBase implementation
string EmitCBase::prefixNameProtect(const AstNode* nodep) VL_MT_STABLE {
const string prefix = v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
// If all-uppercase prefix conflicts with a previous usage of the
// prefix with different capitalization, rename to avoid conflict.
// This is to support OSes where filename compares are non-case significant.
// STATIC:
static V3Mutex s_mutex;
const V3LockGuard lock{s_mutex}; // Otherwise map access is unsafe
static std::map<std::string, std::string> s_memoized;
static std::map<std::string, std::string> s_ucToPrefix;
// Memoize results
const auto mit = s_memoized.find(prefix);
if (mit != s_memoized.end()) return mit->second;
//
// Check capitalization
const string prefixUpper = VString::upcase(prefix);
string result;
{
const auto it = s_ucToPrefix.find(prefixUpper);
if (it == s_ucToPrefix.end()) {
s_ucToPrefix.emplace(prefixUpper, prefix);
result = prefix;
} else if (it->second == prefix) {
result = prefix; // Same capitialization as last time
} else {
VHashSha256 hash{prefix};
result = prefix + "__Vphsh" + hash.digestSymbol();
}
}
s_memoized.emplace(prefix, result);
return result;
}
//######################################################################
// EmitCBaseVisitor implementation

View File

@ -66,9 +66,8 @@ public:
static string topClassName() VL_MT_SAFE { // Return name of top wrapper module
return v3Global.opt.prefix();
}
static string prefixNameProtect(const AstNode* nodep) VL_MT_STABLE { // C++ name with prefix
return v3Global.opt.modPrefix() + "_" + VIdProtect::protect(nodep->name());
}
// Return C++ class name for a module/class object
static string prefixNameProtect(const AstNode* nodep) VL_MT_STABLE;
static bool isAnonOk(const AstVar* varp) {
AstNodeDType* const dtp = varp->dtypep()->skipRefp();
return v3Global.opt.compLimitMembers() != 0 // Enabled

View File

@ -0,0 +1,21 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,64 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// Test different uppercase/lowercase capitalization cases
class ClsMixed;
int m;
int M;
endclass
class Clsmixed;
int m;
int M;
endclass
module ModMixed;
// verilator no_inline_module
int m;
int M;
endmodule
module Modmixed;
// verilator no_inline_module
int m;
int M;
endmodule
module t(/*AUTOARG*/);
// verilator no_inline_module
ModMixed modMixed();
Modmixed modmixed();
initial begin
ClsMixed clsMixed;
Clsmixed clsmixed;
clsMixed = new;
clsMixed.m = 1;
clsMixed.M = 2;
clsmixed = new;
clsmixed.m = 3;
clsmixed.M = 4;
if (clsMixed.m != 1) $stop;
if (clsMixed.M != 2) $stop;
if (clsmixed.m != 3) $stop;
if (clsmixed.M != 4) $stop;
modMixed.m = 1;
modMixed.M = 2;
modmixed.m = 3;
modmixed.M = 4;
if (modMixed.m != 1) $stop;
if (modMixed.M != 2) $stop;
if (modmixed.m != 3) $stop;
if (modmixed.M != 4) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule