//===- CXCursor.h - Routines for manipulating CXCursors -------------------===//
//
// 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 routines for manipulating CXCursors.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H

#include "clang-c/Index.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerUnion.h"
#include <utility>

namespace clang {

class ASTContext;
class ASTUnit;
class Attr;
class CXXBaseSpecifier;
class Decl;
class Expr;
class FieldDecl;
class InclusionDirective;
class LabelStmt;
class MacroDefinitionRecord;
class MacroExpansion;
class NamedDecl;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class OverloadedTemplateStorage;
class OverloadExpr;
class Stmt;
class TemplateDecl;
class TemplateName;
class TypeDecl;
class VarDecl;
class IdentifierInfo;

namespace cxcursor {

CXCursor getCursor(CXTranslationUnit, SourceLocation);

CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
                      CXTranslationUnit TU);
CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
                      SourceRange RegionOfInterest = SourceRange(),
                      bool FirstInDeclGroup = true);
CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
                      CXTranslationUnit TU,
                      SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);

/// Create an Objective-C superclass reference at the given location.
CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
                                     SourceLocation Loc, 
                                     CXTranslationUnit TU);

/// Unpack an ObjCSuperClassRef cursor into the interface it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCInterfaceDecl *, SourceLocation>
  getCursorObjCSuperClassRef(CXCursor C);

/// Create an Objective-C protocol reference at the given location.
CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
                                   SourceLocation Loc, 
                                   CXTranslationUnit TU);

/// Unpack an ObjCProtocolRef cursor into the protocol it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCProtocolDecl *, SourceLocation>
  getCursorObjCProtocolRef(CXCursor C);

/// Create an Objective-C class reference at the given location.
CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
                                SourceLocation Loc, 
                                CXTranslationUnit TU);

/// Unpack an ObjCClassRef cursor into the class it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCInterfaceDecl *, SourceLocation>
  getCursorObjCClassRef(CXCursor C);

/// Create a type reference at the given location.
CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
                           CXTranslationUnit TU);
                               
/// Unpack a TypeRef cursor into the class it references
/// and optionally the location where the reference occurred.
std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);

/// Create a reference to a template at the given location.
CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
                               CXTranslationUnit TU);

/// Unpack a TemplateRef cursor into the template it references and
/// the location where the reference occurred.
std::pair<const TemplateDecl *, SourceLocation>
  getCursorTemplateRef(CXCursor C);

/// Create a reference to a namespace or namespace alias at the given 
/// location.
CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc,
                                CXTranslationUnit TU);

/// Unpack a NamespaceRef cursor into the namespace or namespace alias
/// it references and the location where the reference occurred.
std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);

/// Create a reference to a variable at the given location.
CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc, 
                               CXTranslationUnit TU);

/// Unpack a VariableRef cursor into the variable it references and the
/// location where the where the reference occurred.
std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);

/// Create a reference to a field at the given location.
CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc, 
                             CXTranslationUnit TU);

/// Unpack a MemberRef cursor into the field it references and the 
/// location where the reference occurred.
std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);

/// Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
                                    CXTranslationUnit TU);

/// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);

/// Create a preprocessing directive cursor.
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
                                          CXTranslationUnit TU);

/// Unpack a given preprocessing directive to retrieve its source range.
SourceRange getCursorPreprocessingDirective(CXCursor C);

/// Create a macro definition cursor.
CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
                                   CXTranslationUnit TU);

/// Unpack a given macro definition cursor to retrieve its
/// source range.
const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);

/// Create a macro expansion cursor.
CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);

/// Create a "pseudo" macro expansion cursor, using a macro definition
/// and a source location.
CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc,
                                  CXTranslationUnit TU);

/// Wraps a macro expansion cursor and provides a common interface
/// for a normal macro expansion cursor or a "pseudo" one.
///
/// "Pseudo" macro expansion cursors (essentially a macro definition along with
/// a source location) are created in special cases, for example they can be
/// created for identifiers inside macro definitions, if these identifiers are
/// macro names.
class MacroExpansionCursor {
  CXCursor C;

  bool isPseudo() const { return C.data[1] != nullptr; }
  const MacroDefinitionRecord *getAsMacroDefinition() const {
    assert(isPseudo());
    return static_cast<const MacroDefinitionRecord *>(C.data[0]);
  }
  const MacroExpansion *getAsMacroExpansion() const {
    assert(!isPseudo());
    return static_cast<const MacroExpansion *>(C.data[0]);
  }
  SourceLocation getPseudoLoc() const {
    assert(isPseudo());
    return SourceLocation::getFromPtrEncoding(C.data[1]);
  }

public:
  MacroExpansionCursor(CXCursor C) : C(C) {
    assert(C.kind == CXCursor_MacroExpansion);
  }

  const IdentifierInfo *getName() const;
  const MacroDefinitionRecord *getDefinition() const;
  SourceRange getSourceRange() const;
};

/// Unpack a given macro expansion cursor to retrieve its info.
static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
  return C;
}

/// Create an inclusion directive cursor.
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
                                      CXTranslationUnit TU);

/// Unpack a given inclusion directive cursor to retrieve its
/// source range.
const InclusionDirective *getCursorInclusionDirective(CXCursor C);

/// Create a label reference at the given location.
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
                            CXTranslationUnit TU);

/// Unpack a label reference into the label statement it refers to and
/// the location of the reference.
std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);

/// Create a overloaded declaration reference cursor for an expression.
CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
                                     CXTranslationUnit TU);

/// Create a overloaded declaration reference cursor for a declaration.
CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
                                     CXTranslationUnit TU);

/// Create a overloaded declaration reference cursor for a template name.
CXCursor MakeCursorOverloadedDeclRef(TemplateName Template, 
                                     SourceLocation Location,
                                     CXTranslationUnit TU);

/// Internal storage for an overloaded declaration reference cursor;
typedef llvm::PointerUnion3<const OverloadExpr *, const Decl *,
                            OverloadedTemplateStorage *>
  OverloadedDeclRefStorage;

/// Unpack an overloaded declaration reference into an expression,
/// declaration, or template name along with the source location.
std::pair<OverloadedDeclRefStorage, SourceLocation>
  getCursorOverloadedDeclRef(CXCursor C);

const Decl *getCursorDecl(CXCursor Cursor);
const Expr *getCursorExpr(CXCursor Cursor);
const Stmt *getCursorStmt(CXCursor Cursor);
const Attr *getCursorAttr(CXCursor Cursor);

ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
CXTranslationUnit getCursorTU(CXCursor Cursor);

void getOverriddenCursors(CXCursor cursor,
                          SmallVectorImpl<CXCursor> &overridden);

/// Create an opaque pool used for fast generation of overridden
/// CXCursor arrays.
void *createOverridenCXCursorsPool();

/// Dispose of the overridden CXCursors pool.
void disposeOverridenCXCursorsPool(void *pool);

/// Returns a index/location pair for a selector identifier if the cursor
/// points to one.
std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
static inline int getSelectorIdentifierIndex(CXCursor cursor) {
  return getSelectorIdentifierIndexAndLoc(cursor).first;
}
static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
  return getSelectorIdentifierIndexAndLoc(cursor).second;
}

CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);

static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
  CXCursor newCursor = cursor;
  if (cursor.kind == CXCursor_CallExpr)
    newCursor.xdata = 1;
  return newCursor;
}

CXCursor getTypeRefCursor(CXCursor cursor);

/// Generate a USR for \arg D and put it in \arg Buf.
/// \returns true if no USR was computed or the result should be ignored,
/// false otherwise.
bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf);

bool operator==(CXCursor X, CXCursor Y);

inline bool operator!=(CXCursor X, CXCursor Y) {
  return !(X == Y);
}

/// Return true if the cursor represents a declaration that is the
/// first in a declaration group.
bool isFirstInDeclGroup(CXCursor C);

}} // end namespace: clang::cxcursor

#endif
