diff options
author | Chris Lattner <sabre@nondot.org> | 2009-06-26 04:27:47 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-06-26 04:27:47 +0000 |
commit | 5558e9fc55a1677798c3ac664e613e7fcd41da06 (patch) | |
tree | 1c8567afaa891ddfae58d245bc71c651a53f41c3 /clang/lib/Parse/ParseTemplate.cpp | |
parent | 6dde0bfef7c8a467d4c2470ef126ccef167a904a (diff) | |
download | bcm5719-llvm-5558e9fc55a1677798c3ac664e613e7fcd41da06.tar.gz bcm5719-llvm-5558e9fc55a1677798c3ac664e613e7fcd41da06.zip |
fix PR4452, a crash on invalid. The error recovery is still terrible in this case
but at least we don't crash :)
llvm-svn: 74264
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index ab359f4c5e0..57a09fbc737 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -621,7 +621,11 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, /// replaced with a type annotation token. Otherwise, the /// simple-template-id is always replaced with a template-id /// annotation token. -void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, +/// +/// If an unrecoverable parse error occurs and no annotation token can be +/// formed, this function returns true. +/// +bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, const CXXScopeSpec *SS, SourceLocation TemplateKWLoc, bool AllowTypeAnnotation) { @@ -644,14 +648,19 @@ void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, TemplateArgIsType, TemplateArgLocations, RAngleLoc); + + if (Invalid) { + // If we failed to parse the template ID but skipped ahead to a >, we're not + // going to be able to form a token annotation. Eat the '>' if present. + if (Tok.is(tok::greater)) + ConsumeToken(); + return true; + } ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), TemplateArgIsType.data(), TemplateArgs.size()); - if (Invalid) // FIXME: How to recover from a broken template-id? - return; - // Build the annotation token. if (TNK == TNK_Type_template && AllowTypeAnnotation) { Action::TypeResult Type @@ -659,8 +668,13 @@ void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, LAngleLoc, TemplateArgsPtr, &TemplateArgLocations[0], RAngleLoc); - if (Type.isInvalid()) // FIXME: better recovery? - return; + if (Type.isInvalid()) { + // If we failed to parse the template ID but skipped ahead to a >, we're not + // going to be able to form a token annotation. Eat the '>' if present. + if (Tok.is(tok::greater)) + ConsumeToken(); + return true; + } Tok.setKind(tok::annot_typename); Tok.setAnnotationValue(Type.get()); @@ -705,6 +719,7 @@ void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, // In case the tokens were cached, have Preprocessor replace them with the // annotation token. PP.AnnotateCachedTokens(Tok); + return false; } /// \brief Replaces a template-id annotation token with a type |