1 //===-- ClangExternalASTSourceCallbacks.cpp ---------------------*- 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 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 
16 // Clang headers like to use NDEBUG inside of them to enable/disable debug
17 // related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
18 // or another. This is bad because it means that if clang was built in release
19 // mode, it assumes that you are building in release mode which is not always
20 // the case. You can end up with functions that are defined as empty in header
21 // files when NDEBUG is not defined, and this can cause link errors with the
22 // clang .a files that you have since you might be missing functions in the .a
23 // file. So we have to define NDEBUG when including clang headers to avoid any
24 // mismatches. This is covered by rdar://problem/8691220
25 
26 #if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
27 #define LLDB_DEFINED_NDEBUG_FOR_CLANG
28 #define NDEBUG
29 // Need to include assert.h so it is as clang would expect it to be (disabled)
30 #include <assert.h>
31 #endif
32 
33 #include "clang/AST/DeclBase.h"
34 #include "clang/AST/DeclarationName.h"
35 
36 #ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
37 #undef NDEBUG
38 #undef LLDB_DEFINED_NDEBUG_FOR_CLANG
39 // Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
40 #include <assert.h>
41 #endif
42 
43 #include "lldb/Core/Log.h"
44 #include "clang/AST/Decl.h"
45 
46 using namespace clang;
47 using namespace lldb_private;
48 
49 bool
50 ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName
51 (
52     const clang::DeclContext *decl_ctx,
53     clang::DeclarationName clang_decl_name
54 )
55 {
56     if (m_callback_find_by_name)
57     {
58         llvm::SmallVector <clang::NamedDecl *, 3> results;
59 
60         m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
61 
62         SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
63 
64         return (results.size() != 0);
65     }
66 
67     std::string decl_name (clang_decl_name.getAsString());
68 
69     switch (clang_decl_name.getNameKind()) {
70     // Normal identifiers.
71     case clang::DeclarationName::Identifier:
72         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
73         if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
74         {
75             SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
76             return false;
77         }
78         break;
79 
80     case clang::DeclarationName::ObjCZeroArgSelector:
81         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
82         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
83         return false;
84 
85     case clang::DeclarationName::ObjCOneArgSelector:
86         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
87         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
88         return false;
89 
90     case clang::DeclarationName::ObjCMultiArgSelector:
91         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
92         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
93         return false;
94 
95     case clang::DeclarationName::CXXConstructorName:
96         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
97         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
98         return false;
99 
100 
101     case clang::DeclarationName::CXXDestructorName:
102         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
103         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
104         return false;
105 
106     case clang::DeclarationName::CXXConversionFunctionName:
107         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
108         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
109         return false;
110 
111     case clang::DeclarationName::CXXOperatorName:
112         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
113         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
114         return false;
115 
116     case clang::DeclarationName::CXXLiteralOperatorName:
117         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
118         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
119         return false;
120 
121     case clang::DeclarationName::CXXUsingDirective:
122         //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
123         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
124         return false;
125     }
126 
127     SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
128     return false;
129 }
130 
131 void
132 ClangExternalASTSourceCallbacks::CompleteType (TagDecl *tag_decl)
133 {
134     if (m_callback_tag_decl)
135         m_callback_tag_decl (m_callback_baton, tag_decl);
136 }
137 
138 void
139 ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl)
140 {
141     if (m_callback_objc_decl)
142         m_callback_objc_decl (m_callback_baton, objc_decl);
143 }
144 
145 bool
146 ClangExternalASTSourceCallbacks::layoutRecordType(
147     const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
148     llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
149     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
150     llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
151 {
152     if (m_callback_layout_record_type)
153         return m_callback_layout_record_type(m_callback_baton,
154                                              Record,
155                                              Size,
156                                              Alignment,
157                                              FieldOffsets,
158                                              BaseOffsets,
159                                              VirtualBaseOffsets);
160 
161     return false;
162 }
163 
164 void
165 ClangExternalASTSourceCallbacks::FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
166                                                            llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
167                                                            llvm::SmallVectorImpl<clang::Decl *> &decls)
168 {
169     if (m_callback_tag_decl && decl_ctx)
170     {
171         clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(const_cast<clang::DeclContext *>(decl_ctx));
172         if (tag_decl)
173             CompleteType(tag_decl);
174     }
175 }
176 
177