diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h')
-rw-r--r-- | contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h | 1299 |
1 files changed, 1299 insertions, 0 deletions
diff --git a/contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h b/contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h new file mode 100644 index 0000000000..737c7cb07f --- /dev/null +++ b/contrib/libs/clang16/include/clang/Sema/CodeCompleteConsumer.h @@ -0,0 +1,1299 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- CodeCompleteConsumer.h - Code Completion Interface -------*- 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 CodeCompleteConsumer class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H +#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H + +#include "clang-c/Index.h" +#include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" +#include "clang/Lex/MacroInfo.h" +#include "clang/Sema/CodeCompleteOptions.h" +#include "clang/Sema/DeclSpec.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/type_traits.h" +#include <cassert> +#include <memory> +#include <optional> +#include <string> +#include <utility> + +namespace clang { + +class ASTContext; +class Decl; +class DeclContext; +class FunctionDecl; +class FunctionTemplateDecl; +class IdentifierInfo; +class LangOptions; +class NamedDecl; +class NestedNameSpecifier; +class Preprocessor; +class RawComment; +class Sema; +class UsingShadowDecl; + +/// Default priority values for code-completion results based +/// on their kind. +enum { + /// Priority for the next initialization in a constructor initializer + /// list. + CCP_NextInitializer = 7, + + /// Priority for an enumeration constant inside a switch whose + /// condition is of the enumeration type. + CCP_EnumInCase = 7, + + /// Priority for a send-to-super completion. + CCP_SuperCompletion = 20, + + /// Priority for a declaration that is in the local scope. + CCP_LocalDeclaration = 34, + + /// Priority for a member declaration found from the current + /// method or member function. + CCP_MemberDeclaration = 35, + + /// Priority for a language keyword (that isn't any of the other + /// categories). + CCP_Keyword = 40, + + /// Priority for a code pattern. + CCP_CodePattern = 40, + + /// Priority for a non-type declaration. + CCP_Declaration = 50, + + /// Priority for a type. + CCP_Type = CCP_Declaration, + + /// Priority for a constant value (e.g., enumerator). + CCP_Constant = 65, + + /// Priority for a preprocessor macro. + CCP_Macro = 70, + + /// Priority for a nested-name-specifier. + CCP_NestedNameSpecifier = 75, + + /// Priority for a result that isn't likely to be what the user wants, + /// but is included for completeness. + CCP_Unlikely = 80, + + /// Priority for the Objective-C "_cmd" implicit parameter. + CCP_ObjC_cmd = CCP_Unlikely +}; + +/// Priority value deltas that are added to code-completion results +/// based on the context of the result. +enum { + /// The result is in a base class. + CCD_InBaseClass = 2, + + /// The result is a C++ non-static member function whose qualifiers + /// exactly match the object type on which the member function can be called. + CCD_ObjectQualifierMatch = -1, + + /// The selector of the given message exactly matches the selector + /// of the current method, which might imply that some kind of delegation + /// is occurring. + CCD_SelectorMatch = -3, + + /// Adjustment to the "bool" type in Objective-C, where the typedef + /// "BOOL" is preferred. + CCD_bool_in_ObjC = 1, + + /// Adjustment for KVC code pattern priorities when it doesn't look + /// like the + CCD_ProbablyNotObjCCollection = 15, + + /// An Objective-C method being used as a property. + CCD_MethodAsProperty = 2, + + /// An Objective-C block property completed as a setter with a + /// block placeholder. + CCD_BlockPropertySetter = 3 +}; + +/// Priority value factors by which we will divide or multiply the +/// priority of a code-completion result. +enum { + /// Divide by this factor when a code-completion result's type exactly + /// matches the type we expect. + CCF_ExactTypeMatch = 4, + + /// Divide by this factor when a code-completion result's type is + /// similar to the type we expect (e.g., both arithmetic types, both + /// Objective-C object pointer types). + CCF_SimilarTypeMatch = 2 +}; + +/// A simplified classification of types used when determining +/// "similar" types for code completion. +enum SimplifiedTypeClass { + STC_Arithmetic, + STC_Array, + STC_Block, + STC_Function, + STC_ObjectiveC, + STC_Other, + STC_Pointer, + STC_Record, + STC_Void +}; + +/// Determine the simplified type class of the given canonical type. +SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T); + +/// Determine the type that this declaration will have if it is used +/// as a type or in an expression. +QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND); + +/// Determine the priority to be given to a macro code completion result +/// with the given name. +/// +/// \param MacroName The name of the macro. +/// +/// \param LangOpts Options describing the current language dialect. +/// +/// \param PreferredTypeIsPointer Whether the preferred type for the context +/// of this macro is a pointer type. +unsigned getMacroUsagePriority(StringRef MacroName, + const LangOptions &LangOpts, + bool PreferredTypeIsPointer = false); + +/// Determine the libclang cursor kind associated with the given +/// declaration. +CXCursorKind getCursorKindForDecl(const Decl *D); + +/// The context in which code completion occurred, so that the +/// code-completion consumer can process the results accordingly. +class CodeCompletionContext { +public: + enum Kind { + /// An unspecified code-completion context. + CCC_Other, + + /// An unspecified code-completion context where we should also add + /// macro completions. + CCC_OtherWithMacros, + + /// Code completion occurred within a "top-level" completion context, + /// e.g., at namespace or global scope. + CCC_TopLevel, + + /// Code completion occurred within an Objective-C interface, + /// protocol, or category interface. + CCC_ObjCInterface, + + /// Code completion occurred within an Objective-C implementation + /// or category implementation. + CCC_ObjCImplementation, + + /// Code completion occurred within the instance variable list of + /// an Objective-C interface, implementation, or category implementation. + CCC_ObjCIvarList, + + /// Code completion occurred within a class, struct, or union. + CCC_ClassStructUnion, + + /// Code completion occurred where a statement (or declaration) is + /// expected in a function, method, or block. + CCC_Statement, + + /// Code completion occurred where an expression is expected. + CCC_Expression, + + /// Code completion occurred where an Objective-C message receiver + /// is expected. + CCC_ObjCMessageReceiver, + + /// Code completion occurred on the right-hand side of a member + /// access expression using the dot operator. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_DotMemberAccess, + + /// Code completion occurred on the right-hand side of a member + /// access expression using the arrow operator. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_ArrowMemberAccess, + + /// Code completion occurred on the right-hand side of an Objective-C + /// property access expression. + /// + /// The results of this completion are the members of the type being + /// accessed. The type itself is available via + /// \c CodeCompletionContext::getType(). + CCC_ObjCPropertyAccess, + + /// Code completion occurred after the "enum" keyword, to indicate + /// an enumeration name. + CCC_EnumTag, + + /// Code completion occurred after the "union" keyword, to indicate + /// a union name. + CCC_UnionTag, + + /// Code completion occurred after the "struct" or "class" keyword, + /// to indicate a struct or class name. + CCC_ClassOrStructTag, + + /// Code completion occurred where a protocol name is expected. + CCC_ObjCProtocolName, + + /// Code completion occurred where a namespace or namespace alias + /// is expected. + CCC_Namespace, + + /// Code completion occurred where a type name is expected. + CCC_Type, + + /// Code completion occurred where a new name is expected. + CCC_NewName, + + /// Code completion occurred where both a new name and an existing symbol is + /// permissible. + CCC_SymbolOrNewName, + + /// Code completion occurred where an existing name(such as type, function + /// or variable) is expected. + CCC_Symbol, + + /// Code completion occurred where an macro is being defined. + CCC_MacroName, + + /// Code completion occurred where a macro name is expected + /// (without any arguments, in the case of a function-like macro). + CCC_MacroNameUse, + + /// Code completion occurred within a preprocessor expression. + CCC_PreprocessorExpression, + + /// Code completion occurred where a preprocessor directive is + /// expected. + CCC_PreprocessorDirective, + + /// Code completion occurred in a context where natural language is + /// expected, e.g., a comment or string literal. + /// + /// This context usually implies that no completions should be added, + /// unless they come from an appropriate natural-language dictionary. + CCC_NaturalLanguage, + + /// Code completion for a selector, as in an \@selector expression. + CCC_SelectorName, + + /// Code completion within a type-qualifier list. + CCC_TypeQualifiers, + + /// Code completion in a parenthesized expression, which means that + /// we may also have types here in C and Objective-C (as well as in C++). + CCC_ParenthesizedExpression, + + /// Code completion where an Objective-C instance message is + /// expected. + CCC_ObjCInstanceMessage, + + /// Code completion where an Objective-C class message is expected. + CCC_ObjCClassMessage, + + /// Code completion where the name of an Objective-C class is + /// expected. + CCC_ObjCInterfaceName, + + /// Code completion where an Objective-C category name is expected. + CCC_ObjCCategoryName, + + /// Code completion inside the filename part of a #include directive. + CCC_IncludedFile, + + /// Code completion of an attribute name. + CCC_Attribute, + + /// An unknown context, in which we are recovering from a parsing + /// error and don't know which completions we should give. + CCC_Recovery + }; + + using VisitedContextSet = llvm::SmallPtrSet<DeclContext *, 8>; + +private: + Kind CCKind; + + /// Indicates whether we are completing a name of a using declaration, e.g. + /// using ^; + /// using a::^; + bool IsUsingDeclaration; + + /// The type that would prefer to see at this point (e.g., the type + /// of an initializer or function parameter). + QualType PreferredType; + + /// The type of the base object in a member access expression. + QualType BaseType; + + /// The identifiers for Objective-C selector parts. + ArrayRef<IdentifierInfo *> SelIdents; + + /// The scope specifier that comes before the completion token e.g. + /// "a::b::" + std::optional<CXXScopeSpec> ScopeSpecifier; + + /// A set of declaration contexts visited by Sema when doing lookup for + /// code completion. + VisitedContextSet VisitedContexts; + +public: + /// Construct a new code-completion context of the given kind. + CodeCompletionContext(Kind CCKind) + : CCKind(CCKind), IsUsingDeclaration(false), SelIdents(std::nullopt) {} + + /// Construct a new code-completion context of the given kind. + CodeCompletionContext(Kind CCKind, QualType T, + ArrayRef<IdentifierInfo *> SelIdents = std::nullopt) + : CCKind(CCKind), IsUsingDeclaration(false), SelIdents(SelIdents) { + if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess || + CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage || + CCKind == CCC_ObjCInstanceMessage) + BaseType = T; + else + PreferredType = T; + } + + bool isUsingDeclaration() const { return IsUsingDeclaration; } + void setIsUsingDeclaration(bool V) { IsUsingDeclaration = V; } + + /// Retrieve the kind of code-completion context. + Kind getKind() const { return CCKind; } + + /// Retrieve the type that this expression would prefer to have, e.g., + /// if the expression is a variable initializer or a function argument, the + /// type of the corresponding variable or function parameter. + QualType getPreferredType() const { return PreferredType; } + void setPreferredType(QualType T) { PreferredType = T; } + + /// Retrieve the type of the base object in a member-access + /// expression. + QualType getBaseType() const { return BaseType; } + + /// Retrieve the Objective-C selector identifiers. + ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; } + + /// Determines whether we want C++ constructors as results within this + /// context. + bool wantConstructorResults() const; + + /// Sets the scope specifier that comes before the completion token. + /// This is expected to be set in code completions on qualfied specifiers + /// (e.g. "a::b::"). + void setCXXScopeSpecifier(CXXScopeSpec SS) { + this->ScopeSpecifier = std::move(SS); + } + + /// Adds a visited context. + void addVisitedContext(DeclContext *Ctx) { + VisitedContexts.insert(Ctx); + } + + /// Retrieves all visited contexts. + const VisitedContextSet &getVisitedContexts() const { + return VisitedContexts; + } + + std::optional<const CXXScopeSpec *> getCXXScopeSpecifier() { + if (ScopeSpecifier) + return &*ScopeSpecifier; + return std::nullopt; + } +}; + +/// Get string representation of \p Kind, useful for debugging. +llvm::StringRef getCompletionKindString(CodeCompletionContext::Kind Kind); + +/// A "string" used to describe how code completion can +/// be performed for an entity. +/// +/// A code completion string typically shows how a particular entity can be +/// used. For example, the code completion string for a function would show +/// the syntax to call it, including the parentheses, placeholders for the +/// arguments, etc. +class CodeCompletionString { +public: + /// The different kinds of "chunks" that can occur within a code + /// completion string. + enum ChunkKind { + /// The piece of text that the user is expected to type to + /// match the code-completion string, typically a keyword or the name of a + /// declarator or macro. + CK_TypedText, + + /// A piece of text that should be placed in the buffer, e.g., + /// parentheses or a comma in a function call. + CK_Text, + + /// A code completion string that is entirely optional. For example, + /// an optional code completion string that describes the default arguments + /// in a function call. + CK_Optional, + + /// A string that acts as a placeholder for, e.g., a function + /// call argument. + CK_Placeholder, + + /// A piece of text that describes something about the result but + /// should not be inserted into the buffer. + CK_Informative, + /// A piece of text that describes the type of an entity or, for + /// functions and methods, the return type. + CK_ResultType, + + /// A piece of text that describes the parameter that corresponds + /// to the code-completion location within a function call, message send, + /// macro invocation, etc. + CK_CurrentParameter, + + /// A left parenthesis ('('). + CK_LeftParen, + + /// A right parenthesis (')'). + CK_RightParen, + + /// A left bracket ('['). + CK_LeftBracket, + + /// A right bracket (']'). + CK_RightBracket, + + /// A left brace ('{'). + CK_LeftBrace, + + /// A right brace ('}'). + CK_RightBrace, + + /// A left angle bracket ('<'). + CK_LeftAngle, + + /// A right angle bracket ('>'). + CK_RightAngle, + + /// A comma separator (','). + CK_Comma, + + /// A colon (':'). + CK_Colon, + + /// A semicolon (';'). + CK_SemiColon, + + /// An '=' sign. + CK_Equal, + + /// Horizontal whitespace (' '). + CK_HorizontalSpace, + + /// Vertical whitespace ('\\n' or '\\r\\n', depending on the + /// platform). + CK_VerticalSpace + }; + + /// One piece of the code completion string. + struct Chunk { + /// The kind of data stored in this piece of the code completion + /// string. + ChunkKind Kind = CK_Text; + + union { + /// The text string associated with a CK_Text, CK_Placeholder, + /// CK_Informative, or CK_Comma chunk. + /// The string is owned by the chunk and will be deallocated + /// (with delete[]) when the chunk is destroyed. + const char *Text; + + /// The code completion string associated with a CK_Optional chunk. + /// The optional code completion string is owned by the chunk, and will + /// be deallocated (with delete) when the chunk is destroyed. + CodeCompletionString *Optional; + }; + + Chunk() : Text(nullptr) {} + + explicit Chunk(ChunkKind Kind, const char *Text = ""); + + /// Create a new text chunk. + static Chunk CreateText(const char *Text); + + /// Create a new optional chunk. + static Chunk CreateOptional(CodeCompletionString *Optional); + + /// Create a new placeholder chunk. + static Chunk CreatePlaceholder(const char *Placeholder); + + /// Create a new informative chunk. + static Chunk CreateInformative(const char *Informative); + + /// Create a new result type chunk. + static Chunk CreateResultType(const char *ResultType); + + /// Create a new current-parameter chunk. + static Chunk CreateCurrentParameter(const char *CurrentParameter); + }; + +private: + friend class CodeCompletionBuilder; + friend class CodeCompletionResult; + + /// The number of chunks stored in this string. + unsigned NumChunks : 16; + + /// The number of annotations for this code-completion result. + unsigned NumAnnotations : 16; + + /// The priority of this code-completion string. + unsigned Priority : 16; + + /// The availability of this code-completion result. + unsigned Availability : 2; + + /// The name of the parent context. + StringRef ParentName; + + /// A brief documentation comment attached to the declaration of + /// entity being completed by this result. + const char *BriefComment; + + CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, + unsigned Priority, CXAvailabilityKind Availability, + const char **Annotations, unsigned NumAnnotations, + StringRef ParentName, + const char *BriefComment); + ~CodeCompletionString() = default; + +public: + CodeCompletionString(const CodeCompletionString &) = delete; + CodeCompletionString &operator=(const CodeCompletionString &) = delete; + + using iterator = const Chunk *; + + iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); } + iterator end() const { return begin() + NumChunks; } + bool empty() const { return NumChunks == 0; } + unsigned size() const { return NumChunks; } + + const Chunk &operator[](unsigned I) const { + assert(I < size() && "Chunk index out-of-range"); + return begin()[I]; + } + + /// Returns the text in the first TypedText chunk. + const char *getTypedText() const; + + /// Returns the combined text from all TypedText chunks. + std::string getAllTypedText() const; + + /// Retrieve the priority of this code completion result. + unsigned getPriority() const { return Priority; } + + /// Retrieve the availability of this code completion result. + unsigned getAvailability() const { return Availability; } + + /// Retrieve the number of annotations for this code completion result. + unsigned getAnnotationCount() const; + + /// Retrieve the annotation string specified by \c AnnotationNr. + const char *getAnnotation(unsigned AnnotationNr) const; + + /// Retrieve the name of the parent context. + StringRef getParentContextName() const { + return ParentName; + } + + const char *getBriefComment() const { + return BriefComment; + } + + /// Retrieve a string representation of the code completion string, + /// which is mainly useful for debugging. + std::string getAsString() const; +}; + +/// An allocator used specifically for the purpose of code completion. +class CodeCompletionAllocator : public llvm::BumpPtrAllocator { +public: + /// Copy the given string into this allocator. + const char *CopyString(const Twine &String); +}; + +/// Allocator for a cached set of global code completions. +class GlobalCodeCompletionAllocator : public CodeCompletionAllocator {}; + +class CodeCompletionTUInfo { + llvm::DenseMap<const DeclContext *, StringRef> ParentNames; + std::shared_ptr<GlobalCodeCompletionAllocator> AllocatorRef; + +public: + explicit CodeCompletionTUInfo( + std::shared_ptr<GlobalCodeCompletionAllocator> Allocator) + : AllocatorRef(std::move(Allocator)) {} + + std::shared_ptr<GlobalCodeCompletionAllocator> getAllocatorRef() const { + return AllocatorRef; + } + + CodeCompletionAllocator &getAllocator() const { + assert(AllocatorRef); + return *AllocatorRef; + } + + StringRef getParentName(const DeclContext *DC); +}; + +} // namespace clang + +namespace clang { + +/// A builder class used to construct new code-completion strings. +class CodeCompletionBuilder { +public: + using Chunk = CodeCompletionString::Chunk; + +private: + CodeCompletionAllocator &Allocator; + CodeCompletionTUInfo &CCTUInfo; + unsigned Priority = 0; + CXAvailabilityKind Availability = CXAvailability_Available; + StringRef ParentName; + const char *BriefComment = nullptr; + + /// The chunks stored in this string. + SmallVector<Chunk, 4> Chunks; + + SmallVector<const char *, 2> Annotations; + +public: + CodeCompletionBuilder(CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo) + : Allocator(Allocator), CCTUInfo(CCTUInfo) {} + + CodeCompletionBuilder(CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + unsigned Priority, CXAvailabilityKind Availability) + : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(Priority), + Availability(Availability) {} + + /// Retrieve the allocator into which the code completion + /// strings should be allocated. + CodeCompletionAllocator &getAllocator() const { return Allocator; } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } + + /// Take the resulting completion string. + /// + /// This operation can only be performed once. + CodeCompletionString *TakeString(); + + /// Add a new typed-text chunk. + void AddTypedTextChunk(const char *Text); + + /// Add a new text chunk. + void AddTextChunk(const char *Text); + + /// Add a new optional chunk. + void AddOptionalChunk(CodeCompletionString *Optional); + + /// Add a new placeholder chunk. + void AddPlaceholderChunk(const char *Placeholder); + + /// Add a new informative chunk. + void AddInformativeChunk(const char *Text); + + /// Add a new result-type chunk. + void AddResultTypeChunk(const char *ResultType); + + /// Add a new current-parameter chunk. + void AddCurrentParameterChunk(const char *CurrentParameter); + + /// Add a new chunk. + void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text = ""); + + void AddAnnotation(const char *A) { Annotations.push_back(A); } + + /// Add the parent context information to this code completion. + void addParentContext(const DeclContext *DC); + + const char *getBriefComment() const { return BriefComment; } + void addBriefComment(StringRef Comment); + + StringRef getParentName() const { return ParentName; } +}; + +/// Captures a result of code completion. +class CodeCompletionResult { +public: + /// Describes the kind of result generated. + enum ResultKind { + /// Refers to a declaration. + RK_Declaration = 0, + + /// Refers to a keyword or symbol. + RK_Keyword, + + /// Refers to a macro. + RK_Macro, + + /// Refers to a precomputed pattern. + RK_Pattern + }; + + /// When Kind == RK_Declaration or RK_Pattern, the declaration we are + /// referring to. In the latter case, the declaration might be NULL. + const NamedDecl *Declaration = nullptr; + + union { + /// When Kind == RK_Keyword, the string representing the keyword + /// or symbol's spelling. + const char *Keyword; + + /// When Kind == RK_Pattern, the code-completion string that + /// describes the completion text to insert. + CodeCompletionString *Pattern; + + /// When Kind == RK_Macro, the identifier that refers to a macro. + const IdentifierInfo *Macro; + }; + + /// The priority of this particular code-completion result. + unsigned Priority; + + /// Specifies which parameter (of a function, Objective-C method, + /// macro, etc.) we should start with when formatting the result. + unsigned StartParameter = 0; + + /// The kind of result stored here. + ResultKind Kind; + + /// The cursor kind that describes this result. + CXCursorKind CursorKind; + + /// The availability of this result. + CXAvailabilityKind Availability = CXAvailability_Available; + + /// Fix-its that *must* be applied before inserting the text for the + /// corresponding completion. + /// + /// By default, CodeCompletionBuilder only returns completions with empty + /// fix-its. Extra completions with non-empty fix-its should be explicitly + /// requested by setting CompletionOptions::IncludeFixIts. + /// + /// For the clients to be able to compute position of the cursor after + /// applying fix-its, the following conditions are guaranteed to hold for + /// RemoveRange of the stored fix-its: + /// - Ranges in the fix-its are guaranteed to never contain the completion + /// point (or identifier under completion point, if any) inside them, except + /// at the start or at the end of the range. + /// - If a fix-it range starts or ends with completion point (or starts or + /// ends after the identifier under completion point), it will contain at + /// least one character. It allows to unambiguously recompute completion + /// point after applying the fix-it. + /// + /// The intuition is that provided fix-its change code around the identifier + /// we complete, but are not allowed to touch the identifier itself or the + /// completion point. One example of completions with corrections are the ones + /// replacing '.' with '->' and vice versa: + /// + /// std::unique_ptr<std::vector<int>> vec_ptr; + /// In 'vec_ptr.^', one of the completions is 'push_back', it requires + /// replacing '.' with '->'. + /// In 'vec_ptr->^', one of the completions is 'release', it requires + /// replacing '->' with '.'. + std::vector<FixItHint> FixIts; + + /// Whether this result is hidden by another name. + bool Hidden : 1; + + /// Whether this is a class member from base class. + bool InBaseClass : 1; + + /// Whether this result was found via lookup into a base class. + bool QualifierIsInformative : 1; + + /// Whether this declaration is the beginning of a + /// nested-name-specifier and, therefore, should be followed by '::'. + bool StartsNestedNameSpecifier : 1; + + /// Whether all parameters (of a function, Objective-C + /// method, etc.) should be considered "informative". + bool AllParametersAreInformative : 1; + + /// Whether we're completing a declaration of the given entity, + /// rather than a use of that entity. + bool DeclaringEntity : 1; + + /// When completing a function, whether it can be a call. This will usually be + /// true, but we have some heuristics, e.g. when a pointer to a non-static + /// member function is completed outside of that class' scope, it can never + /// be a call. + bool FunctionCanBeCall : 1; + + /// If the result should have a nested-name-specifier, this is it. + /// When \c QualifierIsInformative, the nested-name-specifier is + /// informative rather than required. + NestedNameSpecifier *Qualifier = nullptr; + + /// If this Decl was unshadowed by using declaration, this can store a + /// pointer to the UsingShadowDecl which was used in the unshadowing process. + /// This information can be used to uprank CodeCompletionResults / which have + /// corresponding `using decl::qualified::name;` nearby. + const UsingShadowDecl *ShadowDecl = nullptr; + + /// If the result is RK_Macro, this can store the information about the macro + /// definition. This should be set in most cases but can be missing when + /// the macro has been undefined. + const MacroInfo *MacroDefInfo = nullptr; + + /// Build a result that refers to a declaration. + CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority, + NestedNameSpecifier *Qualifier = nullptr, + bool QualifierIsInformative = false, + bool Accessible = true, + std::vector<FixItHint> FixIts = std::vector<FixItHint>()) + : Declaration(Declaration), Priority(Priority), Kind(RK_Declaration), + FixIts(std::move(FixIts)), Hidden(false), InBaseClass(false), + QualifierIsInformative(QualifierIsInformative), + StartsNestedNameSpecifier(false), AllParametersAreInformative(false), + DeclaringEntity(false), FunctionCanBeCall(true), Qualifier(Qualifier) { + // FIXME: Add assert to check FixIts range requirements. + computeCursorKindAndAvailability(Accessible); + } + + /// Build a result that refers to a keyword or symbol. + CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword) + : Keyword(Keyword), Priority(Priority), Kind(RK_Keyword), + CursorKind(CXCursor_NotImplemented), Hidden(false), InBaseClass(false), + QualifierIsInformative(false), StartsNestedNameSpecifier(false), + AllParametersAreInformative(false), DeclaringEntity(false), + FunctionCanBeCall(true) {} + + /// Build a result that refers to a macro. + CodeCompletionResult(const IdentifierInfo *Macro, + const MacroInfo *MI = nullptr, + unsigned Priority = CCP_Macro) + : Macro(Macro), Priority(Priority), Kind(RK_Macro), + CursorKind(CXCursor_MacroDefinition), Hidden(false), InBaseClass(false), + QualifierIsInformative(false), StartsNestedNameSpecifier(false), + AllParametersAreInformative(false), DeclaringEntity(false), + FunctionCanBeCall(true), MacroDefInfo(MI) {} + + /// Build a result that refers to a pattern. + CodeCompletionResult( + CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern, + CXCursorKind CursorKind = CXCursor_NotImplemented, + CXAvailabilityKind Availability = CXAvailability_Available, + const NamedDecl *D = nullptr) + : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern), + CursorKind(CursorKind), Availability(Availability), Hidden(false), + InBaseClass(false), QualifierIsInformative(false), + StartsNestedNameSpecifier(false), AllParametersAreInformative(false), + DeclaringEntity(false), FunctionCanBeCall(true) {} + + /// Build a result that refers to a pattern with an associated + /// declaration. + CodeCompletionResult(CodeCompletionString *Pattern, const NamedDecl *D, + unsigned Priority) + : Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern), + Hidden(false), InBaseClass(false), QualifierIsInformative(false), + StartsNestedNameSpecifier(false), AllParametersAreInformative(false), + DeclaringEntity(false), FunctionCanBeCall(true) { + computeCursorKindAndAvailability(); + } + + /// Retrieve the declaration stored in this result. This might be nullptr if + /// Kind is RK_Pattern. + const NamedDecl *getDeclaration() const { + assert(((Kind == RK_Declaration) || (Kind == RK_Pattern)) && + "Not a declaration or pattern result"); + return Declaration; + } + + /// Retrieve the keyword stored in this result. + const char *getKeyword() const { + assert(Kind == RK_Keyword && "Not a keyword result"); + return Keyword; + } + + /// Create a new code-completion string that describes how to insert + /// this result into a program. + /// + /// \param S The semantic analysis that created the result. + /// + /// \param Allocator The allocator that will be used to allocate the + /// string itself. + CodeCompletionString *CreateCodeCompletionString(Sema &S, + const CodeCompletionContext &CCContext, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments); + CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx, + Preprocessor &PP, + const CodeCompletionContext &CCContext, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments); + /// Creates a new code-completion string for the macro result. Similar to the + /// above overloads, except this only requires preprocessor information. + /// The result kind must be `RK_Macro`. + CodeCompletionString * + CreateCodeCompletionStringForMacro(Preprocessor &PP, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo); + + CodeCompletionString *createCodeCompletionStringForDecl( + Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, + bool IncludeBriefComments, const CodeCompletionContext &CCContext, + PrintingPolicy &Policy); + + CodeCompletionString *createCodeCompletionStringForOverride( + Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, + bool IncludeBriefComments, const CodeCompletionContext &CCContext, + PrintingPolicy &Policy); + + /// Retrieve the name that should be used to order a result. + /// + /// If the name needs to be constructed as a string, that string will be + /// saved into Saved and the returned StringRef will refer to it. + StringRef getOrderedName(std::string &Saved) const; + +private: + void computeCursorKindAndAvailability(bool Accessible = true); +}; + +bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y); + +inline bool operator>(const CodeCompletionResult &X, + const CodeCompletionResult &Y) { + return Y < X; +} + +inline bool operator<=(const CodeCompletionResult &X, + const CodeCompletionResult &Y) { + return !(Y < X); +} + +inline bool operator>=(const CodeCompletionResult &X, + const CodeCompletionResult &Y) { + return !(X < Y); +} + +/// Abstract interface for a consumer of code-completion +/// information. +class CodeCompleteConsumer { +protected: + const CodeCompleteOptions CodeCompleteOpts; + +public: + class OverloadCandidate { + public: + /// Describes the type of overload candidate. + enum CandidateKind { + /// The candidate is a function declaration. + CK_Function, + + /// The candidate is a function template, arguments are being completed. + CK_FunctionTemplate, + + /// The "candidate" is actually a variable, expression, or block + /// for which we only have a function prototype. + CK_FunctionType, + + /// The candidate is a variable or expression of function type + /// for which we have the location of the prototype declaration. + CK_FunctionProtoTypeLoc, + + /// The candidate is a template, template arguments are being completed. + CK_Template, + + /// The candidate is aggregate initialization of a record type. + CK_Aggregate, + }; + + private: + /// The kind of overload candidate. + CandidateKind Kind; + + union { + /// The function overload candidate, available when + /// Kind == CK_Function. + FunctionDecl *Function; + + /// The function template overload candidate, available when + /// Kind == CK_FunctionTemplate. + FunctionTemplateDecl *FunctionTemplate; + + /// The function type that describes the entity being called, + /// when Kind == CK_FunctionType. + const FunctionType *Type; + + /// The location of the function prototype that describes the entity being + /// called, when Kind == CK_FunctionProtoTypeLoc. + FunctionProtoTypeLoc ProtoTypeLoc; + + /// The template overload candidate, available when + /// Kind == CK_Template. + const TemplateDecl *Template; + + /// The class being aggregate-initialized, + /// when Kind == CK_Aggregate + const RecordDecl *AggregateType; + }; + + public: + OverloadCandidate(FunctionDecl *Function) + : Kind(CK_Function), Function(Function) { + assert(Function != nullptr); + } + + OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl) + : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { + assert(FunctionTemplateDecl != nullptr); + } + + OverloadCandidate(const FunctionType *Type) + : Kind(CK_FunctionType), Type(Type) { + assert(Type != nullptr); + } + + OverloadCandidate(FunctionProtoTypeLoc Prototype) + : Kind(CK_FunctionProtoTypeLoc), ProtoTypeLoc(Prototype) { + assert(!Prototype.isNull()); + } + + OverloadCandidate(const RecordDecl *Aggregate) + : Kind(CK_Aggregate), AggregateType(Aggregate) { + assert(Aggregate != nullptr); + } + + OverloadCandidate(const TemplateDecl *Template) + : Kind(CK_Template), Template(Template) {} + + /// Determine the kind of overload candidate. + CandidateKind getKind() const { return Kind; } + + /// Retrieve the function overload candidate or the templated + /// function declaration for a function template. + FunctionDecl *getFunction() const; + + /// Retrieve the function template overload candidate. + FunctionTemplateDecl *getFunctionTemplate() const { + assert(getKind() == CK_FunctionTemplate && "Not a function template"); + return FunctionTemplate; + } + + /// Retrieve the function type of the entity, regardless of how the + /// function is stored. + const FunctionType *getFunctionType() const; + + /// Retrieve the function ProtoTypeLoc candidate. + /// This can be called for any Kind, but returns null for kinds + /// other than CK_FunctionProtoTypeLoc. + const FunctionProtoTypeLoc getFunctionProtoTypeLoc() const; + + const TemplateDecl *getTemplate() const { + assert(getKind() == CK_Template && "Not a template"); + return Template; + } + + /// Retrieve the aggregate type being initialized. + const RecordDecl *getAggregate() const { + assert(getKind() == CK_Aggregate); + return AggregateType; + } + + /// Get the number of parameters in this signature. + unsigned getNumParams() const; + + /// Get the type of the Nth parameter. + /// Returns null if the type is unknown or N is out of range. + QualType getParamType(unsigned N) const; + + /// Get the declaration of the Nth parameter. + /// Returns null if the decl is unknown or N is out of range. + const NamedDecl *getParamDecl(unsigned N) const; + + /// Create a new code-completion string that describes the function + /// signature of this overload candidate. + CodeCompletionString * + CreateSignatureString(unsigned CurrentArg, Sema &S, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments, bool Braced) const; + }; + + CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts) + : CodeCompleteOpts(CodeCompleteOpts) {} + + /// Whether the code-completion consumer wants to see macros. + bool includeMacros() const { + return CodeCompleteOpts.IncludeMacros; + } + + /// Whether the code-completion consumer wants to see code patterns. + bool includeCodePatterns() const { + return CodeCompleteOpts.IncludeCodePatterns; + } + + /// Whether to include global (top-level) declaration results. + bool includeGlobals() const { return CodeCompleteOpts.IncludeGlobals; } + + /// Whether to include declarations in namespace contexts (including + /// the global namespace). If this is false, `includeGlobals()` will be + /// ignored. + bool includeNamespaceLevelDecls() const { + return CodeCompleteOpts.IncludeNamespaceLevelDecls; + } + + /// Whether to include brief documentation comments within the set of + /// code completions returned. + bool includeBriefComments() const { + return CodeCompleteOpts.IncludeBriefComments; + } + + /// Whether to include completion items with small fix-its, e.g. change + /// '.' to '->' on member access, etc. + bool includeFixIts() const { return CodeCompleteOpts.IncludeFixIts; } + + /// Hint whether to load data from the external AST in order to provide + /// full results. If false, declarations from the preamble may be omitted. + bool loadExternal() const { + return CodeCompleteOpts.LoadExternal; + } + + /// Deregisters and destroys this code-completion consumer. + virtual ~CodeCompleteConsumer(); + + /// \name Code-completion filtering + /// Check if the result should be filtered out. + virtual bool isResultFilteredOut(StringRef Filter, + CodeCompletionResult Results) { + return false; + } + + /// \name Code-completion callbacks + //@{ + /// Process the finalized code-completion results. + virtual void ProcessCodeCompleteResults(Sema &S, + CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) {} + + /// \param S the semantic-analyzer object for which code-completion is being + /// done. + /// + /// \param CurrentArg the index of the current argument. + /// + /// \param Candidates an array of overload candidates. + /// + /// \param NumCandidates the number of overload candidates + /// + /// \param OpenParLoc location of the opening parenthesis of the argument + /// list. + virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates, + SourceLocation OpenParLoc, + bool Braced) {} + //@} + + /// Retrieve the allocator that will be used to allocate + /// code completion strings. + virtual CodeCompletionAllocator &getAllocator() = 0; + + virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0; +}; + +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for RK_Declaration. +const RawComment *getCompletionComment(const ASTContext &Ctx, + const NamedDecl *Decl); + +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for RK_Pattern. +const RawComment *getPatternCompletionComment(const ASTContext &Ctx, + const NamedDecl *Decl); + +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for OverloadCandidate. +const RawComment * +getParameterComment(const ASTContext &Ctx, + const CodeCompleteConsumer::OverloadCandidate &Result, + unsigned ArgIndex); + +/// A simple code-completion consumer that prints the results it +/// receives in a simple format. +class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { + /// The raw output stream. + raw_ostream &OS; + + CodeCompletionTUInfo CCTUInfo; + +public: + /// Create a new printing code-completion consumer that prints its + /// results to the given raw output stream. + PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, + raw_ostream &OS) + : CodeCompleteConsumer(CodeCompleteOpts), OS(OS), + CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {} + + /// Prints the finalized code-completion results. + void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override; + + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates, + SourceLocation OpenParLoc, + bool Braced) override; + + bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override; + + CodeCompletionAllocator &getAllocator() override { + return CCTUInfo.getAllocator(); + } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } +}; + +} // namespace clang + +#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |