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 // related 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 #ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
31 #undef NDEBUG
32 #undef LLDB_DEFINED_NDEBUG_FOR_CLANG
33 // Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
34 #include <assert.h>
35 #endif
36 
37 #include "clang/AST/ExternalASTSource.h"
38 
39 #include "lldb/Core/dwarf.h"
40 #include "lldb/lldb-defines.h"
41 #include "lldb/lldb-enumerations.h"
42 
43 namespace lldb_private {
44 
45 class ClangASTMetadata {
46 public:
ClangASTMetadata()47   ClangASTMetadata()
48       : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false),
49         m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true) {}
50 
GetIsDynamicCXXType()51   bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; }
52 
SetIsDynamicCXXType(bool b)53   void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; }
54 
SetUserID(lldb::user_id_t user_id)55   void SetUserID(lldb::user_id_t user_id) {
56     m_user_id = user_id;
57     m_union_is_user_id = true;
58     m_union_is_isa_ptr = false;
59   }
60 
GetUserID()61   lldb::user_id_t GetUserID() const {
62     if (m_union_is_user_id)
63       return m_user_id;
64     else
65       return LLDB_INVALID_UID;
66   }
67 
SetISAPtr(uint64_t isa_ptr)68   void SetISAPtr(uint64_t isa_ptr) {
69     m_isa_ptr = isa_ptr;
70     m_union_is_user_id = false;
71     m_union_is_isa_ptr = true;
72   }
73 
GetISAPtr()74   uint64_t GetISAPtr() const {
75     if (m_union_is_isa_ptr)
76       return m_isa_ptr;
77     else
78       return 0;
79   }
80 
SetObjectPtrName(const char * name)81   void SetObjectPtrName(const char *name) {
82     m_has_object_ptr = true;
83     if (strcmp(name, "self") == 0)
84       m_is_self = true;
85     else if (strcmp(name, "this") == 0)
86       m_is_self = false;
87     else
88       m_has_object_ptr = false;
89   }
90 
GetObjectPtrLanguage()91   lldb::LanguageType GetObjectPtrLanguage() const {
92     if (m_has_object_ptr) {
93       if (m_is_self)
94         return lldb::eLanguageTypeObjC;
95       else
96         return lldb::eLanguageTypeC_plus_plus;
97     }
98     return lldb::eLanguageTypeUnknown;
99   }
100 
GetObjectPtrName()101   const char *GetObjectPtrName() const {
102     if (m_has_object_ptr) {
103       if (m_is_self)
104         return "self";
105       else
106         return "this";
107     } else
108       return nullptr;
109   }
110 
HasObjectPtr()111   bool HasObjectPtr() const { return m_has_object_ptr; }
112 
113   void Dump(Stream *s);
114 
115 private:
116   union {
117     lldb::user_id_t m_user_id;
118     uint64_t m_isa_ptr;
119   };
120 
121   bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1,
122       m_is_self : 1, m_is_dynamic_cxx : 1;
123 };
124 
125 class ClangExternalASTSourceCommon : public clang::ExternalASTSource {
126 public:
127   ClangExternalASTSourceCommon();
128   ~ClangExternalASTSourceCommon() override;
129 
130   ClangASTMetadata *GetMetadata(const void *object);
131   void SetMetadata(const void *object, ClangASTMetadata &metadata);
132   bool HasMetadata(const void *object);
133 
134   static ClangExternalASTSourceCommon *Lookup(clang::ExternalASTSource *source);
135 
136 private:
137   typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap;
138 
139   MetadataMap m_metadata;
140 };
141 
142 } // namespace lldb_private
143 
144 #endif // liblldb_ClangExternalASTSourceCommon_h
145