Exemple #1
0
const NamedDecl &findDecl(ParsedAST &AST, llvm::StringRef QName) {
  llvm::SmallVector<llvm::StringRef, 4> Components;
  QName.split(Components, "::");

  auto &Ctx = AST.getASTContext();
  auto LookupDecl = [&Ctx](const DeclContext &Scope,
                           llvm::StringRef Name) -> const NamedDecl & {
    auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name)));
    assert(!LookupRes.empty() && "Lookup failed");
    assert(LookupRes.size() == 1 && "Lookup returned multiple results");
    return *LookupRes.front();
  };

  const DeclContext *Scope = Ctx.getTranslationUnitDecl();
  for (auto NameIt = Components.begin(), End = Components.end() - 1;
       NameIt != End; ++NameIt) {
    Scope = &cast<DeclContext>(LookupDecl(*Scope, *NameIt));
  }
  return LookupDecl(*Scope, Components.back());
}
Exemple #2
0
  Expr* EvaluateTSynthesizer::BuildDynamicExprInfo(Expr* SubTree,
                                                   bool ValuePrinterReq) {
    // We need to evaluate it in its own context. Evaluation on the global
    // scope per se can break for example the compound literals, which have
    // to be constants (see [C99 6.5.2.5])
    Sema::ContextRAII pushedDC(*m_Sema, m_CurDeclContext);

    // 1. 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();

    // 2. Build the template
    Expr* ExprTemplate = ConstructConstCharPtrExpr(Template.c_str());

    // 3. Build the array of addresses
    QualType VarAddrTy = m_Sema->BuildArrayType(m_Context->VoidPtrTy,
                                                ArrayType::Normal,
                                                /*ArraySize*/0,
                                                /*IndexTypeQuals*/0,
                                                m_NoRange,
                                                DeclarationName() );

    llvm::SmallVector<Expr*, 2> Inits;
    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,
                                              Inits,
                                              m_NoELoc).takeAs<InitListExpr>();
    TypeSourceInfo* TSI 
      = m_Context->getTrivialTypeSourceInfo(VarAddrTy, m_NoSLoc);
    Expr* ExprAddresses = m_Sema->BuildCompoundLiteralExpr(m_NoSLoc,
                                                           TSI,
                                                           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();

    llvm::SmallVector<Expr*, 4> CtorArgs;
    CtorArgs.push_back(ExprTemplate);
    CtorArgs.push_back(ExprAddresses);
    CtorArgs.push_back(VPReq);

    // 4. Call the constructor
    QualType ExprInfoTy = m_Context->getTypeDeclType(m_DynamicExprInfoDecl);
    ExprResult Initializer = m_Sema->ActOnParenListExpr(m_NoSLoc, m_NoELoc,
                                                        CtorArgs);
    TypeSourceInfo* TrivialTSI 
      = m_Context->getTrivialTypeSourceInfo(ExprInfoTy, SourceLocation());
    Expr* Result = m_Sema->BuildCXXNew(m_NoSLoc,
                                       /*UseGlobal=*/false,
                                       m_NoSLoc,
                                       /*PlacementArgs=*/MultiExprArg(),
                                       m_NoELoc,
                                       m_NoRange,
                                       ExprInfoTy,
                                       TrivialTSI,
                                       /*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;
  }
  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;
  }