Skip to content
ClangASTSource.cpp 5.71 KiB
Newer Older
/*
 *  ClangASTSource.cpp
 *  lldb
 *
 *  Created by John McCall on 6/1/10.
 *  Copyright 2010 Apple. All rights reserved.
 *
 */

#include "clang/AST/ASTContext.h"
#include "lldb/Expression/ClangASTSource.h"
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"

using namespace clang;
using namespace lldb_private;

ClangASTSource::~ClangASTSource() {}

void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
    // Tell Sema to ask us when looking into the translation unit's decl.
    Context.getTranslationUnitDecl()->setHasExternalVisibleStorage();
    Context.getTranslationUnitDecl()->setHasExternalLexicalStorage();
}

// These are only required for AST source that want to lazily load
// the declarations (or parts thereof) that they return.
Decl *ClangASTSource::GetExternalDecl(uint32_t) { return 0; }
Stmt *ClangASTSource::GetExternalDeclStmt(uint64_t) { return 0; }

// These are also optional, although it might help with ObjC
// debugging if we have respectable signatures.  But a more
// efficient interface (that didn't require scanning all files
// for method signatures!) might help.
Selector ClangASTSource::GetExternalSelector(uint32_t) { return Selector(); }
uint32_t ClangASTSource::GetNumExternalSelectors() { return 0; }

// The core lookup interface.
DeclContext::lookup_result ClangASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
    switch (Name.getNameKind()) {
    // Normal identifiers.
    case DeclarationName::Identifier:
      break;
            
    // Operator names.  Not important for now.
    case DeclarationName::CXXOperatorName:
    case DeclarationName::CXXLiteralOperatorName:
      return DeclContext::lookup_result();
            
    // Using directives found in this context.
    // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
    case DeclarationName::CXXUsingDirective:
      return SetNoExternalVisibleDeclsForName(DC, Name);
            
    // These aren't looked up like this.
    case DeclarationName::ObjCZeroArgSelector:
    case DeclarationName::ObjCOneArgSelector:
    case DeclarationName::ObjCMultiArgSelector:
      return DeclContext::lookup_result();

    // These aren't possible in the global context.
    case DeclarationName::CXXConstructorName:
    case DeclarationName::CXXDestructorName:
    case DeclarationName::CXXConversionFunctionName:
      return DeclContext::lookup_result();
    }
    
	llvm::SmallVector<NamedDecl*, 4> Decls;
    
    NameSearchContext NSC(*this, Decls, Name, DC);
    
    DeclMap.GetDecls(NSC, Name.getAsString().c_str());
    return SetExternalVisibleDeclsForName(DC, Name, Decls);
}

// This is used to support iterating through an entire lexical context,
// which isn't something the debugger should ever need to do.
bool ClangASTSource::FindExternalLexicalDecls(const DeclContext *DC, llvm::SmallVectorImpl<Decl*> &Decls) {
	// true is for error, that's good enough for me
	return true;
}

clang::ASTContext *NameSearchContext::GetASTContext() {
    return &ASTSource.Context;
}

clang::NamedDecl *NameSearchContext::AddVarDecl(void *type) {
    clang::NamedDecl *Decl = VarDecl::Create(ASTSource.Context, 
                                             const_cast<DeclContext*>(DC), 
                                             SourceLocation(), 
                                             Name.getAsIdentifierInfo(), 
                                             QualType::getFromOpaquePtr(type), 
                                             0, 
                                             VarDecl::Static, 
                                             VarDecl::Static);
    Decls.push_back(Decl);
    
    return Decl;
}

clang::NamedDecl *NameSearchContext::AddFunDecl(void *type) {
    clang::FunctionDecl *Decl = FunctionDecl::Create(ASTSource.Context,
                                                     const_cast<DeclContext*>(DC),
                                                     SourceLocation(),
                                                     Name.getAsIdentifierInfo(),
                                                     QualType::getFromOpaquePtr(type),
                                                     NULL,
                                                     FunctionDecl::Static,
                                                     FunctionDecl::Static,
                                                     false,
                                                     true);
    
    QualType QT = QualType::getFromOpaquePtr(type);
    clang::Type *T = QT.getTypePtr();
    const FunctionProtoType *FPT = T->getAs<FunctionProtoType>();
        unsigned NumArgs = FPT->getNumArgs();
        unsigned ArgIndex;
        
        ParmVarDecl **ParmVarDecls = new ParmVarDecl*[NumArgs];
        
        for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
        {
            QualType ArgQT = FPT->getArgType(ArgIndex);
            
            ParmVarDecls[ArgIndex] = ParmVarDecl::Create(ASTSource.Context,
                                                         const_cast<DeclContext*>(DC),
                                                         SourceLocation(),
                                                         NULL,
                                                         ArgQT,
                                                         NULL,
                                                         ParmVarDecl::Static,
                                                         ParmVarDecl::Static,
                                                         NULL);
        }
        
        Decl->setParams(ParmVarDecls, NumArgs);