xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
15ffd83dbSDimitry Andric //===-- ASTResultSynthesizer.cpp ------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "ASTResultSynthesizer.h"
100b57cec5SDimitry Andric 
115ffd83dbSDimitry Andric #include "ClangASTImporter.h"
120b57cec5SDimitry Andric #include "ClangPersistentVariables.h"
130b57cec5SDimitry Andric 
145ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
150b57cec5SDimitry Andric #include "lldb/Target/Target.h"
160b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
1781ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
180b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
190b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
200b57cec5SDimitry Andric #include "clang/AST/Decl.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
220b57cec5SDimitry Andric #include "clang/AST/DeclGroup.h"
230b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
240b57cec5SDimitry Andric #include "clang/AST/Expr.h"
250b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
260b57cec5SDimitry Andric #include "clang/Parse/Parser.h"
270b57cec5SDimitry Andric #include "clang/Sema/SemaDiagnostic.h"
280b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
290b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
30fe6060f1SDimitry Andric #include <cstdlib>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric using namespace clang;
340b57cec5SDimitry Andric using namespace lldb_private;
350b57cec5SDimitry Andric 
ASTResultSynthesizer(ASTConsumer * passthrough,bool top_level,Target & target)360b57cec5SDimitry Andric ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
370b57cec5SDimitry Andric                                            bool top_level, Target &target)
380b57cec5SDimitry Andric     : m_ast_context(nullptr), m_passthrough(passthrough),
390b57cec5SDimitry Andric       m_passthrough_sema(nullptr), m_target(target), m_sema(nullptr),
400b57cec5SDimitry Andric       m_top_level(top_level) {
410b57cec5SDimitry Andric   if (!m_passthrough)
420b57cec5SDimitry Andric     return;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
47fe6060f1SDimitry Andric ASTResultSynthesizer::~ASTResultSynthesizer() = default;
480b57cec5SDimitry Andric 
Initialize(ASTContext & Context)490b57cec5SDimitry Andric void ASTResultSynthesizer::Initialize(ASTContext &Context) {
500b57cec5SDimitry Andric   m_ast_context = &Context;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   if (m_passthrough)
530b57cec5SDimitry Andric     m_passthrough->Initialize(Context);
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
TransformTopLevelDecl(Decl * D)560b57cec5SDimitry Andric void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
5781ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   if (NamedDecl *named_decl = dyn_cast<NamedDecl>(D)) {
600b57cec5SDimitry Andric     if (log && log->GetVerbose()) {
610b57cec5SDimitry Andric       if (named_decl->getIdentifier())
629dba64beSDimitry Andric         LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
630b57cec5SDimitry Andric                   named_decl->getIdentifier()->getNameStart());
640b57cec5SDimitry Andric       else if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D))
659dba64beSDimitry Andric         LLDB_LOGF(log, "TransformTopLevelDecl(%s)",
660b57cec5SDimitry Andric                   method_decl->getSelector().getAsString().c_str());
670b57cec5SDimitry Andric       else
689dba64beSDimitry Andric         LLDB_LOGF(log, "TransformTopLevelDecl(<complex>)");
690b57cec5SDimitry Andric     }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric     if (m_top_level) {
720b57cec5SDimitry Andric       RecordPersistentDecl(named_decl);
730b57cec5SDimitry Andric     }
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   if (LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D)) {
770b57cec5SDimitry Andric     RecordDecl::decl_iterator decl_iterator;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric     for (decl_iterator = linkage_spec_decl->decls_begin();
800b57cec5SDimitry Andric          decl_iterator != linkage_spec_decl->decls_end(); ++decl_iterator) {
810b57cec5SDimitry Andric       TransformTopLevelDecl(*decl_iterator);
820b57cec5SDimitry Andric     }
830b57cec5SDimitry Andric   } else if (!m_top_level) {
840b57cec5SDimitry Andric     if (ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(D)) {
850b57cec5SDimitry Andric       if (m_ast_context &&
860b57cec5SDimitry Andric           !method_decl->getSelector().getAsString().compare("$__lldb_expr:")) {
870b57cec5SDimitry Andric         RecordPersistentTypes(method_decl);
880b57cec5SDimitry Andric         SynthesizeObjCMethodResult(method_decl);
890b57cec5SDimitry Andric       }
900b57cec5SDimitry Andric     } else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) {
910b57cec5SDimitry Andric       // When completing user input the body of the function may be a nullptr.
920b57cec5SDimitry Andric       if (m_ast_context && function_decl->hasBody() &&
930b57cec5SDimitry Andric           !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) {
940b57cec5SDimitry Andric         RecordPersistentTypes(function_decl);
950b57cec5SDimitry Andric         SynthesizeFunctionResult(function_decl);
960b57cec5SDimitry Andric       }
970b57cec5SDimitry Andric     }
980b57cec5SDimitry Andric   }
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric 
HandleTopLevelDecl(DeclGroupRef D)1010b57cec5SDimitry Andric bool ASTResultSynthesizer::HandleTopLevelDecl(DeclGroupRef D) {
1020b57cec5SDimitry Andric   DeclGroupRef::iterator decl_iterator;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   for (decl_iterator = D.begin(); decl_iterator != D.end(); ++decl_iterator) {
1050b57cec5SDimitry Andric     Decl *decl = *decl_iterator;
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric     TransformTopLevelDecl(decl);
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   if (m_passthrough)
1110b57cec5SDimitry Andric     return m_passthrough->HandleTopLevelDecl(D);
1120b57cec5SDimitry Andric   return true;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
SynthesizeFunctionResult(FunctionDecl * FunDecl)1150b57cec5SDimitry Andric bool ASTResultSynthesizer::SynthesizeFunctionResult(FunctionDecl *FunDecl) {
11681ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   if (!m_sema)
1190b57cec5SDimitry Andric     return false;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   FunctionDecl *function_decl = FunDecl;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   if (!function_decl)
1240b57cec5SDimitry Andric     return false;
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   if (log && log->GetVerbose()) {
1270b57cec5SDimitry Andric     std::string s;
1280b57cec5SDimitry Andric     raw_string_ostream os(s);
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric     function_decl->print(os);
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric     os.flush();
1330b57cec5SDimitry Andric 
1349dba64beSDimitry Andric     LLDB_LOGF(log, "Untransformed function AST:\n%s", s.c_str());
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   Stmt *function_body = function_decl->getBody();
1380b57cec5SDimitry Andric   CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   bool ret = SynthesizeBodyResult(compound_stmt, function_decl);
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   if (log && log->GetVerbose()) {
1430b57cec5SDimitry Andric     std::string s;
1440b57cec5SDimitry Andric     raw_string_ostream os(s);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric     function_decl->print(os);
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric     os.flush();
1490b57cec5SDimitry Andric 
1509dba64beSDimitry Andric     LLDB_LOGF(log, "Transformed function AST:\n%s", s.c_str());
1510b57cec5SDimitry Andric   }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   return ret;
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
SynthesizeObjCMethodResult(ObjCMethodDecl * MethodDecl)1560b57cec5SDimitry Andric bool ASTResultSynthesizer::SynthesizeObjCMethodResult(
1570b57cec5SDimitry Andric     ObjCMethodDecl *MethodDecl) {
15881ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   if (!m_sema)
1610b57cec5SDimitry Andric     return false;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   if (!MethodDecl)
1640b57cec5SDimitry Andric     return false;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   if (log && log->GetVerbose()) {
1670b57cec5SDimitry Andric     std::string s;
1680b57cec5SDimitry Andric     raw_string_ostream os(s);
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric     MethodDecl->print(os);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric     os.flush();
1730b57cec5SDimitry Andric 
1749dba64beSDimitry Andric     LLDB_LOGF(log, "Untransformed method AST:\n%s", s.c_str());
1750b57cec5SDimitry Andric   }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   Stmt *method_body = MethodDecl->getBody();
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   if (!method_body)
1800b57cec5SDimitry Andric     return false;
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(method_body);
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   bool ret = SynthesizeBodyResult(compound_stmt, MethodDecl);
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   if (log && log->GetVerbose()) {
1870b57cec5SDimitry Andric     std::string s;
1880b57cec5SDimitry Andric     raw_string_ostream os(s);
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric     MethodDecl->print(os);
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric     os.flush();
1930b57cec5SDimitry Andric 
1949dba64beSDimitry Andric     LLDB_LOGF(log, "Transformed method AST:\n%s", s.c_str());
1950b57cec5SDimitry Andric   }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   return ret;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
200fcaf7f86SDimitry Andric /// Returns true if LLDB can take the address of the given lvalue for the sake
201fcaf7f86SDimitry Andric /// of capturing the expression result. Returns false if LLDB should instead
202fcaf7f86SDimitry Andric /// store the expression result in a result variable.
CanTakeAddressOfLValue(const Expr * lvalue_expr)203fcaf7f86SDimitry Andric static bool CanTakeAddressOfLValue(const Expr *lvalue_expr) {
204fcaf7f86SDimitry Andric   assert(lvalue_expr->getValueKind() == VK_LValue &&
205fcaf7f86SDimitry Andric          "lvalue_expr not a lvalue");
206fcaf7f86SDimitry Andric 
207fcaf7f86SDimitry Andric   QualType qt = lvalue_expr->getType();
208fcaf7f86SDimitry Andric   // If the lvalue has const-qualified non-volatile integral or enum type, then
209fcaf7f86SDimitry Andric   // the underlying value might come from a const static data member as
210fcaf7f86SDimitry Andric   // described in C++11 [class.static.data]p3. If that's the case, then the
211fcaf7f86SDimitry Andric   // value might not have an address if the user didn't also define the member
212fcaf7f86SDimitry Andric   // in a namespace scope. Taking the address would cause that LLDB later fails
213fcaf7f86SDimitry Andric   // to link the expression, so those lvalues should be stored in a result
214fcaf7f86SDimitry Andric   // variable.
215fcaf7f86SDimitry Andric   if (qt->isIntegralOrEnumerationType() && qt.isConstQualified() &&
216fcaf7f86SDimitry Andric       !qt.isVolatileQualified())
217fcaf7f86SDimitry Andric     return false;
218fcaf7f86SDimitry Andric   return true;
219fcaf7f86SDimitry Andric }
220fcaf7f86SDimitry Andric 
SynthesizeBodyResult(CompoundStmt * Body,DeclContext * DC)2210b57cec5SDimitry Andric bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,
2220b57cec5SDimitry Andric                                                 DeclContext *DC) {
22381ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Expressions);
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   ASTContext &Ctx(*m_ast_context);
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   if (!Body)
2280b57cec5SDimitry Andric     return false;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   if (Body->body_empty())
2310b57cec5SDimitry Andric     return false;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   Stmt **last_stmt_ptr = Body->body_end() - 1;
2340b57cec5SDimitry Andric   Stmt *last_stmt = *last_stmt_ptr;
2350b57cec5SDimitry Andric 
2360eae32dcSDimitry Andric   while (isa<NullStmt>(last_stmt)) {
2370b57cec5SDimitry Andric     if (last_stmt_ptr != Body->body_begin()) {
2380b57cec5SDimitry Andric       last_stmt_ptr--;
2390b57cec5SDimitry Andric       last_stmt = *last_stmt_ptr;
2400b57cec5SDimitry Andric     } else {
2410b57cec5SDimitry Andric       return false;
2420b57cec5SDimitry Andric     }
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   Expr *last_expr = dyn_cast<Expr>(last_stmt);
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   if (!last_expr)
2480b57cec5SDimitry Andric     // No auxiliary variable necessary; expression returns void
2490b57cec5SDimitry Andric     return true;
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   // In C++11, last_expr can be a LValueToRvalue implicit cast.  Strip that off
2520b57cec5SDimitry Andric   // if that's the case.
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   do {
2550b57cec5SDimitry Andric     ImplicitCastExpr *implicit_cast = dyn_cast<ImplicitCastExpr>(last_expr);
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric     if (!implicit_cast)
2580b57cec5SDimitry Andric       break;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric     if (implicit_cast->getCastKind() != CK_LValueToRValue)
2610b57cec5SDimitry Andric       break;
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric     last_expr = implicit_cast->getSubExpr();
2640b57cec5SDimitry Andric   } while (false);
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   // is_lvalue is used to record whether the expression returns an assignable
2670b57cec5SDimitry Andric   // Lvalue or an Rvalue.  This is relevant because they are handled
2680b57cec5SDimitry Andric   // differently.
2690b57cec5SDimitry Andric   //
2700b57cec5SDimitry Andric   // For Lvalues
2710b57cec5SDimitry Andric   //
2720b57cec5SDimitry Andric   //   - In AST result synthesis (here!) the expression E is transformed into an
2735ffd83dbSDimitry Andric   //     initialization T *$__lldb_expr_result_ptr = &E.
2740b57cec5SDimitry Andric   //
2750b57cec5SDimitry Andric   //   - In structure allocation, a pointer-sized slot is allocated in the
2765ffd83dbSDimitry Andric   //     struct that is to be passed into the expression.
2770b57cec5SDimitry Andric   //
2780b57cec5SDimitry Andric   //   - In IR transformations, reads and writes to $__lldb_expr_result_ptr are
2795ffd83dbSDimitry Andric   //     redirected at an entry in the struct ($__lldb_arg) passed into the
2805ffd83dbSDimitry Andric   //     expression. (Other persistent variables are treated similarly, having
2815ffd83dbSDimitry Andric   //     been materialized as references, but in those cases the value of the
2825ffd83dbSDimitry Andric   //     reference itself is never modified.)
2830b57cec5SDimitry Andric   //
2840b57cec5SDimitry Andric   //   - During materialization, $0 (the result persistent variable) is ignored.
2850b57cec5SDimitry Andric   //
2860b57cec5SDimitry Andric   //   - During dematerialization, $0 is marked up as a load address with value
2875ffd83dbSDimitry Andric   //     equal to the contents of the structure entry.
2880b57cec5SDimitry Andric   //
289fcaf7f86SDimitry Andric   //   - Note: if we cannot take an address of the resulting Lvalue (e.g. it's
290fcaf7f86SDimitry Andric   //     a static const member without an out-of-class definition), then we
291fcaf7f86SDimitry Andric   //     follow the Rvalue route.
292fcaf7f86SDimitry Andric   //
2930b57cec5SDimitry Andric   // For Rvalues
2940b57cec5SDimitry Andric   //
2950b57cec5SDimitry Andric   //   - In AST result synthesis the expression E is transformed into an
2965ffd83dbSDimitry Andric   //     initialization static T $__lldb_expr_result = E.
2970b57cec5SDimitry Andric   //
2980b57cec5SDimitry Andric   //   - In structure allocation, a pointer-sized slot is allocated in the
2995ffd83dbSDimitry Andric   //     struct that is to be passed into the expression.
3000b57cec5SDimitry Andric   //
3010b57cec5SDimitry Andric   //   - In IR transformations, an instruction is inserted at the beginning of
3025ffd83dbSDimitry Andric   //     the function to dereference the pointer resident in the slot. Reads and
3035ffd83dbSDimitry Andric   //     writes to $__lldb_expr_result are redirected at that dereferenced
3045ffd83dbSDimitry Andric   //     version. Guard variables for the static variable are excised.
3050b57cec5SDimitry Andric   //
3060b57cec5SDimitry Andric   //   - During materialization, $0 (the result persistent variable) is
3075ffd83dbSDimitry Andric   //     populated with the location of a newly-allocated area of memory.
3080b57cec5SDimitry Andric   //
3090b57cec5SDimitry Andric   //   - During dematerialization, $0 is ignored.
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   bool is_lvalue = last_expr->getValueKind() == VK_LValue &&
3120b57cec5SDimitry Andric                    last_expr->getObjectKind() == OK_Ordinary;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   QualType expr_qual_type = last_expr->getType();
3150b57cec5SDimitry Andric   const clang::Type *expr_type = expr_qual_type.getTypePtr();
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   if (!expr_type)
3180b57cec5SDimitry Andric     return false;
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   if (expr_type->isVoidType())
3210b57cec5SDimitry Andric     return true;
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   if (log) {
3240b57cec5SDimitry Andric     std::string s = expr_qual_type.getAsString();
3250b57cec5SDimitry Andric 
3269dba64beSDimitry Andric     LLDB_LOGF(log, "Last statement is an %s with type: %s",
3270b57cec5SDimitry Andric               (is_lvalue ? "lvalue" : "rvalue"), s.c_str());
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   clang::VarDecl *result_decl = nullptr;
3310b57cec5SDimitry Andric 
332fcaf7f86SDimitry Andric   if (is_lvalue && CanTakeAddressOfLValue(last_expr)) {
3330b57cec5SDimitry Andric     IdentifierInfo *result_ptr_id;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric     if (expr_type->isFunctionType())
3360b57cec5SDimitry Andric       result_ptr_id =
3370b57cec5SDimitry Andric           &Ctx.Idents.get("$__lldb_expr_result"); // functions actually should
3380b57cec5SDimitry Andric                                                   // be treated like function
3390b57cec5SDimitry Andric                                                   // pointers
3400b57cec5SDimitry Andric     else
3410b57cec5SDimitry Andric       result_ptr_id = &Ctx.Idents.get("$__lldb_expr_result_ptr");
3420b57cec5SDimitry Andric 
3435ffd83dbSDimitry Andric     m_sema->RequireCompleteType(last_expr->getSourceRange().getBegin(),
3445ffd83dbSDimitry Andric                                 expr_qual_type,
3450b57cec5SDimitry Andric                                 clang::diag::err_incomplete_type);
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric     QualType ptr_qual_type;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric     if (expr_qual_type->getAs<ObjCObjectType>() != nullptr)
3500b57cec5SDimitry Andric       ptr_qual_type = Ctx.getObjCObjectPointerType(expr_qual_type);
3510b57cec5SDimitry Andric     else
3520b57cec5SDimitry Andric       ptr_qual_type = Ctx.getPointerType(expr_qual_type);
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric     result_decl =
3550b57cec5SDimitry Andric         VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(),
3560b57cec5SDimitry Andric                         result_ptr_id, ptr_qual_type, nullptr, SC_Static);
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric     if (!result_decl)
3590b57cec5SDimitry Andric       return false;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     ExprResult address_of_expr =
3620b57cec5SDimitry Andric         m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);
3630b57cec5SDimitry Andric     if (address_of_expr.get())
3640b57cec5SDimitry Andric       m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true);
3650b57cec5SDimitry Andric     else
3660b57cec5SDimitry Andric       return false;
3670b57cec5SDimitry Andric   } else {
3680b57cec5SDimitry Andric     IdentifierInfo &result_id = Ctx.Idents.get("$__lldb_expr_result");
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric     result_decl =
3710b57cec5SDimitry Andric         VarDecl::Create(Ctx, DC, SourceLocation(), SourceLocation(), &result_id,
3720b57cec5SDimitry Andric                         expr_qual_type, nullptr, SC_Static);
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric     if (!result_decl)
3750b57cec5SDimitry Andric       return false;
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric     m_sema->AddInitializerToDecl(result_decl, last_expr, true);
3780b57cec5SDimitry Andric   }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   DC->addDecl(result_decl);
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric   ///////////////////////////////
3830b57cec5SDimitry Andric   // call AddInitializerToDecl
3840b57cec5SDimitry Andric   //
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric   // m_sema->AddInitializerToDecl(result_decl, last_expr);
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   /////////////////////////////////
3890b57cec5SDimitry Andric   // call ConvertDeclToDeclGroup
3900b57cec5SDimitry Andric   //
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric   Sema::DeclGroupPtrTy result_decl_group_ptr;
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric   result_decl_group_ptr = m_sema->ConvertDeclToDeclGroup(result_decl);
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   ////////////////////////
3970b57cec5SDimitry Andric   // call ActOnDeclStmt
3980b57cec5SDimitry Andric   //
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   StmtResult result_initialization_stmt_result(m_sema->ActOnDeclStmt(
4010b57cec5SDimitry Andric       result_decl_group_ptr, SourceLocation(), SourceLocation()));
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   ////////////////////////////////////////////////
4040b57cec5SDimitry Andric   // replace the old statement with the new one
4050b57cec5SDimitry Andric   //
4060b57cec5SDimitry Andric 
407480093f4SDimitry Andric   *last_stmt_ptr = static_cast<Stmt *>(result_initialization_stmt_result.get());
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   return true;
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric 
HandleTranslationUnit(ASTContext & Ctx)4120b57cec5SDimitry Andric void ASTResultSynthesizer::HandleTranslationUnit(ASTContext &Ctx) {
4130b57cec5SDimitry Andric   if (m_passthrough)
4140b57cec5SDimitry Andric     m_passthrough->HandleTranslationUnit(Ctx);
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric 
RecordPersistentTypes(DeclContext * FunDeclCtx)4170b57cec5SDimitry Andric void ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx) {
4180b57cec5SDimitry Andric   typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()),
4210b57cec5SDimitry Andric                         e = TypeDeclIterator(FunDeclCtx->decls_end());
4220b57cec5SDimitry Andric        i != e; ++i) {
4230b57cec5SDimitry Andric     MaybeRecordPersistentType(*i);
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric 
MaybeRecordPersistentType(TypeDecl * D)4270b57cec5SDimitry Andric void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) {
4280b57cec5SDimitry Andric   if (!D->getIdentifier())
4290b57cec5SDimitry Andric     return;
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   StringRef name = D->getName();
432*06c3fb27SDimitry Andric   if (name.empty() || name.front() != '$')
4330b57cec5SDimitry Andric     return;
4340b57cec5SDimitry Andric 
435*06c3fb27SDimitry Andric   LLDB_LOG(GetLog(LLDBLog::Expressions), "Recording persistent type {0}", name);
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   m_decls.push_back(D);
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
RecordPersistentDecl(NamedDecl * D)4400b57cec5SDimitry Andric void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) {
4410b57cec5SDimitry Andric   lldbassert(m_top_level);
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   if (!D->getIdentifier())
4440b57cec5SDimitry Andric     return;
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric   StringRef name = D->getName();
447*06c3fb27SDimitry Andric   if (name.empty())
4480b57cec5SDimitry Andric     return;
4490b57cec5SDimitry Andric 
450*06c3fb27SDimitry Andric   LLDB_LOG(GetLog(LLDBLog::Expressions), "Recording persistent decl {0}", name);
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   m_decls.push_back(D);
4530b57cec5SDimitry Andric }
4540b57cec5SDimitry Andric 
CommitPersistentDecls()4550b57cec5SDimitry Andric void ASTResultSynthesizer::CommitPersistentDecls() {
456480093f4SDimitry Andric   auto *state =
457480093f4SDimitry Andric       m_target.GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC);
458480093f4SDimitry Andric   if (!state)
459480093f4SDimitry Andric     return;
460480093f4SDimitry Andric 
461480093f4SDimitry Andric   auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
462e8d8bef9SDimitry Andric 
463bdd1243dSDimitry Andric   lldb::TypeSystemClangSP scratch_ts_sp = ScratchTypeSystemClang::GetForTarget(
464e8d8bef9SDimitry Andric       m_target, m_ast_context->getLangOpts());
465480093f4SDimitry Andric 
4660b57cec5SDimitry Andric   for (clang::NamedDecl *decl : m_decls) {
4670b57cec5SDimitry Andric     StringRef name = decl->getName();
4680b57cec5SDimitry Andric 
4695ffd83dbSDimitry Andric     Decl *D_scratch = persistent_vars->GetClangASTImporter()->DeportDecl(
470bdd1243dSDimitry Andric         &scratch_ts_sp->getASTContext(), decl);
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric     if (!D_scratch) {
47381ad6265SDimitry Andric       Log *log = GetLog(LLDBLog::Expressions);
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric       if (log) {
4760b57cec5SDimitry Andric         std::string s;
4770b57cec5SDimitry Andric         llvm::raw_string_ostream ss(s);
4780b57cec5SDimitry Andric         decl->dump(ss);
4790b57cec5SDimitry Andric         ss.flush();
4800b57cec5SDimitry Andric 
4819dba64beSDimitry Andric         LLDB_LOGF(log, "Couldn't commit persistent  decl: %s\n", s.c_str());
4820b57cec5SDimitry Andric       }
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric       continue;
4850b57cec5SDimitry Andric     }
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric     if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch))
488*06c3fb27SDimitry Andric       persistent_vars->RegisterPersistentDecl(ConstString(name),
489*06c3fb27SDimitry Andric                                               NamedDecl_scratch, scratch_ts_sp);
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric }
4920b57cec5SDimitry Andric 
HandleTagDeclDefinition(TagDecl * D)4930b57cec5SDimitry Andric void ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D) {
4940b57cec5SDimitry Andric   if (m_passthrough)
4950b57cec5SDimitry Andric     m_passthrough->HandleTagDeclDefinition(D);
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric 
CompleteTentativeDefinition(VarDecl * D)4980b57cec5SDimitry Andric void ASTResultSynthesizer::CompleteTentativeDefinition(VarDecl *D) {
4990b57cec5SDimitry Andric   if (m_passthrough)
5000b57cec5SDimitry Andric     m_passthrough->CompleteTentativeDefinition(D);
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
HandleVTable(CXXRecordDecl * RD)5030b57cec5SDimitry Andric void ASTResultSynthesizer::HandleVTable(CXXRecordDecl *RD) {
5040b57cec5SDimitry Andric   if (m_passthrough)
5050b57cec5SDimitry Andric     m_passthrough->HandleVTable(RD);
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric 
PrintStats()5080b57cec5SDimitry Andric void ASTResultSynthesizer::PrintStats() {
5090b57cec5SDimitry Andric   if (m_passthrough)
5100b57cec5SDimitry Andric     m_passthrough->PrintStats();
5110b57cec5SDimitry Andric }
5120b57cec5SDimitry Andric 
InitializeSema(Sema & S)5130b57cec5SDimitry Andric void ASTResultSynthesizer::InitializeSema(Sema &S) {
5140b57cec5SDimitry Andric   m_sema = &S;
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   if (m_passthrough_sema)
5170b57cec5SDimitry Andric     m_passthrough_sema->InitializeSema(S);
5180b57cec5SDimitry Andric }
5190b57cec5SDimitry Andric 
ForgetSema()5200b57cec5SDimitry Andric void ASTResultSynthesizer::ForgetSema() {
5210b57cec5SDimitry Andric   m_sema = nullptr;
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   if (m_passthrough_sema)
5240b57cec5SDimitry Andric     m_passthrough_sema->ForgetSema();
5250b57cec5SDimitry Andric }
526