[cfe-dev] ConditionalOperator: rvalue or lvalue?

Konstantin Tokarev annulen at yandex.ru
Tue Aug 20 10:57:54 PDT 2013


Hi all,

In the code fragment [1] ConditionalOperator is lvalue in clang AST, while in code fragments [2] and [3] it is reported as rvalue. The difference is that [2] declares DEFAULT_WEIGHT as enum constant, and [3] declares it as int constant.

Is this behavior correct? Why in [1] ConditionalOperator is not rvalue too?


Code [1]

class A {
  unsigned m_fn1(unsigned x) const;
  static const unsigned DEFAULT_WEIGHT = 1;
};
unsigned A::m_fn1(unsigned x) const {
  unsigned ret = x ? x : DEFAULT_WEIGHT;
  return ret;
}

Code [2]

class A {
  unsigned m_fn1(unsigned x) const;
  enum { DEFAULT_WEIGHT = 1 };
};
unsigned A::m_fn1(unsigned x) const {
  unsigned ret = x ? x : DEFAULT_WEIGHT;
  return ret;
}

Code [3]

class A {
  unsigned m_fn1(unsigned x) const;
  static const signed DEFAULT_WEIGHT = 1;
};
unsigned A::m_fn1(unsigned x) const {
  unsigned ret = x ? x : DEFAULT_WEIGHT;
  return ret;
}


AST dump [1]

TranslationUnitDecl 0x3234cf0 <<invalid sloc>>
|-TypedefDecl 0x3235230 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x3235290 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x3235650 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
|-CXXRecordDecl 0x32356a0 <BranchProbabilityInfo.cpp:1:1, line:4:1> class A
| |-CXXRecordDecl 0x32357b0 <line:1:1, col:7> class A
| |-CXXMethodDecl 0x3235910 <line:2:3, col:30> m_fn1 'unsigned int (unsigned int) const'
| | `-ParmVarDecl 0x3235850 <col:18, col:27> x 'unsigned int'
| `-VarDecl 0x32671d0 <line:3:3, col:42> DEFAULT_WEIGHT 'const unsigned int' static
|   `-ImplicitCastExpr 0x3267248 <col:42> 'const unsigned int' <IntegralCast>
|     `-IntegerLiteral 0x3267228 <col:42> 'int' 1
`-CXXMethodDecl 0x3267370 parent 0x32356a0 prev 0x3235910 <line:5:1, line:8:1> m_fn1 'unsigned int (unsigned int) const'
  |-ParmVarDecl 0x32672f0 <line:5:19, col:28> x 'unsigned int'
  `-CompoundStmt 0x3267648 <col:37, line:8:1>
    |-DeclStmt 0x32675d0 <line:6:3, col:40>
    | `-VarDecl 0x3267470 <col:3, col:26> ret 'unsigned int'
    |   `-ImplicitCastExpr 0x32675b8 <col:18, col:26> 'unsigned int' <LValueToRValue>
    |     `-ConditionalOperator 0x3267588 <col:18, col:26> 'const unsigned int' lvalue
    |       |-ImplicitCastExpr 0x3267558 <col:18> '_Bool' <IntegralToBoolean>
    |       | `-ImplicitCastExpr 0x3267540 <col:18> 'unsigned int' <LValueToRValue>
    |       |   `-DeclRefExpr 0x32674c8 <col:18> 'unsigned int' lvalue ParmVar 0x32672f0 'x' 'unsigned int'
    |       |-ImplicitCastExpr 0x3267570 <col:22> 'const unsigned int' lvalue <NoOp>
    |       | `-DeclRefExpr 0x32674f0 <col:22> 'unsigned int' lvalue ParmVar 0x32672f0 'x' 'unsigned int'
    |       `-DeclRefExpr 0x3267518 <col:26> 'const unsigned int' lvalue Var 0x32671d0 'DEFAULT_WEIGHT' 'const unsigned int'
    `-ReturnStmt 0x3267628 <line:7:3, col:10>
      `-ImplicitCastExpr 0x3267610 <col:10> 'unsigned int' <LValueToRValue>
        `-DeclRefExpr 0x32675e8 <col:10> 'unsigned int' lvalue Var 0x3267470 'ret' 'unsigned int'


AST dump [2]

TranslationUnitDecl 0x1d74cf0 <<invalid sloc>>
|-TypedefDecl 0x1d75230 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x1d75290 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x1d75650 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
|-CXXRecordDecl 0x1d756a0 <BranchProbabilityInfo4.cpp:1:1, line:4:1> class A
| |-CXXRecordDecl 0x1d757b0 <line:1:1, col:7> class A
| |-CXXMethodDecl 0x1d75910 <line:2:3, col:30> m_fn1 'unsigned int (unsigned int) const'
| | `-ParmVarDecl 0x1d75850 <col:18, col:27> x 'unsigned int'
| `-EnumDecl 0x1da71c0 <line:3:3, col:29>
|   `-EnumConstantDecl 0x1da7290 <col:10, col:27> DEFAULT_WEIGHT 'enum A::<anonymous at BranchProbabilityInfo4.cpp:3:3>'
|     `-ImplicitCastExpr 0x1da72e0 <col:27> 'unsigned int' <IntegralCast>
|       `-IntegerLiteral 0x1da7270 <col:27> 'int' 1
`-CXXMethodDecl 0x1da73c0 parent 0x1d756a0 prev 0x1d75910 <line:5:1, line:8:1> m_fn1 'unsigned int (unsigned int) const'
  |-ParmVarDecl 0x1da7340 <line:5:19, col:28> x 'unsigned int'
  `-CompoundStmt 0x1da7698 <col:37, line:8:1>
    |-DeclStmt 0x1da7620 <line:6:3, col:40>
    | `-VarDecl 0x1da74c0 <col:3, col:26> ret 'unsigned int'
    |   `-ConditionalOperator 0x1da75f0 <col:18, col:26> 'unsigned int'
    |     |-ImplicitCastExpr 0x1da75a8 <col:18> '_Bool' <IntegralToBoolean>
    |     | `-ImplicitCastExpr 0x1da7590 <col:18> 'unsigned int' <LValueToRValue>
    |     |   `-DeclRefExpr 0x1da7518 <col:18> 'unsigned int' lvalue ParmVar 0x1da7340 'x' 'unsigned int'
    |     |-ImplicitCastExpr 0x1da75c0 <col:22> 'unsigned int' <LValueToRValue>
    |     | `-DeclRefExpr 0x1da7540 <col:22> 'unsigned int' lvalue ParmVar 0x1da7340 'x' 'unsigned int'
    |     `-ImplicitCastExpr 0x1da75d8 <col:26> 'unsigned int' <IntegralCast>
    |       `-DeclRefExpr 0x1da7568 <col:26> 'enum A::<anonymous at BranchProbabilityInfo4.cpp:3:3>' EnumConstant 0x1da7290 'DEFAULT_WEIGHT' 'enum A::<anonymous at BranchProbabilityInfo4.cpp:3:3>'
    `-ReturnStmt 0x1da7678 <line:7:3, col:10>
      `-ImplicitCastExpr 0x1da7660 <col:10> 'unsigned int' <LValueToRValue>
        `-DeclRefExpr 0x1da7638 <col:10> 'unsigned int' lvalue Var 0x1da74c0 'ret' 'unsigned int'

AST dump [3]

TranslationUnitDecl 0x308acf0 <<invalid sloc>>
|-TypedefDecl 0x308b230 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x308b290 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x308b650 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
|-CXXRecordDecl 0x308b6a0 <BranchProbabilityInfo5.cpp:1:1, line:4:1> class A
| |-CXXRecordDecl 0x308b7b0 <line:1:1, col:7> class A
| |-CXXMethodDecl 0x308b910 <line:2:3, col:30> m_fn1 'unsigned int (unsigned int) const'
| | `-ParmVarDecl 0x308b850 <col:18, col:27> x 'unsigned int'
| `-VarDecl 0x30bd1d0 <line:3:3, col:40> DEFAULT_WEIGHT 'const int' static
|   `-IntegerLiteral 0x30bd228 <col:40> 'int' 1
`-CXXMethodDecl 0x30bd360 parent 0x308b6a0 prev 0x308b910 <line:5:1, line:8:1> m_fn1 'unsigned int (unsigned int) const'
  |-ParmVarDecl 0x30bd2e0 <line:5:19, col:28> x 'unsigned int'
  `-CompoundStmt 0x30bd650 <col:37, line:8:1>
    |-DeclStmt 0x30bd5d8 <line:6:3, col:40>
    | `-VarDecl 0x30bd460 <col:3, col:26> ret 'unsigned int'
    |   `-ConditionalOperator 0x30bd5a8 <col:18, col:26> 'unsigned int'
    |     |-ImplicitCastExpr 0x30bd548 <col:18> '_Bool' <IntegralToBoolean>
    |     | `-ImplicitCastExpr 0x30bd530 <col:18> 'unsigned int' <LValueToRValue>
    |     |   `-DeclRefExpr 0x30bd4b8 <col:18> 'unsigned int' lvalue ParmVar 0x30bd2e0 'x' 'unsigned int'
    |     |-ImplicitCastExpr 0x30bd560 <col:22> 'unsigned int' <LValueToRValue>
    |     | `-DeclRefExpr 0x30bd4e0 <col:22> 'unsigned int' lvalue ParmVar 0x30bd2e0 'x' 'unsigned int'
    |     `-ImplicitCastExpr 0x30bd590 <col:26> 'unsigned int' <IntegralCast>
    |       `-ImplicitCastExpr 0x30bd578 <col:26> 'int' <LValueToRValue>
    |         `-DeclRefExpr 0x30bd508 <col:26> 'const int' lvalue Var 0x30bd1d0 'DEFAULT_WEIGHT' 'const int'
    `-ReturnStmt 0x30bd630 <line:7:3, col:10>
      `-ImplicitCastExpr 0x30bd618 <col:10> 'unsigned int' <LValueToRValue>
        `-DeclRefExpr 0x30bd5f0 <col:10> 'unsigned int' lvalue Var 0x30bd460 'ret' 'unsigned int'

-- 
Regards,
Konstantin



More information about the cfe-dev mailing list