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// releated 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
45using namespace clang;
46using namespace lldb_private;
47
48bool
49ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName
50(
51    const clang::DeclContext *decl_ctx,
52    clang::DeclarationName clang_decl_name
53)
54{
55    if (m_callback_find_by_name)
56    {
57        llvm::SmallVector <clang::NamedDecl *, 3> results;
58
59        m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
60
61        SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
62
63        return (results.size() != 0);
64    }
65
66    std::string decl_name (clang_decl_name.getAsString());
67
68    switch (clang_decl_name.getNameKind()) {
69    // Normal identifiers.
70    case clang::DeclarationName::Identifier:
71        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
72        if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
73        {
74            SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
75            return false;
76        }
77        break;
78
79    case clang::DeclarationName::ObjCZeroArgSelector:
80        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
81        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
82        return false;
83
84    case clang::DeclarationName::ObjCOneArgSelector:
85        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
86        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
87        return false;
88
89    case clang::DeclarationName::ObjCMultiArgSelector:
90        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
91        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
92        return false;
93
94    case clang::DeclarationName::CXXConstructorName:
95        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
96        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
97        return false;
98
99
100    case clang::DeclarationName::CXXDestructorName:
101        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
102        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
103        return false;
104
105    case clang::DeclarationName::CXXConversionFunctionName:
106        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
107        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
108        return false;
109
110    case clang::DeclarationName::CXXOperatorName:
111        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
112        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
113        return false;
114
115    case clang::DeclarationName::CXXLiteralOperatorName:
116        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
117        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
118        return false;
119
120    case clang::DeclarationName::CXXUsingDirective:
121        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
122        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
123        return false;
124    }
125
126    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
127    return false;
128}
129
130void
131ClangExternalASTSourceCallbacks::CompleteType (TagDecl *tag_decl)
132{
133    if (m_callback_tag_decl)
134        m_callback_tag_decl (m_callback_baton, tag_decl);
135}
136
137void
138ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl)
139{
140    if (m_callback_objc_decl)
141        m_callback_objc_decl (m_callback_baton, objc_decl);
142}
143
144bool
145ClangExternalASTSourceCallbacks::layoutRecordType(const clang::RecordDecl *Record,
146                                                  uint64_t &Size,
147                                                  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