@@ -394,10 +394,6 @@ class OperationParser : public Parser {
394
394
// / us to diagnose references to blocks that are not defined precisely.
395
395
Block *getBlockNamed (StringRef name, SMLoc loc);
396
396
397
- // / Define the block with the specified name. Returns the Block* or nullptr in
398
- // / the case of redefinition.
399
- Block *defineBlockNamed (StringRef name, SMLoc loc, Block *existing);
400
-
401
397
private:
402
398
// / This class represents a definition of a Block.
403
399
struct BlockDefinition {
@@ -1953,11 +1949,38 @@ ParseResult OperationParser::parseBlock(Block *&block) {
1953
1949
if (parseToken (Token::caret_identifier, " expected block name" ))
1954
1950
return failure ();
1955
1951
1956
- block = defineBlockNamed (name, nameLoc, block);
1952
+ // Define the block with the specified name.
1953
+ auto &blockAndLoc = getBlockInfoByName (name);
1954
+ blockAndLoc.loc = nameLoc;
1955
+
1956
+ // Use a unique pointer for in-flight block being parsed. Release ownership
1957
+ // only in the case of a successful parse. This ensures that the Block
1958
+ // allocated is released if the parse fails and control returns early.
1959
+ std::unique_ptr<Block> inflightBlock;
1960
+
1961
+ // If a block has yet to be set, this is a new definition. If the caller
1962
+ // provided a block, use it. Otherwise create a new one.
1963
+ if (!blockAndLoc.block ) {
1964
+ if (block) {
1965
+ blockAndLoc.block = block;
1966
+ } else {
1967
+ inflightBlock = std::make_unique<Block>();
1968
+ blockAndLoc.block = inflightBlock.get ();
1969
+ }
1957
1970
1958
- // Fail if the block was already defined.
1959
- if (!block)
1971
+ // Otherwise, the block has a forward declaration. Forward declarations are
1972
+ // removed once defined, so if we are defining a existing block and it is
1973
+ // not a forward declaration, then it is a redeclaration. Fail if the block
1974
+ // was already defined.
1975
+ } else if (!eraseForwardRef (blockAndLoc.block )) {
1960
1976
return emitError (nameLoc, " redefinition of block '" ) << name << " '" ;
1977
+ }
1978
+
1979
+ // Populate the high level assembly state if necessary.
1980
+ if (state.asmState )
1981
+ state.asmState ->addDefinition (blockAndLoc.block , nameLoc);
1982
+
1983
+ block = blockAndLoc.block ;
1961
1984
1962
1985
// If an argument list is present, parse it.
1963
1986
if (getToken ().is (Token::l_paren))
@@ -1967,7 +1990,10 @@ ParseResult OperationParser::parseBlock(Block *&block) {
1967
1990
if (parseToken (Token::colon, " expected ':' after block name" ))
1968
1991
return failure ();
1969
1992
1970
- return parseBlockBody (block);
1993
+ ParseResult res = parseBlockBody (block);
1994
+ if (succeeded (res))
1995
+ inflightBlock.release ();
1996
+ return res;
1971
1997
}
1972
1998
1973
1999
ParseResult OperationParser::parseBlockBody (Block *block) {
@@ -1999,32 +2025,6 @@ Block *OperationParser::getBlockNamed(StringRef name, SMLoc loc) {
1999
2025
return blockDef.block ;
2000
2026
}
2001
2027
2002
- // / Define the block with the specified name. Returns the Block* or nullptr in
2003
- // / the case of redefinition.
2004
- Block *OperationParser::defineBlockNamed (StringRef name, SMLoc loc,
2005
- Block *existing) {
2006
- auto &blockAndLoc = getBlockInfoByName (name);
2007
- blockAndLoc.loc = loc;
2008
-
2009
- // If a block has yet to be set, this is a new definition. If the caller
2010
- // provided a block, use it. Otherwise create a new one.
2011
- if (!blockAndLoc.block ) {
2012
- blockAndLoc.block = existing ? existing : new Block ();
2013
-
2014
- // Otherwise, the block has a forward declaration. Forward declarations are
2015
- // removed once defined, so if we are defining a existing block and it is
2016
- // not a forward declaration, then it is a redeclaration.
2017
- } else if (!eraseForwardRef (blockAndLoc.block )) {
2018
- return nullptr ;
2019
- }
2020
-
2021
- // Populate the high level assembly state if necessary.
2022
- if (state.asmState )
2023
- state.asmState ->addDefinition (blockAndLoc.block , loc);
2024
-
2025
- return blockAndLoc.block ;
2026
- }
2027
-
2028
2028
// / Parse a (possibly empty) list of SSA operands with types as block arguments
2029
2029
// / enclosed in parentheses.
2030
2030
// /
0 commit comments