PODness and Type Traits

Make C++ classes track the POD property (C++ [class]p4)
Track the existence of a copy assignment operator.
Implicitly declare the copy assignment operator if none is provided.
Implement most of the parsing job for the G++ type traits extension.
Fully implement the low-hanging fruit of the type traits:
__is_pod: Whether a type is a POD.
__is_class: Whether a type is a (non-union) class.
__is_union: Whether a type is a union.
__is_enum: Whether a type is an enum.
__is_polymorphic: Whether a type is polymorphic (C++ [class.virtual]p1).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61746 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 4cc5c74..07d794e 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -120,6 +120,35 @@
   return child_iterator();
 }
 
+// UnaryTypeTraitExpr
+Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
+  return child_iterator();
+}
+Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
+  return child_iterator();
+}
+
+bool UnaryTypeTraitExpr::Evaluate() const {
+  switch(UTT) {
+  default: assert(false && "Unknown type trait or not implemented");
+  case UTT_IsPOD: return QueriedType->isPODType();
+  case UTT_IsClass: // Fallthrough
+  case UTT_IsUnion:
+    if (const RecordType *Record = QueriedType->getAsRecordType()) {
+      bool Union = Record->getDecl()->isUnion();
+      return UTT == UTT_IsUnion ? Union : !Union;
+    }
+    return false;
+  case UTT_IsEnum: return QueriedType->isEnumeralType();
+  case UTT_IsPolymorphic:
+    if (const RecordType *Record = QueriedType->getAsRecordType()) {
+      // Type traits are only parsed in C++, so we've got CXXRecords.
+      return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
+    }
+    return false;
+  }
+}
+
 OverloadedOperatorKind CXXOperatorCallExpr::getOperator() const {
   // All simple function calls (e.g. func()) are implicitly cast to pointer to
   // function. As a result, we try and obtain the DeclRefExpr from the