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/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index a6cb24c..361434a 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -664,26 +664,28 @@
   } else if (const RecordType *RT = Ty->getAsRecordType()) {
     RecordDecl *RD = RT->getDecl();
     // The type-specifier-seq shall not declare a new class...
-    if (RD->isDefinition() && (RD->getIdentifier() == 0 || S->isDeclScope(RD)))
+    if (RD->isDefinition() &&
+        (RD->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(RD))))
       Diag(RD->getLocation(), diag::err_type_defined_in_condition);
   } else if (const EnumType *ET = Ty->getAsEnumType()) {
     EnumDecl *ED = ET->getDecl();
     // ...or enumeration.
-    if (ED->isDefinition() && (ED->getIdentifier() == 0 || S->isDeclScope(ED)))
+    if (ED->isDefinition() &&
+        (ED->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(ED))))
       Diag(ED->getLocation(), diag::err_type_defined_in_condition);
   }
 
-  DeclTy *Dcl = ActOnDeclarator(S, D, 0);
+  DeclPtrTy Dcl = ActOnDeclarator(S, D, DeclPtrTy());
   if (!Dcl)
     return ExprError();
   AddInitializerToDecl(Dcl, move(AssignExprVal));
 
   // Mark this variable as one that is declared within a conditional.
-  if (VarDecl *VD = dyn_cast<VarDecl>((Decl *)Dcl))
-    VD->setDeclaredInCondition(true);
-
-  return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc,
-                                      cast<VarDecl>(static_cast<Decl *>(Dcl))));
+  // We know that the decl had to be a VarDecl because that is the only type of
+  // decl that can be assigned and the grammar requires an '='.
+  VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
+  VD->setDeclaredInCondition(true);
+  return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc, VD));
 }
 
 /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.