diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
new file mode 100644
index 0000000..a97ac58
--- /dev/null
+++ b/lib/CodeGen/Mangle.cpp
@@ -0,0 +1,516 @@
+//===--------------------- Mangle.cpp - Mangle C++ Names ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements C++ name mangling according to the Itanium C++ ABI,
+// which is used in GCC 3.2 and newer (and many compilers that are
+// ABI-compatible with GCC):
+//
+//   http://www.codesourcery.com/public/cxx-abi/abi.html
+//
+//===----------------------------------------------------------------------===//
+#include "Mangle.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+  class VISIBILITY_HIDDEN CXXNameMangler {
+    ASTContext &Context;
+    llvm::raw_ostream &Out;
+
+  public:
+    CXXNameMangler(ASTContext &C, llvm::raw_ostream &os)
+      : Context(C), Out(os) { }
+
+    bool mangle(const NamedDecl *D);
+    void mangleFunctionEncoding(const FunctionDecl *FD);
+    void mangleName(const NamedDecl *ND);
+    void mangleUnqualifiedName(const NamedDecl *ND);
+    void mangleSourceName(const IdentifierInfo *II);
+    void mangleNestedName(const NamedDecl *ND);
+    void manglePrefix(const DeclContext *DC);
+    void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
+    void mangleCVQualifiers(unsigned Quals);
+    void mangleType(QualType T);
+    void mangleType(const BuiltinType *T);
+    void mangleType(const FunctionType *T);
+    void mangleBareFunctionType(const FunctionType *T, bool MangleReturnType);
+    void mangleType(const TagType *T);
+    void mangleType(const ArrayType *T);
+    void mangleType(const MemberPointerType *T);
+    void mangleType(const TemplateTypeParmType *T);
+    void mangleExpression(Expr *E);
+  };
+}
+
+
+bool CXXNameMangler::mangle(const NamedDecl *D) {
+  // <mangled-name> ::= _Z <encoding>
+  //            ::= <data name>
+  //            ::= <special-name>
+
+  // FIXME: Actually use a visitor to decode these?
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    bool RequiresMangling = false;
+    // Clang's "overloadable" attribute extension to C/C++
+    if (FD->getAttr<OverloadableAttr>())
+      RequiresMangling = true;
+    else if (Context.getLangOptions().CPlusPlus) {
+      RequiresMangling = true;
+      if (isa<LinkageSpecDecl>(FD->getDeclContext()) &&
+          cast<LinkageSpecDecl>(FD->getDeclContext())->getLanguage() 
+            == LinkageSpecDecl::lang_c) {
+        // Entities with C linkage are not mangled.
+        RequiresMangling = false;
+      } 
+    }
+
+    if (RequiresMangling) {
+      Out << "_Z";
+      mangleFunctionEncoding(FD);
+      return true;
+    }
+  } 
+
+  return false;
+}
+
+void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
+  // <encoding> ::= <function name> <bare-function-type>
+  mangleName(FD);
+  mangleBareFunctionType(FD->getType()->getAsFunctionType(), false);
+}
+
+static bool isStdNamespace(const DeclContext *DC) {
+  if (!DC->isNamespace() || !DC->getParent()->isTranslationUnit())
+    return false;
+
+  const NamespaceDecl *NS = cast<NamespaceDecl>(DC);
+  const IdentifierInfo *Name = NS->getIdentifier();
+  if (Name->getLength() != 3)
+    return false;
+
+  const char *Str = Name->getName();
+  if (Str[0] != 's' || Str[1] != 't' || Str[2] != 'd')
+    return false;
+      
+  return true;
+}
+
+void CXXNameMangler::mangleName(const NamedDecl *ND) {
+  //  <name> ::= <nested-name>
+  //         ::= <unscoped-name>
+  //         ::= <unscoped-template-name> <template-args>
+  //         ::= <local-name>     # See Scope Encoding below
+  //
+  //  <unscoped-name> ::= <unqualified-name>
+  //                  ::= St <unqualified-name>   # ::std::
+  if (ND->getDeclContext()->isTranslationUnit()) 
+    mangleUnqualifiedName(ND);
+  else if (isStdNamespace(ND->getDeclContext())) {
+    Out << "St";
+    mangleUnqualifiedName(ND);
+  } else {
+    mangleNestedName(ND);
+  }
+}
+
+void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
+  //  <unqualified-name> ::= <operator-name>
+  //                     ::= <ctor-dtor-name>  
+  //                     ::= <source-name>   
+  DeclarationName Name = ND->getDeclName();
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    mangleSourceName(Name.getAsIdentifierInfo());
+    break;
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    assert(false && "Can't mangle Objective-C selector names here!");
+    break;
+
+  case DeclarationName::CXXConstructorName:
+    // <ctor-dtor-name> ::= C1  # complete object constructor
+    //                  ::= C2  # base object constructor
+    //                  ::= C3  # complete object allocating constructor
+    //
+    // FIXME: We don't even have all of these constructors
+    // in the AST yet.
+    Out << "C1";
+    break;
+
+  case DeclarationName::CXXDestructorName:
+    // <ctor-dtor-name> ::= D0  # deleting destructor
+    //                  ::= D1  # complete object destructor
+    //                  ::= D2  # base object destructor
+    //
+    // FIXME: We don't even have all of these destructors in the AST
+    // yet.
+    Out << "D0";
+    break;
+
+  case DeclarationName::CXXConversionFunctionName:
+    assert(false && "Not sure how to mangle conversion functions yet");
+    break;
+
+  case DeclarationName::CXXOperatorName:
+    mangleOperatorName(Name.getCXXOverloadedOperator(),
+                       cast<FunctionDecl>(ND)->getNumParams());
+    break;
+
+  case DeclarationName::CXXUsingDirective:
+    assert(false && "Can't mangle a using directive name!");
+  }
+}
+
+void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
+  // <source-name> ::= <positive length number> <identifier>
+  // <number> ::= [n] <non-negative decimal integer>
+  // <identifier> ::= <unqualified source code identifier>
+  Out << II->getLength() << II->getName();
+}
+
+void CXXNameMangler::mangleNestedName(const NamedDecl *ND) {
+  // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
+  //               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+  // FIXME: no template support
+  Out << 'N';
+  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
+    mangleCVQualifiers(Method->getTypeQualifiers());
+  manglePrefix(ND->getDeclContext());
+  mangleUnqualifiedName(ND);
+  Out << 'E';
+}
+
+void CXXNameMangler::manglePrefix(const DeclContext *DC) {
+  //  <prefix> ::= <prefix> <unqualified-name>
+  //           ::= <template-prefix> <template-args>
+  //           ::= <template-param>
+  //           ::= # empty
+  //           ::= <substitution>
+  // FIXME: We only handle mangling of namespaces and classes at the moment.
+  if (DC->getParent() != DC)
+    manglePrefix(DC);
+
+  if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC))
+    mangleSourceName(Namespace->getIdentifier());
+  else if (const RecordDecl *Record = dyn_cast<RecordDecl>(DC))
+    mangleSourceName(Record->getIdentifier());
+}
+
+void 
+CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
+  switch (OO) {
+  // <operator-name> ::= nw     # new           
+  case OO_New: Out << "nw"; break;
+  //              ::= na        # new[]
+  case OO_Array_New: Out << "na"; break;
+  //              ::= dl        # delete     
+  case OO_Delete: Out << "dl"; break;
+  //              ::= da        # delete[]      
+  case OO_Array_Delete: Out << "da"; break;
+  //              ::= ps        # + (unary)
+  //              ::= pl        # +
+  case OO_Plus: Out << (Arity == 1? "ps" : "pl"); break;
+  //              ::= ng        # - (unary)     
+  //              ::= mi        # -             
+  case OO_Minus: Out << (Arity == 1? "ng" : "mi"); break;
+  //              ::= ad        # & (unary)     
+  //              ::= an        # &             
+  case OO_Amp: Out << (Arity == 1? "ad" : "an"); break;
+  //              ::= de        # * (unary)     
+  //              ::= ml        # *             
+  case OO_Star: Out << (Arity == 1? "de" : "ml"); break;
+  //              ::= co        # ~             
+  case OO_Tilde: Out << "co"; break;
+  //              ::= dv        # /             
+  case OO_Slash: Out << "dv"; break;
+  //              ::= rm        # %             
+  case OO_Percent: Out << "rm"; break;
+  //              ::= or        # |   
+  case OO_Pipe: Out << "or"; break;          
+  //              ::= eo        # ^             
+  case OO_Caret: Out << "eo"; break;
+  //              ::= aS        # = 
+  case OO_Equal: Out << "aS"; break;
+  //              ::= pL        # +=            
+  case OO_PlusEqual: Out << "pL"; break;
+  //              ::= mI        # -=   
+  case OO_MinusEqual: Out << "mI"; break;
+  //              ::= mL        # *=     
+  case OO_StarEqual: Out << "mL"; break;
+  //              ::= dV        # /=    
+  case OO_SlashEqual: Out << "dV"; break;
+  //              ::= rM        # %=     
+  case OO_PercentEqual: Out << "rM"; break;       
+  //              ::= aN        # &=       
+  case OO_AmpEqual: Out << "aN"; break;     
+  //              ::= oR        # |=   
+  case OO_PipeEqual: Out << "oR"; break;         
+  //              ::= eO        # ^=      
+  case OO_CaretEqual: Out << "eO"; break;      
+  //              ::= ls        # <<     
+  case OO_LessLess: Out << "ls"; break;
+  //              ::= rs        # >>   
+  case OO_GreaterGreater: Out << "rs"; break;         
+  //              ::= lS        # <<=        
+  case OO_LessLessEqual: Out << "lS"; break;   
+  //              ::= rS        # >>=       
+  case OO_GreaterGreaterEqual: Out << "rS"; break;    
+  //              ::= eq        # ==
+  case OO_EqualEqual: Out << "eq"; break;
+  //              ::= ne        # !=     
+  case OO_ExclaimEqual: Out << "ne"; break;       
+  //              ::= lt        # <        
+  case OO_Less: Out << "lt"; break;
+  //              ::= gt        # >             
+  case OO_Greater: Out << "gt"; break;
+  //              ::= le        # <=  
+  case OO_LessEqual: Out << "le"; break;
+  //              ::= ge        # >=    
+  case OO_GreaterEqual: Out << "ge"; break;
+  //              ::= nt        # !        
+  case OO_Exclaim: Out << "nt"; break;
+  //              ::= aa        # &&  
+  case OO_AmpAmp: Out << "aa"; break;
+  //              ::= oo        # || 
+  case OO_PipePipe: Out << "oo"; break;           
+  //              ::= pp        # ++   
+  case OO_PlusPlus: Out << "pp"; break;         
+  //              ::= mm        # --   
+  case OO_MinusMinus: Out << "mm"; break;
+  //              ::= cm        # ,      
+  case OO_Comma: Out << "cm"; break;       
+  //              ::= pm        # ->*      
+  case OO_ArrowStar: Out << "pm"; break;
+  //              ::= pt        # ->    
+  case OO_Arrow: Out << "pt"; break;
+  //              ::= cl        # ()            
+  case OO_Call: Out << "cl"; break;
+  //              ::= ix        # []            
+  case OO_Subscript: Out << "ix"; break;
+  // UNSUPPORTED: ::= qu        # ?
+
+  case OO_None: 
+  case NUM_OVERLOADED_OPERATORS:
+    assert(false && "Not an ovelroaded operator"); 
+    break;
+  }
+}
+
+void CXXNameMangler::mangleCVQualifiers(unsigned Quals) {
+  // <CV-qualifiers> ::= [r] [V] [K] 	# restrict (C99), volatile, const
+  if (Quals & QualType::Restrict)
+    Out << 'r';
+  if (Quals & QualType::Volatile)
+    Out << 'V';
+  if (Quals & QualType::Const)
+    Out << 'K';
+}
+
+void CXXNameMangler::mangleType(QualType T) {
+  // Only operate on the canonical type!
+  T = Context.getCanonicalType(T);
+
+  // FIXME: Should we have a TypeNodes.def to make this easier? (YES!)
+
+  //  <type> ::= <CV-qualifiers> <type>
+  mangleCVQualifiers(T.getCVRQualifiers());
+
+  //         ::= <builtin-type>
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
+    mangleType(BT);
+  //         ::= <function-type>
+  else if (const FunctionType *FT = dyn_cast<FunctionType>(T.getTypePtr()))
+    mangleType(FT);
+  //         ::= <class-enum-type>
+  else if (const TagType *TT = dyn_cast<TagType>(T.getTypePtr()))
+    mangleType(TT);
+  //         ::= <array-type>
+  else if (const ArrayType *AT = dyn_cast<ArrayType>(T.getTypePtr()))
+    mangleType(AT);
+  //         ::= <pointer-to-member-type>
+  else if (const MemberPointerType *MPT 
+             = dyn_cast<MemberPointerType>(T.getTypePtr()))
+    mangleType(MPT);
+  //         ::= <template-param>
+  else if (const TemplateTypeParmType *TypeParm 
+             = dyn_cast<TemplateTypeParmType>(T.getTypePtr()))
+    mangleType(TypeParm);
+  //  FIXME: ::= <template-template-param> <template-args>
+  //  FIXME: ::= <substitution> # See Compression below
+  //         ::= P <type>   # pointer-to
+  else if (const PointerType *PT = dyn_cast<PointerType>(T.getTypePtr())) {
+    Out << 'P';
+    mangleType(PT->getPointeeType());
+  }
+  //         ::= R <type>   # reference-to
+  //         ::= O <type>   # rvalue reference-to (C++0x)
+  else if (const ReferenceType *RT = dyn_cast<ReferenceType>(T.getTypePtr())) {
+    // FIXME: rvalue references
+    Out << 'R';
+    mangleType(RT->getPointeeType());
+  }
+  //         ::= C <type>   # complex pair (C 2000)
+  else if (const ComplexType *CT = dyn_cast<ComplexType>(T.getTypePtr())) {
+    Out << 'C';
+    mangleType(CT->getElementType());
+  } else if (const VectorType *VT = dyn_cast<VectorType>(T.getTypePtr())) {
+    // GNU extension: vector types
+    Out << "U8__vector";
+    mangleType(VT->getElementType());
+  }
+  // FIXME:  ::= G <type>   # imaginary (C 2000)
+  // FIXME:  ::= U <source-name> <type>     # vendor extended type qualifier
+  else
+    assert(false && "Cannot mangle unknown type");
+}
+
+void CXXNameMangler::mangleType(const BuiltinType *T) {
+  //  <builtin-type> ::= v  # void
+  //                 ::= w  # wchar_t
+  //                 ::= b  # bool
+  //                 ::= c  # char
+  //                 ::= a  # signed char
+  //                 ::= h  # unsigned char
+  //                 ::= s  # short
+  //                 ::= t  # unsigned short
+  //                 ::= i  # int
+  //                 ::= j  # unsigned int
+  //                 ::= l  # long
+  //                 ::= m  # unsigned long
+  //                 ::= x  # long long, __int64
+  //                 ::= y  # unsigned long long, __int64
+  //                 ::= n  # __int128
+  // UNSUPPORTED:    ::= o  # unsigned __int128
+  //                 ::= f  # float
+  //                 ::= d  # double
+  //                 ::= e  # long double, __float80
+  // UNSUPPORTED:    ::= g  # __float128
+  // NOT HERE:       ::= z  # ellipsis
+  // UNSUPPORTED:    ::= Dd # IEEE 754r decimal floating point (64 bits)
+  // UNSUPPORTED:    ::= De # IEEE 754r decimal floating point (128 bits)
+  // UNSUPPORTED:    ::= Df # IEEE 754r decimal floating point (32 bits)
+  // UNSUPPORTED:    ::= Dh # IEEE 754r half-precision floating point (16 bits)
+  // UNSUPPORTED:    ::= Di # char32_t
+  // UNSUPPORTED:    ::= Ds # char16_t
+  //                 ::= u <source-name>    # vendor extended type
+  switch (T->getKind()) {
+  case BuiltinType::Void: Out << 'v'; break;
+  case BuiltinType::Bool: Out << 'b'; break;
+  case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'c'; break;
+  case BuiltinType::UChar: Out << 'h'; break;
+  case BuiltinType::UShort: Out << 't'; break;
+  case BuiltinType::UInt: Out << 'j'; break;
+  case BuiltinType::ULong: Out << 'm'; break;
+  case BuiltinType::ULongLong: Out << 'y'; break;
+  case BuiltinType::SChar: Out << 'a'; break;
+  case BuiltinType::WChar: Out << 'w'; break;
+  case BuiltinType::Short: Out << 's'; break;
+  case BuiltinType::Int: Out << 'i'; break;
+  case BuiltinType::Long: Out << 'l'; break;
+  case BuiltinType::LongLong: Out << 'x'; break;
+  case BuiltinType::Float: Out << 'f'; break;
+  case BuiltinType::Double: Out << 'd'; break;
+  case BuiltinType::LongDouble: Out << 'e'; break;
+
+  case BuiltinType::Overload:
+  case BuiltinType::Dependent:
+    assert(false && 
+           "Overloaded and dependent types shouldn't get to name mangling");
+    break;
+  }
+}
+
+void CXXNameMangler::mangleType(const FunctionType *T) {
+  // <function-type> ::= F [Y] <bare-function-type> E
+  Out << 'F';
+  // FIXME: We don't have enough information in the AST to produce the
+  // 'Y' encoding for extern "C" function types.
+  mangleBareFunctionType(T, /*MangleReturnType=*/true);
+  Out << 'E';
+}
+
+void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
+                                            bool MangleReturnType) {
+  // <bare-function-type> ::= <signature type>+
+  if (MangleReturnType)
+    mangleType(T->getResultType());
+
+  const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(T);
+  assert(Proto && "Can't mangle K&R function prototypes");
+
+  for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(),
+                                         ArgEnd = Proto->arg_type_end(); 
+       Arg != ArgEnd; ++Arg)
+    mangleType(*Arg);
+}
+
+void CXXNameMangler::mangleType(const TagType *T) {
+  //  <class-enum-type> ::= <name>
+  mangleName(T->getDecl());
+}
+
+void CXXNameMangler::mangleType(const ArrayType *T) {
+  // <array-type> ::= A <positive dimension number> _ <element type>
+  //              ::= A [<dimension expression>] _ <element type>
+  Out << 'A';
+  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T))
+    Out << CAT->getSize();
+  else if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(T))
+    mangleExpression(VAT->getSizeExpr());
+  else if (const DependentSizedArrayType *DSAT 
+             = dyn_cast<DependentSizedArrayType>(T))
+    mangleExpression(DSAT->getSizeExpr());
+
+  Out << '_';
+  mangleType(T->getElementType());
+}
+
+void CXXNameMangler::mangleType(const MemberPointerType *T) {
+  //  <pointer-to-member-type> ::= M <class type> <member type>
+  Out << 'M';
+  mangleType(QualType(T->getClass(), 0));
+  mangleType(T->getPointeeType());
+}
+
+void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
+  // <template-param> ::= T_    # first template parameter
+  //                  ::= T <parameter-2 non-negative number> _
+  if (T->getIndex() == 0)
+    Out << "T_";
+  else
+    Out << 'T' << (T->getIndex() - 1) << '_';
+}
+
+void CXXNameMangler::mangleExpression(Expr *E) {
+  assert(false && "Cannot mangle expressions yet");
+}
+
+namespace clang {
+  /// \brief Mangles the name of the declaration D and emits that name
+  /// to the given output stream.
+  ///
+  /// If the declaration D requires a mangled name, this routine will
+  /// emit that mangled name to \p os and return true. Otherwise, \p
+  /// os will be unchanged and this routine will return false. In this
+  /// case, the caller should just emit the identifier of the declaration
+  /// (\c D->getIdentifier()) as its name.
+  bool mangleName(const NamedDecl *D, ASTContext &Context, 
+                  llvm::raw_ostream &os) {
+    CXXNameMangler Mangler(Context, os);
+    return Mangler.mangle(D);
+  }
+}
+
