@@ -1430,6 +1430,9 @@ struct FIRModuleContext : public FIRParser {
1430
1430
insertNameIntoGlobalScope);
1431
1431
}
1432
1432
1433
+ // Removes a symbol from symbolTable (Workaround since symbolTable is private)
1434
+ void removeSymbolEntry (StringRef name);
1435
+
1433
1436
// / Resolved a symbol table entry to a value. Emission of error is optional.
1434
1437
ParseResult resolveSymbolEntry (Value &result, SymbolValueEntry &entry,
1435
1438
SMLoc loc, bool fatal = true );
@@ -1511,6 +1514,11 @@ struct FIRModuleContext : public FIRParser {
1511
1514
1512
1515
} // end anonymous namespace
1513
1516
1517
+ // Removes a symbol from symbolTable (Workaround since symbolTable is private)
1518
+ void FIRModuleContext::removeSymbolEntry (StringRef name) {
1519
+ symbolTable.erase (name);
1520
+ }
1521
+
1514
1522
// / Add a symbol entry with the specified name, returning failure if the name
1515
1523
// / is already defined.
1516
1524
// /
@@ -1522,12 +1530,22 @@ ParseResult FIRModuleContext::addSymbolEntry(StringRef name,
1522
1530
bool insertNameIntoGlobalScope) {
1523
1531
// Do a lookup by trying to do an insertion. Do so in a way that we can tell
1524
1532
// if we hit a missing element (SMLoc is null).
1525
- auto entryIt =
1526
- symbolTable.try_emplace (name, SMLoc (), SymbolValueEntry ()).first ;
1527
- if (entryIt->second .first .isValid ()) {
1528
- emitError (loc, " redefinition of name '" + name + " '" )
1529
- .attachNote (translateLocation (entryIt->second .first ))
1530
- << " previous definition here" ;
1533
+ auto [entryIt, inserted] =
1534
+ symbolTable.try_emplace (name, SMLoc (), SymbolValueEntry ());
1535
+
1536
+ // If insertion failed, the name already exists
1537
+ if (!inserted) {
1538
+ if (entryIt->second .first .isValid ()) {
1539
+ // Valid activeSMLoc: active symbol in current scope redeclared
1540
+ emitError (loc, " redefinition of name '" + name + " ' " )
1541
+ .attachNote (translateLocation (entryIt->second .first ))
1542
+ << " previous definition here." ;
1543
+ } else {
1544
+ // Invalid activeSMLoc: symbol from a completed scope redeclared
1545
+ emitError (loc, " redefinition of name '" + name + " ' " )
1546
+ << " - FIRRTL has flat namespace and requires all "
1547
+ << " declarations in a module to have unique names." ;
1548
+ }
1531
1549
return failure ();
1532
1550
}
1533
1551
@@ -1536,7 +1554,6 @@ ParseResult FIRModuleContext::addSymbolEntry(StringRef name,
1536
1554
entryIt->second = {loc, entry};
1537
1555
if (currentScope && !insertNameIntoGlobalScope)
1538
1556
currentScope->scopedDecls .push_back (&*entryIt);
1539
-
1540
1557
return success ();
1541
1558
}
1542
1559
@@ -4878,10 +4895,12 @@ ParseResult FIRStmtParser::parseContract(unsigned blockIndent) {
4878
4895
4879
4896
// Declare the results.
4880
4897
for (auto [id, loc, value, result] :
4881
- llvm::zip (ids, locs, values, contract.getResults ()))
4898
+ llvm::zip (ids, locs, values, contract.getResults ())) {
4899
+ // Remove previous symbol to avoid duplicates
4900
+ moduleContext.removeSymbolEntry (id);
4882
4901
if (failed (moduleContext.addSymbolEntry (id, result, loc)))
4883
4902
return failure ();
4884
-
4903
+ }
4885
4904
return success ();
4886
4905
}
4887
4906
0 commit comments