Very basic support for pure virtual functions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62003 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index dea3688..ba4a47d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -535,6 +535,7 @@
       Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function);
       InvalidDecl = true;
     } else {
+      cast<CXXMethodDecl>(Member)->setVirtual();
       CXXRecordDecl *CurClass = cast<CXXRecordDecl>(CurContext);
       CurClass->setAggregate(false);
       CurClass->setPOD(false);
@@ -542,6 +543,10 @@
     }
   }
 
+  // FIXME: The above definition of virtual is not sufficient. A function is
+  // also virtual if it overrides an already virtual function. This is important
+  // to do here because it decides the validity of a pure specifier.
+
   if (BitWidth) {
     // C++ 9.6p2: Only when declaring an unnamed bit-field may the
     // constant-expression be a value equal to zero.
@@ -608,10 +613,28 @@
       }
 
     } else {
-      // not static member.
-      Diag(Loc, diag::err_member_initialization)
-        << Name << Init->getSourceRange();
-      InvalidDecl = true;
+      // not static member. perhaps virtual function?
+      if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+        IntegerLiteral *IL;
+        if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
+            Context.getCanonicalType(IL->getType()) == Context.IntTy) {
+          if (MD->isVirtual())
+            MD->setPure();
+          else {
+            Diag(Loc, diag::err_non_virtual_pure)
+              << Name << Init->getSourceRange();
+            InvalidDecl = true;
+          }
+        } else {
+          Diag(Loc, diag::err_member_function_initialization)
+            << Name << Init->getSourceRange();
+          InvalidDecl = true;
+        }
+      } else {
+        Diag(Loc, diag::err_member_initialization)
+          << Name << Init->getSourceRange();
+        InvalidDecl = true;
+      }
     }
   }