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