diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index bb75895..12b6c4a 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -903,6 +903,12 @@ public:
   /// external, C linkage.
   bool isExternC() const;
 
+  /// Checks if this variable has C language linkage. Note that this is not the
+  /// same as isExternC since decls with non external linkage can have C
+  /// language linkage. They can also have C language linkage when they are not
+  /// declared in an extern C context, but a previous decl is.
+  bool hasCLanguageLinkage() const;
+
   /// isLocalVarDecl - Returns true for local variable declarations
   /// other than parameters.  Note that this includes static variables
   /// inside of functions. It also includes variables inside blocks.
@@ -1790,6 +1796,12 @@ public:
   /// external, C linkage.
   bool isExternC() const;
 
+  /// Checks if this function has C language linkage. Note that this is not the
+  /// same as isExternC since decls with non external linkage can have C
+  /// language linkage. They can also have C language linkage when they are not
+  /// declared in an extern C context, but a previous decl is.
+  bool hasCLanguageLinkage() const;
+
   /// \brief Determines whether this is a global function.
   bool isGlobal() const;
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 85ab002..497f02a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -268,8 +268,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
   if (D->isInAnonymousNamespace()) {
     const VarDecl *Var = dyn_cast<VarDecl>(D);
     const FunctionDecl *Func = dyn_cast<FunctionDecl>(D);
-    if ((!Var || !Var->getDeclContext()->isExternCContext()) &&
-        (!Func || !Func->getDeclContext()->isExternCContext()))
+    if ((!Var || !Var->hasCLanguageLinkage()) &&
+        (!Func || !Func->hasCLanguageLinkage()))
       return LinkageInfo::uniqueExternal();
   }
 
@@ -634,6 +634,31 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const {
   CachedLinkage = LV.linkage();
   CacheValidAndVisibility = LV.visibility() + 1;
   CachedVisibilityExplicit = LV.visibilityExplicit();
+
+#ifndef NDEBUG
+  // In C (because of gnu inline) and in c++ with microsoft extensions an
+  // static can follow an extern, so we can have two decls with different
+  // linkages.
+  const LangOptions &Opts = getASTContext().getLangOpts();
+  if (!Opts.CPlusPlus || Opts.MicrosoftExt)
+    return LV;
+
+  // We have just computed the linkage for this decl. By induction we know
+  // that all other computed linkages match, check that the one we just computed
+  // also does.
+  NamedDecl *D = NULL;
+  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+    NamedDecl *T = cast<NamedDecl>(*I);
+    if (T == this)
+      continue;
+    if (T->CacheValidAndVisibility != 0) {
+      D = T;
+      break;
+    }
+  }
+  assert(!D || D->CachedLinkage == CachedLinkage);
+#endif
+
   return LV;
 }
 
@@ -772,7 +797,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D, bool OnlyTemplate) {
   //   one such matching entity, the program is ill-formed. Otherwise,
   //   if no matching entity is found, the block scope entity receives
   //   external linkage.
-  if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
+  if (D->getDeclContext()->isFunctionOrMethod()) {
     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
       if (Function->isInAnonymousNamespace() &&
           !Function->getDeclContext()->isExternCContext())
@@ -1177,6 +1202,32 @@ SourceRange VarDecl::getSourceRange() const {
   return DeclaratorDecl::getSourceRange();
 }
 
+template<typename decl_type>
+static bool hasCLanguageLinkageTemplate(const decl_type &D) {
+  // Language linkage is a C++ concept, but saying that everything in C has
+  // C language linkage fits the implementation nicelly.
+  ASTContext &Context = D.getASTContext();
+  if (!Context.getLangOpts().CPlusPlus)
+    return true;
+
+  // dcl.link 4: A C language linkage is ignored in determining the language
+  // linkage of the names of class members and the function type of class member
+  // functions.
+  const DeclContext *DC = D.getDeclContext();
+  if (DC->isRecord())
+    return false;
+
+  // If the first decl is in an extern "C" context, any other redeclaration
+  // will have C language linkage. If the first one is not in an extern "C"
+  // context, we would have reported an error for any other decl being in one.
+  const decl_type *First = D.getFirstDeclaration();
+  return First->getDeclContext()->isExternCContext();
+}
+
+bool VarDecl::hasCLanguageLinkage() const {
+  return hasCLanguageLinkageTemplate(*this);
+}
+
 bool VarDecl::isExternC() const {
   if (getLinkage() != ExternalLinkage)
     return false;
@@ -1702,6 +1753,10 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
   return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
 }
 
+bool FunctionDecl::hasCLanguageLinkage() const {
+  return hasCLanguageLinkageTemplate(*this);
+}
+
 bool FunctionDecl::isExternC() const {
   if (getLinkage() != ExternalLinkage)
     return false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7c193e1..c9d0c77 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1969,32 +1969,6 @@ static bool isABIDefaultCC(Sema &S, CallingConv CC, FunctionDecl *D) {
   return ABIDefaultCC == CC;
 }
 
-/// Check if the given decl has C language linkage. Note that this is not
-/// the same as D.isExternC() since decls with non external linkage can have C
-/// language linkage. They can also have C language linkage when they are
-/// not declared in an extern C context, but a previous decl is.
-template<typename T>
-bool hasCLanguageLinkage(const T &D) {
-  // Language linkage is a C++ concept, but saying that everything in C has
-  // C language linkage fits the implementation nicelly.
-  ASTContext &Context = D.getASTContext();
-  if (!Context.getLangOpts().CPlusPlus)
-    return true;
-
-  // dcl.link 4: A C language linkage is ignored in determining the language
-  // linkage of the names of class members and the function type of class member
-  // functions.
-  const DeclContext *DC = D.getDeclContext();
-  if (DC->isRecord())
-    return false;
-
-  // If the first decl is in an extern "C" context, any other redeclaration
-  // will have C language linkage. If the first one is not in an extern "C"
-  // context, we would have reported an error for any other decl being in one.
-  const T *First = D.getFirstDeclaration();
-  return First->getDeclContext()->isExternCContext();
-}
-
 /// MergeFunctionDecl - We just parsed a function 'New' from
 /// declarator D which has the same name and scope as a previous
 /// declaration 'Old'.  Figure out how to resolve this situation,
@@ -2255,7 +2229,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
       assert(OldQTypeForComparison.isCanonical());
     }
 
-    if (!hasCLanguageLinkage(*Old) && hasCLanguageLinkage(*New)) {
+    if (!Old->hasCLanguageLinkage() && New->hasCLanguageLinkage()) {
       Diag(New->getLocation(), diag::err_different_language_linkage) << New;
       Diag(Old->getLocation(), PrevDiag);
       return true;
@@ -2645,7 +2619,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
     return;
   }
 
-  if (!hasCLanguageLinkage(*Old) && hasCLanguageLinkage(*New)) {
+  if (!Old->hasCLanguageLinkage() && New->hasCLanguageLinkage()) {
     Diag(New->getLocation(), diag::err_different_language_linkage) << New;
     Diag(Old->getLocation(), diag::note_previous_definition);
     New->setInvalidDecl();
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index ccf3200..b4ceae7 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -11,3 +11,25 @@ namespace test1 {
     void f(); // expected-error {{declaration of 'f' has a different language linkage}}
   }
 }
+
+namespace test2 {
+  extern "C" {
+    namespace {
+      extern int x2;
+      void f2();
+    }
+  }
+  namespace {
+    int x2;
+    void f2() {}
+  }
+}
+
+namespace test3 {
+  void dummy() {
+    void Bar();
+    class A {
+      friend void Bar();
+    };
+  }
+}
