Abstract out passing around types and kill off ActionBase.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111901 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 814f203..ea468b0 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -773,7 +773,7 @@
 
   // This is almost certainly an invalid type name. Let the action emit a 
   // diagnostic and attempt to recover.
-  Action::TypeTy *T = 0;
+  ParsedType T;
   if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc,
                                       getCurScope(), SS, T)) {
     // The action emitted a diagnostic, so we don't have to.
@@ -783,8 +783,7 @@
       // name token, and we're done.
       const char *PrevSpec;
       unsigned DiagID;
-      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, 
-                         false);
+      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
       DS.SetRangeEnd(Tok.getLocation());
       ConsumeToken();
       
@@ -981,10 +980,11 @@
       if (Next.is(tok::annot_typename)) {
         DS.getTypeSpecScope() = SS;
         ConsumeToken(); // The C++ scope.
-        if (Tok.getAnnotationValue())
+        if (Tok.getAnnotationValue()) {
+          ParsedType T = getTypeAnnotation(Tok);
           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, 
-                                         PrevSpec, DiagID, 
-                                         Tok.getAnnotationValue());
+                                         PrevSpec, DiagID, T);
+        }
         else
           DS.SetTypeSpecError();
         DS.SetRangeEnd(Tok.getAnnotationEndLoc());
@@ -1013,8 +1013,9 @@
           << Next.getIdentifierInfo();
       }
 
-      TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
-                                            Next.getLocation(), getCurScope(), &SS);
+      ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
+                                               Next.getLocation(),
+                                               getCurScope(), &SS);
 
       // If the referenced identifier is not a type, then this declspec is
       // erroneous: We already checked about that it has no type specifier, and
@@ -1041,10 +1042,11 @@
     }
 
     case tok::annot_typename: {
-      if (Tok.getAnnotationValue())
+      if (Tok.getAnnotationValue()) {
+        ParsedType T = getTypeAnnotation(Tok);
         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                       DiagID, Tok.getAnnotationValue());
-      else
+                                       DiagID, T);
+      } else
         DS.SetTypeSpecError();
       
       if (isInvalid)
@@ -1097,12 +1099,13 @@
         break;
 
       // It has to be available as a typedef too!
-      TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
-                                            Tok.getLocation(), getCurScope());
+      ParsedType TypeRep =
+        Actions.getTypeName(*Tok.getIdentifierInfo(),
+                            Tok.getLocation(), getCurScope());
 
       // If this is not a typedef name, don't parse it as part of the declspec,
       // it must be an implicit int or an error.
-      if (TypeRep == 0) {
+      if (!TypeRep) {
         if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
         goto DoneWithDeclSpec;
       }
@@ -1520,10 +1523,10 @@
 
   // simple-type-specifier:
   case tok::annot_typename: {
-    if (Tok.getAnnotationValue())
+    if (ParsedType T = getTypeAnnotation(Tok)) {
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                     DiagID, Tok.getAnnotationValue());
-    else
+                                     DiagID, T);
+    } else
       DS.SetTypeSpecError();
     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
     ConsumeToken(); // The typename
@@ -1930,7 +1933,7 @@
 
   CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLang().CPlusPlus) {
-    if (ParseOptionalCXXScopeSpecifier(SS, 0, false))
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false))
       return;
 
     if (SS.isSet() && Tok.isNot(tok::identifier)) {
@@ -2016,7 +2019,7 @@
     }
     
     if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID,
-                           Type.get(), false))
+                           Type.get()))
       Diag(StartLoc, DiagID) << PrevSpec;
     
     return;
@@ -2037,8 +2040,8 @@
   if (Tok.is(tok::l_brace))
     ParseEnumBody(StartLoc, TagDecl);
 
-  // FIXME: The DeclSpec should keep the locations of both the keyword and the
-  // name (if there is one).
+  // FIXME: The DeclSpec should keep the locations of both the keyword
+  // and the name (if there is one).
   if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID,
                          TagDecl, Owned))
     Diag(StartLoc, DiagID) << PrevSpec;
@@ -2371,7 +2374,7 @@
 
   // Parse the C++ scope specifier.
   CXXScopeSpec SS;
