diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-01 11:08:04 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-01 11:08:04 +0000 |
commit | 4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa (patch) | |
tree | 867cbbe32a66fd7d62dd9ce9df23a23fefdb8290 /lib/Parse/ParseExprCXX.cpp | |
parent | 6df2408694f81a03eb8b0e3b013272042233c061 (diff) | |
download | FreeBSD-src-4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa.zip FreeBSD-src-4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa.tar.gz |
Update clang to r90226.
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index b2ecc9e..52003e6 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -124,7 +124,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, break; } - if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId) { + if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId && + TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) { Diag(TemplateName.getSourceRange().getBegin(), diag::err_id_after_template_in_nested_name_spec) << TemplateName.getSourceRange(); @@ -148,7 +149,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, TPA.Commit(); TemplateTy Template = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, - ObjectType); + ObjectType, EnteringContext); if (!Template) break; if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, @@ -326,6 +327,24 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { /*ObjectType=*/0, Name)) return ExprError(); + + // This is only the direct operand of an & operator if it is not + // followed by a postfix-expression suffix. + if (isAddressOfOperand) { + switch (Tok.getKind()) { + case tok::l_square: + case tok::l_paren: + case tok::arrow: + case tok::period: + case tok::plusplus: + case tok::minusminus: + isAddressOfOperand = false; + break; + + default: + break; + } + } return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren), isAddressOfOperand); @@ -531,7 +550,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { CommaLocs.data(), RParenLoc); } -/// ParseCXXCondition - if/switch/while/for condition expression. +/// ParseCXXCondition - if/switch/while condition expression. /// /// condition: /// expression @@ -539,11 +558,20 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] /// '=' assignment-expression /// -Parser::OwningExprResult Parser::ParseCXXCondition() { - if (!isCXXConditionDeclaration()) - return ParseExpression(); // expression - - SourceLocation StartLoc = Tok.getLocation(); +/// \param ExprResult if the condition was parsed as an expression, the +/// parsed expression. +/// +/// \param DeclResult if the condition was parsed as a declaration, the +/// parsed declaration. +/// +/// \returns true if there was a parsing, false otherwise. +bool Parser::ParseCXXCondition(OwningExprResult &ExprResult, + DeclPtrTy &DeclResult) { + if (!isCXXConditionDeclaration()) { + ExprResult = ParseExpression(); // expression + DeclResult = DeclPtrTy(); + return ExprResult.isInvalid(); + } // type-specifier-seq DeclSpec DS; @@ -559,7 +587,7 @@ Parser::OwningExprResult Parser::ParseCXXCondition() { OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) { SkipUntil(tok::semi); - return ExprError(); + return true; } DeclaratorInfo.setAsmLabel(AsmLabel.release()); DeclaratorInfo.SetRangeEnd(Loc); @@ -568,21 +596,28 @@ Parser::OwningExprResult Parser::ParseCXXCondition() { // If attributes are present, parse them. if (Tok.is(tok::kw___attribute)) { SourceLocation Loc; - AttributeList *AttrList = ParseAttributes(&Loc); + AttributeList *AttrList = ParseGNUAttributes(&Loc); DeclaratorInfo.AddAttributes(AttrList, Loc); } + // Type-check the declaration itself. + Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope, + DeclaratorInfo); + DeclResult = Dcl.get(); + ExprResult = ExprError(); + // '=' assignment-expression - if (Tok.isNot(tok::equal)) - return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator)); - SourceLocation EqualLoc = ConsumeToken(); - OwningExprResult AssignExpr(ParseAssignmentExpression()); - if (AssignExpr.isInvalid()) - return ExprError(); - - return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc, - DeclaratorInfo,EqualLoc, - move(AssignExpr)); + if (Tok.is(tok::equal)) { + SourceLocation EqualLoc = ConsumeToken(); + OwningExprResult AssignExpr(ParseAssignmentExpression()); + if (!AssignExpr.isInvalid()) + Actions.AddInitializerToDecl(DeclResult, move(AssignExpr)); + } else { + // FIXME: C++0x allows a braced-init-list + Diag(Tok, diag::err_expected_equal_after_declarator); + } + + return false; } /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. @@ -757,6 +792,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, switch (Id.getKind()) { case UnqualifiedId::IK_Identifier: case UnqualifiedId::IK_OperatorFunctionId: + case UnqualifiedId::IK_LiteralOperatorId: TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType, EnteringContext, Template); break; @@ -774,7 +810,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateName.setIdentifier(Name, NameLoc); if (ObjectType) { Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, - TemplateName, ObjectType); + TemplateName, ObjectType, + EnteringContext); TNK = TNK_Dependent_template_name; if (!Template.get()) return true; @@ -813,7 +850,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, return true; if (Id.getKind() == UnqualifiedId::IK_Identifier || - Id.getKind() == UnqualifiedId::IK_OperatorFunctionId) { + Id.getKind() == UnqualifiedId::IK_OperatorFunctionId || + Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) { // Form a parsed representation of the template-id to be stored in the // UnqualifiedId. TemplateIdAnnotation *TemplateId @@ -996,6 +1034,26 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); return false; } + + // Parse a literal-operator-id. + // + // literal-operator-id: [C++0x 13.5.8] + // operator "" identifier + + if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) { + if (Tok.getLength() != 2) + Diag(Tok.getLocation(), diag::err_operator_string_not_empty); + ConsumeStringToken(); + + if (Tok.isNot(tok::identifier)) { + Diag(Tok.getLocation(), diag::err_expected_ident); + return true; + } + + IdentifierInfo *II = Tok.getIdentifierInfo(); + Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken()); + return false; + } // Parse a conversion-function-id. // @@ -1010,7 +1068,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, // Parse the type-specifier-seq. DeclSpec DS; - if (ParseCXXTypeSpecifierSeq(DS)) + if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? return true; // Parse the conversion-declarator, which is merely a sequence of @@ -1111,12 +1169,13 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) return true; - // If we have an operator-function-id and the next token is a '<', we may - // have a + // 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] > - if (Result.getKind() == UnqualifiedId::IK_OperatorFunctionId && + if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || + Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && Tok.is(tok::less)) return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), EnteringContext, ObjectType, @@ -1152,7 +1211,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, // Note that this is a destructor name. Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc, - CurScope, &SS); + CurScope, &SS, false, ObjectType); if (!Ty) { if (ObjectType) Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type) |