diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index ed3edc18d69..8f172f0f911 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -514,9 +514,13 @@ public class AST2BaseTest extends BaseTestCase { protected boolean isCPP; public BindingAssertionHelper(String contents, boolean isCPP) throws ParserException { + this(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C); + } + + public BindingAssertionHelper(String contents, ParserLanguage lang) throws ParserException { this.contents= contents; - this.isCPP= isCPP; - this.tu= parse(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C, true, false); + this.isCPP= lang.isCPP(); + this.tu= parse(contents, lang, true, false); } public IASTTranslationUnit getTranslationUnit() { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index a2773522dc5..9f663484c0d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -4706,8 +4706,9 @@ public class AST2CPPTests extends AST2BaseTest { } // template - // class basic_string { + // struct basic_string { // basic_string& operator+=(const T* s); + // basic_string& append(const T* s); // }; // // template @@ -4721,8 +4722,9 @@ public class AST2CPPTests extends AST2BaseTest { // void test(const string& s) { // auto s1 = "" + s + ""; // auto s2 = s1 += ""; + // auto s3 = s2.append("foo"); // } - public void testTypedefPreservation_380498() throws Exception { + public void testTypedefPreservation_380498_1() throws Exception { BindingAssertionHelper ba= getAssertionHelper(); ICPPVariable s1 = ba.assertNonProblem("s1", ICPPVariable.class); assertTrue(s1.getType() instanceof ITypedef); @@ -4730,6 +4732,25 @@ public class AST2CPPTests extends AST2BaseTest { ICPPVariable s2 = ba.assertNonProblem("s2", ICPPVariable.class); assertTrue(s2.getType() instanceof ITypedef); assertEquals("string", ((ITypedef) s2.getType()).getName()); + ICPPVariable s3 = ba.assertNonProblem("s3", ICPPVariable.class); + assertTrue(s3.getType() instanceof ITypedef); + assertEquals("string", ((ITypedef) s3.getType()).getName()); + } + + // template + // struct vector { + // typedef T* const_iterator; + // const_iterator begin() const; + // }; + // + // void test(const vector& v) { + // auto it = v.begin(); + // } + public void testTypedefPreservation_380498_2() throws Exception { + BindingAssertionHelper ba= getAssertionHelper(); + ICPPVariable it = ba.assertNonProblem("it =", "it", ICPPVariable.class); + assertTrue(it.getType() instanceof ITypedef); + assertEquals("vector::const_iterator", ASTTypeUtil.getType(it.getType(), false)); } // int f() { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index c4569410688..d6fb38c2367 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -125,7 +125,7 @@ import org.eclipse.cdt.internal.core.model.ASTStringUtil; import org.eclipse.cdt.internal.core.parser.ParserException; /** - * Testcases on the AST. + * Test cases on the AST. */ public class AST2Tests extends AST2BaseTest { private static final int NUM_TESTS = 3; @@ -4866,10 +4866,9 @@ public class AST2Tests extends AST2BaseTest { // myUnionPointer->bar=4; // } public void testBug228504_nonExistingMembers() throws Exception { - boolean[] isCpps= {true, false}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp); - for (int i=1; i < 5; i++) { + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), lang); + for (int i= 1; i < 5; i++) { ba.assertNonProblem("foo=" + i, 3); ba.assertProblem("bar=" + i, 3); } @@ -4912,10 +4911,9 @@ public class AST2Tests extends AST2BaseTest { // function1(); // ref // } public void testOutOfOrderResolution_Bug232300() throws Exception { - final boolean[] isCpps= {false, true}; String code= getAboveComment(); - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(code, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); IBinding b1= ba.assertNonProblem("function1(); // decl", 9); IBinding b2= ba.assertNonProblem("function1() {", 9); IBinding b3= ba.assertNonProblem("function1(); // ref", 9); @@ -4927,10 +4925,9 @@ public class AST2Tests extends AST2BaseTest { // #define foo __typeof__((int*)0 - (int*)0) // typedef foo ptrdiff_t; public void testRedefinePtrdiff_Bug230895() throws Exception { - final boolean[] isCpps= {false, true}; String code= getAboveComment(); - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(code, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); IBinding b1= ba.assertNonProblem("ptrdiff_t", 9); assertInstance(b1, ITypedef.class); ITypedef td= (ITypedef) b1; @@ -4944,10 +4941,9 @@ public class AST2Tests extends AST2BaseTest { // struct S; // typedef struct S S; // td public void testRedefineStructInScopeThatIsFullyResolved() throws Exception { - final boolean[] isCpps= {false, true}; String code= getAboveComment(); - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(code, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); ba.assertNonProblem("a; // ref", 1); // now scope is fully resolved ICompositeType ct= ba.assertNonProblem("S;", 1, ICompositeType.class); @@ -4972,10 +4968,9 @@ public class AST2Tests extends AST2BaseTest { // VOID func(VOID) { // } public void testTypedefVoid_Bug221567() throws Exception { - final boolean[] isCpps= { false, true }; String code= getAboveComment(); - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(code, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); ITypedef td= ba.assertNonProblem("VOID;", 4, ITypedef.class); IBinding ref= ba.assertNonProblem("VOID)", 4); assertSame(td, ref); @@ -5021,9 +5016,8 @@ public class AST2Tests extends AST2BaseTest { // int f5(int *(tint[10])); public void testParamWithFunctionType_Bug84242() throws Exception { final String comment= getAboveComment(); - final boolean[] isCpps= {false, true}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(comment, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang); IFunction f= ba.assertNonProblem("f1", 2, IFunction.class); isTypeEqual(f.getType(), "int (int (*)(int))"); @@ -5055,9 +5049,8 @@ public class AST2Tests extends AST2BaseTest { // int (*f1 (int par))[5]; public void testFunctionReturningPtrToArray_Bug216609() throws Exception { final String comment= getAboveComment(); - final boolean[] isCpps= {false, true}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), lang); IFunction f= ba.assertNonProblem("f1", 2, IFunction.class); isTypeEqual(f.getType(), "int (* (int))[5]"); @@ -5077,7 +5070,6 @@ public class AST2Tests extends AST2BaseTest { // void ((f4)()); public void testNestedFunctionDeclarators() throws Exception { final String comment= getAboveComment(); - final boolean[] isCpps= {false, true}; for (ParserLanguage lang: ParserLanguage.values()) { IASTTranslationUnit tu= parseAndCheckBindings(comment, lang); IASTFunctionDefinition fdef= getDeclaration(tu, 0); @@ -5133,8 +5125,8 @@ public class AST2Tests extends AST2BaseTest { public void testLocalVariableResolution_Bug235831() throws Exception { final String comment= getAboveComment(); final boolean[] isCpps= {false, true}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(comment, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang); ba.assertNonProblem("b; a", 1, IVariable.class); // fill cache of inner block IVariable v3= ba.assertNonProblem("a; }", 1, IVariable.class); @@ -5148,9 +5140,8 @@ public class AST2Tests extends AST2BaseTest { // int foo(int (*ptr) (int, int)); public void testComplexParameterBinding_Bug214482() throws Exception { final String comment= getAboveComment(); - final boolean[] isCpps= {false, true}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(comment, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang); IParameter p= ba.assertNonProblem("ptr", 3, IParameter.class); assertEquals("ptr", p.getName()); } @@ -5519,8 +5510,8 @@ public class AST2Tests extends AST2BaseTest { // } public void testAnonymousUnionMember() throws Exception { final boolean[] isCpps= {false, true}; - for (boolean isCpp : isCpps) { - BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), lang); bh.assertNonProblem("a1=", 2); bh.assertProblem("a2=", 2); bh.assertNonProblem("a3=", 2); @@ -5794,9 +5785,8 @@ public class AST2Tests extends AST2BaseTest { // enum X {e0, e4=4, e5, e2=2, e3}; public void testValues() throws Exception { final String code= getAboveComment(); - boolean isCpp= false; - do { - BindingAssertionHelper bh= new BindingAssertionHelper(code, false); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper bh= new BindingAssertionHelper(code, lang); IVariable v= (IVariable) bh.assertNonProblem("a=", 1); checkValue(v.getInitialValue(), -4); v= (IVariable) bh.assertNonProblem("b=", 1); @@ -5814,8 +5804,7 @@ public class AST2Tests extends AST2BaseTest { checkValue(e.getValue(), 4); e= (IEnumerator) bh.assertNonProblem("e5", 2); checkValue(e.getValue(), 5); - isCpp= !isCpp; - } while (isCpp); + } } private void checkValue(IValue initialValue, int i) { @@ -6088,11 +6077,10 @@ public class AST2Tests extends AST2BaseTest { // size_t x = a + 5; // size_t y = 2 + a; // size_t y = a * 2; - public void testTypeOfExpressionWithTypedef_380498() throws Exception { - final boolean[] isCpps= { false, true }; + public void testTypeOfExpressionWithTypedef_380498_1() throws Exception { String code= getAboveComment(); - for (boolean isCpp : isCpps) { - BindingAssertionHelper ba= new BindingAssertionHelper(code, isCpp); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); IASTExpression exp = ba.assertNode("a + 5", IASTExpression.class); assertTrue(exp.getExpressionType() instanceof ITypedef); assertEquals("size_t", ((ITypedef) exp.getExpressionType()).getName()); @@ -6105,6 +6093,21 @@ public class AST2Tests extends AST2BaseTest { } } + // typedef void* VoidPtr; + // typedef VoidPtr (*Func)(); + // + // void test(Func f) { + // f(); + // } + public void testTypeOfExpressionWithTypedef_380498_2() throws Exception { + String code= getAboveComment(); + for (ParserLanguage lang: ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang); + IASTExpression exp = ba.assertNode("f()", IASTExpression.class); + assertTrue(exp.getExpressionType() instanceof ITypedef); + assertEquals("VoidPtr", ((ITypedef) exp.getExpressionType()).getName()); + } + } // typedef int TInt; // int a= TInt; //ref public void testTypeAsExpressionIsProblem_261175() throws Exception { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index ee0d6e2fb11..ac2826999fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 IBM Corporation and others. + * Copyright (c) 2005, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Rational Software - initial implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -350,7 +351,8 @@ public class ASTTypeUtil { result.append(Keywords.ENUM); result.append(SPACE); } - appendCppName((ICPPBinding) type, normalize, normalize, result); + boolean qualify = normalize || (type instanceof ITypedef && type instanceof ICPPSpecialization); + appendCppName((ICPPBinding) type, normalize, qualify, result); } else if (type instanceof ICompositeType) { // 101114 fix, do not display class, and for consistency don't display struct/union as well appendNameCheckAnonymous((ICompositeType) type, result); @@ -469,13 +471,13 @@ public class ASTTypeUtil { public static void appendType(IType type, boolean normalize, StringBuilder result) { IType[] types = new IType[DEAULT_ITYPE_SIZE]; - // push all of the types onto the stack + // Push all of the types onto the stack int i = 0; IQualifierType cvq= null; ICPPReferenceType ref= null; while (type != null && ++i < 100) { if (type instanceof ITypedef) { - if (normalize || type instanceof ICPPSpecialization) { + if (normalize) { // Skip the typedef and proceed with its target type. } else { // Output reference, qualifier and typedef, then stop. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserLanguage.java index 496a88c1381..853ba5b7a34 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ParserLanguage.java @@ -9,14 +9,12 @@ * IBM Corp. - Rational Software - initial implementation * Mike Kucera (IBM) - convert to Java 5 enum *******************************************************************************/ - package org.eclipse.cdt.core.parser; /** * Enumeration of base languages supported by CDT. */ public enum ParserLanguage { - C { @Override public boolean isCPP() { return false; } @Override public String toString() { return "C"; } //$NON-NLS-1$ @@ -28,5 +26,4 @@ public enum ParserLanguage { }; public abstract boolean isCPP(); - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java index 70e5fe1dcbd..4257afabbbf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; @@ -17,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** * Arithmetic conversions as required to compute the type of unary or binary expressions. @@ -47,6 +50,8 @@ public abstract class ArithmeticConversion { * or 5.0.9 of C++ standard */ public final IType convertOperandTypes(int operator, IType op1, IType op2) { + op1 = SemanticUtil.getNestedType(op1, TDEF); + op2 = SemanticUtil.getNestedType(op2, TDEF); if (!isArithmeticOrUnscopedEnum(op1) || !isArithmeticOrUnscopedEnum(op2)) { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java index ad9a34be1b3..2bb764401ea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java @@ -6,9 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * John Camelon (IBM Rational Software) - Initial API and implementation - * Yuan Zhang / Beth Tibbitts (IBM Research) - * Markus Schorn (Wind River Systems) + * John Camelon (IBM Rational Software) - Initial API and implementation + * Yuan Zhang / Beth Tibbitts (IBM Research) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -29,9 +29,8 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType; /** * Function call expression in C. */ -public class CASTFunctionCallExpression extends ASTNode implements - IASTFunctionCallExpression, IASTAmbiguityParent { - +public class CASTFunctionCallExpression extends ASTNode + implements IASTFunctionCallExpression, IASTAmbiguityParent { private IASTExpression functionName; private IASTInitializerClause[] fArguments; @@ -62,11 +61,7 @@ public class CASTFunctionCallExpression extends ASTNode implements CASTFunctionCallExpression copy = new CASTFunctionCallExpression(null, args); copy.setFunctionNameExpression(functionName == null ? null : functionName.copy(style)); - copy.setOffsetAndLength(this); - if (style == CopyStyle.withLocations) { - copy.setCopyLocation(this); - } - return copy; + return copy(copy, style); } @Override @@ -104,12 +99,12 @@ public class CASTFunctionCallExpression extends ASTNode implements } @Override - public boolean accept( ASTVisitor action ){ - if( action.shouldVisitExpressions ){ - switch( action.visit( this ) ){ - case ASTVisitor.PROCESS_ABORT : return false; - case ASTVisitor.PROCESS_SKIP : return true; - default : break; + public boolean accept(ASTVisitor action) { + if (action.shouldVisitExpressions) { + switch (action.visit(this)) { + case ASTVisitor.PROCESS_ABORT: return false; + case ASTVisitor.PROCESS_SKIP: return true; + default: break; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java index 5af070c5710..06f7f315aab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -203,7 +203,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode return ExpressionTypes.typeFromFunctionCall(op); } IType t1 = getArrayExpression().getExpressionType(); - t1= Conversions.lvalue_to_rvalue(t1); + t1= Conversions.lvalue_to_rvalue(t1, true); if (t1 instanceof IPointerType) { t1= ((IPointerType) t1).getType(); return glvalueType(t1); @@ -212,7 +212,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode IType t2= null; IASTInitializerClause arg = getArgument(); if (arg instanceof IASTExpression) { - t2= Conversions.lvalue_to_rvalue(t2); + t2= Conversions.lvalue_to_rvalue(t2, true); if (t2 instanceof IPointerType) { t2= ((IPointerType) t2).getType(); return glvalueType(t2); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index a6a29f4401c..a1b8bf66f81 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -20,6 +20,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionT import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.restoreTypedefs; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; @@ -41,6 +42,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent { private int op; @@ -356,20 +358,20 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr return CPPBasicType.BOOLEAN; case IASTBinaryExpression.op_plus: - if (type1 instanceof IPointerType) { - return restoreTypedefs(type1, originalType1); + if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) { + return type1; } - if (type2 instanceof IPointerType) { - return restoreTypedefs(type2, originalType2); + if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) { + return type2; } break; case IASTBinaryExpression.op_minus: - if (type1 instanceof IPointerType) { - if (type2 instanceof IPointerType) { + if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) { + if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) { return CPPVisitor.getPointerDiffType(this); } - return restoreTypedefs(type1, originalType1); + return type1; } break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index 4a04e12b956..826740ad2f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -222,9 +222,9 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio // Void types: Either both are void or one is a throw expression. if (void2 || void3) { if (isThrowExpression(expr2)) { - fType= Conversions.lvalue_to_rvalue(t3); + fType= Conversions.lvalue_to_rvalue(t3, false); } else if (isThrowExpression(expr3)) { - fType= Conversions.lvalue_to_rvalue(t2); + fType= Conversions.lvalue_to_rvalue(t2, false); } else if (void2 && void3) { fType= uqt2; } else { @@ -293,8 +293,8 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio } // 5.16-6 - t2= Conversions.lvalue_to_rvalue(t2); - t3= Conversions.lvalue_to_rvalue(t3); + t2= Conversions.lvalue_to_rvalue(t2, false); + t3= Conversions.lvalue_to_rvalue(t3, false); if (t2.isSameType(t3)) { fType= t2; } else { @@ -353,7 +353,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio } // Unrelated class types or just one class: if (vcat2 != PRVALUE) { - t2= Conversions.lvalue_to_rvalue(t2); + t2= Conversions.lvalue_to_rvalue(t2, false); } Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY); if (c.converts()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 42df2fd5c8d..f730dec616b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -17,6 +17,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; @@ -386,7 +387,7 @@ public class CPPASTFieldReference extends ASTNode type= SemanticUtil.mapToAST(type, owner); } - IType prValue= prvalueType(type); + IType prValue= prvalueTypeWithResolvedTypedefs(type); if (prValue instanceof IPointerType) { return glvalueType(((IPointerType) prValue).getType()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index e80a54287ac..f2433143b2c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -17,6 +17,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; @@ -254,7 +255,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres if (op == op_star) { IType type= operand.getExpressionType(); - type = prvalueType(type); + type = prvalueTypeWithResolvedTypedefs(type); if (type instanceof IPointerType) { type= ((ITypeContainer) type).getType(); return glvalueType(type); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index 5b544f74265..5f3e0c7c93d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -152,7 +152,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP IASTExpression expr= rtstmt.getReturnValue(); if (expr != null) { IType type= expr.getExpressionType(); - type= Conversions.lvalue_to_rvalue(type); + type= Conversions.lvalue_to_rvalue(type, false); if (type != null) { return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 169c315b3f7..ccbff2cd8ca 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -253,14 +253,19 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt @Override public ICPPFunctionType getType() { if (type == null) { - final IType t = getNestedType(CPPVisitor.createType((definition != null) ? definition : declarations[0]), TDEF); + IType t = CPPVisitor.createType((definition != null) ? definition : declarations[0]); if (t instanceof ICPPFunctionType) { type = (ICPPFunctionType) t; - } else if (t instanceof ISemanticProblem){ - type= new ProblemFunctionType(((ISemanticProblem) t).getID()); } else { - // This case is unexpected - type = new ProblemFunctionType(ISemanticProblem.TYPE_UNRESOLVED_NAME); + t = getNestedType(t, TDEF); + if (t instanceof ICPPFunctionType) { + type = (ICPPFunctionType) t; + } else if (t instanceof ISemanticProblem){ + type= new ProblemFunctionType(((ISemanticProblem) t).getID()); + } else { + // This case is unexpected + type = new ProblemFunctionType(ISemanticProblem.TYPE_UNRESOLVED_NAME); + } } } return type; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 6ae940c814c..c94bc69312f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -1155,7 +1155,7 @@ public class Conversions { /** * 4.1, 4.2, 4.3 */ - public static IType lvalue_to_rvalue(IType type) { + public static IType lvalue_to_rvalue(IType type, boolean resolveTypedefs) { IType t= SemanticUtil.getNestedType(type, TDEF | REF); if (t instanceof IArrayType) { return new CPPPointerType(((IArrayType) t).getType()); @@ -1165,9 +1165,9 @@ public class Conversions { } IType uqType= SemanticUtil.getNestedType(t, TDEF | REF | ALLCVQ); if (uqType instanceof ICPPClassType) { - return SemanticUtil.getNestedType(type, COND_TDEF | REF); + return resolveTypedefs ? t : SemanticUtil.getNestedType(type, COND_TDEF | REF); } - return SemanticUtil.getNestedType(t, COND_TDEF | REF | ALLCVQ); + return resolveTypedefs ? uqType : SemanticUtil.getNestedType(type, COND_TDEF | REF | ALLCVQ); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java index 0f4be05ea7f..56480dbc3aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -39,7 +39,11 @@ public class ExpressionTypes { } public static IType prvalueType(IType type) { - return Conversions.lvalue_to_rvalue(type); + return Conversions.lvalue_to_rvalue(type, false); + } + + public static IType prvalueTypeWithResolvedTypedefs(IType type) { + return Conversions.lvalue_to_rvalue(type, true); } public static ValueCategory valueCategoryFromFunctionCall(ICPPFunction function) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index fea27bfaa2e..16b4c891625 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -235,7 +235,7 @@ public class SemanticUtil { final boolean ptr= (options & PTR) != 0; final boolean mptr= (options & MPTR) != 0; final boolean allcvq= (options & ALLCVQ) != 0; - final boolean cvtype = (options & CVTYPE) != 0; + final boolean cvtype= (options & CVTYPE) != 0; IType beforeTypedefs = null; @@ -249,10 +249,10 @@ public class SemanticUtil { t= ((ITypedef) type).getType(); } } else if (type instanceof IPointerType) { - beforeTypedefs = null; final boolean isMbrPtr = type instanceof ICPPPointerToMemberType; if ((ptr && !isMbrPtr) || (mptr && isMbrPtr)) { t= ((IPointerType) type).getType(); + beforeTypedefs = null; } else if (allcvq) { IPointerType pt= (IPointerType) type; if (pt.isConst() || pt.isVolatile() || pt.isRestrict()) { @@ -263,14 +263,13 @@ public class SemanticUtil { return new CPPPointerType(pt.getType(), false, false, false); } } - return pt; } } else if (type instanceof IQualifierType) { - beforeTypedefs = null; final IQualifierType qt = (IQualifierType) type; final IType qttgt = qt.getType(); if (allcvq || cvtype) { t= qttgt; + beforeTypedefs = null; } else if (tdef || cond_tdef) { t= getNestedType(qttgt, options); if (t == qttgt) @@ -278,10 +277,10 @@ public class SemanticUtil { return addQualifiers(t, qt.isConst(), qt.isVolatile(), false); } } else if (type instanceof IArrayType) { - beforeTypedefs = null; final IArrayType atype= (IArrayType) type; if ((options & ARRAY) != 0) { t= atype.getType(); + beforeTypedefs = null; } else if (allcvq) { IType nested= atype.getType(); IType newNested= getNestedType(nested, ALLCVQ); @@ -290,10 +289,10 @@ public class SemanticUtil { return replaceNestedType((ITypeContainer) atype, newNested); } } else if (type instanceof ICPPReferenceType) { - beforeTypedefs = null; final ICPPReferenceType rt = (ICPPReferenceType) type; if ((options & REF) != 0) { t= rt.getType(); + beforeTypedefs = null; } else if (tdef) { // A typedef within the reference type can influence whether the reference is lvalue or rvalue IType nested= rt.getType(); @@ -404,9 +403,20 @@ public class SemanticUtil { typedefType = getNestedType(typedefType, REF | ALLCVQ | PTR | ARRAY); if (!(typedefType instanceof ITypedef)) return null; - IType nestedType = getNestedType(type, REF | ALLCVQ | PTR | ARRAY); - if (!nestedType.isSameType(((ITypedef) typedefType).getType())) - return null; + IType nestedType = type; + while (!nestedType.isSameType(((ITypedef) typedefType).getType())) { + if (nestedType instanceof IQualifierType) { + nestedType = ((IQualifierType) nestedType).getType(); + } else if (nestedType instanceof IPointerType) { + nestedType = ((IPointerType) nestedType).getType(); + } else if (nestedType instanceof IArrayType) { + nestedType = ((IArrayType) nestedType).getType(); + } else if (nestedType instanceof ICPPReferenceType) { + nestedType = ((ICPPReferenceType) nestedType).getType(); + } else { + return null; + } + } IType result = null; ITypeContainer containerType = null; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index f0f95fad96b..bc27e46dee4 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -1329,7 +1329,7 @@ public class CompletionTests extends AbstractContentAssistTest { // v.push_back(/*cursor*/); // } public void testTypedefSpecialization_Bug307818() throws Exception { - final String[] expected= { "push_back(const int & value) : void" }; + final String[] expected= { "push_back(const vector::value_type & value) : void" }; assertParameterHint(expected); }