-  if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) {
+  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true)) {
     TPA.Revert();
     return false;
   }
@@ -2527,7 +2530,7 @@
       (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
        Tok.is(tok::annot_cxxscope))) {
     CXXScopeSpec SS;
-    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail
+    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true); // ignore fail
 
     if (SS.isNotEmpty()) {
       if (Tok.isNot(tok::star)) {
@@ -2686,8 +2689,7 @@
   if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
     // ParseDeclaratorInternal might already have parsed the scope.
     if (D.getCXXScopeSpec().isEmpty()) {
-      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
-                                     true);
+      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), true);
     }
 
     if (D.getCXXScopeSpec().isValid()) {
@@ -2716,7 +2718,7 @@
                              /*EnteringContext=*/true, 
                              /*AllowDestructorName=*/true, 
                              AllowConstructorName,
-                             /*ObjectType=*/0,
+                             ParsedType(),
                              D.getName()) ||
           // Once we're past the identifier, if the scope was bad, mark the
           // whole declarator bad.
@@ -2951,7 +2953,7 @@
     bool hasExceptionSpec = false;
     SourceLocation ThrowLoc;
     bool hasAnyExceptionSpec = false;
-    llvm::SmallVector<TypeTy*, 2> Exceptions;
+    llvm::SmallVector<ParsedType, 2> Exceptions;
     llvm::SmallVector<SourceRange, 2> ExceptionRanges;
     if (getLang().CPlusPlus) {
       ParseTypeQualifierListOpt(DS, false /*no attributes*/);
@@ -3178,7 +3180,7 @@
   bool hasExceptionSpec = false;
   SourceLocation ThrowLoc;
   bool hasAnyExceptionSpec = false;
-  llvm::SmallVector<TypeTy*, 2> Exceptions;
+  llvm::SmallVector<ParsedType, 2> Exceptions;
   llvm::SmallVector<SourceRange, 2> ExceptionRanges;
   
   if (getLang().CPlusPlus) {
@@ -3418,7 +3420,7 @@
   const bool hasParens = Tok.is(tok::l_paren);
 
   bool isCastExpr;
-  TypeTy *CastTy;
+  ParsedType CastTy;
   SourceRange CastRange;
   OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
                                                                isCastExpr,
@@ -3458,7 +3460,7 @@
   unsigned DiagID;
   // Check for duplicate type specifiers (e.g. "int typeof(int)").
   if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
-                         DiagID, Operand.release()))
+                         DiagID, Operand.get()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index c56a1b4..c8cab42 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -141,7 +141,7 @@
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
   if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_namespace_name);
@@ -274,7 +274,7 @@
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
   IdentifierInfo *NamespcName = 0;
   SourceLocation IdentLoc = SourceLocation();
@@ -336,7 +336,7 @@
     IsTypeName = false;
 
   // Parse nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
   // Check nested-name specifier.
   if (SS.isInvalid()) {
@@ -352,7 +352,7 @@
                          /*EnteringContext=*/false,
                          /*AllowDestructorName=*/true,
                          /*AllowConstructorName=*/true,
-                         /*ObjectType=*/0,
+                         ParsedType(),
                          Name)) {
     SkipUntil(tok::semi);
     return 0;
@@ -485,7 +485,7 @@
       AnnotateTemplateIdTokenAsType(SS);
 
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
-      TypeTy *Type = Tok.getAnnotationValue();
+      ParsedType Type = getTypeAnnotation(Tok);
       EndLocation = Tok.getAnnotationEndLoc();
       ConsumeToken();
 
@@ -538,13 +538,13 @@
     // Retrieve the type from the annotation token, consume that token, and
     // return.
     EndLocation = Tok.getAnnotationEndLoc();
-    TypeTy *Type = Tok.getAnnotationValue();
+    ParsedType Type = getTypeAnnotation(Tok);
     ConsumeToken();
     return Type;
   }
 
   // We have an identifier; check whether it is actually a type.
-  TypeTy *Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
+  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
   if (!Type) {
     Diag(IdLoc, diag::err_expected_class_name);
     return true;
@@ -682,7 +682,7 @@
     // "FOO : BAR" is not a potential typo for "FOO::BAR".
     ColonProtectionRAIIObject X(*this);
 
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true))
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true))
       DS.SetTypeSpecError();
     if (SS.isSet())
       if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
