Index: include/clang/Parse/Action.h
===================================================================
--- include/clang/Parse/Action.h	(revision 60622)
+++ include/clang/Parse/Action.h	(working copy)
@@ -106,7 +106,7 @@
   // Declaration Tracking Callbacks.
   //===--------------------------------------------------------------------===//
   
-  /// isTypeName - Return non-null if the specified identifier is a typedef name
+  /// isTypeName - Return non-null if the specified identifier is a type name
   /// in the current scope.
   /// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or
   /// namespace) that the identifier must be a member of.
Index: lib/Parse/ParseInit.cpp
===================================================================
--- lib/Parse/ParseInit.cpp	(revision 60622)
+++ lib/Parse/ParseInit.cpp	(working copy)
@@ -143,10 +143,10 @@
     // Note that we parse this as an assignment expression, not a constant
     // expression (allowing *=, =, etc) to handle the objc case.  Sema needs
     // to validate that the expression is a constant.
-    ExprResult Idx = ParseAssignmentExpression();
-    if (Idx.isInvalid) {
+    ExprOwner Idx(Actions, ParseAssignmentExpression());
+    if (Idx.isInvalid()) {
       SkipUntil(tok::r_square);
-      return Idx;
+      return Idx.move();
     }
     
     // Given an expression, we could either have a designator (if the next
@@ -170,7 +170,7 @@
       
       return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                          SourceLocation(), 
-                                                         0, Idx.Val);
+                                                         0, Idx.move());
     }
 
     // Create designation if we haven't already.
@@ -179,21 +179,20 @@
     
     // If this is a normal array designator, remember it.
     if (Tok.isNot(tok::ellipsis)) {
-      Desig->AddDesignator(Designator::getArray(Idx.Val));
+      Desig->AddDesignator(Designator::getArray(Idx.move()));
     } else {
       // Handle the gnu array range extension.
       Diag(Tok, diag::ext_gnu_array_range);
       ConsumeToken();
       
-      ExprResult RHS = ParseConstantExpression();
-      if (RHS.isInvalid) {
-        Actions.DeleteExpr(Idx.Val);
+      ExprOwner RHS(Actions, ParseConstantExpression());
+      if (RHS.isInvalid()) {
         SkipUntil(tok::r_square);
-        return RHS;
+        return RHS.move();
       }
-      Desig->AddDesignator(Designator::getArrayRange(Idx.Val, RHS.Val));
+      Desig->AddDesignator(Designator::getArrayRange(Idx.move(), RHS.move()));
     }
-    
+
     MatchRHSPunctuation(tok::r_square, StartLoc);
   }
 
@@ -264,7 +263,7 @@
     
     // If we know that this cannot be a designation, just parse the nested
     // initializer directly.
-    ExprResult SubElt;
+    ExprOwner SubElt(Actions);
     if (!MayBeDesignationStart(Tok.getKind(), PP))
       SubElt = ParseInitializer();
     else {
@@ -275,13 +274,13 @@
       // designator, make sure to remove the designator from
       // InitExprDesignations, otherwise we'll end up with a designator with no
       // making initializer.
-      if (SubElt.isInvalid)
+      if (SubElt.isInvalid())
         InitExprDesignations.EraseDesignation(InitExprs.size());
     }
     
     // If we couldn't parse the subelement, bail out.
-    if (!SubElt.isInvalid) {
-      InitExprs.push_back(SubElt.Val);
+    if (!SubElt.isInvalid()) {
+      InitExprs.push_back(SubElt.move());
     } else {
       InitExprsOk = false;
       
@@ -298,7 +297,7 @@
         break;
       }
     }
-      
+
     // If we don't have a comma continued list, we're done.
     if (Tok.isNot(tok::comma)) break;
     
Index: lib/Parse/ParsePragma.cpp
===================================================================
--- lib/Parse/ParsePragma.cpp	(revision 60622)
+++ lib/Parse/ParsePragma.cpp	(working copy)
@@ -35,15 +35,13 @@
 
   Action::PragmaPackKind Kind = Action::PPK_Default;
   IdentifierInfo *Name = 0;
-  Action::ExprResult Alignment;
-  ExprGuard AlignmentGuard(Actions);
+  ExprOwner Alignment(Actions);
   SourceLocation LParenLoc = Tok.getLocation();
   PP.Lex(Tok);  
   if (Tok.is(tok::numeric_constant)) {
     Alignment = Actions.ActOnNumericConstant(Tok);
-    if (Alignment.isInvalid)
+    if (Alignment.isInvalid())
       return;
-    AlignmentGuard.reset(Alignment);
 
     PP.Lex(Tok);
   } else if (Tok.is(tok::identifier)) {
@@ -67,9 +65,8 @@
         
         if (Tok.is(tok::numeric_constant)) {
           Alignment = Actions.ActOnNumericConstant(Tok);
-          if (Alignment.isInvalid)
+          if (Alignment.isInvalid())
             return;
-          AlignmentGuard.reset(Alignment);
 
           PP.Lex(Tok);
         } else if (Tok.is(tok::identifier)) {
@@ -85,9 +82,8 @@
             }
             
             Alignment = Actions.ActOnNumericConstant(Tok);
-            if (Alignment.isInvalid)
+            if (Alignment.isInvalid())
               return;
-            AlignmentGuard.reset(Alignment);
 
             PP.Lex(Tok);
           }
@@ -97,7 +93,7 @@
         }
       }
     }
-  } 
+  }
 
   if (Tok.isNot(tok::r_paren)) {
     PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_expected_rparen);
@@ -105,7 +101,7 @@
   }
 
   SourceLocation RParenLoc = Tok.getLocation();
-  Actions.ActOnPragmaPack(Kind, Name, AlignmentGuard.take(), PackLoc, 
+  Actions.ActOnPragmaPack(Kind, Name, Alignment.move(), PackLoc,
                           LParenLoc, RParenLoc);
 }
 
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 60622)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -126,13 +126,13 @@
             
             // now parse the non-empty comma separated list of expressions
             while (1) {
-              ExprResult ArgExpr = ParseAssignmentExpression();
-              if (ArgExpr.isInvalid) {
+              ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+              if (ArgExpr.isInvalid()) {
                 ArgExprsOk = false;
                 SkipUntil(tok::r_paren);
                 break;
               } else {
-                ArgExprs.push_back(ArgExpr.Val);
+                ArgExprs.push_back(ArgExpr.move());
               }
               if (Tok.isNot(tok::comma))
                 break;
@@ -158,13 +158,13 @@
             
             // now parse the list of expressions
             while (1) {
-              ExprResult ArgExpr = ParseAssignmentExpression();
-              if (ArgExpr.isInvalid) {
+              ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+              if (ArgExpr.isInvalid()) {
                 ArgExprsOk = false;
                 SkipUntil(tok::r_paren);
                 break;
               } else {
-                ArgExprs.push_back(ArgExpr.Val);
+                ArgExprs.push_back(ArgExpr.move());
               }
               if (Tok.isNot(tok::comma))
                 break;
@@ -270,13 +270,13 @@
   while (1) {
     // If a simple-asm-expr is present, parse it.
     if (Tok.is(tok::kw_asm)) {
-      ExprResult AsmLabel = ParseSimpleAsm();
-      if (AsmLabel.isInvalid) {
+      ExprOwner AsmLabel(Actions, ParseSimpleAsm());
+      if (AsmLabel.isInvalid()) {
         SkipUntil(tok::semi);
         return 0;
       }
       
-      D.setAsmLabel(AsmLabel.Val);
+      D.setAsmLabel(AsmLabel.move());
     }
     
     // If attributes are present, parse them.
@@ -285,16 +285,16 @@
 
     // Inform the current actions module that we just parsed this declarator.
     LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
-        
+
     // Parse declarator '=' initializer.
     if (Tok.is(tok::equal)) {
       ConsumeToken();
-      ExprResult Init = ParseInitializer();
-      if (Init.isInvalid) {
+      ExprOwner Init(Actions, ParseInitializer());
+      if (Init.isInvalid()) {
         SkipUntil(tok::semi);
         return 0;
       }
-      Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val);
+      Actions.AddInitializerToDecl(LastDeclInGroup, Init.move());
     } else if (Tok.is(tok::l_paren)) {
       // Parse C++ direct initializer: '(' expression-list ')'
       SourceLocation LParenLoc = ConsumeParen();
@@ -842,11 +842,11 @@
     
     if (Tok.is(tok::colon)) {
       ConsumeToken();
-      ExprResult Res = ParseConstantExpression();
-      if (Res.isInvalid)
+      ExprOwner Res(Actions, ParseConstantExpression());
+      if (Res.isInvalid())
         SkipUntil(tok::semi, true, true);
       else
-        DeclaratorInfo.BitfieldSize = Res.Val;
+        DeclaratorInfo.BitfieldSize = Res.move();
     }
     
     // If attributes exist after the declarator, parse them.
@@ -1074,21 +1074,20 @@
     SourceLocation IdentLoc = ConsumeToken();
     
     SourceLocation EqualLoc;
-    ExprTy *AssignedVal = 0;
+    ExprOwner AssignedVal(Actions);
     if (Tok.is(tok::equal)) {
       EqualLoc = ConsumeToken();
-      ExprResult Res = ParseConstantExpression();
-      if (Res.isInvalid)
+      AssignedVal = ParseConstantExpression();
+      if (AssignedVal.isInvalid())
         SkipUntil(tok::comma, tok::r_brace, true, true);
-      else
-        AssignedVal = Res.Val;
     }
     
     // Install the enumerator constant into EnumDecl.
     DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
                                                       LastEnumConstDecl,
                                                       IdentLoc, Ident,
-                                                      EqualLoc, AssignedVal);
+                                                      EqualLoc,
+                                                      AssignedVal.move());
     EnumConstantDecls.push_back(EnumConstDecl);
     LastEnumConstDecl = EnumConstDecl;
     
@@ -1797,12 +1796,13 @@
         ConsumeToken();
         
         // Parse the default argument
-        ExprResult DefArgResult = ParseAssignmentExpression();
-        if (DefArgResult.isInvalid) {
+        ExprOwner DefArgResult(Actions, ParseAssignmentExpression());
+        if (DefArgResult.isInvalid()) {
           SkipUntil(tok::comma, tok::r_paren, true, true);
         } else {
           // Inform the actions module about the default argument
-          Actions.ActOnParamDefaultArgument(Param, EqualLoc, DefArgResult.Val);
+          Actions.ActOnParamDefaultArgument(Param, EqualLoc,
+                                            DefArgResult.move());
         }
       }
       
@@ -1934,7 +1934,7 @@
   
   // Handle "direct-declarator [ type-qual-list[opt] * ]".
   bool isStar = false;
-  ExprResult NumElements(false);
+  ExprOwner NumElements(Actions);
   
   // Handle the case where we have '[*]' as the array size.  However, a leading
   // star could be the start of an expression, for example 'X[*p + 4]'.  Verify
@@ -1953,7 +1953,7 @@
   }
   
   // If there was an error parsing the assignment-expression, recover.
-  if (NumElements.isInvalid) {
+  if (NumElements.isInvalid()) {
     // If the expression was invalid, skip it.
     SkipUntil(tok::r_square);
     return;
@@ -1973,7 +1973,7 @@
   // Remember that we parsed a pointer type, and remember the type-quals.
   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
-                                          NumElements.Val, StartLoc));
+                                          NumElements.move(), StartLoc));
 }
 
 /// [GNU]   typeof-specifier:
@@ -1992,14 +1992,14 @@
       return;
     }
 
