Example #1
0
    GrammarFunc* Grammar::MakeFunc(const string& FuncName, const vector<GrammarNode*>& Args)
    {
        // extract the types
        const uint32 NumArgs = Args.size();
        vector<const ESFixedTypeBase*> ArgTypes(NumArgs);
        
        for (uint32 i = 0; i < NumArgs; ++i) {
            ArgTypes[i] = Args[i]->GetType();
        }

        auto Op = Solver->LookupOperator(FuncName, ArgTypes);
        if (Op == nullptr) {
            throw TypeException((string)"Could not resolve operator \"" + FuncName + 
                                "\" to anything meaningful.\n" + "This could be due to " + 
                                "mismatched parameters");
        }
        return Get<GrammarFunc>(this, Op, Args);
    }
Example #2
0
    Expression ESolver::CreateExpression(const OperatorBase* OpInfo,
                                         const vector<Expression>& Children)
    {
        Expression NewExp;
        // Type checks
        if (Children.size() > 0) {
            auto FuncOp = OpInfo->As<FuncOperatorBase>();
            const uint32 NumChildren = Children.size();
            vector<const ESFixedTypeBase*> ArgTypes(NumChildren);
            for (uint32 i = 0; i < NumChildren; ++i) {
                ArgTypes[i] = Children[i]->GetType();
            }
            // Quick type check using name mangling
            auto const& ExpectedName = FuncOp->GetMangledName();
            auto const&& ActualName = FuncOperatorBase::MangleName(OpInfo->GetName(), ArgTypes);
            if (ExpectedName != ActualName) {
                throw TypeException((string)"Error in application of function \"" + OpInfo->GetName() + "\".\n" + 
                                    "This could be due to mismatched numbers or types of parameters");
            }
            // We're good. Create the expression
            if (OpInfo->As<InterpretedFuncOperator>() != nullptr) {
                NewExp = new UserInterpretedFuncExpression(OpInfo->As<InterpretedFuncOperator>(),
                                                           Children);
            } else {
                NewExp = new UserSynthFuncExpression(OpInfo->As<SynthFuncOperator>(),
                                                     Children);
            }
        } else {
            
            // This could be a constant, a UQVariable, an aux variable, 
            // a formal param or a let bound variable
            if (OpInfo->As<VarOperatorBase>() != nullptr) {
                if (OpInfo->As<UQVarOperator>() != nullptr) {
                    NewExp = new UserUQVarExpression(OpInfo->As<UQVarOperator>());
                } else if (OpInfo->As<FormalParamOperator>() != nullptr) {
                    NewExp = new UserFormalParamExpression(OpInfo->As<FormalParamOperator>());
                } else if (OpInfo->As<AuxVarOperator>() != nullptr) {
                    NewExp = new UserAuxVarExpression(OpInfo->As<AuxVarOperator>());
                } else if (OpInfo->As<LetBoundVarOperator>() != nullptr) {
                    NewExp = new UserLetBoundVarExpression(OpInfo->As<LetBoundVarOperator>());
                } else {
                    throw InternalError((string)"BUG: Unhandled operator type at " + __FILE__ + ":" + 
                                        to_string(__LINE__));
                }
            } else {
                // This can only be a const operator now
                if (OpInfo->As<ConstOperator>() != nullptr) {
                    NewExp = new UserConstExpression(OpInfo->As<ConstOperator>());
                } else if (OpInfo->As<MacroOperator>() != nullptr) {
                    // OR it can be a constant macro expression
                    NewExp = new UserInterpretedFuncExpression(OpInfo->As<MacroOperator>(), Children);
                } else {
                    throw TypeException((string)"Error: Could not find a meaningful way to construct " +
                                        "an expression with operator having name \"" + OpInfo->GetName() + 
                                        "\".\nPerhaps you provided arguments where none were expected, " + 
                                        "or this could be a bug");
                }
            }
        }

        ExpMgr->GC();
        return ExpMgr->GetExp(NewExp);
    }
Example #3
0
  // Here is the test Eval function specialization. Here the CallExpr to the
  // function is created.
  CallExpr*
  EvaluateTSynthesizer::BuildEvalCallExpr(const QualType InstTy,
                                          Expr* SubTree,
                                        llvm::SmallVector<Expr*, 2>& CallArgs) {
    // Set up new context for the new FunctionDecl
    DeclContext* PrevContext = m_Sema->CurContext;

    m_Sema->CurContext = m_EvalDecl->getDeclContext();

    // Create template arguments
    Sema::InstantiatingTemplate Inst(*m_Sema, m_NoSLoc, m_EvalDecl);
    // Before instantiation we need the canonical type
    TemplateArgument Arg(InstTy.getCanonicalType());
    TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, &Arg, 1U);

    // Substitute the declaration of the templated function, with the
    // specified template argument
    Decl* D = m_Sema->SubstDecl(m_EvalDecl,
                                m_EvalDecl->getDeclContext(),
                                MultiLevelTemplateArgumentList(TemplateArgs));

    FunctionDecl* Fn = dyn_cast<FunctionDecl>(D);

    // We expect incoming declarations (instantiations) and we
    // need to open the transaction to collect them.
    Transaction::State oldState = getTransaction()->getState();
    getTransaction()->setState(Transaction::kCollecting);

    // Creates new body of the substituted declaration
    m_Sema->InstantiateFunctionDefinition(Fn->getLocation(), Fn, true, true);

    m_Sema->CurContext = PrevContext;

    const FunctionProtoType* FPT = Fn->getType()->getAs<FunctionProtoType>();
    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
    llvm::ArrayRef<QualType> ArgTypes(FPT->arg_type_begin(),
                                      FPT->getNumArgs());
    QualType FnTy = m_Context->getFunctionType(Fn->getResultType(),
                                               ArgTypes,
                                               EPI);
    DeclRefExpr* DRE = m_Sema->BuildDeclRefExpr(Fn,
                                                FnTy,
                                                VK_RValue,
                                                m_NoSLoc
                                                ).takeAs<DeclRefExpr>();

    getTransaction()->setState(oldState);

    // TODO: Figure out a way to avoid passing in wrong source locations
    // of the symbol being replaced. This is important when we calculate the
    // size of the memory buffers and may lead to creation of wrong wrappers.
    Scope* S = m_Sema->getScopeForContext(m_Sema->CurContext);
    CallExpr* EvalCall = m_Sema->ActOnCallExpr(S,
                                               DRE,
                                               SubTree->getLocStart(),
                                               CallArgs,
                                               SubTree->getLocEnd()
                                               ).takeAs<CallExpr>();
    assert (EvalCall && "Cannot create call to Eval");

    return EvalCall;

  }