Introduce a new OpaquePtr<N> struct type, which is a simple POD wrapper for a
pointer.  Its purpose in life is to be a glorified void*, but which does not
implicitly convert to void* or other OpaquePtr's with a different UID.

Introduce Action::DeclPtrTy which is a typedef for OpaquePtr<0>.  Change the 
entire parser/sema interface to use DeclPtrTy instead of DeclTy*.  This
makes the C++ compiler enforce that these aren't convertible to other opaque
types.

We should also convert ExprTy, StmtTy, TypeTy, AttrTy, BaseTy, etc,
but I don't plan to do that in the short term.

The one outstanding known problem with this patch is that we lose the 
bitmangling optimization where ActionResult<DeclPtrTy> doesn't know how to
bitmangle the success bit into the low bit of DeclPtrTy.  I will rectify
this with a subsequent patch.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 94799c3..de9f36d 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -225,7 +225,7 @@
 }
 
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
-                               const char *&PrevSpec, Action::TypeTy *Rep) {
+                               const char *&PrevSpec, void *Rep) {
   if (TypeSpecType != TST_unspecified)
     return BadSpecifier((TST)TypeSpecType, PrevSpec);
   TypeSpecType = T;
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
index 776d701..049228f 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -26,19 +26,19 @@
 Action::~Action() {}
 
 // Defined out-of-line here because of dependecy on AttributeList
-Action::DeclTy *Action::ActOnUsingDirective(Scope *CurScope,
-                                            SourceLocation UsingLoc,
-                                            SourceLocation NamespcLoc,
-                                            const CXXScopeSpec &SS,
-                                            SourceLocation IdentLoc,
-                                            IdentifierInfo *NamespcName,
-                                            AttributeList *AttrList) {
+Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope,
+                                              SourceLocation UsingLoc,
+                                              SourceLocation NamespcLoc,
+                                              const 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;
+  return DeclPtrTy();
 }
 
 
@@ -135,7 +135,7 @@
 
 TemplateNameKind 
 MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
-                              DeclTy *&TemplateDecl,
+                              DeclPtrTy &TemplateDecl,
                               const CXXScopeSpec *SS) {
   return TNK_Non_template;
 }
@@ -143,12 +143,12 @@
 /// ActOnDeclarator - If this is a typedef declarator, we modify the
 /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
 /// popped.
-Action::DeclTy *
-MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) {
+Action::DeclPtrTy
+MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclPtrTy LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
   
   // If there is no identifier associated with this declarator, bail out.
-  if (II == 0) return 0;
+  if (II == 0) return DeclPtrTy();
   
   TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>();
   bool isTypeName =
@@ -162,29 +162,29 @@
     getTable(TypeNameInfoTablePtr)->AddEntry(isTypeName, II);
   
     // Remember that this needs to be removed when the scope is popped.
-    S->AddDecl(II);
+    S->AddDecl(DeclPtrTy::make(II));
   } 
-  return 0;
+  return DeclPtrTy();
 }
 
-Action::DeclTy *
+Action::DeclPtrTy
 MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
                                         IdentifierInfo *ClassName,
                                         SourceLocation ClassLoc,
                                         IdentifierInfo *SuperName,
                                         SourceLocation SuperLoc,
-                                        DeclTy * const *ProtoRefs,
+                                        const DeclPtrTy *ProtoRefs,
                                         unsigned NumProtocols,
                                         SourceLocation EndProtoLoc,
                                         AttributeList *AttrList) {
   // Allocate and add the 'TypeNameInfo' "decl".
   getTable(TypeNameInfoTablePtr)->AddEntry(true, ClassName);
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ActOnForwardClassDeclaration - 
 /// Scope will always be top level file scope. 
-Action::DeclTy *
+Action::DeclPtrTy
 MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
                                 IdentifierInfo **IdentList, unsigned NumElts) {
   for (unsigned i = 0; i != NumElts; ++i) {
@@ -192,9 +192,9 @@
     getTable(TypeNameInfoTablePtr)->AddEntry(true, IdentList[i]);
   
     // Remember that this needs to be removed when the scope is popped.
-    TUScope->AddDecl(IdentList[i]);
+    TUScope->AddDecl(DeclPtrTy::make(IdentList[i]));
   }
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ActOnPopScope - When a scope is popped, if any typedefs are now
@@ -204,7 +204,7 @@
   
   for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
-    IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
+    IdentifierInfo &II = *(*I).getAs<IdentifierInfo>();
     TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
     assert(TI && "This decl didn't get pushed??");
     
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 3ed9802..e139cf9 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -20,14 +20,15 @@
 /// ParseInlineCXXMethodDef - We parsed and verified that the specified
 /// Declarator is a well formed C++ inline method definition. Now lex its body
 /// and store its tokens for parsing after the C++ class is complete.
-Parser::DeclTy *
+Parser::DeclPtrTy
 Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "This isn't a function declarator!");
   assert((Tok.is(tok::l_brace) || Tok.is(tok::colon)) && 
          "Current token not a '{' or ':'!");
 
-  DeclTy *FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0, 0);
+  DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0,
+                                                   DeclPtrTy());
 
   // Consume the tokens and store them for later parsing.
 
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 0ab7042..5a8b2b8 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -228,7 +228,7 @@
 /// [C++0x] static_assert-declaration
 ///         others... [FIXME]
 ///
-Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseDeclaration(unsigned Context) {
   switch (Tok.getKind()) {
   case tok::kw_export:
   case tok::kw_template:
@@ -248,7 +248,7 @@
 ///         declaration-specifiers init-declarator-list[opt] ';'
 ///[C90/C++]init-declarator-list ';'                             [TODO]
 /// [OMP]   threadprivate-directive                              [TODO]
-Parser::DeclTy *Parser::ParseSimpleDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
   ParseDeclarationSpecifiers(DS);
@@ -291,12 +291,12 @@
 /// According to the standard grammar, =default and =delete are function
 /// definitions, but that definitely doesn't fit with the parser here.
 ///
-Parser::DeclTy *Parser::
+Parser::DeclPtrTy Parser::
 ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
   
   // Declarators may be grouped together ("int X, *Y, Z();").  Provide info so
   // that they can be chained properly if the actions want this.
-  Parser::DeclTy *LastDeclInGroup = 0;
+  Parser::DeclPtrTy LastDeclInGroup;
   
   // At this point, we know that it is not a function definition.  Parse the
   // rest of the init-declarator-list.
@@ -307,7 +307,7 @@
       OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
       if (AsmLabel.isInvalid()) {
         SkipUntil(tok::semi);
-        return 0;
+        return DeclPtrTy();
       }
 
       D.setAsmLabel(AsmLabel.release());
@@ -334,7 +334,7 @@
         OwningExprResult Init(ParseInitializer());
         if (Init.isInvalid()) {
           SkipUntil(tok::semi);
-          return 0;
+          return DeclPtrTy();
         }
         Actions.AddInitializerToDecl(LastDeclInGroup, move(Init));
       }
@@ -395,7 +395,7 @@
     // for(is key; in keys) is error.
     if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) {
       Diag(Tok, diag::err_parse_error);
-      return 0;
+      return DeclPtrTy();
     }
     return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
   }
