| 
25 | 25 | import static org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType.VOID;  | 
26 | 26 | import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;  | 
27 | 27 | 
 
  | 
28 |  | -import java.util.Arrays;  | 
29 |  | - | 
30 | 28 | import org.eclipse.cdt.core.CCorePlugin;  | 
31 | 29 | import org.eclipse.cdt.core.dom.IName;  | 
32 | 30 | import org.eclipse.cdt.core.dom.ast.EScopeKind;  | 
 | 31 | +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;  | 
33 | 32 | import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;  | 
34 |  | -import org.eclipse.cdt.core.dom.ast.IASTDeclaration;  | 
35 | 33 | import org.eclipse.cdt.core.dom.ast.IASTDeclarator;  | 
36 | 34 | import org.eclipse.cdt.core.dom.ast.IASTFieldReference;  | 
37 | 35 | import org.eclipse.cdt.core.dom.ast.IASTName;  | 
 | 
43 | 41 | import org.eclipse.cdt.core.dom.ast.IScope;  | 
44 | 42 | import org.eclipse.cdt.core.dom.ast.ISemanticProblem;  | 
45 | 43 | import org.eclipse.cdt.core.dom.ast.IType;  | 
46 |  | -import org.eclipse.cdt.core.dom.ast.ITypedef;  | 
47 | 44 | import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;  | 
48 | 45 | import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;  | 
49 | 46 | import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;  | 
@@ -146,58 +143,6 @@ public void createImplicitMembers() {  | 
146 | 143 | 			implicits[i++] = m;  | 
147 | 144 | 			addBinding(m);  | 
148 | 145 | 		}  | 
149 |  | - | 
150 |  | -		markInheritedConstructorsSourceBases(compTypeSpec);  | 
151 |  | -	}  | 
152 |  | - | 
153 |  | -	/**  | 
154 |  | -	 * Marks bases that serve as sources of inherited constructors.  | 
155 |  | -	 */  | 
156 |  | -	private void markInheritedConstructorsSourceBases(ICPPASTCompositeTypeSpecifier compositeTypeSpec) {  | 
157 |  | -		ICPPBase[] bases = getClassType().getBases();  | 
158 |  | -		if (bases.length == 0)  | 
159 |  | -			return;  | 
160 |  | -		IASTDeclaration[] members = compositeTypeSpec.getMembers();  | 
161 |  | -		for (IASTDeclaration member : members) {  | 
162 |  | -			if (member instanceof ICPPASTUsingDeclaration) {  | 
163 |  | -				IASTName name = ((ICPPASTUsingDeclaration) member).getName();  | 
164 |  | -				if (!(name instanceof ICPPASTQualifiedName))  | 
165 |  | -					continue;  | 
166 |  | -				ICPPASTQualifiedName qName = (ICPPASTQualifiedName) name;  | 
167 |  | -				ICPPASTNameSpecifier[] qualifier = qName.getQualifier();  | 
168 |  | -				if (qualifier.length == 0)  | 
169 |  | -					continue;  | 
170 |  | -				IBinding parent = qualifier[qualifier.length - 1].resolveBinding();  | 
171 |  | -				if (!(parent instanceof IType) || parent instanceof IProblemBinding)  | 
172 |  | -					continue;  | 
173 |  | -				if (isConstructorNameForType(qName.getLastName().getSimpleID(), (IType) parent)) {  | 
174 |  | -					IType type = SemanticUtil.getNestedType((IType) parent, TDEF);  | 
175 |  | -					for (ICPPBase base : bases) {  | 
176 |  | -						IType baseClass = base.getBaseClassType();  | 
177 |  | -						if (type.isSameType(baseClass)) {  | 
178 |  | -							if (base instanceof CPPBaseClause) {  | 
179 |  | -								((CPPBaseClause) base).setInheritedConstructorsSource(true);  | 
180 |  | -							} else {  | 
181 |  | -								CCorePlugin.log(IStatus.ERROR, "Unexpected type of base (" //$NON-NLS-1$  | 
182 |  | -										+ base.getClass().getSimpleName() + ") for '" //$NON-NLS-1$  | 
183 |  | -										+ compositeTypeSpec.getRawSignature() + "'"); //$NON-NLS-1$  | 
184 |  | -							}  | 
185 |  | -						}  | 
186 |  | -					}  | 
187 |  | -				}  | 
188 |  | -			}  | 
189 |  | -		}  | 
190 |  | -	}  | 
191 |  | - | 
192 |  | -	private static boolean isConstructorNameForType(char[] lastName, IType type) {  | 
193 |  | -		while (type instanceof IBinding) {  | 
194 |  | -			if (Arrays.equals(((IBinding) type).getNameCharArray(), lastName))  | 
195 |  | -				return true;  | 
196 |  | -			if (!(type instanceof ITypedef))  | 
197 |  | -				break;  | 
198 |  | -			type = ((ITypedef) type).getType();  | 
199 |  | -		}  | 
200 |  | -		return false;  | 
201 | 146 | 	}  | 
202 | 147 | 
 
  | 
