Added locations and type source info for DeclarationName.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110860 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7d15926..8051dca 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2534,21 +2534,31 @@
   return false;
 }
 
-DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {
+DeclarationNameInfo ASTContext::getNameForTemplate(TemplateName Name,
+                                                   SourceLocation NameLoc) {
   if (TemplateDecl *TD = Name.getAsTemplateDecl())
-    return TD->getDeclName();
-  
+    // DNInfo work in progress: CHECKME: what about DNLoc?
+    return DeclarationNameInfo(TD->getDeclName(), NameLoc);
+
   if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
+    DeclarationName DName;
     if (DTN->isIdentifier()) {
-      return DeclarationNames.getIdentifier(DTN->getIdentifier());
+      DName = DeclarationNames.getIdentifier(DTN->getIdentifier());
+      return DeclarationNameInfo(DName, NameLoc);
     } else {
-      return DeclarationNames.getCXXOperatorName(DTN->getOperator());
+      DName = DeclarationNames.getCXXOperatorName(DTN->getOperator());
+      // DNInfo work in progress: FIXME: source locations?
+      DeclarationNameLoc DNLoc;
+      DNLoc.CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
+      DNLoc.CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
+      return DeclarationNameInfo(DName, NameLoc, DNLoc);
     }
   }
 
   OverloadedTemplateStorage *Storage = Name.getAsOverloadedTemplate();
   assert(Storage);
-  return (*Storage->begin())->getDeclName();
+  // DNInfo work in progress: CHECKME: what about DNLoc?
+  return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);
 }
 
 TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 5e8586f..8b67f77 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -81,6 +81,8 @@
     bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, 
                          DeclContext *&LexicalDC, DeclarationName &Name, 
                          SourceLocation &Loc);
+    void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
+                                  DeclarationNameInfo& To);
     void ImportDeclContext(DeclContext *FromDC);
     bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
     bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
@@ -1386,6 +1388,40 @@
   return false;
 }
 
+void
+ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
+                                          DeclarationNameInfo& To) {
+  // NOTE: To.Name and To.Loc are already imported.
+  // We only have to import To.LocInfo.
+  switch (To.getName().getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXUsingDirective:
+    return;
+
+  case DeclarationName::CXXOperatorName: {
+    SourceRange Range = From.getCXXOperatorNameRange();
+    To.setCXXOperatorNameRange(Importer.Import(Range));
+    return;
+  }
+  case DeclarationName::CXXLiteralOperatorName: {
+    SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
+    To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
+    return;
+  }
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName: {
+    TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
+    To.setNamedTypeInfo(Importer.Import(FromTInfo));
+    return;
+  }
+    assert(0 && "Unknown name kind.");
+  }
+}
+
 void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC) {
   for (DeclContext::decl_iterator From = FromDC->decls_begin(),
                                FromEnd = FromDC->decls_end();
@@ -1823,7 +1859,7 @@
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
     return 0;
-  
+
   // Try to find a function in our own ("to") context with the same name, same
   // type, and in the same context as the function we're importing.
   if (!LexicalDC->isFunctionOrMethod()) {
@@ -1872,6 +1908,10 @@
     }    
   }
 
+  DeclarationNameInfo NameInfo(Name, Loc);
+  // Import additional name location/type info.
+  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
@@ -1894,26 +1934,26 @@
   if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
     ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
                                             cast<CXXRecordDecl>(DC),
-                                            Loc, Name, T, TInfo, 
+                                            NameInfo, T, TInfo, 
                                             FromConstructor->isExplicit(),
                                             D->isInlineSpecified(), 
                                             D->isImplicit());
   } else if (isa<CXXDestructorDecl>(D)) {
     ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
                                            cast<CXXRecordDecl>(DC),
-                                           Loc, Name, T, 
+                                           NameInfo, T, 
                                            D->isInlineSpecified(),
                                            D->isImplicit());
   } else if (CXXConversionDecl *FromConversion
                                            = dyn_cast<CXXConversionDecl>(D)) {
     ToFunction = CXXConversionDecl::Create(Importer.getToContext(), 
                                            cast<CXXRecordDecl>(DC),
-                                           Loc, Name, T, TInfo,
+                                           NameInfo, T, TInfo,
                                            D->isInlineSpecified(),
                                            FromConversion->isExplicit());
   } else {
-    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc, 
-                                      Name, T, TInfo, D->getStorageClass(), 
+    ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
+                                      NameInfo, T, TInfo, D->getStorageClass(),
                                       D->getStorageClassAsWritten(),
                                       D->isInlineSpecified(),
                                       D->hasWrittenPrototype());
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 0e0bbf3..0170b08 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1706,12 +1706,11 @@
 }
 
 FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
-                                   SourceLocation L,
-                                   DeclarationName N, QualType T,
-                                   TypeSourceInfo *TInfo,
+                                   const DeclarationNameInfo &NameInfo,
+                                   QualType T, TypeSourceInfo *TInfo,
                                    StorageClass S, StorageClass SCAsWritten,
                                    bool isInline, bool hasWrittenPrototype) {
-  FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+  FunctionDecl *New = new (C) FunctionDecl(Function, DC, NameInfo, T, TInfo,
                                            S, SCAsWritten, isInline);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index d1ef3b1..75b3558 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -619,10 +619,10 @@
 
 CXXMethodDecl *
 CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                      SourceLocation L, DeclarationName N,
+                      const DeclarationNameInfo &NameInfo,
                       QualType T, TypeSourceInfo *TInfo,
                       bool isStatic, StorageClass SCAsWritten, bool isInline) {
-  return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
+  return new (C) CXXMethodDecl(CXXMethod, RD, NameInfo, T, TInfo,
                                isStatic, SCAsWritten, isInline);
 }
 
@@ -818,20 +818,21 @@
 
 CXXConstructorDecl *
 CXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
-  return new (C) CXXConstructorDecl(0, SourceLocation(), DeclarationName(),
+  return new (C) CXXConstructorDecl(0, DeclarationNameInfo(),
                                     QualType(), 0, false, false, false);
 }
 
 CXXConstructorDecl *
 CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                           SourceLocation L, DeclarationName N,
+                           const DeclarationNameInfo &NameInfo,
                            QualType T, TypeSourceInfo *TInfo,
                            bool isExplicit,
                            bool isInline,
                            bool isImplicitlyDeclared) {
-  assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
-  return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit,
+  return new (C) CXXConstructorDecl(RD, NameInfo, T, TInfo, isExplicit,
                                     isInline, isImplicitlyDeclared);
 }
 
@@ -926,34 +927,38 @@
 
 CXXDestructorDecl *
 CXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
-  return new (C) CXXDestructorDecl(0, SourceLocation(), DeclarationName(),
+  return new (C) CXXDestructorDecl(0, DeclarationNameInfo(),
                                    QualType(), false, false);
 }
 
 CXXDestructorDecl *
 CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                          SourceLocation L, DeclarationName N,
+                          const DeclarationNameInfo &NameInfo,
                           QualType T, bool isInline,
                           bool isImplicitlyDeclared) {
-  assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXDestructorName &&
          "Name must refer to a destructor");
-  return new (C) CXXDestructorDecl(RD, L, N, T, isInline, isImplicitlyDeclared);
+  return new (C) CXXDestructorDecl(RD, NameInfo, T, isInline,
+                                   isImplicitlyDeclared);
 }
 
 CXXConversionDecl *
 CXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
-  return new (C) CXXConversionDecl(0, SourceLocation(), DeclarationName(),
+  return new (C) CXXConversionDecl(0, DeclarationNameInfo(),
                                    QualType(), 0, false, false);
 }
 
 CXXConversionDecl *
 CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
-                          SourceLocation L, DeclarationName N,
+                          const DeclarationNameInfo &NameInfo,
                           QualType T, TypeSourceInfo *TInfo,
                           bool isInline, bool isExplicit) {
-  assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+  assert(NameInfo.getName().getNameKind()
+         == DeclarationName::CXXConversionFunctionName &&
          "Name must refer to a conversion function");
-  return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit);
+  return new (C) CXXConversionDecl(RD, NameInfo, T, TInfo,
+                                   isInline, isExplicit);
 }
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index fae1e72..a42be55 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -347,7 +347,7 @@
 
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
-  std::string Proto = D->getNameAsString();
+  std::string Proto = D->getNameInfo().getAsString();
   if (isa<FunctionType>(D->getType().getTypePtr())) {
     const FunctionType *AFT = D->getType()->getAs<FunctionType>();
 
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 606ce89..860a0b2 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/DenseMap.h"
@@ -485,3 +486,98 @@
   return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
 }
 
+DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    break;
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    NamedType.TInfo = 0;
+    break;
+  case DeclarationName::CXXOperatorName:
+    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
+    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
+    break;
+  case DeclarationName::CXXLiteralOperatorName:
+    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
+    break;
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+    // FIXME: ?
+    break;
+  case DeclarationName::CXXUsingDirective:
+    break;
+  }
+}
+
+std::string DeclarationNameInfo::getAsString() const {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  printName(OS);
+  return OS.str();
+}
+
+void DeclarationNameInfo::printName(llvm::raw_ostream &OS) const {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    Name.printName(OS);
+    return;
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
+      if (Name.getNameKind() == DeclarationName::CXXDestructorName)
+        OS << '~';
+      else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
+        OS << "operator ";
+      OS << TInfo->getType().getAsString();
+    }
+    else
+      Name.printName(OS);
+    return;
+  }
+  assert(false && "Unexpected declaration name kind");
+}
+
+SourceLocation DeclarationNameInfo::getEndLoc() const {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+    return NameLoc;
+
+  case DeclarationName::CXXOperatorName: {
+    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
+    return SourceLocation::getFromRawEncoding(raw);
+  }
+
+  case DeclarationName::CXXLiteralOperatorName: {
+    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
+    return SourceLocation::getFromRawEncoding(raw);
+  }
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+      return TInfo->getTypeLoc().getEndLoc();
+    else
+      return NameLoc;
+
+    // DNInfo work in progress: FIXME.
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXUsingDirective:
+    return NameLoc;
+  }
+  assert(false && "Unexpected declaration name kind");
+  return SourceLocation();
+}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index e40fc79..c4666fa 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -209,6 +209,28 @@
   computeDependence();
 }
 
+DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
+                         SourceRange QualifierRange,
+                         ValueDecl *D, const DeclarationNameInfo &NameInfo,
+                         const TemplateArgumentListInfo *TemplateArgs,
+                         QualType T)
+  : Expr(DeclRefExprClass, T, false, false),
+    DecoratedD(D,
+               (Qualifier? HasQualifierFlag : 0) |
+               (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
+    Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
+  if (Qualifier) {
+    NameQualifier *NQ = getNameQualifier();
+    NQ->NNS = Qualifier;
+    NQ->Range = QualifierRange;
+  }
+
+  if (TemplateArgs)
+    getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
+
+  computeDependence();
+}
+
 DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
                                  NestedNameSpecifier *Qualifier,
                                  SourceRange QualifierRange,
@@ -216,6 +238,18 @@
                                  SourceLocation NameLoc,
                                  QualType T,
                                  const TemplateArgumentListInfo *TemplateArgs) {
+  return Create(Context, Qualifier, QualifierRange, D,
+                DeclarationNameInfo(D->getDeclName(), NameLoc),
+                T, TemplateArgs);
+}
+
+DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
+                                 NestedNameSpecifier *Qualifier,
+                                 SourceRange QualifierRange,
+                                 ValueDecl *D,
+                                 const DeclarationNameInfo &NameInfo,
+                                 QualType T,
+                                 const TemplateArgumentListInfo *TemplateArgs) {
   std::size_t Size = sizeof(DeclRefExpr);
   if (Qualifier != 0)
     Size += sizeof(NameQualifier);
@@ -224,7 +258,7 @@
     Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
   
   void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
-  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
+  return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo,
                                TemplateArgs, T);
 }
 
@@ -242,9 +276,7 @@
 }
 
 SourceRange DeclRefExpr::getSourceRange() const {
-  // FIXME: Does not handle multi-token names well, e.g., operator[].
-  SourceRange R(Loc);
-  
+  SourceRange R = getNameInfo().getSourceRange();
   if (hasQualifier())
     R.setBegin(getQualifierRange().getBegin());
   if (hasExplicitTemplateArgumentList())
@@ -623,7 +655,7 @@
                                SourceRange qualrange,
                                ValueDecl *memberdecl,
                                DeclAccessPair founddecl,
-                               SourceLocation l,
+                               DeclarationNameInfo nameinfo,
                                const TemplateArgumentListInfo *targs,
                                QualType ty) {
   std::size_t Size = sizeof(MemberExpr);
@@ -638,7 +670,7 @@
     Size += ExplicitTemplateArgumentList::sizeFor(*targs);
 
   void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
-  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, l, ty);
+  MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, ty);
 
   if (hasQualOrFound) {
     if (qual && qual->isDependent()) {
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 4907833..4582062 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -159,8 +159,9 @@
 UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
                              CXXRecordDecl *NamingClass,
                              NestedNameSpecifier *Qualifier,
-                             SourceRange QualifierRange, DeclarationName Name,
-                             SourceLocation NameLoc, bool ADL,
+                             SourceRange QualifierRange,
+                             const DeclarationNameInfo &NameInfo,
+                             bool ADL,
                              const TemplateArgumentListInfo &Args,
                              UnresolvedSetIterator Begin, 
                              UnresolvedSetIterator End) 
@@ -171,8 +172,8 @@
     = new (Mem) UnresolvedLookupExpr(C, 
                                      Dependent ? C.DependentTy : C.OverloadTy,
                                      Dependent, NamingClass,
-                                     Qualifier, QualifierRange,
-                                     Name, NameLoc, ADL,
+                                     Qualifier, QualifierRange, NameInfo,
+                                     ADL,
                                      /*Overload*/ true,
                                      /*ExplicitTemplateArgs*/ true,
                                      Begin, End);
@@ -196,14 +197,14 @@
 
 OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, 
                            bool Dependent, NestedNameSpecifier *Qualifier, 
-                           SourceRange QRange, DeclarationName Name, 
-                           SourceLocation NameLoc, bool HasTemplateArgs,
+                           SourceRange QRange,
+                           const DeclarationNameInfo &NameInfo,
+                           bool HasTemplateArgs,
                            UnresolvedSetIterator Begin, 
                            UnresolvedSetIterator End)
   : Expr(K, T, Dependent, Dependent),
-  Results(0), NumResults(0), Name(Name), Qualifier(Qualifier), 
-  QualifierRange(QRange), NameLoc(NameLoc), 
-  HasExplicitTemplateArgs(HasTemplateArgs)
+  Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), 
+  QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs)
 {
   initializeResults(C, Begin, End);
 }
@@ -262,8 +263,7 @@
 DependentScopeDeclRefExpr::Create(ASTContext &C,
                                   NestedNameSpecifier *Qualifier,
                                   SourceRange QualifierRange,
-                                  DeclarationName Name,
-                                  SourceLocation NameLoc,
+                                  const DeclarationNameInfo &NameInfo,
                                   const TemplateArgumentListInfo *Args) {
   std::size_t size = sizeof(DependentScopeDeclRefExpr);
   if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
@@ -272,8 +272,7 @@
   DependentScopeDeclRefExpr *DRE
     = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
                                           Qualifier, QualifierRange,
-                                          Name, NameLoc,
-                                          Args != 0);
+                                          NameInfo, Args != 0);
 
   if (Args)
     reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
@@ -291,7 +290,7 @@
   void *Mem = C.Allocate(size);
 
   return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(),
-                                             DeclarationName(),SourceLocation(),
+                                             DeclarationNameInfo(),
                                              NumTemplateArgs != 0);
 }
 
@@ -750,8 +749,7 @@
                                                  NestedNameSpecifier *Qualifier,
                                                  SourceRange QualifierRange,
                                           NamedDecl *FirstQualifierFoundInScope,
-                                                 DeclarationName Member,
-                                                 SourceLocation MemberLoc,
+                                          DeclarationNameInfo MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs)
   : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
     Base(Base), BaseType(BaseType), IsArrow(IsArrow),
@@ -759,7 +757,7 @@
     OperatorLoc(OperatorLoc),
     Qualifier(Qualifier), QualifierRange(QualifierRange),
     FirstQualifierFoundInScope(FirstQualifierFoundInScope),
-    Member(Member), MemberLoc(MemberLoc) {
+    MemberNameInfo(MemberNameInfo) {
   if (TemplateArgs)
     getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
 }
@@ -771,15 +769,14 @@
                                 NestedNameSpecifier *Qualifier,
                                 SourceRange QualifierRange,
                                 NamedDecl *FirstQualifierFoundInScope,
-                                DeclarationName Member,
-                                SourceLocation MemberLoc,
+                                DeclarationNameInfo MemberNameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
   if (!TemplateArgs)
     return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
                                                IsArrow, OperatorLoc,
                                                Qualifier, QualifierRange,
                                                FirstQualifierFoundInScope,
-                                               Member, MemberLoc);
+                                               MemberNameInfo);
 
   std::size_t size = sizeof(CXXDependentScopeMemberExpr);
   if (TemplateArgs)
@@ -790,7 +787,7 @@
                                                IsArrow, OperatorLoc,
                                                Qualifier, QualifierRange,
                                                FirstQualifierFoundInScope,
-                                               Member, MemberLoc, TemplateArgs);
+                                               MemberNameInfo, TemplateArgs);
 }
 
 CXXDependentScopeMemberExpr *
@@ -800,8 +797,7 @@
     return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
                                                0, SourceLocation(), 0,
                                                SourceRange(), 0,
-                                               DeclarationName(),
-                                               SourceLocation());
+                                               DeclarationNameInfo());
 
   std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
                      ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
@@ -810,8 +806,7 @@
     =  new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
                                              0, SourceLocation(), 0,
                                              SourceRange(), 0,
-                                             DeclarationName(),
-                                             SourceLocation(), 0);
+                                             DeclarationNameInfo(), 0);
   E->HasExplicitTemplateArgs = true;
   return E;
 }
@@ -834,13 +829,12 @@
                                            SourceLocation OperatorLoc,
                                            NestedNameSpecifier *Qualifier,
                                            SourceRange QualifierRange,
