From: Argyrios Kyrtzidis Date: Fri, 6 Aug 2010 09:47:24 +0000 (+0000) Subject: Introduce a new token kind 'cxx_defaultarg_end' to mark the end of C++ default argume... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b602adf9798eaf13850efaf8ed41c69d3cf7da6;p=clang Introduce a new token kind 'cxx_defaultarg_end' to mark the end of C++ default arguments that were part of lexed method declarations. This avoid interference with tokens coming after the point where the default arg tokens were 'injected', e.g. for typedef struct Inst { void m(int x=0); } *InstPtr; when parsing '0' the next token would be '*' and things would be messed up. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110436 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index b16b82854b..a20260381a 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -96,6 +96,7 @@ TOK(unknown) // Not a token. TOK(eof) // End of file. TOK(eom) // End of macro (end of line inside a macro). TOK(code_completion) // Code completion marker +TOK(cxx_defaultarg_end) // C++ default argument end marker // C99 6.4.9: Comments. TOK(comment) // Comment (only in -E -C[C] mode) diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index 62a7ecd5d4..9f12ab501e 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -142,9 +142,13 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { OwningExprResult DefArgResult(ParseAssignmentExpression()); if (DefArgResult.isInvalid()) Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); - else + else { + assert(Tok.is(tok::cxx_defaultarg_end) && + "We didn't parse the whole default arg!"); + ConsumeToken(); // Consume tok::cxx_defaultarg_end. Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, move(DefArgResult)); + } assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, Tok.getLocation()) && diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6f65640d60..65b4fb77ad 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3085,9 +3085,17 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, delete DefArgToks; DefArgToks = 0; Actions.ActOnParamDefaultArgumentError(Param); - } else + } else { + // Mark the end of the default argument so that we know when to + // stop when we parse it later on. + Token DefArgEnd; + DefArgEnd.startToken(); + DefArgEnd.setKind(tok::cxx_defaultarg_end); + DefArgEnd.setLocation(Tok.getLocation()); + DefArgToks->push_back(DefArgEnd); Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, (*DefArgToks)[1].getLocation()); + } } else { // Consume the '='. ConsumeToken(); diff --git a/test/Parser/cxx-default-args.cpp b/test/Parser/cxx-default-args.cpp index a084fb0812..a7bb5eeda8 100644 --- a/test/Parser/cxx-default-args.cpp +++ b/test/Parser/cxx-default-args.cpp @@ -7,3 +7,6 @@ class C { void m(int x = undecl + 0); // expected-error {{use of undeclared identifier 'undecl'}} }; +typedef struct Inst { + void m(int x=0); +} *InstPtr;