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