Index: test/CodeGenCXX/extern-c.cpp
===================================================================
--- test/CodeGenCXX/extern-c.cpp	(revision 178740)
+++ test/CodeGenCXX/extern-c.cpp	(working copy)
@@ -36,3 +36,30 @@
   extern "C" X test2_b;
   X test2_b;
 }
+
+extern "C" {
+  static int unused_var;
+  static int unused_fn() { return 0; }
+
+  __attribute__((used)) static int internal_var;
+  __attribute__((used)) static int internal_fn() { return 0; }
+
+  __attribute__((used)) static int duplicate_internal_var;
+  __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+
+  namespace N {
+    __attribute__((used)) static int duplicate_internal_var;
+    __attribute__((used)) static int duplicate_internal_fn() { return 0; }
+  }
+
+  // CHECK: @llvm.used = appending global {{.*}} @internal_var {{.*}} @internal_fn 
+
+  // CHECK-NOT: @unused
+  // CHECK-NOT: @duplicate_internal
+  // CHECK: @internal_var = alias internal i32* @_Z12internal_var
+  // CHECK-NOT: @unused
+  // CHECK-NOT: @duplicate_internal
+  // CHECK: @internal_fn = alias internal i32 ()* @_Z11internal_fnv
+  // CHECK-NOT: @unused
+  // CHECK-NOT: @duplicate_internal
+}
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 178740)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -186,6 +186,7 @@
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
+  EmitStaticExternCAliases();
   EmitLLVMUsed();
 
   if (CodeGenOpts.ModulesAutolink) {
@@ -1693,6 +1694,39 @@
   return AddrSpace;
 }
 
+template<typename SomeDecl>
+void CodeGenModule::MaybeHandleStaticInExternC(const SomeDecl *D,
+                                               llvm::GlobalValue *GV) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // Must have 'used' attribute, or else inline assembly can't rely on
+  // the name existing.
+  if (!D->template hasAttr<UsedAttr>())
+    return;
+
+  // Must have internal linkage and an ordinary name.
+  if (!D->getIdentifier() || D->getLinkage() != InternalLinkage)
+    return;
+
+  // Must be in an extern "C" context. Entities declared directly within
+  // a record are not extern "C" even if the record is in such a context.
+  const DeclContext *DC = D->getFirstDeclaration()->getDeclContext();
+  if (DC->isRecord() || !DC->isExternCContext())
+    return;
+
+  // OK, this is an internal linkage entity inside an extern "C" linkage
+  // specification. Make a note of that so we can give it the "expected"
+  // mangled name if nothing else is using that name.
+  StaticExternCMap::iterator I =
+      StaticExternCValues.insert(std::make_pair(D->getIdentifier(), GV)).first;
+
+  // If we have multiple internal linkage entities with the same name
+  // in extern "C" regions, none of them gets that name.
+  if (I->second != GV)
+    I->second = 0;
+}
+
 void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
   llvm::Constant *Init = 0;
   QualType ASTTy = D->getType();
@@ -1791,6 +1825,8 @@
     cast<llvm::GlobalValue>(Entry)->eraseFromParent();
   }
 
+  MaybeHandleStaticInExternC(D, GV);
+
   if (D->hasAttr<AnnotateAttr>())
     AddGlobalAnnotations(D, GV);
 
@@ -2069,6 +2105,8 @@
   // FIXME: this is redundant with part of SetFunctionDefinitionAttributes
   setGlobalVisibility(Fn, D);
 
+  MaybeHandleStaticInExternC(D, Fn);
+
   CodeGenFunction(*this).GenerateCode(D, Fn, FI);
 
   SetFunctionDefinitionAttributes(D, Fn);
@@ -2889,6 +2927,21 @@
   GlobalMetadata->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
 }
 
+/// For each function which is declared within an extern "C" region and marked
+/// as 'used', but has internal linkage, create an alias from the unmangled
+/// name to the mangled name if possible. People expect to be able to refer
+/// to such functions with an unmangled name from inline assembly within the
+/// same translation unit.
+void CodeGenModule::EmitStaticExternCAliases() {
+  for (StaticExternCMap::iterator I = StaticExternCValues.begin(),
+                                  E = StaticExternCValues.end();
+       I != E; ++I)
+    if (I->second && !getModule().getNamedValue(I->first->getName()))
+      AddUsedGlobal(
+        new llvm::GlobalAlias(I->second->getType(), I->second->getLinkage(),
+                              I->first->getName(), I->second, &getModule()));
+}
+
 /// Emits metadata nodes associating all the global values in the
 /// current module with the Decls they came from.  This is useful for
 /// projects using IR gen as a subroutine.
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h	(revision 178740)
+++ lib/CodeGen/CodeGenModule.h	(working copy)
@@ -305,6 +305,12 @@
   llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
   llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
 
+  /// Map used to track internal linkage functions declared within
+  /// extern "C" regions.
+  typedef llvm::DenseMap<IdentifierInfo *,
+                         llvm::GlobalValue *> StaticExternCMap;
+  StaticExternCMap StaticExternCValues;
+
   /// CXXGlobalInits - Global variables with initializers that need to run
   /// before main.
   std::vector<llvm::Constant*> CXXGlobalInits;
@@ -731,6 +737,12 @@
   // variable has been instantiated.
   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
 
+  /// \brief If the declaration has internal linkage but is inside an
+  /// extern "C" linkage specification, prepare to emit an alias for it
+  /// to the expected name.
+  template<typename SomeDecl>
+  void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV);
+
   /// AddUsedGlobal - Add a global which should be forced to be
   /// present in the object file; these are emitted to the llvm.used
   /// metadata global.
@@ -1043,6 +1055,10 @@
   /// \brief Emit the link options introduced by imported modules.
   void EmitModuleLinkOptions();
 
+  /// \brief Emit aliases for internal-linkage declarations inside "C" language
+  /// linkage specifications, giving them the "expected" name where possible.
+  void EmitStaticExternCAliases();
+
   void EmitDeclMetadata();
 
   /// EmitCoverageFile - Emit the llvm.gcov metadata used to tell LLVM where
