[cfe-commits] r70389 - in /cfe/trunk: include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h lib/Parse/DeclSpec.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Sema/SemaDecl.cpp test/Parser/cxx-exception-spec.cpp www/cxx_status.html

Sebastian Redl sebastian.redl at getdesigned.at
Wed Apr 29 10:30:04 PDT 2009


Author: cornedbee
Date: Wed Apr 29 12:30:04 2009
New Revision: 70389

URL: http://llvm.org/viewvc/llvm-project?rev=70389&view=rev
Log:
Have the parser communicate the exception specification to the action.

Modified:
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/DeclSpec.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Parser/cxx-exception-spec.cpp
    cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Wed Apr 29 12:30:04 2009
@@ -512,31 +512,45 @@
     /// argument.  If the function is () or (a,b,c), then it has no prototype,
     /// and is treated as a K&R-style function.
     bool hasPrototype : 1;
-    
+
     /// isVariadic - If this function has a prototype, and if that
     /// proto ends with ',...)', this is true. When true, EllipsisLoc
     /// contains the location of the ellipsis.
     bool isVariadic : 1;
 
-    /// When isVariadic is true, the location of the ellipsis in the source.
-    unsigned EllipsisLoc;
-
     /// The type qualifiers: const/volatile/restrict.
     /// The qualifier bitmask values are the same as in QualType. 
     unsigned TypeQuals : 3;
 
+    /// hasExceptionSpec - True if the function has an exception specification.
+    bool hasExceptionSpec : 1;
+
+    /// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
+    bool hasAnyExceptionSpec : 1;
+
     /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
     bool DeleteArgInfo : 1;
 
+    /// When isVariadic is true, the location of the ellipsis in the source.
+    unsigned EllipsisLoc;
+
     /// NumArgs - This is the number of formal arguments provided for the
     /// declarator.
     unsigned NumArgs;
 
+    /// NumExceptions - This is the number of types in the exception-decl, if
+    /// the function has one.
+    unsigned NumExceptions;
+
     /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
     /// describe the arguments for this function declarator.  This is null if
     /// there are no arguments specified.
     ParamInfo *ArgInfo;
-    
+
+    /// Exceptions - This is a pointer to a new[]'d array of TypeTy pointers
+    /// that contains the types in the function's exception specification.
+    ActionBase::TypeTy **Exceptions;
+
     /// freeArgs - reset the argument list to having zero arguments.  This is
     /// used in various places for error recovery.
     void freeArgs() {
@@ -546,10 +560,11 @@
       }
       NumArgs = 0;
     }
-    
+
     void destroy() {
       if (DeleteArgInfo)
         delete[] ArgInfo;
+      delete[] Exceptions;
     }
 
     SourceLocation getEllipsisLoc() const {
@@ -670,7 +685,10 @@
   static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
                                      SourceLocation EllipsisLoc,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
-                                     unsigned TypeQuals, SourceLocation Loc,
+                                     unsigned TypeQuals, bool hasExceptionSpec,
+                                     bool hasAnyExceptionSpec,
+                                     ActionBase::TypeTy **Exceptions,
+                                     unsigned NumExceptions, SourceLocation Loc,
                                      Declarator &TheDeclarator);
   
   /// getBlockPointer - Return a DeclaratorChunk for a block.

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Apr 29 12:30:04 2009
@@ -682,7 +682,9 @@
   // C++ 15: C++ Throw Expression
   OwningExprResult ParseThrowExpression();
   // EndLoc is filled with the location of the last token of the specification.
-  bool ParseExceptionSpecification(SourceLocation &EndLoc);
+  bool ParseExceptionSpecification(SourceLocation &EndLoc,
+                                   std::vector<TypeTy*> &Exceptions,
+                                   bool &hasAnyExceptionSpec);
 
   //===--------------------------------------------------------------------===//
   // C++ 2.13.5: C++ Boolean Literals

Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Wed Apr 29 12:30:04 2009
@@ -32,19 +32,27 @@
                                              ParamInfo *ArgInfo,
                                              unsigned NumArgs,
                                              unsigned TypeQuals,
