//===- CodeCompleteConsumer.h - Code Completion Interface -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  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/Sema/CodeCompleteOptions.h"
#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.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 <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 Sema;
class RawComment;

/// 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_Name,

    /// Code completion occurred where a new name is expected and a
    /// qualified name is permissible.
    CCC_PotentiallyQualifiedName,

    /// 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,

    /// 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;

  /// 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::"
  llvm::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), SelIdents(None) {}

  /// Construct a new code-completion context of the given kind.
  CodeCompletionContext(Kind CCKind, QualType T,
                        ArrayRef<IdentifierInfo *> SelIdents = None)
      : CCKind(CCKind), SelIdents(SelIdents) {
    if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess ||
        CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage ||
        CCKind == CCC_ObjCInstanceMessage)
      BaseType = T;
    else
      PreferredType = T;
  }

  /// 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; }

  /// 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;
  }

  llvm::Optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
    if (ScopeSpecifier)
      return ScopeSpecifier.getPointer();
    return llvm::None;
  }
};

/// Get string representation of \p Kind, useful for 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 TypedText chunk.
  const char *getTypedText() 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 llvm {

template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
  static const bool value = true;
};

} // namespace llvm

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 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;

  /// 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;

  /// 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),
        QualifierIsInformative(QualifierIsInformative),
        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
        DeclaringEntity(false), 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),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false) {}

  /// Build a result that refers to a macro.
  CodeCompletionResult(const IdentifierInfo *Macro,
                       unsigned Priority = CCP_Macro)
      : Macro(Macro), Priority(Priority), Kind(RK_Macro),
        CursorKind(CXCursor_MacroDefinition), Hidden(false),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false) {}

  /// 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),
        QualifierIsInformative(false), StartsNestedNameSpecifier(false),
        AllParametersAreInformative(false), DeclaringEntity(false) {}

  /// 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), QualifierIsInformative(false),
        StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
        DeclaringEntity(false) {
    computeCursorKindAndAvailability();
  }  
  
  /// Retrieve the declaration stored in this result.
  const NamedDecl *getDeclaration() const {
    assert(Kind == RK_Declaration && "Not a declaration 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);

  /// 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);
}

raw_ostream &operator<<(raw_ostream &OS,
                              const CodeCompletionString &CCS);

/// Abstract interface for a consumer of code-completion
/// information.
class CodeCompleteConsumer {
protected:
  const CodeCompleteOptions CodeCompleteOpts;

  /// Whether the output format for the code-completion consumer is
  /// binary.
  bool OutputIsBinary;

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.
      CK_FunctionTemplate,

      /// The "candidate" is actually a variable, expression, or block
      /// for which we only have a function prototype.
      CK_FunctionType
    };

  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;
    };

  public:
    OverloadCandidate(FunctionDecl *Function)
        : Kind(CK_Function), Function(Function) {}

    OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
        : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {}

    OverloadCandidate(const FunctionType *Type)
        : Kind(CK_FunctionType), Type(Type) {}

    /// 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;

    /// 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) const;
  };

  CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
                       bool OutputIsBinary)
      : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) {}

  /// 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;
  }

  /// Determine whether the output of this consumer is binary.
  bool isOutputBinary() const { return OutputIsBinary; }

  /// 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
  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
                                         OverloadCandidate *Candidates,
                                         unsigned NumCandidates) {}
  //@}

  /// 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, false), 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) 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