@@ -962,27 +962,25 @@
       ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
   }
 
-  void *Result;
+  // FIXME: The DeclSpec should keep the locations of both the keyword and the
+  // name (if there is one).
+  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
+
+  const char *PrevSpec = 0;
+  unsigned DiagID;
+  bool Result;
   if (!TypeResult.isInvalid()) {
-    TagType = DeclSpec::TST_typename;
-    Result = TypeResult.get();
-    Owned = false;
+    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc,
+                                PrevSpec, DiagID, TypeResult.get());
   } else if (!TagOrTempResult.isInvalid()) {
-    Result = TagOrTempResult.get();
+    Result = DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
+                                TagOrTempResult.get(), Owned);
   } else {
     DS.SetTypeSpecError();
     return;
   }
 
-  const char *PrevSpec = 0;
-  unsigned DiagID;
-
-  // FIXME: The DeclSpec should keep the locations of both the keyword and the
-  // name (if there is one).
-  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
-
-  if (DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
-                         Result, Owned))
+  if (Result)
     Diag(StartLoc, DiagID) << PrevSpec;
 
   // At this point, we've successfully parsed a class-specifier in 'definition'
@@ -1138,8 +1136,7 @@
 
   // Parse optional '::' and optional nested-name-specifier.
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0,
-                                 /*EnteringContext=*/false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
 
   // The location of the base class itself.
   SourceLocation BaseLoc = Tok.getLocation();
@@ -1252,11 +1249,11 @@
     if (isAccessDecl) {
       // Collect the scope specifier token we annotated earlier.
       CXXScopeSpec SS;
-      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false);
+      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
 
       // Try to parse an unqualified-id.
       UnqualifiedId Name;
-      if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) {
+      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
         SkipUntil(tok::semi);
         return;
       }
@@ -1748,8 +1745,8 @@
 Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
   // parse '::'[opt] nested-name-specifier[opt]
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
-  TypeTy *TemplateTypeTy = 0;
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
+  ParsedType TemplateTypeTy;
   if (Tok.is(tok::annot_template_id)) {
     TemplateIdAnnotation *TemplateId
       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
@@ -1757,7 +1754,7 @@
         TemplateId->Kind == TNK_Dependent_template_name) {
       AnnotateTemplateIdTokenAsType(&SS);
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
-      TemplateTypeTy = Tok.getAnnotationValue();
+      TemplateTypeTy = getTypeAnnotation(Tok);
     }
   }
   if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
@@ -1806,9 +1803,9 @@
 ///         type-id-list ',' type-id
 ///
 bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
-                                         llvm::SmallVector<TypeTy*, 2>
+                                         llvm::SmallVectorImpl<ParsedType>
                                              &Exceptions,
-                                         llvm::SmallVector<SourceRange, 2>
+                                         llvm::SmallVectorImpl<SourceRange>
                                              &Ranges,
                                          bool &hasAnyExceptionSpec) {
   assert(Tok.is(tok::kw_throw) && "expected throw");
@@ -2068,9 +2065,10 @@
     EnterExpressionEvaluationContext Unevaluated(Actions,
                                                   Action::Unevaluated);
     SourceLocation TypeLoc = Tok.getLocation();
-    TypeTy *Ty = ParseTypeName().get();
+    ParsedType Ty = ParseTypeName().get();
     SourceRange TypeRange(Start, Tok.getLocation());
-    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty, TypeRange);
+    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true,
+                                          Ty.getAsOpaquePtr(), TypeRange);
   } else
     return ParseConstantExpression();
 }
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 626a7ec..fac5473 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -244,7 +244,7 @@
 Parser::OwningExprResult
 Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc,
                                                     SourceLocation SuperLoc,