@@ -411,7 +411,7 @@
   SkipUntil(tok::r_brace, true, true);
   if (Tok.is(tok::semi))
     ConsumeToken();
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ParseSpecifierQualifierList
@@ -560,7 +560,7 @@
         continue;
       
       SourceLocation EndProtoLoc;
-      llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
+      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
       ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
       DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
       
@@ -614,7 +614,7 @@
         continue;
       
       SourceLocation EndProtoLoc;
-      llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
+      llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
       ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
       DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
       
@@ -809,7 +809,7 @@
         
       {
         SourceLocation EndProtoLoc;
-        llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
+        llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
         ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
         DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
         DS.SetRangeEnd(EndProtoLoc);
@@ -917,7 +917,7 @@
       return true;
     
     SourceLocation EndProtoLoc;
-    llvm::SmallVector<DeclTy *, 8> ProtocolDecl;
+    llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
     ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
     DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
     
@@ -1129,7 +1129,7 @@
 /// [OBC]   '@' 'defs' '(' class-name ')'
 ///
 void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
-                                  unsigned TagType, DeclTy *TagDecl) {
+                                  unsigned TagType, DeclPtrTy TagDecl) {
   PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
                                         PP.getSourceManager(),
                                         "parsing struct/union body");
@@ -1145,7 +1145,7 @@
     Diag(Tok, diag::ext_empty_struct_union_enum)
       << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
 
-  llvm::SmallVector<DeclTy*, 32> FieldDecls;
+  llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
   llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
 
   // While we still have something to read, read the declarations in the struct.
@@ -1169,9 +1169,9 @@
       for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
         FieldDeclarator &FD = FieldDeclarators[i];
         // Install the declarator into the current TagDecl.
-        DeclTy *Field = Actions.ActOnField(CurScope, TagDecl,
-                                           DS.getSourceRange().getBegin(),
-                                           FD.D, FD.BitfieldSize);
+        DeclPtrTy Field = Actions.ActOnField(CurScope, TagDecl,
+                                             DS.getSourceRange().getBegin(),
+                                             FD.D, FD.BitfieldSize);
         FieldDecls.push_back(Field);
       }
     } else { // Handle @defs
@@ -1188,7 +1188,7 @@
         SkipUntil(tok::semi, true, true);
         continue;
       }
-      llvm::SmallVector<DeclTy*, 16> Fields;
+      llvm::SmallVector<DeclPtrTy, 16> Fields;
       Actions.ActOnDefs(CurScope, TagDecl, Tok.getLocation(), 
                         Tok.getIdentifierInfo(), Fields);
       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
@@ -1292,15 +1292,16 @@
     TK = Action::TK_Declaration;
   else
     TK = Action::TK_Reference;
-  DeclTy *TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK, StartLoc,
-                                     SS, Name, NameLoc, Attr, AS);
+  DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TK,
+                                       StartLoc, SS, Name, NameLoc, Attr, AS);
   
   if (Tok.is(tok::l_brace))
     ParseEnumBody(StartLoc, TagDecl);
   
   // TODO: semantic analysis on the declspec for enums.
   const char *PrevSpec = 0;
-  if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec, TagDecl))
+  if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, PrevSpec,
+                         TagDecl.getAs<void>()))
     Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 }
 
@@ -1314,7 +1315,7 @@
 ///       enumeration-constant:
 ///         identifier
 ///
-void Parser::ParseEnumBody(SourceLocation StartLoc, DeclTy *EnumDecl) {
+void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) {
   // Enter the scope of the enum body and start the definition.
   ParseScope EnumScope(this, Scope::DeclScope);
   Actions.ActOnTagStartDefinition(CurScope, EnumDecl);
@@ -1325,9 +1326,9 @@
   if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
     Diag(Tok, diag::ext_empty_struct_union_enum) << "enum";
   
-  llvm::SmallVector<DeclTy*, 32> EnumConstantDecls;
+  llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls;
 
-  DeclTy *LastEnumConstDecl = 0;
+  DeclPtrTy LastEnumConstDecl;
   
   // Parse the enumerator-list.
   while (Tok.is(tok::identifier)) {
@@ -1344,11 +1345,11 @@
     }
     
     // Install the enumerator constant into EnumDecl.
-    DeclTy *EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
-                                                      LastEnumConstDecl,
-                                                      IdentLoc, Ident,
-                                                      EqualLoc,
-                                                      AssignedVal.release());
+    DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(CurScope, EnumDecl,
+                                                        LastEnumConstDecl,
+                                                        IdentLoc, Ident,
+                                                        EqualLoc,
+                                                        AssignedVal.release());
     EnumConstantDecls.push_back(EnumConstDecl);
     LastEnumConstDecl = EnumConstDecl;
     
@@ -1366,7 +1367,7 @@
   Actions.ActOnEnumBody(StartLoc, EnumDecl, &EnumConstantDecls[0],
                         EnumConstantDecls.size());
   
-  DeclTy *AttrList = 0;
+  Action::AttrTy *AttrList = 0;
   // If attributes exist after the identifier list, parse them.
   if (Tok.is(tok::kw___attribute))
     AttrList = ParseAttributes(); // FIXME: where do they do?
@@ -2195,7 +2196,7 @@
       
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
-      DeclTy *Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
+      DeclPtrTy Param = Actions.ActOnParamDeclarator(CurScope, ParmDecl);
 
       // Parse the default argument, if any. We parse the default
       // arguments in all dialects; the semantic analysis in
@@ -2300,7 +2301,8 @@
   // identifier in ParamInfo.
   ParamsSoFar.insert(Tok.getIdentifierInfo());
   ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
-                                                 Tok.getLocation(), 0));
+                                                 Tok.getLocation(),
+                                                 DeclPtrTy()));
   
   ConsumeToken();  // eat the first identifier.
   
@@ -2327,7 +2329,8 @@
     } else {
       // Remember this identifier in ParamInfo.
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
-                                                     Tok.getLocation(), 0));
+                                                     Tok.getLocation(),
+                                                     DeclPtrTy()));
     }
     
     // Eat the identifier.
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 121bf04..37eb34e 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -42,7 +42,7 @@
 ///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
 ///         'namespace' identifier '=' qualified-namespace-specifier ';'
 ///
-Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
   assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
   SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
   
@@ -55,7 +55,7 @@
   }
   
   // Read label attributes, if present.
-  DeclTy *AttrList = 0;
+  Action::AttrTy *AttrList = 0;
   if (Tok.is(tok::kw___attribute))
     // FIXME: save these somewhere.
     AttrList = ParseAttributes();
@@ -70,7 +70,7 @@
     // Enter a scope for the namespace.
     ParseScope NamespaceScope(this, Scope::DeclScope);
 
-    DeclTy *NamespcDecl =
+    DeclPtrTy NamespcDecl =
       Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
 
     PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
@@ -93,14 +93,14 @@
                       diag::err_expected_ident_lbrace);
   }
   
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ParseNamespaceAlias - Parse the part after the '=' in a namespace
 /// alias definition.
 ///
-Parser::DeclTy *Parser::ParseNamespaceAlias(SourceLocation AliasLoc, 
-                                            IdentifierInfo *Alias) {
+Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation AliasLoc, 
+                                              IdentifierInfo *Alias) {
   assert(Tok.is(tok::equal) && "Not equal token");
   
   ConsumeToken(); // eat the '='.
@@ -113,7 +113,7 @@
     Diag(Tok, diag::err_expected_namespace_name);
     // Skip to end of the definition and eat the ';'.
     SkipUntil(tok::semi);
-    return 0;
+    return DeclPtrTy();
   }
 
   // Parse identifier.
@@ -135,7 +135,7 @@
 ///         'extern' string-literal '{' declaration-seq[opt] '}'
 ///         'extern' string-literal declaration
 ///
-Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
   assert(Tok.is(tok::string_literal) && "Not a string literal!");
   llvm::SmallVector<char, 8> LangBuffer;
   // LangBuffer is guaranteed to be big enough.
@@ -146,7 +146,7 @@
   SourceLocation Loc = ConsumeStringToken();
 
   ParseScope LinkageScope(this, Scope::DeclScope);
-  DeclTy *LinkageSpec 
+  DeclPtrTy LinkageSpec 
     = Actions.ActOnStartLinkageSpecification(CurScope, 
                                              /*FIXME: */SourceLocation(),
                                              Loc, LangBufPtr, StrSize,
@@ -170,7 +170,7 @@
 
 /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
 /// using-directive. Assumes that current token is 'using'.
-Parser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
   assert(Tok.is(tok::kw_using) && "Not using token");
 
   // Eat 'using'.
@@ -194,8 +194,8 @@
 ///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
 ///                 namespace-name attributes[opt] ;
 ///
-Parser::DeclTy *Parser::ParseUsingDirective(unsigned Context,
-                                            SourceLocation UsingLoc) {
+Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
+                                              SourceLocation UsingLoc) {
   assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
 
   // Eat 'namespace'.
@@ -215,7 +215,7 @@
     // If there was invalid namespace name, skip to end of decl, and eat ';'.
     SkipUntil(tok::semi);
     // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
-    return 0;
+    return DeclPtrTy();
   }
   
   // Parse identifier.
@@ -242,11 +242,11 @@
 ///               unqualified-id [TODO]
 ///       'using' :: unqualified-id [TODO]
 ///
-Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
-                                              SourceLocation UsingLoc) {
+Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
+                                                SourceLocation UsingLoc) {
   assert(false && "Not implemented");
   // FIXME: Implement parsing.
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
@@ -254,13 +254,13 @@
 ///      static_assert-declaration:
 ///        static_assert ( constant-expression  ,  string-literal  ) ;
 ///
-Parser::DeclTy *Parser::ParseStaticAssertDeclaration() {
+Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
   assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
   SourceLocation StaticAssertLoc = ConsumeToken();
   
   if (Tok.isNot(tok::l_paren)) {
     Diag(Tok, diag::err_expected_lparen);
-    return 0;
+    return DeclPtrTy();
   }
   
   SourceLocation LParenLoc = ConsumeParen();
@@ -268,21 +268,21 @@
   OwningExprResult AssertExpr(ParseConstantExpression());
   if (AssertExpr.isInvalid()) {
     SkipUntil(tok::semi);
-    return 0;
+    return DeclPtrTy();
   }
   
   if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
-    return 0;
+    return DeclPtrTy();
 
   if (Tok.isNot(tok::string_literal)) {
     Diag(Tok, diag::err_expected_string_literal);
     SkipUntil(tok::semi);
-    return 0;
+    return DeclPtrTy();
   }
   
   OwningExprResult AssertMessage(ParseStringLiteralExpression());
   if (AssertMessage.isInvalid()) 
-    return 0;
+    return DeclPtrTy();
 
   MatchRHSPunctuation(tok::r_paren, LParenLoc);
   
@@ -475,7 +475,7 @@
     TagOrTempResult
       = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
                        StartLoc, SS,
-                       TemplateId->Template, 
+                       DeclPtrTy::make(TemplateId->Template), 
                        TemplateId->TemplateNameLoc, 
                        TemplateId->LAngleLoc, 
                        TemplateArgsPtr,
@@ -518,7 +518,7 @@
   if (TagOrTempResult.isInvalid())
     DS.SetTypeSpecError();
   else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, 
-                              TagOrTempResult.get()))
+                              TagOrTempResult.get().getAs<void>()))
     Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 }
 
@@ -529,8 +529,7 @@
 ///       base-specifier-list:
 ///         base-specifier '...'[opt]
 ///         base-specifier-list ',' base-specifier '...'[opt]
