From 304d72c17d9d2604fd6b7f5bc89586f12a4449d9 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Tue, 31 Jul 2012 18:43:37 -0700 Subject: [PATCH] Bug 299911. Few fixes and a test that is currently failing due to a NPE. --- .../parser/tests/ast2/AST2TemplateTests.java | 44 +++++++++++++++++++ .../cdt/internal/core/dom/parser/Value.java | 8 +++- .../core/dom/parser/cpp/semantics/EvalID.java | 29 ++++++++---- 3 files changed, 70 insertions(+), 11 deletions(-) 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 77ae63e3a0a..c7e8539f991 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 @@ -5591,6 +5591,50 @@ public class AST2TemplateTests extends AST2BaseTest { parseAndCheckBindings(); } + // class A; + // class B; + // + // template + // struct bool_constant { + // static const bool value = bool_value; + // }; + // + // template + // struct ImplicitlyConvertible { + // static From MakeFrom(); + // + // static char Helper(To); + // static char (&Helper(...))[2]; + // + // static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; + // }; + // + // template + // struct IsAorB + // : public bool_constant< + // ImplicitlyConvertible::value || + // ImplicitlyConvertible::value> { + // }; + // + // namespace ns { + // + // template + // class C { + // }; + // + // template + // void f(V a); + // + // } // namespace ns + // + // void test() { + // ns::C::value> a; + // f(a); + // }; + public void _testDependentExpressions() throws Exception { + parseAndCheckBindings(); + } + // template void* foo(int); // template void f(T t) { // if (T* i = foo<0>(0)) 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 8f1b1295048..44e298d51fb 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 @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; @@ -350,9 +351,10 @@ public class Value implements IValue { IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) exp; switch (typeIdEx.getOperator()) { case IASTTypeIdExpression.op_sizeof: - final IType type; ASTTranslationUnit ast = (ASTTranslationUnit) typeIdEx.getTranslationUnit(); - type = ast.createType(typeIdEx.getTypeId()); + final IType type = ast.createType(typeIdEx.getTypeId()); + if (type instanceof ICPPUnknownType) + return null; SizeofCalculator calculator = ast.getSizeofCalculator(); SizeAndAlignment info = calculator.sizeAndAlignment(type); if (info == null) @@ -401,6 +403,8 @@ public class Value implements IValue { final IASTExpression operand = exp.getOperand(); if (operand != null) { IType type = operand.getExpressionType(); + if (type instanceof ICPPUnknownType) + return null; ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit(); SizeofCalculator calculator = ast.getSizeofCalculator(); SizeAndAlignment info = calculator.sizeAndAlignment(type); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 296ac5c9d46..3e5971d1a9c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; @@ -291,21 +292,20 @@ public class EvalID extends CPPEvaluation { if (fieldOwner != null) { fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point); } + IBinding nameOwner = fNameOwner; - if (fNameOwner instanceof ICPPTemplateParameter) { - ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner); + if (nameOwner instanceof ICPPTemplateParameter) { + ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) nameOwner); if (argument != null) { IType type = argument.getTypeValue(); if (type instanceof IBinding) nameOwner = (IBinding) type; } - } else if (fNameOwner instanceof ICPPUnknownBinding) { - try { - nameOwner = CPPTemplates.resolveUnknown((ICPPUnknownBinding) fNameOwner, tpMap, - packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); - } + } else if (nameOwner instanceof ICPPUnknownBinding) { + nameOwner = resolveUnknown(nameOwner, tpMap, packOffset, within, point); + } else if (nameOwner instanceof ICPPClassTemplate) { + nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner), + tpMap, packOffset, within, point); } if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) return this; @@ -316,6 +316,17 @@ public class EvalID extends CPPEvaluation { return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); } + IBinding resolveUnknown(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, + ICPPClassSpecialization within, IASTNode point) { + try { + binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) binding, tpMap, + packOffset, within, point); + } catch (DOMException e) { + CCorePlugin.log(e); + } + return binding; + } + private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, IASTNode point) { LookupData data = new LookupData(fName, templateArgs, point);