diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp | 473 |
1 files changed, 259 insertions, 214 deletions
diff --git a/gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp index 554ab24b02e..663c397ee04 100644 --- a/gnu/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp +++ b/gnu/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 @@ -306,13 +306,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, } // If the next token is not '<', we have a qualified-id that refers - // to a template name, such as T::template apply, but is not a + // to a template name, such as T::template apply, but is not a // template-id. if (Tok.isNot(tok::less)) { TPA.Revert(); break; - } - + } + // Commit to parsing the template-id. TPA.Commit(); TemplateTy Template; @@ -366,7 +366,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, TemplateId->RAngleLoc, CCLoc, EnteringContext)) { - SourceLocation StartLoc + SourceLocation StartLoc = SS.getBeginLoc().isValid()? SS.getBeginLoc() : TemplateId->TemplateNameLoc; SS.SetInvalid(SourceRange(StartLoc, CCLoc)); @@ -480,7 +480,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, UnqualifiedId TemplateName; TemplateName.setIdentifier(&II, Tok.getLocation()); bool MemberOfUnknownSpecialization; - if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, + if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false, TemplateName, ObjectType, @@ -500,22 +500,22 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, continue; } - if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && + if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && (IsTypename || IsTemplateArgumentList(1))) { - // We have something like t::getAs<T>, where getAs is a + // We have something like t::getAs<T>, where getAs is a // member of an unknown specialization. However, this will only // parse correctly as a template, so suggest the keyword 'template' // before 'getAs' and treat this as a dependent template name. unsigned DiagID = diag::err_missing_dependent_template_keyword; if (getLangOpts().MicrosoftExt) DiagID = diag::warn_missing_dependent_template_keyword; - + Diag(Tok.getLocation(), DiagID) << II.getName() << 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(); @@ -524,9 +524,9 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, return true; } else - return true; - - continue; + return true; + + continue; } } @@ -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. @@ -716,7 +719,7 @@ ExprResult Parser::TryParseLambdaExpression() { if (Next.is(tok::identifier) && After.is(tok::identifier)) { return ExprEmpty(); } - + // Here, we're stuck: lambda introducers and Objective-C message sends are // unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of @@ -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 @@ -773,7 +776,7 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, if (Tok.is(tok::code_completion) && !(getLangOpts().ObjC1 && Intro.Default == LCD_None && !Intro.Captures.empty())) { - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, + Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/false); cutOffParsing(); break; @@ -790,14 +793,14 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, if (getLangOpts().ObjC1 && first) Actions.CodeCompleteObjCMessageReceiver(getCurScope()); else - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, + Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/false); cutOffParsing(); break; } first = false; - + // Parse capture. LambdaCaptureKind Kind = LCK_ByCopy; LambdaCaptureInitKind InitKind = LambdaCaptureInitKind::NoInit; @@ -805,12 +808,13 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, IdentifierInfo *Id = nullptr; SourceLocation EllipsisLoc; ExprResult Init; + SourceLocation LocStart = Tok.getLocation(); if (Tok.is(tok::star)) { - Loc = ConsumeToken(); + Loc = ConsumeToken(); if (Tok.is(tok::kw_this)) { - ConsumeToken(); - Kind = LCK_StarThis; + ConsumeToken(); + Kind = LCK_StarThis; } else { return DiagResult(diag::err_expected_star_this_capture); } @@ -823,7 +827,7 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, ConsumeToken(); if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, + Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, /*AfterAmpersand=*/true); cutOffParsing(); break; @@ -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(); @@ -1083,7 +1090,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc, "lambda expression parsing"); - + // FIXME: Call into Actions to add any init-capture declarations to the // scope while parsing the lambda-declarator and compound-statement. @@ -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; @@ -1128,13 +1135,13 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // Parse parameter-declaration-clause. SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo; SourceLocation EllipsisLoc; - + if (Tok.isNot(tok::r_paren)) { Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth); ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); - // For a generic lambda, each 'auto' within the parameter declaration + // For a generic lambda, each 'auto' within the parameter declaration // clause creates a template type parameter, so increment the depth. - if (Actions.getCurGenericLambda()) + if (Actions.getCurGenericLambda()) ++CurTemplateDepthTracker; } T.consumeClose(); @@ -1154,7 +1161,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( SourceLocation ConstexprLoc; tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc, DeclEndLoc); - + addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); // Parse exception-specification[opt]. @@ -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 @@ -1375,7 +1376,7 @@ ExprResult Parser::ParseCXXCasts() { Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, LAngleBracketLoc, DeclaratorInfo, RAngleBracketLoc, - T.getOpenLocation(), Result.get(), + T.getOpenLocation(), Result.get(), T.getCloseLocation()); return Result; @@ -1476,7 +1477,7 @@ ExprResult Parser::ParseCXXUuidof() { return ExprError(); Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true, - Ty.get().getAsOpaquePtr(), + Ty.get().getAsOpaquePtr(), T.getCloseLocation()); } else { EnterExpressionEvaluationContext Unevaluated( @@ -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. /// @@ -1506,13 +1507,13 @@ ExprResult Parser::ParseCXXUuidof() { /// postfix-expression . pseudo-destructor-name /// postfix-expression -> pseudo-destructor-name /// -/// pseudo-destructor-name: -/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name -/// ::[opt] nested-name-specifier template simple-template-id :: -/// ~type-name +/// pseudo-destructor-name: +/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name +/// ::[opt] nested-name-specifier template simple-template-id :: +/// ~type-name /// ::[opt] nested-name-specifier[opt] ~type-name -/// -ExprResult +/// +ExprResult Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, @@ -1561,13 +1562,13 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc, Diag(Tok, diag::err_destructor_tilde_identifier); return ExprError(); } - + // Parse the second type. UnqualifiedId SecondTypeName; IdentifierInfo *Name = Tok.getIdentifierInfo(); SourceLocation NameLoc = ConsumeToken(); SecondTypeName.setIdentifier(Name, NameLoc); - + // If there is a '<', the second type name is a template-id. Parse // it as such. if (Tok.is(tok::less) && @@ -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, @@ -1804,7 +1821,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt, MaybeParseGNUAttributes(DeclaratorInfo); // Type-check the declaration itself. - DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), + DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), DeclaratorInfo); if (Dcl.isInvalid()) return Sema::ConditionError(); @@ -1892,10 +1909,10 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { getTypeAnnotation(Tok), Policy); else DS.SetTypeSpecError(); - + DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeAnnotationToken(); - + DS.Finish(Actions, Policy); return; } @@ -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,8 +2008,8 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { return false; } -/// \brief Finish parsing a C++ unqualified-id that is a template-id of -/// some form. +/// 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 /// operator-function-id is parsed by \c ParseUnqualifiedId() to determine @@ -2003,10 +2023,10 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { /// \param Name for constructor and destructor names, this is the actual /// identifier that may be a template-name. /// -/// \param NameLoc the location of the class-name in a constructor or +/// \param NameLoc the location of the class-name in a constructor or /// destructor. /// -/// \param EnteringContext whether we're entering the scope of the +/// \param EnteringContext whether we're entering the scope of the /// nested-name-specifier. /// /// \param ObjectType if this unqualified-id occurs within a member access @@ -2015,9 +2035,9 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { /// \param Id as input, describes the template-name or operator-function-id /// that precedes the '<'. If template arguments were parsed successfully, /// will be updated with the template-id. -/// +/// /// \param AssumeTemplateId When true, this routine will assume that the name -/// refers to a template without performing name lookup to verify. +/// refers to a template without performing name lookup to verify. /// /// \returns true if a parse error occurred, false otherwise. bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, @@ -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()) { @@ -2051,10 +2070,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateKWLoc.isValid(), Id, ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); - + if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && ObjectType && IsTemplateArgumentList()) { - // We have something like t->getAs<T>(), where getAs is a + // We have something like t->getAs<T>(), where getAs is a // member of an unknown specialization. However, this will only // parse correctly as a template, so suggest the keyword 'template' // before 'getAs' and treat this as a dependent template name. @@ -2075,22 +2094,22 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext, Template, /*AllowInjectedClassName*/ true); if (TNK == TNK_Non_template) - return true; + return true; } } break; - + case UnqualifiedIdKind::IK_ConstructorName: { UnqualifiedId TemplateName; bool MemberOfUnknownSpecialization; TemplateName.setIdentifier(Name, NameLoc); TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), - TemplateName, ObjectType, + TemplateName, ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); break; } - + case UnqualifiedIdKind::IK_DestructorName: { UnqualifiedId TemplateName; bool MemberOfUnknownSpecialization; @@ -2103,33 +2122,33 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, return true; } else { TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), - TemplateName, ObjectType, + TemplateName, ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); - + if (TNK == TNK_Non_template && !Id.DestructorName.get()) { Diag(NameLoc, diag::err_destructor_template_id) << Name << SS.getRange(); - return true; + return true; } } break; } - + default: return false; } - + if (TNK == TNK_Non_template) return false; - + // 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) { @@ -2164,16 +2183,16 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, /*IsCtorOrDtorName=*/true); if (Type.isInvalid()) return true; - + if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName) Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); else Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); - + 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 @@ -2204,7 +2223,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, /// \param SS The nested-name-specifier that preceded this unqualified-id. If /// non-empty, then we are parsing the unqualified-id of a qualified-id. /// -/// \param EnteringContext whether we are entering the scope of the +/// \param EnteringContext whether we are entering the scope of the /// nested-name-specifier. /// /// \param ObjectType if this unqualified-id occurs within a member access @@ -2217,10 +2236,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Result) { assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); - + // Consume the 'operator' keyword. SourceLocation KeywordLoc = ConsumeToken(); - + // Determine what kind of operator name we have. unsigned SymbolIdx = 0; SourceLocation SymbolLocations[3]; @@ -2240,7 +2259,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, T.consumeClose(); if (T.getCloseLocation().isInvalid()) return true; - + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = isNew? OO_Array_New : OO_Array_Delete; @@ -2249,7 +2268,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, } break; } - + #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ case tok::Token: \ SymbolLocations[SymbolIdx++] = ConsumeToken(); \ @@ -2257,7 +2276,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, break; #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) #include "clang/Basic/OperatorKinds.def" - + case tok::l_paren: { // Consume the '(' and ')'. BalancedDelimiterTracker T(*this, tok::l_paren); @@ -2265,13 +2284,13 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, T.consumeClose(); if (T.getCloseLocation().isInvalid()) return true; - + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = OO_Call; break; } - + case tok::l_square: { // Consume the '[' and ']'. BalancedDelimiterTracker T(*this, tok::l_square); @@ -2279,25 +2298,25 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, T.consumeClose(); if (T.getCloseLocation().isInvalid()) return true; - + SymbolLocations[SymbolIdx++] = T.getOpenLocation(); SymbolLocations[SymbolIdx++] = T.getCloseLocation(); Op = OO_Subscript; break; } - + case tok::code_completion: { // Code completion for the operator name. Actions.CodeCompleteOperatorName(getCurScope()); - cutOffParsing(); + cutOffParsing(); // Don't try to parse any further. return true; } - + default: break; } - + if (Op != OO_None) { // We have parsed an operator-function-id. Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); @@ -2390,12 +2409,12 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // // conversion-declarator: // ptr-operator conversion-declarator[opt] - + // Parse the type-specifier-seq. DeclSpec DS(AttrFactory); if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? return true; - + // Parse the conversion-declarator, which is merely a sequence of // ptr-operators. Declarator D(DS, DeclaratorContext::ConversionIdContext); @@ -2405,14 +2424,14 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); if (Ty.isInvalid()) return true; - + // Note that this is a conversion-function-id. - Result.setConversionFunctionId(KeywordLoc, Ty.get(), + Result.setConversionFunctionId(KeywordLoc, Ty.get(), D.getSourceRange().getEnd()); - return false; + 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 @@ -2429,7 +2448,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, /// \param SS The nested-name-specifier that preceded this unqualified-id. If /// non-empty, then we are parsing the unqualified-id of a qualified-id. /// -/// \param EnteringContext whether we are entering the scope of the +/// \param EnteringContext whether we are entering the scope of the /// nested-name-specifier. /// /// \param AllowDestructorName whether we allow parsing of a destructor name. @@ -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: @@ -2477,13 +2503,13 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, } ParsedTemplateTy TemplateName; - if (AllowConstructorName && + 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() && @@ -2493,24 +2519,31 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, Result.setDeductionGuideName(TemplateName, IdLoc); } else { // We have parsed an identifier. - Result.setIdentifier(Id, IdLoc); + Result.setIdentifier(Id, IdLoc); } // 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; } - + // unqualified-id: // template-id (already parsed and annotated) if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); - // If the template-name names the current class, then this is a constructor + // If the template-name names the current class, then this is a constructor if (AllowConstructorName && TemplateId->Name && Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { if (SS.isSet()) { @@ -2518,16 +2551,16 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, // is taken as the constructor name where a constructor can be // declared. Thus, the template arguments are extraneous, so // complain about them and remove them entirely. - Diag(TemplateId->TemplateNameLoc, + Diag(TemplateId->TemplateNameLoc, diag::err_out_of_line_constructor_template_id) << 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,41 +2575,55 @@ 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; } - + // unqualified-id: // operator-function-id // conversion-function-id if (Tok.is(tok::kw_operator)) { if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) return true; - + // If we have an operator-function-id or a literal-operator-id and the next // token is a '<', we may have a - // + // // 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; } - - if (getLangOpts().CPlusPlus && + + if (getLangOpts().CPlusPlus && (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { // C++ [expr.unary.op]p10: - // There is an ambiguity in the unary-expression ~X(), where X is a - // class-name. The ambiguity is resolved in favor of treating ~ as a + // There is an ambiguity in the unary-expression ~X(), where X is a + // class-name. The ambiguity is resolved in favor of treating ~ as a // unary complement rather than treating ~X as referring to a destructor. - + // Parse the '~'. SourceLocation TildeLoc = ConsumeToken(); @@ -2590,7 +2637,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, } return true; } - + // Parse the class-name. if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_destructor_tilde_identifier); @@ -2633,16 +2680,15 @@ 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. - ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, + ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, ClassNameLoc, getCurScope(), SS, ObjectType, EnteringContext); @@ -2652,7 +2698,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); return false; } - + Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus; return true; @@ -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: @@ -2973,7 +3018,7 @@ ExprResult Parser::ParseTypeTrait() { unsigned Arity = TypeTraitArity(Kind); SourceLocation Loc = ConsumeToken(); - + BalancedDelimiterTracker Parens(*this, tok::l_paren); if (Parens.expectAndConsume()) return ExprError(); @@ -2995,7 +3040,7 @@ ExprResult Parser::ParseTypeTrait() { return ExprError(); } } - + // Add this type to the list of arguments. Args.push_back(Ty.get()); } while (TryConsumeToken(tok::comma)); @@ -3221,7 +3266,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ExprType = SimpleExpr; Result = ParseExpression(); if (!Result.isInvalid() && Tok.is(tok::r_paren)) - Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), + Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), Tok.getLocation(), Result.get()); // Match the ')'. |
