forked from OSchip/llvm-project
parent
7b9c57083b
commit
b219c90d7b
|
@ -404,7 +404,27 @@ namespace {
|
|||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// C++ Statements
|
||||
virtual DeclTy *ActOnExceptionDeclarator(Scope *S, Declarator &D) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
|
||||
DeclTy *ExceptionDecl,
|
||||
StmtArg HandlerBlock) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return StmtEmpty();
|
||||
}
|
||||
|
||||
virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
|
||||
StmtArg TryBlock,
|
||||
MultiStmtArg Handlers) {
|
||||
llvm::cout << __FUNCTION__ << "\n";
|
||||
return StmtEmpty();
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -605,6 +605,8 @@ DIAG(err_expected_member_or_base_name, ERROR,
|
|||
"expected class member or base class name")
|
||||
DIAG(ext_ellipsis_exception_spec, EXTENSION,
|
||||
"exception specification of '...' is a Microsoft extension")
|
||||
DIAG(err_expected_catch, ERROR,
|
||||
"expected catch")
|
||||
|
||||
/// C++ Templates
|
||||
DIAG(err_expected_template, ERROR,
|
||||
|
|
|
@ -478,7 +478,24 @@ public:
|
|||
StmtTy *SynchBody) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// C++ Statements
|
||||
virtual DeclTy *ActOnExceptionDeclarator(Scope *S, Declarator &D) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
|
||||
DeclTy *ExceptionDecl,
|
||||
StmtArg HandlerBlock) {
|
||||
return StmtEmpty();
|
||||
}
|
||||
|
||||
virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
|
||||
StmtArg TryBlock,
|
||||
MultiStmtArg Handlers) {
|
||||
return StmtEmpty();
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -646,7 +646,8 @@ public:
|
|||
BlockContext, // Declaration within a block in a function.
|
||||
ForContext, // Declaration within first part of a for loop.
|
||||
ConditionContext, // Condition declaration in a C++ if/switch/while/for.
|
||||
TemplateParamContext // Within a template parameter list.
|
||||
TemplateParamContext,// Within a template parameter list.
|
||||
CXXCatchContext // C++ catch exception-declaration
|
||||
};
|
||||
|
||||
/// DeclaratorKind - The kind of declarator this represents.
|
||||
|
@ -762,7 +763,7 @@ public:
|
|||
/// parameter lists.
|
||||
bool mayOmitIdentifier() const {
|
||||
return Context == TypeNameContext || Context == PrototypeContext ||
|
||||
Context == TemplateParamContext;
|
||||
Context == TemplateParamContext || Context == CXXCatchContext;
|
||||
}
|
||||
|
||||
/// mayHaveIdentifier - Return true if the identifier is either optional or
|
||||
|
|
|
@ -724,13 +724,23 @@ private:
|
|||
OwningStmtResult ParseReturnStatement();
|
||||
OwningStmtResult ParseAsmStatement(bool &msAsm);
|
||||
OwningStmtResult FuzzyParseMicrosoftAsmStatement();
|
||||
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
|
||||
llvm::SmallVectorImpl<ExprTy*> &Constraints,
|
||||
llvm::SmallVectorImpl<ExprTy*> &Exprs);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++ 6: Statements and Blocks
|
||||
|
||||
OwningStmtResult ParseCXXTryBlock();
|
||||
OwningStmtResult ParseCXXCatchBlock();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Objective-C Statements
|
||||
|
||||
OwningStmtResult ParseObjCAtStatement(SourceLocation atLoc);
|
||||
OwningStmtResult ParseObjCTryStmt(SourceLocation atLoc);
|
||||
OwningStmtResult ParseObjCThrowStmt(SourceLocation atLoc);
|
||||
OwningStmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
|
||||
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
|
||||
llvm::SmallVectorImpl<ExprTy*> &Constraints,
|
||||
llvm::SmallVectorImpl<ExprTy*> &Exprs);
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -38,6 +38,7 @@ using namespace clang;
|
|||
/// iteration-statement
|
||||
/// jump-statement
|
||||
/// [C++] declaration-statement
|
||||
/// [C++] try-block
|
||||
/// [OBC] objc-throw-statement
|
||||
/// [OBC] objc-try-catch-statement
|
||||
/// [OBC] objc-synchronized-statement
|
||||
|
@ -161,7 +162,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
|||
SemiError = "return statement";
|
||||
break;
|
||||
|
||||
case tok::kw_asm:
|
||||
case tok::kw_asm: {
|
||||
bool msAsm = false;
|
||||
Res = ParseAsmStatement(msAsm);
|
||||
if (msAsm) return move(Res);
|
||||
|
@ -169,6 +170,10 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
|
|||
break;
|
||||
}
|
||||
|
||||
case tok::kw_try: // C++ 15: try-block
|
||||
return ParseCXXTryBlock();
|
||||
}
|
||||
|
||||
// If we reached this code, the statement must end in a semicolon.
|
||||
if (Tok.is(tok::semi)) {
|
||||
ConsumeToken();
|
||||
|
@ -1243,3 +1248,89 @@ Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
|
|||
|
||||
return Actions.ActOnFinishFunctionBody(Decl, move_convert(FnBody));
|
||||
}
|
||||
|
||||
/// ParseCXXTryBlock - Parse a C++ try-block.
|
||||
///
|
||||
/// try-block:
|
||||
/// 'try' compound-statement handler-seq
|
||||
///
|
||||
/// handler-seq:
|
||||
/// handler handler-seq[opt]
|
||||
///
|
||||
Parser::OwningStmtResult Parser::ParseCXXTryBlock() {
|
||||
assert(Tok.is(tok::kw_try) && "Expected 'try'");
|
||||
|
||||
SourceLocation TryLoc = ConsumeToken();
|
||||
if (Tok.isNot(tok::l_brace))
|
||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||
OwningStmtResult TryBlock(ParseCompoundStatement());
|
||||
if (TryBlock.isInvalid())
|
||||
return move(TryBlock);
|
||||
|
||||
StmtVector Handlers(Actions);
|
||||
if (Tok.isNot(tok::kw_catch))
|
||||
return StmtError(Diag(Tok, diag::err_expected_catch));
|
||||
while (Tok.is(tok::kw_catch)) {
|
||||
OwningStmtResult Handler(ParseCXXCatchBlock());
|
||||
if (!Handler.isInvalid())
|
||||
Handlers.push_back(Handler.release());
|
||||
}
|
||||
// Don't bother creating the full statement if we don't have any usable
|
||||
// handlers.
|
||||
if (Handlers.empty())
|
||||
return StmtError();
|
||||
|
||||
return Actions.ActOnCXXTryBlock(TryLoc, move_convert(TryBlock),
|
||||
move_convert(Handlers));
|
||||
}
|
||||
|
||||
/// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard
|
||||
///
|
||||
/// handler:
|
||||
/// 'catch' '(' exception-declaration ')' compound-statement
|
||||
///
|
||||
/// exception-declaration:
|
||||
/// type-specifier-seq declarator
|
||||
/// type-specifier-seq abstract-declarator
|
||||
/// type-specifier-seq
|
||||
/// '...'
|
||||
///
|
||||
Parser::OwningStmtResult Parser::ParseCXXCatchBlock() {
|
||||
assert(Tok.is(tok::kw_catch) && "Expected 'catch'");
|
||||
|
||||
SourceLocation CatchLoc = ConsumeToken();
|
||||
|
||||
SourceLocation LParenLoc = Tok.getLocation();
|
||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
|
||||
return StmtError();
|
||||
|
||||
// C++ 3.3.2p3:
|
||||
// The name in a catch exception-declaration is local to the handler and
|
||||
// shall not be redeclared in the outermost block of the handler.
|
||||
ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope);
|
||||
|
||||
// exception-declaration is equivalent to '...' or a parameter-declaration
|
||||
// without default arguments.
|
||||
DeclTy *ExceptionDecl = 0;
|
||||
if (Tok.isNot(tok::ellipsis)) {
|
||||
DeclSpec DS;
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
Declarator ExDecl(DS, Declarator::CXXCatchContext);
|
||||
ParseDeclarator(ExDecl);
|
||||
ExceptionDecl = Actions.ActOnExceptionDeclarator(CurScope, ExDecl);
|
||||
} else
|
||||
ConsumeToken();
|
||||
|
||||
if (MatchRHSPunctuation(tok::r_paren, LParenLoc).isInvalid())
|
||||
return StmtError();
|
||||
|
||||
if (Tok.isNot(tok::l_brace))
|
||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||
|
||||
OwningStmtResult Block(ParseCompoundStatement());
|
||||
if (Block.isInvalid())
|
||||
return move(Block);
|
||||
|
||||
return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl,
|
||||
move_convert(Block));
|
||||
}
|
||||
|
|
|
@ -151,6 +151,10 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
|
|||
if (S->isDeclScope(D))
|
||||
return true;
|
||||
if (LangOpt.CPlusPlus) {
|
||||
// C++ 3.3.2p3:
|
||||
// The name declared in a catch exception-declaration is local to the
|
||||
// handler and shall not be redeclared in the outermost block of the
|
||||
// handler.
|
||||
// C++ 3.3.2p4:
|
||||
// Names declared in the for-init-statement, and in the condition of if,
|
||||
// while, for, and switch statements are local to the if, while, for, or
|
||||
|
|
|
@ -631,7 +631,15 @@ public:
|
|||
virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
|
||||
ExprTy *SynchExpr,
|
||||
StmtTy *SynchBody);
|
||||
|
||||
|
||||
//virtual DeclTy *ActOnExceptionDeclarator(Scope *S, Declarator &D);
|
||||
//virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
|
||||
// DeclTy *ExceptionDecl,
|
||||
// StmtArg HandlerBlock);
|
||||
//virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
|
||||
// StmtArg TryBlock,
|
||||
// MultiStmtArg Handlers);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks: SemaExpr.cpp.
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
void f()
|
||||
{
|
||||
try {
|
||||
;
|
||||
} catch(int i) {
|
||||
;
|
||||
} catch(...) {
|
||||
}
|
||||
}
|
||||
|
||||
void g()
|
||||
{
|
||||
try; // expected-error {{expected '{'}}
|
||||
|
||||
try {}
|
||||
catch; // expected-error {{expected '('}}
|
||||
|
||||
try {}
|
||||
catch (...); // expected-error {{expected '{'}}
|
||||
|
||||
try {}
|
||||
catch {} // expected-error {{expected '('}}
|
||||
}
|
Loading…
Reference in New Issue