-                                           DeclarationName MemberName,
-                                           SourceLocation MemberLoc,
+                                   const DeclarationNameInfo &MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs,
                                            UnresolvedSetIterator Begin, 
                                            UnresolvedSetIterator End)
   : OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
-                 Qualifier, QualifierRange, MemberName, MemberLoc,
+                 Qualifier, QualifierRange, MemberNameInfo,
                  TemplateArgs != 0, Begin, End),
     IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
     Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
@@ -855,8 +849,7 @@
                              SourceLocation OperatorLoc,
                              NestedNameSpecifier *Qualifier,
                              SourceRange QualifierRange,
-                             DeclarationName Member,
-                             SourceLocation MemberLoc,
+                             const DeclarationNameInfo &MemberNameInfo,
                              const TemplateArgumentListInfo *TemplateArgs,
                              UnresolvedSetIterator Begin, 
                              UnresolvedSetIterator End) {
@@ -869,7 +862,7 @@
                              Dependent ? C.DependentTy : C.OverloadTy,
                              Dependent, HasUnresolvedUsing, Base, BaseType,
                              IsArrow, OperatorLoc, Qualifier, QualifierRange,
-                             Member, MemberLoc, TemplateArgs, Begin, End);
+                             MemberNameInfo, TemplateArgs, Begin, End);
 }
 
 UnresolvedMemberExpr *
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 41b1415..6ff4711 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -472,7 +472,7 @@
 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
     Qualifier->print(OS, Policy);
-  OS << Node->getDecl();
+  OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgumentList())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                     Node->getTemplateArgs(),
@@ -483,7 +483,7 @@
 void StmtPrinter::VisitDependentScopeDeclRefExpr(
                                            DependentScopeDeclRefExpr *Node) {
   Node->getQualifier()->print(OS, Policy);
-  OS << Node->getDeclName().getAsString();
+  OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                    Node->getTemplateArgs(),
@@ -494,7 +494,7 @@
 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
   if (Node->getQualifier())
     Node->getQualifier()->print(OS, Policy);
-  OS << Node->getName().getAsString();
+  OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                    Node->getTemplateArgs(),
@@ -777,7 +777,7 @@
   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
     Qualifier->print(OS, Policy);
 
-  OS << Node->getMemberDecl();
+  OS << Node->getMemberNameInfo();
 
   if (Node->hasExplicitTemplateArgumentList())
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
@@ -1201,7 +1201,7 @@
     // FIXME: Track use of "template" keyword explicitly?
     OS << "template ";
 
-  OS << Node->getMember().getAsString();
+  OS << Node->getMemberNameInfo();
 
   if (Node->hasExplicitTemplateArgs()) {
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
@@ -1221,7 +1221,7 @@
 
   // FIXME: this might originally have been written with 'template'
 
-  OS << Node->getMemberName().getAsString();
+  OS << Node->getMemberNameInfo();
 
   if (Node->hasExplicitTemplateArgs()) {
     OS << TemplateSpecializationType::PrintTemplateArgumentList(
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 7aab7b7..cb18108 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -231,6 +231,7 @@
 
 void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   VisitDeclaratorDecl(FD);
+  // FIXME: read DeclarationNameLoc.
 
   FD->IdentifierNamespace = Record[Idx++];
   switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
@@ -1403,7 +1404,7 @@
     D = CXXRecordDecl::Create(*Context, Decl::EmptyShell());
     break;
   case pch::DECL_CXX_METHOD:
-    D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), DeclarationName(),
+    D = CXXMethodDecl::Create(*Context, 0, DeclarationNameInfo(),
                               QualType(), 0);
     break;
   case pch::DECL_CXX_CONSTRUCTOR:
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 01c1640..41c8a9a 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -401,6 +401,7 @@
                                      NumTemplateArgs);
 
   E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME: read DeclarationNameLoc.
   E->setLocation(Reader.ReadSourceLocation(Record, Idx));
 }
 
@@ -1154,6 +1155,7 @@
   E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
   E->setFirstQualifierFoundInScope(
                         cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME: read whole DeclarationNameInfo.
   E->setMember(Reader.ReadDeclarationName(Record, Idx));
   E->setMemberLoc(Reader.ReadSourceLocation(Record, Idx));
 }
@@ -1169,6 +1171,7 @@
     ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(),
                                      NumTemplateArgs);
 
+  // FIXME: read whole DeclarationNameInfo.
   E->setDeclName(Reader.ReadDeclarationName(Record, Idx));
   E->setLocation(Reader.ReadSourceLocation(Record, Idx));
   E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
@@ -1207,6 +1210,7 @@
   }
   E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end());
 
+  // FIXME: read whole DeclarationNameInfo.
   E->setName(Reader.ReadDeclarationName(Record, Idx));
   E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
   E->setQualifierRange(Reader.ReadSourceRange(Record, Idx));
@@ -1475,11 +1479,13 @@
       QualType T = GetType(Record[Idx++]);
       Expr *Base = ReadSubExpr();
       ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++]));
+      // FIXME: read DeclarationNameLoc.
       SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
+      DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
       bool IsArrow = Record[Idx++];
 
       S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange,
-                             MemberD, FoundDecl, MemberLoc,
+                             MemberD, FoundDecl, MemberNameInfo,
                              NumTemplateArgs ? &ArgInfo : 0, T);
       break;
     }
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index a509ed1..13e5239 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -214,6 +214,7 @@
 
 void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   VisitDeclaratorDecl(D);
+  // FIXME: write DeclarationNameLoc.
 
   Record.push_back(D->getIdentifierNamespace());
   Record.push_back(D->getTemplatedKind());
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 52f0b79..e464a44 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -382,6 +382,7 @@
     AddExplicitTemplateArgumentList(*E->getExplicitTemplateArgumentList());
 
   Writer.AddDeclRef(E->getDecl(), Record);
+  // FIXME: write DeclarationNameLoc.
   Writer.AddSourceLocation(E->getLocation(), Record);
   Code = pch::EXPR_DECL_REF;
 }
@@ -552,6 +553,7 @@
   Writer.AddTypeRef(E->getType(), Record);
   Writer.AddStmt(E->getBase());
   Writer.AddDeclRef(E->getMemberDecl(), Record);
+  // FIXME: write DeclarationNameLoc.
   Writer.AddSourceLocation(E->getMemberLoc(), Record);
   Record.push_back(E->isArrow());
   Code = pch::EXPR_MEMBER;
@@ -1178,6 +1180,7 @@
   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
   Writer.AddSourceRange(E->getQualifierRange(), Record);
   Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
+  // FIXME: write whole DeclarationNameInfo.
   Writer.AddDeclarationName(E->getMember(), Record);
   Writer.AddSourceLocation(E->getMemberLoc(), Record);
   Code = pch::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
@@ -1199,6 +1202,7 @@
     Record.push_back(0);
   }
 
+  // FIXME: write whole DeclarationNameInfo.
   Writer.AddDeclarationName(E->getDeclName(), Record);
   Writer.AddSourceLocation(E->getLocation(), Record);
   Writer.AddSourceRange(E->getQualifierRange(), Record);
@@ -1242,6 +1246,7 @@
     Record.push_back(OvI.getAccess());
   }
 
+  // FIXME: write whole DeclarationNameInfo.
   Writer.AddDeclarationName(E->getName(), Record);
   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
   Writer.AddSourceRange(E->getQualifierRange(), Record);
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 271bb5b..b638734 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -125,15 +125,34 @@
 
   typedef UnresolvedSetImpl::iterator iterator;
 
-  LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+  LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo,
                Sema::LookupNameKind LookupKind,
                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
     : ResultKind(NotFound),
       Paths(0),
       NamingClass(0),
       SemaRef(SemaRef),
-      Name(Name),
-      NameLoc(NameLoc),
+      NameInfo(NameInfo),
+      LookupKind(LookupKind),
+      IDNS(0),
+      Redecl(Redecl != Sema::NotForRedeclaration),
+      HideTags(true),
+      Diagnose(Redecl == Sema::NotForRedeclaration)
+  {
+    configure();
+  }
+
+  // TODO: consider whether this constructor should be restricted to take
+  // as input a const IndentifierInfo* (instead of Name),
+  // forcing other cases towards the constructor taking a DNInfo.
+  LookupResult(Sema &SemaRef, DeclarationName Name,
+               SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
+    : ResultKind(NotFound),
+      Paths(0),
+      NamingClass(0),
+      SemaRef(SemaRef),
+      NameInfo(Name, NameLoc),
       LookupKind(LookupKind),
       IDNS(0),
       Redecl(Redecl != Sema::NotForRedeclaration),
@@ -151,8 +170,7 @@
       Paths(0),
       NamingClass(0),
       SemaRef(Other.SemaRef),
-      Name(Other.Name),
-      NameLoc(Other.NameLoc),
+      NameInfo(Other.NameInfo),
       LookupKind(Other.LookupKind),
       IDNS(Other.IDNS),
       Redecl(Other.Redecl),
@@ -165,14 +183,24 @@
     if (Paths) deletePaths(Paths);
   }
 
