//===- CIndexer.h - Clang-C Source Indexing Library -------------*- 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 CIndexer, a subclass of Indexer that provides extra
// functionality needed by the CIndex library.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H

#include "clang-c/Index.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "llvm/ADT/STLExtras.h"
#include <utility>

namespace llvm {
  class CrashRecoveryContext;
}

namespace clang {
class ASTUnit;
class MacroInfo;
class MacroDefinitionRecord;
class SourceLocation;
class Token;
class IdentifierInfo;

class CIndexer {
  bool OnlyLocalDecls;
  bool DisplayDiagnostics;
  unsigned Options; // CXGlobalOptFlags.

  std::string ResourcesPath;
  std::shared_ptr<PCHContainerOperations> PCHContainerOps;

  std::string ToolchainPath;

  std::string InvocationEmissionPath;

public:
  CIndexer(std::shared_ptr<PCHContainerOperations> PCHContainerOps =
               std::make_shared<PCHContainerOperations>())
      : OnlyLocalDecls(false), DisplayDiagnostics(false),
        Options(CXGlobalOpt_None), PCHContainerOps(std::move(PCHContainerOps)) {
  }

  /// Whether we only want to see "local" declarations (that did not
  /// come from a previous precompiled header). If false, we want to see all
  /// declarations.
  bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
  void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
  
  bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
  void setDisplayDiagnostics(bool Display = true) {
    DisplayDiagnostics = Display;
  }

  std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
    return PCHContainerOps;
  }

  unsigned getCXGlobalOptFlags() const { return Options; }
  void setCXGlobalOptFlags(unsigned options) { Options = options; }

  bool isOptEnabled(CXGlobalOptFlags opt) const {
    return Options & opt;
  }

  /// Get the path of the clang resource files.
  const std::string &getClangResourcesPath();

  StringRef getClangToolchainPath();

  void setInvocationEmissionPath(StringRef Str) {
    InvocationEmissionPath = Str;
  }

  StringRef getInvocationEmissionPath() const { return InvocationEmissionPath; }
};

/// Logs information about a particular libclang operation like parsing to
/// a new file in the invocation emission path.
class LibclangInvocationReporter {
public:
  enum class OperationKind { ParseOperation, CompletionOperation };

  LibclangInvocationReporter(CIndexer &Idx, OperationKind Op,
                             unsigned ParseOptions,
                             llvm::ArrayRef<const char *> Args,
                             llvm::ArrayRef<std::string> InvocationArgs,
                             llvm::ArrayRef<CXUnsavedFile> UnsavedFiles);
  ~LibclangInvocationReporter();

private:
  std::string File;
};

  /// Return the current size to request for "safety".
  unsigned GetSafetyThreadStackSize();

  /// Set the current size to request for "safety" (or 0, if safety
  /// threads should not be used).
  void SetSafetyThreadStackSize(unsigned Value);

  /// Execution the given code "safely", using crash recovery or safety
  /// threads when possible.
  ///
  /// \return False if a crash was detected.
  bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
                 unsigned Size = 0);

  /// Set the thread priority to background.
  /// FIXME: Move to llvm/Support.
  void setThreadBackgroundPriority();

  /// Print libclang's resource usage to standard error.
  void PrintLibclangResourceUsage(CXTranslationUnit TU);

  namespace cxindex {
    void printDiagsToStderr(ASTUnit *Unit);

    /// If \c MacroDefLoc points at a macro definition with \c II as
    /// its name, this retrieves its MacroInfo.
    MacroInfo *getMacroInfo(const IdentifierInfo &II,
                            SourceLocation MacroDefLoc, CXTranslationUnit TU);

    /// Retrieves the corresponding MacroInfo of a MacroDefinitionRecord.
    const MacroInfo *getMacroInfo(const MacroDefinitionRecord *MacroDef,
                                  CXTranslationUnit TU);

    /// If \c Loc resides inside the definition of \c MI and it points at
    /// an identifier that has ever been a macro name, this returns the latest
    /// MacroDefinitionRecord for that name, otherwise it returns NULL.
    MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
                                                          SourceLocation Loc,
                                                          CXTranslationUnit TU);

    /// If \c Tok resides inside the definition of \c MI and it points at
    /// an identifier that has ever been a macro name, this returns the latest
    /// MacroDefinitionRecord for that name, otherwise it returns NULL.
    MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
                                                          const Token &Tok,
                                                          CXTranslationUnit TU);
    }
    }

#endif
