Fix the rest of PR9316 along with some other bugs spotted by inspection.
I tried to add test cases for these, but I can't because variables
aren't warned on the way functions are and the codegen layer appears to
use different logic for determining that 'a' and 'g' in the test case
should receive C mangling. I've included the test so that if we ever
switch the codegen layer to use these functions, we won't regress due to
latent bugs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126453 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index b482a03..c0300c5 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -708,7 +708,7 @@
   //   external linkage.
   if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
-      if (Function->isInAnonymousNamespace())
+      if (Function->isInAnonymousNamespace() && !Function->isExternC())
         return LinkageInfo::uniqueExternal();
 
       LinkageInfo LV;
@@ -729,7 +729,7 @@
     if (const VarDecl *Var = dyn_cast<VarDecl>(D))
       if (Var->getStorageClass() == SC_Extern ||
           Var->getStorageClass() == SC_PrivateExtern) {
-        if (Var->isInAnonymousNamespace())
+        if (Var->isInAnonymousNamespace() && !Var->isExternC())
           return LinkageInfo::uniqueExternal();
 
         LinkageInfo LV;
@@ -1041,8 +1041,11 @@
             getStorageClass() != SC_Static) ||
       (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
 
-  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
-       DC = DC->getParent()) {
+  const DeclContext *DC = getDeclContext();
+  if (DC->isFunctionOrMethod())
+    return false;
+
+  for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
         return getStorageClass() != SC_Static;
@@ -1050,8 +1053,6 @@
       break;
     }
 
-    if (DC->isFunctionOrMethod())
-      return false;
   }
 
   return false;
@@ -1367,8 +1368,11 @@
   if (!Context.getLangOptions().CPlusPlus)
     return getStorageClass() != SC_Static && !getAttr<OverloadableAttr>();
 
-  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
-       DC = DC->getParent()) {
+  const DeclContext *DC = getDeclContext();
+  if (DC->isRecord())
+    return false;
+
+  for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
         return getStorageClass() != SC_Static &&
@@ -1376,9 +1380,6 @@
 
       break;
     }
-    
-    if (DC->isRecord())
-      break;
   }
 
   return isMain();