summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp72
1 files changed, 55 insertions, 17 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8674485d5f8..5e6c51c1ee9 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -705,13 +705,21 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
///[C90/C++]init-declarator-list ';' [TODO]
/// [OMP] threadprivate-directive [TODO]
///
+/// for-range-declaration: [C++0x 6.5p1: stmt.ranged]
+/// attribute-specifier-seq[opt] type-specifier-seq declarator
+///
/// If RequireSemi is false, this does not check for a ';' at the end of the
/// declaration. If it is true, it checks for and eats it.
+///
+/// If FRI is non-null, we might be parsing a for-range-declaration instead
+/// of a simple-declaration. If we find that we are, we also parse the
+/// for-range-initializer, and place it here.
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
unsigned Context,
SourceLocation &DeclEnd,
ParsedAttributes &attrs,
- bool RequireSemi) {
+ bool RequireSemi,
+ ForRangeInit *FRI) {
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this);
DS.takeAttributesFrom(attrs);
@@ -731,7 +739,7 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
- return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd);
+ return ParseDeclGroup(DS, Context, /*FunctionDefs=*/ false, &DeclEnd, FRI);
}
/// ParseDeclGroup - Having concluded that this is either a function
@@ -740,7 +748,8 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
unsigned Context,
bool AllowFunctionDefinitions,
- SourceLocation *DeclEnd) {
+ SourceLocation *DeclEnd,
+ ForRangeInit *FRI) {
// Parse the first declarator.
ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Context));
ParseDeclarator(D);
@@ -786,8 +795,24 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
}
}
+ if (ParseAttributesAfterDeclarator(D))
+ return DeclGroupPtrTy();
+
+ // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we
+ // must parse and analyze the for-range-initializer before the declaration is
+ // analyzed.
+ if (FRI && Tok.is(tok::colon)) {
+ FRI->ColonLoc = ConsumeToken();
+ // FIXME: handle braced-init-list here.
+ FRI->RangeExpr = ParseExpression();
+ Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
+ Actions.ActOnCXXForRangeDecl(ThisDecl);
+ Actions.FinalizeDeclaration(ThisDecl);
+ return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, &ThisDecl, 1);
+ }
+
llvm::SmallVector<Decl *, 8> DeclsInGroup;
- Decl *FirstDecl = ParseDeclarationAfterDeclarator(D);
+ Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
D.complete(FirstDecl);
if (FirstDecl)
DeclsInGroup.push_back(FirstDecl);
@@ -841,6 +866,26 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
DeclsInGroup.size());
}
+/// Parse an optional simple-asm-expr and attributes, and attach them to a
+/// declarator. Returns true on an error.
+bool Parser::ParseAttributesAfterDeclarator(Declarator &D) {
+ // If a simple-asm-expr is present, parse it.
+ if (Tok.is(tok::kw_asm)) {
+ SourceLocation Loc;
+ ExprResult AsmLabel(ParseSimpleAsm(&Loc));
+ if (AsmLabel.isInvalid()) {
+ SkipUntil(tok::semi, true, true);
+ return true;
+ }
+
+ D.setAsmLabel(AsmLabel.release());
+ D.SetRangeEnd(Loc);
+ }
+
+ MaybeParseGNUAttributes(D);
+ return false;
+}
+
/// \brief Parse 'declaration' after parsing 'declaration-specifiers
/// declarator'. This method parses the remainder of the declaration
/// (including any attributes or initializer, among other things) and
@@ -864,21 +909,14 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
///
Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
- // If a simple-asm-expr is present, parse it.
- if (Tok.is(tok::kw_asm)) {
- SourceLocation Loc;
- ExprResult AsmLabel(ParseSimpleAsm(&Loc));
- if (AsmLabel.isInvalid()) {
- SkipUntil(tok::semi, true, true);
- return 0;
- }
+ if (ParseAttributesAfterDeclarator(D))
+ return 0;
- D.setAsmLabel(AsmLabel.release());
- D.SetRangeEnd(Loc);
- }
-
- MaybeParseGNUAttributes(D);
+ return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
+}
+Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
+ const ParsedTemplateInfo &TemplateInfo) {
// Inform the current actions module that we just parsed this declarator.
Decl *ThisDecl = 0;
switch (TemplateInfo.Kind) {
OpenPOWER on IntegriCloud