-void Parser::ParseBaseClause(DeclTy *ClassDecl)
-{
+void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
   assert(Tok.is(tok::colon) && "Not a base clause");
   ConsumeToken();
 
@@ -572,8 +571,7 @@
 ///                        class-name
 ///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
 ///                        class-name
-Parser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
-{
+Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
   bool IsVirtual = false;
   SourceLocation StartLoc = Tok.getLocation();
 
@@ -666,7 +664,7 @@
 ///       constant-initializer:
 ///         '=' constant-expression
 ///
-Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
+Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
   // static_assert-declaration
   if (Tok.is(tok::kw_static_assert))
     return ParseStaticAssertDeclaration();
@@ -702,7 +700,7 @@
         return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
       default:
         Diag(DSStart, diag::err_no_declarators);
-        return 0;
+        return DeclPtrTy();
     }
   }
 
@@ -717,7 +715,7 @@
       SkipUntil(tok::r_brace, true);
       if (Tok.is(tok::semi))
         ConsumeToken();
-      return 0;
+      return DeclPtrTy();
     }
 
     // function-definition:
@@ -727,7 +725,7 @@
         Diag(Tok, diag::err_func_def_no_params);
         ConsumeBrace();
         SkipUntil(tok::r_brace, true);
-        return 0;
+        return DeclPtrTy();
       }
 
       if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -737,7 +735,7 @@
         // assumes the declarator represents a function, not a typedef.
         ConsumeBrace();
         SkipUntil(tok::r_brace, true);
-        return 0;
+        return DeclPtrTy();
       }
 
       return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
@@ -748,7 +746,7 @@
   //   member-declarator
   //   member-declarator-list ',' member-declarator
 
-  DeclTy *LastDeclInGroup = 0;
+  DeclPtrTy LastDeclInGroup;
   OwningExprResult BitfieldSize(Actions);
   OwningExprResult Init(Actions);
 
@@ -865,7 +863,7 @@
   SkipUntil(tok::r_brace, true, true);
   if (Tok.is(tok::semi))
     ConsumeToken();
-  return 0;
+  return DeclPtrTy();
 }
 
 /// ParseCXXMemberSpecification - Parse the class definition.
@@ -875,7 +873,7 @@
 ///         access-specifier ':' member-specification[opt]
 ///
 void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
-                                         unsigned TagType, DeclTy *TagDecl) {
+                                         unsigned TagType, DeclPtrTy TagDecl) {
   assert((TagType == DeclSpec::TST_struct ||
          TagType == DeclSpec::TST_union  ||
          TagType == DeclSpec::TST_class) && "Invalid TagType!");
@@ -997,7 +995,7 @@
 /// [C++]  mem-initializer-list: 
 ///          mem-initializer 
 ///          mem-initializer , mem-initializer-list 
-void Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) {
+void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
   assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
 
   SourceLocation ColonLoc = ConsumeToken();
@@ -1035,7 +1033,7 @@
 /// [C++] mem-initializer-id:
 ///         '::'[opt] nested-name-specifier[opt] class-name
 ///         identifier
-Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
+Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
   // FIXME: parse '::'[opt] nested-name-specifier[opt]
 
   if (Tok.isNot(tok::identifier)) {
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index b3ec24f..dc57ac1 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -117,7 +117,7 @@
         // an operator and not as part of a simple-template-id.
       }
 
-      DeclTy *Template = 0;
+      DeclPtrTy Template;
       TemplateNameKind TNK = TNK_Non_template;
       // FIXME: If the nested-name-specifier thus far is dependent,
       // set TNK = TNK_Dependent_template_name and skip the
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index ca722fa..8ff1944 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -28,7 +28,7 @@
 /// [OBJC]  objc-protocol-definition
 /// [OBJC]  objc-method-definition
 /// [OBJC]  '@' 'end'
-Parser::DeclTy *Parser::ParseObjCAtDirectives() {
+Parser::DeclPtrTy Parser::ParseObjCAtDirectives() {
   SourceLocation AtLoc = ConsumeToken(); // the "@"
   
   switch (Tok.getObjCKeywordID()) {
@@ -51,7 +51,7 @@
   default:
     Diag(AtLoc, diag::err_unexpected_at);
     SkipUntil(tok::semi);
-    return 0;
+    return DeclPtrTy();
   }
 }
 
@@ -59,7 +59,7 @@
 /// objc-class-declaration: 
 ///    '@' 'class' identifier-list ';'
 ///  
-Parser::DeclTy *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
+Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
   ConsumeToken(); // the identifier "class"
   llvm::SmallVector<IdentifierInfo *, 8> ClassNames;
   
@@ -67,7 +67,7 @@
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident);
       SkipUntil(tok::semi);
-      return 0;
+      return DeclPtrTy();
     }
     ClassNames.push_back(Tok.getIdentifierInfo());
     ConsumeToken();
@@ -80,7 +80,7 @@
   
   // Consume the ';'.
   if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
-    return 0;
+    return DeclPtrTy();
   
   return Actions.ActOnForwardClassDeclaration(atLoc,
                                       &ClassNames[0], ClassNames.size());
@@ -114,7 +114,7 @@
 ///     __attribute__((unavailable))
 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
 ///
-Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration(
+Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
   SourceLocation atLoc, AttributeList *attrList) {
   assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
          "ParseObjCAtInterfaceDeclaration(): Expected @interface");
@@ -122,7 +122,7 @@
   
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
-    return 0;
+    return DeclPtrTy();
   }
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
@@ -139,26 +139,26 @@
       categoryLoc = ConsumeToken();
     } else if (!getLang().ObjC2) {
       Diag(Tok, diag::err_expected_ident); // missing category name.
-      return 0;
+      return DeclPtrTy();
     }
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       SkipUntil(tok::r_paren, false); // don't stop at ';'
-      return 0;
+      return DeclPtrTy();
     }
     rparenLoc = ConsumeParen();
     
     // Next, we need to check for any protocol references.
     SourceLocation EndProtoLoc;
-    llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
+    llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
     if (Tok.is(tok::less) &&
         ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
-      return 0;
+      return DeclPtrTy();
     
     if (attrList) // categories don't support attributes.
       Diag(Tok, diag::err_objc_no_attributes_on_category);
     
-    DeclTy *CategoryType = Actions.ActOnStartCategoryInterface(atLoc, 
+    DeclPtrTy CategoryType = Actions.ActOnStartCategoryInterface(atLoc, 
                                      nameId, nameLoc, categoryId, categoryLoc,
                                      &ProtocolRefs[0], ProtocolRefs.size(),
                                      EndProtoLoc);
@@ -174,19 +174,19 @@
     ConsumeToken();
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing super class name.
-      return 0;
+      return DeclPtrTy();
     }
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken();
   }
   // Next, we need to check for any protocol references.
-  llvm::SmallVector<Action::DeclTy*, 8> ProtocolRefs;
+  llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs;
   SourceLocation EndProtoLoc;
   if (Tok.is(tok::less) &&
       ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
-    return 0;
+    return DeclPtrTy();
   
-  DeclTy *ClsType = 
+  DeclPtrTy ClsType = 
     Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, 
                                      superClassId, superClassLoc,
                                      &ProtocolRefs[0], ProtocolRefs.size(),
@@ -211,11 +211,11 @@
 ///     @required
 ///     @optional
 ///
-void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
+void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
                                         tok::ObjCKeywordKind contextKey) {
-  llvm::SmallVector<DeclTy*, 32> allMethods;
-  llvm::SmallVector<DeclTy*, 16> allProperties;
-  llvm::SmallVector<DeclTy*, 8> allTUVariables;
+  llvm::SmallVector<DeclPtrTy, 32> allMethods;
+  llvm::SmallVector<DeclPtrTy, 16> allProperties;
+  llvm::SmallVector<DeclPtrTy, 8> allTUVariables;
   tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword;
   
   SourceLocation AtEndLoc;
@@ -223,7 +223,7 @@
   while (1) {
     // If this is a method prototype, parse it.
     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
-      DeclTy *methodPrototype = 
+      DeclPtrTy methodPrototype = 
         ParseObjCMethodPrototype(interfaceDecl, MethodImplKind);
       allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
@@ -253,7 +253,7 @@
       
       // FIXME: as the name implies, this rule allows function definitions.
       // We could pass a flag or check for functions during semantic analysis.
-      DeclTy *VFDecl = ParseDeclarationOrFunctionDefinition();
+      DeclPtrTy VFDecl = ParseDeclarationOrFunctionDefinition();
       allTUVariables.push_back(VFDecl);
       continue;
     }
@@ -337,11 +337,11 @@
                                                          PP.getSelectorTable(),
                                                          FD.D.getIdentifier());
         bool isOverridingProperty = false;
-        DeclTy *Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
-                                                 GetterSel, SetterSel,
-                                                 interfaceDecl, 
-                                                 &isOverridingProperty,
-                                                 MethodImplKind);
+        DeclPtrTy Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
+                                                   GetterSel, SetterSel,
+                                                   interfaceDecl, 
+                                                   &isOverridingProperty,
+                                                   MethodImplKind);
         if (!isOverridingProperty)
           allProperties.push_back(Property);
       }
@@ -461,14 +461,14 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl, 
-                          tok::ObjCKeywordKind MethodImplKind) {
+Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, 
+                                          tok::ObjCKeywordKind MethodImplKind) {
   assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
 
   tok::TokenKind methodType = Tok.getKind();  
   SourceLocation mLoc = ConsumeToken();
   
-  DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl, MethodImplKind);
+  DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind);
   // Since this rule is used for both method declarations and definitions,
   // the caller is (optionally) responsible for consuming the ';'.
   return MDecl;
@@ -672,11 +672,10 @@
 ///   objc-keyword-attributes:         [OBJC2]
 ///     __attribute__((unused))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
-                                            tok::TokenKind mType,
-                                            DeclTy *IDecl,
-                                            tok::ObjCKeywordKind MethodImplKind)
-{
+Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc,
+                                              tok::TokenKind mType,
+                                              DeclPtrTy IDecl,
+                                          tok::ObjCKeywordKind MethodImplKind) {
   // Parse the return type if present.
   TypeTy *ReturnType = 0;
   ObjCDeclSpec DSRet;
@@ -692,7 +691,7 @@
       << SourceRange(mLoc, Tok.getLocation());
     // Skip until we get a ; or {}.
     SkipUntil(tok::r_brace);
-    return 0;
+    return DeclPtrTy();
   }
   
   llvm::SmallVector<Declarator, 8> CargNames;
@@ -789,7 +788,7 @@
 ///     '<' identifier-list '>'
 ///
 bool Parser::
-ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &Protocols,
+ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
                             bool WarnOnDeclarations, SourceLocation &EndLoc) {
   assert(Tok.is(tok::less) && "expected <");
   
@@ -847,10 +846,10 @@
 ///   objc-instance-variable-decl:
 ///     struct-declaration 
 ///
-void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
+void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
-  llvm::SmallVector<DeclTy*, 32> AllIvarDecls;
+  llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
   llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
 
   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
@@ -895,9 +894,9 @@
     for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
       FieldDeclarator &FD = FieldDeclarators[i];
       // Install the declarator into interfaceDecl.
-      DeclTy *Field = Actions.ActOnIvar(CurScope,
-                                         DS.getSourceRange().getBegin(),
-                                         FD.D, FD.BitfieldSize, visibility);
+      DeclPtrTy Field = Actions.ActOnIvar(CurScope,
+                                          DS.getSourceRange().getBegin(),
+                                          FD.D, FD.BitfieldSize, visibility);
       AllIvarDecls.push_back(Field);
     }
     
@@ -934,15 +933,15 @@
 ///   "@protocol identifier ;" should be resolved as "@protocol
 ///   identifier-list ;": objc-interface-decl-list may not start with a
 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
-Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
-                                               AttributeList *attrList) {
+Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
+                                                      AttributeList *attrList) {
   assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
          "ParseObjCAtProtocolDeclaration(): Expected @protocol");
   ConsumeToken(); // the "protocol" identifier
   
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing protocol name.
-    return 0;
+    return DeclPtrTy();
   }
   // Save the protocol name, then consume it.
   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
@@ -965,7 +964,7 @@
       if (Tok.isNot(tok::identifier)) {
         Diag(Tok, diag::err_expected_ident);
         SkipUntil(tok::semi);
-        return 0;
+        return DeclPtrTy();
       }
       ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(),
                                                Tok.getLocation()));
@@ -976,7 +975,7 @@
     }
     // Consume the ';'.
     if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
-      return 0;
+      return DeclPtrTy();
     
     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
                                                    &ProtocolRefs[0], 
@@ -987,12 +986,12 @@
   // Last, and definitely not least, parse a protocol declaration.
   SourceLocation EndProtoLoc;
 
-  llvm::SmallVector<DeclTy *, 8> ProtocolRefs;
+  llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
   if (Tok.is(tok::less) &&
       ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc))
-    return 0;
+    return DeclPtrTy();
   