-    ExprResult Result = ParseCastExpression(true/*isUnaryExpression*/);
-    if (Result.isInvalid)
+    ExprOwner Result(Actions, ParseCastExpression(true/*isUnaryExpression*/));
+    if (Result.isInvalid())
       return;
 
     const char *PrevSpec = 0;
     // Check for duplicate type specifiers.
     if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 
-                           Result.Val))
+                           Result.move()))
       Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 
     // FIXME: Not accurate, the range gets one token more than it should.
@@ -2024,10 +2024,9 @@
     if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty))
       Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
   } else { // we have an expression.
-    ExprResult Result = ParseExpression();
-    ExprGuard ResultGuard(Actions, Result);
-    
-    if (Result.isInvalid || Tok.isNot(tok::r_paren)) {
+    ExprOwner Result(Actions, ParseExpression());
+
+    if (Result.isInvalid() || Tok.isNot(tok::r_paren)) {
       MatchRHSPunctuation(tok::r_paren, LParenLoc);
       return;
     }
@@ -2035,7 +2034,7 @@
     const char *PrevSpec = 0;
     // Check for duplicate type specifiers (e.g. "int typeof(int)").
     if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, 
-                           ResultGuard.take()))
+                           Result.move()))
       Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
   }
   DS.SetRangeEnd(RParenLoc);
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp	(revision 60622)
+++ lib/Parse/ParseTemplate.cpp	(working copy)
@@ -15,6 +15,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "AstGuard.h"
 
 using namespace clang;
 
@@ -231,11 +232,11 @@
   }
 
   // Get the a default value, if given.
-  ExprResult defaultExpr;
+  ExprOwner DefaultExpr(Actions);
   if(Tok.is(tok::equal)) {
     ConsumeToken();
-    defaultExpr = ParseCXXIdExpression();
-    if(defaultExpr.isInvalid) {
+    DefaultExpr = ParseCXXIdExpression();
+    if(DefaultExpr.isInvalid()) {
       return 0;
     }
   }
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp	(revision 60622)
+++ lib/Parse/ParseObjc.cpp	(working copy)
@@ -1175,17 +1175,17 @@
 ///    throw expression[opt];
 ///
 Parser::StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) {
-  ExprResult Res;
+  ExprOwner Res(Actions);
   ConsumeToken(); // consume throw
   if (Tok.isNot(tok::semi)) {
     Res = ParseExpression();
-    if (Res.isInvalid) {
+    if (Res.isInvalid()) {
       SkipUntil(tok::semi);
       return true;
     }
   }
   ConsumeToken(); // consume ';'
-  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.Val);
+  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.move());
 }
 
 /// objc-synchronized-statement:
@@ -1198,9 +1198,8 @@
     return true;
   }
   ConsumeParen();  // '('
-  ExprResult Res = ParseExpression();
-  ExprGuard ResGuard(Actions, Res);
-  if (Res.isInvalid) {
+  ExprOwner Res(Actions, ParseExpression());
+  if (Res.isInvalid()) {
     SkipUntil(tok::semi);
     return true;
   }
@@ -1217,13 +1216,13 @@
   // statements can always hold declarations.
   EnterScope(Scope::DeclScope);
 
-  StmtResult SynchBody = ParseCompoundStatementBody();
-  
+  StmtOwner SynchBody(Actions, ParseCompoundStatementBody());
+
   ExitScope();
-  if (SynchBody.isInvalid)
+  if (SynchBody.isInvalid())
     SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
-  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, ResGuard.take(),
-                                             SynchBody.Val);
+  return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.move(),
+                                             SynchBody.move());
 }
 
 ///  objc-try-catch-statement:
@@ -1245,15 +1244,13 @@
     Diag(Tok, diag::err_expected_lbrace);
     return true;
   }
-  StmtResult CatchStmts;
-  StmtResult FinallyStmt;
+  StmtOwner CatchStmts(Actions);
+  StmtOwner FinallyStmt(Actions);
   EnterScope(Scope::DeclScope);
-  StmtResult TryBody = ParseCompoundStatementBody();
+  StmtOwner TryBody(Actions, ParseCompoundStatementBody());
   ExitScope();
-  if (TryBody.isInvalid)
+  if (TryBody.isInvalid())
     TryBody = Actions.ActOnNullStmt(Tok.getLocation());
-  ExprGuard TryGuard(Actions, TryBody);
-  ExprGuard CatchGuard(Actions), FinallyGuard(Actions);
 
   while (Tok.is(tok::at)) {
     // At this point, we need to lookahead to determine if this @ is the start
@@ -1263,10 +1260,10 @@
     if (!AfterAt.isObjCAtKeyword(tok::objc_catch) &&
         !AfterAt.isObjCAtKeyword(tok::objc_finally))
       break;
-      
+
     SourceLocation AtCatchFinallyLoc = ConsumeToken();
     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
-      StmtTy *FirstPart = 0;
+      StmtOwner FirstPart(Actions);
       ConsumeToken(); // consume catch
       if (Tok.is(tok::l_paren)) {
         ConsumeParen();
@@ -1281,26 +1278,24 @@
           if (DeclaratorInfo.getIdentifier()) {
             DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope, 
                                                           DeclaratorInfo, 0);
-            StmtResult stmtResult =
+            FirstPart =
               Actions.ActOnDeclStmt(aBlockVarDecl, 
                                     DS.getSourceRange().getBegin(),
                                     DeclaratorInfo.getSourceRange().getEnd());
-            FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
           }
         } else
           ConsumeToken(); // consume '...'
         SourceLocation RParenLoc = ConsumeParen();
         
-        StmtResult CatchBody(true);
+        StmtOwner CatchBody(Actions, true);
         if (Tok.is(tok::l_brace))
           CatchBody = ParseCompoundStatementBody();
         else
           Diag(Tok, diag::err_expected_lbrace);
-        if (CatchBody.isInvalid)
+        if (CatchBody.isInvalid())
           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
-        CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc, 
-          FirstPart, CatchBody.Val, CatchGuard.take());
-        CatchGuard.reset(CatchStmts);
+        CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
+          RParenLoc, FirstPart.move(), CatchBody.move(), CatchStmts.move());
         ExitScope();
       } else {
         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
@@ -1313,17 +1308,16 @@
       ConsumeToken(); // consume finally
       EnterScope(Scope::DeclScope);
 
-      
-      StmtResult FinallyBody(true);
+
+      StmtOwner FinallyBody(Actions, true);
       if (Tok.is(tok::l_brace))
         FinallyBody = ParseCompoundStatementBody();
       else
         Diag(Tok, diag::err_expected_lbrace);
-      if (FinallyBody.isInvalid)
+      if (FinallyBody.isInvalid())
         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
-      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, 
-                                                   FinallyBody.Val);
-      FinallyGuard.reset(FinallyStmt);
+      FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
+                                                       FinallyBody.move());
       catch_or_finally_seen = true;
       ExitScope();
       break;
@@ -1333,8 +1327,8 @@
     Diag(atLoc, diag::err_missing_catch_finally);
     return true;
   }
-  return Actions.ActOnObjCAtTryStmt(atLoc, TryGuard.take(), CatchGuard.take(), 
-                                    FinallyGuard.take());
+  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.move(), CatchStmts.move(), 
+                                    FinallyStmt.move());
 }
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
@@ -1365,17 +1359,17 @@
   // specified Declarator for the method.
   Actions.ObjCActOnStartOfMethodDef(CurScope, MDecl);
   
-  StmtResult FnBody = ParseCompoundStatementBody();
+  StmtOwner FnBody(Actions, ParseCompoundStatementBody());
   
   // If the function body could not be parsed, make a bogus compoundstmt.
-  if (FnBody.isInvalid)
+  if (FnBody.isInvalid())
     FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 0, 0, false);
   
   // Leave the function body scope.
   ExitScope();
   
   // TODO: Pass argument information.
-  Actions.ActOnFinishFunctionBody(MDecl, FnBody.Val);
+  Actions.ActOnFinishFunctionBody(MDecl, FnBody.move());
   return MDecl;
 }
 
@@ -1386,8 +1380,8 @@
     return ParseObjCThrowStmt(AtLoc);
   else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
     return ParseObjCSynchronizedStmt(AtLoc);
-  ExprResult Res = ParseExpressionWithLeadingAt(AtLoc);
-  if (Res.isInvalid) {
+  ExprOwner Res(Actions, ParseExpressionWithLeadingAt(AtLoc));
+  if (Res.isInvalid()) {
     // If the expression is invalid, skip ahead to the next semicolon. Not
     // doing this opens us up to the possibility of infinite loops if
     // ParseExpression does not consume any tokens.
@@ -1396,7 +1390,7 @@
   }
   // Otherwise, eat the semicolon.
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-  return Actions.ActOnExprStmt(Res.Val);
+  return Actions.ActOnExprStmt(Res.move());
 }
 
 Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
@@ -1439,13 +1433,14 @@
     return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 0);
   }
 
-  ExprResult Res = ParseExpression();
-  if (Res.isInvalid) {
+  ExprOwner Res(Actions, ParseExpression());
+  if (Res.isInvalid()) {
     SkipUntil(tok::r_square);
-    return Res;
+    return Res.move();
   }
   
-  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, Res.Val);
+  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
+                                        0, Res.move());
 }
   
 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse
@@ -1497,17 +1492,17 @@
       
       ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':' 
