1254721Semaste//===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "stdlib.h"
11254721Semaste#include "clang/AST/ASTContext.h"
12254721Semaste#include "clang/AST/Decl.h"
13254721Semaste#include "clang/AST/DeclCXX.h"
14254721Semaste#include "clang/AST/DeclGroup.h"
15254721Semaste#include "clang/AST/DeclObjC.h"
16254721Semaste#include "clang/AST/Expr.h"
17254721Semaste#include "clang/AST/Stmt.h"
18254721Semaste#include "clang/Parse/Parser.h"
19254721Semaste#include "clang/Sema/SemaDiagnostic.h"
20254721Semaste#include "llvm/Support/Casting.h"
21254721Semaste#include "llvm/Support/raw_ostream.h"
22254721Semaste#include "lldb/Core/Log.h"
23254721Semaste#include "lldb/Expression/ClangPersistentVariables.h"
24254721Semaste#include "lldb/Expression/ASTResultSynthesizer.h"
25254721Semaste#include "lldb/Symbol/ClangASTContext.h"
26254721Semaste#include "lldb/Symbol/ClangASTImporter.h"
27254721Semaste#include "lldb/Target/Target.h"
28254721Semaste
29254721Semasteusing namespace llvm;
30254721Semasteusing namespace clang;
31254721Semasteusing namespace lldb_private;
32254721Semaste
33254721SemasteASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
34254721Semaste                                           Target &target) :
35254721Semaste    m_ast_context (NULL),
36254721Semaste    m_passthrough (passthrough),
37254721Semaste    m_passthrough_sema (NULL),
38254721Semaste    m_target (target),
39254721Semaste    m_sema (NULL)
40254721Semaste{
41254721Semaste    if (!m_passthrough)
42254721Semaste        return;
43254721Semaste
44254721Semaste    m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
45254721Semaste}
46254721Semaste
47254721SemasteASTResultSynthesizer::~ASTResultSynthesizer()
48254721Semaste{
49254721Semaste}
50254721Semaste
51254721Semastevoid
52254721SemasteASTResultSynthesizer::Initialize(ASTContext &Context)
53254721Semaste{
54254721Semaste    m_ast_context = &Context;
55254721Semaste
56254721Semaste    if (m_passthrough)
57254721Semaste        m_passthrough->Initialize(Context);
58254721Semaste}
59254721Semaste
60254721Semastevoid
61254721SemasteASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
62254721Semaste{
63254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
64254721Semaste
65254721Semaste    if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
66254721Semaste    {
67254721Semaste        if (log && log->GetVerbose())
68254721Semaste        {
69254721Semaste            if (named_decl->getIdentifier())
70254721Semaste                log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
71254721Semaste            else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
72254721Semaste                log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
73254721Semaste            else
74254721Semaste                log->Printf("TransformTopLevelDecl(<complex>)");
75254721Semaste        }
76254721Semaste
77254721Semaste    }
78254721Semaste
79254721Semaste    if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
80254721Semaste    {
81254721Semaste        RecordDecl::decl_iterator decl_iterator;
82254721Semaste
83254721Semaste        for (decl_iterator = linkage_spec_decl->decls_begin();
84254721Semaste             decl_iterator != linkage_spec_decl->decls_end();
85254721Semaste             ++decl_iterator)
86254721Semaste        {
87254721Semaste            TransformTopLevelDecl(*decl_iterator);
88254721Semaste        }
89254721Semaste    }
90254721Semaste    else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
91254721Semaste    {
92254721Semaste        if (m_ast_context &&
93254721Semaste            !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
94254721Semaste        {
95254721Semaste            RecordPersistentTypes(method_decl);
96254721Semaste            SynthesizeObjCMethodResult(method_decl);
97254721Semaste        }
98254721Semaste    }
99254721Semaste    else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
100254721Semaste    {
101254721Semaste        if (m_ast_context &&
102254721Semaste            !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
103254721Semaste        {
104254721Semaste            RecordPersistentTypes(function_decl);
105254721Semaste            SynthesizeFunctionResult(function_decl);
106254721Semaste        }
107254721Semaste    }
108254721Semaste}
109254721Semaste
110254721Semastebool
111254721SemasteASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
112254721Semaste{
113254721Semaste    DeclGroupRef::iterator decl_iterator;
114254721Semaste
115254721Semaste    for (decl_iterator = D.begin();
116254721Semaste         decl_iterator != D.end();
117254721Semaste         ++decl_iterator)
118254721Semaste    {
119254721Semaste        Decl *decl = *decl_iterator;
120254721Semaste
121254721Semaste        TransformTopLevelDecl(decl);
122254721Semaste    }
123254721Semaste
124254721Semaste    if (m_passthrough)
125254721Semaste        return m_passthrough->HandleTopLevelDecl(D);
126254721Semaste    return true;
127254721Semaste}
128254721Semaste
129254721Semastebool
130254721SemasteASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
131254721Semaste{
132254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
133254721Semaste
134254721Semaste    if (!m_sema)
135254721Semaste        return false;
136254721Semaste
137254721Semaste    FunctionDecl *function_decl = FunDecl;
138254721Semaste
139254721Semaste    if (!function_decl)
140254721Semaste        return false;
141254721Semaste
142254721Semaste    if (log && log->GetVerbose())
143254721Semaste    {
144254721Semaste        std::string s;
145254721Semaste        raw_string_ostream os(s);
146254721Semaste
147254721Semaste        function_decl->print(os);
148254721Semaste
149254721Semaste        os.flush();
150254721Semaste
151254721Semaste        log->Printf ("Untransformed function AST:\n%s", s.c_str());
152254721Semaste    }
153254721Semaste
154254721Semaste    Stmt *function_body = function_decl->getBody();
155254721Semaste    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
156254721Semaste
157254721Semaste    bool ret = SynthesizeBodyResult (compound_stmt,
158254721Semaste                                     function_decl);
159254721Semaste
160254721Semaste    if (log && log->GetVerbose())
161254721Semaste    {
162254721Semaste        std::string s;
163254721Semaste        raw_string_ostream os(s);
164254721Semaste
165254721Semaste        function_decl->print(os);
166254721Semaste
167254721Semaste        os.flush();
168254721Semaste
169254721Semaste        log->Printf ("Transformed function AST:\n%s", s.c_str());
170254721Semaste    }
171254721Semaste
172254721Semaste    return ret;
173254721Semaste}
174254721Semaste
175254721Semastebool
176254721SemasteASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
177254721Semaste{
178254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
179254721Semaste
180254721Semaste    if (!m_sema)
181254721Semaste        return false;
182254721Semaste
183254721Semaste    if (!MethodDecl)
184254721Semaste        return false;
185254721Semaste
186254721Semaste    if (log && log->GetVerbose())
187254721Semaste    {
188254721Semaste        std::string s;
189254721Semaste        raw_string_ostream os(s);
190254721Semaste
191254721Semaste        MethodDecl->print(os);
192254721Semaste
193254721Semaste        os.flush();
194254721Semaste
195254721Semaste        log->Printf ("Untransformed method AST:\n%s", s.c_str());
196254721Semaste    }
197254721Semaste
198254721Semaste    Stmt *method_body = MethodDecl->getBody();
199254721Semaste
200254721Semaste    if (!method_body)
201254721Semaste        return false;
202254721Semaste
203254721Semaste    CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
204254721Semaste
205254721Semaste    bool ret = SynthesizeBodyResult (compound_stmt,
206254721Semaste                                     MethodDecl);
207254721Semaste
208254721Semaste    if (log && log->GetVerbose())
209254721Semaste    {
210254721Semaste        std::string s;
211254721Semaste        raw_string_ostream os(s);
212254721Semaste
213254721Semaste        MethodDecl->print(os);
214254721Semaste
215254721Semaste        os.flush();
216254721Semaste
217254721Semaste        log->Printf("Transformed method AST:\n%s", s.c_str());
218254721Semaste    }
219254721Semaste
220254721Semaste    return ret;
221254721Semaste}
222254721Semaste
223254721Semastebool
224254721SemasteASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
225254721Semaste                                            DeclContext *DC)
226254721Semaste{
227254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
228254721Semaste
229254721Semaste    ASTContext &Ctx(*m_ast_context);
230254721Semaste
231254721Semaste    if (!Body)
232254721Semaste        return false;
233254721Semaste
234254721Semaste    if (Body->body_empty())
235254721Semaste        return false;
236254721Semaste
237254721Semaste    Stmt **last_stmt_ptr = Body->body_end() - 1;
238254721Semaste    Stmt *last_stmt = *last_stmt_ptr;
239254721Semaste
240254721Semaste    while (dyn_cast<NullStmt>(last_stmt))
241254721Semaste    {
242254721Semaste        if (last_stmt_ptr != Body->body_begin())
243254721Semaste        {
244254721Semaste            last_stmt_ptr--;
245254721Semaste            last_stmt = *last_stmt_ptr;
246254721Semaste        }
247254721Semaste        else
248254721Semaste        {
249254721Semaste            return false;
250254721Semaste        }
251254721Semaste    }
252254721Semaste
253254721Semaste    Expr *last_expr = dyn_cast<Expr>(last_stmt);
254254721Semaste
255254721Semaste    if (!last_expr)
256254721Semaste        // No auxiliary variable necessary; expression returns void
257254721Semaste        return true;
258254721Semaste
259254721Semaste    // In C++11, last_expr can be a LValueToRvalue implicit cast.  Strip that off if that's the
260254721Semaste    // case.
261254721Semaste
262254721Semaste    do {
263254721Semaste        ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
264254721Semaste
265254721Semaste        if (!implicit_cast)
266254721Semaste            break;
267254721Semaste
268254721Semaste        if (implicit_cast->getCastKind() != CK_LValueToRValue)
269254721Semaste            break;
270254721Semaste
271254721Semaste        last_expr = implicit_cast->getSubExpr();
272254721Semaste    } while (0);
273254721Semaste
274254721Semaste    // is_lvalue is used to record whether the expression returns an assignable Lvalue or an
275254721Semaste    // Rvalue.  This is relevant because they are handled differently.
276254721Semaste    //
277254721Semaste    // For Lvalues
278254721Semaste    //
279254721Semaste    //   - In AST result synthesis (here!) the expression E is transformed into an initialization
280254721Semaste    //     T *$__lldb_expr_result_ptr = &E.
281254721Semaste    //
282254721Semaste    //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
283254721Semaste    //     passed into the expression.
284254721Semaste    //
285254721Semaste    //   - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at
286254721Semaste    //     an entry in the struct ($__lldb_arg) passed into the expression.  (Other persistent
287254721Semaste    //     variables are treated similarly, having been materialized as references, but in those
288254721Semaste    //     cases the value of the reference itself is never modified.)
289254721Semaste    //
290254721Semaste    //   - During materialization, $0 (the result persistent variable) is ignored.
291254721Semaste    //
292254721Semaste    //   - During dematerialization, $0 is marked up as a load address with value equal to the
293254721Semaste    //     contents of the structure entry.
294254721Semaste    //
295254721Semaste    // For Rvalues
296254721Semaste    //
297254721Semaste    //   - In AST result synthesis the expression E is transformed into an initialization
298254721Semaste    //     static T $__lldb_expr_result = E.
299254721Semaste    //
300254721Semaste    //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
301254721Semaste    //     passed into the expression.
302254721Semaste    //
303254721Semaste    //   - In IR transformations, an instruction is inserted at the beginning of the function to
304254721Semaste    //     dereference the pointer resident in the slot.  Reads and writes to $__lldb_expr_result
305254721Semaste    //     are redirected at that dereferenced version.  Guard variables for the static variable
306254721Semaste    //     are excised.
307254721Semaste    //
308254721Semaste    //   - During materialization, $0 (the result persistent variable) is populated with the location
309254721Semaste    //     of a newly-allocated area of memory.
310254721Semaste    //
311254721Semaste    //   - During dematerialization, $0 is ignored.
312254721Semaste
313254721Semaste    bool is_lvalue =
314254721Semaste        (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) &&
315254721Semaste        (last_expr->getObjectKind() == OK_Ordinary);
316254721Semaste
317254721Semaste    QualType expr_qual_type = last_expr->getType();
318254721Semaste    const clang::Type *expr_type = expr_qual_type.getTypePtr();
319254721Semaste
320254721Semaste    if (!expr_type)
321254721Semaste        return false;
322254721Semaste
323254721Semaste    if (expr_type->isVoidType())
324254721Semaste        return true;
325254721Semaste
326254721Semaste    if (log)
327254721Semaste    {
328254721Semaste        std::string s = expr_qual_type.getAsString();
329254721Semaste
330254721Semaste        log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
331254721Semaste    }
332254721Semaste
333254721Semaste    clang::VarDecl *result_decl = NULL;
334254721Semaste
335254721Semaste    if (is_lvalue)
336254721Semaste    {
337254721Semaste        IdentifierInfo *result_ptr_id;
338254721Semaste
339254721Semaste        if (expr_type->isFunctionType())
340254721Semaste            result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers
341254721Semaste        else
342254721Semaste            result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
343254721Semaste
344254721Semaste        m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
345254721Semaste
346254721Semaste        QualType ptr_qual_type;
347254721Semaste
348254721Semaste        if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
349254721Semaste            ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
350254721Semaste        else
351254721Semaste            ptr_qual_type = Ctx.getPointerType(expr_qual_type);
352254721Semaste
353254721Semaste        result_decl = VarDecl::Create(Ctx,
354254721Semaste                                      DC,
355254721Semaste                                      SourceLocation(),
356254721Semaste                                      SourceLocation(),
357254721Semaste                                      result_ptr_id,
358254721Semaste                                      ptr_qual_type,
359254721Semaste                                      NULL,
360254721Semaste                                      SC_Static);
361254721Semaste
362254721Semaste        if (!result_decl)
363254721Semaste            return false;
364254721Semaste
365254721Semaste        ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
366254721Semaste
367254721Semaste        m_sema->AddInitializerToDecl(result_decl, address_of_expr.take(), true, false);
368254721Semaste    }
369254721Semaste    else
370254721Semaste    {
371254721Semaste        IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
372254721Semaste
373254721Semaste        result_decl = VarDecl::Create(Ctx,
374254721Semaste                                      DC,
375254721Semaste                                      SourceLocation(),
376254721Semaste                                      SourceLocation(),
377254721Semaste                                      &result_id,
378254721Semaste                                      expr_qual_type,
379254721Semaste                                      NULL,
380254721Semaste                                      SC_Static);
381254721Semaste
382254721Semaste        if (!result_decl)
383254721Semaste            return false;
384254721Semaste
385254721Semaste        m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
386254721Semaste    }
387254721Semaste
388254721Semaste    DC->addDecl(result_decl);
389254721Semaste
390254721Semaste    ///////////////////////////////
391254721Semaste    // call AddInitializerToDecl
392254721Semaste    //
393254721Semaste
394254721Semaste    //m_sema->AddInitializerToDecl(result_decl, last_expr);
395254721Semaste
396254721Semaste    /////////////////////////////////
397254721Semaste    // call ConvertDeclToDeclGroup
398254721Semaste    //
399254721Semaste
400254721Semaste    Sema::DeclGroupPtrTy result_decl_group_ptr;
401254721Semaste
402254721Semaste    result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
403254721Semaste
404254721Semaste    ////////////////////////
405254721Semaste    // call ActOnDeclStmt
406254721Semaste    //
407254721Semaste
408254721Semaste    StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
409254721Semaste                                                                       SourceLocation(),
410254721Semaste                                                                       SourceLocation()));
411254721Semaste
412254721Semaste    ////////////////////////////////////////////////
413254721Semaste    // replace the old statement with the new one
414254721Semaste    //
415254721Semaste
416254721Semaste    *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.take());
417254721Semaste
418254721Semaste    return true;
419254721Semaste}
420254721Semaste
421254721Semastevoid
422254721SemasteASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
423254721Semaste{
424254721Semaste    if (m_passthrough)
425254721Semaste        m_passthrough->HandleTranslationUnit(Ctx);
426254721Semaste}
427254721Semaste
428254721Semastevoid
429254721SemasteASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
430254721Semaste{
431254721Semaste    typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
432254721Semaste
433254721Semaste    for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
434254721Semaste         e = TypeDeclIterator(FunDeclCtx->decls_end());
435254721Semaste         i != e;
436254721Semaste         ++i)
437254721Semaste    {
438254721Semaste        MaybeRecordPersistentType(*i);
439254721Semaste    }
440254721Semaste}
441254721Semaste
442254721Semastevoid
443254721SemasteASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
444254721Semaste{
445254721Semaste    if (!D->getIdentifier())
446254721Semaste        return;
447254721Semaste
448254721Semaste    StringRef name = D->getName();
449254721Semaste
450254721Semaste    if (name.size() == 0 || name[0] != '$')
451254721Semaste        return;
452254721Semaste
453254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
454254721Semaste
455254721Semaste    ConstString name_cs(name.str().c_str());
456254721Semaste
457254721Semaste    if (log)
458254721Semaste        log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
459254721Semaste
460254721Semaste    Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(m_target.GetScratchClangASTContext()->getASTContext(),
461254721Semaste                                                                 m_ast_context,
462254721Semaste                                                                 D);
463254721Semaste
464254721Semaste    if (TypeDecl *TypeDecl_scratch = dyn_cast<TypeDecl>(D_scratch))
465254721Semaste        m_target.GetPersistentVariables().RegisterPersistentType(name_cs, TypeDecl_scratch);
466254721Semaste}
467254721Semaste
468254721Semastevoid
469254721SemasteASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
470254721Semaste{
471254721Semaste    if (m_passthrough)
472254721Semaste        m_passthrough->HandleTagDeclDefinition(D);
473254721Semaste}
474254721Semaste
475254721Semastevoid
476254721SemasteASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
477254721Semaste{
478254721Semaste    if (m_passthrough)
479254721Semaste        m_passthrough->CompleteTentativeDefinition(D);
480254721Semaste}
481254721Semaste
482254721Semastevoid
483254721SemasteASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
484254721Semaste{
485254721Semaste    if (m_passthrough)
486254721Semaste        m_passthrough->HandleVTable(RD, DefinitionRequired);
487254721Semaste}
488254721Semaste
489254721Semastevoid
490254721SemasteASTResultSynthesizer::PrintStats()
491254721Semaste{
492254721Semaste    if (m_passthrough)
493254721Semaste        m_passthrough->PrintStats();
494254721Semaste}
495254721Semaste
496254721Semastevoid
497254721SemasteASTResultSynthesizer::InitializeSema(Sema &S)
498254721Semaste{
499254721Semaste    m_sema = &S;
500254721Semaste
501254721Semaste    if (m_passthrough_sema)
502254721Semaste        m_passthrough_sema->InitializeSema(S);
503254721Semaste}
504254721Semaste
505254721Semastevoid
506254721SemasteASTResultSynthesizer::ForgetSema()
507254721Semaste{
508254721Semaste    m_sema = NULL;
509254721Semaste
510254721Semaste    if (m_passthrough_sema)
511254721Semaste        m_passthrough_sema->ForgetSema();
512254721Semaste}
513