diff options
-rw-r--r-- | clang/include/clang/Sema/SemaInternal.h | 148 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 153 |
2 files changed, 149 insertions, 152 deletions
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 4ec77c14eb5..59920d20dcd 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_SEMA_SEMAINTERNAL_H #include "clang/AST/ASTContext.h" +#include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" @@ -86,6 +87,151 @@ inline InheritableAttr *getDLLAttr(Decl *D) { return nullptr; } -} +class TypoCorrectionConsumer : public VisibleDeclConsumer { + typedef SmallVector<TypoCorrection, 1> TypoResultList; + typedef llvm::StringMap<TypoResultList> TypoResultsMap; + typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; + +public: + explicit TypoCorrectionConsumer(Sema &SemaRef, + const DeclarationNameInfo &TypoName, + Sema::LookupNameKind LookupKind, + Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, + bool EnteringContext) + : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S), + SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext), + Result(SemaRef, TypoName, LookupKind), + Namespaces(SemaRef.Context, SemaRef.CurContext, SS), + EnteringContext(EnteringContext), SearchNamespaces(false) { + Result.suppressDiagnostics(); + } + + bool includeHiddenDecls() const override { return true; } + + // Methods for adding potential corrections to the consumer. + void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, + bool InBaseClass) override; + void FoundName(StringRef Name); + void addKeywordResult(StringRef Keyword); + void addCorrection(TypoCorrection Correction); + + bool empty() const { return CorrectionResults.empty(); } + + /// \brief Return the list of TypoCorrections for the given identifier from + /// the set of corrections that have the closest edit distance, if any. + TypoResultList &operator[](StringRef Name) { + return CorrectionResults.begin()->second[Name]; + } + + /// \brief Return the edit distance of the corrections that have the + /// closest/best edit distance from the original typop. + unsigned getBestEditDistance(bool Normalized) { + if (CorrectionResults.empty()) + return (std::numeric_limits<unsigned>::max)(); + + unsigned BestED = CorrectionResults.begin()->first; + return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED; + } + + /// \brief Set-up method to add to the consumer the set of namespaces to use + /// in performing corrections to nested name specifiers. This method also + /// implicitly adds all of the known classes in the current AST context to the + /// to the consumer for correcting nested name specifiers. + void + addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces); + + /// \brief Return the next typo correction that passes all internal filters + /// and is deemed valid by the consumer's CorrectionCandidateCallback, + /// starting with the corrections that have the closest edit distance. An + /// empty TypoCorrection is returned once no more viable corrections remain + /// in the consumer. + TypoCorrection getNextCorrection(); + +private: + class NamespaceSpecifierSet { + struct SpecifierInfo { + DeclContext* DeclCtx; + NestedNameSpecifier* NameSpecifier; + unsigned EditDistance; + }; + + typedef SmallVector<DeclContext*, 4> DeclContextList; + typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList; + + ASTContext &Context; + DeclContextList CurContextChain; + std::string CurNameSpecifier; + SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; + SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; + bool isSorted; + + SpecifierInfoList Specifiers; + llvm::SmallSetVector<unsigned, 4> Distances; + llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap; + + /// \brief Helper for building the list of DeclContexts between the current + /// context and the top of the translation unit + static DeclContextList buildContextChain(DeclContext *Start); + + void sortNamespaces(); + + unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, + NestedNameSpecifier *&NNS); + + public: + NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext, + CXXScopeSpec *CurScopeSpec); + + /// \brief Add the DeclContext (a namespace or record) to the set, computing + /// the corresponding NestedNameSpecifier and its distance in the process. + void addNameSpecifier(DeclContext *Ctx); + + typedef SpecifierInfoList::iterator iterator; + iterator begin() { + if (!isSorted) sortNamespaces(); + return Specifiers.begin(); + } + iterator end() { return Specifiers.end(); } + }; + + void addName(StringRef Name, NamedDecl *ND, + NestedNameSpecifier *NNS = nullptr, bool isKeyword = false); + + /// \brief Find any visible decls for the given typo correction candidate. + /// If none are found, it to the set of candidates for which qualified lookups + /// will be performed to find possible nested name specifier changes. + bool resolveCorrection(TypoCorrection &Candidate); + + /// \brief Perform qualified lookups on the queued set of typo correction + /// candidates and add the nested name specifier changes to each candidate if + /// a lookup succeeds (at which point the candidate will be returned to the + /// main pool of potential corrections). + void performQualifiedLookups(); + + /// \brief The name written that is a typo in the source. + IdentifierInfo *Typo; + + /// \brief The results found that have the smallest edit distance + /// found (so far) with the typo name. + /// + /// The pointer value being set to the current DeclContext indicates + /// whether there is a keyword with this name. + TypoEditDistanceMap CorrectionResults; + + Sema &SemaRef; + Scope *S; + CXXScopeSpec *SS; + CorrectionCandidateCallback &CorrectionValidator; + DeclContext *MemberContext; + LookupResult Result; + NamespaceSpecifierSet Namespaces; + SmallVector<TypoCorrection, 2> QualifiedResults; + bool EnteringContext; + bool SearchNamespaces; +}; + +} // end namespace clang #endif diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index cbeebb2ac98..b85ef5d8c46 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3320,157 +3320,6 @@ static void getNestedNameSpecifierIdentifiers( Identifiers.push_back(II); } -namespace { - -static const unsigned MaxTypoDistanceResultSets = 5; - -class TypoCorrectionConsumer : public VisibleDeclConsumer { - typedef SmallVector<TypoCorrection, 1> TypoResultList; - typedef llvm::StringMap<TypoResultList> TypoResultsMap; - typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; - -public: - explicit TypoCorrectionConsumer(Sema &SemaRef, - const DeclarationNameInfo &TypoName, - Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, - DeclContext *MemberContext, - bool EnteringContext) - : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S), - SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext), - Result(SemaRef, TypoName, LookupKind), - Namespaces(SemaRef.Context, SemaRef.CurContext, SS), - EnteringContext(EnteringContext), SearchNamespaces(false) { - Result.suppressDiagnostics(); - } - - bool includeHiddenDecls() const override { return true; } - - // Methods for adding potential corrections to the consumer. - void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, - bool InBaseClass) override; - void FoundName(StringRef Name); - void addKeywordResult(StringRef Keyword); - void addCorrection(TypoCorrection Correction); - - bool empty() const { return CorrectionResults.empty(); } - - /// \brief Return the list of TypoCorrections for the given identifier from - /// the set of corrections that have the closest edit distance, if any. - TypoResultList &operator[](StringRef Name) { - return CorrectionResults.begin()->second[Name]; - } - - /// \brief Return the edit distance of the corrections that have the - /// closest/best edit distance from the original typop. - unsigned getBestEditDistance(bool Normalized) { - if (CorrectionResults.empty()) - return (std::numeric_limits<unsigned>::max)(); - - unsigned BestED = CorrectionResults.begin()->first; - return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED; - } - - /// \brief Set-up method to add to the consumer the set of namespaces to use - /// in performing corrections to nested name specifiers. This method also - /// implicitly adds all of the known classes in the current AST context to the - /// to the consumer for correcting nested name specifiers. - void - addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces); - - /// \brief Return the next typo correction that passes all internal filters - /// and is deemed valid by the consumer's CorrectionCandidateCallback, - /// starting with the corrections that have the closest edit distance. An - /// empty TypoCorrection is returned once no more viable corrections remain - /// in the consumer. - TypoCorrection getNextCorrection(); - -private: - class NamespaceSpecifierSet { - struct SpecifierInfo { - DeclContext* DeclCtx; - NestedNameSpecifier* NameSpecifier; - unsigned EditDistance; - }; - - typedef SmallVector<DeclContext*, 4> DeclContextList; - typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList; - - ASTContext &Context; - DeclContextList CurContextChain; - std::string CurNameSpecifier; - SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; - SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; - bool isSorted; - - SpecifierInfoList Specifiers; - llvm::SmallSetVector<unsigned, 4> Distances; - llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap; - - /// \brief Helper for building the list of DeclContexts between the current - /// context and the top of the translation unit - static DeclContextList buildContextChain(DeclContext *Start); - - void sortNamespaces(); - - unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, - NestedNameSpecifier *&NNS); - - public: - NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext, - CXXScopeSpec *CurScopeSpec); - - /// \brief Add the DeclContext (a namespace or record) to the set, computing - /// the corresponding NestedNameSpecifier and its distance in the process. - void addNameSpecifier(DeclContext *Ctx); - - typedef SpecifierInfoList::iterator iterator; - iterator begin() { - if (!isSorted) sortNamespaces(); - return Specifiers.begin(); - } - iterator end() { return Specifiers.end(); } - }; - - void addName(StringRef Name, NamedDecl *ND, - NestedNameSpecifier *NNS = nullptr, bool isKeyword = false); - - /// \brief Find any visible decls for the given typo correction candidate. - /// If none are found, it to the set of candidates for which qualified lookups - /// will be performed to find possible nested name specifier changes. - bool resolveCorrection(TypoCorrection &Candidate); - - /// \brief Perform qualified lookups on the queued set of typo correction - /// candidates and add the nested name specifier changes to each candidate if - /// a lookup succeeds (at which point the candidate will be returned to the - /// main pool of potential corrections). - void performQualifiedLookups(); - - /// \brief The name written that is a typo in the source. - IdentifierInfo *Typo; - - /// \brief The results found that have the smallest edit distance - /// found (so far) with the typo name. - /// - /// The pointer value being set to the current DeclContext indicates - /// whether there is a keyword with this name. - TypoEditDistanceMap CorrectionResults; - - Sema &SemaRef; - Scope *S; - CXXScopeSpec *SS; - CorrectionCandidateCallback &CorrectionValidator; - DeclContext *MemberContext; - LookupResult Result; - NamespaceSpecifierSet Namespaces; - SmallVector<TypoCorrection, 2> QualifiedResults; - bool EnteringContext; - bool SearchNamespaces; -}; - -} - void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, bool InBaseClass) { // Don't consider hidden names for typo correction. @@ -3525,6 +3374,8 @@ void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND, addCorrection(TC); } +static const unsigned MaxTypoDistanceResultSets = 5; + void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) { StringRef TypoStr = Typo->getName(); StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName(); |