diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-04 15:04:32 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-04 15:04:32 +0000 |
commit | 51fb8b013e7734b795139f49d3b1f77c539be20a (patch) | |
tree | 59e0e47a9831dcf0e21e547927c8ebb7e113bfd1 /lib/Parse/ParseExpr.cpp | |
parent | 73490b890977362d28dd6326843a1ecae413921d (diff) | |
download | src-51fb8b013e7734b795139f49d3b1f77c539be20a.tar.gz src-51fb8b013e7734b795139f49d3b1f77c539be20a.zip |
Notes
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 168 |
1 files changed, 46 insertions, 122 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 8be89a891680..95a0e989471e 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -340,7 +340,18 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) { // Eat the colon. ColonLoc = ConsumeToken(); } - + + if ((OpToken.is(tok::periodstar) || OpToken.is(tok::arrowstar)) + && Tok.is(tok::identifier)) { + CXXScopeSpec SS; + if (Actions.getTypeName(*Tok.getIdentifierInfo(), + Tok.getLocation(), CurScope, &SS)) { + const char *Opc = OpToken.is(tok::periodstar) ? "'.*'" : "'->*'"; + Diag(OpToken, diag::err_pointer_to_member_type) << Opc; + return ExprError(); + } + + } // Parse another leaf here for the RHS of the operator. // ParseCastExpression works here because all RHS expressions in C have it // as a prefix, at least. However, in C++, an assignment-expression could @@ -612,36 +623,39 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ParseCastExpression(isUnaryExpression, isAddressOfOperand); } - // Support 'Class.property' notation. - // We don't use isTokObjCMessageIdentifierReceiver(), since it allows - // 'super' (which is inappropriate here). - if (getLang().ObjC1 && - Actions.getTypeName(*Tok.getIdentifierInfo(), - Tok.getLocation(), CurScope) && - NextToken().is(tok::period)) { - IdentifierInfo &ReceiverName = *Tok.getIdentifierInfo(); - SourceLocation IdentLoc = ConsumeToken(); + // Consume the identifier so that we can see if it is followed by a '(' or + // '.'. + IdentifierInfo &II = *Tok.getIdentifierInfo(); + SourceLocation ILoc = ConsumeToken(); + + // Support 'Class.property' notation. We don't use + // isTokObjCMessageIdentifierReceiver(), since it allows 'super' (which is + // inappropriate here). + if (getLang().ObjC1 && Tok.is(tok::period) && + Actions.getTypeName(II, ILoc, CurScope)) { SourceLocation DotLoc = ConsumeToken(); - + if (Tok.isNot(tok::identifier)) { - Diag(Tok, diag::err_expected_ident); + Diag(Tok, diag::err_expected_property_name); return ExprError(); } IdentifierInfo &PropertyName = *Tok.getIdentifierInfo(); SourceLocation PropertyLoc = ConsumeToken(); - - Res = Actions.ActOnClassPropertyRefExpr(ReceiverName, PropertyName, - IdentLoc, PropertyLoc); + + Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, + ILoc, PropertyLoc); // These can be followed by postfix-expr pieces. return ParsePostfixExpressionSuffix(move(Res)); } - // Consume the identifier so that we can see if it is followed by a '('. + // Function designators are allowed to be undeclared (C99 6.5.1p2), so we // need to know whether or not this identifier is a function designator or // not. - IdentifierInfo &II = *Tok.getIdentifierInfo(); - SourceLocation L = ConsumeToken(); - Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren)); + UnqualifiedId Name; + CXXScopeSpec ScopeSpec; + Name.setIdentifier(&II, ILoc); + Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, + Tok.is(tok::l_paren), false); // These can be followed by postfix-expr pieces. return ParsePostfixExpressionSuffix(move(Res)); } @@ -954,110 +968,20 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { ConsumeToken(); } - if (Tok.is(tok::identifier)) { - if (!LHS.isInvalid()) - LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc, - OpKind, Tok.getLocation(), - *Tok.getIdentifierInfo(), - ObjCImpDecl, &SS); - ConsumeToken(); - } else if (getLang().CPlusPlus && Tok.is(tok::tilde)) { - // We have a C++ pseudo-destructor or a destructor call, e.g., t.~T() - - // Consume the tilde. - ConsumeToken(); - - if (!Tok.is(tok::identifier)) { - Diag(Tok, diag::err_expected_ident); - return ExprError(); - } - - if (NextToken().is(tok::less)) { - // class-name: - // ~ simple-template-id - TemplateTy Template - = Actions.ActOnDependentTemplateName(SourceLocation(), - *Tok.getIdentifierInfo(), - Tok.getLocation(), - SS, - ObjectType); - if (AnnotateTemplateIdToken(Template, TNK_Type_template, &SS, - SourceLocation(), true)) - return ExprError(); - - assert(Tok.is(tok::annot_typename) && - "AnnotateTemplateIdToken didn't work?"); - if (!LHS.isInvalid()) - LHS = Actions.ActOnDestructorReferenceExpr(CurScope, move(LHS), - OpLoc, OpKind, - Tok.getAnnotationRange(), - Tok.getAnnotationValue(), - SS, - NextToken().is(tok::l_paren)); - } else { - // class-name: - // ~ identifier - if (!LHS.isInvalid()) - LHS = Actions.ActOnDestructorReferenceExpr(CurScope, move(LHS), - OpLoc, OpKind, - Tok.getLocation(), - Tok.getIdentifierInfo(), - SS, - NextToken().is(tok::l_paren)); - } - - // Consume the identifier or template-id token. - ConsumeToken(); - } else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) { - // We have a reference to a member operator, e.g., t.operator int or - // t.operator+. - SourceLocation OperatorLoc = Tok.getLocation(); - - if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) { - if (!LHS.isInvalid()) - LHS = Actions.ActOnOverloadedOperatorReferenceExpr(CurScope, - move(LHS), OpLoc, - OpKind, - OperatorLoc, - Op, &SS); - // TryParseOperatorFunctionId already consumed our token, so - // don't bother - } else if (TypeTy *ConvType = ParseConversionFunctionId()) { - if (!LHS.isInvalid()) - LHS = Actions.ActOnConversionOperatorReferenceExpr(CurScope, - move(LHS), OpLoc, - OpKind, - OperatorLoc, - ConvType, &SS); - } else { - // Don't emit a diagnostic; ParseConversionFunctionId does it for us - return ExprError(); - } - } else if (getLang().CPlusPlus && Tok.is(tok::annot_template_id)) { - // We have a reference to a member template along with explicitly- - // specified template arguments, e.g., t.f<int>. - TemplateIdAnnotation *TemplateId - = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); - if (!LHS.isInvalid()) { - ASTTemplateArgsPtr TemplateArgsPtr(Actions, - TemplateId->getTemplateArgs(), - TemplateId->getTemplateArgIsType(), - TemplateId->NumArgs); - - LHS = Actions.ActOnMemberTemplateIdReferenceExpr(CurScope, move(LHS), - OpLoc, OpKind, SS, - TemplateTy::make(TemplateId->Template), - TemplateId->TemplateNameLoc, - TemplateId->LAngleLoc, - TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), - TemplateId->RAngleLoc); - } - ConsumeToken(); - } else { - Diag(Tok, diag::err_expected_ident); + UnqualifiedId Name; + if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, + /*AllowDestructorName=*/true, + /*AllowConstructorName=*/false, + ObjectType, + Name)) return ExprError(); - } + + if (!LHS.isInvalid()) + LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, OpKind, + SS, Name, ObjCImpDecl, + Tok.is(tok::l_paren)); + break; } case tok::plusplus: // postfix-expression: postfix-expression '++' |