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 ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName( 50 const clang::DeclContext *decl_ctx, 51 clang::DeclarationName clang_decl_name) { 52 if (m_callback_find_by_name) { 53 llvm::SmallVector<clang::NamedDecl *, 3> results; 54 55 m_callback_find_by_name(m_callback_baton, decl_ctx, clang_decl_name, 56 &results); 57 58 SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results); 59 60 return (results.size() != 0); 61 } 62 63 std::string decl_name(clang_decl_name.getAsString()); 64 65 switch (clang_decl_name.getNameKind()) { 66 // Normal identifiers. 67 case clang::DeclarationName::Identifier: 68 // printf 69 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 70 // = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, 71 // decl_name.c_str()); 72 if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0) { 73 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 74 return false; 75 } 76 break; 77 78 case clang::DeclarationName::ObjCZeroArgSelector: 79 // printf 80 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 81 // = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", 82 // decl_ctx, decl_name.c_str()); 83 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 84 return false; 85 86 case clang::DeclarationName::ObjCOneArgSelector: 87 // printf 88 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 89 // = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", 90 // decl_ctx, decl_name.c_str()); 91 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 92 return false; 93 94 case clang::DeclarationName::ObjCMultiArgSelector: 95 // printf 96 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 97 // = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", 98 // decl_ctx, decl_name.c_str()); 99 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 100 return false; 101 102 case clang::DeclarationName::CXXConstructorName: 103 // printf 104 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 105 // = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", 106 // decl_ctx, decl_name.c_str()); 107 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 108 return false; 109 110 case clang::DeclarationName::CXXDestructorName: 111 // printf 112 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 113 // = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", 114 // decl_ctx, decl_name.c_str()); 115 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 116 return false; 117 118 case clang::DeclarationName::CXXConversionFunctionName: 119 // printf 120 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 121 // = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = 122 // \"%s\")\n", decl_ctx, decl_name.c_str()); 123 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 124 return false; 125 126 case clang::DeclarationName::CXXOperatorName: 127 // printf 128 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 129 // = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", 130 // decl_ctx, decl_name.c_str()); 131 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 132 return false; 133 134 case clang::DeclarationName::CXXLiteralOperatorName: 135 // printf 136 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 137 // = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", 138 // decl_ctx, decl_name.c_str()); 139 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 140 return false; 141 142 case clang::DeclarationName::CXXUsingDirective: 143 // printf 144 // ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx 145 // = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", 146 // decl_ctx, decl_name.c_str()); 147 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 148 return false; 149 } 150 151 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 152 return false; 153 } 154 155 void ClangExternalASTSourceCallbacks::CompleteType(TagDecl *tag_decl) { 156 if (m_callback_tag_decl) 157 m_callback_tag_decl(m_callback_baton, tag_decl); 158 } 159 160 void ClangExternalASTSourceCallbacks::CompleteType( 161 ObjCInterfaceDecl *objc_decl) { 162 if (m_callback_objc_decl) 163 m_callback_objc_decl(m_callback_baton, objc_decl); 164 } 165 166 bool ClangExternalASTSourceCallbacks::layoutRecordType( 167 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, 168 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, 169 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, 170 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> 171 &VirtualBaseOffsets) { 172 if (m_callback_layout_record_type) 173 return m_callback_layout_record_type(m_callback_baton, Record, Size, 174 Alignment, FieldOffsets, BaseOffsets, 175 VirtualBaseOffsets); 176 177 return false; 178 } 179 180 void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls( 181 const clang::DeclContext *decl_ctx, 182 llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, 183 llvm::SmallVectorImpl<clang::Decl *> &decls) { 184 if (m_callback_tag_decl && decl_ctx) { 185 clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>( 186 const_cast<clang::DeclContext *>(decl_ctx)); 187 if (tag_decl) 188 CompleteType(tag_decl); 189 } 190 } 191