-      ExprResult Res = ParseAssignmentExpression();
-      if (Res.isInvalid) {
+      ExprOwner Res(Actions, ParseAssignmentExpression());
+      if (Res.isInvalid()) {
         // We must manually skip to a ']', otherwise the expression skipper will
         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
         // the enclosing expression.
         SkipUntil(tok::r_square);
-        return Res;
+        return Res.move();
       }
       
       // We have a valid expression.
-      KeyExprs.push_back(Res.Val);
+      KeyExprs.push_back(Res.move());
       
       // Check for another keyword selector.
       selIdent = ParseObjCSelector(Loc);
@@ -1519,17 +1514,17 @@
     while (Tok.is(tok::comma)) {
       ConsumeToken(); // Eat the ','.
       ///  Parse the expression after ',' 
-      ExprResult Res = ParseAssignmentExpression();
-      if (Res.isInvalid) {
+      ExprOwner Res(Actions, ParseAssignmentExpression());
+      if (Res.isInvalid()) {
         // We must manually skip to a ']', otherwise the expression skipper will
         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
         // the enclosing expression.
         SkipUntil(tok::r_square);
-        return Res;
+        return Res.move();
       }
-      
+
       // We have a valid expression.
-      KeyExprs.push_back(Res.Val);
+      KeyExprs.push_back(Res.move());
     }
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected_ident); // missing selector name.
@@ -1568,8 +1563,8 @@
 }
 
 Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
-  ExprResult Res = ParseStringLiteralExpression();
-  if (Res.isInvalid) return Res;
+  ExprOwner Res(Actions, ParseStringLiteralExpression());
+  if (Res.isInvalid()) return Res.move();
   
   // @"foo" @"bar" is a valid concatenated string.  Eat any subsequent string
   // expressions.  At this point, we know that the only valid thing that starts
@@ -1577,21 +1572,21 @@
   llvm::SmallVector<SourceLocation, 4> AtLocs;
   ExprVector AtStrings(Actions);
   AtLocs.push_back(AtLoc);
-  AtStrings.push_back(Res.Val);
-  
+  AtStrings.push_back(Res.move());
+
   while (Tok.is(tok::at)) {
     AtLocs.push_back(ConsumeToken()); // eat the @.
 
-    ExprResult Lit(true);  // Invalid unless there is a string literal.
+    ExprOwner Lit(Actions, true);  // Invalid unless there is a string literal.
     if (isTokenStringLiteral())
       Lit = ParseStringLiteralExpression();
     else
       Diag(Tok, diag::err_objc_concat_string);
-    
-    if (Lit.isInvalid)
-      return Lit;
 
-    AtStrings.push_back(Lit.Val);
+    if (Lit.isInvalid())
+      return Lit.move();
+
+    AtStrings.push_back(Lit.move());
   }
   
   return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(),
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp	(revision 60622)
+++ lib/Parse/ParseExpr.cpp	(working copy)
@@ -173,10 +173,10 @@
   if (Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 
-  ExprResult LHS = ParseCastExpression(false);
-  if (LHS.isInvalid) return LHS;
+  ExprOwner LHS(Actions, ParseCastExpression(false));
+  if (LHS.isInvalid()) return LHS.move();
   
-  return ParseRHSOfBinaryExpression(LHS, prec::Comma);
+  return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
 }
 
 /// This routine is called when the '@' is seen and consumed. 
@@ -185,10 +185,10 @@
 /// for example, @encode-expression.
 ///
 Parser::ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) {
-  ExprResult LHS = ParseObjCAtExpression(AtLoc);
-  if (LHS.isInvalid) return LHS;
- 
-  return ParseRHSOfBinaryExpression(LHS, prec::Comma);
+  ExprOwner LHS(Actions, ParseObjCAtExpression(AtLoc));
+  if (LHS.isInvalid()) return LHS.move();
+
+  return ParseRHSOfBinaryExpression(LHS.move(), prec::Comma);
 }
 
 /// ParseAssignmentExpression - Parse an expr that doesn't include commas.
@@ -197,10 +197,10 @@
   if (Tok.is(tok::kw_throw))
     return ParseThrowExpression();
 
-  ExprResult LHS = ParseCastExpression(false);
-  if (LHS.isInvalid) return LHS;
+  ExprOwner LHS(Actions, ParseCastExpression(false));
+  if (LHS.isInvalid()) return LHS.move();
   
-  return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
+  return ParseRHSOfBinaryExpression(LHS.move(), prec::Assignment);
 }
 
 /// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression
@@ -216,46 +216,44 @@
                                                     SourceLocation NameLoc,
                                                    IdentifierInfo *ReceiverName,
                                                     ExprTy *ReceiverExpr) {
-  ExprResult R = ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName,
-                                                ReceiverExpr);
-  if (R.isInvalid) return R;
-  R = ParsePostfixExpressionSuffix(R);
-  if (R.isInvalid) return R;
-  return ParseRHSOfBinaryExpression(R, 2);
+  ExprOwner R(Actions, ParseObjCMessageExpressionBody(LBracLoc, NameLoc,
+                                                      ReceiverName,
+                                                      ReceiverExpr));
+  if (R.isInvalid()) return R.move();
+  R = ParsePostfixExpressionSuffix(R.move());
+  if (R.isInvalid()) return R.move();
+  return ParseRHSOfBinaryExpression(R.move(), 2);
 }
 
 
 Parser::ExprResult Parser::ParseConstantExpression() {
-  ExprResult LHS = ParseCastExpression(false);
-  if (LHS.isInvalid) return LHS;
+  ExprOwner LHS(Actions, ParseCastExpression(false));
+  if (LHS.isInvalid()) return LHS.move();
   
-  return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+  return ParseRHSOfBinaryExpression(LHS.move(), prec::Conditional);
 }
 
 /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
 /// LHS and has a precedence of at least MinPrec.
 Parser::ExprResult
-Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
+Parser::ParseRHSOfBinaryExpression(ExprResult LHSArg, unsigned MinPrec) {
   unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
   SourceLocation ColonLoc;
 
-  ExprGuard LHSGuard(Actions, LHS);
+  ExprOwner LHS(Actions, LHSArg);
   while (1) {
     // If this token has a lower precedence than we are allowed to parse (e.g.
     // because we are called recursively, or because the token is not a binop),
     // then we are done!
-    if (NextTokPrec < MinPrec) {
-      LHSGuard.take();
-      return LHS;
-    }
+    if (NextTokPrec < MinPrec)
+      return LHS.move();
 
     // Consume the operator, saving the operator token for error reporting.
     Token OpToken = Tok;
     ConsumeToken();
     
     // Special case handling for the ternary operator.
-    ExprResult TernaryMiddle(true);
-    ExprGuard MiddleGuard(Actions);
+    ExprOwner TernaryMiddle(Actions, true);
     if (NextTokPrec == prec::Conditional) {
       if (Tok.isNot(tok::colon)) {
         // Handle this production specially:
@@ -263,17 +261,15 @@
         // In particular, the RHS of the '?' is 'expression', not
         // 'logical-OR-expression' as we might expect.
         TernaryMiddle = ParseExpression();
-        if (TernaryMiddle.isInvalid) {
-          return TernaryMiddle;
-        }
+        if (TernaryMiddle.isInvalid())
+          return TernaryMiddle.move();
       } else {
         // Special case handling of "X ? Y : Z" where Y is empty:
         //   logical-OR-expression '?' ':' conditional-expression   [GNU]
-        TernaryMiddle = ExprResult(false);
+        TernaryMiddle.reset();
         Diag(Tok, diag::ext_gnu_conditional_expr);
       }
-      MiddleGuard.reset(TernaryMiddle);
-      
+
       if (Tok.isNot(tok::colon)) {
         Diag(Tok, diag::err_expected_colon);
         Diag(OpToken, diag::note_matching) << "?";
@@ -285,11 +281,9 @@
     }
     
     // Parse another leaf here for the RHS of the operator.
-    ExprResult RHS = ParseCastExpression(false);
-    if (RHS.isInvalid) {
-      return RHS;
-    }
-    ExprGuard RHSGuard(Actions, RHS);
+    ExprOwner RHS(Actions, ParseCastExpression(false));
+    if (RHS.isInvalid())
+      return RHS.move();
 
     // Remember the precedence of this operator and get the precedence of the
     // operator immediately to the right of the RHS.
@@ -309,31 +303,24 @@
       // is okay, to bind exactly as tightly.  For example, compile A=B=C=D as
       // A=(B=(C=D)), where each paren is a level of recursion here.
       // The function takes ownership of the RHS.
-      RHSGuard.take();
-      RHS = ParseRHSOfBinaryExpression(RHS, ThisPrec + !isRightAssoc);
-      if (RHS.isInvalid) {
-        return RHS;
-      }
-      RHSGuard.reset(RHS);
+      RHS = ParseRHSOfBinaryExpression(RHS.move(), ThisPrec + !isRightAssoc);
+      if (RHS.isInvalid())
+        return RHS.move();
 
       NextTokPrec = getBinOpPrecedence(Tok.getKind());
     }
     assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
 
-    if (!LHS.isInvalid) {
+    if (!LHS.isInvalid()) {
       // Combine the LHS and RHS into the LHS (e.g. build AST).
-      LHSGuard.take();
-      MiddleGuard.take();
-      RHSGuard.take();
-      if (TernaryMiddle.isInvalid)
+      if (TernaryMiddle.isInvalid())
         LHS = Actions.ActOnBinOp(CurScope, OpToken.getLocation(), 
-                                 OpToken.getKind(), LHS.Val, RHS.Val);
+                                 OpToken.getKind(), LHS.move(), RHS.move());
       else
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
-                                         LHS.Val, TernaryMiddle.Val, RHS.Val);
-      LHSGuard.reset(LHS);
+                                         LHS.move(), TernaryMiddle.move(),
+                                         RHS.move());
     }
-    // If we had an invalid LHS, Middle and RHS will be freed by the guards here
   }
 }
 
@@ -433,7 +420,7 @@
     TryAnnotateTypeOrScopeToken();
   }
 
-  ExprResult Res;
+  ExprOwner Res(Actions);
   tok::TokenKind SavedKind = Tok.getKind();
   
   // This handles all of cast-expression, unary-expression, postfix-expression,
@@ -456,7 +443,7 @@
     SourceLocation LParenLoc = Tok.getLocation();
     SourceLocation RParenLoc;
     Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
-    if (Res.isInvalid) return Res;
+    if (Res.isInvalid()) return Res.move();
     
     switch (ParenExprType) {
     case SimpleExpr:   break;    // Nothing else to do.
@@ -470,15 +457,15 @@
       // the cast-expression that follows it next.
       // TODO: For cast expression with CastTy.
       Res = ParseCastExpression(false);
-      if (!Res.isInvalid)
-        Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
-      return Res;
+      if (!Res.isInvalid())
+        Res = Actions.ActOnCastExpr(LParenLoc, CastTy, RParenLoc, Res.move());
+      return Res.move();
     }
-      
+
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   }
-    
+
     // primary-expression
   case tok::numeric_constant:
     // constant: integer-constant