+  /// Gets the name info to look up.
+  const DeclarationNameInfo &getLookupNameInfo() const {
+    return NameInfo;
+  }
+
+  /// \brief Sets the name info to look up.
+  void setLookupNameInfo(const DeclarationNameInfo &NameInfo) {
+    this->NameInfo = NameInfo;
+  }
+
   /// Gets the name to look up.
   DeclarationName getLookupName() const {
-    return Name;
+    return NameInfo.getName();
   }
 
   /// \brief Sets the name to look up.
   void setLookupName(DeclarationName Name) {
-    this->Name = Name;
+    NameInfo.setName(Name);
   }
 
   /// Gets the kind of lookup to perform.
@@ -444,7 +472,7 @@
   /// Gets the location of the identifier.  This isn't always defined:
   /// sometimes we're doing lookups on synthesized names.
   SourceLocation getNameLoc() const {
-    return NameLoc;
+    return NameInfo.getLoc();
   }
 
   /// \brief Get the Sema object that this lookup result is searching
@@ -572,8 +600,7 @@
 
   // Parameters.
   Sema &SemaRef;
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   SourceRange NameContextRange;
   Sema::LookupNameKind LookupKind;
   unsigned IDNS; // set by configure()
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 02761ac..31c7e0e 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -785,8 +785,8 @@
                                                TypeSourceInfo *ReturnTypeInfo);
   /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
   QualType CreateLocInfoType(QualType T, TypeSourceInfo *TInfo);
-  DeclarationName GetNameForDeclarator(Declarator &D);
-  DeclarationName GetNameFromUnqualifiedId(const UnqualifiedId &Name);
+  DeclarationNameInfo GetNameForDeclarator(Declarator &D);
+  DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
   static QualType GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo = 0);
   bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
   bool CheckDistantExceptionSpec(QualType T);
@@ -1916,14 +1916,16 @@
                                       bool AllowBuiltinCreation=false);
 
   OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
-                                              DeclarationName Name,
-                                              SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                               bool isAddressOfOperand,
                                 const TemplateArgumentListInfo *TemplateArgs);
 
   OwningExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
                                     SourceLocation Loc,
                                     const CXXScopeSpec *SS = 0);
+  OwningExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                                    const DeclarationNameInfo &NameInfo,
+                                    const CXXScopeSpec *SS = 0);
   VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
                                     llvm::SmallVectorImpl<FieldDecl *> &Path);
   OwningExprResult
@@ -1943,18 +1945,16 @@
                                   bool HasTrailingLParen);
 
   OwningExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                                     DeclarationName Name,
-                                                     SourceLocation NameLoc);
+                                         const DeclarationNameInfo &NameInfo);
   OwningExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
-                                             DeclarationName Name,
-                                             SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs);
 
   OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
                                             LookupResult &R,
                                             bool ADL);
   OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                                            SourceLocation Loc,
+                                            const DeclarationNameInfo &NameInfo,
                                             NamedDecl *D);
 
   virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
@@ -2014,8 +2014,7 @@
                                             bool IsArrow,
                                             CXXScopeSpec &SS,
                                             NamedDecl *FirstQualifierInScope,
-                                            DeclarationName Name,
-                                            SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs);
 
   OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
@@ -2043,8 +2042,7 @@
                                             SourceLocation OpLoc,
                                             const CXXScopeSpec &SS,
                                             NamedDecl *FirstQualifierInScope,
-                                            DeclarationName Name,
-                                            SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs);
 
   virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
@@ -3073,8 +3071,7 @@
                                        bool RequiresADL,
                                const TemplateArgumentListInfo &TemplateArgs);
   OwningExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
-                                                DeclarationName Name,
-                                                SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo &TemplateArgs);
 
   virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
@@ -3974,7 +3971,9 @@
   SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
                            SourceRange Range,
                            const MultiLevelTemplateArgumentList &TemplateArgs);
-
+  DeclarationNameInfo
+  SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
   TemplateName
   SubstTemplateName(TemplateName Name, SourceLocation Loc,
                     const MultiLevelTemplateArgumentList &TemplateArgs);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 47eb3ee..de7ad3d 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1881,79 +1881,110 @@
 
 /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
-DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {
   return GetNameFromUnqualifiedId(D.getName());
 }
 
-/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
-DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+/// \brief Retrieves the declaration name from a parsed unqualified-id.
+DeclarationNameInfo
+Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+  DeclarationNameInfo NameInfo;
+  NameInfo.setLoc(Name.StartLocation);
+
   switch (Name.getKind()) {
-    case UnqualifiedId::IK_Identifier:
-      return DeclarationName(Name.Identifier);
-      
-    case UnqualifiedId::IK_OperatorFunctionId:
-      return Context.DeclarationNames.getCXXOperatorName(
-                                              Name.OperatorFunctionId.Operator);
 
-    case UnqualifiedId::IK_LiteralOperatorId:
-      return Context.DeclarationNames.getCXXLiteralOperatorName(
-                                                               Name.Identifier);
+  case UnqualifiedId::IK_Identifier:
+    NameInfo.setName(Name.Identifier);
+    NameInfo.setLoc(Name.StartLocation);
+    return NameInfo;
 
-    case UnqualifiedId::IK_ConversionFunctionId: {
-      QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXConversionFunctionName(
-                                                  Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_ConstructorName: {
-      QualType Ty = GetTypeFromParser(Name.ConstructorName);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXConstructorName(
-                                                  Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_ConstructorTemplateId: {
-      // In well-formed code, we can only have a constructor
-      // template-id that refers to the current context, so go there
-      // to find the actual type being constructed.
-      CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
-      if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
-        return DeclarationName();
+  case UnqualifiedId::IK_OperatorFunctionId:
+    NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
+                                           Name.OperatorFunctionId.Operator));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc
+      = Name.OperatorFunctionId.SymbolLocations[0];
+    NameInfo.getInfo().CXXOperatorName.EndOpNameLoc
+      = Name.EndLocation.getRawEncoding();
+    return NameInfo;
 
-      // Determine the type of the class being constructed.
-      QualType CurClassType = Context.getTypeDeclType(CurClass);
+  case UnqualifiedId::IK_LiteralOperatorId:
+    NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
+                                                           Name.Identifier));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);
+    return NameInfo;
 
-      // FIXME: Check two things: that the template-id names the same type as
-      // CurClassType, and that the template-id does not occur when the name
-      // was qualified.
-
-      return Context.DeclarationNames.getCXXConstructorName(
-                                       Context.getCanonicalType(CurClassType));
-    }
-
-    case UnqualifiedId::IK_DestructorName: {
-      QualType Ty = GetTypeFromParser(Name.DestructorName);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXDestructorName(
-                                                           Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_TemplateId: {
-      TemplateName TName
-        = TemplateName::getFromVoidPointer(Name.TemplateId->Template);
-      return Context.getNameForTemplate(TName);
-    }
+  case UnqualifiedId::IK_ConversionFunctionId: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName(
+                                               Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
   }
-  
+
+  case UnqualifiedId::IK_ConstructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_ConstructorTemplateId: {
+    // In well-formed code, we can only have a constructor
+    // template-id that refers to the current context, so go there
+    // to find the actual type being constructed.
+    CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
+    if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
+      return DeclarationNameInfo();
+
+    // Determine the type of the class being constructed.
+    QualType CurClassType = Context.getTypeDeclType(CurClass);
+
+    // FIXME: Check two things: that the template-id names the same type as
+    // CurClassType, and that the template-id does not occur when the name
+    // was qualified.
+
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                    Context.getCanonicalType(CurClassType)));
+    NameInfo.setLoc(Name.StartLocation);
+    // FIXME: should we retrieve TypeSourceInfo?
+    NameInfo.setNamedTypeInfo(0);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_DestructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXDestructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_TemplateId: {
+    TemplateName TName
+      = TemplateName::getFromVoidPointer(Name.TemplateId->Template);
+    SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
+    return Context.getNameForTemplate(TName, TNameLoc);
+  }
+
+  } // switch (Name.getKind())
+
   assert(false && "Unknown name kind");
-  return DeclarationName();  
+  return DeclarationNameInfo();
 }
 
 /// isNearlyMatchingFunction - Determine whether the C++ functions
@@ -2047,7 +2078,9 @@
 Sema::HandleDeclarator(Scope *S, Declarator &D,
                        MultiTemplateParamsArg TemplateParamLists,
                        bool IsFunctionDefinition) {
-  DeclarationName Name = GetNameForDeclarator(D);
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
 
   // All of these full declarators require an identifier.  If it doesn't have
   // one, the ParsedFreeStandingDeclSpec action should be used.
@@ -2111,7 +2144,7 @@
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType R = TInfo->getType();
 
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
                         ForRedeclaration);
 
   // See if this is a redefinition of a variable in the same scope.
