Implement a module-level symbol table for functions, enforcing uniqueness of
names across the module and auto-renaming conflicts. Have the parser reject
malformed modules that have redefinitions.
PiperOrigin-RevId: 209227560
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index f263804..ae87ad2 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -1945,8 +1945,6 @@
"'");
}
- getModule()->getFunctions().push_back(function);
-
return finalizeFunction(function, braceLoc);
}
@@ -2122,8 +2120,6 @@
if (parseStmtBlock(function))
return ParseFailure;
- getModule()->getFunctions().push_back(function);
-
return finalizeFunction(function, braceLoc);
}
@@ -2579,6 +2575,7 @@
///
ParseResult ModuleParser::parseExtFunc() {
consumeToken(Token::kw_extfunc);
+ auto loc = getToken().getLoc();
StringRef name;
FunctionType *type = nullptr;
@@ -2586,7 +2583,14 @@
return ParseFailure;
// Okay, the external function definition was parsed correctly.
- getModule()->getFunctions().push_back(new ExtFunction(name, type));
+ auto *function = new ExtFunction(name, type);
+ getModule()->getFunctions().push_back(function);
+
+ // Verify no name collision / redefinition.
+ if (function->getName().ref() != name)
+ return emitError(loc,
+ "redefinition of function named '" + name.str() + "'");
+
return ParseSuccess;
}
@@ -2596,6 +2600,7 @@
///
ParseResult ModuleParser::parseCFGFunc() {
consumeToken(Token::kw_cfgfunc);
+ auto loc = getToken().getLoc();
StringRef name;
FunctionType *type = nullptr;
@@ -2603,7 +2608,13 @@
return ParseFailure;
// Okay, the CFG function signature was parsed correctly, create the function.
- auto function = new CFGFunction(name, type);
+ auto *function = new CFGFunction(name, type);
+ getModule()->getFunctions().push_back(function);
+
+ // Verify no name collision / redefinition.
+ if (function->getName().ref() != name)
+ return emitError(loc,
+ "redefinition of function named '" + name.str() + "'");
return CFGFunctionParser(getState(), function).parseFunctionBody();
}
@@ -2624,7 +2635,13 @@
return ParseFailure;
// Okay, the ML function signature was parsed correctly, create the function.
- auto function = MLFunction::create(name, type);
+ auto *function = MLFunction::create(name, type);
+ getModule()->getFunctions().push_back(function);
+
+ // Verify no name collision / redefinition.
+ if (function->getName().ref() != name)
+ return emitError(loc,
+ "redefinition of function named '" + name.str() + "'");
// Create the parser.
auto parser = MLFunctionParser(getState(), function);