From a7bfdd280253dfc94379d83b29ffd66e16a59464 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <76685079+i-garrison@users.noreply.github.com>
Date: Fri, 29 Dec 2023 00:41:44 +0300
Subject: [PATCH] Fix struct declaration introducing name in namespace scope
 (#587)

When AST is used to resolve binding for class-name and elaborated-type-specifier
is found matching [basic.lookup.elab] rule introducing the class-name, behavior
of CPPSemantics.resolveAmbiguities() is different in presence of index.

If there is no index, CPPVisitor.createBinding() for ICPPASTElaboratedTypeSpecifier
creates binding for class-name as introducing the name. When later lookup finds
this binding all is good because binding is declared before the use site.

If index is available, lookup for class-name fails in AST too but now matching
entry is found in the AST index. When later lookup finds this index binding
CPPSemantics.declaredBefore() returns false because it does not look in
AST index and only checks project index.

To fix this additionally check if ICPPClassType object is in AST index,
as we already do for ICPPConstructor. This way declaredBefore() does almost
the same thing as isReachableFromAst() and lookup succeeds returning the
same binding from index.
---
 .../IndexCPPBindingResolutionBugsTest.java    | 35 ++++++++++++++++++-
 .../parser/cpp/semantics/CPPSemantics.java    |  4 +--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugsTest.java
index 41b09277131..7007d2d2c64 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugsTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionBugsTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2023 Wind River Systems, Inc. and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -1414,4 +1414,37 @@ public abstract class IndexCPPBindingResolutionBugsTest extends IndexBindingReso
 	public void testIssue_254() throws Exception {
 		checkBindings();
 	}
+
+	// // no header needed
+
+	//	void introducing_in_global_ns(struct struct_in_global_ns *arg) {}
+	//
+	//	class UsingStructFromGlobalNamespace {
+	//		struct_in_global_ns *p;
+	//	};
+	//
+	//	UsingStructFromGlobalNamespace usingStructFromGlobalNs;
+	//
+	//	namespace named {
+	//	void introducing_in_named_ns(struct struct_in_named_ns *arg) {}
+	//	}
+	//
+	//	class UsingStructFromNamespaceNs {
+	//		named::struct_in_named_ns *p;
+	//	};
+	//
+	//	UsingStructFromNamespaceNs usingStructFromNamespaceNs;
+	//
+	//	namespace {
+	//	void introducing_in_anonymous_ns(struct struct_in_anonymous_ns *arg) {}
+	//	}
+	//
+	//	class UsingStructFromAnonymousNs {
+	//		struct_in_anonymous_ns *p;
+	//	};
+	//
+	//	UsingStructFromAnonymousNs usingStructFromAnonymousNs;
+	public void testStructNameIntroducedInNamespace() throws Exception {
+		checkBindings();
+	}
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 69a3591d454..e767efafa01 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2016 IBM Corporation and others.
+ * Copyright (c) 2004, 2023 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -2513,7 +2513,7 @@ public class CPPSemantics {
 				IIndexFileSet indexFileSet = tu.getIndexFileSet();
 				if (indexFileSet != null && indexFileSet.containsDeclaration(indexBinding)) {
 					return true;
-				} else if (indexBinding instanceof ICPPConstructor) {
+				} else if (indexBinding instanceof ICPPConstructor || indexBinding instanceof ICPPClassType) {
 					IIndexFileSet astFileSet = tu.getASTFileSet();
 					return astFileSet != null && astFileSet.containsDeclaration(indexBinding);
 				} else {