+                                             bool hasExceptionSpec,
+                                             bool hasAnyExceptionSpec,
+                                             ActionBase::TypeTy **Exceptions,
+                                             unsigned NumExceptions,
                                              SourceLocation Loc,
                                              Declarator &TheDeclarator) {
   DeclaratorChunk I;
-  I.Kind             = Function;
-  I.Loc              = Loc;
-  I.Fun.hasPrototype = hasProto;
-  I.Fun.isVariadic   = isVariadic;
-  I.Fun.EllipsisLoc  = EllipsisLoc.getRawEncoding();
-  I.Fun.DeleteArgInfo = false;
-  I.Fun.TypeQuals    = TypeQuals;
-  I.Fun.NumArgs      = NumArgs;
-  I.Fun.ArgInfo      = 0;
-  
+  I.Kind                 = Function;
+  I.Loc                  = Loc;
+  I.Fun.hasPrototype     = hasProto;
+  I.Fun.isVariadic       = isVariadic;
+  I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding();
+  I.Fun.DeleteArgInfo    = false;
+  I.Fun.TypeQuals        = TypeQuals;
+  I.Fun.NumArgs          = NumArgs;
+  I.Fun.ArgInfo          = 0;
+  I.Fun.hasExceptionSpec = hasExceptionSpec;
+  I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
+  I.Fun.NumExceptions    = NumExceptions;
+  I.Fun.Exceptions       = 0;
+
   // new[] an argument array if needed.
   if (NumArgs) {
     // If the 'InlineParams' in Declarator is unused and big enough, put our
@@ -62,6 +70,12 @@
     }
     memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
   }
+  // new[] an exception array if needed
+  if (NumExceptions) {
+    I.Fun.Exceptions = new ActionBase::TypeTy*[NumExceptions];
+    memcpy(I.Fun.Exceptions, Exceptions,
+           sizeof(ActionBase::TypeTy*)*NumExceptions);
+  }
   return I;
 }
 

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Apr 29 12:30:04 2009
@@ -2246,14 +2246,21 @@
 
     // cv-qualifier-seq[opt].
     DeclSpec DS;
+    bool hasExceptionSpec = false;
+    bool hasAnyExceptionSpec = false;
+    // FIXME: Does an empty vector ever allocate? Exception specifications are
+    // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-)
+    std::vector<TypeTy*> Exceptions;
     if (getLang().CPlusPlus) {
       ParseTypeQualifierListOpt(DS, false /*no attributes*/);
       if (!DS.getSourceRange().getEnd().isInvalid())
         Loc = DS.getSourceRange().getEnd();
 
       // Parse exception-specification[opt].
-      if (Tok.is(tok::kw_throw))
-        ParseExceptionSpecification(Loc);
+      if (Tok.is(tok::kw_throw)) {
+        hasExceptionSpec = true;
+        ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec);
+      }
     }
 
     // Remember that we parsed a function type, and remember the attributes.
@@ -2263,6 +2270,11 @@
                                                SourceLocation(),
                                                /*arglist*/ 0, 0,
                                                DS.getTypeQualifiers(),
+                                               hasExceptionSpec,
+                                               hasAnyExceptionSpec,
+                                               Exceptions.empty() ? 0 :
+                                                 &Exceptions[0],
+                                               Exceptions.size(),
                                                LParenLoc, D),
                   Loc);
     return;
@@ -2406,6 +2418,11 @@
   SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
   DeclSpec DS;
+  bool hasExceptionSpec = false;
+  bool hasAnyExceptionSpec = false;
+  // FIXME: Does an empty vector ever allocate? Exception specifications are
+  // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-)
+  std::vector<TypeTy*> Exceptions;
   if (getLang().CPlusPlus) {
     // Parse cv-qualifier-seq[opt].
     ParseTypeQualifierListOpt(DS, false /*no attributes*/);
@@ -2413,8 +2430,10 @@
         Loc = DS.getSourceRange().getEnd();
 
     // Parse exception-specification[opt].
-    if (Tok.is(tok::kw_throw))
-      ParseExceptionSpecification(Loc);
+    if (Tok.is(tok::kw_throw)) {
+      hasExceptionSpec = true;
+      ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec);
+    }
   }
 
   // Remember that we parsed a function type, and remember the attributes.
