diff options
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 203 |
1 files changed, 133 insertions, 70 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index afac257..2f615e1 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -96,6 +96,45 @@ void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType, /*AtDigraph*/false); } +/// \brief Emits an error for a left parentheses after a double colon. +/// +/// When a '(' is found after a '::', emit an error. Attempt to fix the token +/// stream by removing the '(', and the matching ')' if it found. +void Parser::CheckForLParenAfterColonColon() { + if (!Tok.is(tok::l_paren)) + return; + + SourceLocation l_parenLoc = ConsumeParen(), r_parenLoc; + Token Tok1 = getCurToken(); + if (!Tok1.is(tok::identifier) && !Tok1.is(tok::star)) + return; + + if (Tok1.is(tok::identifier)) { + Token Tok2 = GetLookAheadToken(1); + if (Tok2.is(tok::r_paren)) { + ConsumeToken(); + PP.EnterToken(Tok1); + r_parenLoc = ConsumeParen(); + } + } else if (Tok1.is(tok::star)) { + Token Tok2 = GetLookAheadToken(1); + if (Tok2.is(tok::identifier)) { + Token Tok3 = GetLookAheadToken(2); + if (Tok3.is(tok::r_paren)) { + ConsumeToken(); + ConsumeToken(); + PP.EnterToken(Tok2); + PP.EnterToken(Tok1); + r_parenLoc = ConsumeParen(); + } + } + } + + Diag(l_parenLoc, diag::err_paren_after_colon_colon) + << FixItHint::CreateRemoval(l_parenLoc) + << FixItHint::CreateRemoval(r_parenLoc); +} + /// \brief Parse global scope or nested-name-specifier if present. /// /// Parses a C++ global scope specifier ('::') or nested-name-specifier (which @@ -160,7 +199,9 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // '::' - Global scope qualifier. if (Actions.ActOnCXXGlobalScopeSpecifier(getCurScope(), ConsumeToken(), SS)) return true; - + + CheckForLParenAfterColonColon(); + HasScopeSpecifier = true; } @@ -301,8 +342,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, HasScopeSpecifier = true; - ASTTemplateArgsPtr TemplateArgsPtr(Actions, - TemplateId->getTemplateArgs(), + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs); if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), @@ -372,6 +412,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, "NextToken() not working properly!"); SourceLocation CCLoc = ConsumeToken(); + CheckForLParenAfterColonColon(); + HasScopeSpecifier = true; if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc, ObjectType, EnteringContext, SS)) @@ -757,10 +799,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( Scope::FunctionPrototypeScope | Scope::DeclScope); - SourceLocation DeclLoc, DeclEndLoc; + SourceLocation DeclEndLoc; BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - DeclLoc = T.getOpenLocation(); + SourceLocation LParenLoc = T.getOpenLocation(); // Parse parameter-declaration-clause. ParsedAttributes Attr(AttrFactory); @@ -771,7 +813,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc); T.consumeClose(); - DeclEndLoc = T.getCloseLocation(); + SourceLocation RParenLoc = T.getCloseLocation(); + DeclEndLoc = RParenLoc; // Parse 'mutable'[opt]. SourceLocation MutableLoc; @@ -797,9 +840,12 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // Parse attribute-specifier[opt]. MaybeParseCXX0XAttributes(Attr, &DeclEndLoc); + SourceLocation FunLocalRangeEnd = DeclEndLoc; + // Parse trailing-return-type[opt]. TypeResult TrailingReturnType; if (Tok.is(tok::arrow)) { + FunLocalRangeEnd = Tok.getLocation(); SourceRange Range; TrailingReturnType = ParseTrailingReturnType(Range); if (Range.getEnd().isValid()) @@ -808,15 +854,17 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( PrototypeScope.Exit(); + SourceLocation NoLoc; D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, - /*isVariadic=*/EllipsisLoc.isValid(), - /*isAmbiguous=*/false, EllipsisLoc, + /*isAmbiguous=*/false, + LParenLoc, ParamInfo.data(), ParamInfo.size(), + EllipsisLoc, RParenLoc, DS.getTypeQualifiers(), /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/SourceLocation(), - /*ConstQualifierLoc=*/SourceLocation(), - /*VolatileQualifierLoc=*/SourceLocation(), + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, MutableLoc, ESpecType, ESpecRange.getBegin(), DynamicExceptions.data(), @@ -824,7 +872,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, - DeclLoc, DeclEndLoc, D, + LParenLoc, FunLocalRangeEnd, D, TrailingReturnType), Attr, DeclEndLoc); } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) { @@ -853,25 +901,28 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( } ParsedAttributes Attr(AttrFactory); + SourceLocation NoLoc; D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true, - /*isVariadic=*/false, - /*isAmbiguous=*/false, - /*EllipsisLoc=*/SourceLocation(), - /*Params=*/0, /*NumParams=*/0, - /*TypeQuals=*/0, - /*RefQualifierIsLValueRef=*/true, - /*RefQualifierLoc=*/SourceLocation(), - /*ConstQualifierLoc=*/SourceLocation(), - /*VolatileQualifierLoc=*/SourceLocation(), - MutableLoc, - EST_None, - /*ESpecLoc=*/SourceLocation(), - /*Exceptions=*/0, - /*ExceptionRanges=*/0, - /*NumExceptions=*/0, - /*NoexceptExpr=*/0, - DeclLoc, DeclEndLoc, D, - TrailingReturnType), + /*isAmbiguous=*/false, + /*LParenLoc=*/NoLoc, + /*Params=*/0, + /*NumParams=*/0, + /*EllipsisLoc=*/NoLoc, + /*RParenLoc=*/NoLoc, + /*TypeQuals=*/0, + /*RefQualifierIsLValueRef=*/true, + /*RefQualifierLoc=*/NoLoc, + /*ConstQualifierLoc=*/NoLoc, + /*VolatileQualifierLoc=*/NoLoc, + MutableLoc, + EST_None, + /*ESpecLoc=*/NoLoc, + /*Exceptions=*/0, + /*ExceptionRanges=*/0, + /*NumExceptions=*/0, + /*NoexceptExpr=*/0, + DeclLoc, DeclEndLoc, D, + TrailingReturnType), Attr, DeclEndLoc); } @@ -926,10 +977,11 @@ ExprResult Parser::ParseCXXCasts() { // Check for "<::" which is parsed as "[:". If found, fix token stream, // diagnose error, suggest fix, and recover parsing. - Token Next = NextToken(); - if (Tok.is(tok::l_square) && Tok.getLength() == 2 && Next.is(tok::colon) && - areTokensAdjacent(Tok, Next)) - FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); + if (Tok.is(tok::l_square) && Tok.getLength() == 2) { + Token Next = NextToken(); + if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next)) + FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true); + } if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) return ExprError(); @@ -965,7 +1017,7 @@ ExprResult Parser::ParseCXXCasts() { T.getOpenLocation(), Result.take(), T.getCloseLocation()); - return move(Result); + return Result; } /// ParseCXXTypeid - This handles the C++ typeid expression. @@ -988,6 +1040,22 @@ ExprResult Parser::ParseCXXTypeid() { ExprResult Result; + // C++0x [expr.typeid]p3: + // When typeid is applied to an expression other than an lvalue of a + // polymorphic class type [...] The expression is an unevaluated + // operand (Clause 5). + // + // Note that we can't tell whether the expression is an lvalue of a + // polymorphic class type until after we've parsed the expression; we + // speculatively assume the subexpression is unevaluated, and fix it up + // later. + // + // We enter the unevaluated context before trying to determine whether we + // have a type-id, because the tentative parse logic will try to resolve + // names, and must treat them as unevaluated. + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); + if (isTypeIdInParens()) { TypeResult Ty = ParseTypeName(); @@ -1000,16 +1068,6 @@ ExprResult Parser::ParseCXXTypeid() { Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, Ty.get().getAsOpaquePtr(), RParenLoc); } else { - // C++0x [expr.typeid]p3: - // When typeid is applied to an expression other than an lvalue of a - // polymorphic class type [...] The expression is an unevaluated - // operand (Clause 5). - // - // Note that we can't tell whether the expression is an lvalue of a - // polymorphic class type until after we've parsed the expression; we - // speculatively assume the subexpression is unevaluated, and fix it up - // later. - EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); Result = ParseExpression(); // Match the ')'. @@ -1026,7 +1084,7 @@ ExprResult Parser::ParseCXXTypeid() { } } - return move(Result); + return Result; } /// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression. @@ -1074,7 +1132,7 @@ ExprResult Parser::ParseCXXUuidof() { } } - return move(Result); + return Result; } /// \brief Parse a C++ pseudo-destructor expression after the base, @@ -1196,7 +1254,7 @@ ExprResult Parser::ParseThrowExpression() { default: ExprResult Expr(ParseAssignmentExpression()); - if (Expr.isInvalid()) return move(Expr); + if (Expr.isInvalid()) return Expr; return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take()); } } @@ -1245,7 +1303,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); - ExprVector Exprs(Actions); + ExprVector Exprs; CommaLocsTy CommaLocs; if (Tok.isNot(tok::r_paren)) { @@ -1265,7 +1323,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(), - move_arg(Exprs), + Exprs, T.getCloseLocation()); } } @@ -1280,11 +1338,11 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] /// '=' assignment-expression /// -/// \param ExprResult if the condition was parsed as an expression, the -/// parsed expression. +/// \param ExprOut if the condition was parsed as an expression, the parsed +/// expression. /// -/// \param DeclResult if the condition was parsed as a declaration, the -/// parsed declaration. +/// \param DeclOut if the condition was parsed as a declaration, the parsed +/// declaration. /// /// \param Loc The location of the start of the statement that requires this /// condition, e.g., the "for" in a for loop. @@ -1714,8 +1772,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, } // Bundle the template arguments together. - ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), - TemplateArgs.size()); + ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs); // Constructor and destructor names. TypeResult Type @@ -1762,7 +1819,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, /// ptr-operator conversion-declarator[opt] /// \endcode /// -/// \param The nested-name-specifier that preceded this unqualified-id. If +/// \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 @@ -1867,8 +1924,9 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // Parse a literal-operator-id. // - // literal-operator-id: [C++0x 13.5.8] - // operator "" identifier + // literal-operator-id: C++11 [over.literal] + // operator string-literal identifier + // operator user-defined-string-literal if (getLangOpts().CPlusPlus0x && isTokenStringLiteral()) { Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator); @@ -1882,6 +1940,9 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, llvm::SmallVector<SourceLocation, 4> TokLocs; while (isTokenStringLiteral()) { if (!Tok.is(tok::string_literal) && !DiagId) { + // C++11 [over.literal]p1: + // The string-literal or user-defined-string-literal in a + // literal-operator-id shall have no encoding-prefix [...]. DiagLoc = Tok.getLocation(); DiagId = diag::err_literal_operator_string_prefix; } @@ -1903,9 +1964,6 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()], Literal.getUDSuffixOffset(), PP.getSourceManager(), getLangOpts()); - // This form is not permitted by the standard (yet). - DiagLoc = SuffixLoc; - DiagId = diag::err_literal_operator_missing_space; } else if (Tok.is(tok::identifier)) { II = Tok.getIdentifierInfo(); SuffixLoc = ConsumeToken(); @@ -1917,6 +1975,10 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // The string literal must be empty. if (!Literal.GetString().empty() || Literal.Pascal) { + // C++11 [over.literal]p1: + // The string-literal or user-defined-string-literal in a + // literal-operator-id shall [...] contain no characters + // other than the implicit terminating '\0'. DiagLoc = TokLocs.front(); DiagId = diag::err_literal_operator_string_not_empty; } @@ -1981,7 +2043,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, /// /// \endcode /// -/// \param The nested-name-specifier that preceded this unqualified-id. If +/// \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 @@ -2209,7 +2271,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { // A '(' now can be a new-placement or the '(' wrapping the type-id in the // second form of new-expression. It can't be a new-type-id. - ExprVector PlacementArgs(Actions); + ExprVector PlacementArgs; SourceLocation PlacementLParen, PlacementRParen; SourceRange TypeIdParens; @@ -2279,7 +2341,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { if (Tok.is(tok::l_paren)) { SourceLocation ConstructorLParen, ConstructorRParen; - ExprVector ConstructorArgs(Actions); + ExprVector ConstructorArgs; BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); ConstructorLParen = T.getOpenLocation(); @@ -2298,7 +2360,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { } Initializer = Actions.ActOnParenListExpr(ConstructorLParen, ConstructorRParen, - move_arg(ConstructorArgs)); + ConstructorArgs); } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus0x) { Diag(Tok.getLocation(), diag::warn_cxx98_compat_generalized_initializer_lists); @@ -2308,7 +2370,7 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { return Initializer; return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, - move_arg(PlacementArgs), PlacementRParen, + PlacementArgs, PlacementRParen, TypeIdParens, DeclaratorInfo, Initializer.take()); } @@ -2422,7 +2484,7 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { ExprResult Operand(ParseCastExpression(false)); if (Operand.isInvalid()) - return move(Operand); + return Operand; return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take()); } @@ -2453,6 +2515,7 @@ static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { case tok::kw___is_function: return UTT_IsFunction; case tok::kw___is_fundamental: return UTT_IsFundamental; case tok::kw___is_integral: return UTT_IsIntegral; + case tok::kw___is_interface_class: return UTT_IsInterfaceClass; case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference; case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer; case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer; @@ -2804,7 +2867,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(), DeclaratorInfo, CastTy, Tracker.getCloseLocation(), Result.take()); - return move(Result); + return Result; } // Not a compound literal, and not followed by a cast-expression. @@ -2823,5 +2886,5 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, } Tracker.consumeClose(); - return move(Result); + return Result; } |