1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 06:32:10 +02:00

Bug 470726 - Avoid name resolution resulting in PDOM bindings for class template partial specializations defined in the AST

Change-Id: I1e08c7430dd0478357867266648e02cc45eaa888
This commit is contained in:
Nathan Ridge 2016-12-03 23:08:49 -05:00
parent 688b358746
commit f47edd44e3
5 changed files with 89 additions and 3 deletions

View file

@ -199,4 +199,28 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
public void testFriendClassDeclaration_508338() throws Exception { public void testFriendClassDeclaration_508338() throws Exception {
checkBindings(); checkBindings();
} }
// test.h
// template <typename T>
// struct atomic;
//
// template <typename T>
// struct atomic<T*>;
// test1.cpp
// #include "test.h"
// test2.cpp *
// #include "test.h"
//
// template <typename T>
// struct atomic {};
//
// template <typename T>
// struct atomic<T*> {
// void fetch_sub();
// };
public void testClassTemplatePartialSpecialization_470726() throws Exception {
checkBindings();
}
} }

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
@ -224,4 +225,13 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
public Map<ICPPClassType, FinalOverriderMap> getFinalOverriderMapCache() { public Map<ICPPClassType, FinalOverriderMap> getFinalOverriderMapCache() {
return fFinalOverriderMapCache; return fFinalOverriderMapCache;
} }
public void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
ICPPClassTemplatePartialSpecialization astSpec) {
fScopeMapper.recordPartialSpecialization(indexSpec, astSpec);
}
public ICPPClassTemplatePartialSpecialization mapToAST(ICPPClassTemplatePartialSpecialization indexSpec) {
return fScopeMapper.mapToAST(indexSpec);
}
} }

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
@ -279,6 +280,9 @@ public class CPPScopeMapper {
private final CPPASTTranslationUnit fTu; private final CPPASTTranslationUnit fTu;
protected CharArrayMap<IASTName[]> fClasses; protected CharArrayMap<IASTName[]> fClasses;
private final Map<ICPPClassTemplatePartialSpecialization, ICPPClassTemplatePartialSpecialization>
fPartialSpecs = new HashMap<>();
public CPPScopeMapper(CPPASTTranslationUnit tu) { public CPPScopeMapper(CPPASTTranslationUnit tu) {
fTu= tu; fTu= tu;
} }
@ -429,4 +433,17 @@ public class CPPScopeMapper {
} }
return type; return type;
} }
public void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
ICPPClassTemplatePartialSpecialization astSpec) {
fPartialSpecs.put(indexSpec, astSpec);
}
public ICPPClassTemplatePartialSpecialization mapToAST(ICPPClassTemplatePartialSpecialization indexSpec) {
ICPPClassTemplatePartialSpecialization astSpec = fPartialSpecs.get(indexSpec);
if (astSpec != null) {
return astSpec;
}
return indexSpec;
}
} }

View file

@ -837,11 +837,20 @@ public class CPPTemplates {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray()); return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
} }
ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args); ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
ICPPClassTemplatePartialSpecialization indexSpec = null;
if ((isDeclaration || isDefinition) &&
(partialSpec instanceof ICPPClassTemplatePartialSpecialization)) {
indexSpec = (ICPPClassTemplatePartialSpecialization) partialSpec;
partialSpec = null;
}
if (partialSpec == null) { if (partialSpec == null) {
if (isDeclaration || isDefinition) { if (isDeclaration || isDefinition) {
if (template instanceof ICPPClassTemplate) { if (template instanceof ICPPClassTemplate) {
partialSpec = new CPPClassTemplatePartialSpecialization(id, args); partialSpec = new CPPClassTemplatePartialSpecialization(id, args);
if (template instanceof ICPPInternalClassTemplate) { if (indexSpec != null) {
SemanticUtil.recordPartialSpecialization(indexSpec,
(ICPPClassTemplatePartialSpecialization) partialSpec, id);
} else if (template instanceof ICPPInternalClassTemplate) {
((ICPPInternalClassTemplate) template).addPartialSpecialization( ((ICPPInternalClassTemplate) template).addPartialSpecialization(
(ICPPClassTemplatePartialSpecialization) partialSpec); (ICPPClassTemplatePartialSpecialization) partialSpec);
} }
@ -2500,9 +2509,9 @@ public class CPPTemplates {
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic(); return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
} }
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable ct, private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable template,
ICPPTemplateArgument[] args) throws DOMException { ICPPTemplateArgument[] args) throws DOMException {
ICPPPartialSpecialization[] pspecs = ct.getPartialSpecializations(); ICPPPartialSpecialization[] pspecs = template.getPartialSpecializations();
if (pspecs != null && pspecs.length > 0) { if (pspecs != null && pspecs.length > 0) {
final String argStr= ASTTypeUtil.getArgumentListString(args, true); final String argStr= ASTTypeUtil.getArgumentListString(args, true);
for (ICPPPartialSpecialization pspec : pspecs) { for (ICPPPartialSpecialization pspec : pspecs) {
@ -2554,6 +2563,10 @@ public class CPPTemplates {
if (bestMatch == null) if (bestMatch == null)
return null; return null;
if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) {
bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch, point);
}
return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point); return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point);
} }

View file

@ -54,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
@ -559,6 +560,27 @@ public class SemanticUtil {
return scope; return scope;
} }
public static void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
ICPPClassTemplatePartialSpecialization astSpec, IASTNode point) {
if (point != null) {
IASTTranslationUnit ast = point.getTranslationUnit();
if (ast instanceof CPPASTTranslationUnit) {
((CPPASTTranslationUnit) ast).recordPartialSpecialization(indexSpec, astSpec);
}
}
}
public static ICPPClassTemplatePartialSpecialization mapToAST(
ICPPClassTemplatePartialSpecialization indexSpec, IASTNode point) {
if (point != null) {
IASTTranslationUnit ast = point.getTranslationUnit();
if (ast instanceof CPPASTTranslationUnit) {
return ((CPPASTTranslationUnit) ast).mapToAST(indexSpec);
}
}
return indexSpec;
}
public static IType[] getSimplifiedTypes(IType[] types) { public static IType[] getSimplifiedTypes(IType[] types) {
// Don't create a new array until it's really needed. // Don't create a new array until it's really needed.
IType[] result = types; IType[] result = types;