reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
//===-- ClangExternalASTSourceCommon.h --------------------------*- 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
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ClangExternalASTSourceCommon_h
#define liblldb_ClangExternalASTSourceCommon_h

// Clang headers like to use NDEBUG inside of them to enable/disable debug
// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
// or another. This is bad because it means that if clang was built in release
// mode, it assumes that you are building in release mode which is not always
// the case. You can end up with functions that are defined as empty in header
// files when NDEBUG is not defined, and this can cause link errors with the
// clang .a files that you have since you might be missing functions in the .a
// file. So we have to define NDEBUG when including clang headers to avoid any
// mismatches. This is covered by rdar://problem/8691220

#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
#define LLDB_DEFINED_NDEBUG_FOR_CLANG
#define NDEBUG
// Need to include assert.h so it is as clang would expect it to be (disabled)
#include <assert.h>
#endif

#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
#undef NDEBUG
#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
#include <assert.h>
#endif

#include "clang/AST/ExternalASTSource.h"

#include "lldb/Core/dwarf.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"

namespace lldb_private {

class ClangASTMetadata {
public:
  ClangASTMetadata()
      : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false),
        m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true) {}

  bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; }

  void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; }

  void SetUserID(lldb::user_id_t user_id) {
    m_user_id = user_id;
    m_union_is_user_id = true;
    m_union_is_isa_ptr = false;
  }

  lldb::user_id_t GetUserID() const {
    if (m_union_is_user_id)
      return m_user_id;
    else
      return LLDB_INVALID_UID;
  }

  void SetISAPtr(uint64_t isa_ptr) {
    m_isa_ptr = isa_ptr;
    m_union_is_user_id = false;
    m_union_is_isa_ptr = true;
  }

  uint64_t GetISAPtr() const {
    if (m_union_is_isa_ptr)
      return m_isa_ptr;
    else
      return 0;
  }

  void SetObjectPtrName(const char *name) {
    m_has_object_ptr = true;
    if (strcmp(name, "self") == 0)
      m_is_self = true;
    else if (strcmp(name, "this") == 0)
      m_is_self = false;
    else
      m_has_object_ptr = false;
  }

  lldb::LanguageType GetObjectPtrLanguage() const {
    if (m_has_object_ptr) {
      if (m_is_self)
        return lldb::eLanguageTypeObjC;
      else
        return lldb::eLanguageTypeC_plus_plus;
    }
    return lldb::eLanguageTypeUnknown;
  }

  const char *GetObjectPtrName() const {
    if (m_has_object_ptr) {
      if (m_is_self)
        return "self";
      else
        return "this";
    } else
      return nullptr;
  }

  bool HasObjectPtr() const { return m_has_object_ptr; }

  void Dump(Stream *s);

private:
  union {
    lldb::user_id_t m_user_id;
    uint64_t m_isa_ptr;
  };

  bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1,
      m_is_self : 1, m_is_dynamic_cxx : 1;
};

class ClangExternalASTSourceCommon : public clang::ExternalASTSource {
public:
  ClangExternalASTSourceCommon();
  ~ClangExternalASTSourceCommon() override;

  ClangASTMetadata *GetMetadata(const void *object);
  void SetMetadata(const void *object, ClangASTMetadata &metadata);
  bool HasMetadata(const void *object);

  static ClangExternalASTSourceCommon *Lookup(clang::ExternalASTSource *source);

private:
  typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap;

  MetadataMap m_metadata;
};

} // namespace lldb_private

#endif // liblldb_ClangExternalASTSourceCommon_h