-  DeclTy *ProtoType =
+  DeclPtrTy ProtoType =
     Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
                                         &ProtocolRefs[0], ProtocolRefs.size(),
                                         EndProtoLoc, attrList);
@@ -1010,8 +1009,7 @@
 ///
 ///   objc-category-implementation-prologue:
 ///     @implementation identifier ( identifier )
-
-Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration(
+Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
   SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
          "ParseObjCAtImplementationDeclaration(): Expected @implementation");
@@ -1019,7 +1017,7 @@
   
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident); // missing class or category name.
-    return 0;
+    return DeclPtrTy();
   }
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
@@ -1036,19 +1034,19 @@
       categoryLoc = ConsumeToken();
     } else {
       Diag(Tok, diag::err_expected_ident); // missing category name.
-      return 0;
+      return DeclPtrTy();
     }   
     if (Tok.isNot(tok::r_paren)) {
       Diag(Tok, diag::err_expected_rparen);
       SkipUntil(tok::r_paren, false); // don't stop at ';'
-      return 0;
+      return DeclPtrTy();
     }
     rparenLoc = ConsumeParen();
-    DeclTy *ImplCatType = Actions.ActOnStartCategoryImplementation(
+    DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation(
                                     atLoc, nameId, nameLoc, categoryId, 
                                     categoryLoc);
     ObjCImpDecl = ImplCatType;
-    return 0;
+    return DeclPtrTy();
   }
   // We have a class implementation
   SourceLocation superClassLoc;
@@ -1058,12 +1056,12 @@
     ConsumeToken();
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident); // missing super class name.
-      return 0;
+      return DeclPtrTy();
     }
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken(); // Consume super class name
   }
-  DeclTy *ImplClsType = Actions.ActOnStartClassImplementation(
+  DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation(
                                   atLoc, nameId, nameLoc,
                                   superClassId, superClassLoc);
   
@@ -1071,17 +1069,17 @@
     ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
   ObjCImpDecl = ImplClsType;
   
-  return 0;
+  return DeclPtrTy();
 }
 
-Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
+Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_end) &&
          "ParseObjCAtEndDeclaration(): Expected @end");
-  DeclTy *Result = ObjCImpDecl;
+  DeclPtrTy Result = ObjCImpDecl;
   ConsumeToken(); // the "end" identifier
   if (ObjCImpDecl) {
     Actions.ActOnAtEnd(atLoc, ObjCImpDecl);
-    ObjCImpDecl = 0;
+    ObjCImpDecl = DeclPtrTy();
   }
   else
     Diag(atLoc, diag::warn_expected_implementation); // missing @implementation
@@ -1091,30 +1089,28 @@
 ///   compatibility-alias-decl:
 ///     @compatibility_alias alias-name  class-name ';'
 ///
-Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
+Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
   ConsumeToken(); // consume compatibility_alias
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
   IdentifierInfo *classId = Tok.getIdentifierInfo();
   SourceLocation classLoc = ConsumeToken(); // consume class-name;
   if (Tok.isNot(tok::semi)) {
     Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias";
-    return 0;
+    return DeclPtrTy();
   }
-  DeclTy *ClsType = Actions.ActOnCompatiblityAlias(atLoc, 
-                                                   aliasId, aliasLoc,
-                                                   classId, classLoc);
-  return ClsType;
+  return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
+                                        classId, classLoc);
 }
 
 ///   property-synthesis:
@@ -1128,14 +1124,15 @@
 ///     identifier
 ///     identifier '=' identifier
 ///
-Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
+Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
          "ParseObjCPropertyDynamic(): Expected '@synthesize'");
   SourceLocation loc = ConsumeToken(); // consume synthesize
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
+  
   while (Tok.is(tok::identifier)) {
     IdentifierInfo *propertyIvar = 0;
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
@@ -1158,7 +1155,7 @@
   }
   if (Tok.isNot(tok::semi))
     Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
-  return 0;
+  return DeclPtrTy();
 }
 
 ///   property-dynamic:
@@ -1168,13 +1165,13 @@
 ///     identifier
 ///     property-list ',' identifier
 ///
-Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
+Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
          "ParseObjCPropertyDynamic(): Expected '@dynamic'");
   SourceLocation loc = ConsumeToken(); // consume dynamic
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
   while (Tok.is(tok::identifier)) {
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
@@ -1188,7 +1185,7 @@
   }
   if (Tok.isNot(tok::semi))
     Diag(Tok, diag::err_expected_semi_after) << "@dynamic";
-  return 0;
+  return DeclPtrTy();
 }
  
 ///  objc-throw-statement:
@@ -1283,7 +1280,7 @@
 
     SourceLocation AtCatchFinallyLoc = ConsumeToken();
     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
-      DeclTy *FirstPart = 0;
+      DeclPtrTy FirstPart;
       ConsumeToken(); // consume catch
       if (Tok.is(tok::l_paren)) {
         ConsumeParen();
@@ -1348,8 +1345,8 @@
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
-Parser::DeclTy *Parser::ParseObjCMethodDefinition() {
-  DeclTy *MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
+Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
+  DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl);
   
   PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions,
                                         PP.getSourceManager(),
@@ -1368,7 +1365,7 @@
     
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return 0;
+      return DeclPtrTy();
   }
   SourceLocation BraceLoc = Tok.getLocation();
   
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 1d2e82e..b996c74 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -101,7 +101,7 @@
   default: {
     if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
       SourceLocation DeclStart = Tok.getLocation();
-      DeclTy *Decl = ParseDeclaration(Declarator::BlockContext);
+      DeclPtrTy Decl = ParseDeclaration(Declarator::BlockContext);
       // FIXME: Pass in the right location for the end of the declstmt.
       return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
     }
@@ -208,7 +208,7 @@
   SourceLocation ColonLoc = ConsumeToken();
 
   // Read label attributes, if present.
-  DeclTy *AttrList = 0;
+  Action::AttrTy *AttrList = 0;
   if (Tok.is(tok::kw___attribute))
     // TODO: save these somewhere.
     AttrList = ParseAttributes();
