Сравнение значения int с APInt Clang ASTVisitors - PullRequest
0 голосов
/ 01 мая 2020

Я бы хотел сравнить границу ImplicCastExpr в моей проверке ASTvisitor, но, похоже, Clang не позволил бы мне сделать это:

static bool vectorLoopConditionVisitor(Sema &S, Expr *E){

    if(!E){
      S.Diag(E->getBeginLoc(), diag::err_...);
    } else{ 
        const BinaryOperator *BO = dyn_cast<BinaryOperator>(E);
          if(!BO) {
            if(const IntegerLiteral *IL = dyn_cast_or_null<IntegerLiteral>(BO->getRHS()->IgnoreParenImpCasts())) {
              if( IL->getValue() > 65535){
                S.Diag(BO->getOperatorLoc(), diag::err_...);
              }
return false;
}

Это приведет к следующему ошибка, поскольку я пытаюсь сравнить значение int с llvm::APInt:

invalid operands to binary expression ('llvm::APInt' and 'int')

Однако я выполнил аналогичное сравнение без каких-либо проблем в своей другой функции:

static bool vectorLoopInitializationsVisitor(Sema &S, Stmt *St) {


  DeclStmt *Dst = dyn_cast<DeclStmt>(St);


  if (!Dst->isSingleDecl()) {
  ¦ S.Diag(St->getBeginLoc(), diag::err_...);
  }
  VarDecl const *VD = dyn_cast<VarDecl>(Dst->getSingleDecl());

  if(const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(VD->getInit()->IgnoreImpCasts())){
    if (IL->getValue() != 0) {
  ¦   if (IL->getValue() !=
  ¦ ¦   ¦ 12345) { 
  ¦ ¦   S.Diag(St->getBeginLoc(), diag::err_...);
  ¦   }
    }
return false;
}

Проверка обоих типов: llvm::APInt и int. Кто-нибудь может объяснить, почему это так?

Другими словами, что делает CompoundOperator !=, что BinaryOperator > не делает?

1 Ответ

1 голос
/ 01 мая 2020

llvm :: APInt представляет битовый вектор фиксированной ширины. Он не различает guish между значениями со знаком и без знака, поэтому вы не можете просто использовать>,> =, <и <= для сравнения значений, потому что он не знает, хотите ли вы интерпретировать значение APInt как число со знаком или без знака. ! = и == работают, потому что они имеют одинаковую семантику как для знаковых, так и для беззнаковых величин. </p>

Как вы можете видеть здесь , llvm :: APInt обеспечивает отдельные сравнения со знаками и без знака больше чем используя методы sgt и ugt. Эти методы обеспечивают перегрузки, которые принимают значения int64_t и uint64_t соответственно.

Таким образом, правильный код будет: if( IL->getValue().ugt(65535) или if( IL->getValue().sgt(65535)).

...