From b358f1f6d02fcaaf886c6a355a0c9cd92e18a66a Mon Sep 17 00:00:00 2001
From: Markus Schorn <markus.schorn@windriver.com>
Date: Fri, 17 Jul 2009 17:30:36 +0000
Subject: [PATCH] Modeling array sizes, bug 269926.

---
 .../parser/tests/ast2/AST2CPPSpecTest.java    |  50 +++----
 .../core/parser/tests/ast2/AST2CSpecTest.java |   8 +-
 .../parser/tests/ast2/AST2TemplateTests.java  |  18 ++-
 .../cdt/core/parser/tests/ast2/AST2Tests.java |   4 +-
 .../tests/IndexCPPBindingResolutionTest.java  |  14 ++
 .../cdt/internal/pdom/tests/DBTest.java       |  14 +-
 .../eclipse/cdt/core/dom/ast/ASTTypeUtil.java |  27 +++-
 .../eclipse/cdt/core/dom/ast/IArrayType.java  |   7 +
 .../internal/core/dom/parser/ASTQueries.java  |   9 ++
 .../cdt/internal/core/dom/parser/Value.java   |  10 +-
 .../core/dom/parser/c/CArrayType.java         |  40 ++++--
 .../core/dom/parser/cpp/CPPArrayType.java     |  41 +++++-
 .../core/dom/parser/cpp/CPPClassScope.java    |   4 +-
 .../core/dom/parser/cpp/CPPFunction.java      | 115 ++++++++--------
 .../parser/cpp/CPPFunctionSpecialization.java | 114 ++++++++--------
 .../dom/parser/cpp/CPPFunctionTemplate.java   | 124 ++++++++++--------
 .../dom/parser/cpp/CPPImplicitFunction.java   |  57 --------
 .../core/dom/parser/cpp/CPPParameter.java     |  35 ++++-
 .../dom/parser/cpp/ICPPInternalFunction.java  |   8 +-
 .../parser/cpp/semantics/CPPTemplates.java    |  57 ++++++--
 .../dom/parser/cpp/semantics/CPPVisitor.java  |  61 ++++-----
 .../internal/core/index/ArrayTypeClone.java   |  18 ++-
 .../index/composite/CompositeArrayType.java   |  19 ++-
 .../eclipse/cdt/internal/core/pdom/PDOM.java  |  15 +--
 .../cdt/internal/core/pdom/db/Chunk.java      |  17 +--
 .../cdt/internal/core/pdom/db/Database.java   |  21 +--
 .../internal/core/pdom/dom/PDOMArrayType.java |  67 ++++++++--
 27 files changed, 565 insertions(+), 409 deletions(-)

diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
index 3b5d701095a..7f846c25f51 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
@@ -669,28 +669,28 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
 		parse(getAboveComment(), ParserLanguage.CPP, false, 0);
 	}
 
-	// class X; // X is an incomplete type
-	// extern X* xp; // xp is a pointer to an incomplete type
-	// extern int arr[]; // the type of arr is incomplete
-	// typedef int UNKA[]; // UNKA is an incomplete type
-	// UNKA* arrp; // arrp is a pointer to an incomplete type
-	// UNKA** arrpp;
-	// void foo()
-	// {
-	// xp++; //illformed: X is incomplete
-	// arrp++; //illformed: incomplete type
-	// arrpp++; //OK: sizeof UNKA* is known
-	// }
-	// struct X { int i; }; // now X is a complete type
-	// int arr[10]; // now the type of arr is complete
-	// X x;
-	// void bar()
-	// {
-	// xp = &x; // OK; type is ''pointer to X''
-	// arrp = &arr; // illformed: different types
-	// xp++; //OK: X is complete
-	// arrp++; //illformed: UNKA can't be completed
-	// }
+	//	class X; // X is an incomplete type
+	//	extern X* xp; // xp is a pointer to an incomplete type
+	//	extern int arr[]; // the type of arr is incomplete
+	//	typedef int UNKA[]; // UNKA is an incomplete type
+	//	UNKA* arrp; // arrp is a pointer to an incomplete type
+	//	UNKA** arrpp;
+	//	void foo() {
+	//		xp++; //ill-formed: X is incomplete
+	//		arrp++; //ill-formed: incomplete type
+	//		arrpp++; //OK: sizeof UNKA* is known
+	//	}
+	//	struct X {
+	//		int i; 
+	//	}; // now X is a complete type
+	//	int arr[10]; // now the type of arr is complete
+	//	X x;
+	//	void bar() {
+	//		xp = &x; // OK; type is ''pointer to X''
+	//		arrp = &arr; // ill-formed: different types
+	//		xp++; //OK: X is complete
+	//		arrp++; //ill-formed: UNKA can't be completed
+	//	}
 	public void test3_9s7() throws Exception {
 		parse(getAboveComment(), ParserLanguage.CPP, true, 0);
 	}
@@ -797,7 +797,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
 		assertNull(newExpr.getNewPlacement());
 		assertNull(newExpr.getNewInitializer());
 		IASTTypeId typeid= newExpr.getTypeId();
-		isTypeEqual(CPPVisitor.createType(typeid), "int (* [])()");
+		isTypeEqual(CPPVisitor.createType(typeid), "int (* [10])()");
 	}
 
 	// typedef int T;
@@ -835,7 +835,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
 		newExpr= (ICPPASTNewExpression) expr;
 		assertNull(newExpr.getNewPlacement());
 		assertNull(newExpr.getNewInitializer());
-		isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int []");
+		isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]");
 
 		// new (2,f) T[5];
 		expr= getExpressionOfStatement(fdef, 3);
@@ -843,7 +843,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
 		newExpr= (ICPPASTNewExpression) expr;
 		assertInstance(newExpr.getNewPlacement(), IASTExpressionList.class);
 		assertNull(newExpr.getNewInitializer());