@@ -2497,7 +2530,7 @@
                               LookupResult &Previous,
                               MultiTemplateParamsArg TemplateParamLists,
                               bool &Redeclaration) {
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationName Name = GetNameForDeclarator(D).getName();
 
   // Check that there are no default arguments (C++ only).
   if (getLangOptions().CPlusPlus)
@@ -2961,7 +2994,9 @@
                               bool IsFunctionDefinition, bool &Redeclaration) {
   assert(R.getTypePtr()->isFunctionType());
 
-  DeclarationName Name = GetNameForDeclarator(D);
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   FunctionDecl::StorageClass SC = FunctionDecl::None;
   switch (D.getDeclSpec().getStorageClassSpec()) {
   default: assert(0 && "Unknown storage class!");
@@ -3041,7 +3076,7 @@
     // Create the new declaration
     NewFD = CXXConstructorDecl::Create(Context,
                                        cast<CXXRecordDecl>(DC),
-                                       D.getIdentifierLoc(), Name, R, TInfo,
+                                       NameInfo, R, TInfo,
                                        isExplicit, isInline,
                                        /*isImplicitlyDeclared=*/false);
   } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
@@ -3051,7 +3086,7 @@
 
       NewFD = CXXDestructorDecl::Create(Context,
                                         cast<CXXRecordDecl>(DC),
-                                        D.getIdentifierLoc(), Name, R,
+                                        NameInfo, R,
                                         isInline,
                                         /*isImplicitlyDeclared=*/false);
       NewFD->setTypeSourceInfo(TInfo);
@@ -3076,7 +3111,7 @@
 
     CheckConversionDeclarator(D, R, SC);
     NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                      D.getIdentifierLoc(), Name, R, TInfo,
+                                      NameInfo, R, TInfo,
                                       isInline, isExplicit);
 
     isVirtualOkay = true;
@@ -3111,7 +3146,7 @@
     
     // This is a C++ method declaration.
     NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                  D.getIdentifierLoc(), Name, R, TInfo,
+                                  NameInfo, R, TInfo,
                                   isStatic, SCAsWritten, isInline);
 
     isVirtualOkay = !isStatic;
@@ -3128,8 +3163,7 @@
        (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
 
     NewFD = FunctionDecl::Create(Context, DC,
-                                 D.getIdentifierLoc(),
-                                 Name, R, TInfo, SC, SCAsWritten, isInline,
+                                 NameInfo, R, TInfo, SC, SCAsWritten, isInline,
                                  HasPrototype);
   }
 
@@ -3726,6 +3760,8 @@
         DeclarationName Name
           = Context.DeclarationNames.getCXXDestructorName(
                                         Context.getCanonicalType(ClassType));
+//         NewFD->getDeclName().dump();
+//         Name.dump();
         if (NewFD->getDeclName() != Name) {
           Diag(NewFD->getLocation(), diag::err_destructor_name);
           return NewFD->setInvalidDecl();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 94ca031..4156df0 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -893,10 +893,11 @@
                                ExprTy *BW, ExprTy *InitExpr, bool IsDefinition,
                                bool Deleted) {
   const DeclSpec &DS = D.getDeclSpec();
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
+  SourceLocation Loc = NameInfo.getLoc();
   Expr *BitWidth = static_cast<Expr*>(BW);
   Expr *Init = static_cast<Expr*>(InitExpr);
-  SourceLocation Loc = D.getIdentifierLoc();
 
   assert(isa<CXXRecordDecl>(CurContext));
   assert(!DS.isFriendSpecified());
@@ -3476,7 +3477,7 @@
     return DeclPtrTy();
   }
   
-  DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
+  DeclarationName TargetName = GetNameFromUnqualifiedId(Name).getName();
   if (!TargetName)
     return DeclPtrTy();
 
@@ -4248,9 +4249,9 @@
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   DeclarationName Name
     = Context.DeclarationNames.getCXXConstructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXConstructorDecl *DefaultCon
-    = CXXConstructorDecl::Create(Context, ClassDecl,
-                                 ClassDecl->getLocation(), Name,
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
                                  Context.getFunctionType(Context.VoidTy,
                                                          0, 0, false, 0,
                                        ExceptSpec.hasExceptionSpecification(),
@@ -4354,9 +4355,9 @@
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   DeclarationName Name
     = Context.DeclarationNames.getCXXDestructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXDestructorDecl *Destructor
-    = CXXDestructorDecl::Create(Context, ClassDecl,
-                                ClassDecl->getLocation(), Name, Ty,
+    = CXXDestructorDecl::Create(Context, ClassDecl, NameInfo, Ty,
                                 /*isInline=*/true,
                                 /*isImplicitlyDeclared=*/true);
   Destructor->setAccess(AS_public);
@@ -4751,8 +4752,9 @@
   //   An implicitly-declared copy assignment operator is an inline public
   //   member of its class.
   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXMethodDecl *CopyAssignment
-    = CXXMethodDecl::Create(Context, ClassDecl, ClassDecl->getLocation(), Name,
+    = CXXMethodDecl::Create(Context, ClassDecl, NameInfo,
                             Context.getFunctionType(RetType, &ArgType, 1,
                                                     false, 0,
                                          ExceptSpec.hasExceptionSpecification(),
@@ -5227,9 +5229,9 @@
   DeclarationName Name
     = Context.DeclarationNames.getCXXConstructorName(
                                            Context.getCanonicalType(ClassType));
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXConstructorDecl *CopyConstructor
-    = CXXConstructorDecl::Create(Context, ClassDecl,
-                                 ClassDecl->getLocation(), Name,
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
                                  Context.getFunctionType(Context.VoidTy,
                                                          &ArgType, 1,
                                                          false, 0,
@@ -6305,7 +6307,8 @@
   //    namespace scope are not considered.
 
   CXXScopeSpec &ScopeQual = D.getCXXScopeSpec();
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   assert(Name);
 
   // The context we found the declaration in, or in which we should
@@ -6315,7 +6318,7 @@
   // FIXME: handle local classes
 
   // Recover from invalid scope qualifiers as if they just weren't there.
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
                         ForRedeclaration);
   if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
     DC = computeDeclContext(ScopeQual);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index e108ab5..32d683f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -459,13 +459,20 @@
 }
 
 
-
-/// BuildDeclRefExpr - Build a DeclRefExpr.
 Sema::OwningExprResult
 Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
                        const CXXScopeSpec *SS) {
+  DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
+  return BuildDeclRefExpr(D, Ty, NameInfo, SS);
+}
+
+/// BuildDeclRefExpr - Build a DeclRefExpr.
+Sema::OwningExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                       const DeclarationNameInfo &NameInfo,
+                       const CXXScopeSpec *SS) {
   if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
-    Diag(Loc,
+    Diag(NameInfo.getLoc(),
          diag::err_auto_variable_cannot_appear_in_own_initializer)
       << D->getDeclName();
     return ExprError();
@@ -479,7 +486,8 @@
     } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
       if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
         if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
-          Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function)
+          Diag(NameInfo.getLoc(),
+               diag::err_reference_to_local_var_in_enclosing_function)
             << D->getIdentifier() << FD->getDeclName();
           Diag(D->getLocation(), diag::note_local_variable_declared_here)
             << D->getIdentifier();
@@ -489,12 +497,12 @@
     }
   }
 
-  MarkDeclarationReferenced(Loc, D);
+  MarkDeclarationReferenced(NameInfo.getLoc(), D);
 
   return Owned(DeclRefExpr::Create(Context,
                               SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
                                    SS? SS->getRange() : SourceRange(),
-                                   D, Loc, Ty));
+                                   D, NameInfo, Ty));
 }
 
 /// \brief Given a field that represents a member of an anonymous
@@ -639,7 +647,7 @@
   return Owned(Result);
 }
 
-/// Decomposes the given name into a DeclarationName, its location, and
+/// Decomposes the given name into a DeclarationNameInfo, its location, and
 /// possibly a list of template arguments.
 ///
 /// If this produces template arguments, it is permitted to call
@@ -651,8 +659,7 @@
 static void DecomposeUnqualifiedId(Sema &SemaRef,
                                    const UnqualifiedId &Id,
                                    TemplateArgumentListInfo &Buffer,
-                                   DeclarationName &Name,
-                                   SourceLocation &NameLoc,
+                                   DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo *&TemplateArgs) {
   if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
     Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
@@ -666,13 +673,11 @@
 
     TemplateName TName =
       Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
-
-    Name = SemaRef.Context.getNameForTemplate(TName);
-    NameLoc = Id.TemplateId->TemplateNameLoc;
+    SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
+    NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
     TemplateArgs = &Buffer;
   } else {
-    Name = SemaRef.GetNameFromUnqualifiedId(Id);
-    NameLoc = Id.StartLocation;
+    NameInfo = SemaRef.GetNameFromUnqualifiedId(Id);
     TemplateArgs = 0;
   }
 }
@@ -903,8 +908,8 @@
           CXXDependentScopeMemberExpr *DepExpr =
               CXXDependentScopeMemberExpr::Create(
                   Context, DepThis, DepThisType, true, SourceLocation(),
-                  ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name,
-                  R.getNameLoc(), &TList);
+                  ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+                  R.getLookupNameInfo(), &TList);
           CallsUndergoingInstantiation.back()->setCallee(DepExpr);
         } else {
           Diag(R.getNameLoc(), diagnostic) << Name;
@@ -1066,13 +1071,13 @@
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the UnqualifiedId into the following data.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
-  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   IdentifierInfo *II = Name.getAsIdentifierInfo();
+  SourceLocation NameLoc = NameInfo.getLoc();
 
   // C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -1103,13 +1108,12 @@
   }
 
   if (DependentID) {
-    return ActOnDependentIdExpression(SS, Name, NameLoc,
-                                      isAddressOfOperand,
+    return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
                                       TemplateArgs);
   }
   bool IvarLookupFollowUp = false;
   // Perform the required lookup.
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   if (TemplateArgs) {
     // Lookup the template name again to correctly establish the context in
     // which it was found. This is really unfortunate as we already did the
@@ -1271,23 +1275,23 @@
 /// this path.
 Sema::OwningExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                        DeclarationName Name,
-                                        SourceLocation NameLoc) {
+                                        const DeclarationNameInfo &NameInfo) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+    return BuildDependentDeclRefExpr(SS, NameInfo, 0);
 
   if (RequireCompleteDeclContext(SS, DC))
     return ExprError();
 
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   LookupQualifiedName(R, DC);
 
   if (R.isAmbiguous())
     return ExprError();
 
   if (R.empty()) {
-    Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_no_member)
+      << NameInfo.getName() << DC << SS.getRange();
     return ExprError();
   }
 
