summaryrefslogtreecommitdiffstats
path: root/lib/Parse
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
commitfd035e6496665b1f1197868e21cb0a4594e8db6e (patch)
tree53010172e19c77ea447bcd89e117cda052ab52e0 /lib/Parse
parent2fce988e86bc01829142e4362d4eff1af0925147 (diff)
downloadFreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.zip
FreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.tar.gz
Update clang to r96341.
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/DeclSpec.cpp37
-rw-r--r--lib/Parse/Makefile1
-rw-r--r--lib/Parse/ParseDecl.cpp94
-rw-r--r--lib/Parse/ParseDeclCXX.cpp122
-rw-r--r--lib/Parse/ParseExpr.cpp41
-rw-r--r--lib/Parse/ParseExprCXX.cpp7
-rw-r--r--lib/Parse/ParseObjc.cpp24
-rw-r--r--lib/Parse/ParseStmt.cpp90
-rw-r--r--lib/Parse/ParseTemplate.cpp2
-rw-r--r--lib/Parse/ParseTentative.cpp9
-rw-r--r--lib/Parse/Parser.cpp23
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;
OpenPOWER on IntegriCloud