[cfe-dev] differentiate type T& from type T when exporting AST expressions
Richard Smith via cfe-dev
cfe-dev at lists.llvm.org
Mon Oct 12 13:41:36 PDT 2015
On Mon, Oct 12, 2015 at 3:06 AM, Andrzej Kotulski via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> I’m trying to extract type information from clang::Expr by using getType()
> function. I found that while it almost always gives correct type, but it
> has unexpected behavior when using reference types – it doesn’t keep
> information about reference in a type.
> Is this expected behavior?
>
Yes, expressions never have reference type.
> If so, is there another more reliable source of type information that
> keeps reference types separate?
>
It sounds like you want to know whether the expression is a glvalue or a
prvalue; use Expr::isGLValue for that. You will probably also want to look
at Expr::getObjectKind, which identifies the kinds of lvalues that don't
have pointer-like semantics (for instance, an lvalue referring to a
bit-field).
It makes it hard to know whether given object should be treated as a
> pointer type or not. Some examples where this is causing us troubles:
> 1. Should we treat this object as a pointer or not? Treatment of type `T&`
> is closer to `T*` than to `T` in our use case
> 2. Casts – is it casting variable from Type1 to Type2 OR from Type1& to
> Type2&?
> 3. Virtual function calls - should it use dynamic dispatch, or not?
>
> For example, consider following code:
>
>
> int by_value(int x) {
> x = x + 1;
> return x;
> }
>
> int ref_param(int& x) {
> x = x + 1;
> return x;
> }
>
> int& ref_param_ret(int& x) {
> x = x + 1;
> return x;
> }
>
>
> I attach AST dump below. When you dump AST of code above, it is very
> similar for all functions, expressions basically lose information about
> something being reference type. The only place to see the difference is:
>
> 1. ‘x’ is reference type -> looking at the type of variable in
> DeclRefExpr (but not DeclRefExpr::getType() which doesn’t have reference
> type information)
> 2. Function returns reference type -> looking at function type
> signature.
>
>
> How I read ast-dump output:
> DeclRefExpr 0x103072a98 <col:7> 'int' lvalue ParmVar 0x1030728f0 'x'
> 'int &’
>
> Line above means, that:
>
> 1. This is DeclRefExpr expression
> 2. This expression has type int (DeclRefExpr::getType() == int). <-
> Why isn’t it int& ??
> 3. It’s dereferencing parameter variable `x`
> 4. Variable has type int&
>
>
> -ast-dump output:
>
> TranslationUnitDecl 0x103030cc0 <<invalid sloc>> <invalid sloc>
> |-TypedefDecl 0x103031200 <<invalid sloc>> <invalid sloc> implicit
> __int128_t '__int128'
> |-TypedefDecl 0x103031260 <<invalid sloc>> <invalid sloc> implicit
> __uint128_t 'unsigned __int128'
> |-TypedefDecl 0x103031660 <<invalid sloc>> <invalid sloc> implicit
> __builtin_va_list '__va_list_tag [1]'
> |-FunctionDecl 0x103031780 <smallest2.cpp:1:1, line:4:1> line:1:5 by_value
> 'int (int)'
> | |-ParmVarDecl 0x1030316c0 <col:14, col:18> col:18 used x 'int'
> | `-CompoundStmt 0x103031968 <col:21, line:4:1>
> | |-BinaryOperator 0x1030318e0 <line:2:3, col:11> 'int' lvalue '='
> | | |-DeclRefExpr 0x103031830 <col:3> 'int' lvalue ParmVar 0x1030316c0
> 'x' 'int'
> | | `-BinaryOperator 0x1030318b8 <col:7, col:11> 'int' '+'
> | | |-ImplicitCastExpr 0x1030318a0 <col:7> 'int' <LValueToRValue>
> | | | `-DeclRefExpr 0x103031858 <col:7> 'int' lvalue ParmVar
> 0x1030316c0 'x' 'int'
> | | `-IntegerLiteral 0x103031880 <col:11> 'int' 1
> | `-ReturnStmt 0x103031948 <line:3:3, col:10>
> | `-ImplicitCastExpr 0x103031930 <col:10> 'int' <LValueToRValue>
> | `-DeclRefExpr 0x103031908 <col:10> 'int' lvalue ParmVar
> 0x1030316c0 'x' 'int'
> |-FunctionDecl 0x1030726c0 <line:6:1, line:9:1> line:6:5 ref_param 'int
> (int &)'
> | |-ParmVarDecl 0x103072600 <col:15, col:20> col:20 used x 'int &'
> | `-CompoundStmt 0x1030728a8 <col:23, line:9:1>
> | |-BinaryOperator 0x103072820 <line:7:3, col:11> 'int' lvalue '='
> | | |-DeclRefExpr 0x103072770 <col:3> 'int' lvalue ParmVar 0x103072600
> 'x' 'int &'
> | | `-BinaryOperator 0x1030727f8 <col:7, col:11> 'int' '+'
> | | |-ImplicitCastExpr 0x1030727e0 <col:7> 'int' <LValueToRValue>
> | | | `-DeclRefExpr 0x103072798 <col:7> 'int' lvalue ParmVar
> 0x103072600 'x' 'int &'
> | | `-IntegerLiteral 0x1030727c0 <col:11> 'int' 1
> | `-ReturnStmt 0x103072888 <line:8:3, col:10>
> | `-ImplicitCastExpr 0x103072870 <col:10> 'int' <LValueToRValue>
> | `-DeclRefExpr 0x103072848 <col:10> 'int' lvalue ParmVar
> 0x103072600 'x' 'int &'
> `-FunctionDecl 0x1030729c0 <line:11:1, line:14:1> line:11:6 ref_param_ret
> 'int &(int &)'
> |-ParmVarDecl 0x1030728f0 <col:20, col:25> col:25 used x 'int &'
> `-CompoundStmt 0x103072b90 <col:28, line:14:1>
> |-BinaryOperator 0x103072b20 <line:12:3, col:11> 'int' lvalue '='
> | |-DeclRefExpr 0x103072a70 <col:3> 'int' lvalue ParmVar 0x1030728f0
> 'x' 'int &'
> | `-BinaryOperator 0x103072af8 <col:7, col:11> 'int' '+'
> | |-ImplicitCastExpr 0x103072ae0 <col:7> 'int' <LValueToRValue>
> | | `-DeclRefExpr 0x103072a98 <col:7> 'int' lvalue ParmVar
> 0x1030728f0 'x' 'int &'
> | `-IntegerLiteral 0x103072ac0 <col:11> 'int' 1
> `-ReturnStmt 0x103072b70 <line:13:3, col:10>
> `-DeclRefExpr 0x103072b48 <col:10> 'int' lvalue ParmVar 0x1030728f0
> 'x' 'int &'
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20151012/16e41eaf/attachment.html>
More information about the cfe-dev
mailing list