1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 14:12: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 {
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.IType;
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.ICPPFunctionType;
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() {
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.IScope;
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.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
@ -278,6 +279,9 @@ public class CPPScopeMapper {
private final Map<String, List<UsingDirectiveWrapper>> fPerName= new HashMap<>();
private final CPPASTTranslationUnit fTu;
protected CharArrayMap<IASTName[]> fClasses;
private final Map<ICPPClassTemplatePartialSpecialization, ICPPClassTemplatePartialSpecialization>
fPartialSpecs = new HashMap<>();
public CPPScopeMapper(CPPASTTranslationUnit tu) {
fTu= tu;
@ -429,4 +433,17 @@ public class CPPScopeMapper {
}
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());
}
ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
ICPPClassTemplatePartialSpecialization indexSpec = null;
if ((isDeclaration || isDefinition) &&
(partialSpec instanceof ICPPClassTemplatePartialSpecialization)) {
indexSpec = (ICPPClassTemplatePartialSpecialization) partialSpec;
partialSpec = null;
}
if (partialSpec == null) {
if (isDeclaration || isDefinition) {
if (template instanceof ICPPClassTemplate) {
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(
(ICPPClassTemplatePartialSpecialization) partialSpec);
}
@ -2500,9 +2509,9 @@ public class CPPTemplates {
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
}
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable ct,
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable template,
ICPPTemplateArgument[] args) throws DOMException {
ICPPPartialSpecialization[] pspecs = ct.getPartialSpecializations();
ICPPPartialSpecialization[] pspecs = template.getPartialSpecializations();
if (pspecs != null && pspecs.length > 0) {
final String argStr= ASTTypeUtil.getArgumentListString(args, true);
for (ICPPPartialSpecialization pspec : pspecs) {
@ -2554,6 +2563,10 @@ public class CPPTemplates {
if (bestMatch == null)
return null;
if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) {
bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch, 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.ICPPASTInitializerList;
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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
@ -559,6 +560,27 @@ public class SemanticUtil {
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) {
// Don't create a new array until it's really needed.
IType[] result = types;