diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp | 285 | 
1 files changed, 165 insertions, 120 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp index 554ab24b02e1..26e75999518a 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp @@ -100,7 +100,7 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,               /*AtDigraph*/false);  } -/// \brief Parse global scope or nested-name-specifier if present. +/// Parse global scope or nested-name-specifier if present.  ///  /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which  /// may be preceded by '::'). Note that this routine will not parse ::new or @@ -515,7 +515,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,            << FixItHint::CreateInsertion(Tok.getLocation(), "template ");          if (TemplateNameKind TNK = Actions.ActOnDependentTemplateName( -                getCurScope(), SS, SourceLocation(), TemplateName, ObjectType, +                getCurScope(), SS, Tok.getLocation(), TemplateName, ObjectType,                  EnteringContext, Template, /*AllowInjectedClassName*/ true)) {            // Consume the identifier.            ConsumeToken(); @@ -553,7 +553,7 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe                           /*AllowDestructorName=*/false,                           /*AllowConstructorName=*/false,                           /*AllowDeductionGuide=*/false, -                         /*ObjectType=*/nullptr, TemplateKWLoc, Name)) +                         /*ObjectType=*/nullptr, &TemplateKWLoc, Name))      return ExprError();    // This is only the direct operand of an & operator if it is not @@ -561,10 +561,13 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe    if (isAddressOfOperand && isPostfixExpressionSuffixStart())      isAddressOfOperand = false; -  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, -                                   Tok.is(tok::l_paren), isAddressOfOperand, -                                   nullptr, /*IsInlineAsmIdentifier=*/false, -                                   &Replacement); +  ExprResult E = Actions.ActOnIdExpression( +      getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren), +      isAddressOfOperand, nullptr, /*IsInlineAsmIdentifier=*/false, +      &Replacement); +  if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less)) +    checkPotentialAngleBracket(E); +  return E;  }  /// ParseCXXIdExpression - Handle id-expression. @@ -730,7 +733,7 @@ ExprResult Parser::TryParseLambdaExpression() {    return ParseLambdaExpressionAfterIntroducer(Intro);  } -/// \brief Parse a lambda introducer. +/// Parse a lambda introducer.  /// \param Intro A LambdaIntroducer filled in with information about the  ///        contents of the lambda-introducer.  /// \param SkippedInits If non-null, we are disambiguating between an Obj-C @@ -805,6 +808,7 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,      IdentifierInfo *Id = nullptr;      SourceLocation EllipsisLoc;      ExprResult Init; +    SourceLocation LocStart = Tok.getLocation();      if (Tok.is(tok::star)) {        Loc = ConsumeToken();  @@ -978,8 +982,11 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,            Loc, Kind == LCK_ByRef, Id, InitKind, InitExpr);        Init = InitExpr;      } + +    SourceLocation LocEnd = PrevTokLocation; +      Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, -                     InitCaptureType); +                     InitCaptureType, SourceRange(LocStart, LocEnd));    }    T.consumeClose(); @@ -1106,12 +1113,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(    // after '(...)'. nvcc doesn't accept this.    auto WarnIfHasCUDATargetAttr = [&] {      if (getLangOpts().CUDA) -      for (auto *A = Attr.getList(); A != nullptr; A = A->getNext()) -        if (A->getKind() == AttributeList::AT_CUDADevice || -            A->getKind() == AttributeList::AT_CUDAHost || -            A->getKind() == AttributeList::AT_CUDAGlobal) -          Diag(A->getLoc(), diag::warn_cuda_attr_lambda_position) -              << A->getName()->getName(); +      for (const ParsedAttr &A : Attr) +        if (A.getKind() == ParsedAttr::AT_CUDADevice || +            A.getKind() == ParsedAttr::AT_CUDAHost || +            A.getKind() == ParsedAttr::AT_CUDAGlobal) +          Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position) +              << A.getName()->getName();    };    TypeResult TrailingReturnType; @@ -1183,7 +1190,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(      if (Tok.is(tok::arrow)) {        FunLocalRangeEnd = Tok.getLocation();        SourceRange Range; -      TrailingReturnType = ParseTrailingReturnType(Range); +      TrailingReturnType = +          ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false);        if (Range.getEnd().isValid())          DeclEndLoc = Range.getEnd();      } @@ -1193,29 +1201,23 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(      WarnIfHasCUDATargetAttr();      SourceLocation NoLoc; -    D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, -                                           /*isAmbiguous=*/false, -                                           LParenLoc, -                                           ParamInfo.data(), ParamInfo.size(), -                                           EllipsisLoc, RParenLoc, -                                           DS.getTypeQualifiers(), -                                           /*RefQualifierIsLValueRef=*/true, -                                           /*RefQualifierLoc=*/NoLoc, -                                           /*ConstQualifierLoc=*/NoLoc, -                                           /*VolatileQualifierLoc=*/NoLoc, -                                           /*RestrictQualifierLoc=*/NoLoc, -                                           MutableLoc, -                                           ESpecType, ESpecRange, -                                           DynamicExceptions.data(), -                                           DynamicExceptionRanges.data(), -                                           DynamicExceptions.size(), -                                           NoexceptExpr.isUsable() ? -                                             NoexceptExpr.get() : nullptr, -                                           /*ExceptionSpecTokens*/nullptr, -                                           /*DeclsInPrototype=*/None, -                                           LParenLoc, FunLocalRangeEnd, D, -                                           TrailingReturnType), -                  Attr, DeclEndLoc); +    D.AddTypeInfo(DeclaratorChunk::getFunction( +                      /*hasProto=*/true, +                      /*isAmbiguous=*/false, LParenLoc, ParamInfo.data(), +                      ParamInfo.size(), EllipsisLoc, RParenLoc, +                      DS.getTypeQualifiers(), +                      /*RefQualifierIsLValueRef=*/true, +                      /*RefQualifierLoc=*/NoLoc, +                      /*ConstQualifierLoc=*/NoLoc, +                      /*VolatileQualifierLoc=*/NoLoc, +                      /*RestrictQualifierLoc=*/NoLoc, MutableLoc, ESpecType, +                      ESpecRange, DynamicExceptions.data(), +                      DynamicExceptionRanges.data(), DynamicExceptions.size(), +                      NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, +                      /*ExceptionSpecTokens*/ nullptr, +                      /*DeclsInPrototype=*/None, LParenLoc, FunLocalRangeEnd, D, +                      TrailingReturnType), +                  std::move(Attr), DeclEndLoc);    } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,                           tok::kw_constexpr) ||               (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { @@ -1253,7 +1255,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(      // Parse the return type, if there is one.      if (Tok.is(tok::arrow)) {        SourceRange Range; -      TrailingReturnType = ParseTrailingReturnType(Range); +      TrailingReturnType = +          ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false);        if (Range.getEnd().isValid())          DeclEndLoc = Range.getEnd();      } @@ -1261,31 +1264,29 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(      WarnIfHasCUDATargetAttr();      SourceLocation NoLoc; -    D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, -                                               /*isAmbiguous=*/false, -                                               /*LParenLoc=*/NoLoc, -                                               /*Params=*/nullptr, -                                               /*NumParams=*/0, -                                               /*EllipsisLoc=*/NoLoc, -                                               /*RParenLoc=*/NoLoc, -                                               /*TypeQuals=*/0, -                                               /*RefQualifierIsLValueRef=*/true, -                                               /*RefQualifierLoc=*/NoLoc, -                                               /*ConstQualifierLoc=*/NoLoc, -                                               /*VolatileQualifierLoc=*/NoLoc, -                                               /*RestrictQualifierLoc=*/NoLoc, -                                               MutableLoc, -                                               EST_None, -                                               /*ESpecRange=*/SourceRange(), -                                               /*Exceptions=*/nullptr, -                                               /*ExceptionRanges=*/nullptr, -                                               /*NumExceptions=*/0, -                                               /*NoexceptExpr=*/nullptr, -                                               /*ExceptionSpecTokens=*/nullptr, -                                               /*DeclsInPrototype=*/None, -                                               DeclLoc, DeclEndLoc, D, -                                               TrailingReturnType), -                  Attr, DeclEndLoc); +    D.AddTypeInfo(DeclaratorChunk::getFunction( +                      /*hasProto=*/true, +                      /*isAmbiguous=*/false, +                      /*LParenLoc=*/NoLoc, +                      /*Params=*/nullptr, +                      /*NumParams=*/0, +                      /*EllipsisLoc=*/NoLoc, +                      /*RParenLoc=*/NoLoc, +                      /*TypeQuals=*/0, +                      /*RefQualifierIsLValueRef=*/true, +                      /*RefQualifierLoc=*/NoLoc, +                      /*ConstQualifierLoc=*/NoLoc, +                      /*VolatileQualifierLoc=*/NoLoc, +                      /*RestrictQualifierLoc=*/NoLoc, MutableLoc, EST_None, +                      /*ESpecRange=*/SourceRange(), +                      /*Exceptions=*/nullptr, +                      /*ExceptionRanges=*/nullptr, +                      /*NumExceptions=*/0, +                      /*NoexceptExpr=*/nullptr, +                      /*ExceptionSpecTokens=*/nullptr, +                      /*DeclsInPrototype=*/None, DeclLoc, DeclEndLoc, D, +                      TrailingReturnType), +                  std::move(Attr), DeclEndLoc);    }    // FIXME: Rename BlockScope -> ClosureScope if we decide to continue using @@ -1498,7 +1499,7 @@ ExprResult Parser::ParseCXXUuidof() {    return Result;  } -/// \brief Parse a C++ pseudo-destructor expression after the base, +/// Parse a C++ pseudo-destructor expression after the base,  /// . or -> operator, and nested-name-specifier have already been  /// parsed.  /// @@ -1619,7 +1620,7 @@ ExprResult Parser::ParseThrowExpression() {    }  } -/// \brief Parse the C++ Coroutines co_yield expression. +/// Parse the C++ Coroutines co_yield expression.  ///  ///       co_yield-expression:  ///         'co_yield' assignment-expression[opt] @@ -1672,9 +1673,9 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {      if (Init.isInvalid())        return Init;      Expr *InitList = Init.get(); -    return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(), -                                             MultiExprArg(&InitList, 1), -                                             SourceLocation()); +    return Actions.ActOnCXXTypeConstructExpr( +        TypeRep, InitList->getLocStart(), MultiExprArg(&InitList, 1), +        InitList->getLocEnd(), /*ListInitialization=*/true);    } else {      BalancedDelimiterTracker T(*this, tok::l_paren);      T.consumeOpen(); @@ -1702,9 +1703,9 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {      assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&             "Unexpected number of commas!"); -    return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),  -                                             Exprs, -                                             T.getCloseLocation()); +    return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), +                                             Exprs, T.getCloseLocation(), +                                             /*ListInitialization=*/false);    }  } @@ -1733,6 +1734,8 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {  Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,                                                  SourceLocation Loc,                                                  Sema::ConditionKind CK) { +  ParenBraceBracketBalancer BalancerRAIIObj(*this); +    if (Tok.is(tok::code_completion)) {      Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);      cutOffParsing(); @@ -1742,17 +1745,34 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,    ParsedAttributesWithRange attrs(AttrFactory);    MaybeParseCXX11Attributes(attrs); +  const auto WarnOnInit = [this, &CK] { +    Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 +                                ? diag::warn_cxx14_compat_init_statement +                                : diag::ext_init_statement) +        << (CK == Sema::ConditionKind::Switch); +  }; +    // Determine what kind of thing we have.    switch (isCXXConditionDeclarationOrInitStatement(InitStmt)) {    case ConditionOrInitStatement::Expression: {      ProhibitAttributes(attrs); +    // We can have an empty expression here. +    //   if (; true); +    if (InitStmt && Tok.is(tok::semi)) { +      WarnOnInit(); +      SourceLocation SemiLoc = ConsumeToken(); +      *InitStmt = Actions.ActOnNullStmt(SemiLoc); +      return ParseCXXCondition(nullptr, Loc, CK); +    } +      // Parse the expression.      ExprResult Expr = ParseExpression(); // expression      if (Expr.isInvalid())        return Sema::ConditionError();      if (InitStmt && Tok.is(tok::semi)) { +      WarnOnInit();        *InitStmt = Actions.ActOnExprStmt(Expr.get());        ConsumeToken();        return ParseCXXCondition(nullptr, Loc, CK); @@ -1762,10 +1782,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,    }    case ConditionOrInitStatement::InitStmtDecl: { -    Diag(Tok.getLocation(), getLangOpts().CPlusPlus17 -                                ? diag::warn_cxx14_compat_init_statement -                                : diag::ext_init_statement) -        << (CK == Sema::ConditionKind::Switch); +    WarnOnInit();      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;      DeclGroupPtrTy DG =          ParseSimpleDeclaration(DeclaratorContext::InitStmtContext, DeclEnd, @@ -1946,6 +1963,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {    case tok::kw_wchar_t:      DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);      break; +  case tok::kw_char8_t: +    DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy); +    break;    case tok::kw_char16_t:      DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);      break; @@ -1988,7 +2008,7 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {    return false;  } -/// \brief Finish parsing a C++ unqualified-id that is a template-id of +/// Finish parsing a C++ unqualified-id that is a template-id of  /// some form.   ///  /// This routine is invoked when a '<' is encountered after an identifier or @@ -2028,9 +2048,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,                                            ParsedType ObjectType,                                            UnqualifiedId &Id,                                            bool AssumeTemplateId) { -  assert((AssumeTemplateId || Tok.is(tok::less)) && -         "Expected '<' to finish parsing a template-id"); -   +  assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id"); +    TemplateTy Template;    TemplateNameKind TNK = TNK_Non_template;    switch (Id.getKind()) { @@ -2126,10 +2145,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,    // Parse the enclosed template argument list.    SourceLocation LAngleLoc, RAngleLoc;    TemplateArgList TemplateArgs; -  if (Tok.is(tok::less) && ParseTemplateIdAfterTemplateName( -                               true, LAngleLoc, TemplateArgs, RAngleLoc)) +  if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, +                                       RAngleLoc))      return true; -   +    if (Id.getKind() == UnqualifiedIdKind::IK_Identifier ||        Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||        Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) { @@ -2173,7 +2192,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,    return false;  } -/// \brief Parse an operator-function-id or conversion-function-id as part +/// Parse an operator-function-id or conversion-function-id as part  /// of a C++ unqualified-id.  ///  /// This routine is responsible only for parsing the operator-function-id or @@ -2412,7 +2431,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,    return false;    } -/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the +/// Parse a C++ unqualified-id (or a C identifier), which describes the  /// name of an entity.  ///  /// \code @@ -2449,16 +2468,23 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,                                  bool AllowConstructorName,                                  bool AllowDeductionGuide,                                  ParsedType ObjectType, -                                SourceLocation& TemplateKWLoc, +                                SourceLocation *TemplateKWLoc,                                  UnqualifiedId &Result) { +  if (TemplateKWLoc) +    *TemplateKWLoc = SourceLocation();    // Handle 'A::template B'. This is for template-ids which have not    // already been annotated by ParseOptionalCXXScopeSpecifier().    bool TemplateSpecified = false; -  if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) && -      (ObjectType || SS.isSet())) { -    TemplateSpecified = true; -    TemplateKWLoc = ConsumeToken(); +  if (Tok.is(tok::kw_template)) { +    if (TemplateKWLoc && (ObjectType || SS.isSet())) { +      TemplateSpecified = true; +      *TemplateKWLoc = ConsumeToken(); +    } else { +      SourceLocation TemplateLoc = ConsumeToken(); +      Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) +        << FixItHint::CreateRemoval(TemplateLoc); +    }    }    // unqualified-id: @@ -2480,10 +2506,10 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,      if (AllowConstructorName &&           Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {        // We have parsed a constructor name. -      ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, false, -                                          false, nullptr, -                                          /*IsCtorOrDtorName=*/true, -                                          /*NonTrivialTypeSourceInfo=*/true); +      ParsedType Ty = Actions.getConstructorName(*Id, IdLoc, getCurScope(), SS, +                                                 EnteringContext); +      if (!Ty) +        return true;        Result.setConstructorName(Ty, IdLoc, IdLoc);      } else if (getLangOpts().CPlusPlus17 &&                 AllowDeductionGuide && SS.isEmpty() && @@ -2497,11 +2523,18 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,      }      // If the next token is a '<', we may have a template. -    if (TemplateSpecified || Tok.is(tok::less)) -      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, Id, IdLoc, -                                          EnteringContext, ObjectType, -                                          Result, TemplateSpecified); -     +    TemplateTy Template; +    if (Tok.is(tok::less)) +      return ParseUnqualifiedIdTemplateId( +          SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc, +          EnteringContext, ObjectType, Result, TemplateSpecified); +    else if (TemplateSpecified && +             Actions.ActOnDependentTemplateName( +                 getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, +                 EnteringContext, Template, +                 /*AllowInjectedClassName*/ true) == TNK_Non_template) +      return true; +      return false;    } @@ -2523,11 +2556,11 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,            << TemplateId->Name            << FixItHint::CreateRemoval(                      SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); -        ParsedType Ty = -            Actions.getTypeName(*TemplateId->Name, TemplateId->TemplateNameLoc, -                                getCurScope(), &SS, false, false, nullptr, -                                /*IsCtorOrDtorName=*/true, -                                /*NontrivialTypeSourceInfo=*/true); +        ParsedType Ty = Actions.getConstructorName( +            *TemplateId->Name, TemplateId->TemplateNameLoc, getCurScope(), SS, +            EnteringContext); +        if (!Ty) +          return true;          Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,                                    TemplateId->RAngleLoc);          ConsumeAnnotationToken(); @@ -2542,7 +2575,14 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,      // We have already parsed a template-id; consume the annotation token as      // our unqualified-id.      Result.setTemplateId(TemplateId); -    TemplateKWLoc = TemplateId->TemplateKWLoc; +    SourceLocation TemplateLoc = TemplateId->TemplateKWLoc; +    if (TemplateLoc.isValid()) { +      if (TemplateKWLoc && (ObjectType || SS.isSet())) +        *TemplateKWLoc = TemplateLoc; +      else +        Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id) +            << FixItHint::CreateRemoval(TemplateLoc); +    }      ConsumeAnnotationToken();      return false;    } @@ -2559,13 +2599,20 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,      //       //   template-id:      //     operator-function-id < template-argument-list[opt] > +    TemplateTy Template;      if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||           Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) && -        (TemplateSpecified || Tok.is(tok::less))) -      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, -                                          nullptr, SourceLocation(), -                                          EnteringContext, ObjectType, -                                          Result, TemplateSpecified); +        Tok.is(tok::less)) +      return ParseUnqualifiedIdTemplateId( +          SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr, +          SourceLocation(), EnteringContext, ObjectType, Result, +          TemplateSpecified); +    else if (TemplateSpecified && +             Actions.ActOnDependentTemplateName( +                 getCurScope(), SS, *TemplateKWLoc, Result, ObjectType, +                 EnteringContext, Template, +                 /*AllowInjectedClassName*/ true) == TNK_Non_template) +      return true;      return false;    } @@ -2633,12 +2680,11 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,      IdentifierInfo *ClassName = Tok.getIdentifierInfo();      SourceLocation ClassNameLoc = ConsumeToken(); -    if (TemplateSpecified || Tok.is(tok::less)) { +    if (Tok.is(tok::less)) {        Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc); -      return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc, -                                          ClassName, ClassNameLoc, -                                          EnteringContext, ObjectType, -                                          Result, TemplateSpecified); +      return ParseUnqualifiedIdTemplateId( +          SS, TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName, +          ClassNameLoc, EnteringContext, ObjectType, Result, TemplateSpecified);      }      // Note that this is a destructor name. @@ -2839,10 +2885,9 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {      D.AddTypeInfo(DeclaratorChunk::getArray(0,                                              /*static=*/false, /*star=*/false, -                                            Size.get(), -                                            T.getOpenLocation(), +                                            Size.get(), T.getOpenLocation(),                                              T.getCloseLocation()), -                  Attrs, T.getCloseLocation()); +                  std::move(Attrs), T.getCloseLocation());      if (T.getCloseLocation().isInvalid())        return; @@ -2957,7 +3002,7 @@ static unsigned TypeTraitArity(tok::TokenKind kind) {    }  } -/// \brief Parse the built-in type-trait pseudo-functions that allow  +/// Parse the built-in type-trait pseudo-functions that allow   /// implementation of the TR1/C++11 type traits templates.  ///  ///       primary-expression:  | 