@@ -444,7 +444,7 @@
       if (isDeclarationStatement()) {
         // FIXME: Save the __extension__ on the decl as a node somehow.
         SourceLocation DeclStart = Tok.getLocation();
-        DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
+        DeclPtrTy Res = ParseDeclaration(Declarator::BlockContext);
         // FIXME: Pass in the right location for the end of the declstmt.
         R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
       } else {
@@ -912,7 +912,7 @@
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
     SourceLocation DeclStart = Tok.getLocation();
-    DeclTy *aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
+    DeclPtrTy aBlockVarDecl = ParseSimpleDeclaration(Declarator::ForContext);
     // FIXME: Pass in the right location for the end of the declstmt.
     FirstPart = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
                                           DeclStart);
@@ -1287,7 +1287,7 @@
   return true;
 }
 
-Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl) {
+Parser::DeclPtrTy Parser::ParseFunctionStatementBody(DeclPtrTy Decl) {
   assert(Tok.is(tok::l_brace));
   SourceLocation LBraceLoc = Tok.getLocation();
          
@@ -1369,7 +1369,7 @@
 
   // exception-declaration is equivalent to '...' or a parameter-declaration
   // without default arguments.
-  DeclTy *ExceptionDecl = 0;
+  DeclPtrTy ExceptionDecl;
   if (Tok.isNot(tok::ellipsis)) {
     DeclSpec DS;
     if (ParseCXXTypeSpecifierSeq(DS))
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 2c07823..29b8a14 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -16,7 +16,6 @@
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
 #include "AstGuard.h"
-
 using namespace clang;
 
 /// \brief Parse a template declaration or an explicit specialization.
@@ -34,7 +33,7 @@
 ///
 ///       explicit-specialization: [ C++ temp.expl.spec]
 ///         'template' '<' '>' declaration
-Parser::DeclTy *
+Parser::DeclPtrTy
 Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
                                                  AccessSpecifier AS) {
   assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) && 
@@ -78,7 +77,7 @@
       TemplateLoc = ConsumeToken();
     } else {
       Diag(Tok.getLocation(), diag::err_expected_template);
-      return 0;
+      return DeclPtrTy();
     }
   
     // Parse the '<' template-parameter-list '>'
@@ -141,7 +140,7 @@
 Parser::ParseTemplateParameterList(unsigned Depth,
                                    TemplateParameterList &TemplateParams) {
   while(1) {
-    if (DeclTy* TmpParam 
+    if (DeclPtrTy TmpParam
           = ParseTemplateParameter(Depth, TemplateParams.size())) {
       TemplateParams.push_back(TmpParam);
     } else {
@@ -183,7 +182,7 @@
 ///         'typename' identifier[opt] '=' type-id
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
-Parser::DeclTy *
+Parser::DeclPtrTy 
 Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
   if(Tok.is(tok::kw_class) ||
      (Tok.is(tok::kw_typename) && 
@@ -210,7 +209,7 @@
 ///         'class' identifier[opt] '=' type-id
 ///         'typename' identifier[opt]
 ///         'typename' identifier[opt] '=' type-id
-Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
+Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){
   assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) &&
 	 "A type-parameter starts with 'class' or 'typename'");
 
@@ -230,12 +229,12 @@
     // don't consume this token.
   } else {
     Diag(Tok.getLocation(), diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
   
-  DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
-                                                 KeyLoc, ParamName, NameLoc,
-                                                 Depth, Position);
+  DeclPtrTy TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
+                                                   KeyLoc, ParamName, NameLoc,
+                                                   Depth, Position);
 
   // Grab a default type id (if given).
   if(Tok.is(tok::equal)) {
@@ -256,7 +255,7 @@
 ///       type-parameter:    [C++ temp.param]
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
 ///         'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression
-Parser::DeclTy * 
+Parser::DeclPtrTy
 Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
 
@@ -268,7 +267,7 @@
     ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
     if(!ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
                                 RAngleLoc)) {
-      return 0;
+      return DeclPtrTy();
     }
   }
 
@@ -277,7 +276,7 @@
   if(!Tok.is(tok::kw_class)) {
     Diag(Tok.getLocation(), diag::err_expected_class_before) 
       << PP.getSpelling(Tok);
-    return 0;
+    return DeclPtrTy();
   }
   SourceLocation ClassLoc = ConsumeToken();
 
@@ -292,7 +291,7 @@
     // don't consume this token.
   } else {
     Diag(Tok.getLocation(), diag::err_expected_ident);
-    return 0;
+    return DeclPtrTy();
   }
 
   TemplateParamsTy *ParamList = 
@@ -302,7 +301,7 @@
                                        TemplateParams.size(),
                                        RAngleLoc);
 
-  Parser::DeclTy * Param
+  Parser::DeclPtrTy Param
     = Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
                                              ParamList, ParamName,
                                              NameLoc, Depth, Position);
@@ -334,7 +333,7 @@
 /// parameters.
 /// FIXME: We need to make a ParseParameterDeclaration that works for
 /// non-type template parameters and normal function parameters.
-Parser::DeclTy * 
+Parser::DeclPtrTy 
 Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
   SourceLocation StartLoc = Tok.getLocation();
 
@@ -354,12 +353,12 @@
     // TODO: This is currently a placeholder for some kind of Sema Error.
     Diag(Tok.getLocation(), diag::err_parse_error);
     SkipUntil(tok::comma, tok::greater, true, true);
-    return 0;
+    return DeclPtrTy();
   }
 
   // Create the parameter. 
