[cfe-commits] r64922 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseObjc.cpp lib/Parse/ParseTemplate.cpp lib/Sema/SemaType.cpp

Douglas Gregor dgregor at apple.com
Wed Feb 18 09:45:21 PST 2009


Author: dgregor
Date: Wed Feb 18 11:45:20 2009
New Revision: 64922

URL: http://llvm.org/viewvc/llvm-project?rev=64922&view=rev
Log:
Update Parser::ParseTypeName to return a TypeResult, which also tells
us whether there was an error in trying to parse a type-name (type-id
in C++). This allows propagation of errors further in the compiler,
suppressing more bogus error messages.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb 18 11:45:20 2009
@@ -105,6 +105,7 @@
   typedef Action::StmtResult        StmtResult;
   typedef Action::BaseResult        BaseResult;
   typedef Action::MemInitResult     MemInitResult;
+  typedef Action::TypeResult        TypeResult;
 
   typedef Action::OwningExprResult OwningExprResult;
   typedef Action::OwningStmtResult OwningStmtResult;
@@ -912,8 +913,7 @@
   TPResult TryParseFunctionDeclarator();
   TPResult TryParseBracketDeclarator();
 
-
-  TypeTy *ParseTypeName();
+  TypeResult ParseTypeName();
   void ParseBlockId();
   // EndLoc, if non-NULL, is filled with the location of the last token of
   // the attribute list.

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Feb 18 11:45:20 2009
@@ -28,7 +28,7 @@
 ///         specifier-qualifier-list abstract-declarator[opt]
 ///
 /// Called type-id in C++.
-Parser::TypeTy *Parser::ParseTypeName() {
+Action::TypeResult Parser::ParseTypeName() {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
   ParseSpecifierQualifierList(DS);
@@ -37,7 +37,10 @@
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
   ParseDeclarator(DeclaratorInfo);
   
-  return Actions.ActOnTypeName(CurScope, DeclaratorInfo).get();
+  if (DeclaratorInfo.getInvalidType())
+    return true;
+
+  return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
 }
 
 /// ParseAttributes - Parse a non-empty attributes list.
@@ -2383,8 +2386,10 @@
     }
 
     OwningExprResult Result(ParseCastExpression(true/*isUnaryExpression*/));
-    if (Result.isInvalid())
+    if (Result.isInvalid()) {
+      DS.SetTypeSpecError();
       return;
+    }
 
     const char *PrevSpec = 0;
     // Check for duplicate type specifiers.
@@ -2400,24 +2405,32 @@
   SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
   
   if (isTypeIdInParens()) {
-    TypeTy *Ty = ParseTypeName();
+    Action::TypeResult Ty = ParseTypeName();
 
-    assert(Ty && "Parser::ParseTypeofSpecifier(): missing type");
+    assert((Ty.isInvalid() || Ty.get()) && 
+           "Parser::ParseTypeofSpecifier(): missing type");
 
     if (Tok.isNot(tok::r_paren)) {
       MatchRHSPunctuation(tok::r_paren, LParenLoc);
       return;
     }
     RParenLoc = ConsumeParen();
-    const char *PrevSpec = 0;
-    // Check for duplicate type specifiers (e.g. "int typeof(int)").
-    if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
-      Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+
+    if (Ty.isInvalid())
+      DS.SetTypeSpecError();
+    else {
+      const char *PrevSpec = 0;
+      // Check for duplicate type specifiers (e.g. "int typeof(int)").
+      if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, 
+                             Ty.get()))
+        Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
+    }
   } else { // we have an expression.
     OwningExprResult Result(ParseExpression());
 
     if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
       MatchRHSPunctuation(tok::r_paren, LParenLoc);
+      DS.SetTypeSpecError();
       return;
     }
     RParenLoc = ConsumeParen();

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Feb 18 11:45:20 2009
@@ -939,18 +939,22 @@
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprError();
 
-    TypeTy *Ty = ParseTypeName();
+    TypeResult Ty = ParseTypeName();
 
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       return ExprError();
     }
