diff options
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index a4dcdb1e2a09..6cf7b6d3dc55 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -122,20 +122,15 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, return nullptr; } - ParamLists.push_back( - Actions.ActOnTemplateParameterList(CurTemplateDepthTracker.getDepth(), - ExportLoc, - TemplateLoc, LAngleLoc, - TemplateParams, RAngleLoc)); - + ExprResult OptionalRequiresClauseConstraintER; if (!TemplateParams.empty()) { isSpecialization = false; ++CurTemplateDepthTracker; if (TryConsumeToken(tok::kw_requires)) { - ExprResult ER = + OptionalRequiresClauseConstraintER = Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); - if (!ER.isUsable()) { + if (!OptionalRequiresClauseConstraintER.isUsable()) { // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); TryConsumeToken(tok::semi); @@ -145,8 +140,15 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, } else { LastParamListWasEmpty = true; } + + ParamLists.push_back(Actions.ActOnTemplateParameterList( + CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc, + TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get())); } while (Tok.isOneOf(tok::kw_export, tok::kw_template)); + unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope; + ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization); + // Parse the actual template declaration. return ParseSingleDeclarationAfterTemplate(Context, ParsedTemplateInfo(&ParamLists, @@ -209,11 +211,15 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Tok.is(tok::semi)) { ProhibitAttributes(prefixAttrs); DeclEnd = ConsumeToken(); + RecordDecl *AnonRecord = nullptr; Decl *Decl = Actions.ParsedFreeStandingDeclSpec( getCurScope(), AS, DS, TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams : MultiTemplateParamsArg(), - TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation); + TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation, + AnonRecord); + assert(!AnonRecord && + "Anonymous unions/structs should not be valid with template"); DS.complete(Decl); return Decl; } @@ -280,7 +286,7 @@ Parser::ParseSingleDeclarationAfterTemplate( TemplateParameterLists FakedParamLists; FakedParamLists.push_back(Actions.ActOnTemplateParameterList( 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, - LAngleLoc)); + LAngleLoc, nullptr)); return ParseFunctionDefinition( DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists, @@ -631,7 +637,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { Actions.ActOnTemplateParameterList(Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams, - RAngleLoc); + RAngleLoc, nullptr); // Grab a default argument (if available). // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before @@ -827,6 +833,7 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, } // Strip the initial '>' from the token. + Token PrevTok = Tok; if (RemainingToken == tok::equal && Next.is(tok::equal) && areTokensAdjacent(Tok, Next)) { // Join two adjacent '=' tokens into one, for cases like: @@ -843,6 +850,21 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, PP.getSourceManager(), getLangOpts())); + // The advance from '>>' to '>' in a ObjectiveC template argument list needs + // to be properly reflected in the token cache to allow correct interaction + // between annotation and backtracking. + if (ObjCGenericList && PrevTok.getKind() == tok::greatergreater && + RemainingToken == tok::greater && PP.IsPreviousCachedToken(PrevTok)) { + PrevTok.setKind(RemainingToken); + PrevTok.setLength(1); + // Break tok::greatergreater into two tok::greater but only add the second + // one in case the client asks to consume the last token. + if (ConsumeLastToken) + PP.ReplacePreviousCachedToken({PrevTok, Tok}); + else + PP.ReplacePreviousCachedToken({PrevTok}); + } + if (!ConsumeLastToken) { // Since we're not supposed to consume the '>' token, we need to push // this token and revert the current token back to the '>'. @@ -1061,7 +1083,7 @@ void Parser::AnnotateTemplateIdTokenAsType() { TemplateId->RAngleLoc); // Create the new "type" annotation token. Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get()); + setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get()); if (TemplateId->SS.isNotEmpty()) // it was a C++ qualified type name. Tok.setLocation(TemplateId->SS.getBeginLoc()); // End location stays the same @@ -1094,9 +1116,9 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // followed by a token that terminates a template argument, such as ',', // '>', or (in some cases) '>>'. CXXScopeSpec SS; // nested-name-specifier, if present - ParseOptionalCXXScopeSpecifier(SS, ParsedType(), + ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false); - + ParsedTemplateArgument Result; SourceLocation EllipsisLoc; if (SS.isSet() && Tok.is(tok::kw_template)) { @@ -1117,11 +1139,10 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // template argument. TemplateTy Template; if (isEndOfTemplateArgument(Tok) && - Actions.ActOnDependentTemplateName(getCurScope(), - SS, TemplateKWLoc, Name, - /*ObjectType=*/ ParsedType(), - /*EnteringContext=*/false, - Template)) + Actions.ActOnDependentTemplateName( + getCurScope(), SS, TemplateKWLoc, Name, + /*ObjectType=*/nullptr, + /*EnteringContext=*/false, Template)) Result = ParsedTemplateArgument(SS, Template, Name.StartLocation); } } else if (Tok.is(tok::identifier)) { @@ -1135,13 +1156,11 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { if (isEndOfTemplateArgument(Tok)) { bool MemberOfUnknownSpecialization; - TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, - /*hasTemplateKeyword=*/false, - Name, - /*ObjectType=*/ ParsedType(), - /*EnteringContext=*/false, - Template, - MemberOfUnknownSpecialization); + TemplateNameKind TNK = Actions.isTemplateName( + getCurScope(), SS, + /*hasTemplateKeyword=*/false, Name, + /*ObjectType=*/nullptr, + /*EnteringContext=*/false, Template, MemberOfUnknownSpecialization); if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) { // We have an id-expression that refers to a class template or // (C++0x) alias template. @@ -1352,7 +1371,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { // Append the current token at the end of the new token stream so that it // doesn't get lost. LPT.Toks.push_back(Tok); - PP.EnterTokenStream(LPT.Toks.data(), LPT.Toks.size(), true, false); + PP.EnterTokenStream(LPT.Toks, true); // Consume the previously pushed token. ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); |