203 | 148 | 	@Override  | 
@@ -255,7 +200,65 @@ public void addName(IASTName name, boolean adlOnly) {  | 
255 | 200 | 				addConstructor(name);  | 
256 | 201 | 				return;  | 
257 | 202 | 			}  | 
 | 203 | +		} else if (parent.getParent() instanceof ICPPASTUsingDeclaration usingDeclaration  | 
 | 204 | +				&& parent instanceof ICPPASTQualifiedName qName) {  | 
 | 205 | + | 
 | 206 | +			// In addition to normal class scope population procedure this method will be called after  | 
 | 207 | +			// ambiguity resolution for CPPASTAmbiguousUsingDeclaration to handle nominated base class constructors.  | 
 | 208 | + | 
 | 209 | +			// [C++20] 9.9 The using declaration [namespace.udecl]  | 
 | 210 | +			//   3) In a using-declaration used as a member-declaration, each using-declarator shall either  | 
 | 211 | +			//      name an enumerator or have a nested-name-specifier naming a base class of the class being defined.  | 
 | 212 | +			//      If a using-declarator names a constructor, its nested-name-specifier shall name a direct base class  | 
 | 213 | +			//      of the class being defined  | 
 | 214 | + | 
 | 215 | +			// [C++20] 6.5.4.2 Class members [class.qual]  | 
 | 216 | +			//   (2) In a lookup in which function names are not ignored  | 
 | 217 | +			//       and the nested-name-specifier nominates a class C:  | 
 | 218 | +			//   (2.1) if the name specified after the nested-name-specifier,  | 
 | 219 | +			//         when looked up in C, is the injected-class-name of C (11.1), or  | 
 | 220 | +			//   (2.2) in a using-declarator of a using-declaration (9.9) that is a member-declaration,  | 
 | 221 | +			//         if the name specified after the nested-name-specifier is the same as the  | 
 | 222 | +			//         identifier or the simple-template-id's template-name in the last component  | 
 | 223 | +			//         of the nested-name-specifier,  | 
 | 224 | +			//       the name is instead considered to name the constructor of class C.  | 
 | 225 | +			//       ...  | 
 | 226 | +			//       Such a constructor name shall be used only in the declarator-id of  | 
 | 227 | +			//       a declaration that names a constructor or in a using-declaration.  | 
 | 228 | + | 
 | 229 | +			final ICPPASTNameSpecifier[] qualifier = qName.getQualifier();  | 
 | 230 | +			final char[] lastName = name.getSimpleID();  | 
 | 231 | + | 
 | 232 | +			if (usingDeclaration.getPropertyInParent() == IASTCompositeTypeSpecifier.MEMBER_DECLARATION  | 
 | 233 | +					&& qualifier.length > 0 && qualifier[qualifier.length - 1] instanceof IASTName lastSegmentName  | 
 | 234 | +					&& CharArrayUtils.equals(lastSegmentName.getSimpleID(), lastName)) {  | 
 | 235 | +				ICPPBase[] bases = getClassType().getBases();  | 
 | 236 | +				if (bases.length > 0) {  | 
 | 237 | +					IBinding nominatedBinding = lastSegmentName.resolveBinding();  | 
 | 238 | +					if (nominatedBinding instanceof IType nominatedType  | 
 | 239 | +							&& !(nominatedType instanceof IProblemBinding)) {  | 
 | 240 | +						IType type = SemanticUtil.getNestedType(nominatedType, TDEF);  | 
 | 241 | +						for (ICPPBase base : bases) {  | 
 | 242 | +							IType baseClass = base.getBaseClassType();  | 
 | 243 | +							if (type.isSameType(baseClass)) {  | 
 | 244 | +								// Member using-declaration names direct base class constructor  | 
 | 245 | +								// Mark nominated base class as inherited constructors source and skip adding to scope  | 
 | 246 | +								if (base instanceof CPPBaseClause baseClause) {  | 
 | 247 | +									baseClause.setInheritedConstructorsSource(true);  | 
 | 248 | +								} else {  | 
 | 249 | +									ICPPASTCompositeTypeSpecifier compTypeSpec = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();  | 
 | 250 | +									CCorePlugin.log(IStatus.ERROR, "Unexpected type of base (" //$NON-NLS-1$  | 
 | 251 | +											+ base.getClass().getSimpleName() + ") for '" //$NON-NLS-1$  | 
 | 252 | +											+ compTypeSpec.getRawSignature() + "'"); //$NON-NLS-1$  | 
 | 253 | +								}  | 
 | 254 | +								return;  | 
 | 255 | +							}  | 
 | 256 | +						}  | 
 | 257 | +					}  | 
 | 258 | +				}  | 
 | 259 | +			}  | 
258 | 260 | 		}  | 
 | 261 | + | 
259 | 262 | 		super.addName(name, adlOnly);  | 
260 | 263 | 	}  | 
261 | 264 | 
 
  | 
 | 
0 commit comments