+/* Like c_determine_visibility, but with additional C++-specific
+ behavior. */
+
+void
+determine_visibility (tree decl)
+{
+ tree class_type;
+
+ /* Cloned constructors and destructors get the same visibility as
+ the underlying function. That should be set up in
+ maybe_clone_body. */
+ gcc_assert (!DECL_CLONED_FUNCTION_P (decl));
+
+ /* Give the common code a chance to make a determination. */
+ if (c_determine_visibility (decl))
+ return;
+
+ /* If DECL is a member of a class, visibility specifiers on the
+ class can influence the visibility of the DECL. */
+ if (DECL_CLASS_SCOPE_P (decl))
+ class_type = DECL_CONTEXT (decl);
+ else if (TREE_CODE (decl) == VAR_DECL
+ && DECL_TINFO_P (decl)
+ && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl))))
+ class_type = TREE_TYPE (DECL_NAME (decl));
+ else
+ {
+ /* Virtual tables have DECL_CONTEXT set to their associated class,
+ so they are automatically handled above. */
+ gcc_assert (TREE_CODE (decl) != VAR_DECL
+ || !DECL_VTABLE_OR_VTT_P (decl));
+ /* Entities not associated with any class just get the
+ visibility specified by their attributes. */
+ return;
+ }
+
+ /* By default, static data members and function members receive
+ the visibility of their containing class. */
+ if (class_type)
+ {
+ if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type)))
+ {
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)
+ && visibility_options.inlines_hidden)
+ {
+ /* Don't change it if it has been set explicitly by user. */
+ if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ }
+ else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+ {
+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ else if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+ DECL_VISIBILITY_SPECIFIED (decl) = 0;
+ }
+ }
+}
+
+/* DECL is a FUNCTION_DECL or VAR_DECL. If the object file linkage
+ for DECL has not already been determined, do so now by setting
+ DECL_EXTERNAL, DECL_COMDAT and other related flags. Until this
+ function is called entities with vague linkage whose definitions
+ are available must have TREE_PUBLIC set.
+
+ If this function decides to place DECL in COMDAT, it will set
+ appropriate flags -- but will not clear DECL_EXTERNAL. It is up to
+ the caller to decide whether or not to clear DECL_EXTERNAL. Some
+ callers defer that decision until it is clear that DECL is actually
+ required. */