ASTResultSynthesizer.cpp revision 292932
189051Sjake//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===//
289051Sjake//
389051Sjake//                     The LLVM Compiler Infrastructure
489051Sjake//
589051Sjake// This file is distributed under the University of Illinois Open Source
689051Sjake// License. See LICENSE.TXT for details.
789051Sjake//
889051Sjake//===----------------------------------------------------------------------===//
989051Sjake
1089051Sjake#include "ASTResultSynthesizer.h"
1189051Sjake
1289051Sjake#include "ClangPersistentVariables.h"
1389051Sjake
1489051Sjake#include "stdlib.h"
1589051Sjake#include "clang/AST/ASTContext.h"
1689051Sjake#include "clang/AST/Decl.h"
1789051Sjake#include "clang/AST/DeclCXX.h"
1889051Sjake#include "clang/AST/DeclGroup.h"
1989051Sjake#include "clang/AST/DeclObjC.h"
2089051Sjake#include "clang/AST/Expr.h"
2189051Sjake#include "clang/AST/Stmt.h"
2289051Sjake#include "clang/Parse/Parser.h"
2389051Sjake#include "clang/Sema/SemaDiagnostic.h"
2489051Sjake#include "llvm/Support/Casting.h"
2589051Sjake#include "llvm/Support/raw_ostream.h"
2689051Sjake#include "lldb/Core/Log.h"
27114188Sjake#include "lldb/Symbol/ClangASTContext.h"
28114188Sjake#include "lldb/Symbol/ClangASTImporter.h"
29114188Sjake#include "lldb/Target/Target.h"
3089051Sjake
3189051Sjakeusing namespace llvm;
3289051Sjakeusing namespace clang;
3389051Sjakeusing namespace lldb_private;
3489051Sjake
3589051SjakeASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
3689051Sjake                                           Target &target) :
3789051Sjake    m_ast_context (NULL),
3889051Sjake    m_passthrough (passthrough),
3989051Sjake    m_passthrough_sema (NULL),
4092199Sjake    m_target (target),
4192199Sjake    m_sema (NULL)
4292199Sjake{
4391783Sjake    if (!m_passthrough)
4489051Sjake        return;
4589051Sjake
4689051Sjake    m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
4789051Sjake}
48112399Sjake
4997001SjakeASTResultSynthesizer::~ASTResultSynthesizer()
50112399Sjake{
5197001Sjake}
5297001Sjake
5397001Sjakevoid
5497001SjakeASTResultSynthesizer::Initialize(ASTContext &Context)
5597001Sjake{
5697001Sjake    m_ast_context = &Context;
5797001Sjake
5897001Sjake    if (m_passthrough)
5997001Sjake        m_passthrough->Initialize(Context);
6097001Sjake}
6197001Sjake
6297001Sjakevoid
6397001SjakeASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
6497001Sjake{
6597001Sjake    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
6697001Sjake
6797001Sjake    if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
6897001Sjake    {
6997001Sjake        if (log && log->GetVerbose())
7097001Sjake        {
7197001Sjake            if (named_decl->getIdentifier())
7297001Sjake                log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
7397001Sjake            else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
7497001Sjake                log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
7597001Sjake            else
7697001Sjake                log->Printf("TransformTopLevelDecl(<complex>)");
7797001Sjake        }
7897001Sjake
7997001Sjake    }
8097001Sjake
8197001Sjake    if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
8297001Sjake    {
8397001Sjake        RecordDecl::decl_iterator decl_iterator;
8497001Sjake
85112399Sjake        for (decl_iterator = linkage_spec_decl->decls_begin();
8697001Sjake             decl_iterator != linkage_spec_decl->decls_end();
8797001Sjake             ++decl_iterator)
88112399Sjake        {
89112399Sjake            TransformTopLevelDecl(*decl_iterator);
9097001Sjake        }
91112399Sjake    }
9297001Sjake    else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
9397001Sjake    {
9497001Sjake        if (m_ast_context &&
9597001Sjake            !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
9697001Sjake        {
9797001Sjake            RecordPersistentTypes(method_decl);
9897001Sjake            SynthesizeObjCMethodResult(method_decl);
9997001Sjake        }
10097001Sjake    }
10197001Sjake    else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
10297001Sjake    {
10397001Sjake        if (m_ast_context &&
10497001Sjake            !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
10597001Sjake        {
10697001Sjake            RecordPersistentTypes(function_decl);
10797001Sjake            SynthesizeFunctionResult(function_decl);
10897001Sjake        }
10997001Sjake    }
11097001Sjake}
11197001Sjake
11297001Sjakebool
11397001SjakeASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
11497001Sjake{
11597001Sjake    DeclGroupRef::iterator decl_iterator;
11697001Sjake
11797001Sjake    for (decl_iterator = D.begin();
11897001Sjake         decl_iterator != D.end();
11997001Sjake         ++decl_iterator)
12097001Sjake    {
12197001Sjake        Decl *decl = *decl_iterator;
12297001Sjake
12397001Sjake        TransformTopLevelDecl(decl);
12497001Sjake    }
12597001Sjake
126112399Sjake    if (m_passthrough)
12797001Sjake        return m_passthrough->HandleTopLevelDecl(D);
12897001Sjake    return true;
129112399Sjake}
130112399Sjake
131112399Sjakebool
132112399SjakeASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
133112399Sjake{
134112399Sjake    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
135112399Sjake
136112399Sjake    if (!m_sema)
137112399Sjake        return false;
138112399Sjake
139112399Sjake    FunctionDecl *function_decl = FunDecl;
140112399Sjake
141112399Sjake    if (!function_decl)
142112399Sjake        return false;
143112399Sjake
144112399Sjake    if (log && log->GetVerbose())
145112399Sjake    {
146112399Sjake        std::string s;
147112399Sjake        raw_string_ostream os(s);
148112399Sjake
149112399Sjake        function_decl->print(os);
150112399Sjake
151112399Sjake        os.flush();
152112399Sjake
153112399Sjake        log->Printf ("Untransformed function AST:\n%s", s.c_str());
154112399Sjake    }
155112399Sjake
156112399Sjake    Stmt *function_body = function_decl->getBody();
157112399Sjake    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
158112399Sjake
159112399Sjake    bool ret = SynthesizeBodyResult (compound_stmt,
160112399Sjake                                     function_decl);
16189051Sjake
16289051Sjake    if (log && log->GetVerbose())
16389051Sjake    {
16492199Sjake        std::string s;
16592199Sjake        raw_string_ostream os(s);
16692199Sjake
16792199Sjake        function_decl->print(os);
16892199Sjake
16992199Sjake        os.flush();
17092199Sjake
17192199Sjake        log->Printf ("Transformed function AST:\n%s", s.c_str());
17292199Sjake    }
17392199Sjake
17492199Sjake    return ret;
17589051Sjake}
17689051Sjake
17792199Sjakebool
178108379SjakeASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
17989051Sjake{
18089051Sjake    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
18189051Sjake
18289051Sjake    if (!m_sema)
18389051Sjake        return false;
18489051Sjake
18589051Sjake    if (!MethodDecl)
18691783Sjake        return false;
18791783Sjake
18891783Sjake    if (log && log->GetVerbose())
18991783Sjake    {
19091783Sjake        std::string s;
19191783Sjake        raw_string_ostream os(s);
19291783Sjake
19391783Sjake        MethodDecl->print(os);
19491783Sjake
19589051Sjake        os.flush();
19691783Sjake
19789051Sjake        log->Printf ("Untransformed method AST:\n%s", s.c_str());
19891783Sjake    }
19991783Sjake
20089051Sjake    Stmt *method_body = MethodDecl->getBody();
20191783Sjake
20291783Sjake    if (!method_body)
20389051Sjake        return false;
20491783Sjake
20591783Sjake    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
20689051Sjake
20791783Sjake    bool ret = SynthesizeBodyResult (compound_stmt,
20891783Sjake                                     MethodDecl);
20991783Sjake
21089051Sjake    if (log && log->GetVerbose())
211100718Sjake    {
21289051Sjake        std::string s;
21389051Sjake        raw_string_ostream os(s);
21489051Sjake
21589051Sjake        MethodDecl->print(os);
21689051Sjake
21789051Sjake        os.flush();
21889051Sjake
21991783Sjake        log->Printf("Transformed method AST:\n%s", s.c_str());
22091783Sjake    }
22191783Sjake
22291783Sjake    return ret;
22391783Sjake}
22489051Sjake
22591783Sjakebool
22691783SjakeASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
22791783Sjake                                            DeclContext *DC)
22891783Sjake{
22991783Sjake    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
23089051Sjake
23191783Sjake    ASTContext &Ctx(*m_ast_context);
23289051Sjake
23391783Sjake    if (!Body)
23491783Sjake        return false;
23589051Sjake
23691783Sjake    if (Body->body_empty())
23791783Sjake        return false;
23889051Sjake
23991783Sjake    Stmt **last_stmt_ptr = Body->body_end() - 1;
24091783Sjake    Stmt *last_stmt = *last_stmt_ptr;
24189051Sjake
24291783Sjake    while (dyn_cast<NullStmt>(last_stmt))
24391783Sjake    {
24491783Sjake        if (last_stmt_ptr != Body->body_begin())
24589051Sjake        {
24689051Sjake            last_stmt_ptr--;
24791783Sjake            last_stmt = *last_stmt_ptr;
24889051Sjake        }
24991783Sjake        else
25091783Sjake        {
25191783Sjake            return false;
25289051Sjake        }
25389051Sjake    }
25492199Sjake
25589051Sjake    Expr *last_expr = dyn_cast<Expr>(last_stmt);
25689051Sjake
25789051Sjake    if (!last_expr)
25889051Sjake        // No auxiliary variable necessary; expression returns void
25991783Sjake        return true;
26089051Sjake
26189051Sjake    // In C++11, last_expr can be a LValueToRvalue implicit cast.  Strip that off if that's the
26291783Sjake    // case.
26391783Sjake
26491783Sjake    do {
26591783Sjake        ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
26691783Sjake
26791783Sjake        if (!implicit_cast)
26891783Sjake            break;
26991783Sjake
27091783Sjake        if (implicit_cast->getCastKind() != CK_LValueToRValue)
27189051Sjake            break;
27291783Sjake
27391783Sjake        last_expr = implicit_cast->getSubExpr();
27491783Sjake    } while (0);
27589051Sjake
27689051Sjake    // is_lvalue is used to record whether the expression returns an assignable Lvalue or an
27792199Sjake    // Rvalue.  This is relevant because they are handled differently.
27889051Sjake    //
27989051Sjake    // For Lvalues
280    //
281    //   - In AST result synthesis (here!) the expression E is transformed into an initialization
282    //     T *$__lldb_expr_result_ptr = &E.
283    //
284    //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
285    //     passed into the expression.
286    //
287    //   - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at
288    //     an entry in the struct ($__lldb_arg) passed into the expression.  (Other persistent
289    //     variables are treated similarly, having been materialized as references, but in those
290    //     cases the value of the reference itself is never modified.)
291    //
292    //   - During materialization, $0 (the result persistent variable) is ignored.
293    //
294    //   - During dematerialization, $0 is marked up as a load address with value equal to the
295    //     contents of the structure entry.
296    //
297    // For Rvalues
298    //
299    //   - In AST result synthesis the expression E is transformed into an initialization
300    //     static T $__lldb_expr_result = E.
301    //
302    //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
303    //     passed into the expression.
304    //
305    //   - In IR transformations, an instruction is inserted at the beginning of the function to
306    //     dereference the pointer resident in the slot.  Reads and writes to $__lldb_expr_result
307    //     are redirected at that dereferenced version.  Guard variables for the static variable
308    //     are excised.
309    //
310    //   - During materialization, $0 (the result persistent variable) is populated with the location
311    //     of a newly-allocated area of memory.
312    //
313    //   - During dematerialization, $0 is ignored.
314
315    bool is_lvalue =
316        (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) &&
317        (last_expr->getObjectKind() == OK_Ordinary);
318
319    QualType expr_qual_type = last_expr->getType();
320    const clang::Type *expr_type = expr_qual_type.getTypePtr();
321
322    if (!expr_type)
323        return false;
324
325    if (expr_type->isVoidType())
326        return true;
327
328    if (log)
329    {
330        std::string s = expr_qual_type.getAsString();
331
332        log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
333    }
334
335    clang::VarDecl *result_decl = NULL;
336
337    if (is_lvalue)
338    {
339        IdentifierInfo *result_ptr_id;
340
341        if (expr_type->isFunctionType())
342            result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers
343        else
344            result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
345
346        m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
347
348        QualType ptr_qual_type;
349
350        if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
351            ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
352        else
353            ptr_qual_type = Ctx.getPointerType(expr_qual_type);
354
355        result_decl = VarDecl::Create(Ctx,
356                                      DC,
357                                      SourceLocation(),
358                                      SourceLocation(),
359                                      result_ptr_id,
360                                      ptr_qual_type,
361                                      NULL,
362                                      SC_Static);
363
364        if (!result_decl)
365            return false;
366
367        ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
368
369        m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
370    }
371    else
372    {
373        IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
374
375        result_decl = VarDecl::Create(Ctx,
376                                      DC,
377                                      SourceLocation(),
378                                      SourceLocation(),
379                                      &result_id,
380                                      expr_qual_type,
381                                      NULL,
382                                      SC_Static);
383
384        if (!result_decl)
385            return false;
386
387        m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
388    }
389
390    DC->addDecl(result_decl);
391
392    ///////////////////////////////
393    // call AddInitializerToDecl
394    //
395
396    //m_sema->AddInitializerToDecl(result_decl, last_expr);
397
398    /////////////////////////////////
399    // call ConvertDeclToDeclGroup
400    //
401
402    Sema::DeclGroupPtrTy result_decl_group_ptr;
403
404    result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
405
406    ////////////////////////
407    // call ActOnDeclStmt
408    //
409
410    StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
411                                                                       SourceLocation(),
412                                                                       SourceLocation()));
413
414    ////////////////////////////////////////////////
415    // replace the old statement with the new one
416    //
417
418    *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get());
419
420    return true;
421}
422
423void
424ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
425{
426    if (m_passthrough)
427        m_passthrough->HandleTranslationUnit(Ctx);
428}
429
430void
431ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
432{
433    typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
434
435    for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
436         e = TypeDeclIterator(FunDeclCtx->decls_end());
437         i != e;
438         ++i)
439    {
440        MaybeRecordPersistentType(*i);
441    }
442}
443
444void
445ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
446{
447    if (!D->getIdentifier())
448        return;
449
450    StringRef name = D->getName();
451
452    if (name.size() == 0 || name[0] != '$')
453        return;
454
455    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
456
457    ConstString name_cs(name.str().c_str());
458
459    if (log)
460        log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
461
462    Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(),
463                                                                 m_ast_context,
464                                                                 D);
465
466    if (TypeDecl *TypeDecl_scratch = dyn_cast<TypeDecl>(D_scratch))
467        llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->RegisterPersistentType(name_cs, TypeDecl_scratch);
468}
469
470void
471ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
472{
473    if (m_passthrough)
474        m_passthrough->HandleTagDeclDefinition(D);
475}
476
477void
478ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
479{
480    if (m_passthrough)
481        m_passthrough->CompleteTentativeDefinition(D);
482}
483
484void
485ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD)
486{
487    if (m_passthrough)
488        m_passthrough->HandleVTable(RD);
489}
490
491void
492ASTResultSynthesizer::PrintStats()
493{
494    if (m_passthrough)
495        m_passthrough->PrintStats();
496}
497
498void
499ASTResultSynthesizer::InitializeSema(Sema &S)
500{
501    m_sema = &S;
502
503    if (m_passthrough_sema)
504        m_passthrough_sema->InitializeSema(S);
505}
506
507void
508ASTResultSynthesizer::ForgetSema()
509{
510    m_sema = NULL;
511
512    if (m_passthrough_sema)
513        m_passthrough_sema->ForgetSema();
514}
515