Add support for -fvisibility-ms-compat.

We treat this as an alternative to -fvisibility=<?>
which changes the default value visibility to "hidden"
and the default type visibility to "default".

Expose a -cc1 option for changing the default type
visibility, repurposing -fvisibility as the default
value visibility option (also setting type visibility
from it in the absence of a specific option).

rdar://13079314

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175480 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 0183c0b..6e93dd6 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -80,7 +80,9 @@
 /// Is the given declaration a "type" or a "value" for the purposes of
 /// visibility computation?
 static bool usesTypeVisibility(const NamedDecl *D) {
-  return isa<TypeDecl>(D) || isa<ClassTemplateDecl>(D);
+  return isa<TypeDecl>(D) ||
+         isa<ClassTemplateDecl>(D) ||
+         isa<ObjCInterfaceDecl>(D);
 }
 
 /// Return the explicit visibility of the given declaration.
@@ -440,10 +442,15 @@
 
     // Add in global settings if the above didn't give us direct visibility.
     if (!LV.visibilityExplicit()) {
-      // FIXME: type visibility
-      LV.mergeVisibility(Context.getLangOpts().getVisibilityMode(),
-                         /*explicit*/ false);
-
+      // Use global type/value visibility as appropriate.
+      Visibility globalVisibility;
+      if (computation == LVForValue) {
+        globalVisibility = Context.getLangOpts().getValueVisibilityMode();
+      } else {
+        assert(computation == LVForType);
+        globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
+      }
+      LV.mergeVisibility(globalVisibility, /*explicit*/ false);
 
       // If we're paying attention to global visibility, apply
       // -finline-visibility-hidden if this is an inline method.