-                                                    TypeTy *ReceiverType,
+                                                    ParsedType ReceiverType,
                                                     Expr *ReceiverExpr) {
   OwningExprResult R
     = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc,
@@ -423,7 +423,7 @@
 ///
 Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                                      bool isAddressOfOperand,
-                                                     TypeTy *TypeOfCast) {
+                                                     ParsedType TypeOfCast) {
   bool NotCastExpr;
   OwningExprResult Res = ParseCastExpression(isUnaryExpression,
                                              isAddressOfOperand,
@@ -548,7 +548,7 @@
 Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
                                                      bool isAddressOfOperand,
                                                      bool &NotCastExpr,
-                                                     TypeTy *TypeOfCast) {
+                                                     ParsedType TypeOfCast) {
   OwningExprResult Res;
   tok::TokenKind SavedKind = Tok.getKind();
   NotCastExpr = false;
@@ -570,7 +570,7 @@
     // not start a cast expression.
     ParenParseOption ParenExprType =
       (isUnaryExpression && !getLang().CPlusPlus)? CompoundLiteral : CastExpr;
-    TypeTy *CastTy;
+    ParsedType CastTy;
     SourceLocation LParenLoc = Tok.getLocation();
     SourceLocation RParenLoc;
     
@@ -826,7 +826,7 @@
         // type, translate it into a type and continue parsing as a
         // cast expression.
         CXXScopeSpec SS;
-        ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+        ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
         AnnotateTemplateIdTokenAsType(&SS);
         return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
                                    NotCastExpr, TypeOfCast);
@@ -1027,7 +1027,7 @@
       SourceLocation OpLoc = ConsumeToken();  // Eat the "." or "->" token.
 
       CXXScopeSpec SS;
-      Action::TypeTy *ObjectType = 0;
+      ParsedType ObjectType;
       bool MayBePseudoDestructor = false;
       if (getLang().CPlusPlus && !LHS.isInvalid()) {
         LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(),
@@ -1039,7 +1039,7 @@
         ParseOptionalCXXScopeSpecifier(SS, ObjectType, false,
                                        &MayBePseudoDestructor);
         if (SS.isNotEmpty())
-          ObjectType = 0;
+          ObjectType = ParsedType();
       }
 
       if (Tok.is(tok::code_completion)) {
@@ -1108,7 +1108,7 @@
 Parser::OwningExprResult
 Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok,
                                           bool &isCastExpr,
-                                          TypeTy *&CastTy,
+                                          ParsedType &CastTy,
                                           SourceRange &CastRange) {
 
   assert((OpTok.is(tok::kw_typeof)    || OpTok.is(tok::kw_sizeof) ||
@@ -1151,8 +1151,7 @@
     EnterExpressionEvaluationContext Unevaluated(Actions,
                                                  Action::Unevaluated);
     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, 
-                                   0/*TypeOfCast*/,
-                                   CastTy, RParenLoc);
+                                   ParsedType(), CastTy, RParenLoc);
     CastRange = SourceRange(LParenLoc, RParenLoc);
 
     // If ParseParenExpression parsed a '(typename)' sequence only, then this is
@@ -1192,7 +1191,7 @@
   ConsumeToken();
 
   bool isCastExpr;
-  TypeTy *CastTy;
+  ParsedType CastTy;
   SourceRange CastRange;
   OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok,
                                                                isCastExpr,
@@ -1202,7 +1201,8 @@
   if (isCastExpr)
     return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(),
                                           OpTok.is(tok::kw_sizeof),
-                                          /*isType=*/true, CastTy,
+                                          /*isType=*/true,
+                                          CastTy.getAsOpaquePtr(),
                                           CastRange);
 
   // If we get here, the operand to the sizeof/alignof was an expresion.
@@ -1414,14 +1414,14 @@
 ///
 Parser::OwningExprResult
 Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
-                             TypeTy *TypeOfCast, TypeTy *&CastTy,
+                             ParsedType TypeOfCast, ParsedType &CastTy,
                              SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
   GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
   SourceLocation OpenLoc = ConsumeParen();
   OwningExprResult Result(true);
   bool isAmbiguousTypeId;
-  CastTy = 0;
+  CastTy = ParsedType();
 
   if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
     Diag(Tok, diag::ext_gnu_statement_expr);
@@ -1532,7 +1532,7 @@
 ///         '(' type-name ')' '{' initializer-list ',' '}'
 ///
 Parser::OwningExprResult
-Parser::ParseCompoundLiteralExpression(TypeTy *Ty,
+Parser::ParseCompoundLiteralExpression(ParsedType Ty,
                                        SourceLocation LParenLoc,
                                        SourceLocation RParenLoc) {
   assert(Tok.is(tok::l_brace) && "Not a compound literal!");
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 82c5970..b8c16a2 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -57,7 +57,7 @@
 ///
 /// \returns true if there was an error parsing a scope specifier
 bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
-                                            Action::TypeTy *ObjectType,
+                                            ParsedType ObjectType,
                                             bool EnteringContext,
                                             bool *MayBePseudoDestructor) {
   assert(getLang().CPlusPlus &&
@@ -104,7 +104,7 @@
       //
       // To implement this, we clear out the object type as soon as we've
       // seen a leading '::' or part of a nested-name-specifier.
-      ObjectType = 0;
+      ObjectType = ParsedType();
       
       if (Tok.is(tok::code_completion)) {
         // Code completion for a nested-name-specifier, where the code
@@ -212,13 +212,13 @@
           HasScopeSpecifier = true;
         }
 
-        if (TypeToken.getAnnotationValue())
-          SS.setScopeRep(
-            Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS,
-                                                TypeToken.getAnnotationValue(),
+        if (ParsedType T = getTypeAnnotation(TypeToken)) {
+          CXXScopeTy *Scope =
+            Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, T,
                                                 TypeToken.getAnnotationRange(),
-                                                CCLoc));
-        else
+                                                CCLoc);
+          SS.setScopeRep(Scope);
+        } else
           SS.setScopeRep(0);
         SS.setEndLoc(CCLoc);
         continue;
@@ -403,14 +403,14 @@
   //   '::' unqualified-id
   //
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
   
   UnqualifiedId Name;
   if (ParseUnqualifiedId(SS, 
                          /*EnteringContext=*/false, 
                          /*AllowDestructorName=*/false, 
                          /*AllowConstructorName=*/false, 
-                         /*ObjectType=*/0,
+                         /*ObjectType=*/ ParsedType(),
                          Name))
     return ExprError();
 
@@ -519,7 +519,7 @@
       return ExprError();
 
     Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
-                                    Ty.get(), RParenLoc);
+                                    Ty.get().getAsOpaquePtr(), RParenLoc);
   } else {
     // C++0x [expr.typeid]p3:
     //   When typeid is applied to an expression other than an lvalue of a
@@ -565,7 +565,7 @@
 Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc,
                                  tok::TokenKind OpKind,
                                  CXXScopeSpec &SS,
-                                 Action::TypeTy *ObjectType) {
+                                 ParsedType ObjectType) {
   // We're parsing either a pseudo-destructor-name or a dependent
   // member access that has the same form as a
   // pseudo-destructor-name. We parse both in the same way and let
@@ -680,7 +680,7 @@
 Parser::OwningExprResult
 Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-  TypeTy *TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
+  ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
 
   assert(Tok.is(tok::l_paren) && "Expected '('!");
   SourceLocation LParenLoc = ConsumeParen();
@@ -876,7 +876,7 @@
   // type-name
   case tok::annot_typename: {
     DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
-                       Tok.getAnnotationValue());
+                       getTypeAnnotation(Tok));
     break;
   }
 
@@ -1004,7 +1004,7 @@
                                           IdentifierInfo *Name,
                                           SourceLocation NameLoc,
                                           bool EnteringContext,
-                                          TypeTy *ObjectType,
+                                          ParsedType ObjectType,
                                           UnqualifiedId &Id,
                                           bool AssumeTemplateId,
                                           SourceLocation TemplateKWLoc) {
@@ -1085,7 +1085,7 @@
                                    EnteringContext, Template,
                                    MemberOfUnknownSpecialization);
       
-      if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+      if (TNK == TNK_Non_template && !Id.DestructorName.get()) {
         Diag(NameLoc, diag::err_destructor_template_id)
           << Name << SS.getRange();
         return true;        
@@ -1203,7 +1203,7 @@
 ///
 /// \returns true if parsing fails, false otherwise.
 bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
-                                        TypeTy *ObjectType,
+                                        ParsedType ObjectType,
                                         UnqualifiedId &Result) {
   assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
   
@@ -1382,7 +1382,7 @@
 bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                                 bool AllowDestructorName,
                                 bool AllowConstructorName,
-                                TypeTy *ObjectType,
+                                ParsedType ObjectType,
                                 UnqualifiedId &Result) {
 
   // Handle 'A::template B'. This is for template-ids which have not
@@ -1516,17 +1516,17 @@
     SourceLocation ClassNameLoc = ConsumeToken();
     
     if (TemplateSpecified || Tok.is(tok::less)) {
-      Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+      Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc);
       return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
                                           EnteringContext, ObjectType, Result,
                                           TemplateSpecified, TemplateKWLoc);
     }
     
     // Note that this is a destructor name.
-    Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName, 
-                                                   ClassNameLoc, getCurScope(),
-                                                   SS, ObjectType,
-                                                   EnteringContext);
+    ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, 
+                                              ClassNameLoc, getCurScope(),
+                                              SS, ObjectType,
+                                              EnteringContext);
     if (!Ty)
       return true;
 
@@ -1804,7 +1804,7 @@
 /// based on the context past the parens.
 Parser::OwningExprResult
 Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
-                                         TypeTy *&CastTy,
+                                         ParsedType &CastTy,
                                          SourceLocation LParenLoc,
                                          SourceLocation &RParenLoc) {
   assert(getLang().CPlusPlus && "Should only be called for C++!");
@@ -1812,7 +1812,7 @@
   assert(isTypeIdInParens() && "Not a type-id!");
 
   OwningExprResult Result(true);
-  CastTy = 0;
+  CastTy = ParsedType();
 
   // We need to disambiguate a very ugly part of the C++ syntax:
   //
@@ -1857,7 +1857,8 @@
       // will be consumed.
       Result = ParseCastExpression(false/*isUnaryExpression*/,
                                    false/*isAddressofOperand*/,
-                                   NotCastExpr, 0/*TypeOfCast*/);
+                                   NotCastExpr,
+                                   ParsedType()/*TypeOfCast*/);
     }
 
     // If we parsed a cast-expression, it's really a type-id, otherwise it's
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 3be43d8..8d2bc83 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -149,7 +149,8 @@
           NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) {
         CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
-                                                           ConsumeToken(), 0, 
+                                                           ConsumeToken(),
+                                                           ParsedType(), 
                                                            0);
       }
 
@@ -167,7 +168,7 @@
         CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
-                                                           TypeOrExpr,
+                                   ParsedType::getFromOpaquePtr(TypeOrExpr),
                                                            0);
       }
 
@@ -179,7 +180,7 @@
     } else if (getLang().ObjC1 && Tok.is(tok::identifier)) {
       IdentifierInfo *II = Tok.getIdentifierInfo();
       SourceLocation IILoc = Tok.getLocation();
-      TypeTy *ReceiverType;
+      ParsedType ReceiverType;
       // Three cases. This is a message send to a type: [type foo]
       // This is a message send to super:  [super foo]
       // This is a message sent to an expr:  [super.bar foo]
@@ -194,7 +195,7 @@
         if (Kind == Action::ObjCSuperMessage)
           return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                              ConsumeToken(),
-                                                             0,
+                                                             ParsedType(),
                                                              0);
         ConsumeToken(); // the identifier
         if (!ReceiverType) {
@@ -239,7 +240,8 @@
       CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
       return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                          SourceLocation(),
-                                                         0, Idx.take());
+                                                         ParsedType(),
+                                                         Idx.take());
     }
 
     // If this is a normal array designator, remember it.
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 5e28e64..ead7013 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -720,7 +720,7 @@
 ///     '(' objc-type-qualifiers[opt] type-name ')'
 ///     '(' objc-type-qualifiers[opt] ')'
 ///
-Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS, bool IsParameter) {
+ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, bool IsParameter) {
   assert(Tok.is(tok::l_paren) && "expected (");
 
   SourceLocation LParenLoc = ConsumeParen();
@@ -729,7 +729,7 @@
   // Parse type qualifiers, in, inout, etc.
   ParseObjCTypeQualifierList(DS, IsParameter);
 
-  TypeTy *Ty = 0;
+  ParsedType Ty;
   if (isTypeSpecifierQualifier()) {
     TypeResult TypeSpec = ParseTypeName();
     if (!TypeSpec.isInvalid())
@@ -786,12 +786,12 @@
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
-                                       /*ReturnType=*/0, IDecl);
+                                       /*ReturnType=*/ ParsedType(), IDecl);
     ConsumeCodeCompletionToken();
   }
 
   // Parse the return type if present.
-  TypeTy *ReturnType = 0;
+  ParsedType ReturnType;
   ObjCDeclSpec DSRet;
   if (Tok.is(tok::l_paren))
     ReturnType = ParseObjCTypeName(DSRet, false);
@@ -852,7 +852,7 @@
     }
     ConsumeToken(); // Eat the ':'.
 
-    ArgInfo.Type = 0;
+    ArgInfo.Type = ParsedType();
     if (Tok.is(tok::l_paren)) // Parse the argument type if present.
       ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, true);
 
@@ -1822,7 +1822,7 @@
     return true;
 
   IsExpr = false;
-  TypeOrExpr = Type.get();
+  TypeOrExpr = Type.get().getAsOpaquePtr();
   return false;
 }
 
@@ -1867,8 +1867,8 @@
     // get in Objective-C.
     if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
         NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
-      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0, 
-                                            0);
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
+                                            ParsedType(), 0);
 
     // Parse the receiver, which is either a type or an expression.
     bool IsExpr;
@@ -1879,23 +1879,26 @@
     }
 
     if (IsExpr)
-      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0,
+      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
+                                            ParsedType(),
                                             static_cast<Expr*>(TypeOrExpr));
 
     return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
-                                          TypeOrExpr, 0);
+                              ParsedType::getFromOpaquePtr(TypeOrExpr),
+                                          0);
   }
   
   if (Tok.is(tok::identifier)) {
     IdentifierInfo *Name = Tok.getIdentifierInfo();
     SourceLocation NameLoc = Tok.getLocation();
-    TypeTy *ReceiverType;
+    ParsedType ReceiverType;
     switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc,
                                        Name == Ident_super,
                                        NextToken().is(tok::period),
                                        ReceiverType)) {
     case Action::ObjCSuperMessage:
-      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0, 0);
+      return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
+                                            ParsedType(), 0);
 
     case Action::ObjCClassMessage:
       if (!ReceiverType) {
@@ -1921,8 +1924,8 @@
     return move(Res);
   }
 
-  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, 
-                                        Res.take());
+  return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
+                                        ParsedType(), Res.take());
 }
 
 /// \brief Parse the remainder of an Objective-C message following the
@@ -1966,7 +1969,7 @@
 Parser::OwningExprResult
 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
                                        SourceLocation SuperLoc,
-                                       TypeTy *ReceiverType,
+                                       ParsedType ReceiverType,
                                        ExprArg ReceiverExpr) {
   if (Tok.is(tok::code_completion)) {
     if (SuperLoc.isValid())
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 835b6e5..a1c64ea 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -481,7 +481,7 @@
   // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
   // we introduce the type parameter into the local scope.
   SourceLocation EqualLoc;
-  TypeTy *DefaultArg = 0;
+  ParsedType DefaultArg;
   if (Tok.is(tok::equal)) {
     EqualLoc = ConsumeToken();
     DefaultArg = ParseTypeName().get();
@@ -587,7 +587,7 @@
   // Parse this as a typename.
   Declarator ParamDecl(DS, Declarator::TemplateParamContext);
   ParseDeclarator(ParamDecl);
-  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) {
+  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
     // This probably shouldn't happen - and it's more of a Sema thing, but
     // basically we didn't parse the type name because we couldn't associate
     // it with an AST node. we should just skip to the comma or greater.
@@ -785,7 +785,7 @@
     }
 
     Tok.setKind(tok::annot_typename);
-    Tok.setAnnotationValue(Type.get());
+    setTypeAnnotation(Tok, Type.get());
     if (SS && SS->isNotEmpty())
       Tok.setLocation(SS->getBeginLoc());
     else if (TemplateKWLoc.isValid())
@@ -858,7 +858,7 @@
                                   TemplateId->RAngleLoc);
   // Create the new "type" annotation token.
   Tok.setKind(tok::annot_typename);
-  Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get());
+  setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get());
   if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
     Tok.setLocation(SS->getBeginLoc());
   // End location stays the same
