void TraverseTUnitConsumer::InvestigateASTContextTypes( ASTContext& context ) { // const SmallVectorImpl<Type *>& auto& types = context.getTypes(); TypePrinter printer(context.getPrintingPolicy(), /* indentation */ 2); const char *placeholder = ""; // "hey" for(const Type *type : types) { llvm::errs() << " - "; printer.print(type, Qualifiers(), llvm::errs(), placeholder); llvm::errs() << "\n"; } (terrs().magenta() << "InvestigateASTContextTypes(): END.\n").reset(); }
static Qualifiers getDeclQualifiers(const Decl *D) { if(auto Value = dyn_cast<ValueDecl>(D)) return Value->getType().split().second; return Qualifiers(); }
Expr* EvaluateTSynthesizer::BuildDynamicExprInfo(Expr* SubTree, bool ValuePrinterReq) { // 1. Find the DynamicExprInfo class CXXRecordDecl* ExprInfo = cast_or_null<CXXRecordDecl>(m_Interpreter->LookupDecl("cling"). LookupDecl("DynamicExprInfo"). getSingleDecl()); assert(ExprInfo && "DynamicExprInfo declaration not found!"); // 2. Get the expression containing @-s and get the variable addresses std::string Template; llvm::SmallVector<DeclRefExpr*, 4> Addresses; llvm::raw_string_ostream OS(Template); const PrintingPolicy& Policy = m_Context->getPrintingPolicy(); StmtPrinterHelper helper(Policy, Addresses, m_Sema); // In case when we print non paren inits like int i = h->Draw(); // not int i(h->Draw()). This simplifies the LifetimeHandler's // constructor, there we don't need to add parenthesis while // wrapping the expression. if (!isa<ParenListExpr>(SubTree)) OS << '('; SubTree->printPretty(OS, &helper, Policy); if (!isa<ParenListExpr>(SubTree)) OS << ')'; OS.flush(); // 3. Build the template Expr* ExprTemplate = ConstructConstCharPtrExpr(Template.c_str()); // 4. Build the array of addresses QualType VarAddrTy = m_Sema->BuildArrayType(m_Context->VoidPtrTy, ArrayType::Normal, /*ArraySize*/0, Qualifiers(), m_NoRange, DeclarationName() ); ASTOwningVector<Expr*> Inits(*m_Sema); Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext); for (unsigned int i = 0; i < Addresses.size(); ++i) { Expr* UnOp = m_Sema->BuildUnaryOp(S, m_NoSLoc, UO_AddrOf, Addresses[i]).take(); m_Sema->ImpCastExprToType(UnOp, m_Context->getPointerType(m_Context->VoidPtrTy), CK_BitCast); Inits.push_back(UnOp); } // We need valid source locations to avoid assert(InitList.isExplicit()...) InitListExpr* ILE = m_Sema->ActOnInitList(m_NoSLoc, move_arg(Inits), m_NoELoc).takeAs<InitListExpr>(); Expr* ExprAddresses = m_Sema->BuildCompoundLiteralExpr(m_NoSLoc, m_Context->CreateTypeSourceInfo(VarAddrTy), m_NoELoc, ILE).take(); assert (ExprAddresses && "Could not build the void* array"); m_Sema->ImpCastExprToType(ExprAddresses, m_Context->getPointerType(m_Context->VoidPtrTy), CK_ArrayToPointerDecay); // Is the result of the expression to be printed or not Expr* VPReq = 0; if (ValuePrinterReq) VPReq = m_Sema->ActOnCXXBoolLiteral(m_NoSLoc, tok::kw_true).take(); else VPReq = m_Sema->ActOnCXXBoolLiteral(m_NoSLoc, tok::kw_false).take(); ASTOwningVector<Expr*> CtorArgs(*m_Sema); CtorArgs.push_back(ExprTemplate); CtorArgs.push_back(ExprAddresses); CtorArgs.push_back(VPReq); // 5. Call the constructor QualType ExprInfoTy = m_Context->getTypeDeclType(ExprInfo); ExprResult Initializer = m_Sema->ActOnParenListExpr(m_NoSLoc, m_NoELoc, move_arg(CtorArgs)); Expr* Result = m_Sema->BuildCXXNew(m_NoSLoc, /*UseGlobal=*/false, m_NoSLoc, /*PlacementArgs=*/MultiExprArg(), m_NoELoc, m_NoRange, ExprInfoTy, m_Context->CreateTypeSourceInfo(ExprInfoTy), /*ArraySize=*/0, //BuildCXXNew depends on the SLoc to be //valid! // TODO: Propose a patch in clang m_NoRange, Initializer.take(), /*TypeMayContainAuto*/false ).take(); return Result; }