Exemple #1
0
void TemplateDlg::EnterTemplate()
{
	const PackageTemplate& tp = ActualTemplate();
	ArrayMap<String, EscValue> var;
	var.Add("PACKAGE", (String)~package);
	StdLib(var);
	label.Clear();
	ctrl.Clear();
	Point pos = templist.GetRect().BottomLeft();
	pos.y += 8;
	int cx = cancel.GetRect().right - pos.x;
	for(int i = 0; i < tp.item.GetCount(); i++) {
		const TemplateItem& m = tp.item[i];
		if(m.type == TEMPLATEITEM_OPTION)
			ctrl.Create<Option>().SetLabel(m.label);
		else {
			label.Add().SetLabel(m.label).LeftPos(pos.x, cx).TopPos(pos.y);
			Add(label.Top());
			pos.y += label.Top().GetMinSize().cy;
			switch(m.type) {
			case TEMPLATEITEM_ID: {
				EditField *e = new EditField;
				e->SetFilter(IdFilter);
				ctrl.Add(e);
				break;
			}
			case TEMPLATEITEM_FILENAME: {
				EditField *e = new EditField;
				e->SetFilter(FilenameFilter);
				ctrl.Add(e);
				break;
			}
			case TEMPLATEITEM_SELECT: {
				DropList *d = new DropList;
				for(int i = 0; i < m.value.GetCount(); i++)
					d->Add(i, m.value[i]);
				if(m.value.GetCount())
					d->SetIndex(0);
				ctrl.Add(d);
				break;
			}
			case TEMPLATEITEM_TEXT: {
			    EditField *e = new EditField;
			    ctrl.Add(e);
			    break;
			}
			}
		}
		Add(ctrl.Top());
		ctrl.Top() << ~delay;
		ctrl.Top().LeftPos(pos.x, cx).TopPos(pos.y);
		pos.y += ctrl.Top().GetMinSize().cy + 6;
		ctrl.Top().ClearModify();
	}
	Inits();
	Preview();
}
  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;
  }
  ASTNodeInfo EvaluateTSynthesizer::VisitDeclStmt(DeclStmt* Node) {
    // Visit all the children, which are the contents of the DeclGroupRef
    for (Stmt::child_iterator
           I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
      if (*I) {
        Expr* E = cast_or_null<Expr>(*I);
        if (!E || !IsArtificiallyDependent(E))
          continue;
        //FIXME: don't assume there is only one decl.
        assert(Node->isSingleDecl() && "There is more that one decl in stmt");
        VarDecl* CuredDecl = cast_or_null<VarDecl>(Node->getSingleDecl());
        assert(CuredDecl && "Not a variable declaration!");
        QualType CuredDeclTy = CuredDecl->getType();
        // check if the case is sometype * somevar = init;
        // or some_builtin_type somevar = init;
        if (CuredDecl->hasInit() && (CuredDeclTy->isAnyPointerType()
                                     || !CuredDeclTy->isRecordType())) {
          *I = SubstituteUnknownSymbol(CuredDeclTy, CuredDecl->getInit());
          continue;
        }

        // 1. Check whether this is the case of MyClass A(dep->symbol())
        // 2. Insert the RuntimeUniverse's LifetimeHandler instance
        // 3. Change the A's initializer to *(MyClass*)instance.getMemory()
        // 4. Make A reference (&A)
        // 5. Set the new initializer of A
        if (CuredDeclTy->isLValueReferenceType())
          continue;

        // Set Sema's Current DeclContext to the one we need
        DeclContext* OldDC = m_Sema->CurContext;
        m_Sema->CurContext = CuredDecl->getDeclContext();

        // 2.1 Find the LifetimeHandler type
        CXXRecordDecl* Handler
          = cast_or_null<CXXRecordDecl>(m_Interpreter->LookupDecl("cling").
                                        LookupDecl("runtime").
                                        LookupDecl("internal").
                                        LookupDecl("LifetimeHandler").
                                        getSingleDecl());
        assert(Handler && "LifetimeHandler type not found!");
        if (Handler) {
          ASTNodeInfo NewNode;
          // 2.2 Get unique name for the LifetimeHandler instance and
          // initialize it
          std::string UniqueName;
          m_Interpreter->createUniqueName(UniqueName);
          IdentifierInfo& II = m_Context->Idents.get(UniqueName);

          // Prepare the initialization Exprs.
          // We want to call LifetimeHandler(DynamicExprInfo* ExprInfo,
          //                                 DeclContext DC,
          //                                 const char* type)
          ASTOwningVector<Expr*> Inits(*m_Sema);
          // Add MyClass in LifetimeHandler unique(DynamicExprInfo* ExprInfo
          //                                       DC,
          //                                       "MyClass")
          // Build Arg0 DynamicExprInfo
          Inits.push_back(BuildDynamicExprInfo(E));
          // Build Arg1 DeclContext* DC
          CXXRecordDecl* D = dyn_cast<CXXRecordDecl>(m_Interpreter->
                                                     LookupDecl("clang").
                                                     LookupDecl("DeclContext").
                                                     getSingleDecl());
          assert(D && "DeclContext declaration not found!");
          QualType DCTy = m_Context->getTypeDeclType(D);
          Inits.push_back(ConstructCStyleCasePtrExpr(DCTy,
                                                     (uint64_t)m_CurDeclContext)
                          );
          // Build Arg2 llvm::StringRef
          // Get the type of the type without specifiers
          PrintingPolicy Policy(m_Context->getLangOpts());
          Policy.SuppressTagKeyword = 1;
          std::string Res;
          CuredDeclTy.getAsStringInternal(Res, Policy);
          Inits.push_back(ConstructConstCharPtrExpr(Res.c_str()));

          // 2.3 Create a variable from LifetimeHandler.
          QualType HandlerTy = m_Context->getTypeDeclType(Handler);
          VarDecl* HandlerInstance = VarDecl::Create(*m_Context,
                                                    CuredDecl->getDeclContext(),
                                                     m_NoSLoc,
                                                     m_NoSLoc,
                                                     &II,
                                                     HandlerTy,
                                                     /*TypeSourceInfo**/0,
                                                     SC_None,
                                                     SC_None);

          // 2.4 Call the best-match constructor. The method does overload
          // resolution of the constructors and then initializes the new
          // variable with it
          ExprResult InitExprResult
            = m_Sema->ActOnParenListExpr(m_NoSLoc,
                                         m_NoELoc,
                                         move_arg(Inits));
          m_Sema->AddInitializerToDecl(HandlerInstance,
                                       InitExprResult.take(),
                                       /*DirectInit*/ true,
                                       /*TypeMayContainAuto*/ false);

          // 2.5 Register the instance in the enclosing context
          CuredDecl->getDeclContext()->addDecl(HandlerInstance);
          NewNode.addNode(new (m_Context)
                          DeclStmt(DeclGroupRef(HandlerInstance),
                                   m_NoSLoc,
                                   m_NoELoc)
                          );

          // 3.1 Find the declaration - LifetimeHandler::getMemory()
          CXXMethodDecl* getMemDecl
            = m_Interpreter->LookupDecl("getMemory",
                                        Handler).getAs<CXXMethodDecl>();
          assert(getMemDecl && "LifetimeHandler::getMemory not found!");
          // 3.2 Build a DeclRefExpr, which holds the object
          DeclRefExpr* MemberExprBase
            = m_Sema->BuildDeclRefExpr(HandlerInstance,
                                       HandlerTy,
                                       VK_LValue,
                                       m_NoSLoc
                                       ).takeAs<DeclRefExpr>();
          // 3.3 Create a MemberExpr to getMemory from its declaration.
          CXXScopeSpec SS;
          LookupResult MemberLookup(*m_Sema, getMemDecl->getDeclName(),
                                    m_NoSLoc, Sema::LookupMemberName);
          // Add the declaration as if doesn't exist.
          // TODO: Check whether this is the most appropriate variant
          MemberLookup.addDecl(getMemDecl, AS_public);
          MemberLookup.resolveKind();
          Expr* MemberExpr = m_Sema->BuildMemberReferenceExpr(MemberExprBase,
                                                              HandlerTy,
                                                              m_NoSLoc,
                                                              /*IsArrow=*/false,
                                                              SS,
                                                              m_NoSLoc,
                                                    /*FirstQualifierInScope=*/0,
                                                              MemberLookup,
                                                              /*TemplateArgs=*/0
                                                              ).take();
          // 3.4 Build the actual call
          Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext);
          Expr* theCall = m_Sema->ActOnCallExpr(S,
                                                MemberExpr,
                                                m_NoSLoc,
                                                MultiExprArg(),
                                                m_NoELoc).take();
          // Cast to the type LHS type
          TypeSourceInfo* CuredDeclTSI
            = m_Context->CreateTypeSourceInfo(m_Context->getPointerType(
                                                                  CuredDeclTy));
          Expr* Result = m_Sema->BuildCStyleCastExpr(m_NoSLoc,
                                                     CuredDeclTSI,
                                                     m_NoELoc,
                                                     theCall).take();
          // Cast once more (dereference the cstyle cast)
          Result = m_Sema->BuildUnaryOp(S, m_NoSLoc, UO_Deref, Result).take();
          // 4.
          CuredDecl->setType(m_Context->getLValueReferenceType(CuredDeclTy));
          // 5.
          CuredDecl->setInit(Result);

          NewNode.addNode(Node);

          // Restore Sema's original DeclContext
          m_Sema->CurContext = OldDC;
          return NewNode;
        }
      }
    }
    return ASTNodeInfo(Node, 0);
  }