-		isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int []");
+		isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]");
 	}
 
 	// int n=2;
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
index 38189e50b59..817ec7c74fd 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2009 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
@@ -1203,8 +1203,10 @@ public class AST2CSpecTest extends AST2SpecBaseTest {
 		buffer.append("for (int j = 0, k = n*m+300; j < k; j++)\n"); //$NON-NLS-1$
 		buffer.append("// a is a pointer to a VLA with n*m+300 elements\n"); //$NON-NLS-1$
 		buffer.append("a[i][j] += x;\n"); //$NON-NLS-1$
-		buffer.append("}\n"); //$NON-NLS-1$
-		parseCandCPP(buffer.toString(), true, 0);
+		buffer.append("}\n");
+		String code = buffer.toString(); //$NON-NLS-1$
+		// no valid c++ code
+		parse(code, ParserLanguage.C, true, 0);
 	}
 	
 	/**
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index abe7e48a1cf..a6a1d25e70b 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -1971,8 +1971,7 @@ public class AST2TemplateTests extends AST2BaseTest {
 		ICPPSpecialization spec = (ICPPSpecialization) col.getName(9).resolveBinding();
 		assertSame(spec.getSpecializedBinding(), ctor);
 		
-		ICPPSpecialization c = (ICPPSpecialization) col.getName(10).resolveBinding();
-		assertSame(c.getSpecializedBinding(), g);
+		ICPPParameter c = (ICPPParameter) col.getName(10).resolveBinding();
 		
 		assertSame(blah, col.getName(11).resolveBinding());
 		assertSame(c, col.getName(12).resolveBinding());
@@ -1980,8 +1979,7 @@ public class AST2TemplateTests extends AST2BaseTest {
 		ICPPSpecialization spec2 = (ICPPSpecialization) col.getName(13).resolveBinding();
 		assertSame(spec.getSpecializedBinding(), ctor);
 		
-		ICPPSpecialization c2 = (ICPPSpecialization) col.getName(14).resolveBinding();
-		assertSame(c2.getSpecializedBinding(), g);
+		ICPPParameter c2 = (ICPPParameter) col.getName(14).resolveBinding();
 		
 		assertSame(blah, col.getName(15).resolveBinding());
 		assertSame(c2, col.getName(16).resolveBinding());
@@ -4056,7 +4054,7 @@ public class AST2TemplateTests extends AST2BaseTest {
 	//	void test() {
 	//	  S(a);
 	//	}
-	public void _testFunctionTemplateWithArrayReferenceParameter_269926() throws Exception {
+	public void testFunctionTemplateWithArrayReferenceParameter_269926() throws Exception {
 		final String code = getAboveComment();
 		parseAndCheckBindings(code, ParserLanguage.CPP);		
 	}
@@ -4106,4 +4104,14 @@ public class AST2TemplateTests extends AST2BaseTest {
 		final String code = getAboveComment();
 		parseAndCheckBindings(code, ParserLanguage.CPP);
 	}
+	
+	//	template <int N> void T(int (&array)[N]) {};
+	//	void test() {
+	//	  int a[2];
+	//	  T<2>(a); 
+	//	}
+	public void testInstantiationOfArraySize_269926() throws Exception {
+		final String code= getAboveComment();
+		parseAndCheckBindings(code, ParserLanguage.CPP);
+	}
 }
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 d7f0016ba1b..04a3b44903a 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
@@ -5157,10 +5157,10 @@ public class AST2Tests extends AST2BaseTest {
     		BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp);
 
     		IFunction f= ba.assertNonProblem("f1", 2, IFunction.class);
-    		isTypeEqual(f.getType(), "int (* (int))[]");
+    		isTypeEqual(f.getType(), "int (* (int))[5]");
     		
     		f= ba.assertNonProblem("f1 ", 2, IFunction.class);
-    		isTypeEqual(f.getType(), "int (* (int))[]");
+    		isTypeEqual(f.getType(), "int (* (int))[5]");
     	}
     }
     
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
index 708c1272d70..2b58d14a7e3 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
@@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.core.dom.ast.ICompositeType;
 import org.eclipse.cdt.core.dom.ast.IEnumeration;
 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.IType;
 import org.eclipse.cdt.core.dom.ast.IValue;
@@ -1363,6 +1364,19 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
 		assertNotNull(numericalValue);
 		assertEquals(i, numericalValue.intValue());
 	}
+	
+	// void f(int (&v)[1]);
+	// void f(int (&v)[2]);
+	
+	// void test() {
+	//   int a[1], b[2];
+	//   f(a); f(b);
+	// }
+	public void testArrayTypeWithSize_269926() throws Exception {
+    	IFunction f1= getBindingFromASTName("f(a)", 1, IFunction.class);
+    	IFunction f2= getBindingFromASTName("f(b)", 1, IFunction.class);
+    	assertFalse(f1.equals(f2));
+	}
 
 	/* CPP assertion helpers */
 	/* ##################################################################### */
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
index ef5d1117ec9..932fc73b827 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 QNX Software Systems
+ * Copyright (c) 2005, 2009 QNX Software Systems
  * 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
