003 File Manager
Current Path:
/usr/src/contrib/llvm-project/clang/include/clang/Sema
usr
/
src
/
contrib
/
llvm-project
/
clang
/
include
/
clang
/
Sema
/
📁
..
📄
AnalysisBasedWarnings.h
(2.72 KB)
📄
CXXFieldCollector.h
(2.5 KB)
📄
CleanupInfo.h
(1.28 KB)
📄
CodeCompleteConsumer.h
(41.13 KB)
📄
CodeCompleteOptions.h
(1.85 KB)
📄
DeclSpec.h
(98.42 KB)
📄
DelayedDiagnostic.h
(10.8 KB)
📄
Designator.h
(6.43 KB)
📄
ExternalSemaSource.h
(9.7 KB)
📄
IdentifierResolver.h
(6.46 KB)
📄
Initialization.h
(48.15 KB)
📄
Lookup.h
(25.5 KB)
📄
MultiplexExternalSemaSource.h
(15.39 KB)
📄
ObjCMethodList.h
(2.21 KB)
📄
Overload.h
(41.57 KB)
📄
Ownership.h
(9.58 KB)
📄
ParsedAttr.h
(39.62 KB)
📄
ParsedTemplate.h
(9.9 KB)
📄
Scope.h
(17.01 KB)
📄
ScopeInfo.h
(36.31 KB)
📄
Sema.h
(569.19 KB)
📄
SemaConcept.h
(5.51 KB)
📄
SemaConsumer.h
(1.49 KB)
📄
SemaDiagnostic.h
(501 B)
📄
SemaFixItUtils.h
(3.21 KB)
📄
SemaInternal.h
(12.72 KB)
📄
SemaLambda.h
(1.28 KB)
📄
Template.h
(23.11 KB)
📄
TemplateDeduction.h
(12.2 KB)
📄
TemplateInstCallback.h
(2.55 KB)
📄
TypoCorrection.h
(15.04 KB)
📄
Weak.h
(1.54 KB)
Editing: TypoCorrection.h
//===- TypoCorrection.h - Class for typo correction results -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the TypoCorrection class, which stores the results of // Sema's typo correction (Sema::CorrectTypo). // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H #define LLVM_CLANG_SEMA_TYPOCORRECTION_H #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/DeclSpec.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include <cstddef> #include <limits> #include <string> #include <utility> #include <vector> namespace clang { class DeclContext; class IdentifierInfo; class LangOptions; class MemberExpr; class NestedNameSpecifier; class Sema; /// Simple class containing the result of Sema::CorrectTypo class TypoCorrection { public: // "Distance" for unusable corrections static const unsigned InvalidDistance = std::numeric_limits<unsigned>::max(); // The largest distance still considered valid (larger edit distances are // mapped to InvalidDistance by getEditDistance). static const unsigned MaximumDistance = 10000U; // Relative weightings of the "edit distance" components. The higher the // weight, the more of a penalty to fitness the component will give (higher // weights mean greater contribution to the total edit distance, with the // best correction candidates having the lowest edit distance). static const unsigned CharDistanceWeight = 100U; static const unsigned QualifierDistanceWeight = 110U; static const unsigned CallbackDistanceWeight = 150U; TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0, unsigned QualifierDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), CharDistance(CharDistance), QualifierDistance(QualifierDistance) { if (NameDecl) CorrectionDecls.push_back(NameDecl); } TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0) : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS), CharDistance(CharDistance) { if (Name) CorrectionDecls.push_back(Name); } TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), CharDistance(CharDistance) {} TypoCorrection() = default; /// Gets the DeclarationName of the typo correction DeclarationName getCorrection() const { return CorrectionName; } IdentifierInfo *getCorrectionAsIdentifierInfo() const { return CorrectionName.getAsIdentifierInfo(); } /// Gets the NestedNameSpecifier needed to use the typo correction NestedNameSpecifier *getCorrectionSpecifier() const { return CorrectionNameSpec; } void setCorrectionSpecifier(NestedNameSpecifier *NNS) { CorrectionNameSpec = NNS; ForceSpecifierReplacement = (NNS != nullptr); } void WillReplaceSpecifier(bool ForceReplacement) { ForceSpecifierReplacement = ForceReplacement; } bool WillReplaceSpecifier() const { return ForceSpecifierReplacement; } void setQualifierDistance(unsigned ED) { QualifierDistance = ED; } void setCallbackDistance(unsigned ED) { CallbackDistance = ED; } // Convert the given weighted edit distance to a roughly equivalent number of // single-character edits (typically for comparison to the length of the // string being edited). static unsigned NormalizeEditDistance(unsigned ED) { if (ED > MaximumDistance) return InvalidDistance; return (ED + CharDistanceWeight / 2) / CharDistanceWeight; } /// Gets the "edit distance" of the typo correction from the typo. /// If Normalized is true, scale the distance down by the CharDistanceWeight /// to return the edit distance in terms of single-character edits. unsigned getEditDistance(bool Normalized = true) const { if (CharDistance > MaximumDistance || QualifierDistance > MaximumDistance || CallbackDistance > MaximumDistance) return InvalidDistance; unsigned ED = CharDistance * CharDistanceWeight + QualifierDistance * QualifierDistanceWeight + CallbackDistance * CallbackDistanceWeight; if (ED > MaximumDistance) return InvalidDistance; // Half the CharDistanceWeight is added to ED to simulate rounding since // integer division truncates the value (i.e. round-to-nearest-int instead // of round-to-zero). return Normalized ? NormalizeEditDistance(ED) : ED; } /// Get the correction declaration found by name lookup (before we /// looked through using shadow declarations and the like). NamedDecl *getFoundDecl() const { return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr; } /// Gets the pointer to the declaration of the typo correction NamedDecl *getCorrectionDecl() const { auto *D = getFoundDecl(); return D ? D->getUnderlyingDecl() : nullptr; } template <class DeclClass> DeclClass *getCorrectionDeclAs() const { return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); } /// Clears the list of NamedDecls. void ClearCorrectionDecls() { CorrectionDecls.clear(); } /// Clears the list of NamedDecls before adding the new one. void setCorrectionDecl(NamedDecl *CDecl) { CorrectionDecls.clear(); addCorrectionDecl(CDecl); } /// Clears the list of NamedDecls and adds the given set. void setCorrectionDecls(ArrayRef<NamedDecl*> Decls) { CorrectionDecls.clear(); CorrectionDecls.insert(CorrectionDecls.begin(), Decls.begin(), Decls.end()); } /// Add the given NamedDecl to the list of NamedDecls that are the /// declarations associated with the DeclarationName of this TypoCorrection void addCorrectionDecl(NamedDecl *CDecl); std::string getAsString(const LangOptions &LO) const; std::string getQuoted(const LangOptions &LO) const { return "'" + getAsString(LO) + "'"; } /// Returns whether this TypoCorrection has a non-empty DeclarationName explicit operator bool() const { return bool(CorrectionName); } /// Mark this TypoCorrection as being a keyword. /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be /// added to the list of the correction's NamedDecl pointers, NULL is added /// as the only element in the list to mark this TypoCorrection as a keyword. void makeKeyword() { CorrectionDecls.clear(); CorrectionDecls.push_back(nullptr); ForceSpecifierReplacement = true; } // Check if this TypoCorrection is a keyword by checking if the first // item in CorrectionDecls is NULL. bool isKeyword() const { return !CorrectionDecls.empty() && CorrectionDecls.front() == nullptr; } // Check if this TypoCorrection is the given keyword. template<std::size_t StrLen> bool isKeyword(const char (&Str)[StrLen]) const { return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str); } // Returns true if the correction either is a keyword or has a known decl. bool isResolved() const { return !CorrectionDecls.empty(); } bool isOverloaded() const { return CorrectionDecls.size() > 1; } void setCorrectionRange(CXXScopeSpec *SS, const DeclarationNameInfo &TypoName) { CorrectionRange = TypoName.getSourceRange(); if (ForceSpecifierReplacement && SS && !SS->isEmpty()) CorrectionRange.setBegin(SS->getBeginLoc()); } SourceRange getCorrectionRange() const { return CorrectionRange; } using decl_iterator = SmallVectorImpl<NamedDecl *>::iterator; decl_iterator begin() { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); } decl_iterator end() { return CorrectionDecls.end(); } using const_decl_iterator = SmallVectorImpl<NamedDecl *>::const_iterator; const_decl_iterator begin() const { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); } const_decl_iterator end() const { return CorrectionDecls.end(); } /// Returns whether this typo correction is correcting to a /// declaration that was declared in a module that has not been imported. bool requiresImport() const { return RequiresImport; } void setRequiresImport(bool Req) { RequiresImport = Req; } /// Extra diagnostics are printed after the first diagnostic for the typo. /// This can be used to attach external notes to the diag. void addExtraDiagnostic(PartialDiagnostic PD) { ExtraDiagnostics.push_back(std::move(PD)); } ArrayRef<PartialDiagnostic> getExtraDiagnostics() const { return ExtraDiagnostics; } private: bool hasCorrectionDecl() const { return (!isKeyword() && !CorrectionDecls.empty()); } // Results. DeclarationName CorrectionName; NestedNameSpecifier *CorrectionNameSpec = nullptr; SmallVector<NamedDecl *, 1> CorrectionDecls; unsigned CharDistance = 0; unsigned QualifierDistance = 0; unsigned CallbackDistance = 0; SourceRange CorrectionRange; bool ForceSpecifierReplacement = false; bool RequiresImport = false; std::vector<PartialDiagnostic> ExtraDiagnostics; }; /// Base class for callback objects used by Sema::CorrectTypo to check /// the validity of a potential typo correction. class CorrectionCandidateCallback { public: static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr, NestedNameSpecifier *TypoNNS = nullptr) : Typo(Typo), TypoNNS(TypoNNS) {} virtual ~CorrectionCandidateCallback() = default; /// Simple predicate used by the default RankCandidate to /// determine whether to return an edit distance of 0 or InvalidDistance. /// This can be overridden by validators that only need to determine if a /// candidate is viable, without ranking potentially viable candidates. /// Only ValidateCandidate or RankCandidate need to be overridden by a /// callback wishing to check the viability of correction candidates. /// The default predicate always returns true if the candidate is not a type /// name or keyword, true for types if WantTypeSpecifiers is true, and true /// for keywords if WantTypeSpecifiers, WantExpressionKeywords, /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true. virtual bool ValidateCandidate(const TypoCorrection &candidate); /// Method used by Sema::CorrectTypo to assign an "edit distance" rank /// to a candidate (where a lower value represents a better candidate), or /// returning InvalidDistance if the candidate is not at all viable. For /// validation callbacks that only need to determine if a candidate is viable, /// the default RankCandidate returns either 0 or InvalidDistance depending /// whether ValidateCandidate returns true or false. virtual unsigned RankCandidate(const TypoCorrection &candidate) { return (!MatchesTypo(candidate) && ValidateCandidate(candidate)) ? 0 : InvalidDistance; } /// Clone this CorrectionCandidateCallback. CorrectionCandidateCallbacks are /// initially stack-allocated. However in case where delayed typo-correction /// is done we need to move the callback to storage with a longer lifetime. /// Every class deriving from CorrectionCandidateCallback must implement /// this method. virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0; void setTypoName(IdentifierInfo *II) { Typo = II; } void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; } // Flags for context-dependent keywords. WantFunctionLikeCasts is only // used/meaningful when WantCXXNamedCasts is false. // TODO: Expand these to apply to non-keywords or possibly remove them. bool WantTypeSpecifiers = true; bool WantExpressionKeywords = true; bool WantCXXNamedCasts = true; bool WantFunctionLikeCasts = true; bool WantRemainingKeywords = true; bool WantObjCSuper = false; // Temporary hack for the one case where a CorrectTypoContext enum is used // when looking up results. bool IsObjCIvarLookup = false; bool IsAddressOfOperand = false; protected: bool MatchesTypo(const TypoCorrection &candidate) { return Typo && candidate.isResolved() && !candidate.requiresImport() && candidate.getCorrectionAsIdentifierInfo() == Typo && // FIXME: This probably does not return true when both // NestedNameSpecifiers have the same textual representation. candidate.getCorrectionSpecifier() == TypoNNS; } IdentifierInfo *Typo; NestedNameSpecifier *TypoNNS; }; class DefaultFilterCCC final : public CorrectionCandidateCallback { public: explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr, NestedNameSpecifier *TypoNNS = nullptr) : CorrectionCandidateCallback(Typo, TypoNNS) {} std::unique_ptr<CorrectionCandidateCallback> clone() override { return std::make_unique<DefaultFilterCCC>(*this); } }; /// Simple template class for restricting typo correction candidates /// to ones having a single Decl* of the given type. template <class C> class DeclFilterCCC final : public CorrectionCandidateCallback { public: bool ValidateCandidate(const TypoCorrection &candidate) override { return candidate.getCorrectionDeclAs<C>(); } std::unique_ptr<CorrectionCandidateCallback> clone() override { return std::make_unique<DeclFilterCCC>(*this); } }; // Callback class to limit the allowed keywords and to only accept typo // corrections that are keywords or whose decls refer to functions (or template // functions) that accept the given number of arguments. class FunctionCallFilterCCC : public CorrectionCandidateCallback { public: FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, bool HasExplicitTemplateArgs, MemberExpr *ME = nullptr); bool ValidateCandidate(const TypoCorrection &candidate) override; std::unique_ptr<CorrectionCandidateCallback> clone() override { return std::make_unique<FunctionCallFilterCCC>(*this); } private: unsigned NumArgs; bool HasExplicitTemplateArgs; DeclContext *CurContext; MemberExpr *MemberFn; }; // Callback class that effectively disabled typo correction class NoTypoCorrectionCCC final : public CorrectionCandidateCallback { public: NoTypoCorrectionCCC() { WantTypeSpecifiers = false; WantExpressionKeywords = false; WantCXXNamedCasts = false; WantFunctionLikeCasts = false; WantRemainingKeywords = false; } bool ValidateCandidate(const TypoCorrection &candidate) override { return false; } std::unique_ptr<CorrectionCandidateCallback> clone() override { return std::make_unique<NoTypoCorrectionCCC>(*this); } }; } // namespace clang #endif // LLVM_CLANG_SEMA_TYPOCORRECTION_H
Upload File
Create Folder