@@ -488,7 +475,7 @@
     ConsumeToken();
     
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
 
   case tok::kw_true:
   case tok::kw_false:
@@ -506,26 +493,26 @@
     SourceLocation L = ConsumeToken();
     Res = Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren));
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   }
   case tok::char_constant:     // constant: character-constant
     Res = Actions.ActOnCharacterConstant(Tok);
     ConsumeToken();
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);    
+    return ParsePostfixExpressionSuffix(Res.move());
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
     Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
     ConsumeToken();
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   case tok::string_literal:    // primary-expression: string-literal
   case tok::wide_string_literal:
     Res = ParseStringLiteralExpression();
-    if (Res.isInvalid) return Res;
+    if (Res.isInvalid()) return Res.move();
     // This can be followed by postfix-expr pieces (e.g. "foo"[1]).
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   case tok::kw___builtin_va_arg:
   case tok::kw___builtin_offsetof:
   case tok::kw___builtin_choose_expr:
@@ -539,9 +526,9 @@
   case tok::minusminus: {  // unary-expression: '--' unary-expression
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(true);
-    if (!Res.isInvalid)
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
-    return Res;
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+    return Res.move();
   }
   case tok::amp:           // unary-expression: '&' cast-expression
   case tok::star:          // unary-expression: '*' cast-expression
@@ -553,19 +540,19 @@
   case tok::kw___imag: {   // unary-expression: '__imag' cast-expression [GNU]
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
-    if (!Res.isInvalid)
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
-    return Res;
-  }    
-      
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+    return Res.move();
+  }
+
   case tok::kw___extension__:{//unary-expression:'__extension__' cast-expr [GNU]
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
     SourceLocation SavedLoc = ConsumeToken();
     Res = ParseCastExpression(false);
-    if (!Res.isInvalid)
-      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.Val);
-    return Res;
+    if (!Res.isInvalid())
+      Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.move());
+    return Res.move();
   }
   case tok::kw_sizeof:     // unary-expression: 'sizeof' unary-expression
                            // unary-expression: 'sizeof' '(' type-name ')'
@@ -585,7 +572,7 @@
     Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
                                  Tok.getIdentifierInfo());
     ConsumeToken();
-    return Res;
+    return Res.move();
   }
   case tok::kw_const_cast:
   case tok::kw_dynamic_cast:
@@ -593,15 +580,15 @@
   case tok::kw_static_cast:
     Res = ParseCXXCasts();
     // These can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   case tok::kw_typeid:
     Res = ParseCXXTypeid();
     // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   case tok::kw_this:
     Res = ParseCXXThis();
     // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
 
   case tok::kw_char:
   case tok::kw_wchar_t:
@@ -629,14 +616,14 @@
 
     Res = ParseCXXTypeConstructExpression(DS);
     // This can be followed by postfix-expr pieces.
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
   }
 
   case tok::annot_cxxscope: // [C++] id-expression: qualified-id
   case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
                          //                      template-id
     Res = ParseCXXIdExpression();
-    return ParsePostfixExpressionSuffix(Res);
+    return ParsePostfixExpressionSuffix(Res.move());
 
   case tok::coloncolon: // [C++] new-expression or [C++] delete-expression
     // If the next token is neither 'new' nor 'delete', the :: would have been
@@ -694,35 +681,32 @@
 ///         argument-expression
 ///         argument-expression-list ',' assignment-expression
 ///
-Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
-  ExprGuard LHSGuard(Actions, LHS);
+Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHSArg) {
+  ExprOwner LHS(Actions, LHSArg);
   // Now that the primary-expression piece of the postfix-expression has been
   // parsed, see if there are any postfix-expression pieces here.
   SourceLocation Loc;
   while (1) {
     switch (Tok.getKind()) {
     default:  // Not a postfix-expression suffix.
-      LHSGuard.take();
-      return LHS;
+      return LHS.move();
     case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
       Loc = ConsumeBracket();
-      ExprResult Idx = ParseExpression();
-      ExprGuard IdxGuard(Actions, Idx);
+      ExprOwner Idx(Actions, ParseExpression());
 
       SourceLocation RLoc = Tok.getLocation();
-      
-      if (!LHS.isInvalid && !Idx.isInvalid && Tok.is(tok::r_square)) {
-        LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHSGuard.take(), Loc, 
-                                              IdxGuard.take(), RLoc);
-        LHSGuard.reset(LHS);
-      } else 
+
+      if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
+        LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHS.move(), Loc,
+                                              Idx.move(), RLoc);
+      } else
         LHS = ExprResult(true);
 
       // Match the ']'.
       MatchRHSPunctuation(tok::r_square, Loc);
       break;
     }
-      
+
     case tok::l_paren: {   // p-e: p-e '(' argument-expression-list[opt] ')'
       ExprVector ArgExprs(Actions);
       CommaLocsTy CommaLocs;
@@ -737,14 +721,13 @@
       }
         
       // Match the ')'.
-      if (!LHS.isInvalid && Tok.is(tok::r_paren)) {
+      if (!LHS.isInvalid() && Tok.is(tok::r_paren)) {
         assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&&
                "Unexpected number of commas!");
-        LHS = Actions.ActOnCallExpr(CurScope, LHSGuard.take(), Loc, 
+        LHS = Actions.ActOnCallExpr(CurScope, LHS.move(), Loc, 
                                     ArgExprs.take(),
                                     ArgExprs.size(), &CommaLocs[0],
                                     Tok.getLocation());
-        LHSGuard.reset(LHS);
       }
       
       MatchRHSPunctuation(tok::r_paren, Loc);
@@ -760,21 +743,19 @@
         return ExprResult(true);
       }
       
-      if (!LHS.isInvalid) {
-        LHS = Actions.ActOnMemberReferenceExpr(LHSGuard.take(), OpLoc, OpKind,
+      if (!LHS.isInvalid()) {
+        LHS = Actions.ActOnMemberReferenceExpr(LHS.move(), OpLoc, OpKind,
                                                Tok.getLocation(),
                                                *Tok.getIdentifierInfo());
-        LHSGuard.reset(LHS);
       }
       ConsumeToken();
       break;
     }
     case tok::plusplus:    // postfix-expression: postfix-expression '++'
     case tok::minusminus:  // postfix-expression: postfix-expression '--'
-      if (!LHS.isInvalid) {
+      if (!LHS.isInvalid()) {
         LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(), 
-                                          Tok.getKind(), LHSGuard.take());
-        LHSGuard.reset(LHS);
+                                          Tok.getKind(), LHS.move());
       }
       ConsumeToken();
       break;
@@ -798,7 +779,7 @@
   ConsumeToken();
   
   // If the operand doesn't start with an '(', it must be an expression.
-  ExprResult Operand;
+  ExprOwner Operand(Actions);
   if (Tok.isNot(tok::l_paren)) {
     Operand = ParseCastExpression(true);
   } else {
@@ -822,16 +803,16 @@
     // If this is a parenthesized expression, it is the start of a 
     // unary-expression, but doesn't include any postfix pieces.  Parse these
     // now if present.
-    Operand = ParsePostfixExpressionSuffix(Operand);
+    Operand = ParsePostfixExpressionSuffix(Operand.move());
   }
   
   // If we get here, the operand to the sizeof/alignof was an expresion.
-  if (!Operand.isInvalid)
+  if (!Operand.isInvalid())
     Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
                                              OpTok.is(tok::kw_sizeof),
-                                             /*isType=*/false, Operand.Val,
+                                             /*isType=*/false, Operand.move(),
                                              SourceRange());
-  return Operand;
+  return Operand.move();
 }
 
 /// ParseBuiltinPrimaryExpression
@@ -850,7 +831,7 @@
 /// [GNU]   offsetof-member-designator '[' expression ']'
 ///
 Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
-  ExprResult Res(false);
+  ExprOwner Res(Actions);
   const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo();
 
   tok::TokenKind T = Tok.getKind();
@@ -868,9 +849,8 @@
   switch (T) {
   default: assert(0 && "Not a builtin primary expression!");
   case tok::kw___builtin_va_arg: {
-    ExprResult Expr = ParseAssignmentExpression();
-    ExprGuard ExprGuard(Actions, Expr);
-    if (Expr.isInvalid) {
+    ExprOwner Expr(Actions, ParseAssignmentExpression());
+    if (Expr.isInvalid()) {
       SkipUntil(tok::r_paren);
       return ExprResult(true);
     }
@@ -879,12 +859,12 @@
       return ExprResult(true);
 
     TypeTy *Ty = ParseTypeName();
-    
+
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       return ExprResult(true);
     }
-    Res = Actions.ActOnVAArg(StartLoc, ExprGuard.take(), Ty, ConsumeParen());
+    Res = Actions.ActOnVAArg(StartLoc, Expr.move(), Ty, ConsumeParen());
     break;
   }
   case tok::kw___builtin_offsetof: {
@@ -931,11 +911,11 @@
         Comps.back().isBrackets = true;
         Comps.back().LocStart = ConsumeBracket();
         Res = ParseExpression();
-        if (Res.isInvalid) {
+        if (Res.isInvalid()) {
           SkipUntil(tok::r_paren);
-          return Res;
+          return Res.move();
         }
-        Comps.back().U.E = Res.Val;
+        Comps.back().U.E = Res.move();
 
         Comps.back().LocEnd =
           MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
@@ -951,36 +931,33 @@
     break;
   }
   case tok::kw___builtin_choose_expr: {
-    ExprResult Cond = ParseAssignmentExpression();
-    ExprGuard CondGuard(Actions, Cond);
-    if (Cond.isInvalid) {
+    ExprOwner Cond(Actions, ParseAssignmentExpression());
+    if (Cond.isInvalid()) {
       SkipUntil(tok::r_paren);
-      return Cond;
+      return Cond.move();
     }
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
-    ExprResult Expr1 = ParseAssignmentExpression();
-    ExprGuard Guard1(Actions, Expr1);
-    if (Expr1.isInvalid) {
+    ExprOwner Expr1(Actions, ParseAssignmentExpression());
+    if (Expr1.isInvalid()) {
       SkipUntil(tok::r_paren);
-      return Expr1;
-    }    
+      return Expr1.move();
+    }
     if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
       return ExprResult(true);
     
-    ExprResult Expr2 = ParseAssignmentExpression();
-    ExprGuard Guard2(Actions, Expr2);
-    if (Expr2.isInvalid) {
+    ExprOwner Expr2(Actions, ParseAssignmentExpression());
+    if (Expr2.isInvalid()) {
       SkipUntil(tok::r_paren);
-      return Expr2;
-    }    
+      return Expr2.move();
+    }
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       return ExprResult(true);
     }
-    Res = Actions.ActOnChooseExpr(StartLoc, CondGuard.take(), Guard1.take(),
-                                  Guard2.take(), ConsumeParen());
+    Res = Actions.ActOnChooseExpr(StartLoc, Cond.move(), Expr1.move(),
+                                  Expr2.move(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_overload: {
@@ -991,13 +968,13 @@
     // comma.  If there is no comma, break and attempt to match r-paren.
     if (Tok.isNot(tok::r_paren)) {
       while (1) {
-        ExprResult ArgExpr = ParseAssignmentExpression();
-        if (ArgExpr.isInvalid) {
+        ExprOwner ArgExpr(Actions, ParseAssignmentExpression());
+        if (ArgExpr.isInvalid()) {
           SkipUntil(tok::r_paren);
           return ExprResult(true);
         } else
-          ArgExprs.push_back(ArgExpr.Val);
-        
+          ArgExprs.push_back(ArgExpr.move());
+
         if (Tok.isNot(tok::comma))
           break;
         // Move to the next argument, remember where the comma was.
@@ -1033,7 +1010,7 @@
   
   // These can be followed by postfix-expr pieces because they are
   // primary-expressions.
-  return ParsePostfixExpressionSuffix(Res);
+  return ParsePostfixExpressionSuffix(Res.move());
 }
 
 /// ParseParenExpression - This parses the unit that starts with a '(' token,
@@ -1054,18 +1031,19 @@
                                                 SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
   SourceLocation OpenLoc = ConsumeParen();
-  ExprResult Result(true);
+  ExprOwner Result(Actions, true);
   CastTy = 0;
   
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
-    Parser::StmtResult Stmt = ParseCompoundStatement(true);
+    StmtOwner Stmt(Actions, ParseCompoundStatement(true));
     ExprType = CompoundStmt;
-    
+
     // If the substmt parsed correctly, build the AST node.
-    if (!Stmt.isInvalid && Tok.is(tok::r_paren))
-      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.Val, Tok.getLocation());
-    
+    if (!Stmt.isInvalid() && Tok.is(tok::r_paren))
+      Result = Actions.ActOnStmtExpr(
+        OpenLoc, Stmt.move(), Tok.getLocation());
+
   } else if (ExprType >= CompoundLiteral && isTypeIdInParens()) {
     // Otherwise, this is a compound literal expression or cast expression.
     TypeTy *Ty = ParseTypeName();
@@ -1081,8 +1059,9 @@
         Diag(OpenLoc, diag::ext_c99_compound_literal);
       Result = ParseInitializer();
       ExprType = CompoundLiteral;
-      if (!Result.isInvalid)
-        return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
+      if (!Result.isInvalid())
+        return Actions.ActOnCompoundLiteral(OpenLoc, Ty, RParenLoc,
+                                            Result.take());
     } else if (ExprType == CastExpr) {
       // Note that this doesn't parse the subsequence cast-expression, it just
       // returns the parsed type to the callee.
@@ -1093,16 +1072,17 @@
       Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
       return ExprResult(true);
     }
-    return Result;
+    return Result.move();
   } else {
     Result = ParseExpression();
     ExprType = SimpleExpr;
-    if (!Result.isInvalid && Tok.is(tok::r_paren))
-      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.Val);
+    if (!Result.isInvalid() && Tok.is(tok::r_paren))
+      Result = Actions.ActOnParenExpr(
+        OpenLoc, Tok.getLocation(), Result.take());
   }
   
   // Match the ')'.
-  if (Result.isInvalid)
+  if (Result.isInvalid())
     SkipUntil(tok::r_paren);
   else {
     if (Tok.is(tok::r_paren))
@@ -1111,7 +1091,7 @@
       MatchRHSPunctuation(tok::r_paren, OpenLoc);
   }
   
-  return Result;
+  return Result.move();
 }
 
 /// ParseStringLiteralExpression - This handles the various token types that
@@ -1148,11 +1128,11 @@
 ///
 bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
   while (1) {
-    ExprResult Expr = ParseAssignmentExpression();
-    if (Expr.isInvalid)
+    ExprOwner Expr(Actions, ParseAssignmentExpression());
+    if (Expr.isInvalid())
       return true;
 
-    Exprs.push_back(Expr.Val);
+    Exprs.push_back(Expr.move());
 
     if (Tok.isNot(tok::comma))
       return false;
@@ -1209,16 +1189,16 @@
   // Inform sema that we are starting a block.
   Actions.ActOnBlockArguments(ParamInfo);
   
-  ExprResult Result = true;
+  ExprOwner Result(Actions, true);
   if (Tok.is(tok::l_brace)) {
-    StmtResult Stmt = ParseCompoundStatementBody();
-    if (!Stmt.isInvalid) {
-      Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope);
+    StmtOwner Stmt(Actions, ParseCompoundStatementBody());
+    if (!Stmt.isInvalid()) {
+      Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.move(), CurScope);
     } else {
       Actions.ActOnBlockError(CaretLoc, CurScope);
     }
   }
   ExitScope();
-  return Result;
+  return Result.move();
 }
 
Index: lib/Parse/AstGuard.h
===================================================================
--- lib/Parse/AstGuard.h	(revision 60622)
+++ lib/Parse/AstGuard.h	(working copy)
@@ -19,38 +19,94 @@
 
 namespace clang
 {
-  /// RAII guard for freeing StmtTys and ExprTys on early exit in the parser.
-  /// Instantiated for statements and expressions (Action::DeleteStmt and
-  /// Action::DeleteExpr).
   template <void (Action::*Destroyer)(void*)>
-  class ASTGuard {
+  class ASTOwner;
+
+  typedef ASTOwner<&Action::DeleteStmt> StmtOwner;
+  typedef ASTOwner<&Action::DeleteExpr> ExprOwner;
+
+  /// Some trickery to switch between an ActionResult and an ASTOwner
+  template <typename Owner> struct ResultOfOwner;
+  template <> struct ResultOfOwner<StmtOwner> {
+    typedef Action::StmtResult type;
+  };
+  template <> struct ResultOfOwner<ExprOwner> {
+    typedef Action::ExprResult type;
+  };
+
+  /// Move emulation helper for ASTOwner. Implicitly convertible to ActionResult
+  /// and void*, which means ASTOwner::move() can be used universally.
+  template <void (Action::*Destroyer)(void*)>
+  class ASTMove {
+    ASTOwner<Destroyer> &Moved;
+
+  public:
+    explicit ASTMove(ASTOwner<Destroyer> &moved) : Moved(moved) {}
+    ASTOwner<Destroyer> * operator ->() {
+      return &Moved;
+    }
+
+    operator typename ResultOfOwner< ASTOwner<Destroyer> >::type() {
+      if (Moved.isInvalid())
+        return true;
+      return Moved.take();
+    }
+
+    operator void*() {
+      if (Moved.isInvalid())
+        return 0;
+      return Moved.take();
+    }
+  };
+
+  /// RAII owning pointer for StmtTys and ExprTys. Simple move emulation.
+  template <void (Action::*Destroyer)(void*)>
+  class ASTOwner {
+    typedef typename ResultOfOwner<ASTOwner>::type Result;
+
     Action &Actions;
     void *Node;
+    bool Invalid;
 
     void destroy() {
       if (Node)
         (Actions.*Destroyer)(Node);
     }
 
-    ASTGuard(const ASTGuard&); // DO NOT IMPLEMENT
+    ASTOwner(const ASTOwner&); // DO NOT IMPLEMENT
     // Reference member prevents copy assignment.
 
   public:
-    explicit ASTGuard(Action &actions) : Actions(actions), Node(0) {}
-    ASTGuard(Action &actions, void *node)
-      : Actions(actions), Node(node) {}
-    template <unsigned N>
-    ASTGuard(Action &actions, const Action::ActionResult<N> &res)
-      : Actions(actions), Node(res.Val) {}
-    ~ASTGuard() { destroy(); }
+    explicit ASTOwner(Action &actions, bool invalid = false)
+      : Actions(actions), Node(0), Invalid(invalid) {}
+    ASTOwner(Action &actions, void *node)
+      : Actions(actions), Node(node), Invalid(false) {}
+    ASTOwner(Action &actions, const Result &res)
+      : Actions(actions), Node(res.Val), Invalid(res.isInvalid) {}
+    ASTOwner(ASTMove<Destroyer> mover)
+      : Actions(mover->Actions), Node(mover->take()), Invalid(mover->Invalid) {}
+    ASTOwner & operator =(ASTMove<Destroyer> mover) {
+      assert(&Actions == &mover->Actions &&
+             "AST Owners from different actions.");
+      destroy();
+      Node = mover->take();
+      Invalid = mover->Invalid;
+      return *this;
+    }
+    ASTOwner & operator =(const Result &res) {
+      reset(res);
+      return *this;
+    }
 
-    void reset(void *element) {
+    void reset(void *node = 0) {
       destroy();
-      Node = element;
+      Node = node;
+      Invalid = false;
     }
-    template <unsigned N>
-    void reset(const Action::ActionResult<N> &res) {
-      reset(res.Val);
+    void reset(const Result &res) {
+      destroy();
+      Node = res.Val;
+      Invalid = res.isInvalid;
     }
     void *take() {
       void *Temp = Node;
@@ -58,11 +114,14 @@
       return Temp;
     }
     void *get() const { return Node; }
+    bool isInvalid() const { return Invalid; }
+    bool isUsable() const { return !Invalid && Node; }
+
+    ASTMove<Destroyer> move() {
+      return ASTMove<Destroyer>(*this);
+    }
   };
 
-  typedef ASTGuard<&Action::DeleteStmt> StmtGuard;
-  typedef ASTGuard<&Action::DeleteExpr> ExprGuard;
-
   /// RAII SmallVector wrapper that holds Action::ExprTy* and similar,
   /// automatically freeing them on destruction unless it's been disowned.
   /// Instantiated for statements and expressions (Action::DeleteStmt and
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp	(revision 60622)
+++ lib/Parse/ParseStmt.cpp	(working copy)
@@ -74,8 +74,8 @@
 /// 
 Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
   const char *SemiError = 0;
-  Parser::StmtResult Res;
-  
+  StmtOwner Res(Actions);
+
   // Cases in this switch statement should fall through if the parser expects
   // the token to end in a semicolon (in which case SemiError should be set),
   // or they directly 'return;' if not.
@@ -98,16 +98,16 @@
   default:
     if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
       SourceLocation DeclStart = Tok.getLocation();
-      DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
+      DeclTy *Decl = ParseDeclaration(Declarator::BlockContext);
       // FIXME: Pass in the right location for the end of the declstmt.
-      return Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
+      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
     } else if (Tok.is(tok::r_brace)) {
       Diag(Tok, diag::err_expected_statement);
       return true;
     } else {
       // expression[opt] ';'
-      ExprResult Res = ParseExpression();
-      if (Res.isInvalid) {
+      ExprOwner Expr(Actions, ParseExpression());
+      if (Expr.isInvalid()) {
         // If the expression is invalid, skip ahead to the next semicolon.  Not
         // doing this opens us up to the possibility of infinite loops if
         // ParseExpression does not consume any tokens.
@@ -116,7 +116,7 @@
       }
       // Otherwise, eat the semicolon.
       ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-      return Actions.ActOnExprStmt(Res.Val);
+      return Actions.ActOnExprStmt(Expr.move());
     }
     
   case tok::kw_case:                // C99 6.8.1: labeled-statement
@@ -163,7 +163,7 @@
   case tok::kw_asm:
     bool msAsm = false;
     Res = ParseAsmStatement(msAsm);
-    if (msAsm) return Res;
+    if (msAsm) return Res.move();
     SemiError = "asm statement";
     break;
   }
@@ -171,12 +171,12 @@
   // If we reached this code, the statement must end in a semicolon.
   if (Tok.is(tok::semi)) {
     ConsumeToken();
-  } else if (!Res.isInvalid) {
+  } else if (!Res.isInvalid()) {
     Diag(Tok, diag::err_expected_semi_after) << SemiError;
     // Skip until we see a } or ;, but don't eat it.
     SkipUntil(tok::r_brace, true, true);
   }
-  return Res;
+  return Res.move();
 }
 
 /// ParseLabeledStatement - We have an identifier and a ':' after it.
@@ -203,15 +203,15 @@
     // TODO: save these somewhere.
     AttrList = ParseAttributes();
 
-  StmtResult SubStmt = ParseStatement();
-  
+  StmtOwner SubStmt(Actions, ParseStatement());
+
   // Broken substmt shouldn't prevent the label from being added to the AST.
-  if (SubStmt.isInvalid)
+  if (SubStmt.isInvalid())
     SubStmt = Actions.ActOnNullStmt(ColonLoc);
-  
+
   return Actions.ActOnLabelStmt(IdentTok.getLocation(), 
                                 IdentTok.getIdentifierInfo(),
-                                ColonLoc, SubStmt.Val);
+                                ColonLoc, SubStmt.move());
 }
 
 /// ParseCaseStatement
@@ -225,29 +225,26 @@
   assert(Tok.is(tok::kw_case) && "Not a case stmt!");
   SourceLocation CaseLoc = ConsumeToken();  // eat the 'case'.
 
-  ExprResult LHS = ParseConstantExpression();
-  if (LHS.isInvalid) {
+  ExprOwner LHS(Actions, ParseConstantExpression());
+  if (LHS.isInvalid()) {
     SkipUntil(tok::colon);
     return true;
   }
-  ExprGuard LHSGuard(Actions, LHS);
-  
+
   // GNU case range extension.
   SourceLocation DotDotDotLoc;
-  ExprTy *RHSVal = 0;
+  ExprOwner RHS(Actions);
   if (Tok.is(tok::ellipsis)) {
     Diag(Tok, diag::ext_gnu_case_range);
     DotDotDotLoc = ConsumeToken();
-    
-    ExprResult RHS = ParseConstantExpression();
-    if (RHS.isInvalid) {
+
+    RHS = ParseConstantExpression();
+    if (RHS.isInvalid()) {
       SkipUntil(tok::colon);
       return true;
     }
-    RHSVal = RHS.Val;
   }
-  ExprGuard RHSGuard(Actions, RHSVal);
-  
+
   if (Tok.isNot(tok::colon)) {
     Diag(Tok, diag::err_expected_colon_after) << "'case'";
     SkipUntil(tok::colon);
@@ -262,14 +259,14 @@
     return true;
   }
   
-  StmtResult SubStmt = ParseStatement();
+  StmtOwner SubStmt(Actions, ParseStatement());
 
   // Broken substmt shouldn't prevent the case from being added to the AST.
-  if (SubStmt.isInvalid)
+  if (SubStmt.isInvalid())
     SubStmt = Actions.ActOnNullStmt(ColonLoc);
   
-  return Actions.ActOnCaseStmt(CaseLoc, LHSGuard.take(), DotDotDotLoc,
-                               RHSGuard.take(), ColonLoc, SubStmt.Val);
+  return Actions.ActOnCaseStmt(CaseLoc, LHS.move(), DotDotDotLoc,
+                               RHS.move(), ColonLoc, SubStmt.move());
 }
 
 /// ParseDefaultStatement
@@ -295,11 +292,12 @@
     return true;
   }
 
-  StmtResult SubStmt = ParseStatement();
-  if (SubStmt.isInvalid)
+  StmtOwner SubStmt(Actions, ParseStatement());
+  if (SubStmt.isInvalid())
     return true;
   
-  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope);
+  return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
+                                  SubStmt.move(), CurScope);
 }
 
 
@@ -338,10 +336,10 @@
   EnterScope(Scope::DeclScope);
 
   // Parse the statements in the body.
-  StmtResult Body = ParseCompoundStatementBody(isStmtExpr);
+  StmtOwner Body(Actions, ParseCompoundStatementBody(isStmtExpr));
 
   ExitScope();
-  return Body;
+  return Body.move();
 }
 
 
@@ -358,7 +356,7 @@
   typedef StmtVector StmtsTy;
   StmtsTy Stmts(Actions);
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    StmtResult R;
+    StmtOwner R(Actions);
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(false);
     } else {
@@ -382,28 +380,28 @@
       } else {
         // Otherwise this was a unary __extension__ marker.  Parse the
         // subexpression and add the __extension__ unary op. 
-        ExprResult Res = ParseCastExpression(false);
+        ExprOwner Res(Actions, ParseCastExpression(false));
 
-        if (Res.isInvalid) {
+        if (Res.isInvalid()) {
           SkipUntil(tok::semi);
           continue;
         }
         
         // Add the __extension__ node to the AST.
         Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, 
-                                   Res.Val);
-        if (Res.isInvalid)
+                                   Res.move());
+        if (Res.isInvalid())
           continue;
         
         // Eat the semicolon at the end of stmt and convert the expr into a
         // statement.
         ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-        R = Actions.ActOnExprStmt(Res.Val);
+        R = Actions.ActOnExprStmt(Res.move());
       }
     }
     
-    if (!R.isInvalid && R.Val)
-      Stmts.push_back(R.Val);
+    if (R.isUsable())
+      Stmts.push_back(R.move());
   }
   
   // We broke out of the while loop because we found a '}' or EOF.
@@ -452,7 +450,7 @@
     EnterScope(Scope::DeclScope | Scope::ControlScope);
 
   // Parse the condition.
-  ExprResult CondExp;
+  ExprOwner CondExp(Actions);
   if (getLang().CPlusPlus) {
     SourceLocation LParenLoc = ConsumeParen();
     CondExp = ParseCXXCondition();
@@ -460,9 +458,8 @@
   } else {
     CondExp = ParseSimpleParenExpression();
   }
-  ExprGuard CondGuard(Actions, CondExp);
 
-  if (CondExp.isInvalid) {
+  if (CondExp.isInvalid()) {
     SkipUntil(tok::semi);
     if (C99orCXX)
       ExitScope();
@@ -492,7 +489,7 @@
 
   // Read the 'then' stmt.
   SourceLocation ThenStmtLoc = Tok.getLocation();
-  StmtResult ThenStmt = ParseStatement();
+  StmtOwner ThenStmt(Actions, ParseStatement());
 
   // Pop the 'if' scope if needed.
   if (NeedsInnerScope) ExitScope();
@@ -500,8 +497,8 @@
   // If it has an else, parse it.
   SourceLocation ElseLoc;
   SourceLocation ElseStmtLoc;
-  StmtResult ElseStmt(false);
-  
+  StmtOwner ElseStmt(Actions);
+
   if (Tok.is(tok::kw_else)) {
     ElseLoc = ConsumeToken();
     
@@ -516,7 +513,7 @@
     //
     NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
     if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-    
+
     ElseStmtLoc = Tok.getLocation();
     ElseStmt = ParseStatement();
 
@@ -530,21 +527,21 @@
   // If the then or else stmt is invalid and the other is valid (and present),
   // make turn the invalid one into a null stmt to avoid dropping the other 
   // part.  If both are invalid, return error.
-  if ((ThenStmt.isInvalid && ElseStmt.isInvalid) ||
-      (ThenStmt.isInvalid && ElseStmt.Val == 0) ||
-      (ThenStmt.Val == 0  && ElseStmt.isInvalid)) {
+  if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
+      (ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
+      (ThenStmt.get() == 0  && ElseStmt.isInvalid())) {
     // Both invalid, or one is invalid and other is non-present: return error.
     return true;
   }
-  
+
   // Now if either are invalid, replace with a ';'.
-  if (ThenStmt.isInvalid)
+  if (ThenStmt.isInvalid())
     ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
-  if (ElseStmt.isInvalid)
+  if (ElseStmt.isInvalid())
     ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
-  
-  return Actions.ActOnIfStmt(IfLoc, CondGuard.take(), ThenStmt.Val,
-                             ElseLoc, ElseStmt.Val);
+
+  return Actions.ActOnIfStmt(IfLoc, CondExp.move(), ThenStmt.move(),
+                             ElseLoc, ElseStmt.move());
 }
 
 /// ParseSwitchStatement
@@ -581,7 +578,7 @@
     EnterScope(Scope::BreakScope);
 
   // Parse the condition.
-  ExprResult Cond;
+  ExprOwner Cond(Actions);
   if (getLang().CPlusPlus) {
     SourceLocation LParenLoc = ConsumeParen();
     Cond = ParseCXXCondition();
@@ -590,13 +587,13 @@
     Cond = ParseSimpleParenExpression();
   }
   
-  if (Cond.isInvalid) {
+  if (Cond.isInvalid()) {
     ExitScope();
     return true;
   }
-    
-  StmtResult Switch = Actions.ActOnStartOfSwitchStmt(Cond.Val);
-  
+
+  StmtOwner Switch(Actions, Actions.ActOnStartOfSwitchStmt(Cond.move()));
+
   // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
@@ -612,19 +609,19 @@
   if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
-  StmtResult Body = ParseStatement();
+  StmtOwner Body(Actions, ParseStatement());
 
   // Pop the body scope if needed.
   if (NeedsInnerScope) ExitScope();
   
-  if (Body.isInvalid) {
+  if (Body.isInvalid()) {
     Body = Actions.ActOnNullStmt(Tok.getLocation());
     // FIXME: Remove the case statement list from the Switch statement.
   }
   
   ExitScope();
   
-  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.Val, Body.Val);
+  return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.move(), Body.move());
 }
 
 /// ParseWhileStatement
@@ -663,7 +660,7 @@
     EnterScope(Scope::BreakScope | Scope::ContinueScope);
 
   // Parse the condition.
-  ExprResult Cond;
+  ExprOwner Cond(Actions);
   if (getLang().CPlusPlus) {
     SourceLocation LParenLoc = ConsumeParen();
     Cond = ParseCXXCondition();
@@ -671,8 +668,7 @@
   } else {
     Cond = ParseSimpleParenExpression();
   }
-  ExprGuard CondGuard(Actions, Cond);
-  
+
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
@@ -688,17 +684,16 @@
   if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
-  StmtResult Body = ParseStatement();
-  StmtGuard BodyGuard(Actions, Body);
+  StmtOwner Body(Actions, ParseStatement());
 
   // Pop the body scope if needed.
   if (NeedsInnerScope) ExitScope();
 
   ExitScope();
   
-  if (Cond.isInvalid || Body.isInvalid) return true;
+  if (Cond.isInvalid() || Body.isInvalid()) return true;
   
-  return Actions.ActOnWhileStmt(WhileLoc, CondGuard.take(), BodyGuard.take());
+  return Actions.ActOnWhileStmt(WhileLoc, Cond.move(), Body.move());
 }
 
 /// ParseDoStatement
@@ -729,15 +724,14 @@
   if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
-  StmtResult Body = ParseStatement();
-  StmtGuard BodyGuard(Actions, Body);
+  StmtOwner Body(Actions, ParseStatement());
 
   // Pop the body scope if needed.
   if (NeedsInnerScope) ExitScope();
 
   if (Tok.isNot(tok::kw_while)) {
     ExitScope();
-    if (!Body.isInvalid) {
+    if (!Body.isInvalid()) {
       Diag(Tok, diag::err_expected_while);
       Diag(DoLoc, diag::note_matching) << "do";
       SkipUntil(tok::semi, false, true);
@@ -754,15 +748,13 @@
   }
   
   // Parse the condition.
-  ExprResult Cond = ParseSimpleParenExpression();
-  ExprGuard CondGuard(Actions, Cond);
-  
+  ExprOwner Cond(Actions, ParseSimpleParenExpression());
+
   ExitScope();
-  
-  if (Cond.isInvalid || Body.isInvalid) return true;
-  
-  return Actions.ActOnDoStmt(DoLoc, BodyGuard.take(),
-                             WhileLoc, CondGuard.take());
+
+  if (Cond.isInvalid() || Body.isInvalid()) return true;
+
+  return Actions.ActOnDoStmt(DoLoc, Body.move(), WhileLoc, Cond.move());
 }
 
 /// ParseForStatement
@@ -812,15 +804,12 @@
     EnterScope(Scope::BreakScope | Scope::ContinueScope);
 
   SourceLocation LParenLoc = ConsumeParen();
-  ExprResult Value;
-  
-  StmtTy *FirstPart = 0;
-  ExprTy *SecondPart = 0;
-  StmtTy *ThirdPart = 0;
+  ExprOwner Value(Actions);
+
   bool ForEach = false;
-  StmtGuard FirstGuard(Actions), ThirdGuard(Actions);
-  ExprGuard SecondGuard(Actions);
-  
+  StmtOwner FirstPart(Actions), ThirdPart(Actions);
+  ExprOwner SecondPart(Actions);
+
   // Parse the first part of the for specifier.
   if (Tok.is(tok::semi)) {  // for (;
     // no first part, eat the ';'.
@@ -833,80 +822,62 @@
     SourceLocation DeclStart = Tok.getLocation();
     DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
     // FIXME: Pass in the right location for the end of the declstmt.
-    StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
-                                                  DeclStart);
-    FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
+    FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
+                                          DeclStart);
     if ((ForEach = isTokIdentifier_in())) {
       ConsumeToken(); // consume 'in'
-      Value = ParseExpression();
-      if (!Value.isInvalid)
-        SecondPart = Value.Val;
+      SecondPart = ParseExpression();
     }
   } else {
     Value = ParseExpression();
 
     // Turn the expression into a stmt.
-    if (!Value.isInvalid) {
-      StmtResult R = Actions.ActOnExprStmt(Value.Val);
-      if (!R.isInvalid)
-        FirstPart = R.Val;
-    }
+    if (!Value.isInvalid())
+      FirstPart = Actions.ActOnExprStmt(Value.move());
       
     if (Tok.is(tok::semi)) {
       ConsumeToken();
     }
     else if ((ForEach = isTokIdentifier_in())) {
       ConsumeToken(); // consume 'in'
-      Value = ParseExpression();
-      if (!Value.isInvalid)
-        SecondPart = Value.Val;
+      SecondPart = ParseExpression();
     }
     else {
-      if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
+      if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
       SkipUntil(tok::semi);
     }
   }
-  FirstGuard.reset(FirstPart);
-  SecondGuard.reset(SecondPart);
   if (!ForEach) {
-    assert(!SecondGuard.get() && "Shouldn't have a second expression yet.");
+    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
     // Parse the second part of the for specifier.
     if (Tok.is(tok::semi)) {  // for (...;;
       // no second part.
-      Value = ExprResult();
     } else {
-      Value = getLang().CPlusPlus ? ParseCXXCondition()
-                                  : ParseExpression();
-      if (!Value.isInvalid)
-        SecondPart = Value.Val;
+      SecondPart = getLang().CPlusPlus ? ParseCXXCondition()
+                                       : ParseExpression();
     }
-  
+
     if (Tok.is(tok::semi)) {
       ConsumeToken();
     } else {
-      if (!Value.isInvalid) Diag(Tok, diag::err_expected_semi_for);
+      if (!SecondPart.isInvalid()) Diag(Tok, diag::err_expected_semi_for);
       SkipUntil(tok::semi);
     }
   
     // Parse the third part of the for specifier.
     if (Tok.is(tok::r_paren)) {  // for (...;...;)
       // no third part.
-      Value = ExprResult();
     } else {
       Value = ParseExpression();
-      if (!Value.isInvalid) {
+      if (!Value.isInvalid()) {
         // Turn the expression into a stmt.
-        StmtResult R = Actions.ActOnExprStmt(Value.Val);
-        if (!R.isInvalid)
-          ThirdPart = R.Val;
+        ThirdPart = Actions.ActOnExprStmt(Value.move());
       }
     }
-    SecondGuard.reset(SecondPart);
-    ThirdGuard.reset(ThirdPart);
   }
   // Match the ')'.
   SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
-  
+
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
@@ -920,29 +891,28 @@
   //
   bool NeedsInnerScope = C99orCXX && Tok.isNot(tok::l_brace);
   if (NeedsInnerScope) EnterScope(Scope::DeclScope);
-  
+
   // Read the body statement.
-  StmtResult Body = ParseStatement();
-  
+  StmtOwner Body(Actions, ParseStatement());
+
   // Pop the body scope if needed.
   if (NeedsInnerScope) ExitScope();
 
   // Leave the for-scope.
   ExitScope();
-    
-  if (Body.isInvalid)
-    return Body;
+
+  if (Body.isInvalid())
+    return true;
   
-  // Release all the guards.
-  FirstGuard.take();
-  SecondGuard.take();
-  ThirdGuard.take();
   if (!ForEach) 
-    return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart, 
-                                SecondPart, ThirdPart, RParenLoc, Body.Val);
+    return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.move(),
+                                SecondPart.move(), ThirdPart.move(), RParenLoc,
+                                Body.move());
   else
-    return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart, 
-                                              SecondPart, RParenLoc, Body.Val);
+    return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
+                                              FirstPart.move(),
+                                              SecondPart.move(),
+                                              RParenLoc, Body.move());
 }
 
 /// ParseGotoStatement
@@ -956,7 +926,7 @@
   assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
   SourceLocation GotoLoc = ConsumeToken();  // eat the 'goto'.
   
-  StmtResult Res;
+  StmtOwner Res(Actions);
   if (Tok.is(tok::identifier)) {
     Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
                                 Tok.getIdentifierInfo());
@@ -965,18 +935,18 @@
     // GNU indirect goto extension.
     Diag(Tok, diag::ext_gnu_indirect_goto);
     SourceLocation StarLoc = ConsumeToken();
-    ExprResult R = ParseExpression();
-    if (R.isInvalid) {  // Skip to the semicolon, but don't consume it.
+    ExprOwner R(Actions, ParseExpression());
+    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
       SkipUntil(tok::semi, false, true);
       return true;
     }
-    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.Val);
+    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.move());
   } else {
     Diag(Tok, diag::err_expected_ident);
     return true;
   }
-    
-  return Res;
+
+  return Res.move();
 }
 
 /// ParseContinueStatement
@@ -1008,15 +978,15 @@
   assert(Tok.is(tok::kw_return) && "Not a return stmt!");
   SourceLocation ReturnLoc = ConsumeToken();  // eat the 'return'.
   
-  ExprResult R(0);
+  ExprOwner R(Actions);
   if (Tok.isNot(tok::semi)) {
     R = ParseExpression();
-    if (R.isInvalid) {  // Skip to the semicolon, but don't consume it.
+    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
       SkipUntil(tok::semi, false, true);
       return true;
     }
   }
-  return Actions.ActOnReturnStmt(ReturnLoc, R.Val);
+  return Actions.ActOnReturnStmt(ReturnLoc, R.move());
 }
 
 /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this
@@ -1098,11 +1068,10 @@
   }
   Loc = ConsumeParen();
   
-  ExprResult AsmString = ParseAsmStringLiteral();
-  if (AsmString.isInvalid)
+  ExprOwner AsmString(Actions, ParseAsmStringLiteral());
+  if (AsmString.isInvalid())
     return true;
-  ExprGuard AsmGuard(Actions, AsmString);
-  
+
   llvm::SmallVector<std::string, 4> Names;
   ExprVector Constraints(Actions);
   ExprVector Exprs(Actions);
@@ -1139,12 +1108,12 @@
     
       // Parse the asm-string list for clobbers.
       while (1) {
-        ExprResult Clobber = ParseAsmStringLiteral();
+        ExprOwner Clobber(Actions, ParseAsmStringLiteral());
 
-        if (Clobber.isInvalid)
+        if (Clobber.isInvalid())
           break;
       
-        Clobbers.push_back(Clobber.Val);
+        Clobbers.push_back(Clobber.move());
       
         if (Tok.isNot(tok::comma)) break;
         ConsumeToken();
@@ -1157,7 +1126,7 @@
   return Actions.ActOnAsmStmt(AsmLoc, isSimple, isVolatile,
                               NumOutputs, NumInputs,
                               &Names[0], Constraints.take(),
-                              Exprs.take(), AsmGuard.take(),
+                              Exprs.take(), AsmString.move(),
                               Clobbers.size(), Clobbers.take(),
                               RParenLoc);
 }
@@ -1203,13 +1172,13 @@
       MatchRHSPunctuation(tok::r_square, Loc);
     } else
       Names.push_back(std::string());
-    
-    ExprResult Constraint = ParseAsmStringLiteral();
-    if (Constraint.isInvalid) {
+
+    ExprOwner Constraint(Actions, ParseAsmStringLiteral());
+    if (Constraint.isInvalid()) {
         SkipUntil(tok::r_paren);
         return true;
     }
-    Constraints.push_back(Constraint.Val);
+    Constraints.push_back(Constraint.move());
 
     if (Tok.isNot(tok::l_paren)) {
       Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
@@ -1218,12 +1187,12 @@
     }
     
     // Read the parenthesized expression.
-    ExprResult Res = ParseSimpleParenExpression();
-    if (Res.isInvalid) {
+    ExprOwner Res(Actions, ParseSimpleParenExpression());
+    if (Res.isInvalid()) {
       SkipUntil(tok::r_paren);
       return true;
     }
-    Exprs.push_back(Res.Val);
+    Exprs.push_back(Res.move());
     // Eat the comma and continue parsing if it exists.
     if (Tok.isNot(tok::comma)) return false;
     ConsumeToken();
@@ -1237,14 +1206,14 @@
   // Do not enter a scope for the brace, as the arguments are in the same scope
   // (the function body) as the body itself.  Instead, just read the statement
   // list and put it into a CompoundStmt for safe keeping.
-  StmtResult FnBody = ParseCompoundStatementBody();
+  StmtOwner FnBody(Actions, ParseCompoundStatementBody());
   
   // If the function body could not be parsed, make a bogus compoundstmt.
-  if (FnBody.isInvalid)
+  if (FnBody.isInvalid())
     FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
   
   // Leave the function body scope.
   ExitScope();
   
-  return Actions.ActOnFinishFunctionBody(Decl, FnBody.Val);
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.move());
 }
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp	(revision 60622)
+++ lib/Parse/ParseDeclCXX.cpp	(working copy)
@@ -489,8 +489,8 @@
   //   member-declarator-list ',' member-declarator
 
   DeclTy *LastDeclInGroup = 0;
-  ExprTy *BitfieldSize = 0;
-  ExprTy *Init = 0;
+  ExprOwner BitfieldSize(Actions);
+  ExprOwner Init(Actions);
 
   while (1) {
 
@@ -501,11 +501,9 @@
 
     if (Tok.is(tok::colon)) {
       ConsumeToken();
-      ExprResult Res = ParseConstantExpression();
-      if (Res.isInvalid)
+      BitfieldSize = ParseConstantExpression();
+      if (BitfieldSize.isInvalid())
         SkipUntil(tok::comma, true, true);
-      else
-        BitfieldSize = Res.Val;
     }
     
     // pure-specifier:
@@ -516,11 +514,9 @@
 
     if (Tok.is(tok::equal)) {
       ConsumeToken();
-      ExprResult Res = ParseInitializer();
-      if (Res.isInvalid)
+      Init = ParseInitializer();
+      if (Init.isInvalid())
         SkipUntil(tok::comma, true, true);
-      else
-        Init = Res.Val;
     }
 
     // If attributes exist after the declarator, parse them.
@@ -533,7 +529,8 @@
     // See Sema::ActOnCXXMemberDeclarator for details.
     LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
                                                        DeclaratorInfo,
-                                                       BitfieldSize, Init,
+                                                       BitfieldSize.move(),
+                                                       Init.move(),
                                                        LastDeclInGroup);
 
     // If we don't have a comma, it is either the end of the list (a ';')
@@ -546,7 +543,8 @@
     
     // Parse the next declarator.
     DeclaratorInfo.clear();
-    BitfieldSize = Init = 0;
+    BitfieldSize.reset();
+    Init.reset();
     
     // Attributes are only allowed on the second declarator.
     if (Tok.is(tok::kw___attribute))
Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp	(revision 60622)
+++ lib/Parse/ParseExprCXX.cpp	(working copy)
@@ -38,7 +38,7 @@
       (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon)))
     return false;
 
-  // ::new and ::delete aren'T nested-name-specifiers, so parsing the :: as
+  // ::new and ::delete aren't nested-name-specifiers, so parsing the :: as
   // a scope specifier only makes things more complicated.
   if (Tok.is(tok::coloncolon) && (NextToken().is(tok::kw_new) ||
                                   NextToken().is(tok::kw_delete)))
@@ -221,14 +221,14 @@
   if (Tok.isNot(tok::l_paren))
     return Diag(Tok, diag::err_expected_lparen_after) << CastName;
 
-  ExprResult Result = ParseSimpleParenExpression(RParenLoc);
+  ExprOwner Result(Actions, ParseSimpleParenExpression(RParenLoc));
 
-  if (!Result.isInvalid)
+  if (!Result.isInvalid())
     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
                                        LAngleBracketLoc, CastTy, RAngleBracketLoc,
-                                       LParenLoc, Result.Val, RParenLoc);
+                                       LParenLoc, Result.move(), RParenLoc);
 
-  return Result;
+  return Result.move();
 }
 
 /// ParseCXXTypeid - This handles the C++ typeid expression.
@@ -249,7 +249,7 @@
       "typeid"))
     return ExprResult(true);
 
-  Parser::ExprResult Result;
+  ExprOwner Result(Actions);
 
   if (isTypeIdInParens()) {
     TypeTy *Ty = ParseTypeName();
@@ -266,17 +266,17 @@
     Result = ParseExpression();
 
     // Match the ')'.
-    if (Result.isInvalid)
+    if (Result.isInvalid())
       SkipUntil(tok::r_paren);
     else {
       MatchRHSPunctuation(tok::r_paren, LParenLoc);
 
       Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
-                                      Result.Val, RParenLoc);
+                                      Result.move(), RParenLoc);
     }
   }
 
-  return Result;
+  return Result.move();
 }
 
 /// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
@@ -310,9 +310,9 @@
     return Actions.ActOnCXXThrow(ThrowLoc);
 
   default:
-    ExprResult Expr = ParseAssignmentExpression();
-    if (Expr.isInvalid) return Expr;
-    return Actions.ActOnCXXThrow(ThrowLoc, Expr.Val);
+    ExprOwner Expr(Actions, ParseAssignmentExpression());
+    if (Expr.isInvalid()) return Expr.move();
+    return Actions.ActOnCXXThrow(ThrowLoc, Expr.move());
   }
 }
 
@@ -388,12 +388,12 @@
 
   // simple-asm-expr[opt]
   if (Tok.is(tok::kw_asm)) {
-    ExprResult AsmLabel = ParseSimpleAsm();
-    if (AsmLabel.isInvalid) {
+    ExprOwner AsmLabel(Actions, ParseSimpleAsm());
+    if (AsmLabel.isInvalid()) {
       SkipUntil(tok::semi);
       return true;
     }
-    DeclaratorInfo.setAsmLabel(AsmLabel.Val);
+    DeclaratorInfo.setAsmLabel(AsmLabel.move());
   }
 
   // If attributes are present, parse them.
@@ -404,13 +404,13 @@
   if (Tok.isNot(tok::equal))
     return Diag(Tok, diag::err_expected_equal_after_declarator);
   SourceLocation EqualLoc = ConsumeToken();
-  ExprResult AssignExpr = ParseAssignmentExpression();
-  if (AssignExpr.isInvalid)
+  ExprOwner AssignExpr(Actions, ParseAssignmentExpression());
+  if (AssignExpr.isInvalid())
     return true;
   
   return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
                                                   DeclaratorInfo,
-                                                  EqualLoc, AssignExpr.Val);
+                                                  EqualLoc, AssignExpr.move());
 }
 
 /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
@@ -776,8 +776,9 @@
   bool first = true;
   while (Tok.is(tok::l_square)) {
     SourceLocation LLoc = ConsumeBracket();
-    ExprResult Size = first ? ParseExpression() : ParseConstantExpression();
-    if (Size.isInvalid) {
+    ExprOwner Size(Actions, first ? ParseExpression()
+                                  : ParseConstantExpression());
+    if (Size.isInvalid()) {
       // Recover
       SkipUntil(tok::r_square);
       return;
@@ -785,7 +786,7 @@
     first = false;
 
     D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
-                                            Size.Val, LLoc));
+                                            Size.move(), LLoc));
 
     if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid())
       return;
@@ -850,9 +851,9 @@
       return true;
   }
 
-  ExprResult Operand = ParseCastExpression(false);
-  if (Operand.isInvalid)
-    return Operand;
+  ExprOwner Operand(Actions, ParseCastExpression(false));
+  if (Operand.isInvalid())
+    return Operand.move();
 
-  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.Val);
+  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.move());
 }
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 60622)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include "clang/Parse/Scope.h"
 #include "ExtensionRAIIObject.h"
 #include "ParsePragma.h"
+#include "AstGuard.h"
 using namespace clang;
 
 Parser::Parser(Preprocessor &pp, Action &actions)
@@ -325,13 +326,13 @@
     return ParseExternalDeclaration();
   }
   case tok::kw_asm: {
-    ExprResult Result = ParseSimpleAsm();
+    ExprOwner Result(Actions, ParseSimpleAsm());
 
     ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
                      "top-level asm block");
 
-    if (!Result.isInvalid)
-      return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.Val);
+    if (!Result.isInvalid())
+      return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.move());
     return 0;
   }
   case tok::at:
@@ -660,12 +661,12 @@
     return true;
   }
 
-  ExprResult Res = ParseStringLiteralExpression();
-  if (Res.isInvalid) return true;
+  ExprOwner Res(Actions, ParseStringLiteralExpression());
+  if (Res.isInvalid()) return true;
 
   // TODO: Diagnose: wide string literal in 'asm'
 
-  return Res;
+  return Res.move();
 }
 
 /// ParseSimpleAsm
@@ -684,14 +685,14 @@
 
   ConsumeParen();
 
-  ExprResult Result = ParseAsmStringLiteral();
+  ExprOwner Result(Actions, ParseAsmStringLiteral());
 
-  if (Result.isInvalid)
+  if (Result.isInvalid())
     SkipUntil(tok::r_paren);
   else
     MatchRHSPunctuation(tok::r_paren, Loc);
 
-  return Result;
+  return Result.move();
 }
 
 /// TryAnnotateTypeOrScopeToken - If the current token position is on a
