Calculate the value kind of an expression when it's created and
store it on the expression node.  Also store an "object kind",
which distinguishes ordinary "addressed" l-values (like
variable references and pointer dereferences) and bitfield,
@property, and vector-component l-values.

Currently we're not using these for much, but I aim to switch
pretty much everything calculating l-valueness over to them.
For now they shouldn't necessarily be trusted.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119685 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 159a269..b4edc5f 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2813,7 +2813,7 @@
                              Importer.Import(E->getQualifierRange()),
                              ToD,
                              Importer.Import(E->getLocation()),
-                             T,
+                             T, E->getValueKind(),
                              /*FIXME:TemplateArgs=*/0);
 }
 
@@ -2858,7 +2858,8 @@
     return 0;
   
   return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
-                                                     T,
+                                                     T, E->getValueKind(),
+                                                     E->getObjectKind(),
                                          Importer.Import(E->getOperatorLoc()));                                        
 }
 
@@ -2900,7 +2901,8 @@
     return 0;
   
   return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
-                                                      T,
+                                                      T, E->getValueKind(),
+                                                      E->getObjectKind(),
                                           Importer.Import(E->getOperatorLoc()));
 }
 
@@ -2927,7 +2929,9 @@
   
   return new (Importer.getToContext()) 
                         CompoundAssignOperator(LHS, RHS, E->getOpcode(),
-                                               T, CompLHSType, CompResultType,
+                                               T, E->getValueKind(),
+                                               E->getObjectKind(),
+                                               CompLHSType, CompResultType,
                                           Importer.Import(E->getOperatorLoc()));
 }
 
@@ -2972,7 +2976,8 @@
   if (ImportCastPath(E, BasePath))
     return 0;
 
-  return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
+  return CStyleCastExpr::Create(Importer.getToContext(), T,
+                                E->getValueKind(), E->getCastKind(),
                                 SubExpr, &BasePath, TInfo,
                                 Importer.Import(E->getLParenLoc()),
                                 Importer.Import(E->getRParenLoc()));
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index cce4343..f21c9a3 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -318,6 +318,7 @@
                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       Expr *E = new (Context) DeclRefExpr(NTTP,
                                   NTTP->getType().getNonLValueExprType(Context),
+                                  Expr::getValueKindForType(NTTP->getType()),
                                           NTTP->getLocation());
       TemplateArgs.push_back(TemplateArgument(E));
     } else {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index b03594f..c920611 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -194,8 +194,8 @@
                          SourceRange QualifierRange,
                          ValueDecl *D, SourceLocation NameLoc,
                          const TemplateArgumentListInfo *TemplateArgs,
-                         QualType T)
-  : Expr(DeclRefExprClass, T, false, false),
+                         QualType T, ExprValueKind VK)
+  : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false),
     DecoratedD(D,
                (Qualifier? HasQualifierFlag : 0) |
                (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
@@ -216,8 +216,8 @@
                          SourceRange QualifierRange,
                          ValueDecl *D, const DeclarationNameInfo &NameInfo,
                          const TemplateArgumentListInfo *TemplateArgs,
-                         QualType T)
-  : Expr(DeclRefExprClass, T, false, false),
+                         QualType T, ExprValueKind VK)
+  : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false),
     DecoratedD(D,
                (Qualifier? HasQualifierFlag : 0) |
                (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
@@ -240,10 +240,11 @@
                                  ValueDecl *D,
                                  SourceLocation NameLoc,
                                  QualType T,
+                                 ExprValueKind VK,
                                  const TemplateArgumentListInfo *TemplateArgs) {
   return Create(Context, Qualifier, QualifierRange, D,
                 DeclarationNameInfo(D->getDeclName(), NameLoc),
-                T, TemplateArgs);
+                T, VK, TemplateArgs);
 }
 
 DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@@ -252,6 +253,7 @@
                                  ValueDecl *D,
                                  const DeclarationNameInfo &NameInfo,
                                  QualType T,
+                                 ExprValueKind VK,
                                  const TemplateArgumentListInfo *TemplateArgs) {
   std::size_t Size = sizeof(DeclRefExpr);
   if (Qualifier != 0)
@@ -262,7 +264,7 @@
   
   void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
   return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo,
-                               TemplateArgs, T);
+                               TemplateArgs, T, VK);
 }
 
 DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier,
@@ -592,8 +594,9 @@
 //===----------------------------------------------------------------------===//
 
 CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args,
-                   unsigned numargs, QualType t, SourceLocation rparenloc)
-  : Expr(SC, t,
+                   unsigned numargs, QualType t, ExprValueKind VK,
+                   SourceLocation rparenloc)
+  : Expr(SC, t, VK, OK_Ordinary,
          fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
          fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
     NumArgs(numargs) {
@@ -607,8 +610,8 @@
 }
 
 CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
-                   QualType t, SourceLocation rparenloc)
-  : Expr(CallExprClass, t,
+                   QualType t, ExprValueKind VK, SourceLocation rparenloc)
+  : Expr(CallExprClass, t, VK, OK_Ordinary,
          fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs),
          fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)),
     NumArgs(numargs) {
@@ -740,7 +743,8 @@
                            OffsetOfNode* compsPtr, unsigned numComps, 
                            Expr** exprsPtr, unsigned numExprs,
                            SourceLocation RParenLoc)
-  : Expr(OffsetOfExprClass, type, /*TypeDependent=*/false, 
+  : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary,
+         /*TypeDependent=*/false, 
          /*ValueDependent=*/tsi->getType()->isDependentType() ||
          hasAnyTypeDependentArguments(exprsPtr, numExprs) ||
          hasAnyValueDependentArguments(exprsPtr, numExprs)),
@@ -771,7 +775,9 @@
                                DeclAccessPair founddecl,
                                DeclarationNameInfo nameinfo,
                                const TemplateArgumentListInfo *targs,
-                               QualType ty) {
+                               QualType ty,
+                               ExprValueKind vk,
+                               ExprObjectKind ok) {
   std::size_t Size = sizeof(MemberExpr);
 
   bool hasQualOrFound = (qual != 0 ||
@@ -784,7 +790,8 @@
     Size += ExplicitTemplateArgumentList::sizeFor(*targs);
 
   void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>());
-  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, ty);
+  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo,
+                                       ty, vk, ok);
 
   if (hasQualOrFound) {
     if (qual && qual->isDependent()) {
@@ -964,7 +971,7 @@
 
 
 CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T,
-                                       CastKind K, Expr *Op,
+                                       ExprValueKind VK, CastKind K, Expr *Op,
                                        const CXXCastPath *BasePath,
                                        TypeSourceInfo *WrittenTy,
                                        SourceLocation L, SourceLocation R) {
@@ -972,7 +979,7 @@
   void *Buffer =
     C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
   CStyleCastExpr *E =
-    new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R);
+    new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -1089,7 +1096,7 @@
 InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
                            Expr **initExprs, unsigned numInits,
                            SourceLocation rbraceloc)
-  : Expr(InitListExprClass, QualType(), false, false),
+  : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false),
     InitExprs(C, numInits),
     LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
     UnionFieldInit(0), HadArrayRangeDesignator(false) 
@@ -2158,6 +2165,7 @@
 }
 
 ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 ExprValueKind VK,
                                  SourceLocation LBracLoc,
                                  SourceLocation SuperLoc,
                                  bool IsInstanceSuper,
@@ -2166,8 +2174,8 @@
                                  ObjCMethodDecl *Method,
                                  Expr **Args, unsigned NumArgs,
                                  SourceLocation RBracLoc)
-  : Expr(ObjCMessageExprClass, T, /*TypeDependent=*/false,
-         /*ValueDependent=*/false),
+  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
+         /*TypeDependent=*/false, /*ValueDependent=*/false),
     NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
     HasMethod(Method != 0), SuperLoc(SuperLoc),
     SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
@@ -2180,13 +2188,14 @@
 }
 
 ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 ExprValueKind VK,
                                  SourceLocation LBracLoc,
                                  TypeSourceInfo *Receiver,
                                  Selector Sel, 
                                  ObjCMethodDecl *Method,
                                  Expr **Args, unsigned NumArgs,
                                  SourceLocation RBracLoc)
-  : Expr(ObjCMessageExprClass, T, T->isDependentType(),
+  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
          (T->isDependentType() || 
           hasAnyValueDependentArguments(Args, NumArgs))),
     NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0),
@@ -2200,13 +2209,14 @@
 }
 
 ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 ExprValueKind VK,
                                  SourceLocation LBracLoc,
                                  Expr *Receiver,
                                  Selector Sel, 
                                  ObjCMethodDecl *Method,
                                  Expr **Args, unsigned NumArgs,
                                  SourceLocation RBracLoc)
-  : Expr(ObjCMessageExprClass, T, Receiver->isTypeDependent(),
+  : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(),
          (Receiver->isTypeDependent() || 
           hasAnyValueDependentArguments(Args, NumArgs))),
     NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0),
@@ -2220,6 +2230,7 @@
 }
 
 ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         ExprValueKind VK,
                                          SourceLocation LBracLoc,
                                          SourceLocation SuperLoc,
                                          bool IsInstanceSuper,
@@ -2231,12 +2242,13 @@
   unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
     NumArgs * sizeof(Expr *);
   void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
-  return new (Mem) ObjCMessageExpr(T, LBracLoc, SuperLoc, IsInstanceSuper,
+  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper,
                                    SuperType, Sel, Method, Args, NumArgs, 
                                    RBracLoc);
 }
 
 ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         ExprValueKind VK,
                                          SourceLocation LBracLoc,
                                          TypeSourceInfo *Receiver,
                                          Selector Sel, 
@@ -2246,11 +2258,12 @@
   unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
     NumArgs * sizeof(Expr *);
   void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
-  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args,
                                    NumArgs, RBracLoc);
 }
 
 ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         ExprValueKind VK,
                                          SourceLocation LBracLoc,
                                          Expr *Receiver,
                                          Selector Sel, 
@@ -2260,7 +2273,7 @@
   unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
     NumArgs * sizeof(Expr *);
   void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
-  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+  return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args, 
                                    NumArgs, RBracLoc);
 }
 
@@ -2343,6 +2356,7 @@
                                        unsigned NumIndexExprs,
                                        Expr *Init)
   : Expr(DesignatedInitExprClass, Ty,
+         Init->getValueKind(), Init->getObjectKind(),
          Init->isTypeDependent(), Init->isValueDependent()),
     EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
     NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
@@ -2483,7 +2497,7 @@
 ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
                              Expr **exprs, unsigned nexprs,
                              SourceLocation rparenloc)
-: Expr(ParenListExprClass, QualType(),
+: Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
        hasAnyTypeDependentArguments(exprs, nexprs),
        hasAnyValueDependentArguments(exprs, nexprs)),
   NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 1820ff7..63bf2dd 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -116,7 +116,8 @@
                        SourceLocation startLoc, SourceLocation endLoc,
                        SourceLocation constructorLParen,
                        SourceLocation constructorRParen)
-  : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
+  : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
+         ty->isDependentType(), ty->isDependentType()),
     GlobalNew(globalNew),
     Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
     OperatorDelete(operatorDelete), Constructor(constructor),
@@ -247,7 +248,7 @@
                            bool HasTemplateArgs,
                            UnresolvedSetIterator Begin, 
                            UnresolvedSetIterator End)
-  : Expr(K, T, Dependent, Dependent),
+  : Expr(K, T, VK_LValue, OK_Ordinary, Dependent, Dependent),
   Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), 
   QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
 {
@@ -436,6 +437,7 @@
 }
 
 CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
+                                             ExprValueKind VK,
                                              CastKind K, Expr *Op,
                                              const CXXCastPath *BasePath,
                                              TypeSourceInfo *WrittenTy,
@@ -444,7 +446,7 @@
   void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
                             + PathSize * sizeof(CXXBaseSpecifier*));
   CXXStaticCastExpr *E =
-    new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
+    new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -457,6 +459,7 @@
 }
 
 CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
+                                               ExprValueKind VK,
                                                CastKind K, Expr *Op,
                                                const CXXCastPath *BasePath,
                                                TypeSourceInfo *WrittenTy,
@@ -465,7 +468,7 @@
   void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
                             + PathSize * sizeof(CXXBaseSpecifier*));
   CXXDynamicCastExpr *E =
-    new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
+    new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -478,14 +481,15 @@
 }
 
 CXXReinterpretCastExpr *
-CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
+CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
+                               CastKind K, Expr *Op,
                                const CXXCastPath *BasePath,
                                TypeSourceInfo *WrittenTy, SourceLocation L) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
   void *Buffer =
     C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
   CXXReinterpretCastExpr *E =
-    new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
+    new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -497,10 +501,11 @@
   return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
 }
 
-CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
+CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T,
+                                           ExprValueKind VK, Expr *Op,
                                            TypeSourceInfo *WrittenTy,
                                            SourceLocation L) {
-  return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
+  return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L);
 }
 
 CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
@@ -508,7 +513,7 @@
 }
 
 CXXFunctionalCastExpr *
-CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
+CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
                               TypeSourceInfo *Written, SourceLocation L,
                               CastKind K, Expr *Op, const CXXCastPath *BasePath,
                                SourceLocation R) {
@@ -516,7 +521,7 @@
   void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
                             + PathSize * sizeof(CXXBaseSpecifier*));
   CXXFunctionalCastExpr *E =
-    new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
+    new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R);
   if (PathSize) E->setCastPath(*BasePath);
   return E;
 }
@@ -592,7 +597,7 @@
                                    bool ZeroInitialization, 
                                    ConstructionKind ConstructKind,
                                    SourceRange ParenRange)
-: Expr(SC, T,
+: Expr(SC, T, VK_RValue, OK_Ordinary,
        T->isDependentType(),
        (T->isDependentType() ||
         CallExpr::hasAnyValueDependentArguments(args, numargs))),
@@ -615,7 +620,8 @@
                                                CXXTemporary **temps,
                                                unsigned numtemps)
   : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
-       subexpr->isTypeDependent(), subexpr->isValueDependent()),
+         subexpr->getValueKind(), subexpr->getObjectKind(),
+         subexpr->isTypeDependent(), subexpr->isValueDependent()),
     SubExpr(subexpr), Temps(0), NumTemps(0) {
   if (numtemps) {
     setNumTemporaries(C, numtemps);
@@ -671,6 +677,7 @@
                                                  SourceLocation RParenLoc)
   : Expr(CXXUnresolvedConstructExprClass, 
          Type->getType().getNonReferenceType(),
+         VK_RValue, OK_Ordinary,
          Type->getType()->isDependentType(), true),
     Type(Type),
     LParenLoc(LParenLoc),
@@ -722,7 +729,8 @@
                                           NamedDecl *FirstQualifierFoundInScope,
                                           DeclarationNameInfo MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs)
-  : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
+  : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
+         VK_LValue, OK_Ordinary, true, true),
     Base(Base), BaseType(BaseType), IsArrow(IsArrow),
     HasExplicitTemplateArgs(TemplateArgs != 0),
     OperatorLoc(OperatorLoc),
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 60fbfd2..4677910 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -292,9 +292,7 @@
   }
       
   case Expr::CXXUuidofExprClass:
-    // Assume that Microsoft's __uuidof returns an lvalue, like typeid does.
-    // FIXME: Is this really the case?
-    return Cl::CL_LValue;
+    return Cl::CL_PRValue;
   }
   
   llvm_unreachable("unhandled expression kind in classification");
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index afc9b50..15a8d61 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -105,10 +105,27 @@
          << " " << (void*)Node;
       DumpSourceRange(Node);
     }
+    void DumpValueKind(ExprValueKind K) {
+      switch (K) {
+      case VK_RValue: break;
+      case VK_LValue: OS << " lvalue"; break;
+      case VK_XValue: OS << " xvalue"; break;
+      }
+    }
+    void DumpObjectKind(ExprObjectKind K) {
+      switch (K) {
+      case OK_Ordinary: break;
+      case OK_BitField: OS << " bitfield"; break;
+      case OK_ObjCProperty: OS << " objcproperty"; break;
+      case OK_VectorComponent: OS << " vectorcomponent"; break;
+      }
+    }
     void DumpExpr(const Expr *Node) {
       DumpStmt(Node);
       OS << ' ';
       DumpType(Node->getType());
+      DumpValueKind(Node->getValueKind());
+      DumpObjectKind(Node->getObjectKind());
     }
     void DumpSourceRange(const Stmt *Node);
     void DumpLocation(SourceLocation Loc);
@@ -122,7 +139,6 @@
     // Exprs
     void VisitExpr(Expr *Node);
     void VisitCastExpr(CastExpr *Node);
-    void VisitImplicitCastExpr(ImplicitCastExpr *Node);
     void VisitDeclRefExpr(DeclRefExpr *Node);
     void VisitPredefinedExpr(PredefinedExpr *Node);
     void VisitCharacterLiteral(CharacterLiteral *Node);
@@ -344,20 +360,6 @@
   OS << ">";
 }
 
-void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
-  VisitCastExpr(Node);
-  switch (Node->getValueKind()) {
-  case VK_LValue:
-    OS << " lvalue";
-    break;
-  case VK_XValue:
-    OS << " xvalue";
-    break;
-  case VK_RValue:
-    break;
-  }
-}
-
 void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
   DumpExpr(Node);