[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