Implement Sebastian's idea for simplifying our handling of the greater-than operator/delimiter. Also, clean up after ourselves following a failed parse of a template-argument-list
llvm-svn: 64166
This commit is contained in:
parent
fe174df170
commit
0db4ccd7fb
|
@ -64,34 +64,18 @@ class Parser {
|
||||||
/// argument list.
|
/// argument list.
|
||||||
bool GreaterThanIsOperator;
|
bool GreaterThanIsOperator;
|
||||||
|
|
||||||
/// \brief RAII object that makes '>' behave like the closing angle
|
/// \brief RAII object that makes '>' behave either as an operator
|
||||||
/// bracket for a template argument list.
|
/// or as the closing angle bracket for a template argument list.
|
||||||
struct MakeGreaterThanTemplateArgumentListTerminator {
|
struct GreaterThanIsOperatorScope {
|
||||||
bool &GreaterThanIsOperator;
|
bool &GreaterThanIsOperator;
|
||||||
bool OldGreaterThanIsOperator;
|
bool OldGreaterThanIsOperator;
|
||||||
|
|
||||||
MakeGreaterThanTemplateArgumentListTerminator(bool >IO)
|
GreaterThanIsOperatorScope(bool >IO, bool Val)
|
||||||
: GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
|
: GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
|
||||||
GTIO = false;
|
GreaterThanIsOperator = Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
~MakeGreaterThanTemplateArgumentListTerminator() {
|
~GreaterThanIsOperatorScope() {
|
||||||
GreaterThanIsOperator = OldGreaterThanIsOperator;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief RAII object that makes '>' behave like an
|
|
||||||
/// operator. Occurs, for example, inside parentheses.
|
|
||||||
struct MakeGreaterThanAnOperator {
|
|
||||||
bool &GreaterThanIsOperator;
|
|
||||||
bool OldGreaterThanIsOperator;
|
|
||||||
|
|
||||||
MakeGreaterThanAnOperator(bool >IO)
|
|
||||||
: GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) {
|
|
||||||
GTIO = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~MakeGreaterThanAnOperator() {
|
|
||||||
GreaterThanIsOperator = OldGreaterThanIsOperator;
|
GreaterThanIsOperator = OldGreaterThanIsOperator;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1112,7 +1112,7 @@ Parser::OwningExprResult
|
||||||
Parser::ParseParenExpression(ParenParseOption &ExprType,
|
Parser::ParseParenExpression(ParenParseOption &ExprType,
|
||||||
TypeTy *&CastTy, SourceLocation &RParenLoc) {
|
TypeTy *&CastTy, SourceLocation &RParenLoc) {
|
||||||
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
|
assert(Tok.is(tok::l_paren) && "Not a paren expr!");
|
||||||
MakeGreaterThanAnOperator G(GreaterThanIsOperator);
|
GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
|
||||||
SourceLocation OpenLoc = ConsumeParen();
|
SourceLocation OpenLoc = ConsumeParen();
|
||||||
OwningExprResult Result(Actions, true);
|
OwningExprResult Result(Actions, true);
|
||||||
CastTy = 0;
|
CastTy = 0;
|
||||||
|
|
|
@ -371,13 +371,17 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
|
||||||
TemplateArgList TemplateArgs;
|
TemplateArgList TemplateArgs;
|
||||||
TemplateArgIsTypeList TemplateArgIsType;
|
TemplateArgIsTypeList TemplateArgIsType;
|
||||||
{
|
{
|
||||||
MakeGreaterThanTemplateArgumentListTerminator G(GreaterThanIsOperator);
|
GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
|
||||||
if (Tok.isNot(tok::greater) &&
|
if (Tok.isNot(tok::greater) &&
|
||||||
ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType)) {
|
ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType)) {
|
||||||
// Try to find the closing '>'.
|
// Try to find the closing '>'.
|
||||||
SkipUntil(tok::greater, true, true);
|
SkipUntil(tok::greater, true, true);
|
||||||
|
|
||||||
|
// Clean up any template arguments that we successfully parsed.
|
||||||
|
ASTTemplateArgsPtr TemplateArgsPtr(Actions, &TemplateArgs[0],
|
||||||
|
&TemplateArgIsType[0],
|
||||||
|
TemplateArgs.size());
|
||||||
|
|
||||||
// FIXME: What's our recovery strategy for failed template-argument-lists?
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue