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/Sema/Action.cpp b/lib/Sema/Action.cpp
index 32d537d..1df0e01 100644
--- a/lib/Sema/Action.cpp
+++ b/lib/Sema/Action.cpp
@@ -34,71 +34,5 @@
   OS << '\n';
 }
 
-///  Out-of-line virtual destructor to provide home for ActionBase class.
-ActionBase::~ActionBase() {}
-
 ///  Out-of-line virtual destructor to provide home for Action class.
 Action::~Action() {}
-
-Action::ObjCMessageKind Action::getObjCMessageKind(Scope *S,
-                                                   IdentifierInfo *Name,
-                                                   SourceLocation NameLoc,
-                                                   bool IsSuper,
-                                                   bool HasTrailingDot,
-                                                   TypeTy *&ReceiverType) {
-  ReceiverType = 0;
-
-  if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
-    return ObjCSuperMessage;
-      
-  if (TypeTy *TyName = getTypeName(*Name, NameLoc, S)) {
-    DeclSpec DS;
-    const char *PrevSpec = 0;
-    unsigned DiagID = 0;
-    if (!DS.SetTypeSpecType(DeclSpec::TST_typename, NameLoc, PrevSpec,
-                            DiagID, TyName)) {
-      DS.SetRangeEnd(NameLoc);
-      Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-      TypeResult Ty = ActOnTypeName(S, DeclaratorInfo);
-      if (!Ty.isInvalid())
-        ReceiverType = Ty.get();
-    }
-    return ObjCClassMessage;
-  }
-      
-  return ObjCInstanceMessage;
-}
-
-// Defined out-of-line here because of dependecy on AttributeList
-Decl *Action::ActOnUsingDirective(Scope *CurScope,
-                                  SourceLocation UsingLoc,
-                                  SourceLocation NamespcLoc,
-                                  CXXScopeSpec &SS,
-                                  SourceLocation IdentLoc,
-                                  IdentifierInfo *NamespcName,
-                                  AttributeList *AttrList) {
-
-  // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
-  // passed AttributeList, however other actions don't free it, is it
-  // temporary state or bug?
-  delete AttrList;
-  return 0;
-}
-
-// Defined out-of-line here because of dependency on AttributeList
-Decl *Action::ActOnUsingDeclaration(Scope *CurScope,
-                                    AccessSpecifier AS,
-                                    bool HasUsingKeyword,
-                                    SourceLocation UsingLoc,
-                                    CXXScopeSpec &SS,
-                                    UnqualifiedId &Name,
-                                    AttributeList *AttrList,
-                                    bool IsTypeName,
-                                    SourceLocation TypenameLoc) {
-
-  // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
-  // passed AttributeList, however other actions don't free it, is it
-  // temporary state or bug?
-  delete AttrList;
-  return 0;
-}
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index cf99227..3f34aa6 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -19,7 +19,7 @@
 AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
                              IdentifierInfo *sName, SourceLocation sLoc,
                              IdentifierInfo *pName, SourceLocation pLoc,
-                             ActionBase::ExprTy **ExprList, unsigned numArgs,
+                             Expr **ExprList, unsigned numArgs,
                              AttributeList *n, bool declspec, bool cxx0x)
   : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
     ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
@@ -28,7 +28,7 @@
   if (numArgs == 0)
     Args = 0;
   else {
-    Args = new ActionBase::ExprTy*[numArgs];
+    Args = new Expr*[numArgs];
     memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
   }
 }
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index d1481bf..956775a 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -54,7 +54,7 @@
                                              bool hasExceptionSpec,
                                              SourceLocation ThrowLoc,
                                              bool hasAnyExceptionSpec,
-                                             ActionBase::TypeTy **Exceptions,
+                                             ParsedType *Exceptions,
                                              SourceRange *ExceptionRanges,
                                              unsigned NumExceptions,
                                              SourceLocation LPLoc,
@@ -291,7 +291,63 @@
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               void *Rep, bool Owned) {
+                               ParsedType Rep) {
+  assert(isTypeRep(T) && "T does not store a type");
+  assert(Rep && "no type provided!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  TypeRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Expr *Rep) {
+  assert(isExprRep(T) && "T does not store an expr");
+  assert(Rep && "no expression provided!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  ExprRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Decl *Rep, bool Owned) {
+  assert(isDeclRep(T) && "T does not store a decl");
+  // Unlike the other cases, we don't assert that we actually get a decl.
+
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  DeclRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = Owned;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID) {
+  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
+         "rep required for these type-spec kinds!");
   if (TypeSpecType != TST_unspecified) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     DiagID = diag::err_invalid_decl_spec_combination;
@@ -303,9 +359,8 @@
     return false;
   }
   TypeSpecType = T;
-  TypeRep = Rep;
   TSTLoc = Loc;
-  TypeSpecOwned = Owned;
+  TypeSpecOwned = false;
   if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
     PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
     DiagID = diag::err_invalid_vector_decl_spec;
@@ -341,7 +396,6 @@
 
 bool DeclSpec::SetTypeSpecError() {
   TypeSpecType = TST_error;
-  TypeRep = 0;
   TSTLoc = SourceLocation();
   return false;
 }
@@ -577,11 +631,8 @@
 
 bool DeclSpec::isMissingDeclaratorOk() {
   TST tst = getTypeSpecType();
-  return (tst == TST_union
-       || tst == TST_struct
-       || tst == TST_class
-       || tst == TST_enum
-          ) && getTypeRep() != 0 && StorageClassSpec != DeclSpec::SCS_typedef;
+  return isDeclRep(tst) && getRepAsDecl() != 0 &&
+    StorageClassSpec != DeclSpec::SCS_typedef;
 }
 
 void UnqualifiedId::clear() {
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index f1bdc7a..72b58f4 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -118,7 +118,7 @@
 /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
 Action::OwningExprResult
 Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
-                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation LAngleBracketLoc, ParsedType Ty,
                         SourceLocation RAngleBracketLoc,
                         SourceLocation LParenLoc, ExprArg E,
                         SourceLocation RParenLoc) {
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 9794ec6..de09ba4 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -283,7 +283,7 @@
 bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
                                         SourceLocation IdLoc,
                                         IdentifierInfo &II,
-                                        TypeTy *ObjectTypePtr) {
+                                        ParsedType ObjectTypePtr) {
   QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
   LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
   
@@ -567,10 +567,10 @@
                                                     SourceLocation IdLoc,
                                                     SourceLocation CCLoc,
                                                     IdentifierInfo &II,
-                                                    TypeTy *ObjectTypePtr,
+                                                    ParsedType ObjectTypePtr,
                                                     bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
-                                     QualType::getFromOpaquePtr(ObjectTypePtr),
+                                     GetTypeFromParser(ObjectTypePtr),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      false);
 }
@@ -582,21 +582,20 @@
 ///
 /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
 bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
-                                     IdentifierInfo &II, TypeTy *ObjectType,
+                                     IdentifierInfo &II, ParsedType ObjectType,
                                      bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
-                                     II, QualType::getFromOpaquePtr(ObjectType),
+                                     II, GetTypeFromParser(ObjectType),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      true);
 }
 
 Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                     const CXXScopeSpec &SS,
-                                                    TypeTy *Ty,
+                                                    ParsedType Ty,
                                                     SourceRange TypeRange,
                                                     SourceLocation CCLoc) {
-  NestedNameSpecifier *Prefix
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  NestedNameSpecifier *Prefix = SS.getScopeRep();
   QualType T = GetTypeFromParser(Ty);
   return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
                                      T.getTypePtr());
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index be94c27..fba670e 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3741,14 +3741,14 @@
     // Fall through
   }
 
-  TypeTy *Receiver = 0;
+  ParsedType Receiver;
   if (CDecl)
-    Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+    Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
   return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 
                                       NumSelIdents);
 }
 
-void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
                                         IdentifierInfo **SelIdents,
                                         unsigned NumSelIdents) {
   typedef CodeCompleteConsumer::Result Result;
@@ -4295,7 +4295,7 @@
 
 void Sema::CodeCompleteObjCMethodDecl(Scope *S, 
                                       bool IsInstanceMethod,
-                                      TypeTy *ReturnTy,
+                                      ParsedType ReturnTy,
                                       Decl *IDecl) {
   // Determine the return type of the method we're declaring, if
   // provided.
@@ -4445,7 +4445,7 @@
 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 
                                               bool IsInstanceMethod,
                                               bool AtParameterName,
-                                              TypeTy *ReturnTy,
+                                              ParsedType ReturnTy,
                                               IdentifierInfo **SelIdents,
                                               unsigned NumSelIdents) {
   // If we have an external source, load the entire class method
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0ed9391..30cfb18 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -59,14 +59,14 @@
 ///
 /// If name lookup results in an ambiguity, this routine will complain
 /// and then return NULL.
-Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
-                                Scope *S, CXXScopeSpec *SS,
-                                bool isClassName,
-                                TypeTy *ObjectTypePtr) {
+ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                             Scope *S, CXXScopeSpec *SS,
+                             bool isClassName,
+                             ParsedType ObjectTypePtr) {
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = 0;
   if (ObjectTypePtr) {
-    QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+    QualType ObjectType = ObjectTypePtr.get();
     if (ObjectType->isRecordType())
       LookupCtx = computeDeclContext(ObjectType);
   } else if (SS && SS->isNotEmpty()) {
@@ -84,22 +84,22 @@
         // We therefore do not perform any name lookup if the result would
         // refer to a member of an unknown specialization.
         if (!isClassName)
-          return 0;
+          return ParsedType();
         
         // We know from the grammar that this name refers to a type,
         // so build a dependent node to describe the type.
-        return CheckTypenameType(ETK_None,
-                                 (NestedNameSpecifier *)SS->getScopeRep(), II,
-                                 SourceLocation(), SS->getRange(), NameLoc
-                                 ).getAsOpaquePtr();
+        QualType T =
+          CheckTypenameType(ETK_None, SS->getScopeRep(), II,
+                            SourceLocation(), SS->getRange(), NameLoc);
+        return ParsedType::make(T);
       }
       
-      return 0;
+      return ParsedType();
     }
     
     if (!LookupCtx->isDependentContext() &&
         RequireCompleteDeclContext(*SS, LookupCtx))
-      return 0;
+      return ParsedType();
   }
 
   // FIXME: LookupNestedNameSpecifierName isn't the right kind of
@@ -135,7 +135,7 @@
   case LookupResult::FoundOverloaded:
   case LookupResult::FoundUnresolvedValue:
     Result.suppressDiagnostics();
-    return 0;
+    return ParsedType();
 
   case LookupResult::Ambiguous:
     // Recover from type-hiding ambiguities by hiding the type.  We'll
@@ -145,7 +145,7 @@
     // that only makes sense if the identifier was treated like a type.
     if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // Look to see if we have a type anywhere in the list of results.
@@ -167,7 +167,7 @@
       // will produce the ambiguity, or will complain that it expected
       // a type name.
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // We found a type within the ambiguous lookup; diagnose the
@@ -198,10 +198,10 @@
   } else {
     // If it's not plausibly a type, suppress diagnostics.
     Result.suppressDiagnostics();
-    return 0;
+    return ParsedType();
   }
 
-  return T.getAsOpaquePtr();
+  return ParsedType::make(T);
 }
 
 /// isTagName() - This method is called *for error recovery purposes only*
@@ -232,9 +232,9 @@
                                    SourceLocation IILoc,
                                    Scope *S,
                                    CXXScopeSpec *SS,
-                                   TypeTy *&SuggestedType) {
+                                   ParsedType &SuggestedType) {
   // We don't have anything to suggest (yet).
-  SuggestedType = 0;
+  SuggestedType = ParsedType();
   
   // There may have been a typo in the name of the type. Look up typo
   // results, in case we have something that we can suggest.
@@ -282,7 +282,7 @@
     TemplateTy TemplateResult;
     bool MemberOfUnknownSpecialization;
     if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false,
-                       Name, 0, true, TemplateResult,
+                       Name, ParsedType(), true, TemplateResult,
                        MemberOfUnknownSpecialization) == TNK_Type_template) {
       TemplateName TplName = TemplateResult.getAsVal<TemplateName>();
       Diag(IILoc, diag::err_template_missing_args) << TplName;
@@ -1594,7 +1594,7 @@
       DS.getTypeSpecType() == DeclSpec::TST_struct ||
       DS.getTypeSpecType() == DeclSpec::TST_union ||
       DS.getTypeSpecType() == DeclSpec::TST_enum) {
-    TagD = static_cast<Decl *>(DS.getTypeRep());
+    TagD = DS.getRepAsDecl();
 
     if (!TagD) // We probably had an error
       return 0;
@@ -2123,11 +2123,10 @@
   switch (DS.getTypeSpecType()) {
   case DeclSpec::TST_typename:
   case DeclSpec::TST_typeofType:
-  case DeclSpec::TST_typeofExpr:
   case DeclSpec::TST_decltype: {
     // Grab the type from the parser.
     TypeSourceInfo *TSI = 0;
-    QualType T = S.GetTypeFromParser(DS.getTypeRep(), &TSI);
+    QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
     if (T.isNull() || !T->isDependentType()) break;
 
     // Make sure there's a type source info.  This isn't really much
@@ -2141,8 +2140,16 @@
     if (!TSI) return true;
 
     // Store the new type back in the decl spec.
-    QualType LocType = S.CreateLocInfoType(TSI->getType(), TSI);
-    DS.UpdateTypeRep(LocType.getAsOpaquePtr());
+    ParsedType LocType = S.CreateParsedType(TSI->getType(), TSI);
+    DS.UpdateTypeRep(LocType);
+    break;
+  }
+
+  case DeclSpec::TST_typeofExpr: {
+    Expr *E = DS.getRepAsExpr();
+    OwningExprResult Result = S.RebuildExprInCurrentInstantiation(E);
+    if (Result.isInvalid()) return true;
+    DS.UpdateExprRep(Result.get());
     break;
   }
 
@@ -4478,13 +4485,13 @@
   }
 }
 
-Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
-                                                   Decl **Group,
-                                                   unsigned NumDecls) {
+Sema::DeclGroupPtrTy
+Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                              Decl **Group, unsigned NumDecls) {
   llvm::SmallVector<Decl*, 8> Decls;
 
   if (DS.isTypeSpecOwned())
-    Decls.push_back((Decl*)DS.getTypeRep());
+    Decls.push_back(DS.getRepAsDecl());
 
   for (unsigned i = 0; i != NumDecls; ++i)
     if (Decl *D = Group[i])
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3213b2e..dcee0b3 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -291,13 +291,13 @@
   if (!II)
     II = &S.Context.Idents.get("id");
   
-  Sema::TypeTy *TypeRep = S.getTypeName(*II, Attr.getLoc(), 
+  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 
                         S.getScopeForContext(d->getDeclContext()->getParent()));
   if (!TypeRep) {
     S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
     return;
   }
-  QualType QT(QualType::getFromOpaquePtr(TypeRep));
+  QualType QT = TypeRep.get();
   // Diagnose use of non-object type in iboutletcollection attribute.
   // FIXME. Gnu attribute extension ignores use of builtin types in
   // attributes. So, __attribute__((iboutletcollection(char))) will be
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index d590a3c..f30cbc5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -584,7 +584,7 @@
 Sema::BaseResult
 Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         TypeTy *basetype, SourceLocation BaseLoc) {
+                         ParsedType basetype, SourceLocation BaseLoc) {
   if (!classdecl)
     return true;
 
@@ -906,7 +906,7 @@
     isFunc = true;
   else if (D.getNumTypeObjects() == 0 &&
            D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
-    QualType TDType = GetTypeFromParser(DS.getTypeRep());
+    QualType TDType = GetTypeFromParser(DS.getRepAsType());
     isFunc = TDType->isFunctionType();
   }
 
@@ -1058,7 +1058,7 @@
                           Scope *S,
                           CXXScopeSpec &SS,
                           IdentifierInfo *MemberOrBase,
-                          TypeTy *TemplateTypeTy,
+                          ParsedType TemplateTypeTy,
                           SourceLocation IdLoc,
                           SourceLocation LParenLoc,
                           ExprTy **Args, unsigned NumArgs,
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index ba6e771..283d540 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1466,7 +1466,7 @@
 Decl *Sema::ActOnMethodDeclaration(
     SourceLocation MethodLoc, SourceLocation EndLoc,
     tok::TokenKind MethodType, Decl *ClassDecl,
-    ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
     Selector Sel,
     // optional arguments. The number of types/arguments is obtained
     // from the Sel.getNumArgs().
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9bff8f3..b1e2b7f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2215,7 +2215,7 @@
 
   if (isType) {
     TypeSourceInfo *TInfo;
-    (void) GetTypeFromParser(TyOrEx, &TInfo);
+    (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
     return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
   }
 
@@ -3792,7 +3792,7 @@
 }
 
 Action::OwningExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
                            SourceLocation RParenLoc, Expr *InitExpr) {
   assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
   // FIXME: put back this assert when initializers are worked out.
@@ -4047,7 +4047,7 @@
 }
 
 Action::OwningExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
                     SourceLocation RParenLoc, Expr *castExpr) {
   assert((Ty != 0) && (castExpr != 0) &&
          "ActOnCastExpr(): missing type or expr");
@@ -4148,7 +4148,7 @@
 Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
                                                   SourceLocation R,
                                                   MultiExprArg Val,
-                                                  TypeTy *TypeOfCast) {
+                                                  ParsedType TypeOfCast) {
   unsigned nexprs = Val.size();
   Expr **exprs = reinterpret_cast<Expr**>(Val.release());
   assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
@@ -6988,7 +6988,7 @@
 Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
                                                   SourceLocation BuiltinLoc,
                                                   SourceLocation TypeLoc,
-                                                  TypeTy *argty,
+                                                  ParsedType argty,
                                                   OffsetOfComponent *CompPtr,
                                                   unsigned NumComponents,
                                                   SourceLocation RPLoc) {
@@ -7007,7 +7007,7 @@
 
 
 Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
-                                                      TypeTy *arg1,TypeTy *arg2,
+                                                      ParsedType arg1,ParsedType arg2,
                                                       SourceLocation RPLoc) {
   TypeSourceInfo *argTInfo1;
   QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
@@ -7297,7 +7297,7 @@
 }
 
 Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
-                                        Expr *expr, TypeTy *type,
+                                        Expr *expr, ParsedType type,
                                         SourceLocation RPLoc) {
   TypeSourceInfo *TInfo;
   QualType T = GetTypeFromParser(type, &TInfo);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8a3dcc9..8aa8ba5 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -27,12 +27,12 @@
 #include "llvm/ADT/STLExtras.h"
 using namespace clang;
 
-Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
-                                        IdentifierInfo &II, 
-                                        SourceLocation NameLoc,
-                                        Scope *S, CXXScopeSpec &SS,
-                                        TypeTy *ObjectTypePtr,
-                                        bool EnteringContext) {
+ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
+                                   IdentifierInfo &II, 
+                                   SourceLocation NameLoc,
+                                   Scope *S, CXXScopeSpec &SS,
+                                   ParsedType ObjectTypePtr,
+                                   bool EnteringContext) {
   // Determine where to perform name lookup.
 
   // FIXME: This area of the standard is very messy, and the current
@@ -149,7 +149,7 @@
 
     // FIXME: Should we be suppressing ambiguities here?
     if (Found.isAmbiguous())
-      return 0;
+      return ParsedType();
 
     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
       QualType T = Context.getTypeDeclType(Type);
@@ -158,7 +158,7 @@
           Context.hasSameUnqualifiedType(T, SearchType)) {
         // We found our type!
 
-        return T.getAsOpaquePtr();
+        return ParsedType::make(T);
       }
     }
 
@@ -191,7 +191,7 @@
               = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
           if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
                 Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
         }
 
         continue;
@@ -210,7 +210,7 @@
         // specialized.
         if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
           if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -221,7 +221,7 @@
                                     = SpecName.getAsDependentTemplateName()) {
           if (DepTemplate->isIdentifier() &&
               DepTemplate->getIdentifier() == Template->getIdentifier())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -242,8 +242,10 @@
       Range = SourceRange(NameLoc);
     }
 
-    return CheckTypenameType(ETK_None, NNS, II, SourceLocation(),
-                             Range, NameLoc).getAsOpaquePtr();
+    QualType T = CheckTypenameType(ETK_None, NNS, II,
+                                   SourceLocation(),
+                                   Range, NameLoc);
+    return ParsedType::make(T);
   }
 
   if (ObjectTypePtr)
@@ -252,7 +254,7 @@
   else
     Diag(NameLoc, diag::err_destructor_class_name);
 
-  return 0;
+  return ParsedType();
 }
 
 /// \brief Build a C++ typeid expression with a type operand.
@@ -350,7 +352,8 @@
   if (isType) {
     // The operand is a type; handle it as such.
     TypeSourceInfo *TInfo = 0;
-    QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+    QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
+                                   &TInfo);
     if (T.isNull())
       return ExprError();
     
@@ -480,7 +483,7 @@
 /// or class type construction ("ClassType(x,y,z)")
 /// or creation of a value-initialized type ("int()").
 Action::OwningExprResult
-Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep,
                                 SourceLocation LParenLoc,
                                 MultiExprArg exprs,
                                 SourceLocation *CommaLocs,
@@ -1922,7 +1925,7 @@
 Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
                                                  SourceLocation KWLoc,
                                                  SourceLocation LParen,
-                                                 TypeTy *Ty,
+                                                 ParsedType Ty,
                                                  SourceLocation RParen) {
   QualType T = GetTypeFromParser(Ty);
 
@@ -2678,7 +2681,7 @@
 
 Sema::OwningExprResult
 Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
-                                   tok::TokenKind OpKind, TypeTy *&ObjectType,
+                                   tok::TokenKind OpKind, ParsedType &ObjectType,
                                    bool &MayBePseudoDestructor) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
   OwningExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
@@ -2695,7 +2698,7 @@
       if (const PointerType *Ptr = BaseType->getAs<PointerType>())
         BaseType = Ptr->getPointeeType();
     
-    ObjectType = BaseType.getAsOpaquePtr();
+    ObjectType = ParsedType::make(BaseType);
     MayBePseudoDestructor = true;
     return Owned(Base);
   }
@@ -2741,7 +2744,7 @@
     //
     // This also indicates that we should be parsing a
     // pseudo-destructor-name.
-    ObjectType = 0;
+    ObjectType = ParsedType();
     MayBePseudoDestructor = true;
     return Owned(Base);
   }
@@ -2757,7 +2760,7 @@
   //   unqualified-id, and the type of the object expression is of a class
   //   type C (or of pointer to a class type C), the unqualified-id is looked
   //   up in the scope of class C. [...]
-  ObjectType = BaseType.getAsOpaquePtr();
+  ObjectType = ParsedType::make(BaseType);
   return move(Base);
 }
 
@@ -2909,12 +2912,12 @@
 
   // Compute the object type that we should use for name lookup purposes. Only
   // record types and dependent types matter.
-  void *ObjectTypePtrForLookup = 0;
+  ParsedType ObjectTypePtrForLookup;
   if (!SS.isSet()) {
-    ObjectTypePtrForLookup = const_cast<RecordType*>(
-                                               ObjectType->getAs<RecordType>());
-    if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
-      ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+    if (const Type *T = ObjectType->getAs<RecordType>())
+      ObjectTypePtrForLookup = ParsedType::make(QualType(T, 0));
+    else if (ObjectType->isDependentType())
+      ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
   }
   
   // Convert the name of the type being destructed (following the ~) into a 
@@ -2923,9 +2926,9 @@
   TypeSourceInfo *DestructedTypeInfo = 0;
   PseudoDestructorTypeStorage Destructed;
   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
-    TypeTy *T = getTypeName(*SecondTypeName.Identifier, 
-                            SecondTypeName.StartLocation,
-                            S, &SS, true, ObjectTypePtrForLookup);
+    ParsedType T = getTypeName(*SecondTypeName.Identifier, 
+                               SecondTypeName.StartLocation,
+                               S, &SS, true, ObjectTypePtrForLookup);
     if (!T && 
         ((SS.isSet() && !computeDeclContext(SS, false)) ||
          (!SS.isSet() && ObjectType->isDependentType()))) {
@@ -2979,9 +2982,9 @@
   if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || 
       FirstTypeName.Identifier) {
     if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
-      TypeTy *T = getTypeName(*FirstTypeName.Identifier, 
-                              FirstTypeName.StartLocation,
-                              S, &SS, false, ObjectTypePtrForLookup);
+      ParsedType T = getTypeName(*FirstTypeName.Identifier, 
+                                 FirstTypeName.StartLocation,
+                                 S, &SS, false, ObjectTypePtrForLookup);
       if (!T) {
         Diag(FirstTypeName.StartLocation, 
              diag::err_pseudo_dtor_destructor_non_type)
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index b9071e6..cf818c4 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -135,7 +135,7 @@
 Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
                                                  SourceLocation EncodeLoc,
                                                  SourceLocation LParenLoc,
-                                                 TypeTy *ty,
+                                                 ParsedType ty,
                                                  SourceLocation RParenLoc) {
   // FIXME: Preserve type source info ?
   TypeSourceInfo *TInfo;
@@ -531,8 +531,8 @@
                                                SourceLocation NameLoc,
                                                bool IsSuper,
                                                bool HasTrailingDot,
-                                               TypeTy *&ReceiverType) {
-  ReceiverType = 0;
+                                               ParsedType &ReceiverType) {
+  ReceiverType = ParsedType();
 
   // If the identifier is "super" and there is no trailing dot, we're
   // messaging super.
@@ -579,7 +579,7 @@
     //  We have a class message, and T is the type we're
     //  messaging. Build source-location information for it.
     TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
-    ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+    ReceiverType = CreateParsedType(T, TSInfo);
     return ObjCClassMessage;
   }
   }
@@ -606,7 +606,7 @@
 
         QualType T = Context.getObjCInterfaceType(Class);
         TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
-        ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+        ReceiverType = CreateParsedType(T, TSInfo);
         return ObjCClassMessage;
       }
     } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
@@ -780,7 +780,7 @@
 // ArgExprs is optional - if it is present, the number of expressions
 // is obtained from Sel.getNumArgs().
 Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S, 
-                                               TypeTy *Receiver,
+                                               ParsedType Receiver,
                                                Selector Sel,
                                                SourceLocation LBracLoc,
                                                SourceLocation SelectorLoc,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 9445ced..c62bbeb 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -104,7 +104,7 @@
                                       CXXScopeSpec &SS,
                                       bool hasTemplateKeyword,
                                       UnqualifiedId &Name,
-                                      TypeTy *ObjectTypePtr,
+                                      ParsedType ObjectTypePtr,
                                       bool EnteringContext,
                                       TemplateTy &TemplateResult,
                                       bool &MemberOfUnknownSpecialization) {
@@ -131,7 +131,7 @@
     return TNK_Non_template;
   }
 
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
 
   LookupResult R(*this, TName, Name.getSourceRange().getBegin(), 
                  LookupOrdinaryName);
@@ -472,7 +472,7 @@
                                SourceLocation ParamNameLoc,
                                unsigned Depth, unsigned Position,
                                SourceLocation EqualLoc,
-                               TypeTy *DefaultArg) {
+                               ParsedType DefaultArg) {
   assert(S->isTemplateParamScope() &&
          "Template type parameter not in template parameter scope!");
   bool Invalid = false;
@@ -1540,7 +1540,7 @@
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
 
-  return CreateLocInfoType(Result, DI).getAsOpaquePtr();
+  return CreateParsedType(Result, DI);
 }
 
 Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
@@ -1575,7 +1575,7 @@
     = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
   QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
 
-  return ElabType.getAsOpaquePtr();
+  return ParsedType::make(ElabType);
 }
 
 Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
@@ -1661,7 +1661,7 @@
                                                   SourceLocation TemplateKWLoc,
                                                   CXXScopeSpec &SS,
                                                   UnqualifiedId &Name,
-                                                  TypeTy *ObjectType,
+                                                  ParsedType ObjectType,
                                                   bool EnteringContext,
                                                   TemplateTy &Result) {
   if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
@@ -1673,7 +1673,7 @@
   if (SS.isSet())
     LookupCtx = computeDeclContext(SS, EnteringContext);
   if (!LookupCtx && ObjectType)
-    LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+    LookupCtx = computeDeclContext(ObjectType.get());
   if (LookupCtx) {
     // C++0x [temp.names]p5:
     //   If a name prefixed by the keyword template is not the name of
@@ -5224,7 +5224,7 @@
   }
 
   ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
-  return Context.getDependentNameType(Kwd, NNS, Name).getAsOpaquePtr();
+  return ParsedType::make(Context.getDependentNameType(Kwd, NNS, Name));
 }
 
 Sema::TypeResult
@@ -5259,13 +5259,13 @@
     cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
   }
   
-  return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+  return CreateParsedType(T, TSI);
 }
 
 Sema::TypeResult
 Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
                         const CXXScopeSpec &SS, SourceLocation TemplateLoc, 
-                        TypeTy *Ty) {
+                        ParsedType Ty) {
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
       !getLangOptions().CPlusPlus0x)
     Diag(TypenameLoc, diag::ext_typename_outside_of_template)
@@ -5296,7 +5296,7 @@
     TL.setQualifierRange(SS.getRange());
 
     TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
-    return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+    return CreateParsedType(T, TSI);
   }
 
   // TODO: it's really silly that we make a template specialization
@@ -5327,7 +5327,7 @@
   }
   TL.setKeywordLoc(TypenameLoc);
   TL.setQualifierRange(SS.getRange());
-  return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+  return CreateParsedType(T, TSI);
 }
 
 /// \brief Build the type that describes a C++ typename specifier,
@@ -5485,6 +5485,12 @@
   return Rebuilder.TransformType(T);
 }
 
+OwningExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) {
+  CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(),
+                                          DeclarationName());
+  return Rebuilder.TransformExpr(E);
+}
+
 bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
   if (SS.isInvalid()) return true;
 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 05c87ac..b7c41a6 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -265,8 +265,7 @@
   case DeclSpec::TST_enum:
   case DeclSpec::TST_union:
   case DeclSpec::TST_struct: {
-    TypeDecl *D 
-      = dyn_cast_or_null<TypeDecl>(static_cast<Decl *>(DS.getTypeRep()));
+    TypeDecl *D = dyn_cast_or_null<TypeDecl>(DS.getRepAsDecl());
     if (!D) {
       // This can happen in C++ with ambiguous lookups.
       Result = Context.IntTy;
@@ -298,7 +297,7 @@
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
     if (Result.isNull())
       TheDeclarator.setInvalidType(true);
     else if (DeclSpec::ProtocolQualifierListTy PQ
@@ -337,13 +336,13 @@
   }
   case DeclSpec::TST_typeofType:
     // FIXME: Preserve type source info.
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
     assert(!Result.isNull() && "Didn't get a type for typeof?");
     // TypeQuals handled by caller.
     Result = Context.getTypeOfType(Result);
     break;
   case DeclSpec::TST_typeofExpr: {
-    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for typeof?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildTypeofExprType(E);
@@ -354,7 +353,7 @@
     break;
   }
   case DeclSpec::TST_decltype: {
-    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for decltype?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildDecltypeType(E);
@@ -926,8 +925,8 @@
   return Context.getBlockPointerType(T);
 }
 
-QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
-  QualType QT = QualType::getFromOpaquePtr(Ty);
+QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
+  QualType QT = Ty.get();
   if (QT.isNull()) {
     if (TInfo) *TInfo = 0;
     return QualType();
@@ -969,7 +968,7 @@
     T = ConvertDeclSpecToType(*this, D, FnAttrsFromDeclSpec);
     
     if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
-      TagDecl* Owned = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+      TagDecl* Owned = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
       // Owned is embedded if it was defined here, or if it is the
       // very first (i.e., canonical) declaration of this tag type.
       Owned->setEmbeddedInDeclarator(Owned->isDefinition() ||
@@ -1188,7 +1187,7 @@
       if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
         // C++ [dcl.fct]p6:
         //   Types shall not be defined in return or parameter types.
-        TagDecl *Tag = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+        TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
         if (Tag->isDefinition())
           Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
             << Context.getTypeDeclType(Tag);
@@ -1472,7 +1471,7 @@
     }
     void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
 
       // If we got no declarator info from previous Sema routines,
       // just fill with the typespec loc.
@@ -1500,9 +1499,9 @@
       assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
       TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
       TL.setParensRange(DS.getTypeofParensRange());
-      assert(DS.getTypeRep());
+      assert(DS.getRepAsType());
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       TL.setUnderlyingTInfo(TInfo);
     }
     void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
@@ -1525,7 +1524,7 @@
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc()));
           return;
@@ -1543,7 +1542,7 @@
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc()));
           return;
@@ -1563,7 +1562,7 @@
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
                     TInfo->getTypeLoc()));
@@ -1668,24 +1667,21 @@
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
   
-  TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
-  
-  // We have source information for the return type that was not in the
-  // declaration specifiers; copy that information into the current type
-  // location so that it will be retained. This occurs, for example, with 
-  // a C++ conversion function, where the return type occurs within the
-  // declarator-id rather than in the declaration specifiers.
-  if (ReturnTypeInfo && D.getDeclSpec().getTypeSpecType() == TST_unspecified) {
+  // If we have different source information for the return type, use
+  // that.  This really only applies to C++ conversion functions.
+  if (ReturnTypeInfo) {
     TypeLoc TL = ReturnTypeInfo->getTypeLoc();
     assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
     memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+  } else {
+    TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
   }
       
   return TInfo;
 }
 
 /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
-QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
+ParsedType Sema::CreateParsedType(QualType T, TypeSourceInfo *TInfo) {
   // FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser
   // and Sema during declaration parsing. Try deallocating/caching them when
   // it's appropriate, instead of allocating them and keeping them around.
@@ -1693,7 +1689,7 @@
   new (LocT) LocInfoType(T, TInfo);
   assert(LocT->getTypeClass() != T->getTypeClass() &&
          "LocInfoType's TypeClass conflicts with an existing Type class");
-  return QualType(LocT, 0);
+  return ParsedType::make(QualType(LocT, 0));
 }
 
 void LocInfoType::getAsStringInternal(std::string &Str,
@@ -1727,8 +1723,7 @@
         << Context.getTypeDeclType(OwnedTag);
   }
 
-  T = CreateLocInfoType(T, TInfo);
-  return T.getAsOpaquePtr();
+  return CreateParsedType(T, TInfo);
 }
 
 
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 843580b..89e0b60 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1500,7 +1500,7 @@
                                                 Expr *Sub,
                                                 SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(TypeRange,
-                                               TInfo->getType().getAsOpaquePtr(),
+                                             ParsedType::make(TInfo->getType()),
                                                LParenLoc,
                                          Sema::MultiExprArg(getSema(), &Sub, 1),
                                                /*CommaLocs=*/0,
@@ -1572,7 +1572,7 @@
                                                QualType T,
                                                SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
-                                               T.getAsOpaquePtr(), LParenLoc,
+                                               ParsedType::make(T), LParenLoc,
                                                MultiExprArg(getSema(), 0, 0),
                                                0, RParenLoc);
   }
@@ -1630,7 +1630,7 @@
                                          QualType T,
                                          SourceLocation RParenLoc) {
     return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
-                                         T.getAsOpaquePtr(), RParenLoc);
+                                         ParsedType::make(T), RParenLoc);
   }
 
   /// \brief Build a new (previously unresolved) declaration reference
@@ -1696,7 +1696,7 @@
                                                  SourceLocation *Commas,
                                                  SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -1715,7 +1715,7 @@
                                                      SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
                                                            /*FIXME*/LParenLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -5391,7 +5391,7 @@
   if (Base.isInvalid())
     return SemaRef.ExprError();
 
-  Sema::TypeTy *ObjectTypePtr = 0;
+  ParsedType ObjectTypePtr;
   bool MayBePseudoDestructor = false;
   Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 
                                               E->getOperatorLoc(),
@@ -5401,7 +5401,7 @@
   if (Base.isInvalid())
     return SemaRef.ExprError();
                                               
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
   NestedNameSpecifier *Qualifier
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange(),
@@ -5429,7 +5429,7 @@
       SS.setRange(E->getQualifierRange());
     }
     
-    Sema::TypeTy *T = SemaRef.getDestructorName(E->getTildeLoc(),
+    ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
                                               *E->getDestroyedTypeIdentifier(),
                                                 E->getDestroyedTypeLoc(),
                                                 /*Scope=*/0,
@@ -5814,7 +5814,7 @@
       return SemaRef.ExprError();
 
     // Start the member reference and compute the object's type.
-    Sema::TypeTy *ObjectTy = 0;
+    ParsedType ObjectTy;
     bool MayBePseudoDestructor = false;
     Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
                                                 E->getOperatorLoc(),
@@ -5824,7 +5824,7 @@
     if (Base.isInvalid())
       return SemaRef.ExprError();
 
-    ObjectType = QualType::getFromOpaquePtr(ObjectTy);
+    ObjectType = ObjectTy.get();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
     OldBase = 0;
@@ -6556,7 +6556,7 @@
                                        /*FIXME:*/getDerived().getBaseLocation(),
                                        SS,
                                        Name,
-                                       ObjectType.getAsOpaquePtr(),
+                                       ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
                                        Template);
   return Template.template getAsVal<TemplateName>();
@@ -6579,7 +6579,7 @@
                                        /*FIXME:*/getDerived().getBaseLocation(),
                                        SS,
                                        Name,
-                                       ObjectType.getAsOpaquePtr(),
+                                       ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
                                        Template);
   return Template.template getAsVal<TemplateName>();