@@ -893,7 +893,7 @@
   // followed by a token that terminates a template argument, such as ',', 
   // '>', or (in some cases) '>>'.
   CXXScopeSpec SS; // nested-name-specifier, if present
-  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, 
+  ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
                                  /*EnteringContext=*/false);
   
   if (SS.isSet() && Tok.is(tok::kw_template)) {
@@ -912,8 +912,9 @@
       // template argument.
       TemplateTy Template;
       if (isEndOfTemplateArgument(Tok) &&
-          Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc, SS, Name, 
-                                             /*ObjectType=*/0,
+          Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc,
+                                             SS, Name, 
+                                             /*ObjectType=*/ ParsedType(),
                                              /*EnteringContext=*/false,
                                              Template))
         return ParsedTemplateArgument(SS, Template, Name.StartLocation);
@@ -930,7 +931,7 @@
       TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,
                                                /*hasTemplateKeyword=*/false,
                                                     Name,
-                                                    /*ObjectType=*/0, 
+                                               /*ObjectType=*/ ParsedType(), 
                                                     /*EnteringContext=*/false, 
                                                     Template,
                                                 MemberOfUnknownSpecialization);
@@ -965,7 +966,8 @@
     if (TypeArg.isInvalid())
       return ParsedTemplateArgument();
     
-    return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), 
+    return ParsedTemplateArgument(ParsedTemplateArgument::Type,
+                                  TypeArg.get().getAsOpaquePtr(), 
                                   Loc);
   }
   
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 498a7d3..a339894 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -921,7 +921,7 @@
     //            simple-template-id
     SourceLocation TypenameLoc = ConsumeToken();
     CXXScopeSpec SS;
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false))
+    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/ParsedType(), false))
       return true;
     if (!SS.isSet()) {
       Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
@@ -949,7 +949,7 @@
       if (Tok.getAnnotationValue())
         Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, 
                                        SourceLocation(),
-                                       Tok.getAnnotationValue());
+                                       getTypeAnnotation(Tok));
       else
         Ty = true;
     } else {
@@ -960,7 +960,7 @@
 
     SourceLocation EndLoc = Tok.getLastLoc();
     Tok.setKind(tok::annot_typename);
-    Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
+    setTypeAnnotation(Tok, Ty.isInvalid() ? ParsedType() : Ty.get());
     Tok.setAnnotationEndLoc(EndLoc);
     Tok.setLocation(TypenameLoc);
     PP.AnnotateCachedTokens(Tok);
@@ -972,17 +972,18 @@
 
   CXXScopeSpec SS;
   if (getLang().CPlusPlus)
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
       return true;
 
   if (Tok.is(tok::identifier)) {
     // Determine whether the identifier is a type name.
-    if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
-                                         Tok.getLocation(), getCurScope(), &SS)) {
+    if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
+                                            Tok.getLocation(), getCurScope(),
+                                            &SS)) {
       // This is a typename. Replace the current token in-place with an
       // annotation type token.
       Tok.setKind(tok::annot_typename);
-      Tok.setAnnotationValue(Ty);
+      setTypeAnnotation(Tok, Ty);
       Tok.setAnnotationEndLoc(Tok.getLocation());
       if (SS.isNotEmpty()) // it was a C++ qualified type name.
         Tok.setLocation(SS.getBeginLoc());
@@ -1009,7 +1010,8 @@
       if (TemplateNameKind TNK
           = Actions.isTemplateName(getCurScope(), SS,
                                    /*hasTemplateKeyword=*/false, TemplateName,
-                                   /*ObjectType=*/0, EnteringContext,
+                                   /*ObjectType=*/ ParsedType(),
+                                   EnteringContext,
                                    Template, MemberOfUnknownSpecialization)) {
         // Consume the identifier.
         ConsumeToken();
@@ -1077,7 +1079,7 @@
          "Cannot be a type or scope token!");
 
   CXXScopeSpec SS;
-  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
+  if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
     return true;
   if (SS.isEmpty())
     return false;