-  DeclTy *Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
-                                                        Depth, Position);
+  DeclPtrTy Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
+                                                          Depth, Position);
 
   // If there is a default value, parse it.
   if (Tok.is(tok::equal)) {
@@ -402,7 +401,7 @@
 /// last token in the stream (e.g., so that it can be replaced with an
 /// annotation token).
 bool 
-Parser::ParseTemplateIdAfterTemplateName(DeclTy *Template,
+Parser::ParseTemplateIdAfterTemplateName(DeclPtrTy Template,
                                          SourceLocation TemplateNameLoc, 
                                          const CXXScopeSpec *SS,
                                          bool ConsumeLastToken,
@@ -495,7 +494,7 @@
 /// replaced with a type annotation token. Otherwise, the
 /// simple-template-id is always replaced with a template-id
 /// annotation token.
-void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
+void Parser::AnnotateTemplateIdToken(DeclPtrTy Template, TemplateNameKind TNK,
                                      const CXXScopeSpec *SS, 
                                      SourceLocation TemplateKWLoc,
                                      bool AllowTypeAnnotation) {
@@ -552,7 +551,7 @@
       = TemplateIdAnnotation::Allocate(TemplateArgs.size());
     TemplateId->TemplateNameLoc = TemplateNameLoc;
     TemplateId->Name = Name;
-    TemplateId->Template = Template;
+    TemplateId->Template = Template.getAs<void*>();
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
     TemplateId->RAngleLoc = RAngleLoc;
@@ -599,7 +598,7 @@
                                      TemplateId->NumArgs);
 
   Action::TypeResult Type 
-    = Actions.ActOnClassTemplateId(TemplateId->Template, 
+    = Actions.ActOnClassTemplateId(DeclPtrTy::make(TemplateId->Template),
                                    TemplateId->TemplateNameLoc,
                                    TemplateId->LAngleLoc, 
                                    TemplateArgsPtr,
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 7f2c5d3..00a3349 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -27,7 +27,7 @@
   CurScope = 0;
   NumCachedScopes = 0;
   ParenCount = BracketCount = BraceCount = 0;
-  ObjCImpDecl = 0;
+  ObjCImpDecl = DeclPtrTy();
 
   // Add #pragma handlers. These are removed and destroyed in the
   // destructor.
@@ -324,8 +324,8 @@
 
 /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
 /// action tells us to.  This returns true if the EOF was encountered.
-bool Parser::ParseTopLevelDecl(DeclTy*& Result) {
-  Result = 0;
+bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) {
+  Result = DeclPtrTy();
   if (Tok.is(tok::eof)) {
     Actions.ActOnEndOfTranslationUnit();
     return true;
@@ -342,7 +342,7 @@
 void Parser::ParseTranslationUnit() {
   Initialize();
 
-  DeclTy *Res;
+  DeclPtrTy Res;
   while (!ParseTopLevelDecl(Res))
     /*parse them all*/;
   
@@ -368,20 +368,20 @@
 /// [GNU] asm-definition:
 ///         simple-asm-expr ';'
 ///
-Parser::DeclTy *Parser::ParseExternalDeclaration() {
+Parser::DeclPtrTy Parser::ParseExternalDeclaration() {
   switch (Tok.getKind()) {
   case tok::semi:
     Diag(Tok, diag::ext_top_level_semi);
     ConsumeToken();
     // TODO: Invoke action for top-level semicolon.
-    return 0;
+    return DeclPtrTy();
   case tok::r_brace:
     Diag(Tok, diag::err_expected_external_declaration);
     ConsumeBrace();
-    return 0;
+    return DeclPtrTy();
   case tok::eof:
     Diag(Tok, diag::err_expected_external_declaration);
-    return 0;
+    return DeclPtrTy();
   case tok::kw___extension__: {
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
@@ -396,7 +396,7 @@
 
     if (!Result.isInvalid())
       return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
-    return 0;
+    return DeclPtrTy();
   }
   case tok::at:
     // @ is not a legal token unless objc is enabled, no need to check.
@@ -405,11 +405,9 @@
   case tok::plus:
     if (getLang().ObjC1)
       return ParseObjCMethodDefinition();
-    else {
-      Diag(Tok, diag::err_expected_external_declaration);
-      ConsumeToken();
-    }
-    return 0;
+    Diag(Tok, diag::err_expected_external_declaration);
+    ConsumeToken();
+    return DeclPtrTy();
   case tok::kw_using:
   case tok::kw_namespace:
   case tok::kw_typedef:
@@ -440,7 +438,7 @@
 /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode]
 /// [OMP]   threadprivate-directive                              [TODO]
 ///
-Parser::DeclTy *
+Parser::DeclPtrTy
 Parser::ParseDeclarationOrFunctionDefinition(
                                   TemplateParameterLists *TemplateParams,
                                   AccessSpecifier AS) {
@@ -464,7 +462,7 @@
         !Tok.isObjCAtKeyword(tok::objc_protocol)) {
       Diag(Tok, diag::err_objc_unexpected_attr);
       SkipUntil(tok::semi); // FIXME: better skip?
-      return 0;
+      return DeclPtrTy();
     }
     const char *PrevSpec = 0;
     if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
@@ -491,7 +489,7 @@
     SkipUntil(tok::r_brace, true, true);
     if (Tok.is(tok::semi))
       ConsumeToken();
-    return 0;
+    return DeclPtrTy();
   }
 
   // If the declarator is the start of a function definition, handle it.
@@ -521,7 +519,7 @@
       } else {
         SkipUntil(tok::semi);
       }
-      return 0;
+      return DeclPtrTy();
     }
     return ParseFunctionDefinition(DeclaratorInfo);
   } else {
@@ -530,7 +528,7 @@
     else
       Diag(Tok, diag::err_invalid_token_after_toplevel_declarator);
     SkipUntil(tok::semi);
-    return 0;
+    return DeclPtrTy();
   }
 
   // Parse the init-declarator-list for a normal declaration.
@@ -550,7 +548,7 @@
 /// [C++] function-definition: [C++ 8.4]
 ///         decl-specifier-seq[opt] declarator function-try-block [TODO]
 ///
-Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
+Parser::DeclPtrTy Parser::ParseFunctionDefinition(Declarator &D) {
   const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
   assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
          "This isn't a function declarator!");
@@ -584,7 +582,7 @@
 
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return 0;
+      return DeclPtrTy();
   }
 
   // Enter a scope for the function body.
@@ -592,7 +590,7 @@
 
   // Tell the actions module that we have entered a function definition with the
   // specified Declarator for the function.
-  DeclTy *Res = Actions.ActOnStartOfFunctionDef(CurScope, D);
+  DeclPtrTy Res = Actions.ActOnStartOfFunctionDef(CurScope, D);
 
   // If we have a colon, then we're probably parsing a C++
   // ctor-initializer.
@@ -652,14 +650,14 @@
 
     // Handle the full declarator list.
     while (1) {
-      DeclTy *AttrList;
+      Action::AttrTy *AttrList;
       // If attributes are present, parse them.
       if (Tok.is(tok::kw___attribute))
         // FIXME: attach attributes too.
         AttrList = ParseAttributes();
 
       // Ask the actions module to compute the type for this declarator.
-      Action::DeclTy *Param =
+      Action::DeclPtrTy Param =
         Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
 
       if (Param &&
@@ -862,7 +860,7 @@
     
     // If this is a template-id, annotate with a template-id or type token.
     if (NextToken().is(tok::less)) {
-      DeclTy *Template;
+      DeclPtrTy Template;
       if (TemplateNameKind TNK 
             = Actions.isTemplateName(*Tok.getIdentifierInfo(),
                                      CurScope, Template, &SS))