@@ -33,6 +33,7 @@ import org.eclipse.core.runtime.IPath;
 public class DBTest extends BaseTestCase {
 	protected Database db;
 	
+	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
 		db = new Database(getTestDir().append(getName()+System.currentTimeMillis()+".dat").toFile(),
@@ -52,6 +53,7 @@ public class DBTest extends BaseTestCase {
 		return path;
 	}
 	
+	@Override
 	protected void tearDown() throws Exception {
 		db.close();
 		if(!db.getLocation().delete()) {
@@ -72,8 +74,8 @@ public class DBTest extends BaseTestCase {
 		assertEquals(-blocksize, db.getShort(mem - Database.BLOCK_HEADER_SIZE));
 		db.free(mem);
 		assertEquals(blocksize, db.getShort(mem - Database.BLOCK_HEADER_SIZE));
-		assertEquals(mem - Database.BLOCK_HEADER_SIZE, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
-		assertEquals(mem - Database.BLOCK_HEADER_SIZE + blocksize, db.getRecPtr((freeDeltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
+		assertEquals(mem, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
+		assertEquals(mem + blocksize, db.getRecPtr((freeDeltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
 	}
 
 	public void testBug192437() throws IOException {
@@ -110,10 +112,10 @@ public class DBTest extends BaseTestCase {
 		long mem2 = db.malloc(realsize);
 		db.free(mem1);
 		db.free(mem2);
-		assertEquals(mem2 - Database.BLOCK_HEADER_SIZE, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
+		assertEquals(mem2, db.getRecPtr((deltas-Database.MIN_BLOCK_DELTAS+1) * Database.INT_SIZE));
 		assertEquals(0, db.getRecPtr(mem2));
-		assertEquals(mem1 - Database.BLOCK_HEADER_SIZE, db.getRecPtr(mem2 + Database.INT_SIZE));
-		assertEquals(mem2 - Database.BLOCK_HEADER_SIZE, db.getRecPtr(mem1));
+		assertEquals(mem1, db.getRecPtr(mem2 + Database.INT_SIZE));
+		assertEquals(mem2, db.getRecPtr(mem1));
 		assertEquals(0, db.getRecPtr(mem1 + Database.INT_SIZE));
 	}
 	
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 530263c84c9..de722e02fe1 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
@@ -39,6 +39,7 @@ import org.eclipse.cdt.core.parser.GCCKeywords;
 import org.eclipse.cdt.core.parser.Keywords;
 import org.eclipse.cdt.core.parser.util.ArrayUtil;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
+import org.eclipse.cdt.internal.core.dom.parser.Value;
 import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId;
 import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
 import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding;
@@ -202,22 +203,23 @@ public class ASTTypeUtil {
 			result.append(Keywords.cpLBRACKET);
 			if (type instanceof ICArrayType) {
 				try {
-					if (((ICArrayType) type).isConst()) {
+					final ICArrayType catype = (ICArrayType) type;
+					if (catype.isConst()) {
 						result.append(Keywords.CONST); needSpace = true;
 					}
-					if (((ICArrayType) type).isRestrict()) {
+					if (catype.isRestrict()) {
 						if (needSpace) {
 							result.append(SPACE); needSpace = false;
 						}
 						result.append(Keywords.RESTRICT); needSpace = true;
 					}
-					if (((ICArrayType) type).isStatic()) {
+					if (catype.isStatic()) {
 						if (needSpace) {
 							result.append(SPACE); needSpace = false;
 						}
 						result.append(Keywords.STATIC); needSpace = true;
 					}
-					if (((ICArrayType) type).isVolatile()) {
+					if (catype.isVolatile()) {
 						if (needSpace) {
 							result.append(SPACE); needSpace = false;
 						}
@@ -225,6 +227,23 @@ public class ASTTypeUtil {
 					}
 				} catch (DOMException e) {
 				}
+			} 
+			IValue val= ((IArrayType) type).getSize();
+			if (val != null && val != Value.UNKNOWN) {
+				if (normalize) {
+					if (needSpace) {
+						result.append(SPACE); needSpace = false;
+					}
+					result.append(val.getSignature());
+				} else {
+					Long v= val.numericalValue();
+					if (v != null) {
+						if (needSpace) {
+							result.append(SPACE); needSpace = false;
+						}
+						result.append(v.longValue());
+					}
+				}
 			}
 			result.append(Keywords.cpRBRACKET);
 		} else if (type instanceof IBasicType) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java
index d34b5712bfd..e6214691b62 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     Andrew Niefer (IBM Corporation) - initial API and implementation
+ *     Markus Schorn (Wind River Systems)
  *******************************************************************************/
 package org.eclipse.cdt.core.dom.ast;
 
@@ -20,6 +21,12 @@ public interface IArrayType extends IType {
      */
     IType getType();
     
+    /**
+     * Returns the value for the size of the array type, or <code>null</code> if it is unspecified.
+     * @since 5.2
+     */
+    IValue getSize();
+    
     /**
      * get the expression that represents the size of this array
      * @throws DOMException
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
index c45479f48de..c0f4b88d6d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
@@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
 import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
 import org.eclipse.cdt.core.dom.ast.IASTName;
 import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.parser.util.ArrayUtil;
 import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@@ -136,4 +137,12 @@ public class ASTQueries {
 		}
 		return active;
 	}
+
+	public static boolean isSameType(IType type1, IType type2) {
+		if (type1 == type2)
+			return true;
+		if (type1 == null || type2 == null)
+			return false;
+		return type1.isSameType(type2);
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
index 6a4dd4459a4..15cc82d0489 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2009 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
@@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalExce
 public class Value implements IValue {
 	public static final int MAX_RECURSION_DEPTH = 25;
 	public final static IValue UNKNOWN= new Value("<unknown>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
+	public final static IValue NOT_INITIALIZED= new Value("<__>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
 	
 	private static final String SCOPE_OP = "::"; //$NON-NLS-1$
 	private static final char UNIQUE_CHAR = '_';
@@ -225,8 +226,8 @@ public class Value implements IValue {
 	 */
 	public static boolean referencesTemplateParameter(IValue tval) {
 		final char[] rep= tval.getInternalExpression();
-		for (int i = 0; i < rep.length; i++) {
-			if (rep[i] == TEMPLATE_PARAM_CHAR)
+		for (char element : rep) {
+			if (element == TEMPLATE_PARAM_CHAR)
 				return true;
 		}
 		return false;
@@ -237,8 +238,7 @@ public class Value implements IValue {
 	 */
 	public static boolean isDependentValue(IValue nonTypeValue) {
 		final char[] rep= nonTypeValue.getInternalExpression();
-		for (int i = 0; i < rep.length; i++) {
-			final char c = rep[i];
+		for (final char c : rep) {
 			if (c == REFERENCE_CHAR || c == TEMPLATE_PARAM_CHAR)
 				return true;
 		}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java
index 9484d774f93..daca3228d46 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java
@@ -6,7 +6,7 @@
  *  http://www.eclipse.org/legal/epl-v10.html
  * 
  *  Contributors:
- *     IBM Corporation - initial API and implementation
+ *     Devin Steffler (IBM Corporation) - initial API and implementation
  *******************************************************************************/
 package org.eclipse.cdt.internal.core.dom.parser.c;
 
@@ -16,14 +16,14 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
 import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.IValue;
 import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
 import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
+import org.eclipse.cdt.internal.core.dom.parser.Value;
 import org.eclipse.cdt.internal.core.index.IIndexType;
 
-/**
- * @author dsteffle
- */
 public class CArrayType implements ICArrayType, ITypeContainer {
 	IType type;
 	ICASTArrayModifier mod;
@@ -35,7 +35,7 @@ public class CArrayType implements ICArrayType, ITypeContainer {
     public boolean isSameType(IType obj) {
         if (obj == this)
             return true;
-        if (obj instanceof ITypedef)
+        if (obj instanceof ITypedef || obj instanceof IIndexType)
             return obj.isSameType(this);
         if (obj instanceof ICArrayType) {
         	ICArrayType at = (ICArrayType) obj;
@@ -46,18 +46,24 @@ public class CArrayType implements ICArrayType, ITypeContainer {
         		if (isVolatile() != at.isVolatile()) return false;
         		if (isVariableLength() != at.isVariableLength()) return false;
 
-        		return at.getType().isSameType(type);
+        		return at.getType().isSameType(type) && hasSameSize(at);
         	} catch (DOMException e) {
         		return false;
         	}
         }
-        // Workaround for bug 182976, no PDOMCArrayType.
-        else if (obj instanceof IArrayType && obj instanceof IIndexType) {
-        	return obj.isSameType(this);
-        }
     	return false;
     }
     
+	private boolean hasSameSize(IArrayType rhs) {
+		IValue s1 = getSize();
+		IValue s2 = rhs.getSize();
+		if (s1 == s2)
+			return true;
+		if (s1 == null || s2 == null)
+			return false;
+		return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
+	}
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.cdt.core.dom.ast.IArrayType#getType()
 	 */
@@ -117,9 +123,17 @@ public class CArrayType implements ICArrayType, ITypeContainer {
         return mod;
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.core.dom.ast.IArrayType#getArraySizeExpression()
-     */
+    public IValue getSize() {
+    	if (mod != null) {
+    		IASTExpression sizeExpression = mod.getConstantExpression();
+    		if (sizeExpression != null) {
+    			return Value.create(sizeExpression, Value.MAX_RECURSION_DEPTH);
+    		}
+    	}
+    	return null;
+    }
+
+	@Deprecated
     public IASTExpression getArraySizeExpression() {
         if (mod != null)
             return mod.getConstantExpression();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java
index 24de95ea2e8..bc83450f549 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java
@@ -16,16 +16,25 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
 import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
+import org.eclipse.cdt.internal.core.dom.parser.Value;
 
 public class CPPArrayType implements IArrayType, ITypeContainer {
     private IType type;
     private IASTExpression sizeExpression;
-    
+    private IValue value= Value.NOT_INITIALIZED;
+
     public CPPArrayType(IType type) {
         this.type = type;
     }
     
+    public CPPArrayType(IType type, IValue value) {
+    	this.type= type;
+    	this.value= value;
+    }
+    
     public CPPArrayType(IType type, IASTExpression sizeExp) {
         this.type = type;
         this.sizeExpression = sizeExp;
@@ -46,16 +55,34 @@ public class CPPArrayType implements IArrayType, ITypeContainer {
             return ((ITypedef) obj).isSameType(this);
         
         if (obj instanceof IArrayType) {
-            IType objType = ((IArrayType) obj).getType();
-			if (objType != null)
-				return objType.isSameType(type);
+            final IArrayType rhs = (IArrayType) obj;
+			IType objType = rhs.getType();
+			if (objType != null) {
+				if (objType.isSameType(type)) {
+					IValue s1= getSize();
+					IValue s2= rhs.getSize();
+					if (s1 == s2)
+						return true;
+					if (s1 == null || s2 == null)
+						return false;
+					return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
+				}
+			}
         }
     	return false;
     }
+
+    public IValue getSize() {
+    	if (value != Value.NOT_INITIALIZED)
+    		return value;
+    	
+    	if (sizeExpression == null)
+    		return value= null;
+
+    	return value= Value.create(sizeExpression, Value.MAX_RECURSION_DEPTH);
+    }
     
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.core.dom.ast.IArrayType#getArraySizeExpression()
-     */
+    @Deprecated
     public IASTExpression getArraySizeExpression() {
         return sizeExpression;
     }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
index 2f50f68fe33..e355be20a01 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
@@ -99,9 +99,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
         }
         char[] className = name.getLookupKey();
 
-		IParameter[] voidPs = new IParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE) };
+		IParameter[] voidPs = new IParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE, 0) };
 		IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(clsType, true, false));
-		IParameter[] ps = new IParameter[] { new CPPParameter(pType) };
+		IParameter[] ps = new IParameter[] { new CPPParameter(pType, 0) };
 
 		int i= 0;
 		ImplicitsAnalysis ia= new ImplicitsAnalysis(compTypeSpec);
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 894a4969147..374ac4289ff 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
@@ -164,18 +164,18 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
         return definition;
     }
     
-	public void addDefinition(IASTNode node) {
+	public final void addDefinition(IASTNode node) {
 		ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
 		if (dtor != null) {
-			updateParameterBindings(dtor);
+			updateFunctionParameterBindings(dtor);
 			definition = dtor;
 		}
 	}
 	
-	public void addDeclaration(IASTNode node) {
+	public final void addDeclaration(IASTNode node) {
 		ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
 		if (dtor != null) {
-			updateParameterBindings(dtor);
+			updateFunctionParameterBindings(dtor);
 
 			if (declarations == null) {
 				declarations = new ICPPASTFunctionDeclarator[] { dtor };
@@ -213,7 +213,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
 		if (size > 0) {
 			for (int i = 0; i < size; i++) {
 				IASTParameterDeclaration p = params[i];
-				final IASTName name = ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName();
+				final IASTName name = getParamName(p);
 				final IBinding binding= name.resolveBinding();
 				if (binding instanceof IParameter) {
 					result[i]= (IParameter) binding;
@@ -287,67 +287,60 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
         return type;
     }
 
-    public IBinding resolveParameter(IASTParameterDeclaration param) {
-        IASTDeclarator dtor = param.getDeclarator();
-        while (dtor.getNestedDeclarator() != null)
-            dtor = dtor.getNestedDeclarator();
-    	IASTName name = dtor.getName();
-    	IBinding binding = name.getBinding();
-    	if (binding != null)
-    		return binding;
+    public IBinding resolveParameter(CPPParameter param) {
+		int pos= param.getParameterPosition();
 		
-    	IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
-    	IASTParameterDeclaration[] ps = fdtor.getParameters();
-    	int i = 0;
-    	for (; i < ps.length; i++) {
-    		if (param == ps[i])
-    			break;
-    	}
-    	
-    	//create a new binding and set it for the corresponding parameter in all known defns and decls
-    	binding = new CPPParameter(name);
-    	IASTParameterDeclaration temp = null;
-    	if (definition != null) {
-    		IASTParameterDeclaration[] paramDecls = definition.getParameters();
-    		if (paramDecls.length > i) { // This will be less than i if we have a void parameter
-	    		temp = paramDecls[i];
-	    		IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-	    		if (n != name) {
-	    		    n.setBinding(binding);
-	    		    ASTInternal.addDeclaration(binding, n);
-	    		}
+    	int tdeclLen= declarations == null ? 0 : declarations.length;
+    	for (int i= -1; i < tdeclLen; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= definition;
+    			if (tdecl == null)
+    				continue;
+    		} else {
+    			tdecl= declarations[i];
+    			if (tdecl == null)
+    				break;
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		if (pos < params.length) {
+				final IASTName oName = getParamName(params[pos]);
+    			return oName.resolvePreBinding();
     		}
     	}
-    	if (declarations != null) {
-    		for (int j = 0; j < declarations.length && declarations[j] != null; j++) {
-    			IASTParameterDeclaration[] paramDecls = declarations[j].getParameters();
-    			if (paramDecls.length > i) {
-	    			temp = paramDecls[i];
-	        		IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-	        		if (n != name) {
-	        		    n.setBinding(binding);
-	        		    ASTInternal.addDeclaration(binding, n);
-	        		}
-    			}
-    		}
-    	}
-    	return binding;
+    	return param;
     }
+
+	private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
+		return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
+	}
     
-    protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
-    	ICPPASTFunctionDeclarator orig = definition != null ? definition : declarations[0];
-    	IASTParameterDeclaration[] ops = orig.getParameters();
-    	IASTParameterDeclaration[] nps = fdtor.getParameters();
-    	CPPParameter temp = null;
-    	for (int i = 0; i < ops.length; i++) {
-    		temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
-    		if (temp != null && nps.length > i) {		//length could be different, ie 0 or 1 with void
-    		    IASTDeclarator dtor = nps[i].getDeclarator();
-    		    while (dtor.getNestedDeclarator() != null)
-    		        dtor = dtor.getNestedDeclarator();
-    		    IASTName name = dtor.getName();
-    			name.setBinding(temp);
-    			ASTInternal.addDeclaration(temp, name);
+    protected final void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
+		IASTParameterDeclaration[] updateParams = fdtor.getParameters();
+
+    	int k= 0;
+    	int tdeclLen= declarations == null ? 0 : declarations.length;
+    	for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= definition;
+    			if (tdecl == null)
+    				continue;
+    		} else {
+    			tdecl= declarations[i];
+    			if (tdecl == null)
+    				break;
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		int end= Math.min(params.length, updateParams.length);
+    		for (; k < end; k++) {
+    			final IASTName oName = getParamName(params[k]);
+    			IBinding b= oName.resolvePreBinding();
+    			IASTName n = getParamName(updateParams[k]);
+    			n.setBinding(b);
+    			ASTInternal.addDeclaration(b, n);
     		}
     	}
     }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java
index 9f755ab3c5a..af759b451fe 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java
@@ -158,41 +158,70 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
         return false;
 	}
 
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#resolveParameter(org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration)
-     */
-    public IBinding resolveParameter(IASTParameterDeclaration param) {
-        IASTDeclarator dtor = param.getDeclarator();
-        while (dtor.getNestedDeclarator() != null)
-            dtor = dtor.getNestedDeclarator();
-        IASTName name = dtor.getName();
-    	IBinding binding = name.getBinding();
-    	if (binding != null)
-    		return binding;
+    public IBinding resolveParameter(CPPParameter param) {
+		int pos= param.getParameterPosition();
 		
-    	ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
-    	IASTParameterDeclaration[] ps = fdtor.getParameters();
-    	int i = 0;
-    	for (; i < ps.length; i++) {
-    		if (param == ps[i])
+    	final IASTNode[] decls= getDeclarations();
+		int tdeclLen= decls == null ? 0 : decls.length;
+    	for (int i= -1; i < tdeclLen; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= (ICPPASTFunctionDeclarator) getDefinition();
+    			if (tdecl == null)
+    				continue;
+    		} else if (decls != null){
+    			tdecl= (ICPPASTFunctionDeclarator) decls[i];
+    			if (tdecl == null)
+    				break;
+    		} else {
     			break;
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		if (pos < params.length) {
+    			final IASTName oName = getParamName(params[pos]);
+    			return oName.resolvePreBinding();
+    		}
     	}
-    	
-        try {
-            IParameter[] params = getParameters();
-            if (i < params.length) {
-        	    final IParameter myParam = params[i];
-				name.setBinding(myParam);
-        	    ASTInternal.addDeclaration(myParam, name);
-        	    return myParam;
-        	}
-
-        } catch (DOMException e) {
-            return e.getProblem();
-        }
-        return null;
+    	return param;
     }
     
+    protected void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
+		IASTParameterDeclaration[] updateParams = fdtor.getParameters();
+
+    	int k= 0;
+    	final IASTNode[] decls= getDeclarations();
+    	int tdeclLen= decls == null ? 0 : decls.length;
+    	for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= (ICPPASTFunctionDeclarator) getDefinition();
+    			if (tdecl == null)
+    				continue;
+    		} else if (decls != null) {
+    			tdecl= (ICPPASTFunctionDeclarator) decls[i];
+    			if (tdecl == null)
+    				break;
+    		} else {
+    			break;
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		int end= Math.min(params.length, updateParams.length);
+    		for (; k < end; k++) {
+    			final IASTName oName = getParamName(params[k]);
+    			IBinding b= oName.resolvePreBinding();
+    			IASTName n = getParamName(updateParams[k]);
+    			n.setBinding(b);
+    			ASTInternal.addDeclaration(b, n);
+    		}
+    	}
+    }
+
+	private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
+		return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
+	}
+
 	private ICPPASTFunctionDeclarator extractFunctionDtor(IASTNode node) {
 		if (node instanceof IASTName)
 			node = node.getParent();
@@ -209,7 +238,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
 	public void addDefinition(IASTNode node) {
 		ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
 		if (dtor != null) {
-			updateParameterBindings(dtor);
+			updateFunctionParameterBindings(dtor);
 	        super.addDefinition(dtor);
 		}
 	}
@@ -218,32 +247,11 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
 	public void addDeclaration(IASTNode node) {
 		ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
 		if (dtor != null) {
-			updateParameterBindings(dtor);
+			updateFunctionParameterBindings(dtor);
 	        super.addDeclaration(dtor);
 		}
 	}
 
-    protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
-        IParameter[] params = null;
-        try {
-            params = getParameters();
-        } catch (DOMException e) {
-            return;
-        }
-        IASTParameterDeclaration[] nps = fdtor.getParameters();
-    	for (int i = 0; i < nps.length; i++) {
-    		final IParameter param = params[i];
-			if (param != null) {
-    		    IASTDeclarator dtor = nps[i].getDeclarator();
-    		    while (dtor.getNestedDeclarator() != null)
-    		        dtor = dtor.getNestedDeclarator();
-    		    IASTName name = dtor.getName();
-    			name.setBinding(param);
-    			ASTInternal.addDeclaration(param, name);
-    		}
-    	}
-    }
-
 	@Override
 	public String toString() {
 		StringBuilder result = new StringBuilder();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java
index da111fe7cf1..691478121f7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java
@@ -113,7 +113,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
 	public void addDefinition(IASTNode node) {
 		if (!(node instanceof IASTName))
 			return;
-		updateFunctionParameterBindings((IASTName) node);
+		ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node);
+		if (fdecl == null)
+			return;
+		
+		updateFunctionParameterBindings(fdecl);
 		super.addDefinition(node);
 	}
 
@@ -121,24 +125,12 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
 	public void addDeclaration(IASTNode node) {
 		if (!(node instanceof IASTName))
 			return;
-		updateFunctionParameterBindings((IASTName) node);
-		super.addDeclaration(node);
-	}
+		ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node);
+		if (fdecl == null)
+			return;
 
-	private void updateFunctionParameterBindings(IASTName declName) {
-		IASTName defName = definition != null ? definition : declarations[0];
-		ICPPASTFunctionDeclarator orig = getDeclaratorByName(defName);
-    	IASTParameterDeclaration[] ops = orig.getParameters();
-    	IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters();
-    	CPPParameter temp = null;
-    	for(int i = 0; i < nps.length; i++) {
-    		temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
-    		if (temp != null) {
-    		    IASTName name = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
-    			name.setBinding(temp);
-    			ASTInternal.addDeclaration(temp, name);
-    		}
-    	}
+		updateFunctionParameterBindings(fdecl);
+		super.addDeclaration(node);
 	}
 
 	public IParameter[] getParameters() {
@@ -212,49 +204,69 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
         return false;
 	}
 
-	public IBinding resolveParameter(IASTParameterDeclaration param) {
-	   	IASTName name = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
-    	IBinding binding = name.getBinding();
-    	if (binding != null)
-    		return binding;
+    public IBinding resolveParameter(CPPParameter param) {
+		int pos= param.getParameterPosition();
 		
-    	ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
-    	IASTParameterDeclaration[] ps = fdtor.getParameters();
-    	int i = 0;
-    	for (; i < ps.length; i++) {
-    		if (param == ps[i])
+    	final IASTNode[] decls= getDeclarations();
+		int tdeclLen= decls == null ? 0 : decls.length;
+    	for (int i= -1; i < tdeclLen; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= getDeclaratorByName(getDefinition());
+    			if (tdecl == null)
+    				continue;
+    		} else if (decls != null){
+    			tdecl= getDeclaratorByName(decls[i]);
+    			if (tdecl == null)
+    				break;
+    		} else {
     			break;
-    	}
-    	
-    	//create a new binding and set it for the corresponding parameter in all known defns and decls
-    	binding = new CPPParameter(name);
-    	IASTParameterDeclaration temp = null;
-    	if (definition != null) {
-    		ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition);
-    		if (fdecl != null) {
-    			temp = fdecl.getParameters()[i];
-    			IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-    			if (n != name) {
-    				n.setBinding(binding);
-    				ASTInternal.addDeclaration(binding, n);
-    			}
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		if (pos < params.length) {
+    			final IASTName oName = getParamName(params[pos]);
+    			return oName.resolvePreBinding();
     		}
     	}
-    	if (declarations != null) {
-    		for(int j = 0; j < declarations.length && declarations[j] != null; j++) {
-        		ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]);
-        		if (fdecl != null) {
-        			temp = fdecl.getParameters()[i];
-        			IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-        			if (n != name) {
-        				n.setBinding(binding);
-        				ASTInternal.addDeclaration(binding, n);
-        			}
-        		}
-    		}
-    	}
-    	return binding;	
+    	return param;
     }
+    
+    protected void updateFunctionParameterBindings(ICPPASTFunctionDeclarator fdtor) {
+		IASTParameterDeclaration[] updateParams = fdtor.getParameters();
+
+    	int k= 0;
+    	final IASTNode[] decls= getDeclarations();
+    	int tdeclLen= decls == null ? 0 : decls.length;
+    	for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
+    		ICPPASTFunctionDeclarator tdecl;
+    		if (i == -1) {
+    			tdecl= getDeclaratorByName(getDefinition());
+    			if (tdecl == null)
+    				continue;
+    		} else if (decls != null) {
+    			tdecl= getDeclaratorByName(decls[i]);
+    			if (tdecl == null)
+    				break;
+    		} else {
+    			break;
+    		}
+    		
+    		IASTParameterDeclaration[] params = tdecl.getParameters();
+    		int end= Math.min(params.length, updateParams.length);
+    		for (; k < end; k++) {
+    			final IASTName oName = getParamName(params[k]);
+    			IBinding b= oName.resolvePreBinding();
+    			IASTName n = getParamName(updateParams[k]);
+    			n.setBinding(b);
+    			ASTInternal.addDeclaration(b, n);
+    		}
+    	}
+    }
+
+	private IASTName getParamName(final IASTParameterDeclaration paramDecl) {
+		return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
+	}
 
 	public boolean isStatic() {
 		return hasStorageClass(IASTDeclSpecifier.sc_static);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
index 4cc8c709507..704139fd908 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
@@ -11,15 +11,10 @@
  *******************************************************************************/
 package org.eclipse.cdt.internal.core.dom.parser.cpp;
 
-import org.eclipse.cdt.core.dom.ast.IASTName;
-import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
 import org.eclipse.cdt.core.dom.ast.IBinding;
 import org.eclipse.cdt.core.dom.ast.IParameter;
 import org.eclipse.cdt.core.dom.ast.IScope;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
-import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
-import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
 
 /**
  * The CPPImplicitFunction is used to represent implicit functions that exist on the translation
@@ -82,58 +77,6 @@ public class CPPImplicitFunction extends CPPFunction {
         return null;
     }
     
-    @Override
-	public IBinding resolveParameter(IASTParameterDeclaration param) {
-		IASTName aName = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
-		IParameter binding = (IParameter) aName.getBinding();
-		if (binding != null)
-			return binding;
-
-		// get the index in the parameter list
-		ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
-		IASTParameterDeclaration[] ps = fdtor.getParameters();
-		int i = 0;
-		for (; i < ps.length; i++) {
-			if (param == ps[i])
-				break;
-		}
-
-		// set the binding for the corresponding parameter in all known defns and decls
-		binding = parms[i];
-		IASTParameterDeclaration temp = null;
-		if (definition != null) {
-			temp = definition.getParameters()[i];
-			IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-			n.setBinding(binding);
-			ASTInternal.addDeclaration(binding, n);
-		}
-		if (declarations != null) {
-			for (int j = 0; j < declarations.length && declarations[j] != null; j++) {
-				temp = declarations[j].getParameters()[i];
-				IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
-				n.setBinding(binding);
-				ASTInternal.addDeclaration(binding, n);
-			}
-		}
-		return binding;
-    }
-   
-    @Override
-	protected void updateParameterBindings(ICPPASTFunctionDeclarator fdtor) {
-		if (parms != null) {
-			IASTParameterDeclaration[] nps = fdtor.getParameters();
-			if (nps.length != parms.length)
-				return;
-
-			for (int i = 0; i < nps.length; i++) {
-				IASTName aName = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
-				final IParameter param = parms[i];
-				aName.setBinding(param);
-				ASTInternal.addDeclaration(param, aName);
-			}
-		}
-	}
-
     @Override
 	public boolean takesVarArgs() {
         return takesVarArgs;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
index e2f6bcc123c..ccc28b74943 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
@@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
 import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
 import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
 import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
 import org.eclipse.cdt.core.dom.ast.IASTInitializer;
 import org.eclipse.cdt.core.dom.ast.IASTName;
@@ -30,6 +31,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
 import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.Linkage;
 import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
 import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@@ -38,7 +40,7 @@ import org.eclipse.core.runtime.PlatformObject;
 /**
  * Binding for a c++ function parameter
  */
-public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPInternalBinding {
+public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPInternalBinding, ICPPTwoPhaseBinding {
     public static class CPPParameterProblem extends ProblemBinding implements ICPPParameter {
         public CPPParameterProblem(IASTNode node, int id, char[] arg) {
             super(node, id, arg);
@@ -83,14 +85,17 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
 
 	private IType type = null;
 	private IASTName[] declarations = null;
+	private int fPosition;
 	
 	
-	public CPPParameter(IASTName name) {
+	public CPPParameter(IASTName name, int pos) {
 		this.declarations = new IASTName[] { name };
+		fPosition= pos;
 	}
 	
-	public CPPParameter(IType type) {
+	public CPPParameter(IType type, int pos) {
 	    this.type = type;
+	    fPosition= pos;
 	}
 	
     /* (non-Javadoc)
@@ -301,4 +306,28 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
 	public IValue getInitialValue() {
 		return null;
 	}
+
+	public IBinding resolveFinalBinding(CPPASTNameBase name) {
+		// check if the binding has been updated.
+		IBinding current= name.getPreBinding();
+		if (current != this)
+			return current;
+		
+		IASTNode node= getPrimaryDeclaration();
+		while (node != null && !(node instanceof IASTFunctionDeclarator)) {
+			node= node.getParent();
+		}
+		if (node instanceof IASTFunctionDeclarator) {
+			IASTName funcName= ASTQueries.findInnermostDeclarator((IASTFunctionDeclarator) node).getName();
+			IBinding b= funcName.resolvePreBinding();
+			if (b instanceof ICPPInternalFunction) {
+				return ((ICPPInternalFunction) b).resolveParameter(this);
+			}
+		}
+		return this;
+	}
+
+	public int getParameterPosition() {
+		return fPosition;
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java
index b7b472f8300..638e1e06ca6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java
@@ -12,7 +12,6 @@
 
 package org.eclipse.cdt.internal.core.dom.parser.cpp;
 
-import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
 import org.eclipse.cdt.core.dom.ast.IBinding;
 
 /**
@@ -20,8 +19,11 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
  */
 public interface ICPPInternalFunction extends ICPPInternalBinding {
 
-    public IBinding resolveParameter( IASTParameterDeclaration param );
-    
+	/**
+	 * Called to resolve the parameter in the second phase.
+	 */
+	public IBinding resolveParameter(CPPParameter parameter);
+	
     /**
      * Returns whether there is a static declaration for this function.
      * @param resolveAll checks for names that are not yet resolved to this binding.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index 0a348ab252d..03c4685eb2e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -96,6 +96,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
 import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
 import org.eclipse.cdt.internal.core.dom.parser.Value;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
@@ -842,11 +843,11 @@ public class CPPTemplates {
 			}		
 
 			if (type instanceof ITypeContainer) {
-				final ITypeContainer tc = (ITypeContainer) type;
-				IType nestedType = tc.getType();
+				final ITypeContainer typeContainer = (ITypeContainer) type;
+				IType nestedType = typeContainer.getType();
 				IType newNestedType = instantiateType(nestedType, tpMap, within);
-				if (type instanceof ICPPPointerToMemberType) {
-					ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
+				if (typeContainer instanceof ICPPPointerToMemberType) {
+					ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
 					IType memberOfClass = ptm.getMemberOfClass();
 					IType newMemberOfClass = instantiateType(memberOfClass, tpMap, within);
 					if (newNestedType != nestedType || newMemberOfClass != memberOfClass) {
@@ -854,13 +855,22 @@ public class CPPTemplates {
 							return new CPPPointerToMemberType(newNestedType, newMemberOfClass,
 								ptm.isConst(), ptm.isVolatile());
 						}
-						return type;
+						return typeContainer;
+					}
+				} else if (typeContainer instanceof IArrayType) {
+					IArrayType at= (IArrayType) typeContainer;
+					IValue asize= at.getSize();
+					if (asize != null) {
+						IValue newSize= instantiateValue(asize, tpMap, within, Value.MAX_RECURSION_DEPTH);
+						if (newSize != asize) {
+							return new CPPArrayType(newNestedType, newSize);
+						}
 					}
 				}
 				if (newNestedType != nestedType) {
-					return SemanticUtil.replaceNestedType(tc, newNestedType);
+					return SemanticUtil.replaceNestedType(typeContainer, newNestedType);
 				} 
-				return type;
+				return typeContainer;
 			} 
 
 			return type;
@@ -1595,6 +1605,32 @@ public class CPPTemplates {
 				}
 				p = ((ICPPReferenceType) p).getType();
 				a = ((ICPPReferenceType) a).getType();
+			} else if (p instanceof IArrayType) {
+				if (!(a instanceof IArrayType)) {
+					return false;
+				}
+				IArrayType aa= (IArrayType) a;
+				IArrayType pa= (IArrayType) p;
+				IValue as= aa.getSize();
+				IValue ps= pa.getSize();
+				if (as != ps) {
+					if (as == null || ps == null)
+						return false;
+					
+					int parPos= Value.isTemplateParameter(ps);
+					if (parPos >= 0) { 
+						ICPPTemplateArgument old= map.getArgument(parPos);
+						if (old == null) {
+							map.put(parPos, new CPPTemplateArgument(ps, new CPPBasicType(IBasicType.t_int, 0)));
+						} else if (!ps.equals(old.getNonTypeValue())) {
+							return false;
+						}
+					} else if (!ps.equals(as)) {
+						return false;
+					}
+				}
+				p = pa.getType();
+				a = aa.getType();
 			} else if (p instanceof IQualifierType) {
 				if (a instanceof IQualifierType) {
 					a = ((IQualifierType) a).getType(); //TODO a = strip qualifiers from p out of a
@@ -1915,7 +1951,7 @@ public class CPPTemplates {
 			if (!(paramType instanceof IType))
 				return null;
 
-			IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType) };
+			IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType, 0) };
 
 			return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
 		} catch (DOMException e) {
@@ -2085,6 +2121,11 @@ public class CPPTemplates {
 					return true;
 				t= ptmt.getType();
 			} else if (t instanceof ITypeContainer) {
+				if (t instanceof IArrayType) {
+					IValue asize= ((IArrayType) t).getSize();
+					if (asize != null && Value.isDependentValue(asize))
+						return true;
+				}
 				t= ((ITypeContainer) t).getType();
 			} else {
 				return false;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index b7796c390da..cbe265a0044 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -166,7 +166,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
 import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
 import org.eclipse.cdt.internal.core.index.IIndexScope;
 
@@ -454,6 +453,7 @@ public class CPPVisitor extends ASTQueries {
         }
 		return binding;
 	}
+	
 	private static IBinding createBinding(IASTDeclaration declaration) {
 		if (declaration instanceof ICPPASTNamespaceDefinition) {
 			ICPPASTNamespaceDefinition namespaceDef = (ICPPASTNamespaceDefinition) declaration;
@@ -499,6 +499,7 @@ public class CPPVisitor extends ASTQueries {
 
 		return null;
 	}
+	
 	private static IBinding createBinding(IASTDeclarator declarator) {
 		IASTNode parent = findOutermostDeclarator(declarator).getParent();
 		declarator= findInnermostDeclarator(declarator);
@@ -556,16 +557,13 @@ public class CPPVisitor extends ASTQueries {
 				if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
 						findTypeRelevantDeclarator(fdtor) != fdtor)
 					return null;
-				IBinding temp = findInnermostDeclarator(fdtor).getName().resolveBinding();
-				if (temp instanceof ICPPInternalFunction) {
-					return ((ICPPInternalFunction) temp).resolveParameter(param);
-				} else if (temp instanceof IProblemBinding) {
-				    //problems with the function, still create binding for the parameter
-				    return new CPPParameter(name);
-				} else if (temp instanceof IIndexBinding) {
-					return new CPPParameter(name);
+				IASTParameterDeclaration[] params = fdtor.getParameters();
+				int i=0;
+				for(;i<params.length; i++) {
+					if (params[i] == param)
+						break;
 				}
-				return null;
+				return new CPPParameter(name, i);
 			} else if (parent instanceof ICPPASTTemplateDeclaration) {
 				return CPPTemplates.createBinding(param);
 			}
@@ -600,28 +598,7 @@ public class CPPVisitor extends ASTQueries {
         
         IASTSimpleDeclaration simpleDecl = (parent instanceof IASTSimpleDeclaration) ?
         		(IASTSimpleDeclaration) parent : null;
-        if (parent instanceof ICPPASTParameterDeclaration) {
-			ICPPASTParameterDeclaration param = (ICPPASTParameterDeclaration) parent;
-			parent = param.getParent();
-			if (parent instanceof IASTStandardFunctionDeclarator) {
-				IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
-				// if the fdtor does not declare a function we don't create a binding for the parameter.
-				if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
-						findTypeRelevantDeclarator(fdtor) != fdtor)
-					return null;
-				IBinding temp = findInnermostDeclarator(fdtor).getName().resolveBinding();
-				if (temp instanceof ICPPInternalFunction) {
-					binding = ((ICPPInternalFunction) temp).resolveParameter(param);
-				} else if (temp instanceof IProblemBinding) {
-				    //problems with the function, still create binding for the parameter
-				    binding = new CPPParameter(name);
-				} else if (temp instanceof IIndexBinding) {
-					binding= new CPPParameter(name);
-				}
-			} else if (parent instanceof ICPPASTTemplateDeclaration) {
-				return CPPTemplates.createBinding(param);
-			}
-		} else if (simpleDecl != null &&
+        if (simpleDecl != null &&
 				simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
 		    if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef && name.isActive()) {
 		        IType t1 = ((ITypedef) binding).getType();
@@ -687,7 +664,7 @@ public class CPPVisitor extends ASTQueries {
                 }
 		    }
 		    if (t1 != null && t2 != null) {
-		    	if (t1.isSameType(t2)) {
+				if (t1.isSameType(t2) || isCompatibleArray(t1, t2) != null) {
 		    		ASTInternal.addDeclaration(binding, name);
 		    	} else {
 		    		binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
@@ -702,6 +679,24 @@ public class CPPVisitor extends ASTQueries {
 		return binding;
 	}
 
+	private static IType isCompatibleArray(IType t1, IType t2) {
+		if (t1 instanceof IArrayType && t2 instanceof IArrayType) {
+			IArrayType a1 = (IArrayType) t1;
+			IArrayType a2 = (IArrayType) t2;
+			if (!isSameType(a1.getType(), a2.getType())) {
+				return null;
+			}
+			if (a1.getSize() == null) {
+				if (a2.getSize() != null) {
+					return a2;
+				}
+			} else if (a2.getSize() == null) {
+				return a1;
+			}
+		}
+		return null;
+	}
+
 	public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) {
 	    if (containingScope == null || !(containingScope instanceof ICPPClassScope))
 	        return false;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/ArrayTypeClone.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/ArrayTypeClone.java
index d8d81484b14..e727bcea22f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/ArrayTypeClone.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/ArrayTypeClone.java
@@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
 import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
 
 public class ArrayTypeClone implements IIndexType, IArrayType, ITypeContainer {
@@ -37,9 +39,23 @@ public class ArrayTypeClone implements IIndexType, IArrayType, ITypeContainer {
 			return false;
 
 		IArrayType rhs = (IArrayType) type;
-		return type1.isSameType(rhs.getType());
+		if (type1.isSameType(rhs.getType())) {
+			IValue s1= getSize();
+			IValue s2= rhs.getSize();
+			if (s1 == s2)
+				return true;
+			if (s1 == null || s2 == null)
+				return false;
+			return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
+		}
+		return false;
 	}
 
+	public IValue getSize() {
+		return delegate.getSize();
+	}
+	
+	@Deprecated
 	public IASTExpression getArraySizeExpression() throws DOMException {
 		return delegate.getArraySizeExpression();
 	}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeArrayType.java
index 76d4326b3bd..208c55c15ff 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeArrayType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeArrayType.java
@@ -1,18 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2007 Symbian Software Systems and others.
+ * Copyright (c) 2007, 2009 Symbian Software Systems 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
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- * Andrew Ferguson (Symbian) - Initial implementation
+ *    Andrew Ferguson (Symbian) - Initial implementation
  *******************************************************************************/
 package org.eclipse.cdt.internal.core.index.composite;
 
-import org.eclipse.cdt.core.dom.ast.DOMException;
 import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
+import org.eclipse.cdt.core.dom.ast.IValue;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
 import org.eclipse.cdt.internal.core.index.ArrayTypeClone;
 
@@ -21,12 +21,17 @@ public class CompositeArrayType extends CompositeTypeContainer implements IArray
 		super((ITypeContainer) arrayType, cf);
 	}
 
-	public IASTExpression getArraySizeExpression() throws DOMException {
-		fail(); return null;
-	}
-	
 	@Override
 	public Object clone() {
 		return new ArrayTypeClone(this);
 	}
+
+	public IValue getSize() {
+		return ((IArrayType) type).getSize();
+	}
+
+	@Deprecated
+	public IASTExpression getArraySizeExpression() {
+		return null;
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index fd879e803c4..14e66009dd8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -181,18 +181,11 @@ public class PDOM extends PlatformObject implements IPDOM {
 	 *  84.0 - storing free record pointers as (ptr>>3) and allocated pointers as (ptr-2)>>3 RECPTR_DENSE_VERSION
 	 *  
 	 *  CDT 7.0 development (versions not supported on the 6.0.x branch)
-	 *  next: 90.0
+	 *  90.0 - support for array sizes, bug 269926
 	 */
-	private static final int MIN_SUPPORTED_VERSION= version(83, 0);
-	private static final int MAX_SUPPORTED_VERSION= version(84, Short.MAX_VALUE);
-	private static int DEFAULT_VERSION = version(84, 0);
-	public static final int DENSE_RECPTR_VERSION = version(84, 0);
-	
-	static {
-		if (System.getProperty("org.eclipse.cdt.core.parser.pdom.useDensePointers", "false").equals("true")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-			DEFAULT_VERSION= DENSE_RECPTR_VERSION;
-		}
-	}
+	private static final int MIN_SUPPORTED_VERSION= version(90, 0);
+	private static final int MAX_SUPPORTED_VERSION= version(90, Short.MAX_VALUE);
+	private static final int DEFAULT_VERSION = version(90, 0);
 	
 	private static int version(int major, int minor) {
 		return (major << 16) + minor;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
index 5b8a80ce3c5..9ca79c26fc9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
@@ -106,19 +106,10 @@ final class Chunk {
 	 * pointer is not moved past the BLOCK_HEADER_SIZE.
 	 */
 	public void putRecPtr(final long offset, final long value) {
-		if (!fDatabase.usesDensePointers()) {
-			putFreeRecPtr(offset, value);
-		} else {
-			putFreeRecPtr(offset, value == 0 ? value : value - Database.BLOCK_HEADER_SIZE);
-		}
-		return;
+		putFreeRecPtr(offset, value == 0 ? value : value - Database.BLOCK_HEADER_SIZE);
 	}
 	
 	public void putFreeRecPtr(final long offset, final long value) {
-		if (!fDatabase.usesDensePointers()) {
-			putInt(offset, (int) value);
-			return;
-		}
 		/*
 		 * This assert verifies the alignment. We expect the low bits to be clear.
 		 */
@@ -127,9 +118,6 @@ final class Chunk {
 	}
 	
 	public long getRecPtr(final long offset) {
-		if (!fDatabase.usesDensePointers()) {
-			return getInt(offset);
-		}
 		long address = getFreeRecPtr(offset);
 		return address != 0 ? (address + Database.BLOCK_HEADER_SIZE) : address;
 	}
@@ -137,9 +125,6 @@ final class Chunk {
 	
 	public long getFreeRecPtr(final long offset) {
 		int value = getInt(offset);
-		if (!fDatabase.usesDensePointers()) {
-			return value;
-		}
 		/*
 		 * We need to properly manage the integer that was read. The value will be sign-extended 
 		 * so if the most significant bit is set, the resulting long will look negative. By 
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
index 07f51a85d9d..6f3b205a1a1 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
@@ -24,7 +24,6 @@ import java.nio.channels.FileChannel;
 import java.util.ArrayList;
 
 import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.internal.core.pdom.PDOM;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
@@ -74,6 +73,9 @@ public class Database {
 	public static final int MIN_BLOCK_DELTAS = 2;	// a block must at least be 2 + 2*4 bytes to link the free blocks.
 	public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE/BLOCK_SIZE_DELTA;	
 	public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS*BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;  
+	public static final int PTR_SIZE = 4;  // size of a pointer in the database in bytes  
+	public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
+
 
 	public static final int VERSION_OFFSET = 0;
 	public static final int DATA_AREA = (CHUNK_SIZE / BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 2) * INT_SIZE;
@@ -360,14 +362,8 @@ public class Database {
 			 * special status, the indexing operation should be stopped. This is desired since generally, once
 			 * the max size is exceeded, there are lots of errors.
 			 */
-			long max_size;
-			if (usesDensePointers()) {
-				max_size = ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
-			} else {
-				max_size = ((long) 1 << (Integer.SIZE - 1));
-			}
-			if (address >= max_size) {
-				Object bindings[] = { this.getLocation().getAbsolutePath(), max_size };
+			if (address >= MAX_DB_SIZE) {
+				Object bindings[] = { this.getLocation().getAbsolutePath(), MAX_DB_SIZE };
 				throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID,
 						CCorePlugin.STATUS_PDOM_TOO_LARGE, NLS.bind(CCorePlugin
 								.getResourceString("pdom.DatabaseTooLarge"), bindings), null)); //$NON-NLS-1$
@@ -376,13 +372,6 @@ public class Database {
 		}
 	}
 
-	/**
-	 * Returns whether this database uses dense pointers.
-	 */
-	boolean usesDensePointers() {
-		return getVersion() >= PDOM.DENSE_RECPTR_VERSION;
-	}
-
 	/**
 	 * for testing purposes, only.
 	 */
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java
index 5da5d41a224..d8121bebd61 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMArrayType.java
@@ -17,18 +17,26 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
 import org.eclipse.cdt.core.dom.ast.IType;
 import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
+import org.eclipse.cdt.internal.core.dom.parser.Value;
 import org.eclipse.cdt.internal.core.index.ArrayTypeClone;
 import org.eclipse.cdt.internal.core.index.IIndexBindingConstants;
 import org.eclipse.cdt.internal.core.index.IIndexType;
+import org.eclipse.cdt.internal.core.pdom.db.Database;
 import org.eclipse.core.runtime.CoreException;
 
 public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, ITypeContainer {
 
 	private static final int TYPE = PDOMNode.RECORD_SIZE;
+	private static final int ARRAYSIZE= TYPE + Database.PTR_SIZE;
 	@SuppressWarnings("hiding")
-	private static final int RECORD_SIZE= TYPE+4;
+	private static final int RECORD_SIZE= ARRAYSIZE + Database.PTR_SIZE;
 
+	private IType fCachedType= null;
+	private IValue fCachedValue= Value.NOT_INITIALIZED;
+	
 	public PDOMArrayType(PDOMLinkage linkage, long record) {
 		super(linkage, record);
 	}
@@ -38,7 +46,13 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
 		PDOMNode targetTypeNode = getLinkage().addType(this, type.getType());
 		if (targetTypeNode != null) {
 			long typeRec = targetTypeNode.getRecord();
-			getDB().putRecPtr(record + TYPE, typeRec);
+			final Database db = getDB();
+			db.putRecPtr(record + TYPE, typeRec);
+			IValue val= type.getSize();
+			if (val != null) {
+				long ptr= PDOMValue.store(db, linkage, val);
+				db.putRecPtr(record + ARRAYSIZE, ptr);
+			}
 		}
 	}
 
@@ -52,18 +66,33 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
 		return IIndexBindingConstants.ARRAY_TYPE;
 	}
 
-	public IASTExpression getArraySizeExpression() throws DOMException {
-		return null;
+	public IType getType() {
+		if (fCachedType == null) {
+			try {
+				PDOMNode node = getLinkage().getNode(getDB().getRecPtr(record + TYPE));
+				if (node instanceof IType) {
+					return fCachedType= (IType) node;
+				}
+			} catch (CoreException e) {
+				CCorePlugin.log(e);
+			}
+		}
+		return fCachedType;
 	}
 
-	public IType getType() {
-		try {
-			PDOMNode node = getLinkage().getNode(getDB().getRecPtr(record + TYPE));
-			return node instanceof IType ? (IType)node : null;
-		} catch (CoreException e) {
-			CCorePlugin.log(e);
-			return null;
+	
+	public IValue getSize() {
+		if (fCachedValue == Value.NOT_INITIALIZED) {
+			try {
+				final Database db = getDB();
+				long ptr= db.getRecPtr(record + ARRAYSIZE);
+				return fCachedValue= PDOMValue.restore(db, getLinkage(), ptr); 
+			} catch (CoreException e) {
+				CCorePlugin.log(e);
+			}
+			return fCachedValue= null;
 		}
+		return fCachedValue;
 	}
 
 	public boolean isSameType(IType type) {
@@ -78,7 +107,16 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
 		    return false;
 		
 		IArrayType rhs = (IArrayType) type;
-		return type1.isSameType( rhs.getType() );
+		if (type1.isSameType(rhs.getType())) {
+			IValue s1 = getSize();
+			IValue s2 = rhs.getSize();
+			if (s1 == s2)
+				return true;
+			if (s1 == null || s2 == null)
+				return false;
+			return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
+		}
+		return false;
 	}
 
 	public void setType(IType type) {
@@ -95,4 +133,9 @@ public class PDOMArrayType extends PDOMNode implements IIndexType, IArrayType, I
 		linkage.deleteType(getType(), record);
 		super.delete(linkage);
 	}
+	
+	@Deprecated
+	public IASTExpression getArraySizeExpression() throws DOMException {
+		return null;
+	}
 }