ClangExternalASTSourceCommon.h revision 9c09181404cc35f65d5353231246959135fb7684
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    lldb::user_id_t GetUserID () const
78    {
79        if (m_union_is_user_id)
80            return m_user_id;
81        else
82            return LLDB_INVALID_UID;
83    }
84
85    void
86    SetISAPtr (uint64_t isa_ptr)
87    {
88        m_isa_ptr = isa_ptr;
89        m_union_is_user_id = false;
90        m_union_is_isa_ptr = true;
91    }
92
93    uint64_t GetISAPtr () const
94    {
95        if (m_union_is_isa_ptr)
96            return m_isa_ptr;
97        else
98            return 0;
99    }
100
101    void SetObjectPtrName(const char *name)
102    {
103        m_has_object_ptr = true;
104        if (strcmp (name, "self") == 0)
105            m_is_self = true;
106        else if (strcmp (name, "this") == 0)
107            m_is_self = false;
108        else
109            m_has_object_ptr = false;
110    }
111
112    lldb::LanguageType
113    GetObjectPtrLanguage () const
114    {
115        if (m_has_object_ptr)
116        {
117            if (m_is_self)
118                return lldb::eLanguageTypeObjC;
119            else
120                return lldb::eLanguageTypeC_plus_plus;
121        }
122        return lldb::eLanguageTypeUnknown;
123
124    }
125    const char *GetObjectPtrName() const
126    {
127        if (m_has_object_ptr)
128        {
129            if (m_is_self)
130                return "self";
131            else
132                return "this";
133        }
134        else
135            return NULL;
136    }
137
138    bool HasObjectPtr() const
139    {
140        return m_has_object_ptr;
141    }
142
143private:
144    union
145    {
146        lldb::user_id_t m_user_id;
147        uint64_t  m_isa_ptr;
148    };
149    bool m_union_is_user_id : 1,
150         m_union_is_isa_ptr : 1,
151         m_has_object_ptr : 1,
152         m_is_self : 1,
153         m_is_dynamic_cxx : 1;
154
155};
156
157class ClangExternalASTSourceCommon : public clang::ExternalASTSource
158{
159public:
160    ClangExternalASTSourceCommon();
161    ~ClangExternalASTSourceCommon();
162
163    virtual ClangASTMetadata *GetMetadata(uintptr_t object);
164    virtual void SetMetadata(uintptr_t object, ClangASTMetadata &metadata);
165    virtual bool HasMetadata(uintptr_t object);
166private:
167    typedef llvm::DenseMap<uintptr_t, ClangASTMetadata> MetadataMap;
168
169    MetadataMap m_metadata;
170    uint64_t    m_magic;        ///< Because we don't have RTTI, we must take it
171                                ///< on faith that any valid ExternalASTSource that
172                                ///< we try to use the *Metadata APIs on inherits
173                                ///< from ClangExternalASTSourceCommon.  This magic
174                                ///< number exists to enforce that.
175};
176
177}
178
179#endif
180