@@ -1563,7 +1567,8 @@
 static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
                                    const CXXScopeSpec &SS, ValueDecl *Member,
                                    DeclAccessPair FoundDecl,
-                                   SourceLocation Loc, QualType Ty,
+                                   const DeclarationNameInfo &MemberNameInfo,
+                                   QualType Ty,
                           const TemplateArgumentListInfo *TemplateArgs = 0) {
   NestedNameSpecifier *Qualifier = 0;
   SourceRange QualifierRange;
@@ -1573,7 +1578,8 @@
   }
 
   return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
-                            Member, FoundDecl, Loc, TemplateArgs, Ty);
+                            Member, FoundDecl, MemberNameInfo,
+                            TemplateArgs, Ty);
 }
 
 /// Builds an implicit member access expression.  The current context
@@ -1703,7 +1709,8 @@
   // If this is a single, fully-resolved result and we don't need ADL,
   // just build an ordinary singleton decl ref.
   if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())
-    return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
+    return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
+                                    R.getFoundDecl());
 
   // We only need to check the declaration if there's exactly one
   // result, because in the overloaded case the results can only be
@@ -1722,8 +1729,7 @@
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
                                    (NestedNameSpecifier*) SS.getScopeRep(),
-                                   SS.getRange(),
-                                   R.getLookupName(), R.getNameLoc(),
+                                   SS.getRange(), R.getLookupNameInfo(),
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
@@ -1734,11 +1740,13 @@
 /// \brief Complete semantic analysis for a reference to the given declaration.
 Sema::OwningExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                               SourceLocation Loc, NamedDecl *D) {
+                               const DeclarationNameInfo &NameInfo,
+                               NamedDecl *D) {
   assert(D && "Cannot refer to a NULL declaration");
   assert(!isa<FunctionTemplateDecl>(D) &&
          "Cannot refer unambiguously to a function template");
 
+  SourceLocation Loc = NameInfo.getLoc();
   if (CheckDeclInExpr(*this, Loc, D))
     return ExprError();
 
@@ -1830,7 +1838,8 @@
   // If this reference is not in a block or if the referenced variable is
   // within the block, create a normal DeclRefExpr.
 
-  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS);
+  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+                          NameInfo, &SS);
 }
 
 Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
@@ -2534,7 +2543,7 @@
                                bool IsArrow, SourceLocation OpLoc,
                                const CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
   Expr *BaseExpr = Base.takeAs<Expr>();
 
@@ -2552,13 +2561,14 @@
     if (PT && (!getLangOptions().ObjC1 ||
                PT->getPointeeType()->isRecordType())) {
       assert(BaseExpr && "cannot happen with implicit member accesses");
-      Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+      Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union)
         << BaseType << BaseExpr->getSourceRange();
       return ExprError();
     }
   }
 
-  assert(BaseType->isDependentType() || Name.isDependentName() ||
+  assert(BaseType->isDependentType() ||
+         NameInfo.getName().isDependentName() ||
          isDependentScopeSpecifier(SS));
 
   // Get the type being accessed in BaseType.  If this is an arrow, the BaseExpr
@@ -2568,8 +2578,7 @@
                  static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
                                                    SS.getRange(),
                                                    FirstQualifierInScope,
-                                                   Name, NameLoc,
-                                                   TemplateArgs));
+                                                   NameInfo, TemplateArgs));
 }
 
 /// We know that the given qualified member reference points only to
@@ -2713,7 +2722,7 @@
                                SourceLocation OpLoc, bool IsArrow,
                                CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
   Expr *Base = BaseArg.takeAs<Expr>();
 
@@ -2722,10 +2731,9 @@
     return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
                                     IsArrow, OpLoc,
                                     SS, FirstQualifierInScope,
-                                    Name, NameLoc,
-                                    TemplateArgs);
+                                    NameInfo, TemplateArgs);
 
-  LookupResult R(*this, Name, NameLoc, LookupMemberName);
+  LookupResult R(*this, NameInfo, LookupMemberName);
 
   // Implicit member accesses.
   if (!Base) {
@@ -2777,8 +2785,9 @@
 
   NestedNameSpecifier *Qualifier =
     static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-  DeclarationName MemberName = R.getLookupName();
-  SourceLocation MemberLoc = R.getNameLoc();
+  const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
+  DeclarationName MemberName = MemberNameInfo.getName();
+  SourceLocation MemberLoc = MemberNameInfo.getLoc();
 
   if (R.isAmbiguous())
     return ExprError();
@@ -2827,7 +2836,7 @@
                                      BaseExpr, BaseExprType,
                                      IsArrow, OpLoc,
                                      Qualifier, SS.getRange(),
-                                     MemberName, MemberLoc,
+                                     MemberNameInfo,
                                      TemplateArgs, R.begin(), R.end());
 
     return Owned(MemExpr);
@@ -2849,7 +2858,7 @@
   if (!BaseExpr) {
     // If this is not an instance member, convert to a non-member access.
     if (!MemberDecl->isCXXInstanceMember())
-      return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+      return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl);
 
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
@@ -2900,34 +2909,36 @@
     if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
       return ExprError();
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 FD, FoundDecl, MemberLoc, MemberType));
+                                 FD, FoundDecl, MemberNameInfo,
+                                 MemberType));
   }
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, Var);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Var, FoundDecl, MemberLoc,
+                                 Var, FoundDecl, MemberNameInfo,
                                  Var->getType().getNonReferenceType()));
   }
 
   if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 MemberFn, FoundDecl, MemberLoc,
+                                 MemberFn, FoundDecl, MemberNameInfo,
                                  MemberFn->getType()));
   }
 
   if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Enum, FoundDecl, MemberLoc, Enum->getType()));
+                                 Enum, FoundDecl, MemberNameInfo,
+                                 Enum->getType()));
   }
 
   Owned(BaseExpr);
 
   // We found something that we didn't expect. Complain.
   if (isa<TypeDecl>(MemberDecl))
-    Diag(MemberLoc,diag::err_typecheck_member_reference_type)
+    Diag(MemberLoc, diag::err_typecheck_member_reference_type)
       << MemberName << BaseType << int(IsArrow);
   else
     Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
@@ -3310,12 +3321,12 @@
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the name into its component parts.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
   DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+                         NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   bool IsArrow = (OpKind == tok::arrow);
 
   NamedDecl *FirstQualifierInScope
@@ -3332,10 +3343,9 @@
     Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
                                       IsArrow, OpLoc,
                                       SS, FirstQualifierInScope,
-                                      Name, NameLoc,
-                                      TemplateArgs);
+                                      NameInfo, TemplateArgs);
   } else {
-    LookupResult R(*this, Name, NameLoc, LookupMemberName);
+    LookupResult R(*this, NameInfo, LookupMemberName);
     Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
                               SS, ObjCImpDecl, TemplateArgs != 0);
 
@@ -3351,7 +3361,7 @@
       // call now.
       if (!HasTrailingLParen &&
           Id.getKind() == UnqualifiedId::IK_DestructorName)
-        return DiagnoseDtorReference(NameLoc, move(Result));
+        return DiagnoseDtorReference(NameInfo.getLoc(), move(Result));
 
       return move(Result);
     }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 7bebce1..14f4cd1 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -3041,7 +3041,7 @@
     assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
 
   MemberExpr *ME = 
-      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 
+      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
                                SourceLocation(), Method->getType());
   QualType ResultType = Method->getCallResultType();
   MarkDeclarationReferenced(Exp->getLocStart(), Method);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 837cafd..a54716c 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -267,7 +267,7 @@
   // operators, make sure that the implicitly-declared new and delete
   // operators can be found.
   if (!isForRedeclaration()) {
-    switch (Name.getCXXOverloadedOperator()) {
+    switch (NameInfo.getName().getCXXOverloadedOperator()) {
     case OO_New:
     case OO_Delete:
     case OO_Array_New:
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index db563cf..339a793 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6645,6 +6645,8 @@
   OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc);
   assert(Op != OO_None && "Invalid opcode for overloaded unary operator");
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+  // TODO: provide better source location info.
+  DeclarationNameInfo OpNameInfo(OpName, OpLoc);
 
   Expr *Args[2] = { Input, 0 };
   unsigned NumArgs = 1;
@@ -6669,7 +6671,7 @@
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, OpLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
     input.release();
@@ -6839,9 +6841,11 @@
 
     // FIXME: save results of ADL from here?
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // TODO: provide better source location info in DNLoc component.
+    DeclarationNameInfo OpNameInfo(OpName, OpLoc);
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, OpLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
@@ -7036,9 +7040,12 @@
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
 
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // CHECKME: no 'operator' keyword?
+    DeclarationNameInfo OpNameInfo(OpName, LLoc);
+    OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, LLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, /*Overloaded*/ false,
                                      UnresolvedSetIterator(),
                                      UnresolvedSetIterator());
@@ -7790,7 +7797,7 @@
                               MemExpr->getQualifierRange(),
                               Fn, 
                               Found,
-                              MemExpr->getMemberLoc(),
+                              MemExpr->getMemberNameInfo(),
                               TemplateArgs,
                               Fn->getType());
   }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 2864e00..4a5f038 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -334,8 +334,7 @@
 /// specifier naming a dependent type.
 Sema::OwningExprResult
 Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
