Bug 472436 - Track whether an EvalID involves a pointer dereference
authorNathan Ridge <zeratul976@hotmail.com>
Mon, 13 Jul 2015 03:21:42 +0000 (23:21 -0400)
committerSergey Prigogin <eclipse.sprigogin@gmail.com>
Mon, 13 Jul 2015 19:41:22 +0000 (15:41 -0400)
Change-Id: If09ff059180bd7bdc50a73d13377838a24ed121f
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java

index 383cc4d..42f4469 100644 (file)
@@ -8008,11 +8008,30 @@ public class AST2TemplateTests extends AST2TestBase {
        //              S s;
        //              auto waldo = bar(&s);
        //      }
-       public void testDependentFieldReference_472436() throws Exception {
+       public void testDependentFieldReference_472436a() throws Exception {
                BindingAssertionHelper helper = getAssertionHelper();
                helper.assertVariableType("waldo", CommonCPPTypes.int_);        
        }
     
+       //      struct T {
+       //              int foo;
+       //      };
+       //      struct S {
+       //              T* other;
+       //      };
+       //
+       //      template <typename T>
+       //      auto bar(T t) -> decltype(t->other->foo);
+       //      
+       //      int main() {
+       //              S s;
+       //              auto waldo = bar(&s);
+       //      }
+       public void testDependentFieldReference_472436b() throws Exception {
+               BindingAssertionHelper helper = getAssertionHelper();
+               helper.assertVariableType("waldo", CommonCPPTypes.int_);        
+       }
+       
        //      template <typename>
        //      struct Bind {};
        //      template <typename Func, typename ... BoundArgs>
index aca4eab..8701c17 100644 (file)
@@ -301,7 +301,7 @@ public class CPPASTFieldReference extends ASTNode
                                return EvalFixed.INCOMPLETE;
                        }
                }               
-               return new EvalID(ownerEval, qualifier, fName.getSimpleID(), false, true, args, this);
+               return new EvalID(ownerEval, qualifier, fName.getSimpleID(), false, true, fIsDeref, args, this);
        }
 
        @Override
index e89cdf1..bcb2f42 100644 (file)
@@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
 import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.core.dom.ast.IEnumerator;
 import org.eclipse.cdt.core.dom.ast.IFunction;
+import org.eclipse.cdt.core.dom.ast.IPointerType;
 import org.eclipse.cdt.core.dom.ast.IProblemBinding;
 import org.eclipse.cdt.core.dom.ast.IScope;
 import org.eclipse.cdt.core.dom.ast.IType;
@@ -64,15 +65,19 @@ public class EvalID extends CPPDependentEvaluation {
        private final IBinding fNameOwner;
        private final boolean fAddressOf;
        private final boolean fQualified;
+       private final boolean fIsPointerDeref;
        private final ICPPTemplateArgument[] fTemplateArgs;
 
        public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf,
-                       boolean qualified, ICPPTemplateArgument[] templateArgs, IASTNode pointOfDefinition) {
-               this(fieldOwner, nameOwner, simpleID, addressOf, qualified, templateArgs, findEnclosingTemplate(pointOfDefinition));
+                       boolean qualified, boolean isPointerDeref, ICPPTemplateArgument[] templateArgs, 
+                       IASTNode pointOfDefinition) {
+               this(fieldOwner, nameOwner, simpleID, addressOf, qualified, isPointerDeref, templateArgs, 
+                               findEnclosingTemplate(pointOfDefinition));
        }
 
        public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf,
-                       boolean qualified, ICPPTemplateArgument[] templateArgs, IBinding templateDefinition) {
+                       boolean qualified, boolean isPointerDeref, ICPPTemplateArgument[] templateArgs, 
+                       IBinding templateDefinition) {
                super(templateDefinition);
                if (simpleID == null)
                        throw new NullPointerException("simpleID"); //$NON-NLS-1$
@@ -81,6 +86,7 @@ public class EvalID extends CPPDependentEvaluation {
                fNameOwner= nameOwner;
                fAddressOf= addressOf;
                fQualified= qualified;
+               fIsPointerDeref= isPointerDeref;
                fTemplateArgs= templateArgs;
        }
 
@@ -106,6 +112,10 @@ public class EvalID extends CPPDependentEvaluation {
        public boolean isQualified() {
                return fQualified;
        }
+       
+       public boolean isPointerDeref() {
+               return fIsPointerDeref;
+       }
 
        /**
         * Returns the template arguments, or {@code null} if there are no template arguments.
@@ -164,6 +174,8 @@ public class EvalID extends CPPDependentEvaluation {
                        firstBytes |= ITypeMarshalBuffer.FLAG2;
                if (fTemplateArgs != null)
                        firstBytes |= ITypeMarshalBuffer.FLAG3;
+               if (fIsPointerDeref)
+                       firstBytes |= ITypeMarshalBuffer.FLAG4;
 
                buffer.putShort(firstBytes);
                buffer.marshalEvaluation(fFieldOwner, false);
@@ -181,6 +193,7 @@ public class EvalID extends CPPDependentEvaluation {
        public static ISerializableEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
                final boolean addressOf= (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
                final boolean qualified= (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
+               final boolean isPointerDeref= (firstBytes & ITypeMarshalBuffer.FLAG4) != 0;
                ICPPEvaluation fieldOwner= (ICPPEvaluation) buffer.unmarshalEvaluation();
                char[] name= buffer.getCharArray();
                IBinding nameOwner= buffer.unmarshalBinding();
@@ -193,7 +206,8 @@ public class EvalID extends CPPDependentEvaluation {
                        }
                }
                IBinding templateDefinition= buffer.unmarshalBinding();
-               return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args, templateDefinition);
+               return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, isPointerDeref, args, 
+                               templateDefinition);
        }
 
        public static ICPPEvaluation create(IASTIdExpression expr) {
@@ -238,7 +252,7 @@ public class EvalID extends CPPDependentEvaluation {
                        }
 
                        return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
-                                       name instanceof ICPPASTQualifiedName, templateArgs, expr);
+                                       name instanceof ICPPASTQualifiedName, false, templateArgs, expr);
                }
                /**
                 * 9.3.1-3 Transformation to class member access within a non-static member function.
@@ -357,6 +371,14 @@ public class EvalID extends CPPDependentEvaluation {
                
                if (fieldOwner != null && !fieldOwner.isTypeDependent()) {
                        IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point);
+                       if (fIsPointerDeref) {
+                               fieldOwnerType = SemanticUtil.getSimplifiedType(fieldOwnerType);
+                               if (fieldOwnerType instanceof IPointerType) {
+                                       fieldOwnerType = ((IPointerType) fieldOwnerType).getType();
+                               } else {
+                                       return EvalFixed.INCOMPLETE;
+                               }
+                       }
                        IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
                        IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
                        if (fieldOwnerClassType instanceof ICPPClassType) {
@@ -366,7 +388,8 @@ public class EvalID extends CPPDependentEvaluation {
                        }
                }
 
-               return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs, getTemplateDefinition());
+               return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, fIsPointerDeref, templateArgs, 
+                               getTemplateDefinition());
        }
 
        @Override
@@ -377,7 +400,8 @@ public class EvalID extends CPPDependentEvaluation {
                ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, context.recordStep());
                if (fieldOwner == fFieldOwner)
                        return this;
-               return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs, getTemplateDefinition());
+               return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fIsPointerDeref, 
+                               fTemplateArgs, getTemplateDefinition());
        }
 
        private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs,
index 6c1ac68..d5a39a0 100644 (file)
@@ -399,7 +399,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
                        ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c);
                        
                        if (a != a2 || b != b2 || c != c2 || templateDefinition != compositeTemplateDefinition)
-                               e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), c2, compositeTemplateDefinition);
+                               e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), e.isPointerDeref(), c2, 
+                                               compositeTemplateDefinition);
                        return e;
                }
                if (eval instanceof EvalInitList) {
index 9d4b757..4ee4af7 100644 (file)
@@ -265,10 +265,11 @@ public class PDOM extends PlatformObject implements IPDOM {
         *  
         *  CDT 8.8 development (versions not supported on the 8.7.x branch)
         *  190.0 - Signature change for methods with ref-qualifiers, bug 470014.
+        *  191.0 - Added EvalID.fIsPointerDeref, bug 472436.
         */
-       private static final int MIN_SUPPORTED_VERSION= version(190, 0);
-       private static final int MAX_SUPPORTED_VERSION= version(190, Short.MAX_VALUE);
-       private static final int DEFAULT_VERSION = version(190, 0);
+       private static final int MIN_SUPPORTED_VERSION= version(191, 0);
+       private static final int MAX_SUPPORTED_VERSION= version(191, Short.MAX_VALUE);
+       private static final int DEFAULT_VERSION = version(191, 0);
 
        private static int version(int major, int minor) {
                return (major << 16) + minor;