1//===-- ClangExternalASTSourceCommon.h --------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_ClangExternalASTSourceCommon_h
11#define liblldb_ClangExternalASTSourceCommon_h
12
13// Clang headers like to use NDEBUG inside of them to enable/disable debug
14// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
15// or another. This is bad because it means that if clang was built in release
16// mode, it assumes that you are building in release mode which is not always
17// the case. You can end up with functions that are defined as empty in header
18// files when NDEBUG is not defined, and this can cause link errors with the
19// clang .a files that you have since you might be missing functions in the .a
20// file. So we have to define NDEBUG when including clang headers to avoid any
21// mismatches. This is covered by rdar://problem/8691220
22
23#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
24#define LLDB_DEFINED_NDEBUG_FOR_CLANG
25#define NDEBUG
26// Need to include assert.h so it is as clang would expect it to be (disabled)
27#include <assert.h>
28#endif
29
30#include "clang/AST/ExternalASTSource.h"
31
32#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
33#undef NDEBUG
34#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
35// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
36#include <assert.h>
37#endif
38
39#include "lldb/lldb-defines.h"
40#include "lldb/lldb-enumerations.h"
41#include "lldb/Core/dwarf.h"
42
43namespace lldb_private {
44
45class ClangASTMetadata
46{
47public:
48    ClangASTMetadata () :
49        m_user_id(0),
50        m_union_is_user_id(false),
51        m_union_is_isa_ptr(false),
52        m_has_object_ptr(false),
53        m_is_self (false),
54        m_is_dynamic_cxx (true)
55    {
56    }
57
58    bool
59    GetIsDynamicCXXType () const
60    {
61        return m_is_dynamic_cxx;
62    }
63
64    void
65    SetIsDynamicCXXType (bool b)
66    {
67        m_is_dynamic_cxx = b;
68    }
69
70    void
71    SetUserID (lldb::user_id_t user_id)
72    {
73        m_user_id = user_id;
74        m_union_is_user_id = true;
75        m_union_is_isa_ptr = false;
76    }
77
78    lldb::user_id_t
79    GetUserID () const
80    {
81        if (m_union_is_user_id)
82            return m_user_id;
83        else
84            return LLDB_INVALID_UID;
85    }
86
87    void
88    SetISAPtr (uint64_t isa_ptr)
89    {
90        m_isa_ptr = isa_ptr;
91        m_union_is_user_id = false;
92        m_union_is_isa_ptr = true;
93    }
94
95    uint64_t
96    GetISAPtr () const
97    {
98        if (m_union_is_isa_ptr)
99            return m_isa_ptr;
100        else
101            return 0;
102    }
103
104    void
105    SetObjectPtrName(const char *name)
106    {
107        m_has_object_ptr = true;
108        if (strcmp (name, "self") == 0)
109            m_is_self = true;
110        else if (strcmp (name, "this") == 0)
111            m_is_self = false;
112        else
113            m_has_object_ptr = false;
114    }
115
116    lldb::LanguageType
117    GetObjectPtrLanguage () const
118    {
119        if (m_has_object_ptr)
120        {
121            if (m_is_self)
122                return lldb::eLanguageTypeObjC;
123            else
124                return lldb::eLanguageTypeC_plus_plus;
125        }
126        return lldb::eLanguageTypeUnknown;
127
128    }
129    const char *
130    GetObjectPtrName() const
131    {
132        if (m_has_object_ptr)
133        {
134            if (m_is_self)
135                return "self";
136            else
137                return "this";
138        }
139        else
140            return NULL;
141    }
142
143    bool
144    HasObjectPtr() const
145    {
146        return m_has_object_ptr;
147    }
148
149    void
150    Dump (Stream *s);
151
152private:
153    union
154    {
155        lldb::user_id_t m_user_id;
156        uint64_t  m_isa_ptr;
157    };
158    bool m_union_is_user_id : 1,
159         m_union_is_isa_ptr : 1,
160         m_has_object_ptr : 1,
161         m_is_self : 1,
162         m_is_dynamic_cxx : 1;
163
164};
165
166class ClangExternalASTSourceCommon : public clang::ExternalASTSource
167{
168public:
169    ClangExternalASTSourceCommon();
170    ~ClangExternalASTSourceCommon();
171
172    virtual ClangASTMetadata *GetMetadata(const void *object);
173    virtual void SetMetadata(const void *object, ClangASTMetadata &metadata);
174    virtual bool HasMetadata(const void *object);
175private:
176    typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap;
177
178    MetadataMap m_metadata;
179    uint64_t    m_magic;        ///< Because we don't have RTTI, we must take it
180                                ///< on faith that any valid ExternalASTSource that
181                                ///< we try to use the *Metadata APIs on inherits
182                                ///< from ClangExternalASTSourceCommon.  This magic
183                                ///< number exists to enforce that.
184};
185
186}
187
188#endif
189