1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 380498. Fixed few more cases where typedefs were not preserved.

This commit is contained in:
Sergey Prigogin 2012-06-05 10:32:51 -07:00
parent 077c4ed4a1
commit 2bc64f56f3
18 changed files with 160 additions and 110 deletions

View file

@ -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() {

View file

@ -4706,8 +4706,9 @@ public class AST2CPPTests extends AST2BaseTest {
}
// template<typename T>
// class basic_string {
// struct basic_string {
// basic_string& operator+=(const T* s);
// basic_string& append(const T* s);
// };
//
// template<typename T>
@ -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 <typename T>
// struct vector {
// typedef T* const_iterator;
// const_iterator begin() const;
// };
//
// void test(const vector<int>& 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<int>::const_iterator", ASTTypeUtil.getType(it.getType(), false));
}
// int f() {

View file

@ -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 {

View file

@ -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.

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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()) {

View file

@ -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());
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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);
}
/**

View file

@ -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) {

View file

@ -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;

View file

@ -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<int>::value_type & value) : void" };
assertParameterHint(expected);
}