-                                 DeclarationName Name,
-                                 SourceLocation NameLoc,
+                                 const DeclarationNameInfo &NameInfo,
                                  bool isAddressOfOperand,
                            const TemplateArgumentListInfo *TemplateArgs) {
   NestedNameSpecifier *Qualifier
@@ -358,22 +357,21 @@
                                                      /*Op*/ SourceLocation(),
                                                      Qualifier, SS.getRange(),
                                                      FirstQualifierInScope,
-                                                     Name, NameLoc,
+                                                     NameInfo,
                                                      TemplateArgs));
   }
 
-  return BuildDependentDeclRefExpr(SS, Name, NameLoc, TemplateArgs);
+  return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs);
 }
 
 Sema::OwningExprResult
 Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
-                                DeclarationName Name,
-                                SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
   return Owned(DependentScopeDeclRefExpr::Create(Context,
                static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
                                                  SS.getRange(),
-                                                 Name, NameLoc,
+                                                 NameInfo,
                                                  TemplateArgs));
 }
 
@@ -1598,7 +1596,7 @@
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
                                    Qualifier, QualifierRange,
-                                   R.getLookupName(), R.getNameLoc(),
+                                   R.getLookupNameInfo(),
                                    RequiresADL, TemplateArgs, 
                                    R.begin(), R.end());
 
@@ -1608,17 +1606,16 @@
 // We actually only call this from template instantiation.
 Sema::OwningExprResult
 Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
-                                   DeclarationName Name,
-                                   SourceLocation NameLoc,
+                                   const DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo &TemplateArgs) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) ||
       DC->isDependentContext() ||
       RequireCompleteDeclContext(SS, DC))
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
+    return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs);
 
   bool MemberOfUnknownSpecialization;
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
                      MemberOfUnknownSpecialization);
 
@@ -1626,14 +1623,15 @@
     return ExprError();
   
   if (R.empty()) {
-    Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
-      << Name << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
+      << NameInfo.getName() << SS.getRange();
     return ExprError();
   }
 
   if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
-    Diag(NameLoc, diag::err_template_kw_refers_to_class_template)
-      << (NestedNameSpecifier*) SS.getScopeRep() << Name << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
+      << (NestedNameSpecifier*) SS.getScopeRep()
+      << NameInfo.getName() << SS.getRange();
     Diag(Temp->getLocation(), diag::note_referenced_class_template);
     return ExprError();
   }
@@ -1693,7 +1691,7 @@
     } else if (TNK == TNK_Non_template) {
       Diag(Name.getSourceRange().getBegin(), 
            diag::err_template_kw_refers_to_non_template)
-        << GetNameFromUnqualifiedId(Name)
+        << GetNameFromUnqualifiedId(Name).getName()
         << Name.getSourceRange()
         << TemplateKWLoc;
       return TNK_Non_template;
@@ -1726,7 +1724,7 @@
   
   Diag(Name.getSourceRange().getBegin(), 
        diag::err_template_kw_refers_to_non_template)
-    << GetNameFromUnqualifiedId(Name)
+    << GetNameFromUnqualifiedId(Name).getName()
     << Name.getSourceRange()
     << TemplateKWLoc;
   return TNK_Non_template;
@@ -2047,12 +2045,15 @@
         // We have a template argument such as \c T::template X, which we
         // parsed as a template template argument. However, since we now
         // know that we need a non-type template argument, convert this
-        // template name into an expression.          
+        // template name into an expression.
+
+        DeclarationNameInfo NameInfo(DTN->getIdentifier(),
+                                     Arg.getTemplateNameLoc());
+
         Expr *E = DependentScopeDeclRefExpr::Create(Context,
                                                     DTN->getQualifier(),
                                                Arg.getTemplateQualifierRange(),
-                                                    DTN->getIdentifier(),
-                                                    Arg.getTemplateNameLoc());
+                                                    NameInfo);
         
         TemplateArgument Result;
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
@@ -4938,7 +4939,9 @@
                                                   SourceLocation TemplateLoc,
                                                   Declarator &D) {
   // Explicit instantiations always require a name.
-  DeclarationName Name = GetNameForDeclarator(D);
+  // TODO: check if/when DNInfo should replace Name.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   if (!Name) {
     if (!D.isInvalidType())
       Diag(D.getDeclSpec().getSourceRange().getBegin(),
@@ -4988,7 +4991,7 @@
     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
                            : TSK_ExplicitInstantiationDeclaration;
     
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
   LookupParsedName(Previous, S, &D.getCXXScopeSpec());
 
   if (!R->isFunctionType()) {
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 1a22abb..e97880c 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1611,6 +1611,15 @@
   return Instantiator.TransformNestedNameSpecifier(NNS, Range);
 }
 
+/// \brief Do template substitution on declaration name info.
+DeclarationNameInfo
+Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                         const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
+                                    NameInfo.getName());
+  return Instantiator.TransformDeclarationNameInfo(NameInfo);
+}
+
 TemplateName
 Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
                         const MultiLevelTemplateArgumentList &TemplateArgs) {
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8e184f1..fe21ace 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1294,39 +1294,27 @@
   CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
   CXXMethodDecl *Method = 0;
 
-  DeclarationName Name = D->getDeclName();
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
-    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
-    Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
-                                    SemaRef.Context.getCanonicalType(ClassTy));
     Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
-                                        Constructor->getLocation(),
-                                        Name, T, TInfo,
+                                        NameInfo, T, TInfo,
                                         Constructor->isExplicit(),
                                         Constructor->isInlineSpecified(),
                                         false);
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
-    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
-    Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
-                                   SemaRef.Context.getCanonicalType(ClassTy));
     Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
-                                       Destructor->getLocation(), Name,
-                                       T, Destructor->isInlineSpecified(),
+                                       NameInfo, T,
+                                       Destructor->isInlineSpecified(),
                                        false);
   } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
-    CanQualType ConvTy
-      = SemaRef.Context.getCanonicalType(
-                                      T->getAs<FunctionType>()->getResultType());
-    Name = SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(
-                                                                      ConvTy);
     Method = CXXConversionDecl::Create(SemaRef.Context, Record,
-                                       Conversion->getLocation(), Name,
-                                       T, TInfo,
+                                       NameInfo, T, TInfo,
                                        Conversion->isInlineSpecified(),
                                        Conversion->isExplicit());
   } else {
-    Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
-                                   D->getDeclName(), T, TInfo,
+    Method = CXXMethodDecl::Create(SemaRef.Context, Record,
+                                   NameInfo, T, TInfo,
                                    D->isStatic(),
                                    D->getStorageClassAsWritten(),
                                    D->isInlineSpecified());
@@ -1390,8 +1378,8 @@
   if (InitMethodInstantiation(Method, D))
     Method->setInvalidDecl();
 
-  LookupResult Previous(SemaRef, Name, SourceLocation(),
-                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+  LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+                        Sema::ForRedeclaration);
 
   if (!FunctionTemplate || TemplateParams || isFriend) {
     SemaRef.LookupQualifiedName(Previous, Record);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index eaf47a6..081d938 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -276,9 +276,9 @@
   /// and destructor names and then (if needed) rebuilds the declaration name.
   /// Identifiers and selectors are returned unmodified. Sublcasses may
   /// override this function to provide alternate behavior.
-  DeclarationName TransformDeclarationName(DeclarationName Name,
-                                           SourceLocation Loc,
-                                           QualType ObjectType = QualType());
+  DeclarationNameInfo
+  TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType = QualType());
 
   /// \brief Transform the given template name.
   ///
@@ -1032,15 +1032,16 @@
   /// Subclasses may override this routine to provide different behavior.
   OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
                                       SourceRange QualifierRange,
-                                      ValueDecl *VD, SourceLocation Loc,
+                                      ValueDecl *VD,
+                                      const DeclarationNameInfo &NameInfo,
                                       TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setScopeRep(Qualifier);
     SS.setRange(QualifierRange);
 
     // FIXME: loses template args.
-    
-    return getSema().BuildDeclarationNameExpr(SS, Loc, VD);
+
+    return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD);
   }
 
   /// \brief Build a new expression in parentheses.
@@ -1149,7 +1150,7 @@
                                      bool isArrow,
                                      NestedNameSpecifier *Qualifier,
                                      SourceRange QualifierRange,
-                                     SourceLocation MemberLoc,
+                                     const DeclarationNameInfo &MemberNameInfo,
                                      ValueDecl *Member,
                                      NamedDecl *FoundDecl,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
