]> granicus.if.org Git - clang/commitdiff
Update Parser::ParseTypeName to return a TypeResult, which also tells
authorDouglas Gregor <dgregor@apple.com>
Wed, 18 Feb 2009 17:45:20 +0000 (17:45 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 18 Feb 2009 17:45:20 +0000 (17:45 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64922 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 4c51e0508a8d2d5f548b3d6147669aad38936fff..2432f445d9c8a7860a515afb5d8b6b26290ee958 100644 (file)
@@ -105,6 +105,7 @@ public:
   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 @@ private:
   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.
index 9974aea0051f178d304ca5fa7ee9793ec448c7af..6e68b20fa5e34a947644fb7de7de60161b0efaa0 100644 (file)
@@ -28,7 +28,7 @@ using namespace clang;
 ///         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 @@ Parser::TypeTy *Parser::ParseTypeName() {
   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 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
     }
 
     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 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
   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();
index d2e59ece354cf0e919cab833b2a50edcecc24858..5133af8f7f5710dbb385514a7ebaccb4e373437e 100644 (file)
@@ -939,18 +939,22 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
     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 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
         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 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
     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 @@ Parser::ParseParenExpression(ParenParseOption &ExprType,
 
   } 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 @@ Parser::ParseParenExpression(ParenParseOption &ExprType,
         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);
     }
 
index e8ef8ea61ee7c07de713f1568ebeaa5498b16393..fb60bde4f1ea49cd3ea3211dabec03bb17592ed9 100644 (file)
@@ -211,7 +211,7 @@ Parser::OwningExprResult Parser::ParseCXXCasts() {
   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 @@ Parser::OwningExprResult Parser::ParseCXXCasts() {
 
   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 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() {
   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 @@ Parser::OwningExprResult Parser::ParseUnaryTypeTrait()
   // 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);
 }
index a147ee47e82c9a7acba66cd35cb786afa952eeba..4ddddb3749b143df158975b1a5815cb10bbe6e45 100644 (file)
@@ -629,8 +629,11 @@ Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
   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 @@ Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) {
 
   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
index 52824f51c1343d5b078ae9ecba0b64c524bbebd4..747a4de1523cc64cdb8b81ba508a4972b2a00295 100644 (file)
@@ -240,9 +240,10 @@ Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
   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 @@ void *Parser::ParseTemplateArgument(bool &ArgIsType) {
   // 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();
index a385a13f4c8619df7527e44ce7f7d5c45bced4ef..677f994cac009e146a4d5c0cb91e7ad00ac11e2f 100644 (file)
@@ -29,7 +29,6 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
   QualType Result;
   
   switch (DS.getTypeSpecType()) {
-  default: assert(0 && "Unknown TypeSpecType!");
   case DeclSpec::TST_void:
     Result = Context.VoidTy;
     break;
@@ -169,6 +168,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
     Result = Context.getTypeOfExpr(E);
     break;
   }
+  case DeclSpec::TST_error:
+    return QualType();
   }
   
   // Handle complex types.
@@ -277,8 +278,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
       // 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 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
   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();
 }