//===-- 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"

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;
}

