diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
commit | fd035e6496665b1f1197868e21cb0a4594e8db6e (patch) | |
tree | 53010172e19c77ea447bcd89e117cda052ab52e0 /lib/Parse | |
parent | 2fce988e86bc01829142e4362d4eff1af0925147 (diff) | |
download | FreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.zip FreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.tar.gz |
Update clang to r96341.
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 37 | ||||
-rw-r--r-- | lib/Parse/Makefile | 1 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 94 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 122 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 41 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 24 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 90 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 9 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 23 |
11 files changed, 344 insertions, 106 deletions
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 9e5f5a2..4a699e7 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -253,6 +253,11 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); TypeSpecWidth = W; TSWLoc = Loc; + if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::warn_vector_long_decl_spec_combination; + return true; + } return false; } @@ -289,6 +294,38 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, TypeRep = Rep; TSTLoc = Loc; TypeSpecOwned = Owned; + if (TypeAltiVecVector && (TypeSpecType == TST_double)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_vector_double_decl_spec_combination; + return true; + } + return false; +} + +bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID) { + if (TypeSpecType != TST_unspecified) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_vector_decl_spec_combination; + return true; + } + TypeAltiVecVector = isAltiVecVector; + AltiVecLoc = Loc; + return false; +} + +bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID) { + if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) { + PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); + DiagID = diag::err_invalid_pixel_decl_spec_combination; + return true; + } + TypeSpecType = TST_int; + TypeSpecSign = TSS_unsigned; + TypeSpecWidth = TSW_short; + TypeAltiVecPixel = isAltiVecPixel; + TSTLoc = Loc; return false; } diff --git a/lib/Parse/Makefile b/lib/Parse/Makefile index 5d69029..de16e3e 100644 --- a/lib/Parse/Makefile +++ b/lib/Parse/Makefile @@ -14,7 +14,6 @@ LEVEL = ../../../.. LIBRARYNAME := clangParse BUILD_ARCHIVE = 1 -CXXFLAGS = -fno-rtti CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index b5ba8ac..8aa6936 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -733,7 +733,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, if (TagName) { Diag(Loc, diag::err_use_of_tag_name_without_tag) - << Tok.getIdentifierInfo() << TagName + << Tok.getIdentifierInfo() << TagName << getLang().CPlusPlus << CodeModificationHint::CreateInsertion(Tok.getLocation(),TagName); // Parse this as a tag as if the missing tag were present. @@ -1029,6 +1029,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DS.hasTypeSpecifier()) goto DoneWithDeclSpec; + // Check for need to substitute AltiVec keyword tokens. + if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) + break; + // It has to be available as a typedef too! TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), Tok.getLocation(), CurScope); @@ -1270,6 +1274,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, DiagID); break; + case tok::kw___vector: + isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); + break; + case tok::kw___pixel: + isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); + break; // class-specifier: case tok::kw_class: @@ -1395,20 +1405,26 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, /// [OBJC] class-name objc-protocol-refs[opt] [TODO] /// [OBJC] typedef-name objc-protocol-refs[opt] [TODO] /// [C++0x] 'decltype' ( expression ) +/// [AltiVec] '__vector' bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, const char *&PrevSpec, unsigned &DiagID, - const ParsedTemplateInfo &TemplateInfo) { + const ParsedTemplateInfo &TemplateInfo, + bool SuppressDeclarations) { SourceLocation Loc = Tok.getLocation(); switch (Tok.getKind()) { case tok::identifier: // foo::bar + // Check for need to substitute AltiVec keyword tokens. + if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) + break; + // Fall through. case tok::kw_typename: // typename foo::bar // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, - TemplateInfo); + TemplateInfo, SuppressDeclarations); // Otherwise, not a type specifier. return false; case tok::coloncolon: // ::foo::bar @@ -1420,7 +1436,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, - TemplateInfo); + TemplateInfo, SuppressDeclarations); // Otherwise, not a type specifier. return false; @@ -1519,14 +1535,21 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec, DiagID); break; - + case tok::kw___vector: + isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID); + break; + case tok::kw___pixel: + isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID); + break; + // class-specifier: case tok::kw_class: case tok::kw_struct: case tok::kw_union: { tok::TokenKind Kind = Tok.getKind(); ConsumeToken(); - ParseClassSpecifier(Kind, Loc, DS, TemplateInfo); + ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS_none, + SuppressDeclarations); return true; } @@ -1750,14 +1773,14 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, ConsumeToken(); if (!Tok.isObjCAtKeyword(tok::objc_defs)) { Diag(Tok, diag::err_unexpected_at); - SkipUntil(tok::semi, true, true); + SkipUntil(tok::semi, true); continue; } ConsumeToken(); ExpectAndConsume(tok::l_paren, diag::err_expected_lparen); if (!Tok.is(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - SkipUntil(tok::semi, true, true); + SkipUntil(tok::semi, true); continue; } llvm::SmallVector<DeclPtrTy, 16> Fields; @@ -1771,26 +1794,28 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, if (Tok.is(tok::semi)) { ConsumeToken(); } else if (Tok.is(tok::r_brace)) { - Diag(Tok, diag::ext_expected_semi_decl_list); + ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list); break; } else { - Diag(Tok, diag::err_expected_semi_decl_list); - // Skip to end of block or statement + ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list); + // Skip to end of block or statement to avoid ext-warning on extra ';'. SkipUntil(tok::r_brace, true, true); + // If we stopped at a ';', eat it. + if (Tok.is(tok::semi)) ConsumeToken(); } } SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - AttributeList *AttrList = 0; + llvm::OwningPtr<AttributeList> AttrList; // If attributes exist after struct contents, parse them. if (Tok.is(tok::kw___attribute)) - AttrList = ParseGNUAttributes(); + AttrList.reset(ParseGNUAttributes()); Actions.ActOnFields(CurScope, RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(), LBraceLoc, RBraceLoc, - AttrList); + AttrList.get()); StructScope.Exit(); Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc); } @@ -1817,10 +1842,10 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, ConsumeToken(); } - AttributeList *Attr = 0; + llvm::OwningPtr<AttributeList> Attr; // If attributes exist after tag, parse them. if (Tok.is(tok::kw___attribute)) - Attr = ParseGNUAttributes(); + Attr.reset(ParseGNUAttributes()); CXXScopeSpec SS; if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, 0, false)) { @@ -1870,7 +1895,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, bool Owned = false; bool IsDependent = false; DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TUK, - StartLoc, SS, Name, NameLoc, Attr, AS, + StartLoc, SS, Name, NameLoc, Attr.get(), + AS, Action::MultiTemplateParamsArg(Actions), Owned, IsDependent); assert(!IsDependent && "didn't expect dependent enum"); @@ -1878,10 +1904,12 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (Tok.is(tok::l_brace)) ParseEnumBody(StartLoc, TagDecl); - // TODO: semantic analysis on the declspec for enums. + // FIXME: The DeclSpec should keep the locations of both the keyword and the + // name (if there is one). + SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; const char *PrevSpec = 0; unsigned DiagID; - if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, DiagID, + if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID, TagDecl.getAs<void>(), Owned)) Diag(StartLoc, DiagID) << PrevSpec; } @@ -1948,14 +1976,14 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { // Eat the }. SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - AttributeList *Attr = 0; + llvm::OwningPtr<AttributeList> Attr; // If attributes exist after the identifier list, parse them. if (Tok.is(tok::kw___attribute)) - Attr = ParseGNUAttributes(); // FIXME: where do they do? + Attr.reset(ParseGNUAttributes()); // FIXME: where do they do? Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl, EnumConstantDecls.data(), EnumConstantDecls.size(), - CurScope, Attr); + CurScope, Attr.get()); EnumScope.Exit(); Actions.ActOnTagFinishDefinition(CurScope, EnumDecl, RBraceLoc); @@ -1981,6 +2009,9 @@ bool Parser::isTypeSpecifierQualifier() { default: return false; case tok::identifier: // foo::bar + if (TryAltiVecVectorToken()) + return true; + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -2026,6 +2057,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: + case tok::kw___vector: // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -2066,7 +2098,9 @@ bool Parser::isDeclarationSpecifier() { // Unfortunate hack to support "Class.factoryMethod" notation. if (getLang().ObjC1 && NextToken().is(tok::period)) return false; - // Fall through + if (TryAltiVecVectorToken()) + return true; + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just @@ -2117,6 +2151,7 @@ bool Parser::isDeclarationSpecifier() { case tok::kw__Decimal32: case tok::kw__Decimal64: case tok::kw__Decimal128: + case tok::kw___vector: // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -2608,10 +2643,10 @@ void Parser::ParseParenDeclarator(Declarator &D) { // In either case, we need to eat any attributes to be able to determine what // sort of paren this is. // - AttributeList *AttrList = 0; + llvm::OwningPtr<AttributeList> AttrList; bool RequiresArg = false; if (Tok.is(tok::kw___attribute)) { - AttrList = ParseGNUAttributes(); + AttrList.reset(ParseGNUAttributes()); // We require that the argument list (if this is a non-grouping paren) be // present even if the attribute list was empty. @@ -2621,7 +2656,7 @@ void Parser::ParseParenDeclarator(Declarator &D) { if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) || Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) { - AttrList = ParseMicrosoftTypeAttributes(AttrList); + AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take())); } // If we haven't past the identifier yet (or where the identifier would be @@ -2652,7 +2687,7 @@ void Parser::ParseParenDeclarator(Declarator &D) { bool hadGroupingParens = D.hasGroupingParens(); D.setGroupingParens(true); if (AttrList) - D.AddAttributes(AttrList, SourceLocation()); + D.AddAttributes(AttrList.take(), SourceLocation()); ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); // Match the ')'. @@ -2669,7 +2704,7 @@ void Parser::ParseParenDeclarator(Declarator &D) { // ParseFunctionDeclarator to handle of argument list. D.SetIdentifier(0, Tok.getLocation()); - ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg); + ParseFunctionDeclarator(StartLoc, D, AttrList.take(), RequiresArg); } /// ParseFunctionDeclarator - We are after the identifier and have parsed the @@ -2762,7 +2797,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Alternatively, this parameter list may be an identifier list form for a // K&R-style function: void foo(a,b,c) - if (!getLang().CPlusPlus && Tok.is(tok::identifier)) { + if (!getLang().CPlusPlus && Tok.is(tok::identifier) + && !TryAltiVecVectorToken()) { if (!TryAnnotateTypeOrScopeToken()) { // K&R identifier lists can't have typedefs as identifiers, per // C99 6.7.5.3p11. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index efaf8ee..51ee6a4 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -64,12 +64,12 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, } // Read label attributes, if present. - Action::AttrTy *AttrList = 0; + llvm::OwningPtr<AttributeList> AttrList; if (Tok.is(tok::kw___attribute)) { attrTok = Tok; // FIXME: save these somewhere. - AttrList = ParseGNUAttributes(); + AttrList.reset(ParseGNUAttributes()); } if (Tok.is(tok::equal)) { @@ -91,7 +91,8 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, ParseScope NamespaceScope(this, Scope::DeclScope); DeclPtrTy NamespcDecl = - Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace); + Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace, + AttrList.get()); PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions, PP.getSourceManager(), @@ -191,6 +192,8 @@ Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS, SourceLocation()); } + DS.abort(); + if (Attr.HasAttr) Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed) << Attr.Range; @@ -325,8 +328,6 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, // Parse nested-name-specifier. ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); - AttributeList *AttrList = 0; - // Check nested-name specifier. if (SS.isInvalid()) { SkipUntil(tok::semi); @@ -348,8 +349,9 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, } // Parse (optional) attributes (most likely GNU strong-using extension). + llvm::OwningPtr<AttributeList> AttrList; if (Tok.is(tok::kw___attribute)) - AttrList = ParseGNUAttributes(); + AttrList.reset(ParseGNUAttributes()); // Eat ';'. DeclEnd = Tok.getLocation(); @@ -358,7 +360,7 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, tok::semi); return Actions.ActOnUsingDeclaration(CurScope, AS, true, UsingLoc, SS, Name, - AttrList, IsTypeName, TypenameLoc); + AttrList.get(), IsTypeName, TypenameLoc); } /// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion. @@ -547,7 +549,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which /// until we reach the start of a definition or see a token that -/// cannot start a definition. +/// cannot start a definition. If SuppressDeclarations is true, we do know. /// /// class-specifier: [C++ class] /// class-head '{' member-specification[opt] '}' @@ -587,7 +589,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation StartLoc, DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, - AccessSpecifier AS) { + AccessSpecifier AS, bool SuppressDeclarations){ DeclSpec::TST TagType; if (TagTokKind == tok::kw_struct) TagType = DeclSpec::TST_struct; @@ -733,8 +735,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // have to be treated differently. If we have 'struct foo {...' or // 'struct foo :...' then this is a definition. Otherwise we have // something like 'struct foo xyz', a reference. + // However, in some contexts, things look like declarations but are just + // references, e.g. + // new struct s; + // or + // &T::operator struct s; + // For these, SuppressDeclarations is true. Action::TagUseKind TUK; - if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) { + if (SuppressDeclarations) + TUK = Action::TUK_Reference; + else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){ if (DS.isFriendSpecified()) { // C++ [class.friend]p2: // A class shall not be defined in a friend declaration. @@ -917,9 +927,62 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, const char *PrevSpec = 0; unsigned DiagID; - if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, DiagID, + // FIXME: The DeclSpec should keep the locations of both the keyword and the + // name (if there is one). + SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; + + if (DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID, Result, Owned)) Diag(StartLoc, DiagID) << PrevSpec; + + // At this point, we've successfully parsed a class-specifier in 'definition' + // form (e.g. "struct foo { int x; }". While we could just return here, we're + // going to look at what comes after it to improve error recovery. If an + // impossible token occurs next, we assume that the programmer forgot a ; at + // the end of the declaration and recover that way. + // + // This switch enumerates the valid "follow" set for definition. + if (TUK == Action::TUK_Definition) { + switch (Tok.getKind()) { + case tok::semi: // struct foo {...} ; + case tok::star: // struct foo {...} * P; + case tok::amp: // struct foo {...} & R = ... + case tok::identifier: // struct foo {...} V ; + case tok::r_paren: //(struct foo {...} ) {4} + case tok::annot_cxxscope: // struct foo {...} a:: b; + case tok::annot_typename: // struct foo {...} a ::b; + case tok::annot_template_id: // struct foo {...} a<int> ::b; + case tok::l_paren: // struct foo {...} ( x); + case tok::comma: // __builtin_offsetof(struct foo{...} , + // Storage-class specifiers + case tok::kw_static: // struct foo {...} static x; + case tok::kw_extern: // struct foo {...} extern x; + case tok::kw_typedef: // struct foo {...} typedef x; + case tok::kw_register: // struct foo {...} register x; + case tok::kw_auto: // struct foo {...} auto x; + // Type qualifiers + case tok::kw_const: // struct foo {...} const x; + case tok::kw_volatile: // struct foo {...} volatile x; + case tok::kw_restrict: // struct foo {...} restrict x; + case tok::kw_inline: // struct foo {...} inline foo() {}; + break; + + case tok::r_brace: // struct bar { struct foo {...} } + // Missing ';' at end of struct is accepted as an extension in C mode. + if (!getLang().CPlusPlus) break; + // FALL THROUGH. + default: + ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, + TagType == DeclSpec::TST_class ? "class" + : TagType == DeclSpec::TST_struct? "struct" : "union"); + // Push this token back into the preprocessor and change our current token + // to ';' so that the rest of the code recovers as though there were an + // ';' after the definition. + PP.EnterToken(Tok); + Tok.setKind(tok::semi); + break; + } + } } /// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. @@ -1164,7 +1227,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, return ParseCXXClassMemberDeclaration(AS, TemplateInfo); } - // Don't parse FOO:BAR as if it were a typo for FOO::BAR. + // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it + // is a bitfield. ColonProtectionRAIIObject X(*this); CXX0XAttributeList AttrList; @@ -1185,8 +1249,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, if (Tok.is(tok::kw_namespace)) { Diag(UsingLoc, diag::err_using_namespace_in_class); SkipUntil(tok::semi, true, true); - } - else { + } else { SourceLocation DeclEnd; // Otherwise, it must be using-declaration. ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd, AS); @@ -1367,19 +1430,16 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, ParseDeclarator(DeclaratorInfo); } - if (Tok.is(tok::semi)) { - ConsumeToken(); - Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(), - DeclsInGroup.size()); + if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { + // Skip to end of block or statement. + SkipUntil(tok::r_brace, true, true); + // If we stopped at a ';', eat it. + if (Tok.is(tok::semi)) ConsumeToken(); return; } - Diag(Tok, diag::err_expected_semi_decl_list); - // Skip to end of block or statement - SkipUntil(tok::r_brace, true, true); - if (Tok.is(tok::semi)) - ConsumeToken(); - return; + Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(), + DeclsInGroup.size()); } /// ParseCXXMemberSpecification - Parse the class definition. @@ -1489,10 +1549,10 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - AttributeList *AttrList = 0; // If attributes exist after class contents, parse them. + llvm::OwningPtr<AttributeList> AttrList; if (Tok.is(tok::kw___attribute)) - AttrList = ParseGNUAttributes(); // FIXME: where should I put them? + AttrList.reset(ParseGNUAttributes()); // FIXME: where should I put them? Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, LBraceLoc, RBraceLoc); @@ -1546,12 +1606,15 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) { SourceLocation ColonLoc = ConsumeToken(); llvm::SmallVector<MemInitTy*, 4> MemInitializers; - + bool AnyErrors = false; + do { MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); if (!MemInit.isInvalid()) MemInitializers.push_back(MemInit.get()); - + else + AnyErrors = true; + if (Tok.is(tok::comma)) ConsumeToken(); else if (Tok.is(tok::l_brace)) @@ -1565,7 +1628,8 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) { } while (true); Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, - MemInitializers.data(), MemInitializers.size()); + MemInitializers.data(), MemInitializers.size(), + AnyErrors); } /// ParseMemInitializer - Parse a C++ member initializer, which is diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 669575c..c763c2c 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -22,6 +22,7 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" #include "clang/Basic/PrettyStackTrace.h" #include "RAIIObjectsForParser.h" #include "llvm/ADT/SmallVector.h" @@ -780,6 +781,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_void: case tok::kw_typename: case tok::kw_typeof: + case tok::kw___vector: case tok::annot_typename: { if (!getLang().CPlusPlus) { Diag(Tok, diag::err_expected_expression); @@ -805,9 +807,44 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ParsePostfixExpressionSuffix(move(Res)); } - case tok::annot_cxxscope: // [C++] id-expression: qualified-id + case tok::annot_cxxscope: { // [C++] id-expression: qualified-id + Token Next = NextToken(); + if (Next.is(tok::annot_template_id)) { + TemplateIdAnnotation *TemplateId + = static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue()); + if (TemplateId->Kind == TNK_Type_template) { + // We have a qualified template-id that we know refers to a + // type, translate it into a type and continue parsing as a + // cast expression. + CXXScopeSpec SS; + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + AnnotateTemplateIdTokenAsType(&SS); + return ParseCastExpression(isUnaryExpression, isAddressOfOperand, + NotCastExpr, TypeOfCast); + } + } + + // Parse as an id-expression. + Res = ParseCXXIdExpression(isAddressOfOperand); + return ParsePostfixExpressionSuffix(move(Res)); + } + + case tok::annot_template_id: { // [C++] template-id + TemplateIdAnnotation *TemplateId + = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); + if (TemplateId->Kind == TNK_Type_template) { + // We have a template-id that we know refers to a type, + // translate it into a type and continue parsing as a cast + // expression. + AnnotateTemplateIdTokenAsType(); + return ParseCastExpression(isUnaryExpression, isAddressOfOperand, + NotCastExpr, TypeOfCast); + } + + // Fall through to treat the template-id as an id-expression. + } + case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id - case tok::annot_template_id: // [C++] template-id Res = ParseCXXIdExpression(isAddressOfOperand); return ParsePostfixExpressionSuffix(move(Res)); diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index ca50ef4..0dbe1ea 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -763,12 +763,15 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { bool isInvalid = 0; // Parse one or more of the type specifiers. - if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) { + if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, + ParsedTemplateInfo(), /*SuppressDeclarations*/true)) { Diag(Tok, diag::err_operator_missing_type_specifier); return true; } - while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ; + while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, + ParsedTemplateInfo(), /*SuppressDeclarations*/true)) + {} return false; } diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index ae85aa3..d1c9be2 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -515,7 +515,8 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl, DS.setSetterName(Tok.getIdentifierInfo()); ConsumeToken(); // consume method name - if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "", + if (ExpectAndConsume(tok::colon, + diag::err_expected_colon_after_setter_name, "", tok::r_paren)) return; } else { @@ -786,15 +787,15 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, llvm::SmallVector<Declarator, 8> CargNames; if (Tok.isNot(tok::colon)) { // If attributes exist after the method, parse them. - AttributeList *MethodAttrs = 0; + llvm::OwningPtr<AttributeList> MethodAttrs; if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) - MethodAttrs = ParseGNUAttributes(); + MethodAttrs.reset(ParseGNUAttributes()); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); DeclPtrTy Result = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - 0, CargNames, MethodAttrs, + 0, CargNames, MethodAttrs.get(), MethodImplKind); PD.complete(Result); return Result; @@ -862,9 +863,9 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, // FIXME: Add support for optional parmameter list... // If attributes exist after the method, parse them. - AttributeList *MethodAttrs = 0; + llvm::OwningPtr<AttributeList> MethodAttrs; if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) - MethodAttrs = ParseGNUAttributes(); + MethodAttrs.reset(ParseGNUAttributes()); if (KeyIdents.size() == 0) return DeclPtrTy(); @@ -873,9 +874,16 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, DeclPtrTy Result = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, - &ArgInfos[0], CargNames, MethodAttrs, + &ArgInfos[0], CargNames, + MethodAttrs.get(), MethodImplKind, isVariadic); PD.complete(Result); + + // Delete referenced AttributeList objects. + for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator + I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I) + delete I->ArgAttrs; + return Result; } @@ -1481,7 +1489,9 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { // Inform the actions module about the parameter declarator, so it // gets added to the current scope. + // FIXME. Probably can build a VarDecl and avoid setting DeclContext. FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl); + Actions.ActOnObjCCatchParam(FirstPart); } else ConsumeToken(); // consume '...' diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 21e960a..9fd145d 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -81,6 +81,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { CXX0XAttributeList Attr; if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) Attr = ParseCXX0XAttributes(); + llvm::OwningPtr<AttributeList> AttrList(Attr.AttrList); // Cases in this switch statement should fall through if the parser expects // the token to end in a semicolon (in which case SemiError should be set), @@ -102,13 +103,14 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { case tok::identifier: if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement // identifier ':' statement - return ParseLabeledStatement(Attr.AttrList); + return ParseLabeledStatement(AttrList.take()); } // PASS THROUGH. default: { if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) { SourceLocation DeclStart = Tok.getLocation(), DeclEnd; + AttrList.take(); //Passing 'Attr' to ParseDeclaration transfers ownership. DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext, DeclEnd, Attr); return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd); @@ -135,43 +137,43 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } case tok::kw_case: // C99 6.8.1: labeled-statement - return ParseCaseStatement(Attr.AttrList); + return ParseCaseStatement(AttrList.take()); case tok::kw_default: // C99 6.8.1: labeled-statement - return ParseDefaultStatement(Attr.AttrList); + return ParseDefaultStatement(AttrList.take()); case tok::l_brace: // C99 6.8.2: compound-statement - return ParseCompoundStatement(Attr.AttrList); + return ParseCompoundStatement(AttrList.take()); case tok::semi: // C99 6.8.3p3: expression[opt] ';' return Actions.ActOnNullStmt(ConsumeToken()); case tok::kw_if: // C99 6.8.4.1: if-statement - return ParseIfStatement(Attr.AttrList); + return ParseIfStatement(AttrList.take()); case tok::kw_switch: // C99 6.8.4.2: switch-statement - return ParseSwitchStatement(Attr.AttrList); + return ParseSwitchStatement(AttrList.take()); case tok::kw_while: // C99 6.8.5.1: while-statement - return ParseWhileStatement(Attr.AttrList); + return ParseWhileStatement(AttrList.take()); case tok::kw_do: // C99 6.8.5.2: do-statement - Res = ParseDoStatement(Attr.AttrList); + Res = ParseDoStatement(AttrList.take()); SemiError = "do/while"; break; case tok::kw_for: // C99 6.8.5.3: for-statement - return ParseForStatement(Attr.AttrList); + return ParseForStatement(AttrList.take()); case tok::kw_goto: // C99 6.8.6.1: goto-statement - Res = ParseGotoStatement(Attr.AttrList); + Res = ParseGotoStatement(AttrList.take()); SemiError = "goto"; break; case tok::kw_continue: // C99 6.8.6.2: continue-statement - Res = ParseContinueStatement(Attr.AttrList); + Res = ParseContinueStatement(AttrList.take()); SemiError = "continue"; break; case tok::kw_break: // C99 6.8.6.3: break-statement - Res = ParseBreakStatement(Attr.AttrList); + Res = ParseBreakStatement(AttrList.take()); SemiError = "break"; break; case tok::kw_return: // C99 6.8.6.4: return-statement - Res = ParseReturnStatement(Attr.AttrList); + Res = ParseReturnStatement(AttrList.take()); SemiError = "return"; break; @@ -187,7 +189,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } case tok::kw_try: // C++ 15: try-block - return ParseCXXTryBlock(Attr.AttrList); + return ParseCXXTryBlock(AttrList.take()); } // If we reached this code, the statement must end in a semicolon. @@ -215,6 +217,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && "Not an identifier!"); + llvm::OwningPtr<AttributeList> AttrList(Attr); Token IdentTok = Tok; // Save the whole token. ConsumeToken(); // eat the identifier. @@ -225,7 +228,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { // Read label attributes, if present. if (Tok.is(tok::kw___attribute)) - Attr = addAttributeLists(Attr, ParseGNUAttributes()); + AttrList.reset(addAttributeLists(AttrList.take(), ParseGNUAttributes())); OwningStmtResult SubStmt(ParseStatement()); @@ -233,6 +236,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { if (SubStmt.isInvalid()) SubStmt = Actions.ActOnNullStmt(ColonLoc); + // FIXME: use attributes? return Actions.ActOnLabelStmt(IdentTok.getLocation(), IdentTok.getIdentifierInfo(), ColonLoc, move(SubStmt)); @@ -246,6 +250,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { assert(Tok.is(tok::kw_case) && "Not a case stmt!"); // FIXME: Use attributes? + delete Attr; // It is very very common for code to contain many case statements recursively // nested, as in (but usually without indentation): @@ -371,6 +376,8 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { /// Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { //FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_default) && "Not a default stmt!"); SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'. @@ -427,6 +434,8 @@ Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { Parser::OwningStmtResult Parser::ParseCompoundStatement(AttributeList *Attr, bool isStmtExpr) { //FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::l_brace) && "Not a compount stmt!"); // Enter a scope to hold everything within the compound stmt. Compound @@ -562,6 +571,8 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult, /// Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_if) && "Not an if stmt!"); SourceLocation IfLoc = ConsumeToken(); // eat the 'if'. @@ -686,6 +697,8 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { /// [C++] 'switch' '(' condition ')' statement Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_switch) && "Not a switch stmt!"); SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'. @@ -741,19 +754,19 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { // Read the body statement. OwningStmtResult Body(ParseStatement()); - // Pop the body scope if needed. + // Pop the scopes. InnerScope.Exit(); - - if (Body.isInvalid()) { - Body = Actions.ActOnNullStmt(Tok.getLocation()); - // FIXME: Remove the case statement list from the Switch statement. - } - SwitchScope.Exit(); - if (Cond.isInvalid() && !CondVar.get()) + if (Cond.isInvalid() && !CondVar.get()) { + Actions.ActOnSwitchBodyError(SwitchLoc, move(Switch), move(Body)); return StmtError(); + } + if (Body.isInvalid()) + // FIXME: Remove the case statement list from the Switch statement. + Body = Actions.ActOnNullStmt(Tok.getLocation()); + return Actions.ActOnFinishSwitchStmt(SwitchLoc, move(Switch), move(Body)); } @@ -763,6 +776,8 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { /// [C++] 'while' '(' condition ')' statement Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_while) && "Not a while stmt!"); SourceLocation WhileLoc = Tok.getLocation(); ConsumeToken(); // eat the 'while'. @@ -836,6 +851,8 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { /// Note: this lets the caller parse the end ';'. Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_do) && "Not a do stmt!"); SourceLocation DoLoc = ConsumeToken(); // eat the 'do'. @@ -911,6 +928,8 @@ Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { /// Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_for) && "Not a for stmt!"); SourceLocation ForLoc = ConsumeToken(); // eat the 'for'. @@ -1081,6 +1100,8 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { /// Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. @@ -1115,6 +1136,8 @@ Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) { /// Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. return Actions.ActOnContinueStmt(ContinueLoc, CurScope); } @@ -1127,6 +1150,8 @@ Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) { /// Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. return Actions.ActOnBreakStmt(BreakLoc, CurScope); } @@ -1136,6 +1161,8 @@ Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) { /// 'return' expression[opt] ';' Parser::OwningStmtResult Parser::ParseReturnStatement(AttributeList *Attr) { // FIXME: Use attributes? + delete Attr; + assert(Tok.is(tok::kw_return) && "Not a return stmt!"); SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. @@ -1171,7 +1198,6 @@ Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() { Tok.isNot(tok::r_brace) && Tok.isNot(tok::semi) && Tok.isNot(tok::eof)); } - llvm::SmallVector<std::string, 4> Names; Token t; t.setKind(tok::string_literal); t.setLiteralData("\"FIXME: not done\""); @@ -1181,7 +1207,7 @@ Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() { ExprVector Constraints(Actions); ExprVector Exprs(Actions); ExprVector Clobbers(Actions); - return Actions.ActOnAsmStmt(Tok.getLocation(), true, true, 0, 0, Names.data(), + return Actions.ActOnAsmStmt(Tok.getLocation(), true, true, 0, 0, 0, move_arg(Constraints), move_arg(Exprs), move(AsmString), move_arg(Clobbers), Tok.getLocation(), true); @@ -1245,7 +1271,7 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { if (AsmString.isInvalid()) return StmtError(); - llvm::SmallVector<std::string, 4> Names; + llvm::SmallVector<IdentifierInfo *, 4> Names; ExprVector Constraints(Actions); ExprVector Exprs(Actions); ExprVector Clobbers(Actions); @@ -1336,9 +1362,9 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { /// // // FIXME: Avoid unnecessary std::string trashing. -bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names, - llvm::SmallVectorImpl<ExprTy*> &Constraints, - llvm::SmallVectorImpl<ExprTy*> &Exprs) { +bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, + llvm::SmallVectorImpl<ExprTy *> &Constraints, + llvm::SmallVectorImpl<ExprTy *> &Exprs) { // 'asm-operands' isn't present? if (!isTokenStringLiteral() && Tok.isNot(tok::l_square)) return false; @@ -1357,10 +1383,10 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names, IdentifierInfo *II = Tok.getIdentifierInfo(); ConsumeToken(); - Names.push_back(II->getName()); + Names.push_back(II); MatchRHSPunctuation(tok::r_square, Loc); } else - Names.push_back(std::string()); + Names.push_back(0); OwningExprResult Constraint(ParseAsmStringLiteral()); if (Constraint.isInvalid()) { @@ -1448,6 +1474,8 @@ Parser::DeclPtrTy Parser::ParseFunctionTryBlock(DeclPtrTy Decl) { /// Parser::OwningStmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) { // FIXME: Add attributes? + delete Attr; + assert(Tok.is(tok::kw_try) && "Expected 'try'"); SourceLocation TryLoc = ConsumeToken(); diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 797c1df..12f26bf 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -836,7 +836,7 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get()); if (SS && SS->isNotEmpty()) // it was a C++ qualified type name. Tok.setLocation(SS->getBeginLoc()); - Tok.setAnnotationEndLoc(TemplateId->TemplateNameLoc); + // End location stays the same // Replace the template-id annotation token, and possible the scope-specifier // that precedes it, with the typename annotation token. diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 51c5670..6251a2f 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -672,6 +672,11 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, Parser::TPResult Parser::isCXXDeclarationSpecifier() { switch (Tok.getKind()) { case tok::identifier: // foo::bar + // Check for need to substitute AltiVec __vector keyword + // for "vector" identifier. + if (TryAltiVecVectorToken()) + return TPResult::True(); + // Fall through. case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -750,6 +755,10 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw___ptr64: case tok::kw___forceinline: return TPResult::True(); + + // AltiVec + case tok::kw___vector: + 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. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index f2bc303..30899c5 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -346,6 +346,11 @@ void Parser::Initialize() { } Ident_super = &PP.getIdentifierTable().get("super"); + + if (getLang().AltiVec) { + Ident_vector = &PP.getIdentifierTable().get("vector"); + Ident_pixel = &PP.getIdentifierTable().get("pixel"); + } } /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the @@ -588,7 +593,6 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, if (Tok.is(tok::string_literal) && getLang().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_extern && DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { - DS.abort(); DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext); return Actions.ConvertDeclToDeclGroup(TheDecl); } @@ -738,11 +742,11 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { // Handle the full declarator list. while (1) { - Action::AttrTy *AttrList; // If attributes are present, parse them. + llvm::OwningPtr<AttributeList> AttrList; if (Tok.is(tok::kw___attribute)) // FIXME: attach attributes too. - AttrList = ParseGNUAttributes(); + AttrList.reset(ParseGNUAttributes()); // Ask the actions module to compute the type for this declarator. Action::DeclPtrTy Param = @@ -835,6 +839,16 @@ Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { assert(Tok.is(tok::kw_asm) && "Not an asm!"); SourceLocation Loc = ConsumeToken(); + if (Tok.is(tok::kw_volatile)) { + // Remove from the end of 'asm' to the end of 'volatile'. + SourceRange RemovalRange(PP.getLocForEndOfToken(Loc), + PP.getLocForEndOfToken(Tok.getLocation())); + + Diag(Tok, diag::warn_file_asm_volatile) + << CodeModificationHint::CreateRemoval(RemovalRange); + ConsumeToken(); + } + if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen_after) << "asm"; return ExprError(); @@ -930,9 +944,10 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { return false; } + SourceLocation EndLoc = Tok.getLastLoc(); Tok.setKind(tok::annot_typename); Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get()); - Tok.setAnnotationEndLoc(Tok.getLocation()); + Tok.setAnnotationEndLoc(EndLoc); Tok.setLocation(TypenameLoc); PP.AnnotateCachedTokens(Tok); return true; |