1 //===-- ASTResultSynthesizer.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "ASTResultSynthesizer.h"
11 
12 #include "ClangPersistentVariables.h"
13 
14 #include "lldb/Core/Log.h"
15 #include "lldb/Symbol/ClangASTContext.h"
16 #include "lldb/Symbol/ClangASTImporter.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Utility/LLDBAssert.h"
19 #include "stdlib.h"
20 #include "clang/AST/ASTContext.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclCXX.h"
23 #include "clang/AST/DeclGroup.h"
24 #include "clang/AST/DeclObjC.h"
25 #include "clang/AST/Expr.h"
26 #include "clang/AST/Stmt.h"
27 #include "clang/Parse/Parser.h"
28 #include "clang/Sema/SemaDiagnostic.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/raw_ostream.h"
31 
32 using namespace llvm;
33 using namespace clang;
34 using namespace lldb_private;
35 
36 ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough, bool top_level, Target &target)
37     : m_ast_context(NULL),
38       m_passthrough(passthrough),
39       m_passthrough_sema(NULL),
40       m_target(target),
41       m_sema(NULL),
42       m_top_level(top_level)
43 {
44     if (!m_passthrough)
45         return;
46 
47     m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
48 }
49 
50 ASTResultSynthesizer::~ASTResultSynthesizer()
51 {
52 }
53 
54 void
55 ASTResultSynthesizer::Initialize(ASTContext &Context)
56 {
57     m_ast_context = &Context;
58 
59     if (m_passthrough)
60         m_passthrough->Initialize(Context);
61 }
62 
63 void
64 ASTResultSynthesizer::TransformTopLevelDecl(Decl* D)
65 {
66     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
67 
68     if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D))
69     {
70         if (log && log->GetVerbose())
71         {
72             if (named_decl->getIdentifier())
73                 log->Printf("TransformTopLevelDecl(%s)", named_decl->getIdentifier()->getNameStart());
74             else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
75                 log->Printf("TransformTopLevelDecl(%s)", method_decl->getSelector().getAsString().c_str());
76             else
77                 log->Printf("TransformTopLevelDecl(<complex>)");
78         }
79 
80         if (m_top_level)
81         {
82             RecordPersistentDecl(named_decl);
83         }
84     }
85 
86     if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D))
87     {
88         RecordDecl::decl_iterator decl_iterator;
89 
90         for (decl_iterator = linkage_spec_decl->decls_begin();
91              decl_iterator != linkage_spec_decl->decls_end();
92              ++decl_iterator)
93         {
94             TransformTopLevelDecl(*decl_iterator);
95         }
96     }
97     else if (!m_top_level)
98     {
99         if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
100         {
101             if (m_ast_context && !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
102             {
103                 RecordPersistentTypes(method_decl);
104                 SynthesizeObjCMethodResult(method_decl);
105             }
106         }
107         else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D))
108         {
109             if (m_ast_context && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
110             {
111                 RecordPersistentTypes(function_decl);
112                 SynthesizeFunctionResult(function_decl);
113             }
114         }
115     }
116 }
117 
118 bool
119 ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D)
120 {
121     DeclGroupRef::iterator decl_iterator;
122 
123     for (decl_iterator = D.begin();
124          decl_iterator != D.end();
125          ++decl_iterator)
126     {
127         Decl *decl = *decl_iterator;
128 
129         TransformTopLevelDecl(decl);
130     }
131 
132     if (m_passthrough)
133         return m_passthrough->HandleTopLevelDecl(D);
134     return true;
135 }
136 
137 bool
138 ASTResultSynthesizer::SynthesizeFunctionResult (FunctionDecl *FunDecl)
139 {
140     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
141 
142     if (!m_sema)
143         return false;
144 
145     FunctionDecl *function_decl = FunDecl;
146 
147     if (!function_decl)
148         return false;
149 
150     if (log && log->GetVerbose())
151     {
152         std::string s;
153         raw_string_ostream os(s);
154 
155         function_decl->print(os);
156 
157         os.flush();
158 
159         log->Printf ("Untransformed function AST:\n%s", s.c_str());
160     }
161 
162     Stmt *function_body = function_decl->getBody();
163     CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
164 
165     bool ret = SynthesizeBodyResult (compound_stmt,
166                                      function_decl);
167 
168     if (log && log->GetVerbose())
169     {
170         std::string s;
171         raw_string_ostream os(s);
172 
173         function_decl->print(os);
174 
175         os.flush();
176 
177         log->Printf ("Transformed function AST:\n%s", s.c_str());
178     }
179 
180     return ret;
181 }
182 
183 bool
184 ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
185 {
186     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
187 
188     if (!m_sema)
189         return false;
190 
191     if (!MethodDecl)
192         return false;
193 
194     if (log && log->GetVerbose())
195     {
196         std::string s;
197         raw_string_ostream os(s);
198 
199         MethodDecl->print(os);
200 
201         os.flush();
202 
203         log->Printf ("Untransformed method AST:\n%s", s.c_str());
204     }
205 
206     Stmt *method_body = MethodDecl->getBody();
207 
208     if (!method_body)
209         return false;
210 
211     CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
212 
213     bool ret = SynthesizeBodyResult (compound_stmt,
214                                      MethodDecl);
215 
216     if (log && log->GetVerbose())
217     {
218         std::string s;
219         raw_string_ostream os(s);
220 
221         MethodDecl->print(os);
222 
223         os.flush();
224 
225         log->Printf("Transformed method AST:\n%s", s.c_str());
226     }
227 
228     return ret;
229 }
230 
231 bool
232 ASTResultSynthesizer::SynthesizeBodyResult (CompoundStmt *Body,
233                                             DeclContext *DC)
234 {
235     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
236 
237     ASTContext &Ctx(*m_ast_context);
238 
239     if (!Body)
240         return false;
241 
242     if (Body->body_empty())
243         return false;
244 
245     Stmt **last_stmt_ptr = Body->body_end() - 1;
246     Stmt *last_stmt = *last_stmt_ptr;
247 
248     while (dyn_cast<NullStmt>(last_stmt))
249     {
250         if (last_stmt_ptr != Body->body_begin())
251         {
252             last_stmt_ptr--;
253             last_stmt = *last_stmt_ptr;
254         }
255         else
256         {
257             return false;
258         }
259     }
260 
261     Expr *last_expr = dyn_cast<Expr>(last_stmt);
262 
263     if (!last_expr)
264         // No auxiliary variable necessary; expression returns void
265         return true;
266 
267     // In C++11, last_expr can be a LValueToRvalue implicit cast.  Strip that off if that's the
268     // case.
269 
270     do {
271         ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
272 
273         if (!implicit_cast)
274             break;
275 
276         if (implicit_cast->getCastKind() != CK_LValueToRValue)
277             break;
278 
279         last_expr = implicit_cast->getSubExpr();
280     } while (0);
281 
282     // is_lvalue is used to record whether the expression returns an assignable Lvalue or an
283     // Rvalue.  This is relevant because they are handled differently.
284     //
285     // For Lvalues
286     //
287     //   - In AST result synthesis (here!) the expression E is transformed into an initialization
288     //     T *$__lldb_expr_result_ptr = &E.
289     //
290     //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
291     //     passed into the expression.
292     //
293     //   - In IR transformations, reads and writes to $__lldb_expr_result_ptr are redirected at
294     //     an entry in the struct ($__lldb_arg) passed into the expression.  (Other persistent
295     //     variables are treated similarly, having been materialized as references, but in those
296     //     cases the value of the reference itself is never modified.)
297     //
298     //   - During materialization, $0 (the result persistent variable) is ignored.
299     //
300     //   - During dematerialization, $0 is marked up as a load address with value equal to the
301     //     contents of the structure entry.
302     //
303     // For Rvalues
304     //
305     //   - In AST result synthesis the expression E is transformed into an initialization
306     //     static T $__lldb_expr_result = E.
307     //
308     //   - In structure allocation, a pointer-sized slot is allocated in the struct that is to be
309     //     passed into the expression.
310     //
311     //   - In IR transformations, an instruction is inserted at the beginning of the function to
312     //     dereference the pointer resident in the slot.  Reads and writes to $__lldb_expr_result
313     //     are redirected at that dereferenced version.  Guard variables for the static variable
314     //     are excised.
315     //
316     //   - During materialization, $0 (the result persistent variable) is populated with the location
317     //     of a newly-allocated area of memory.
318     //
319     //   - During dematerialization, $0 is ignored.
320 
321     bool is_lvalue =
322         (last_expr->getValueKind() == VK_LValue || last_expr->getValueKind() == VK_XValue) &&
323         (last_expr->getObjectKind() == OK_Ordinary);
324 
325     QualType expr_qual_type = last_expr->getType();
326     const clang::Type *expr_type = expr_qual_type.getTypePtr();
327 
328     if (!expr_type)
329         return false;
330 
331     if (expr_type->isVoidType())
332         return true;
333 
334     if (log)
335     {
336         std::string s = expr_qual_type.getAsString();
337 
338         log->Printf("Last statement is an %s with type: %s", (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
339     }
340 
341     clang::VarDecl *result_decl = NULL;
342 
343     if (is_lvalue)
344     {
345         IdentifierInfo *result_ptr_id;
346 
347         if (expr_type->isFunctionType())
348             result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should be treated like function pointers
349         else
350             result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
351 
352         m_sema->RequireCompleteType(SourceLocation(), expr_qual_type, clang::diag::err_incomplete_type);
353 
354         QualType ptr_qual_type;
355 
356         if (expr_qual_type->getAs<ObjCObjectType>() != NULL)
357             ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
358         else
359             ptr_qual_type = Ctx.getPointerType(expr_qual_type);
360 
361         result_decl = VarDecl::Create(Ctx,
362                                       DC,
363                                       SourceLocation(),
364                                       SourceLocation(),
365                                       result_ptr_id,
366                                       ptr_qual_type,
367                                       NULL,
368                                       SC_Static);
369 
370         if (!result_decl)
371             return false;
372 
373         ExprResult address_of_expr = m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
374 
375         m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, false);
376     }
377     else
378     {
379         IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
380 
381         result_decl = VarDecl::Create(Ctx,
382                                       DC,
383                                       SourceLocation(),
384                                       SourceLocation(),
385                                       &result_id,
386                                       expr_qual_type,
387                                       NULL,
388                                       SC_Static);
389 
390         if (!result_decl)
391             return false;
392 
393         m_sema->AddInitializerToDecl(result_decl, last_expr, true, false);
394     }
395 
396     DC->addDecl(result_decl);
397 
398     ///////////////////////////////
399     // call AddInitializerToDecl
400     //
401 
402     //m_sema->AddInitializerToDecl(result_decl, last_expr);
403 
404     /////////////////////////////////
405     // call ConvertDeclToDeclGroup
406     //
407 
408     Sema::DeclGroupPtrTy result_decl_group_ptr;
409 
410     result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
411 
412     ////////////////////////
413     // call ActOnDeclStmt
414     //
415 
416     StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(result_decl_group_ptr,
417                                                                        SourceLocation(),
418                                                                        SourceLocation()));
419 
420     ////////////////////////////////////////////////
421     // replace the old statement with the new one
422     //
423 
424     *last_stmt_ptr = reinterpret_cast<Stmt*>(result_initialization_stmt_result.get());
425 
426     return true;
427 }
428 
429 void
430 ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx)
431 {
432     if (m_passthrough)
433         m_passthrough->HandleTranslationUnit(Ctx);
434 }
435 
436 void
437 ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
438 {
439     typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
440 
441     for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
442          e = TypeDeclIterator(FunDeclCtx->decls_end());
443          i != e;
444          ++i)
445     {
446         MaybeRecordPersistentType(*i);
447     }
448 }
449 
450 void
451 ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
452 {
453     if (!D->getIdentifier())
454         return;
455 
456     StringRef name = D->getName();
457 
458     if (name.size() == 0 || name[0] != '$')
459         return;
460 
461     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
462 
463     ConstString name_cs(name.str().c_str());
464 
465     if (log)
466         log->Printf("Recording persistent type %s\n", name_cs.GetCString());
467 
468     m_decls.push_back(D);
469 }
470 
471 void
472 ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D)
473 {
474     lldbassert(m_top_level);
475 
476     if (!D->getIdentifier())
477         return;
478 
479     StringRef name = D->getName();
480 
481     if (name.size() == 0)
482         return;
483 
484     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
485 
486     ConstString name_cs(name.str().c_str());
487 
488     if (log)
489         log->Printf("Recording persistent decl %s\n", name_cs.GetCString());
490 
491     m_decls.push_back(D);
492 }
493 
494 void
495 ASTResultSynthesizer::CommitPersistentDecls()
496 {
497     for (clang::NamedDecl *decl : m_decls)
498     {
499         StringRef name = decl->getName();
500         ConstString name_cs(name.str().c_str());
501 
502         Decl *D_scratch = m_target.GetClangASTImporter()->DeportDecl(
503             m_target.GetScratchClangASTContext()->getASTContext(), m_ast_context, decl);
504 
505         if (!D_scratch)
506         {
507             Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
508 
509             if (log)
510             {
511                 std::string s;
512                 llvm::raw_string_ostream ss(s);
513                 decl->dump(ss);
514                 ss.flush();
515 
516                 log->Printf("Couldn't commit persistent  decl: %s\n", s.c_str());
517             }
518 
519             continue;
520         }
521 
522         if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
523             llvm::cast<ClangPersistentVariables>(m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
524                 ->RegisterPersistentDecl(name_cs, NamedDecl_scratch);
525     }
526 }
527 
528 void
529 ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
530 {
531     if (m_passthrough)
532         m_passthrough->HandleTagDeclDefinition(D);
533 }
534 
535 void
536 ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D)
537 {
538     if (m_passthrough)
539         m_passthrough->CompleteTentativeDefinition(D);
540 }
541 
542 void
543 ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD)
544 {
545     if (m_passthrough)
546         m_passthrough->HandleVTable(RD);
547 }
548 
549 void
550 ASTResultSynthesizer::PrintStats()
551 {
552     if (m_passthrough)
553         m_passthrough->PrintStats();
554 }
555 
556 void
557 ASTResultSynthesizer::InitializeSema(Sema &S)
558 {
559     m_sema = &S;
560 
561     if (m_passthrough_sema)
562         m_passthrough_sema->InitializeSema(S);
563 }
564 
565 void
566 ASTResultSynthesizer::ForgetSema()
567 {
568     m_sema = NULL;
569 
570     if (m_passthrough_sema)
571         m_passthrough_sema->ForgetSema();
572 }
573