-    Res = Actions.ActOnVAArg(StartLoc, Expr.release(), Ty, ConsumeParen());
+    if (Ty.isInvalid())
+      Res = ExprError();
+    else
+      Res = Actions.ActOnVAArg(StartLoc, Expr.release(), Ty.get(), 
+                               ConsumeParen());
     break;
   }
   case tok::kw___builtin_offsetof: {
     SourceLocation TypeLoc = Tok.getLocation();
-    TypeTy *Ty = ParseTypeName();
+    TypeResult Ty = ParseTypeName();
 
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprError();
@@ -1001,9 +1005,12 @@
         Comps.back().LocEnd =
           MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
       } else if (Tok.is(tok::r_paren)) {
-        Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc, Ty, 
-                                           &Comps[0], Comps.size(), 
-                                           ConsumeParen());
+        if (Ty.isInvalid())
+          Res = ExprError();
+        else
+          Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc, 
+                                             Ty.get(), &Comps[0], 
+                                             Comps.size(), ConsumeParen());
         break;
       } else {
         // Error occurred.
@@ -1075,18 +1082,23 @@
     break;
   }
   case tok::kw___builtin_types_compatible_p:
-    TypeTy *Ty1 = ParseTypeName();
+    TypeResult Ty1 = ParseTypeName();
 
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprError();
 
-    TypeTy *Ty2 = ParseTypeName();
+    TypeResult Ty2 = ParseTypeName();
 
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       return ExprError();
     }
-    Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1, Ty2, ConsumeParen());
+
+    if (Ty1.isInvalid() || Ty2.isInvalid())
+      Res = ExprError();
+    else
+      Res = Actions.ActOnTypesCompatibleExpr(StartLoc, Ty1.get(), Ty2.get(),
+                                             ConsumeParen());
     break;
   }
 
@@ -1129,7 +1141,7 @@
 
   } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
     // Otherwise, this is a compound literal expression or cast expression.
-    TypeTy *Ty = ParseTypeName();
+    TypeResult Ty = ParseTypeName();
 
     // Match the ')'.
     if (Tok.is(tok::r_paren))
@@ -1142,17 +1154,21 @@
         Diag(OpenLoc, diag::ext_c99_compound_literal);
       Result = ParseInitializer();
       ExprType = CompoundLiteral;
-      if (!Result.isInvalid())
-        return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc,
+      if (!Result.isInvalid() && !Ty.isInvalid())
+        return Actions.ActOnCompoundLiteral(OpenLoc, Ty.get(), RParenLoc,
                                             move(Result));
       return move(Result);
     }
 
     if (ExprType == CastExpr) {
-      // Note that this doesn't parse the subsequence cast-expression, it just
+      // Note that this doesn't parse the subsequent cast-expression, it just
       // returns the parsed type to the callee.
       ExprType = CastExpr;
-      CastTy = Ty;
+
+      if (Ty.isInvalid())
+        return ExprError();
+
+      CastTy = Ty.get();
       return OwningExprResult(Actions);
     }
 

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Feb 18 11:45:20 2009
@@ -211,7 +211,7 @@
   if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
     return ExprError();
 
-  TypeTy *CastTy = ParseTypeName();
+  TypeResult CastTy = ParseTypeName();
   SourceLocation RAngleBracketLoc = Tok.getLocation();
 
   if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
@@ -224,9 +224,10 @@
 
   OwningExprResult Result(ParseSimpleParenExpression(RParenLoc));
 
-  if (!Result.isInvalid())
+  if (!Result.isInvalid() && !CastTy.isInvalid())
     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
-                                       LAngleBracketLoc, CastTy, RAngleBracketLoc,
+                                       LAngleBracketLoc, CastTy.get(), 
+                                       RAngleBracketLoc,
                                        LParenLoc, Result.release(), RParenLoc);
 
   return move(Result);
@@ -253,16 +254,16 @@
   OwningExprResult Result(Actions);
 
   if (isTypeIdInParens()) {
-    TypeTy *Ty = ParseTypeName();
+    TypeResult Ty = ParseTypeName();
 
     // Match the ')'.
     MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
-    if (!Ty)
+    if (Ty.isInvalid())
       return ExprError();
 
     Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
-                                    Ty, RParenLoc);
+                                    Ty.get(), RParenLoc);
   } else {
     Result = ParseExpression();
 
@@ -919,9 +920,12 @@
   // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
   // there will be cryptic errors about mismatched parentheses and missing
   // specifiers.
-  TypeTy *Ty = ParseTypeName();
+  TypeResult Ty = ParseTypeName();
 
   SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
 
-  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty, RParen);
+  if (Ty.isInvalid())
+    return ExprError();
+
+  return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen);
 }

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Wed Feb 18 11:45:20 2009
@@ -629,8 +629,11 @@
   ParseObjCTypeQualifierList(DS);
 
   TypeTy *Ty = 0;
-  if (isTypeSpecifierQualifier())
-    Ty = ParseTypeName();
+  if (isTypeSpecifierQualifier()) {
+    TypeResult TypeSpec = ParseTypeName();
+    if (!TypeSpec.isInvalid())
+      Ty = TypeSpec.get();
+  }
   
   if (Tok.is(tok::r_paren))
     ConsumeParen();
@@ -1627,12 +1630,15 @@
 
   SourceLocation LParenLoc = ConsumeParen();
 
-  TypeTy *Ty = ParseTypeName();
+  TypeResult Ty = ParseTypeName();
 
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
-  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, Ty,
-                                                 RParenLoc));
+  if (Ty.isInvalid())
+    return ExprError();
+
+  return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, 
+                                                 Ty.get(), RParenLoc));
 }
 
 ///     objc-protocol-expression

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Wed Feb 18 11:45:20 2009
@@ -240,9 +240,10 @@
   if(Tok.is(tok::equal)) {
     SourceLocation EqualLoc = ConsumeToken();
     SourceLocation DefaultLoc = Tok.getLocation();
-    if (TypeTy *DefaultType = ParseTypeName())
+    TypeResult DefaultType = ParseTypeName();
+    if (!DefaultType.isInvalid())
       Actions.ActOnTypeParameterDefault(TypeParam, EqualLoc, DefaultLoc,
-                                        DefaultType);
+                                        DefaultType.get());
   }
   
   return TypeParam;
@@ -529,7 +530,10 @@
   // Therefore, we initially try to parse a type-id.
   if (isCXXTypeId(TypeIdAsTemplateArgument)) {
     ArgIsType = true;
-    return ParseTypeName();
+    TypeResult TypeArg = ParseTypeName();
+    if (TypeArg.isInvalid())
+      return 0;
+    return TypeArg.get();
   }
 
   OwningExprResult ExprArg = ParseAssignmentExpression();

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Feb 18 11:45:20 2009
@@ -29,7 +29,6 @@
   QualType Result;
   
   switch (DS.getTypeSpecType()) {
-  default: assert(0 && "Unknown TypeSpecType!");
   case DeclSpec::TST_void:
     Result = Context.VoidTy;
     break;
@@ -169,6 +168,8 @@
     Result = Context.getTypeOfExpr(E);
     break;
   }
+  case DeclSpec::TST_error:
+    return QualType();
   }
   
   // Handle complex types.
@@ -277,8 +278,11 @@
       // We default to a dependent type initially.  Can be modified by
       // the first return statement.
       T = Context.DependentTy;
-    else
+    else {
       T = ConvertDeclSpecToType(DS);
+      if (T.isNull())
+        return T;
+    }
     break;
   }
 
@@ -725,16 +729,13 @@
   assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
   
   QualType T = GetTypeForDeclarator(D, S);
+  if (T.isNull())
+    return true;
 
-  assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
-  
   // Check that there are no default arguments (C++ only).
   if (getLangOptions().CPlusPlus)
     CheckExtraCXXDefaultArguments(D);
 
-  // In this context, we *do not* check D.getInvalidType(). If the declarator
-  // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
-  // though it will not reflect the user specified type.
   return T.getAsOpaquePtr();
 }
 





More information about the cfe-commits mailing list