summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp203
1 files changed, 133 insertions, 70 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
index afac257..2f615e1 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
+++ b/contrib/llvm/tools/clang/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;
}
OpenPOWER on IntegriCloud