Sema-check virtual declarations. Complete dynamic_cast checking.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58804 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index ea3c175..bdc2faf 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -310,6 +310,15 @@
     return true;
   }
 
+  // If the base class is polymorphic, the new one is, too.
+  RecordDecl *BaseDecl = BaseType->getAsRecordType()->getDecl();
+  assert(BaseDecl && "Record type has no declaration");
+  BaseDecl = BaseDecl->getDefinition(Context);
+  assert(BaseDecl && "Base type is not incomplete, but has no definition");
+  if (cast<CXXRecordDecl>(BaseDecl)->isPolymorphic()) {
+    cast<CXXRecordDecl>(Decl)->setPolymorphic(true);
+  }
+
   // Create the base specifier.
   return new CXXBaseSpecifier(SpecifierRange, Virtual, 
                               BaseType->isClassType(), Access, BaseType);
@@ -468,8 +477,16 @@
   if (isInstField && (AS == AS_private || AS == AS_protected))
     cast<CXXRecordDecl>(CurContext)->setAggregate(false);
 
-  // FIXME: If the member is a virtual function, mark it its class as
-  // a non-aggregate.
+  if (DS.isVirtualSpecified()) {
+    if (!isFunc || DS.getStorageClassSpec() == DeclSpec::SCS_static) {
+      Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function);
+      InvalidDecl = true;
+    } else {
+      CXXRecordDecl *CurClass = cast<CXXRecordDecl>(CurContext);
+      CurClass->setAggregate(false);
+      CurClass->setPolymorphic(true);
+    }
+  }
 
   if (BitWidth) {
     // C++ 9.6p2: Only when declaring an unnamed bit-field may the
diff --git a/lib/Sema/SemaNamedCast.cpp b/lib/Sema/SemaNamedCast.cpp
index 980e012..bf559d6 100644
--- a/lib/Sema/SemaNamedCast.cpp
+++ b/lib/Sema/SemaNamedCast.cpp
@@ -671,7 +671,12 @@
   }
 
   // C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
-  // FIXME: Information not yet available.
+  const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(Context);
+  assert(SrcDecl && "Definition missing");
+  if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
+    Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic,
+      SrcPointee.getUnqualifiedType().getAsString(), SrcExpr->getSourceRange());
+  }
 
   // Done. Everything else is run-time checks.
 }