@@ -2422,7 +2441,11 @@
                                              EllipsisLoc,
                                              &ParamInfo[0], ParamInfo.size(),
                                              DS.getTypeQualifiers(),
-                                             LParenLoc, D),
+                                             hasExceptionSpec,
+                                             hasAnyExceptionSpec,
+                                             Exceptions.empty() ? 0 :
+                                               &Exceptions[0],
+                                             Exceptions.size(), LParenLoc, D),
                 Loc);
 }
 
@@ -2496,7 +2519,9 @@
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
                                              SourceLocation(),
                                              &ParamInfo[0], ParamInfo.size(),
-                                             /*TypeQuals*/0, LParenLoc, D),
+                                             /*TypeQuals*/0,
+                                             /*exception*/false, false, 0, 0,
+                                             LParenLoc, D),
                 RLoc);
 }
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Apr 29 12:30:04 2009
@@ -1112,7 +1112,9 @@
 ///         type-id
 ///         type-id-list ',' type-id
 ///
-bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
+bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
+                                         std::vector<TypeTy*> &Exceptions,
+                                         bool &hasAnyExceptionSpec) {
   assert(Tok.is(tok::kw_throw) && "expected throw");
   
   SourceLocation ThrowLoc = ConsumeToken();
@@ -1125,6 +1127,7 @@
   // Parse throw(...), a Microsoft extension that means "this function
   // can throw anything".
   if (Tok.is(tok::ellipsis)) {
+    hasAnyExceptionSpec = true;
     SourceLocation EllipsisLoc = ConsumeToken();
     if (!getLang().Microsoft)
       Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
@@ -1134,10 +1137,12 @@
 
   // Parse the sequence of type-ids.
   while (Tok.isNot(tok::r_paren)) {
-    ParseTypeName();
+    TypeResult Res(ParseTypeName());
+    if (!Res.isInvalid())
+      Exceptions.push_back(Res.get());
     if (Tok.is(tok::comma))
       ConsumeToken();
-    else 
+    else
       break;
   }
 

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Apr 29 12:30:04 2009
@@ -1353,8 +1353,9 @@
     // Otherwise, pretend we saw (void).
     ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, 
                                                        SourceLocation(),
-                                                       0, 0, 0, CaretLoc,
-                                                       ParamInfo),
+                                                       0, 0, 0,
+                                                       false, false, 0, 0,
+                                                       CaretLoc, ParamInfo),
                           CaretLoc);
     // Inform sema that we are starting a block.
     Actions.ActOnBlockArguments(ParamInfo, CurScope);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Apr 29 12:30:04 2009
@@ -3066,8 +3066,8 @@
   Error = Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(),
-                                             0, 0, 0, Loc, D),
+  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
+                                             0, 0, false, false, 0, 0, Loc, D),
                 SourceLocation());
   D.SetIdentifier(&II, Loc);
 

Modified: cfe/trunk/test/Parser/cxx-exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-exception-spec.cpp?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx-exception-spec.cpp (original)
+++ cfe/trunk/test/Parser/cxx-exception-spec.cpp Wed Apr 29 12:30:04 2009
@@ -13,3 +13,5 @@
 class Class {
   void foo() throw (X, Y) { }
 };
+
+void (*fptr)() throw();

Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=70389&r1=70388&r2=70389&view=diff

==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Wed Apr 29 12:30:04 2009
@@ -1668,7 +1668,7 @@
 </tr>
 <tr>
   <td>  15.4 [except.spec]</td>
-  <td></td>
+  <td class="complete" align="center">&#x2713;</td>
   <td></td>
   <td></td>
   <td></td>





More information about the cfe-commits mailing list