aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-04-27 04:48:22 +0000
committerDouglas Gregor <dgregor@apple.com>2011-04-27 04:48:22 +0000
commit3b887354b1b667c97d070ddc67b5354353c4c07b (patch)
tree6918d42ba0eff9ecd953365c511ddd0289e3d874 /lib/Parse
parent173d51286bcaff4b6b76eebf6542d3b1311142e2 (diff)
Extend Sema::ClassifyName() to support C++, ironing out a few issues
in the classification of template names and using declarations. We now properly typo-correct the leading identifiers in statements to types, templates, values, etc. As an added bonus, this reduces the number of lookups required for disambiguation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130288 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/ParseStmt.cpp29
-rw-r--r--lib/Parse/Parser.cpp3
2 files changed, 26 insertions, 6 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index a324bdc045..3aec4ea210 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -113,7 +113,7 @@ Retry:
return ParseLabeledStatement(attrs);
}
- if (!getLang().CPlusPlus) {
+ if (Next.isNot(tok::coloncolon)) {
// FIXME: Temporarily enable this code only for C.
CXXScopeSpec SS;
IdentifierInfo *Name = Tok.getIdentifierInfo();
@@ -147,7 +147,7 @@ Retry:
// we're in a syntactic context we haven't handled yet.
break;
- case Sema::NC_Type:
+ case Sema::NC_Type: {
// We have a type. In C, this means that we have a declaration.
if (!getLang().CPlusPlus) {
ParsedType Type = Classification.getType();
@@ -195,9 +195,15 @@ Retry:
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
- // In C++, we might also have a functional-style cast.
- // FIXME: Implement this!
+ // In C++, we might also have a functional-style cast. Just annotate
+ // this as a type token.
+ Tok.setKind(tok::annot_typename);
+ setTypeAnnotation(Tok, Classification.getType());
+ Tok.setAnnotationEndLoc(NameLoc);
+ Tok.setLocation(NameLoc);
+ PP.AnnotateCachedTokens(Tok);
break;
+ }
case Sema::NC_Expression:
ConsumeToken(); // the identifier
@@ -211,7 +217,20 @@ Retry:
if (AnnotateTemplateIdToken(
TemplateTy::make(Classification.getTemplateName()),
Classification.getTemplateNameKind(),
- SS, Id)) {
+ SS, Id, SourceLocation(),
+ /*AllowTypeAnnotation=*/false)) {
+ // Handle errors here by skipping up to the next semicolon or '}', and
+ // eat the semicolon if that's what stopped us.
+ SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
+ if (Tok.is(tok::semi))
+ ConsumeToken();
+ return StmtError();
+ }
+
+ // If the next token is '::', jump right into parsing a
+ // nested-name-specifier. We don't want to leave the template-id
+ // hanging.
+ if (NextToken().is(tok::coloncolon) && TryAnnotateCXXScopeToken(false)){
// Handle errors here by skipping up to the next semicolon or '}', and
// eat the semicolon if that's what stopped us.
SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index debc7404b9..ee4ef4263a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1255,7 +1255,8 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
assert(getLang().CPlusPlus &&
"Call sites of this function should be guarded by checking for C++");
- assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
+ assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+ (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)))&&
"Cannot be a type or scope token!");
CXXScopeSpec SS;