//===-- ClangExternalASTSourceCallbacks.cpp ---------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"

// C Includes
// C++ Includes
// Other libraries and framework includes

// Clang headers like to use NDEBUG inside of them to enable/disable debug 
// related features using "#ifndef NDEBUG" preprocessor blocks to do one thing
// or another. This is bad because it means that if clang was built in release
// mode, it assumes that you are building in release mode which is not always
// the case. You can end up with functions that are defined as empty in header
// files when NDEBUG is not defined, and this can cause link errors with the
// clang .a files that you have since you might be missing functions in the .a
// file. So we have to define NDEBUG when including clang headers to avoid any
// mismatches. This is covered by rdar://problem/8691220

#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
#define LLDB_DEFINED_NDEBUG_FOR_CLANG
#define NDEBUG
// Need to include assert.h so it is as clang would expect it to be (disabled)
#include <assert.h>
#endif

#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"

#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
#undef NDEBUG
#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
#include <assert.h>
#endif

#include "lldb/Core/Log.h"
#include "clang/AST/Decl.h"

using namespace clang;
using namespace lldb_private;

bool
ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName 
(
    const clang::DeclContext *decl_ctx,
    clang::DeclarationName clang_decl_name
)
{
    if (m_callback_find_by_name)
    {
        llvm::SmallVector <clang::NamedDecl *, 3> results;
        
        m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
        
        SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
        
        return (results.size() != 0);
    }
        
    std::string decl_name (clang_decl_name.getAsString());

    switch (clang_decl_name.getNameKind()) {
    // Normal identifiers.
    case clang::DeclarationName::Identifier:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
        {
            SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
            return false;
        }
        break;

    case clang::DeclarationName::ObjCZeroArgSelector:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::ObjCOneArgSelector:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::ObjCMultiArgSelector:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::CXXConstructorName:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;


    case clang::DeclarationName::CXXDestructorName:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::CXXConversionFunctionName:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::CXXOperatorName:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::CXXLiteralOperatorName:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;

    case clang::DeclarationName::CXXUsingDirective:
        //printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
        SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
        return false;
    }

    SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
    return false;
}

void
ClangExternalASTSourceCallbacks::CompleteType (TagDecl *tag_decl)
{
    if (m_callback_tag_decl)
        m_callback_tag_decl (m_callback_baton, tag_decl);
}

void
ClangExternalASTSourceCallbacks::CompleteType (ObjCInterfaceDecl *objc_decl)
{
    if (m_callback_objc_decl)
        m_callback_objc_decl (m_callback_baton, objc_decl);
}

bool
ClangExternalASTSourceCallbacks::layoutRecordType(
    const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
    llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
    llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
{
    if (m_callback_layout_record_type)
        return m_callback_layout_record_type(m_callback_baton,
                                             Record,
                                             Size, 
                                             Alignment, 
                                             FieldOffsets, 
                                             BaseOffsets, 
                                             VirtualBaseOffsets);
    
    return false;
}

void
ClangExternalASTSourceCallbacks::FindExternalLexicalDecls (const clang::DeclContext *decl_ctx,
                                                           llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
                                                           llvm::SmallVectorImpl<clang::Decl *> &decls)
{
    if (m_callback_tag_decl && decl_ctx)
    {
        clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(const_cast<clang::DeclContext *>(decl_ctx));
        if (tag_decl)
            CompleteType(tag_decl);
    }
}