@@ -1165,7 +1166,7 @@
 
       MemberExpr *ME =
         new (getSema().Context) MemberExpr(BaseExpr, isArrow,
-                                           Member, MemberLoc,
+                                           Member, MemberNameInfo,
                                            cast<FieldDecl>(Member)->getType());
       return getSema().Owned(ME);
     }
@@ -1182,8 +1183,7 @@
 
     // FIXME: this involves duplicating earlier analysis in a lot of
     // cases; we should avoid this when possible.
-    LookupResult R(getSema(), Member->getDeclName(), MemberLoc,
-                   Sema::LookupMemberName);
+    LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
     R.addDecl(FoundDecl);
     R.resolveKind();
 
@@ -1252,11 +1252,11 @@
 
     CXXScopeSpec SS;
     QualType BaseType = ((Expr*) Base.get())->getType();
+    DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
     return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
                                               OpLoc, /*IsArrow*/ false,
                                               SS, /*FirstQualifierInScope*/ 0,
-                                              DeclarationName(&Accessor),
-                                              AccessorLoc,
+                                              NameInfo,
                                               /* TemplateArgs */ 0);
   }
 
@@ -1654,18 +1654,17 @@
   /// Subclasses may override this routine to provide different behavior.
   OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
                                                 SourceRange QualifierRange,
-                                                DeclarationName Name,
-                                                SourceLocation Location,
+                                       const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
     SS.setScopeRep(NNS);
 
     if (TemplateArgs)
-      return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
+      return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo,
                                                     *TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
+    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo);
   }
 
   /// \brief Build a new template-id expression.
@@ -1745,8 +1744,7 @@
                                               NestedNameSpecifier *Qualifier,
                                                   SourceRange QualifierRange,
                                             NamedDecl *FirstQualifierInScope,
-                                                  DeclarationName Name,
-                                                  SourceLocation MemberLoc,
+                                   const DeclarationNameInfo &MemberNameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
@@ -1755,7 +1753,8 @@
     return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
                                             OperatorLoc, IsArrow,
                                             SS, FirstQualifierInScope,
-                                            Name, MemberLoc, TemplateArgs);
+                                            MemberNameInfo,
+                                            TemplateArgs);
   }
 
   /// \brief Build a new member reference expression.
@@ -2098,12 +2097,13 @@
 }
 
 template<typename Derived>
-DeclarationName
-TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
-                                                 SourceLocation Loc,
-                                                 QualType ObjectType) {
+DeclarationNameInfo
+TreeTransform<Derived>
+::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType) {
+  DeclarationName Name = NameInfo.getName();
   if (!Name)
-    return Name;
+    return DeclarationNameInfo();
 
   switch (Name.getNameKind()) {
   case DeclarationName::Identifier:
@@ -2113,24 +2113,41 @@
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
-    return Name;
+    return NameInfo;
 
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName: {
-    TemporaryBase Rebase(*this, Loc, Name);
-    QualType T = getDerived().TransformType(Name.getCXXNameType(), 
-                                            ObjectType);
-    if (T.isNull())
-      return DeclarationName();
+    TypeSourceInfo *NewTInfo;
+    CanQualType NewCanTy;
+    if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
+       NewTInfo = getDerived().TransformType(OldTInfo, ObjectType);
+       if (!NewTInfo)
+         return DeclarationNameInfo();
+       NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
+    }
+    else {
+      NewTInfo = 0;
+      TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
+      QualType NewT = getDerived().TransformType(Name.getCXXNameType(),
+                                                 ObjectType);
+      if (NewT.isNull())
+        return DeclarationNameInfo();
+      NewCanTy = SemaRef.Context.getCanonicalType(NewT);
+    }
 
-    return SemaRef.Context.DeclarationNames.getCXXSpecialName(
-                                                           Name.getNameKind(),
-                                          SemaRef.Context.getCanonicalType(T));
+    DeclarationName NewName
+      = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
+                                                           NewCanTy);
+    DeclarationNameInfo NewNameInfo(NameInfo);
+    NewNameInfo.setName(NewName);
+    NewNameInfo.setNamedTypeInfo(NewTInfo);
+    return NewNameInfo;
   }
   }
 
-  return DeclarationName();
+  assert(0 && "Unknown name kind.");
+  return DeclarationNameInfo();
 }
 
 template<typename Derived>
@@ -4197,9 +4214,15 @@
   if (!ND)
     return SemaRef.ExprError();
 
-  if (!getDerived().AlwaysRebuild() && 
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
+  if (!NameInfo.getName())
+    return SemaRef.ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
       Qualifier == E->getQualifier() &&
       ND == E->getDecl() &&
+      NameInfo.getName() == E->getDecl()->getDeclName() &&
       !E->hasExplicitTemplateArgumentList()) {
 
     // Mark it referenced in the new context regardless.
@@ -4223,7 +4246,7 @@
   }
 
   return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
-                                         ND, E->getLocation(), TemplateArgs);
+                                         ND, NameInfo, TemplateArgs);
 }
 
 template<typename Derived>
@@ -4522,7 +4545,7 @@
                                         E->isArrow(),
                                         Qualifier,
                                         E->getQualifierRange(),
-                                        E->getMemberLoc(),
+                                        E->getMemberNameInfo(),
                                         Member,
                                         FoundDecl,
                                         (E->hasExplicitTemplateArgumentList()
@@ -5573,27 +5596,29 @@
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
-                                                  DependentScopeDeclRefExpr *E) {
+                                               DependentScopeDeclRefExpr *E) {
   NestedNameSpecifier *NNS
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange());
   if (!NNS)
     return SemaRef.ExprError();
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
-  if (!Name)
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
+  if (!NameInfo.getName())
     return SemaRef.ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
     if (!getDerived().AlwaysRebuild() &&
         NNS == E->getQualifier() &&
-        Name == E->getDeclName())
+        // Note: it is sufficient to compare the Name component of NameInfo:
+        // if name has not changed, DNLoc has not changed either.
+        NameInfo.getName() == E->getDeclName())
       return SemaRef.Owned(E->Retain());
 
     return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                          E->getQualifierRange(),
-                                                         Name, E->getLocation(),
+                                                         NameInfo,
                                                          /*TemplateArgs*/ 0);
   }
 
@@ -5607,7 +5632,7 @@
 
   return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                        E->getQualifierRange(),
-                                                       Name, E->getLocation(),
+                                                       NameInfo,
                                                        &TransArgs);
 }
 
@@ -5799,7 +5824,7 @@
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
-                                                     CXXDependentScopeMemberExpr *E) {
+                                             CXXDependentScopeMemberExpr *E) {
   // Transform the base of the expression.
   OwningExprResult Base(SemaRef, (Expr*) 0);
   Expr *OldBase;
@@ -5847,10 +5872,10 @@
       return SemaRef.ExprError();
   }
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
-                                            ObjectType);
-  if (!Name)
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo(),
+                                                ObjectType);
+  if (!NameInfo.getName())
     return SemaRef.ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
@@ -5860,7 +5885,7 @@
         Base.get() == OldBase &&
         BaseType == E->getBaseType() &&
         Qualifier == E->getQualifier() &&
-        Name == E->getMember() &&
+        NameInfo.getName() == E->getMember() &&
         FirstQualifierInScope == E->getFirstQualifierFoundInScope())
       return SemaRef.Owned(E->Retain());
 
@@ -5871,8 +5896,7 @@
                                                        Qualifier,
                                                        E->getQualifierRange(),
                                                        FirstQualifierInScope,
-                                                       Name,
-                                                       E->getMemberLoc(),
+                                                       NameInfo,
                                                        /*TemplateArgs*/ 0);
   }
 
@@ -5891,8 +5915,7 @@
                                                      Qualifier,
                                                      E->getQualifierRange(),
                                                      FirstQualifierInScope,
-                                                     Name,
-                                                     E->getMemberLoc(),
+                                                     NameInfo,
                                                      &TransArgs);
 }
 
@@ -5920,7 +5943,7 @@
       return SemaRef.ExprError();
   }
 
-  LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
+  LookupResult R(SemaRef, Old->getMemberNameInfo(),
                  Sema::LookupOrdinaryName);
 
   // Transform all the decls.
@@ -6265,7 +6288,7 @@
                                                        E->getDecl()));
   if (!ND)
     return SemaRef.ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       ND == E->getDecl()) {
     // Mark it referenced in the new context regardless.
@@ -6275,8 +6298,9 @@
     return SemaRef.Owned(E->Retain());
   }
   
+  DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation());
   return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
-                                         ND, E->getLocation(), 0);
+                                         ND, NameInfo, 0);
 }
 
 //===----------------------------------------------------------------------===//
@@ -6708,18 +6732,19 @@
                                              Destroyed,
                                              /*FIXME?*/true);
   }
-  
+
   TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
-  DeclarationName Name
-    = SemaRef.Context.DeclarationNames.getCXXDestructorName(
-                SemaRef.Context.getCanonicalType(DestroyedType->getType()));
-  
+  DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
+  DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
+  NameInfo.setNamedTypeInfo(DestroyedType);
+
   // FIXME: the ScopeType should be tacked onto SS.
-  
+
   return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
                                             OperatorLoc, isArrow,
                                             SS, /*FIXME: FirstQualifier*/ 0,
-                                            Name, Destroyed.getLocation(),
+                                            NameInfo,
                                             /*TemplateArgs*/ 0);
 }