diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-01 10:34:51 +0000 |
commit | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (patch) | |
tree | 1e68501209c9133fbda8d45171e59f8d6f12dd55 /lib/Parse | |
parent | 77212133072dc40f070a280af8217032f55a9eb4 (diff) | |
download | FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.zip FreeBSD-src-bb1e3bc1e0be2b8f891db46457a8943451bf4d8b.tar.gz |
Updaet clang to 92395.
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseCXXInlineMethods.cpp | 10 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 26 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 32 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 112 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 19 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 13 |
8 files changed, 141 insertions, 79 deletions
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index b9314d2..f1e639c 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -95,9 +95,12 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { if (HasTemplateScope) Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate); + // The current scope is still active if we're the top-level class. + // Otherwise we'll need to push and enter a new scope. bool HasClassScope = !Class.TopLevelClass; - ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, - HasClassScope); + ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, HasClassScope); + if (HasClassScope) + Actions.ActOnStartDelayedMemberDeclarations(CurScope, Class.TagOrTemplate); for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) { LateParsedMethodDeclaration &LM = Class.MethodDecls.front(); @@ -148,6 +151,9 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I) ParseLexedMethodDeclarations(*Class.NestedClasses[I]); + + if (HasClassScope) + Actions.ActOnFinishDelayedMemberDeclarations(CurScope, Class.TagOrTemplate); } /// ParseLexedMethodDefs - We finished parsing the member specification of a top diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 5dd78f7..f429ac9 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -550,13 +550,17 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, SourceLocation DelLoc = ConsumeToken(); Actions.SetDeclDeleted(ThisDecl, DelLoc); } else { - if (getLang().CPlusPlus) + if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { + EnterScope(0); Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl); + } OwningExprResult Init(ParseInitializer()); - if (getLang().CPlusPlus) + if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl); + ExitScope(); + } if (Init.isInvalid()) { SkipUntil(tok::semi, true, true); @@ -570,14 +574,30 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, ExprVector Exprs(Actions); CommaLocsTy CommaLocs; + if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { + EnterScope(0); + Actions.ActOnCXXEnterDeclInitializer(CurScope, ThisDecl); + } + if (ParseExpressionList(Exprs, CommaLocs)) { SkipUntil(tok::r_paren); + + if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { + Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl); + ExitScope(); + } } else { // Match the ')'. SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && "Unexpected number of commas!"); + + if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { + Actions.ActOnCXXExitDeclInitializer(CurScope, ThisDecl); + ExitScope(); + } + Actions.AddCXXDirectInitializerToDecl(ThisDecl, LParenLoc, move_arg(Exprs), CommaLocs.data(), RParenLoc); @@ -2349,7 +2369,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (ParseUnqualifiedId(D.getCXXScopeSpec(), /*EnteringContext=*/true, /*AllowDestructorName=*/true, - /*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(), + /*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(), /*ObjectType=*/0, D.getName())) { D.SetIdentifier(0, Tok.getLocation()); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d4d19a0..265d0f3 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -852,20 +852,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, SS, Name, StartLoc, NameLoc); } - // Parse the optional base clause (C++ only). - if (getLang().CPlusPlus && Tok.is(tok::colon)) - ParseBaseClause(TagOrTempResult.get()); - // If there is a body, parse it and inform the actions module. - if (Tok.is(tok::l_brace)) + if (TUK == Action::TUK_Definition) { + assert(Tok.is(tok::l_brace) || + (getLang().CPlusPlus && Tok.is(tok::colon))); if (getLang().CPlusPlus) ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get()); else ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); - else if (TUK == Action::TUK_Definition) { - // FIXME: Complain that we have a base-specifier list but no - // definition. - Diag(Tok, diag::err_expected_lbrace); } void *Result; @@ -1364,8 +1358,6 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, PP.getSourceManager(), "parsing struct/union/class body"); - SourceLocation LBraceLoc = ConsumeBrace(); - // Determine whether this is a top-level (non-nested) class. bool TopLevelClass = ClassStack.empty() || CurScope->isInCXXInlineMethodScope(); @@ -1378,11 +1370,27 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (TagDecl) Actions.ActOnTagStartDefinition(CurScope, TagDecl); - else { + + if (Tok.is(tok::colon)) { + ParseBaseClause(TagDecl); + + if (!Tok.is(tok::l_brace)) { + Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); + return; + } + } + + assert(Tok.is(tok::l_brace)); + + SourceLocation LBraceLoc = ConsumeBrace(); + + if (!TagDecl) { SkipUntil(tok::r_brace, false, false); return; } + Actions.ActOnStartCXXMemberDeclarations(CurScope, TagDecl, LBraceLoc); + // C++ 11p3: Members of a class defined with the keyword class are private // by default. Members of a class defined with the keywords struct or union // are public by default. diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 2c53847..9904a2c 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1589,7 +1589,7 @@ Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Actions.FullExpr(Res)); + return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res)); } Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index a2ac646..9085b87 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -131,7 +131,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Actions.FullExpr(Expr)); + return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr)); } case tok::kw_case: // C99 6.8.1: labeled-statement @@ -494,7 +494,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - R = Actions.ActOnExprStmt(Actions.FullExpr(Res)); + R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res)); } } @@ -593,7 +593,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { if (ParseParenExprOrCondition(CondExp, CondVar)) return StmtError(); - FullExprArg FullCondExp(Actions.FullExpr(CondExp)); + FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp)); // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this @@ -720,7 +720,7 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { if (ParseParenExprOrCondition(Cond, CondVar)) return StmtError(); - FullExprArg FullCond(Actions.FullExpr(Cond)); + FullExprArg FullCond(Actions.MakeFullExpr(Cond)); OwningStmtResult Switch = Actions.ActOnStartOfSwitchStmt(FullCond, CondVar); @@ -801,7 +801,7 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { if (ParseParenExprOrCondition(Cond, CondVar)) return StmtError(); - FullExprArg FullCond(Actions.FullExpr(Cond)); + FullExprArg FullCond(Actions.MakeFullExpr(Cond)); // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this @@ -993,7 +993,7 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { // Turn the expression into a stmt. if (!Value.isInvalid()) - FirstPart = Actions.ActOnExprStmt(Actions.FullExpr(Value)); + FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value)); if (Tok.is(tok::semi)) { ConsumeToken(); @@ -1060,8 +1060,8 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { if (!ForEach) return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart), - Actions.FullExpr(SecondPart), SecondVar, - Actions.FullExpr(ThirdPart), RParenLoc, + Actions.MakeFullExpr(SecondPart), SecondVar, + Actions.MakeFullExpr(ThirdPart), RParenLoc, move(Body)); return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, @@ -1232,7 +1232,6 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { // Remember if this was a volatile asm. bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; - bool isSimple = false; if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "asm"; SkipUntil(tok::r_paren); @@ -1249,53 +1248,73 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { ExprVector Exprs(Actions); ExprVector Clobbers(Actions); - unsigned NumInputs = 0, NumOutputs = 0; - - SourceLocation RParenLoc; if (Tok.is(tok::r_paren)) { - // We have a simple asm expression - isSimple = true; - - RParenLoc = ConsumeParen(); - } else { - // Parse Outputs, if present. - if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) - return StmtError(); - - NumOutputs = Names.size(); + // We have a simple asm expression like 'asm("foo")'. + SourceLocation RParenLoc = ConsumeParen(); + return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile, + /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, + move_arg(Constraints), move_arg(Exprs), + move(AsmString), move_arg(Clobbers), + RParenLoc); + } - // Parse Inputs, if present. - if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) - return StmtError(); + // Parse Outputs, if present. + bool AteExtraColon = false; + if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { + // In C++ mode, parse "::" like ": :". + AteExtraColon = Tok.is(tok::coloncolon); + ConsumeToken(); + + if (!AteExtraColon && + ParseAsmOperandsOpt(Names, Constraints, Exprs)) + return StmtError(); + } + + unsigned NumOutputs = Names.size(); + + // Parse Inputs, if present. + if (AteExtraColon || + Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { + // In C++ mode, parse "::" like ": :". + if (AteExtraColon) + AteExtraColon = false; + else { + AteExtraColon = Tok.is(tok::coloncolon); + ConsumeToken(); + } + + if (!AteExtraColon && + ParseAsmOperandsOpt(Names, Constraints, Exprs)) + return StmtError(); + } - assert(Names.size() == Constraints.size() && - Constraints.size() == Exprs.size() - && "Input operand size mismatch!"); + assert(Names.size() == Constraints.size() && + Constraints.size() == Exprs.size() && + "Input operand size mismatch!"); - NumInputs = Names.size() - NumOutputs; + unsigned NumInputs = Names.size() - NumOutputs; - // Parse the clobbers, if present. - if (Tok.is(tok::colon)) { + // Parse the clobbers, if present. + if (AteExtraColon || Tok.is(tok::colon)) { + if (!AteExtraColon) ConsumeToken(); - // Parse the asm-string list for clobbers. - while (1) { - OwningExprResult Clobber(ParseAsmStringLiteral()); + // Parse the asm-string list for clobbers. + while (1) { + OwningExprResult Clobber(ParseAsmStringLiteral()); - if (Clobber.isInvalid()) - break; + if (Clobber.isInvalid()) + break; - Clobbers.push_back(Clobber.release()); + Clobbers.push_back(Clobber.release()); - if (Tok.isNot(tok::comma)) break; - ConsumeToken(); - } + if (Tok.isNot(tok::comma)) break; + ConsumeToken(); } - - RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); } - return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile, + SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, Loc); + return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile, NumOutputs, NumInputs, Names.data(), move_arg(Constraints), move_arg(Exprs), move(AsmString), move_arg(Clobbers), @@ -1303,8 +1322,7 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { } /// ParseAsmOperands - Parse the asm-operands production as used by -/// asm-statement. We also parse a leading ':' token. If the leading colon is -/// not present, we do not parse anything. +/// asm-statement, assuming the leading ':' token was eaten. /// /// [GNU] asm-operands: /// asm-operand @@ -1319,10 +1337,6 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names, llvm::SmallVectorImpl<ExprTy*> &Constraints, llvm::SmallVectorImpl<ExprTy*> &Exprs) { - // Only do anything if this operand is present. - if (Tok.isNot(tok::colon)) return false; - ConsumeToken(); - // 'asm-operands' isn't present? if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) return false; diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index cc28541..8b8af99 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -643,8 +643,10 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, } } - if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater)) + if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater)) { + Diag(Tok.getLocation(), diag::err_expected_greater); return true; + } // Determine the location of the '>' or '>>'. Only consume this // token if the caller asked us to. @@ -989,7 +991,7 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { ConsumeToken(); } - return Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater); + return false; } /// \brief Parse a C++ explicit template instantiation diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index dabd065..51c5670 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -680,10 +680,11 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { // Otherwise, not a typename. return TPResult::False(); - case tok::coloncolon: // ::foo::bar - if (NextToken().is(tok::kw_new) || // ::new - NextToken().is(tok::kw_delete)) // ::delete - return TPResult::False(); + case tok::coloncolon: { // ::foo::bar + const Token &Next = NextToken(); + if (Next.is(tok::kw_new) || // ::new + Next.is(tok::kw_delete)) // ::delete + return TPResult::False(); // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -691,7 +692,8 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { return isCXXDeclarationSpecifier(); // Otherwise, not a typename. return TPResult::False(); - + } + // decl-specifier: // storage-class-specifier // type-specifier @@ -699,7 +701,6 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { // 'friend' // 'typedef' // 'constexpr' - case tok::kw_friend: case tok::kw_typedef: case tok::kw_constexpr: @@ -750,6 +751,12 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw___forceinline: return TPResult::True(); + case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed + // We've already annotated a scope; try to annotate a type. + if (!(TryAnnotateTypeOrScopeToken() && Tok.is(tok::annot_typename))) + return TPResult::False(); + // If that succeeded, fallthrough into the generic simple-type-id case. + // The ambiguity resides in a simple-type-specifier/typename-specifier // followed by a '('. The '(' could either be the start of: // diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index a864e7c..52c0153 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -880,7 +880,7 @@ Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { /// as the current tokens, so only call it in contexts where these are invalid. bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) - || Tok.is(tok::kw_typename)) && + || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) && "Cannot be a type or scope token!"); if (Tok.is(tok::kw_typename)) { @@ -935,6 +935,9 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { return true; } + // Remembers whether the token was originally a scope annotation. + bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope); + CXXScopeSpec SS; if (getLang().CPlusPlus) ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext); @@ -1017,9 +1020,11 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { Tok.setAnnotationValue(SS.getScopeRep()); Tok.setAnnotationRange(SS.getRange()); - // In case the tokens were cached, have Preprocessor replace them with the - // annotation token. - PP.AnnotateCachedTokens(Tok); + // In case the tokens were cached, have Preprocessor replace them + // with the annotation token. We don't need to do this if we've + // just reverted back to the state we were in before being called. + if (!wasScopeAnnotation) + PP.AnnotateCachedTokens(Tok); return true; } |