diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp | 285 | 
1 files changed, 141 insertions, 144 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp index 0e448e31207d..d5bee1d0e368 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp @@ -35,6 +35,7 @@  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/TinyPtrVector.h"  #include "llvm/Support/ErrorHandling.h"  #include <limits>  #include <list> @@ -86,7 +87,7 @@ namespace {    /// A collection of using directives, as used by C++ unqualified    /// lookup.    class UnqualUsingDirectiveSet { -    typedef llvm::SmallVector<UnqualUsingEntry, 8> ListTy; +    typedef SmallVector<UnqualUsingEntry, 8> ListTy;      ListTy list;      llvm::SmallPtrSet<DeclContext*, 8> visited; @@ -147,7 +148,7 @@ namespace {      // by its using directives, transitively) as if they appeared in      // the given effective context.      void addUsingDirectives(DeclContext *DC, DeclContext *EffectiveDC) { -      llvm::SmallVector<DeclContext*,4> queue; +      SmallVector<DeclContext*,4> queue;        while (true) {          DeclContext::udir_iterator I, End;          for (llvm::tie(I, End) = DC->getUsingDirectives(); I != End; ++I) { @@ -460,7 +461,7 @@ void LookupResult::setAmbiguousBaseSubobjectTypes(CXXBasePaths &P) {    setAmbiguous(AmbiguousBaseSubobjectTypes);  } -void LookupResult::print(llvm::raw_ostream &Out) { +void LookupResult::print(raw_ostream &Out) {    Out << Decls.size() << " result(s)";    if (isAmbiguous()) Out << ", ambiguous";    if (Paths) Out << ", base paths present"; @@ -549,6 +550,16 @@ void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) {    if (!Class->hasDeclaredCopyAssignment())      DeclareImplicitCopyAssignment(Class); +  if (getLangOptions().CPlusPlus0x) { +    // If the move constructor has not yet been declared, do so now. +    if (Class->needsImplicitMoveConstructor()) +      DeclareImplicitMoveConstructor(Class); // might not actually do it + +    // If the move assignment operator has not yet been declared, do so now. +    if (Class->needsImplicitMoveAssignment()) +      DeclareImplicitMoveAssignment(Class); // might not actually do it +  } +    // If the destructor has not yet been declared, do so now.    if (!Class->hasDeclaredDestructor())      DeclareImplicitDestructor(Class); @@ -585,11 +596,14 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,      if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC))        if (Record->getDefinition() &&            CanDeclareSpecialMemberFunction(S.Context, Record)) { +        CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(Record);          if (Record->needsImplicitDefaultConstructor()) -          S.DeclareImplicitDefaultConstructor( -                                           const_cast<CXXRecordDecl *>(Record)); +          S.DeclareImplicitDefaultConstructor(Class);          if (!Record->hasDeclaredCopyConstructor()) -          S.DeclareImplicitCopyConstructor(const_cast<CXXRecordDecl *>(Record)); +          S.DeclareImplicitCopyConstructor(Class); +        if (S.getLangOptions().CPlusPlus0x && +            Record->needsImplicitMoveConstructor()) +          S.DeclareImplicitMoveConstructor(Class);        }      break; @@ -604,10 +618,17 @@ static void DeclareImplicitMemberFunctionsWithName(Sema &S,      if (Name.getCXXOverloadedOperator() != OO_Equal)        break; -    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) -      if (Record->getDefinition() && !Record->hasDeclaredCopyAssignment() && -          CanDeclareSpecialMemberFunction(S.Context, Record)) -        S.DeclareImplicitCopyAssignment(const_cast<CXXRecordDecl *>(Record)); +    if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) { +      if (Record->getDefinition() && +          CanDeclareSpecialMemberFunction(S.Context, Record)) { +        CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(Record); +        if (!Record->hasDeclaredCopyAssignment()) +          S.DeclareImplicitCopyAssignment(Class); +        if (S.getLangOptions().CPlusPlus0x && +            Record->needsImplicitMoveAssignment()) +          S.DeclareImplicitMoveAssignment(Class); +      } +    }      break;    default: @@ -648,7 +669,7 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {    //   name lookup. Instead, any conversion function templates visible in the    //   context of the use are considered. [...]    const CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); -  if (!Record->isDefinition()) +  if (!Record->isCompleteDefinition())      return Found;    const UnresolvedSetImpl *Unresolved = Record->getConversionFunctions(); @@ -1187,7 +1208,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,    // We have not yet looked into these namespaces, much less added    // their "using-children" to the queue. -  llvm::SmallVector<NamespaceDecl*, 8> Queue; +  SmallVector<NamespaceDecl*, 8> Queue;    // We have already looked into the initial namespace; seed the queue    // with its using-children. @@ -1332,7 +1353,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,    // Make sure that the declaration context is complete.    assert((!isa<TagDecl>(LookupCtx) ||            LookupCtx->isDependentContext() || -          cast<TagDecl>(LookupCtx)->isDefinition() || +          cast<TagDecl>(LookupCtx)->isCompleteDefinition() ||            Context.getTypeDeclType(cast<TagDecl>(LookupCtx))->getAs<TagType>()              ->isBeingDefined()) &&           "Declaration context must already be complete!"); @@ -1802,7 +1823,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,    // Add direct and indirect base classes along with their associated    // namespaces. -  llvm::SmallVector<CXXRecordDecl *, 32> Bases; +  SmallVector<CXXRecordDecl *, 32> Bases;    Bases.push_back(Class);    while (!Bases.empty()) {      // Pop this class off the stack. @@ -1852,7 +1873,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {    //   the types do not contribute to this set. The sets of namespaces    //   and classes are determined in the following way: -  llvm::SmallVector<const Type *, 16> Queue; +  SmallVector<const Type *, 16> Queue;    const Type *T = Ty->getCanonicalTypeInternal().getTypePtr();    while (true) { @@ -1979,6 +2000,12 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {      case Type::ObjCObjectPointer:        Result.Namespaces.insert(Result.S.Context.getTranslationUnitDecl());        break; + +    // Atomic types are just wrappers; use the associations of the +    // contained type. +    case Type::Atomic: +      T = cast<AtomicType>(T)->getValueType().getTypePtr(); +      continue;      }      if (Queue.empty()) break; @@ -2210,12 +2237,14 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,        Name = Context.DeclarationNames.getCXXConstructorName(CanTy);        if (!RD->hasDeclaredCopyConstructor())          DeclareImplicitCopyConstructor(RD); -      // TODO: Move constructors +      if (getLangOptions().CPlusPlus0x && RD->needsImplicitMoveConstructor()) +        DeclareImplicitMoveConstructor(RD);      } else {        Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);        if (!RD->hasDeclaredCopyAssignment())          DeclareImplicitCopyAssignment(RD); -      // TODO: Move assignment +      if (getLangOptions().CPlusPlus0x && RD->needsImplicitMoveAssignment()) +        DeclareImplicitMoveAssignment(RD);      }      QualType ArgType = CanTy; @@ -2358,6 +2387,15 @@ CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class,    return cast_or_null<CXXConstructorDecl>(Result->getMethod());  } +/// \brief Look up the moving constructor for the given class. +CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class) { +  SpecialMemberOverloadResult *Result = +    LookupSpecialMember(Class, CXXMoveConstructor, false, +                        false, false, false, false); + +  return cast_or_null<CXXConstructorDecl>(Result->getMethod()); +} +  /// \brief Look up the constructors for the given class.  DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {    // If the implicit constructors have not yet been declared, do so now. @@ -2366,6 +2404,8 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {        DeclareImplicitDefaultConstructor(Class);      if (!Class->hasDeclaredCopyConstructor())        DeclareImplicitCopyConstructor(Class); +    if (getLangOptions().CPlusPlus0x && Class->needsImplicitMoveConstructor()) +      DeclareImplicitMoveConstructor(Class);    }    CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class)); @@ -2394,6 +2434,20 @@ CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class,    return Result->getMethod();  } +/// \brief Look up the moving assignment operator for the given class. +CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class, +                                            bool RValueThis, +                                            unsigned ThisQuals) { +  assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) && +         "non-const, non-volatile qualifiers for copy assignment this"); +  SpecialMemberOverloadResult *Result = +    LookupSpecialMember(Class, CXXMoveAssignment, false, false, RValueThis, +                        ThisQuals & Qualifiers::Const, +                        ThisQuals & Qualifiers::Volatile); + +  return Result->getMethod(); +} +  /// \brief Look for the destructor of the given class.  ///  /// During semantic analysis, this routine should be used in lieu of @@ -2530,24 +2584,7 @@ public:    /// \brief An entry in the shadow map, which is optimized to store a    /// single declaration (the common case) but can also store a list    /// of declarations. -  class ShadowMapEntry { -    typedef llvm::SmallVector<NamedDecl *, 4> DeclVector; - -    /// \brief Contains either the solitary NamedDecl * or a vector -    /// of declarations. -    llvm::PointerUnion<NamedDecl *, DeclVector*> DeclOrVector; - -  public: -    ShadowMapEntry() : DeclOrVector() { } - -    void Add(NamedDecl *ND); -    void Destroy(); - -    // Iteration. -    typedef NamedDecl * const *iterator; -    iterator begin(); -    iterator end(); -  }; +  typedef llvm::TinyPtrVector<NamedDecl*> ShadowMapEntry;  private:    /// \brief A mapping from declaration names to the declarations that have @@ -2581,7 +2618,9 @@ public:    NamedDecl *checkHidden(NamedDecl *ND);    /// \brief Add a declaration to the current shadow map. -  void add(NamedDecl *ND) { ShadowMaps.back()[ND->getDeclName()].Add(ND); } +  void add(NamedDecl *ND) { +    ShadowMaps.back()[ND->getDeclName()].push_back(ND); +  }  };  /// \brief RAII object that records when we've entered a shadow context. @@ -2596,66 +2635,12 @@ public:    }    ~ShadowContextRAII() { -    for (ShadowMap::iterator E = Visible.ShadowMaps.back().begin(), -                          EEnd = Visible.ShadowMaps.back().end(); -         E != EEnd; -         ++E) -      E->second.Destroy(); -      Visible.ShadowMaps.pop_back();    }  };  } // end anonymous namespace -void VisibleDeclsRecord::ShadowMapEntry::Add(NamedDecl *ND) { -  if (DeclOrVector.isNull()) { -    // 0 - > 1 elements: just set the single element information. -    DeclOrVector = ND; -    return; -  } - -  if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) { -    // 1 -> 2 elements: create the vector of results and push in the -    // existing declaration. -    DeclVector *Vec = new DeclVector; -    Vec->push_back(PrevND); -    DeclOrVector = Vec; -  } - -  // Add the new element to the end of the vector. -  DeclOrVector.get<DeclVector*>()->push_back(ND); -} - -void VisibleDeclsRecord::ShadowMapEntry::Destroy() { -  if (DeclVector *Vec = DeclOrVector.dyn_cast<DeclVector *>()) { -    delete Vec; -    DeclOrVector = ((NamedDecl *)0); -  } -} - -VisibleDeclsRecord::ShadowMapEntry::iterator -VisibleDeclsRecord::ShadowMapEntry::begin() { -  if (DeclOrVector.isNull()) -    return 0; - -  if (DeclOrVector.is<NamedDecl *>()) -    return DeclOrVector.getAddrOf<NamedDecl *>(); - -  return DeclOrVector.get<DeclVector *>()->begin(); -} - -VisibleDeclsRecord::ShadowMapEntry::iterator -VisibleDeclsRecord::ShadowMapEntry::end() { -  if (DeclOrVector.isNull()) -    return 0; - -  if (DeclOrVector.is<NamedDecl *>()) -    return DeclOrVector.getAddrOf<NamedDecl *>() + 1; - -  return DeclOrVector.get<DeclVector *>()->end(); -} -  NamedDecl *VisibleDeclsRecord::checkHidden(NamedDecl *ND) {    // Look through using declarations.    ND = ND->getUnderlyingDecl(); @@ -2722,7 +2707,7 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,           D != DEnd; ++D) {        if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {          if (Result.isAcceptableDecl(ND)) { -          Consumer.FoundDecl(ND, Visited.checkHidden(ND), InBaseClass); +          Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass);            Visited.add(ND);          }        } else if (ObjCForwardProtocolDecl *ForwardProto @@ -2733,19 +2718,17 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,               P != PEnd;               ++P) {            if (Result.isAcceptableDecl(*P)) { -            Consumer.FoundDecl(*P, Visited.checkHidden(*P), InBaseClass); +            Consumer.FoundDecl(*P, Visited.checkHidden(*P), Ctx, InBaseClass);              Visited.add(*P);            }          }        } else if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D)) { -        for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end(); -             I != IEnd; ++I) { -          ObjCInterfaceDecl *IFace = I->getInterface(); +          ObjCInterfaceDecl *IFace = Class->getForwardInterfaceDecl();            if (Result.isAcceptableDecl(IFace)) { -            Consumer.FoundDecl(IFace, Visited.checkHidden(IFace), InBaseClass); +            Consumer.FoundDecl(IFace, Visited.checkHidden(IFace), Ctx, +                               InBaseClass);              Visited.add(IFace);            } -        }        }        // Visit transparent contexts and inline namespaces inside this context. @@ -2885,7 +2868,7 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,           D != DEnd; ++D) {        if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))          if (Result.isAcceptableDecl(ND)) { -          Consumer.FoundDecl(ND, Visited.checkHidden(ND), false); +          Consumer.FoundDecl(ND, Visited.checkHidden(ND), 0, false);            Visited.add(ND);          }      } @@ -2909,24 +2892,7 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,                                    Result.getNameLoc(), Sema::LookupMemberName);            if (ObjCInterfaceDecl *IFace = Method->getClassInterface()) {              LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, -                               /*InBaseClass=*/false, Consumer, Visited); - -            // Look for properties from which we can synthesize ivars, if -            // permitted. -            if (Result.getSema().getLangOptions().ObjCNonFragileABI2 && -                IFace->getImplementation() && -                Result.getLookupKind() == Sema::LookupOrdinaryName) { -              for (ObjCInterfaceDecl::prop_iterator -                        P = IFace->prop_begin(), -                     PEnd = IFace->prop_end(); -                   P != PEnd; ++P) { -                if (Result.getSema().canSynthesizeProvisionalIvar(*P) && -                    !IFace->lookupInstanceVariable((*P)->getIdentifier())) { -                  Consumer.FoundDecl(*P, Visited.checkHidden(*P), false); -                  Visited.add(*P); -                } -              } -            } +                               /*InBaseClass=*/false, Consumer, Visited);                          }          } @@ -3056,7 +3022,7 @@ static const unsigned MaxTypoDistanceResultSets = 5;  class TypoCorrectionConsumer : public VisibleDeclConsumer {    /// \brief The name written that is a typo in the source. -  llvm::StringRef Typo; +  StringRef Typo;    /// \brief The results found that have the smallest edit distance    /// found (so far) with the typo name. @@ -3084,11 +3050,12 @@ public:        delete I->second;    } -  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass); -  void FoundName(llvm::StringRef Name); -  void addKeywordResult(llvm::StringRef Keyword); -  void addName(llvm::StringRef Name, NamedDecl *ND, unsigned Distance, -               NestedNameSpecifier *NNS=NULL); +  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, +                         bool InBaseClass); +  void FoundName(StringRef Name); +  void addKeywordResult(StringRef Keyword); +  void addName(StringRef Name, NamedDecl *ND, unsigned Distance, +               NestedNameSpecifier *NNS=NULL, bool isKeyword=false);    void addCorrection(TypoCorrection Correction);    typedef TypoResultsMap::iterator result_iterator; @@ -3099,7 +3066,7 @@ public:    unsigned size() const { return BestResults.size(); }    bool empty() const { return BestResults.empty(); } -  TypoCorrection &operator[](llvm::StringRef Name) { +  TypoCorrection &operator[](StringRef Name) {      return (*BestResults.begin()->second)[Name];    } @@ -3115,7 +3082,7 @@ public:  }  void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding, -                                       bool InBaseClass) { +                                       DeclContext *Ctx, bool InBaseClass) {    // Don't consider hidden names for typo correction.    if (Hiding)      return; @@ -3130,7 +3097,7 @@ void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,    FoundName(Name->getName());  } -void TypoCorrectionConsumer::FoundName(llvm::StringRef Name) { +void TypoCorrectionConsumer::FoundName(StringRef Name) {    // Use a simple length-based heuristic to determine the minimum possible    // edit distance. If the minimum isn't good enough, bail out early.    unsigned MinED = abs((int)Name.size() - (int)Typo.size()); @@ -3156,7 +3123,7 @@ void TypoCorrectionConsumer::FoundName(llvm::StringRef Name) {    addName(Name, NULL, ED);  } -void TypoCorrectionConsumer::addKeywordResult(llvm::StringRef Keyword) { +void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {    // Compute the edit distance between the typo and this keyword.    // If this edit distance is not worse than the best edit    // distance we've seen so far, add it to the list of results. @@ -3167,19 +3134,21 @@ void TypoCorrectionConsumer::addKeywordResult(llvm::StringRef Keyword) {      return;    } -  addName(Keyword, TypoCorrection::KeywordDecl(), ED); +  addName(Keyword, NULL, ED, NULL, true);  } -void TypoCorrectionConsumer::addName(llvm::StringRef Name, +void TypoCorrectionConsumer::addName(StringRef Name,                                       NamedDecl *ND,                                       unsigned Distance, -                                     NestedNameSpecifier *NNS) { -  addCorrection(TypoCorrection(&SemaRef.Context.Idents.get(Name), -                               ND, NNS, Distance)); +                                     NestedNameSpecifier *NNS, +                                     bool isKeyword) { +  TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, Distance); +  if (isKeyword) TC.makeKeyword(); +  addCorrection(TC);  }  void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { -  llvm::StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName(); +  StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();    TypoResultsMap *& Map = BestResults[Correction.getEditDistance()];    if (!Map)      Map = new TypoResultsMap; @@ -3213,8 +3182,8 @@ class SpecifierInfo {        : DeclCtx(Ctx), NameSpecifier(NNS), EditDistance(ED) {}  }; -typedef llvm::SmallVector<DeclContext*, 4> DeclContextList; -typedef llvm::SmallVector<SpecifierInfo, 16> SpecifierInfoList; +typedef SmallVector<DeclContext*, 4> DeclContextList; +typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;  class NamespaceSpecifierSet {    ASTContext &Context; @@ -3264,14 +3233,14 @@ DeclContextList NamespaceSpecifierSet::BuildContextChain(DeclContext *Start) {  }  void NamespaceSpecifierSet::SortNamespaces() { -  llvm::SmallVector<unsigned, 4> sortedDistances; +  SmallVector<unsigned, 4> sortedDistances;    sortedDistances.append(Distances.begin(), Distances.end());    if (sortedDistances.size() > 1)      std::sort(sortedDistances.begin(), sortedDistances.end());    Specifiers.clear(); -  for (llvm::SmallVector<unsigned, 4>::iterator DI = sortedDistances.begin(), +  for (SmallVector<unsigned, 4>::iterator DI = sortedDistances.begin(),                                               DIEnd = sortedDistances.end();         DI != DIEnd; ++DI) {      SpecifierInfoList &SpecList = DistanceMap[*DI]; @@ -3648,7 +3617,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,                                = Context.Idents.getExternalIdentifierLookup()) {          llvm::OwningPtr<IdentifierIterator> Iter(External->getIdentifiers());          do { -          llvm::StringRef Name = Iter->Next(); +          StringRef Name = Iter->Next();            if (Name.empty())              break; @@ -3692,7 +3661,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,    if (getLangOptions().CPlusPlus) {      // Load any externally-known namespaces.      if (ExternalSource && !LoadedExternalKnownNamespaces) { -      llvm::SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces; +      SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;        LoadedExternalKnownNamespaces = true;        ExternalSource->ReadKnownNamespaces(ExternalKnownNamespaces);        for (unsigned I = 0, N = ExternalKnownNamespaces.size(); I != N; ++I) @@ -3730,6 +3699,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,        switch (TmpRes.getResultKind()) {        case LookupResult::NotFound:        case LookupResult::NotFoundInCurrentInstantiation: +      case LookupResult::FoundUnresolvedValue:          QualifiedResults.insert(Name);          // We didn't find this name in our scope, or didn't like what we found;          // ignore it. @@ -3745,12 +3715,18 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,          // We don't deal with ambiguities.          return TypoCorrection(); +      case LookupResult::FoundOverloaded: { +        // Store all of the Decls for overloaded symbols +        for (LookupResult::iterator TRD = TmpRes.begin(), +                                 TRDEnd = TmpRes.end(); +             TRD != TRDEnd; ++TRD) +          I->second.addCorrectionDecl(*TRD); +        ++I; +        break; +      } +        case LookupResult::Found: -      case LookupResult::FoundOverloaded: -      case LookupResult::FoundUnresolvedValue:          I->second.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>()); -        // FIXME: This sets the CorrectionDecl to NULL for overloaded functions. -        // It would be nice to find the right one with overload resolution.          ++I;          break;        } @@ -3786,14 +3762,23 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,            switch (TmpRes.getResultKind()) {            case LookupResult::Found: -          case LookupResult::FoundOverloaded: -          case LookupResult::FoundUnresolvedValue:              Consumer.addName((*QRI)->getName(), TmpRes.getAsSingle<NamedDecl>(),                               QualifiedED, NI->NameSpecifier);              break; +          case LookupResult::FoundOverloaded: { +            TypoCorrection corr(&Context.Idents.get((*QRI)->getName()), NULL, +                                NI->NameSpecifier, QualifiedED); +            for (LookupResult::iterator TRD = TmpRes.begin(), +                                     TRDEnd = TmpRes.end(); +                 TRD != TRDEnd; ++TRD) +              corr.addCorrectionDecl(*TRD); +            Consumer.addCorrection(corr); +            break; +          }            case LookupResult::NotFound:            case LookupResult::NotFoundInCurrentInstantiation:            case LookupResult::Ambiguous: +          case LookupResult::FoundUnresolvedValue:              break;            }          } @@ -3870,6 +3855,18 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,    return TypoCorrection();  } +void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) { +  if (!CDecl) return; + +  if (isKeyword()) +    CorrectionDecls.clear(); + +  CorrectionDecls.push_back(CDecl); + +  if (!CorrectionName) +    CorrectionName = CDecl->getDeclName(); +} +  std::string TypoCorrection::getAsString(const LangOptions &LO) const {    if (CorrectionNameSpec) {      std::string tmpBuffer;  | 
