[cfe-commits] r61312 - in /cfe/trunk: Driver/PrintParserCallbacks.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h lib/Parse/ParseStmt.cpp lib/Sema/IdentifierResolver.cpp lib/Sema/Sema.h test/Parser/cxx-try.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Sun Dec 21 08:41:38 PST 2008
Author: cornedbee
Date: Sun Dec 21 10:41:36 2008
New Revision: 61312
URL: http://llvm.org/viewvc/llvm-project?rev=61312&view=rev
Log:
Parser support for C++ try-catch.
Added:
cfe/trunk/test/Parser/cxx-try.cpp
Modified:
cfe/trunk/Driver/PrintParserCallbacks.cpp
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/DeclSpec.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Sema/IdentifierResolver.cpp
cfe/trunk/lib/Sema/Sema.h
Modified: cfe/trunk/Driver/PrintParserCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/PrintParserCallbacks.cpp?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/Driver/PrintParserCallbacks.cpp (original)
+++ cfe/trunk/Driver/PrintParserCallbacks.cpp Sun Dec 21 10:41:36 2008
@@ -404,7 +404,27 @@
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.
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sun Dec 21 10:41:36 2008
@@ -605,6 +605,8 @@
"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,
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sun Dec 21 10:41:36 2008
@@ -478,7 +478,24 @@
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.
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Sun Dec 21 10:41:36 2008
@@ -646,7 +646,8 @@
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 @@
/// 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
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Dec 21 10:41:36 2008
@@ -724,13 +724,23 @@
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);
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Sun Dec 21 10:41:36 2008
@@ -38,6 +38,7 @@
/// 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 @@
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 @@
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 @@
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));
+}
Modified: cfe/trunk/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.cpp?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Sun Dec 21 10:41:36 2008
@@ -151,6 +151,10 @@
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
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=61312&r1=61311&r2=61312&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Dec 21 10:41:36 2008
@@ -631,7 +631,15 @@
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.
Added: cfe/trunk/test/Parser/cxx-try.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-try.cpp?rev=61312&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx-try.cpp (added)
+++ cfe/trunk/test/Parser/cxx-try.cpp Sun Dec 21 10:41:36 2008
@@ -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 '('}}
+}
More information about the cfe-commits
mailing list