+/* Finish computing the `literal type' property of class type T.
+
+ At this point, we have already processed base classes and
+ non-static data members. We need to check whether the copy
+ constructor is trivial, the destructor is trivial, and there
+ is a trivial default constructor or at least one constexpr
+ constructor other than the copy constructor. */
+
+static void
+finalize_literal_type_property (tree t)
+{
+ if (cxx_dialect < cxx0x
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
+ /* FIXME These constraints seem unnecessary; remove from standard.
+ || !TYPE_HAS_TRIVIAL_COPY_CTOR (t)
+ || TYPE_HAS_COMPLEX_MOVE_CTOR (t)*/ )
+ CLASSTYPE_LITERAL_P (t) = false;
+ else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
+ && !TYPE_HAS_CONSTEXPR_CTOR (t))
+ CLASSTYPE_LITERAL_P (t) = false;
+
+ if (!CLASSTYPE_LITERAL_P (t) && !CLASSTYPE_TEMPLATE_INSTANTIATION (t))
+ {
+ tree fn;
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARED_CONSTEXPR_P (fn)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ {
+ error ("enclosing class of %q+D is not a literal type", fn);
+ DECL_DECLARED_CONSTEXPR_P (fn) = false;
+ }
+ }
+}
+