From 3fa775ca1d16506625a5f96baba390460ffae1b3 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 5 Dec 2012 21:28:31 -0500 Subject: [PATCH 01/19] Bug 388623 - [regression] Error involving dependent expressions Change-Id: I5d32ca41b7d87d0f220b192889e3908a0f7c84fd Reviewed-on: https://git.eclipse.org/r/9057 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 18 +++++++++++++++++- .../dom/parser/cpp/semantics/EvalBinding.java | 11 +++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) 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 372773a006d..e07b132667a 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 @@ -6883,7 +6883,23 @@ public class AST2TemplateTests extends AST2BaseTest { assertEquals("bool", ASTTypeUtil.getType(td.getType())); ah.assertProblem("B::type", "type"); } - + + // template + // struct is_convertible { + // static char check(From); + // static From from; + // static const int value = sizeof(check(from)); + // }; + // template + // struct S { + // typedef int type; + // }; + // struct Cat {}; + // typedef S::value>::type T; + public void testDependentExpressionInvolvingField_388623() throws Exception { + parseAndCheckBindings(getAboveComment(), CPP, true); + } + // struct S { // typedef int a_type; // }; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index 783547f31c8..ea7f4f82be7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; 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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; @@ -351,6 +352,16 @@ public class EvalBinding extends CPPEvaluation { binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, binding, point); } + } else if (binding instanceof ICPPField) { + IBinding owner = binding.getOwner(); + if (owner instanceof ICPPClassTemplate) { + owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), + tpMap, packOffset, within, point); + } + if (owner instanceof ICPPClassSpecialization) { + binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, + binding, point); + } } if (binding == fBinding) return this; From 22c8d75b1a719f0fa9ed7b8a8612087f4b95eae7 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 6 Dec 2012 15:24:01 -0800 Subject: [PATCH 02/19] Bug 395019 - Error when using __is_base_of Change-Id: Ife9a63658555b7a94246b0d938dd139bb8d0ab08 Reviewed-on: https://git.eclipse.org/r/9060 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../cdt/core/parser/tests/ast2/AST2CPPTests.java | 16 ++++++++++++++-- .../cdt/internal/core/dom/parser/Value.java | 4 +++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index c58b157fdcc..97b8e1f9f70 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -9953,8 +9953,8 @@ public class AST2CPPTests extends AST2BaseTest { // template struct CT {}; // typedef int TD; // bool operator==(S1 a, int r ); - // static const int x = sizeof(CT((TD * (CT::*)) 0 )); - // template bool operator==(S1 a, const CT& r ); + // static const int x = sizeof(CT((TD * (CT::*)) 0)); + // template bool operator==(S1 a, const CT& r); public void testOrderInAmbiguityResolution_390759() throws Exception { parseAndCheckBindings(); } @@ -9973,4 +9973,16 @@ public class AST2CPPTests extends AST2BaseTest { public void testADLForFunctionObject_388287() throws Exception { parseAndCheckBindings(); } + + // template struct A {}; + // template <> + // struct A { + // typedef int type; + // }; + // struct S {}; + // const bool b = __is_base_of(S, int); + // typedef A::type T; + public void testIsBaseOf_395019() throws Exception { + parseAndCheckBindings(getAboveComment(), CPP, true); + } } 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 79fb138efd2..40e95a7be0b 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 @@ -334,8 +334,10 @@ public class Value implements IValue { IType type1, IType type2, IASTNode point) { switch (operator) { case __is_base_of: - if (type1 instanceof ICPPClassType && type1 instanceof ICPPClassType) { + if (type1 instanceof ICPPClassType && type2 instanceof ICPPClassType) { return ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1) ? 1 : 0; + } else { + return 0; } } return VALUE_CANNOT_BE_DETERMINED; From f2d8b90495f81fa69c619904169263ff0cacc484 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 6 Dec 2012 15:51:14 -0800 Subject: [PATCH 03/19] Bug 395247 - Error involving variadic constructor Change-Id: Ia5f911e0a80a5372943a505b814c333c53a5a602 Reviewed-on: https://git.eclipse.org/r/9061 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/tests/ast2/AST2TemplateTests.java | 14 +++++++++++++- .../dom/parser/cpp/semantics/CPPSemantics.java | 3 +++ .../core/dom/parser/cpp/semantics/LookupData.java | 2 +- 3 files changed, 17 insertions(+), 2 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 e07b132667a..868304db03e 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 @@ -6897,7 +6897,7 @@ public class AST2TemplateTests extends AST2BaseTest { // struct Cat {}; // typedef S::value>::type T; public void testDependentExpressionInvolvingField_388623() throws Exception { - parseAndCheckBindings(getAboveComment(), CPP, true); + parseAndCheckBindings(); } // struct S { @@ -6911,4 +6911,16 @@ public class AST2TemplateTests extends AST2BaseTest { public void testSFINAEInDefaultArgument() throws Exception { parseAndCheckBindings(); } + + // template + // struct M { + // template + // M(Args...); + // }; + // void foo() { + // new M((int*)0, 0); + // } + public void testVariadicConstructor_395247() throws Exception { + parseAndCheckBindings(); + } } 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 dec5a062f90..eeb245d2399 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 @@ -417,6 +417,9 @@ public class CPPSemantics { if (cls instanceof ICPPUnknownBinding) { binding= new CPPUnknownConstructor(cls); } else { + // Do not interpret template arguments to a template class as being + // explicit template arguments to its templated constructor. + data.fTemplateArguments = null; binding= CPPSemantics.resolveFunction(data, ClassTypeHelper.getConstructors(cls, lookupPoint), true); } } catch (DOMException e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index bb4677269e0..eb52bce8ca3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -79,7 +79,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; * Context data for IASTName lookup */ public class LookupData extends ScopeLookupData { - final public ICPPTemplateArgument[] fTemplateArguments; + public ICPPTemplateArgument[] fTemplateArguments; public Map> usingDirectives= Collections.emptyMap(); /** Used to ensure we don't visit things more than once. */ From b2238a81f489d728d8bea2cec1aded0208c372ce Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 5 Dec 2012 15:11:29 -0800 Subject: [PATCH 04/19] Bug 395873 - [breakpoints] breakpointContribution conditional contribution doesn't check for missing property Change-Id: If75c23f393c1fc983de1ddd4ddea3b003c1ec1b3 Reviewed-on: https://git.eclipse.org/r/9050 Reviewed-by: Mikhail Khodjaiants IP-Clean: Mikhail Khodjaiants Tested-by: Mikhail Khodjaiants Reviewed-by: Elena Laskavaia --- .../breakpoints/DefaultCBreakpointUIContribution.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java index 00d5b6107ba..ce5529ed9ab 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/DefaultCBreakpointUIContribution.java @@ -124,13 +124,10 @@ class DefaultCBreakpointUIContribution implements ICBreakpointsUIContribution { @Override public boolean isApplicable(Map properties) { - for (Object key : properties.keySet()) { - String value = conditions.get(key); - if (value != null) { - String realValue = (String) properties.get(key); - if (!value.equals(realValue)) { - return false; - } + for (Object key : conditions.keySet()) { + Object bpValue = properties.get(key); + if ( bpValue == null || !bpValue.equals(conditions.get(key)) ) { + return false; } } return true; From 8cf540fbf6f9d5bcb5a8387b63bfd6c281f0784a Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 5 Dec 2012 22:15:23 -0500 Subject: [PATCH 05/19] Bug 365498 - Strange warning placement for defaulted constructor Change-Id: Ia80fbd9694310aff0900e80cb9175e101c653604 Reviewed-on: https://git.eclipse.org/r/9065 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../checkers/ClassMembersInitializationCheckerTest.java | 9 +++++++++ .../internal/core/dom/parser/cpp/GNUCPPSourceParser.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java index 0f1faaeba99..ed41608005c 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java @@ -577,4 +577,13 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { runOnProject(); checkNoErrors(); } + + // struct S { + // int i; + // S() = default; + // }; + public void testBug365498_defaultedConstructor() throws Exception{ + loadCodeAndRun(getAboveComment()); + checkErrorLine(3); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index b7082f7aa78..6f3083e69b8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -2528,7 +2528,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { default: throwBacktrack(kind); } - return adjustEndOffset(fdef, consume(IToken.tSEMI).getEndOffset()); + return setRange(fdef, firstOffset, consume(IToken.tSEMI).getEndOffset()); } if (LT(1) == IToken.tCOLON) { From 05d97a6e80ee938115a0f9390402632906c504b6 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Thu, 6 Dec 2012 17:02:51 -0500 Subject: [PATCH 06/19] Log exception when no program for launch is found. --- .../src/org/eclipse/cdt/core/CommandLauncher.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncher.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncher.java index fc4b097932c..a5e0555717e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncher.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CommandLauncher.java @@ -190,6 +190,8 @@ public class CommandLauncher implements ICommandLauncher { fCommandArgs[0] = command; // to print original command on the console fErrorMessage = ""; //$NON-NLS-1$ } catch (IOException e) { + CCorePlugin.log(e); + if (isFound == null) { IPath location = PathUtil.findProgramLocation(command, envPathValue); isFound = location != null; From 7582b75465243c1e821a48604e1d8701fc91986c Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Fri, 7 Dec 2012 10:23:33 -0500 Subject: [PATCH 07/19] Fix unit test case failure due to warning in .log --- .../scannerconfig2/DefaultRunSIProvider.java | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java index 70773c52503..f947282bb18 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/DefaultRunSIProvider.java @@ -123,27 +123,29 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider { ICommandLauncher launcher = new CommandLauncher(); launcher.setProject(project); - String[] comandLineOptions = getCommandLineOptions(); IPath program = getCommandToLaunch(); - URI workingDirectoryURI = MakeBuilderUtil.getBuildDirectoryURI(project, MakeBuilder.BUILDER_ID); - String[] envp = setEnvironment(launcher, env); - - ErrorParserManager epm = new ErrorParserManager(project, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID}); - - List parsers = new ArrayList(); - IConsoleParser parser = ScannerInfoConsoleParserFactory.getESIConsoleParser(project, context, providerId, buildInfo, collector, markerGenerator); - if (parser != null) { - parsers.add(parser); + if (! program.isEmpty()) { + String[] comandLineOptions = getCommandLineOptions(); + URI workingDirectoryURI = MakeBuilderUtil.getBuildDirectoryURI(project, MakeBuilder.BUILDER_ID); + String[] envp = setEnvironment(launcher, env); + + ErrorParserManager epm = new ErrorParserManager(project, markerGenerator, new String[] {GMAKE_ERROR_PARSER_ID}); + + List parsers = new ArrayList(); + IConsoleParser parser = ScannerInfoConsoleParserFactory.getESIConsoleParser(project, context, providerId, buildInfo, collector, markerGenerator); + if (parser != null) { + parsers.add(parser); + } + + buildRunnerHelper.setLaunchParameters(launcher, program, comandLineOptions, workingDirectoryURI, envp ); + buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + buildRunnerHelper.greeting(MakeMessages.getFormattedString("ExternalScannerInfoProvider.Greeting", project.getName())); //$NON-NLS-1$ + buildRunnerHelper.build(new SubProgressMonitor(monitor, TICKS_EXECUTE_PROGRAM, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + buildRunnerHelper.close(); + buildRunnerHelper.goodbye(); } - buildRunnerHelper.setLaunchParameters(launcher, program, comandLineOptions, workingDirectoryURI, envp ); - buildRunnerHelper.prepareStreams(epm, parsers, console, new SubProgressMonitor(monitor, TICKS_STREAM_PROGRESS_MONITOR, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - - buildRunnerHelper.greeting(MakeMessages.getFormattedString("ExternalScannerInfoProvider.Greeting", project.getName())); //$NON-NLS-1$ - buildRunnerHelper.build(new SubProgressMonitor(monitor, TICKS_EXECUTE_PROGRAM, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); - buildRunnerHelper.close(); - buildRunnerHelper.goodbye(); - } catch (Exception e) { MakeCorePlugin.log(e); } finally { From 032c010a82df819e49dabe341e28f68fac60bfd5 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 6 Dec 2012 23:17:52 -0500 Subject: [PATCH 08/19] Bug 395018 - False 'member was not initalized in this constructor' warning for defaulted copy/move constructor Change-Id: Ib7800e46174b195fd15daef923abfff482fd3aff Reviewed-on: https://git.eclipse.org/r/9059 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../ClassMembersInitializationChecker.java | 13 ++-- ...ClassMembersInitializationCheckerTest.java | 26 +++++-- .../cdt/core/dom/ast/cpp/SemanticQueries.java | 67 +++++++++++++++++++ 3 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/SemanticQueries.java diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java index a22cc9c15ba..17c48840337 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java @@ -8,6 +8,7 @@ * Contributors: * Anton Gorenkov - initial implementation * Marc-Andre Laperle + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.codan.internal.checkers; @@ -44,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; @@ -254,16 +256,19 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker { IBinding binding = functionDefinition.getDeclarator().getName().resolveBinding(); if (binding instanceof ICPPConstructor) { ICPPConstructor constructor = (ICPPConstructor) binding; - if (constructor.getClassOwner().getKey() != ICompositeType.k_union) { - return constructor; - } + // Skip defaulted copy and move constructors. + if (functionDefinition.isDefaulted() && SemanticQueries.isCopyOrMoveConstructor(constructor)) + return null; + if (constructor.getClassOwner().getKey() == ICompositeType.k_union) + return null; + return constructor; } } return null; } } - + @Override public void initPreferences(IProblemWorkingCopy problem) { super.initPreferences(problem); diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java index ed41608005c..e318918b84c 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java @@ -8,6 +8,7 @@ * Contributors: * Anton Gorenkov - initial implementation * Marc-Andre Laperle + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.codan.core.internal.checkers; @@ -578,12 +579,27 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { checkNoErrors(); } - // struct S { - // int i; - // S() = default; - // }; - public void testBug365498_defaultedConstructor() throws Exception{ + // struct S { + // int i; + // S() = default; + // }; + public void testBug365498_defaultedConstructor() throws Exception { loadCodeAndRun(getAboveComment()); checkErrorLine(3); } + + // struct S { + // S(S&) = default; + // S(const S&) = default; + // S(volatile S&) = default; + // S(const volatile S&) = default; + // S(S&&) = default; + // S(const S&&) = default; + // S(volatile S&&) = default; + // S(const volatile S&&) = default; + // }; + public void testBug395018_defaultedCopyOrMoveConstructor() throws Exception { + loadCodeAndRun(getAboveComment()); + checkNoErrors(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/SemanticQueries.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/SemanticQueries.java new file mode 100644 index 00000000000..60fd014f6c4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/SemanticQueries.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2012 Nathan Ridge. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; + +/** + * @since 5.5 + */ +public class SemanticQueries { + + public static boolean isCopyOrMoveConstructor(ICPPConstructor constructor) { + return isCopyOrMoveConstructor(constructor, CopyOrMoveConstructorKind.COPY_OR_MOVE); + } + + public static boolean isMoveConstructor(ICPPConstructor constructor) { + return isCopyOrMoveConstructor(constructor, CopyOrMoveConstructorKind.MOVE); + } + + public static boolean isCopyConstructor(ICPPConstructor constructor) { + return isCopyOrMoveConstructor(constructor, CopyOrMoveConstructorKind.COPY); + } + + private enum CopyOrMoveConstructorKind { COPY, MOVE, COPY_OR_MOVE } + + private static boolean isCopyOrMoveConstructor(ICPPConstructor constructor, CopyOrMoveConstructorKind kind) { + // 12.8/2-3 [class.copy]: + // "A non-template constructor for class X is a copy [move] constructor + // if its first parameter is of type X&[&], const X&[&], volatile X&[&] + // or const volatile X&[&], and either there are no other parametrs or + // else all other parametrs have default arguments." + if (constructor instanceof ICPPFunctionTemplate) + return false; + if (!isCallableWithNumberOfArguments(constructor, 1)) + return false; + IType firstArgumentType = constructor.getType().getParameterTypes()[0]; + firstArgumentType = SemanticUtil.getNestedType(firstArgumentType, TDEF); + if (!(firstArgumentType instanceof ICPPReferenceType)) + return false; + ICPPReferenceType firstArgReferenceType = (ICPPReferenceType) firstArgumentType; + boolean isRvalue = firstArgReferenceType.isRValueReference(); + if (isRvalue && kind == CopyOrMoveConstructorKind.COPY) + return false; + if (!isRvalue && kind == CopyOrMoveConstructorKind.MOVE) + return false; + firstArgumentType = firstArgReferenceType.getType(); + firstArgumentType = SemanticUtil.getNestedType(firstArgumentType, CVTYPE); + return firstArgumentType.isSameType(constructor.getClassOwner()); + } + + private static boolean isCallableWithNumberOfArguments(ICPPFunction function, int numArguments) { + return function.getParameters().length >= numArguments + && function.getRequiredArgumentCount() <= numArguments; + } +} From d159cd9545c77d98407e55407c647f078913e900 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 6 Dec 2012 23:23:59 -0500 Subject: [PATCH 09/19] Bug 379631 - code-completion of functions in using-declarations Change-Id: Ifae9e0e790629e03c1ad93988ea535e42373d448 Reviewed-on: https://git.eclipse.org/r/9066 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../text/contentassist2/CompletionTests.java | 15 ++++- .../internal/ui/text/CHeuristicScanner.java | 30 ++++++++- .../DOMCompletionProposalComputer.java | 65 ++++++++++++++++--- 3 files changed, 97 insertions(+), 13 deletions(-) diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 49b0c3e24b3..da4abfe8443 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -12,10 +12,9 @@ * IBM Corporation * Sergey Prigogin (Google) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) + * Nathan Ridge *******************************************************************************/ -package org.eclipse.cdt.ui.tests.text.contentassist2; - -import java.io.File; +package org.eclipse.cdt.ui.tests.text.contentassist2;import java.io.File; import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -28,6 +27,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.cdt.core.testplugin.TestScannerProvider; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +; /** * A collection of code completion tests. @@ -1365,4 +1365,13 @@ public class CompletionTests extends AbstractContentAssistTest { final String[] expected= { "__builtin_va_arg(ap, type)" }; assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); } + + // namespace N { + // void foo(int); + // } + // using N::f/*cursor*/ + public void testUsingDeclaration_Bug379631() throws Exception { + final String[] expected= { "foo;" }; + assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CHeuristicScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CHeuristicScanner.java index 4a8a10c2c67..db8e3f30b1c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CHeuristicScanner.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CHeuristicScanner.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation * Sergey Prigogin, Google * Anton Leherbauer (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; @@ -1202,4 +1203,31 @@ public final class CHeuristicScanner implements Symbols { } } + /** + * A simplified interface to CHeuristicScanner's + * nextToken() and previousToken() methods. + */ + public static class TokenStream { + private CHeuristicScanner fScanner; + private int fPos; + private final int fDocumentLength; + + public TokenStream(IDocument document, int startPos) { + fScanner = new CHeuristicScanner(document); + fPos = startPos; + fDocumentLength = document.getLength(); + } + + public int nextToken() { + int result = fScanner.nextToken(fPos, fDocumentLength); + fPos = fScanner.getPosition(); + return result; + } + + public int previousToken() { + int result = fScanner.previousToken(fPos, 0); + fPos = fScanner.getPosition(); + return result; + } + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java index 1fdb266723d..54dacc3d7f5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 QNX Software Systems and others. + * Copyright (c) 2007, 2012 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ * Anton Leherbauer (Wind River Systems) * Sergey Prigogin (Google) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.contentassist; @@ -83,6 +84,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.AccessContext; import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; +import org.eclipse.cdt.internal.ui.text.CHeuristicScanner; +import org.eclipse.cdt.internal.ui.text.Symbols; import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; /** @@ -91,7 +94,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; * @author Bryan Wilkinson */ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer { - /** * Default constructor is required (executable extension). */ @@ -152,6 +154,40 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer return proposals; } + /** + * Checks whether the invocation offset is inside a using-declaration. + * + * @param context the invocation context + * @return {@code true} if the invocation offset is inside a using-declaration + */ + private boolean inUsingDeclaration(CContentAssistInvocationContext context) { + IDocument doc = context.getDocument(); + int offset = context.getInvocationOffset(); + + // Look at the tokens preceding the invocation offset. + CHeuristicScanner.TokenStream tokenStream = new CHeuristicScanner.TokenStream(doc, offset); + int token = tokenStream.previousToken(); + + // There may be a partially typed identifier which is being completed. + if (token == Symbols.TokenIDENT) + token = tokenStream.previousToken(); + + // Before that, there may be any number of "namespace::" token pairs. + while (token == Symbols.TokenDOUBLECOLON) { + token = tokenStream.previousToken(); + if (token == Symbols.TokenUSING) { // there could also be a leading "::" for global namespace + return true; + } else if (token != Symbols.TokenIDENT) { + return false; + } else { + token = tokenStream.previousToken(); + } + } + + // Before that, there must be a "using" token. + return token == Symbols.TokenUSING; + } + /** * Test whether the invocation offset is inside or before the preprocessor directive keyword. * @@ -377,10 +413,11 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer StringBuilder repStringBuff = new StringBuilder(); repStringBuff.append(function.getName()); + repStringBuff.append('('); StringBuilder dispargs = new StringBuilder(); // for the dispargString - StringBuilder idargs = new StringBuilder(); // for the idargString + StringBuilder idargs = new StringBuilder(); // for the idargString boolean hasArgs = true; String returnTypeStr = null; IParameter[] params = function.getParameters(); @@ -388,12 +425,12 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer for (int i = 0; i < params.length; ++i) { IType paramType = params[i].getType(); if (i > 0) { - dispargs.append(','); - idargs.append(','); - } + dispargs.append(','); + idargs.append(','); + } dispargs.append(ASTTypeUtil.getType(paramType, false)); - idargs.append(ASTTypeUtil.getType(paramType, false)); + idargs.append(ASTTypeUtil.getType(paramType, false)); String paramName = params[i].getName(); if (paramName != null && paramName.length() > 0) { dispargs.append(' '); @@ -439,7 +476,17 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer idStringBuff.append(')'); String idString = idStringBuff.toString(); - repStringBuff.append(')'); + // In a using declaration, emitting parentheses after the function + // name is useless, since the user will just have to delete them. + // Instead, emitting a semicolon is useful. + boolean inUsingDeclaration = inUsingDeclaration(context); + if (inUsingDeclaration) { + repStringBuff.setLength(repStringBuff.length() - 1); // Remove opening parenthesis + repStringBuff.append(';'); + } else { + repStringBuff.append(')'); + } + String repString = repStringBuff.toString(); final int relevance = function instanceof ICPPMethod ? @@ -447,7 +494,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer CCompletionProposal proposal = createProposal(repString, dispString, idString, context.getCompletionNode().getLength(), image, baseRelevance + relevance, context); if (!context.isContextInformationStyle()) { - int cursorPosition = hasArgs ? (repString.length() - 1) : repString.length(); + int cursorPosition = (!inUsingDeclaration && hasArgs) ? (repString.length() - 1) : repString.length(); proposal.setCursorPosition(cursorPosition); } From 63a7756b6c33914128d751c6008d0aa6cc497eb2 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 6 Dec 2012 23:19:56 -0500 Subject: [PATCH 10/19] Bug 395243 - Error involving dependent expressions Change-Id: Ie15f8415f930248c54041f0f2e60149874e670e8 Reviewed-on: https://git.eclipse.org/r/9062 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 34 +++++++++++++---- .../dom/parser/cpp/CPPDeferredFunction.java | 31 +++++++++++----- .../dom/parser/cpp/CPPUnknownConstructor.java | 8 +++- .../parser/cpp/semantics/CPPFunctionSet.java | 9 +++-- .../parser/cpp/semantics/CPPSemantics.java | 9 +++-- .../parser/cpp/semantics/CPPTemplates.java | 32 ++++++---------- .../parser/cpp/semantics/EvalFunctionSet.java | 3 +- .../core/dom/parser/cpp/semantics/EvalID.java | 37 ++++++++++++------- 8 files changed, 102 insertions(+), 61 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 868304db03e..915a4c94767 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 @@ -12,6 +12,7 @@ * Andrew Ferguson (Symbian) * Sergey Prigogin (Google) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -6912,15 +6913,32 @@ public class AST2TemplateTests extends AST2BaseTest { parseAndCheckBindings(); } - // template - // struct M { - // template - // M(Args...); - // }; - // void foo() { - // new M((int*)0, 0); - // } + // template + // struct M { + // template + // M(Args...); + // }; + // void foo() { + // new M((int*)0, 0); + // } public void testVariadicConstructor_395247() throws Exception { parseAndCheckBindings(); } + + // template struct Int {}; + // template + // struct identity { + // typedef T type; + // }; + // template + // char waldo(T); + // template + // struct S { + // F f; + // static const int value = sizeof(waldo(f)); + // }; + // typedef identity::value>>::type reference; + public void testDependentExpressions_395243() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java index daf282b6106..108f60c3d83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java @@ -8,12 +8,11 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -30,19 +29,33 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY); - public static ICPPFunction createForSample(IFunction sample) throws DOMException { - if (sample instanceof ICPPConstructor) - return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner()); - - final IBinding owner = sample.getOwner(); - return new CPPDeferredFunction(owner, sample.getNameCharArray()); + /** + * Creates a CPPDeferredFunction given a set of overloaded functions + * (some of which may be templates) that the function might resolve to. + * At least one candidate must be provided. + * + * @param candidates a set of overloaded functions, some of which may be templates + * @return the constructed CPPDeferredFunction + */ + public static ICPPFunction createForCandidates(ICPPFunction... candidates) { + if (candidates[0] instanceof ICPPConstructor) + return new CPPUnknownConstructor(((ICPPConstructor) candidates[0]).getClassOwner(), candidates); + + final IBinding owner = candidates[0].getOwner(); + return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates); } private final IBinding fOwner; + private final ICPPFunction[] fCandidates; - public CPPDeferredFunction(IBinding owner, char[] name) { + public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) { super(name); fOwner= owner; + fCandidates = candidates; + } + + public ICPPFunction[] getCandidates() { + return fCandidates; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java index 0dd63fc488a..94b59961cfa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java @@ -8,11 +8,13 @@ * Contributors: * Markus Schorn - initial API and implementation * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ICPPFunction; /** * Represents a reference to a constructor (instance), which cannot be resolved because @@ -21,7 +23,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; public class CPPUnknownConstructor extends CPPDeferredFunction implements ICPPConstructor { public CPPUnknownConstructor(ICPPClassType owner) { - super(owner, owner.getNameCharArray()); + super(owner, owner.getNameCharArray(), null); + } + + public CPPUnknownConstructor(ICPPClassType owner, ICPPFunction[] candidates) { + super(owner, owner.getNameCharArray(), candidates); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java index 8d1842259e7..0eef3cfa56e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -31,7 +32,7 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { private final ICPPFunction[] fBindings; private final IASTName fName; private final ICPPTemplateArgument[] fTemplateArguments; - + public CPPFunctionSet(ICPPFunction[] bindingList, ICPPTemplateArgument[] args, IASTName name) { fBindings = ArrayUtil.removeNulls(bindingList); fTemplateArguments= args; @@ -89,10 +90,10 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { fName.setBinding(selectedFunction); } } - + public void setToUnknown() { if (fName != null) { - fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray())); + fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray(), fBindings)); } } } 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 eeb245d2399..58e8713a21f 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 @@ -13,6 +13,7 @@ * Sergey Prigogin (Google) * Mike Kucera (IBM) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -451,7 +452,7 @@ public class CPPSemantics { final ASTNodeProperty namePropertyInParent = name.getPropertyInParent(); if (binding == null && data.skippedScope != null) { if (data.hasFunctionArguments()) { - binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID()); + binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID(), null); } else { if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) { binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID()); @@ -2395,7 +2396,7 @@ public class CPPSemantics { if (viableCount == 1) return fns[0]; setTargetedFunctionsToUnknown(argTypes); - return CPPDeferredFunction.createForSample(fns[0]); + return CPPDeferredFunction.createForCandidates(fns); } IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good @@ -2403,7 +2404,7 @@ public class CPPSemantics { // Loop over all functions List potentialCosts= null; - IFunction unknownFunction= null; + ICPPFunction unknownFunction= null; final CPPASTTranslationUnit tu = data.getTranslationUnit(); for (ICPPFunction fn : fns) { if (fn == null) @@ -2455,7 +2456,7 @@ public class CPPSemantics { return null; setTargetedFunctionsToUnknown(argTypes); - return CPPDeferredFunction.createForSample(unknownFunction); + return CPPDeferredFunction.createForCandidates(fns); } if (ambiguousFunctions != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 877e605ba48..39e5db03281 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -11,6 +11,7 @@ * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -163,7 +164,6 @@ public class CPPTemplates { static final int PACK_SIZE_DEFER = -1; static final int PACK_SIZE_FAIL = -2; static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; - private static final ICPPFunction[] NO_FUNCTIONS = {}; static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } /** @@ -1726,18 +1726,12 @@ public class CPPTemplates { requireTemplate= false; if (func instanceof ICPPFunctionTemplate) { - ICPPFunctionTemplate template= (ICPPFunctionTemplate) func; - try { - if (containsDependentType(fnArgs)) - return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)}; + if (containsDependentType(fnArgs)) + return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)}; - if (requireTemplate) { - if (hasDependentArgument(tmplArgs)) - return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)}; - } - } catch (DOMException e) { - return NO_FUNCTIONS; - } + if (requireTemplate && hasDependentArgument(tmplArgs)) + return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)}; + haveTemplate= true; break; } @@ -1803,15 +1797,11 @@ public class CPPTemplates { // Extract template arguments and parameter types. if (!checkedForDependentType) { - try { - if (isDependentType(conversionType)) { - inst= CPPDeferredFunction.createForSample(template); - done= true; - } - checkedForDependentType= true; - } catch (DOMException e) { - return functions; + if (isDependentType(conversionType)) { + inst= CPPDeferredFunction.createForCandidates(functions); + done= true; } + checkedForDependentType= true; } CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); try { @@ -1869,7 +1859,7 @@ public class CPPTemplates { ICPPTemplateArgument[] args, IASTNode point) { try { if (target != null && isDependentType(target)) { - return CPPDeferredFunction.createForSample(template); + return CPPDeferredFunction.createForCandidates(template); } if (template instanceof ICPPConstructor || args == null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index 4e16f5a0751..a31627bcb5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -145,7 +145,8 @@ public class EvalFunctionSet extends CPPEvaluation { ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments(); ICPPTemplateArgument[] arguments = originalArguments; - arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); + if (originalArguments != null) + arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); IBinding originalOwner = fFunctionSet.getOwner(); IBinding owner = originalOwner; 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 501189404f1..9a055e968d2 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 @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -48,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; @@ -184,15 +186,6 @@ public class EvalID extends CPPEvaluation { return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr)); } if (binding instanceof ICPPUnknownBinding) { - IBinding owner = binding.getOwner(); - if (owner instanceof IProblemBinding) - return EvalFixed.INCOMPLETE; - - ICPPEvaluation fieldOwner= null; - IType fieldOwnerType= withinNonStaticMethod(expr); - if (fieldOwnerType != null) { - fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN); - } ICPPTemplateArgument[] templateArgs = null; final IASTName lastName = name.getLastName(); if (lastName instanceof ICPPASTTemplateId) { @@ -202,12 +195,30 @@ public class EvalID extends CPPEvaluation { return EvalFixed.INCOMPLETE; } } + + if (binding instanceof CPPDeferredFunction) { + CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding; + if (deferredFunction.getCandidates() != null) { + CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null); + return new EvalFunctionSet(functionSet, isAddressOf(expr)); + } + } + + IBinding owner = binding.getOwner(); + if (owner instanceof IProblemBinding) + return EvalFixed.INCOMPLETE; + + ICPPEvaluation fieldOwner= null; + IType fieldOwnerType= withinNonStaticMethod(expr); + if (fieldOwnerType != null) { + fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN); + } + return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), name instanceof ICPPASTQualifiedName, templateArgs); } - /** - * 9.3.1-3 Transformation to class member access within a non-static member function. - */ + + // 9.3.1-3 Transformation to class member access within a non-static member function. if (binding instanceof ICPPMember && !(binding instanceof IType) && !(binding instanceof ICPPConstructor) &&!((ICPPMember) binding).isStatic()) { IType fieldOwnerType= withinNonStaticMethod(expr); @@ -305,7 +316,7 @@ public class EvalID extends CPPEvaluation { if (eval != null) return eval; } - + return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); } From 88b19449f211113eb5a54159b3e70e4faf4ea630 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Fri, 7 Dec 2012 03:49:54 -0500 Subject: [PATCH 11/19] Bug 389782 - Error with uniform initialization involving conversion Change-Id: I2a8227b187bd3b4f7fcc7b7a9b9f0b1c9f289117 Reviewed-on: https://git.eclipse.org/r/9058 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/tests/ast2/AST2BaseTest.java | 30 +++++- .../core/parser/tests/ast2/AST2CPPTests.java | 94 +++++++++++++++++++ .../core/dom/parser/ArithmeticConversion.java | 57 +++++++++++ .../cpp/semantics/BuiltinOperators.java | 4 +- .../parser/cpp/semantics/CPPSemantics.java | 2 +- .../dom/parser/cpp/semantics/Conversions.java | 4 +- .../core/dom/parser/cpp/semantics/Cost.java | 78 ++++++++++++--- 7 files changed, 249 insertions(+), 20 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index a54e0bc32e3..71b4341cedb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -11,6 +11,7 @@ * Andrew Ferguson (Symbian) * Mike Kucera (IBM) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -106,6 +107,7 @@ public class AST2BaseTest extends BaseTestCase { Map map= new HashMap(); map.put("__GNUC__", "4"); map.put("__GNUC_MINOR__", "7"); + map.put("__SIZEOF_SHORT__", "2"); map.put("__SIZEOF_INT__", "4"); map.put("__SIZEOF_LONG__", "8"); return map; @@ -113,6 +115,7 @@ public class AST2BaseTest extends BaseTestCase { private static Map getStdMap() { Map map= new HashMap(); + map.put("__SIZEOF_SHORT__", "2"); map.put("__SIZEOF_INT__", "4"); map.put("__SIZEOF_LONG__", "8"); return map; @@ -511,7 +514,7 @@ public class AST2BaseTest extends BaseTestCase { protected IASTTranslationUnit tu; protected String contents; protected boolean isCPP; - + public BindingAssertionHelper(String contents, boolean isCPP) throws ParserException { this(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C); } @@ -567,6 +570,31 @@ public class AST2BaseTest extends BaseTestCase { return (T) binding; } + private int getIdentifierLength(String str) { + int i; + for (i = 0; i < str.length() && Character.isJavaIdentifierPart(str.charAt(i)); ++i) { + } + return i; + } + + public IProblemBinding assertProblemOnFirstIdentifier(String section) { + return assertProblem(section, getIdentifierLength(section)); + } + + public IProblemBinding assertProblemOnFirstIdentifier(String section, int problemId) { + IProblemBinding problemBinding = assertProblemOnFirstIdentifier(section); + assertEquals(problemId, problemBinding.getID()); + return problemBinding; + } + + public T assertNonProblemOnFirstIdentifier(String section, Class type, Class... cs) { + return assertNonProblem(section, getIdentifierLength(section), type, cs); + } + + public IBinding assertNonProblemOnFirstIdentifier(String section) { + return assertNonProblem(section, getIdentifierLength(section), IBinding.class); + } + public void assertNoName(String section, int len) { IASTName name= findName(section, len); if (name != null) { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 97b8e1f9f70..41fe973a720 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -12,6 +12,7 @@ * Andrew Ferguson (Symbian) * Sergey Prigogin (Google) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -9985,4 +9986,97 @@ public class AST2CPPTests extends AST2BaseTest { public void testIsBaseOf_395019() throws Exception { parseAndCheckBindings(getAboveComment(), CPP, true); } + + // struct Bool { Bool(bool); }; + // struct Char { Char(char); }; + // struct Short { Short(short); }; + // struct Int { Int(int); }; + // struct UInt { UInt(unsigned int); }; + // struct Long { Long(long); }; + // struct ULong { ULong(unsigned long); }; + // struct Float { Float(float); }; + // struct Double { Double(double); }; + // struct LongDouble { LongDouble(long double); }; + // void fbool(Bool); + // void fchar(Char); + // void fshort(Short); + // void fint(Int); + // void flong(Long); + // void fuint(UInt); + // void fulong(ULong); + // void ffloat(Float); + // void fdouble(Double); + // void flongdouble(LongDouble); + // enum UnscopedEnum : int { x, y, z }; + // + // int main() { + // bool vbool; + // char vchar; + // short vshort; + // unsigned short vushort; + // int vint; + // unsigned int vuint; + // long vlong; + // float vfloat; + // double vdouble; + // long double vlongdouble; + // UnscopedEnum vue; + // + // // Narrowing conversions + // fint({vdouble}); + // ffloat({vlongdouble}); + // ffloat({vdouble}); + // fdouble({vlongdouble}); + // fdouble({vint}); + // fdouble({vue}); + // fshort({vint}); + // fuint({vint}); + // fint({vuint}); + // fulong({vshort}); + // fbool({vint}); + // fchar({vint}); + // + // // Non-narrowing conversions + // fint({vshort}); + // flong({vint}); + // fuint({vushort}); + // flong({vshort}); + // fulong({vuint}); + // fulong({vushort}); + // fdouble({vfloat}); + // flongdouble({vfloat}); + // flongdouble({vdouble}); + // fint({vbool}); + // fint({vchar}); + // } + public void testNarrowingConversionsInListInitialization_389782() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + + // Narrowing conversions + helper.assertProblemOnFirstIdentifier("fint({vdouble"); + helper.assertProblemOnFirstIdentifier("ffloat({vlongdouble"); + helper.assertProblemOnFirstIdentifier("ffloat({vdouble"); + helper.assertProblemOnFirstIdentifier("fdouble({vlongdouble"); + helper.assertProblemOnFirstIdentifier("fdouble({vint"); + helper.assertProblemOnFirstIdentifier("fdouble({vue"); + helper.assertProblemOnFirstIdentifier("fshort({vint"); + helper.assertProblemOnFirstIdentifier("fuint({vint"); + helper.assertProblemOnFirstIdentifier("fint({vuint"); + helper.assertProblemOnFirstIdentifier("fulong({vshort"); + helper.assertProblemOnFirstIdentifier("fbool({vint"); + helper.assertProblemOnFirstIdentifier("fchar({vint"); + + // Non-narrowing conversions + helper.assertNonProblemOnFirstIdentifier("fint({vshort"); + helper.assertNonProblemOnFirstIdentifier("flong({vint"); + helper.assertNonProblemOnFirstIdentifier("fuint({vushort"); + helper.assertNonProblemOnFirstIdentifier("flong({vshort"); + helper.assertNonProblemOnFirstIdentifier("fulong({vuint"); + helper.assertNonProblemOnFirstIdentifier("fulong({vushort"); + helper.assertNonProblemOnFirstIdentifier("fdouble({vfloat"); + helper.assertNonProblemOnFirstIdentifier("flongdouble({vfloat"); + helper.assertNonProblemOnFirstIdentifier("flongdouble({vdouble"); + helper.assertNonProblemOnFirstIdentifier("fint({vbool"); + helper.assertNonProblemOnFirstIdentifier("fint({vchar"); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java index 8b0b4163d8f..c9e68fe1402 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java @@ -7,18 +7,21 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** @@ -367,4 +370,58 @@ public abstract class ArithmeticConversion { return false; } } + + /** + * Make a best-effort guess at the sizeof() of an integral type. + */ + private static long getApproximateSize(ICPPBasicType type) { + switch (type.getKind()) { + case eChar: return 1; + case eWChar: return 2; + case eInt: + // Note: we return 6 for long so that both long -> int + // and long long -> long conversions are reported + // as narrowing, to be on the safe side. + return type.isShort() ? 2 + : type.isLong() ? 6 + : type.isLongLong() ? 8 + : 4; + case eBoolean: return 1; + case eChar16: return 2; + case eChar32: return 4; + case eInt128: return 16; + default: return 0; // shouldn't happen + } + } + + /** + * Checks whether a target integral type can represent all values of a source integral type. + * @param target the target integral type + * @param source the source integral type + * @param point point for sizeof lookup + * @return whether the target integral type can represent all values of the source integral type + */ + public static boolean fitsIntoType(ICPPBasicType target, ICPPBasicType source, IASTNode point) { + // A boolean cannot represent any other type. + if (target.getKind() == Kind.eBoolean && source.getKind() != Kind.eBoolean) + return false; + // A boolean can be represented by any other integral type. + if (source.getKind() == Kind.eBoolean) + return true; + + // If the source is signed, it might be negative, so an unsigned target cannot represent it. + if (!source.isUnsigned() && target.isUnsigned()) + return false; + + // Otherwise, go by the size and signedness of the type. + SizeAndAlignment sourceSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(source, point); + SizeAndAlignment targetSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(target, point); + long sizeofSource = sourceSizeAndAlignment == null ? getApproximateSize(source) : sourceSizeAndAlignment.size; + long sizeofTarget = targetSizeAndAlignment == null ? getApproximateSize(target) : targetSizeAndAlignment.size; + + if (sizeofSource == sizeofTarget) + return target.isUnsigned() == source.isUnsigned(); + else + return sizeofSource < sizeofTarget; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java index 4c5ff020493..f265c57a3bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java @@ -590,7 +590,7 @@ class BuiltinOperators { return type instanceof IBasicType && ((IBasicType) type).getKind() == Kind.eBoolean; } - private static boolean isFloatingPoint(IType type) { + public static boolean isFloatingPoint(IType type) { if (type instanceof IBasicType) { IBasicType.Kind kind= ((IBasicType) type).getKind(); switch (kind) { @@ -638,7 +638,7 @@ class BuiltinOperators { return false; } - private static boolean isIntegral(IType type) { + public static boolean isIntegral(IType type) { if (type instanceof IBasicType) { IBasicType.Kind kind= ((IBasicType) type).getKind(); switch (kind) { 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 58e8713a21f..a447998e76e 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 @@ -2730,7 +2730,7 @@ public class CPPSemantics { } cost = Conversions.checkImplicitConversionSequence(paramType, argType, sourceIsLValue, udc, ctx, data.getLookupPoint()); - if (data.fNoNarrowing && cost.isNarrowingConversion()) { + if (data.fNoNarrowing && cost.isNarrowingConversion(data.getLookupPoint())) { cost= Cost.NO_CONVERSION; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 0707a73c5db..b79fccf9806 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -351,7 +351,7 @@ public class Conversions { clause.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point); if (!cost.converts()) return cost; - if (cost.isNarrowingConversion()) { + if (cost.isNarrowingConversion(point)) { cost.setRank(Rank.NO_MATCH); return cost; } @@ -381,7 +381,7 @@ public class Conversions { final ICPPEvaluation firstArg = args[0]; if (!firstArg.isInitializerList()) { Cost cost= checkImplicitConversionSequence(target, firstArg.getTypeOrFunctionSet(point), firstArg.getValueCategory(point), udc, Context.ORDINARY, point); - if (cost.isNarrowingConversion()) { + if (cost.isNarrowingConversion(point)) { return Cost.NO_CONVERSION; } return cost; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java index cacff06b092..3e8308c84fc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,12 +10,16 @@ * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * Andrew Ferguson (Symbian) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; +import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; @@ -261,22 +265,68 @@ public class Cost { return buf.toString(); } - public boolean isNarrowingConversion() { - if (fCouldNarrow) { - if (source instanceof CPPBasicType && target instanceof ICPPBasicType) { - ICPPBasicType basicTarget= (ICPPBasicType) target; - final Kind targetKind = basicTarget.getKind(); - if (targetKind != Kind.eInt && targetKind != Kind.eFloat && targetKind != Kind.eDouble) { - return true; - } - Long val= ((CPPBasicType) source).getAssociatedNumericalValue(); - if (val != null) { - long n= val.longValue(); - return !ArithmeticConversion.fitsIntoType(basicTarget, n); + public boolean isNarrowingConversion(IASTNode point) { + if (!fCouldNarrow) + return false; + + // Determine whether this is a narrowing conversion, according to 8.5.4/7 (dcl.list.init). + + if (!(target instanceof ICPPBasicType)) + return false; + ICPPBasicType basicTarget = (ICPPBasicType) target; + + // Deal with an enumeration source type. + // If it has a fixed underlying type, treat it as if it were that underlying type. + // If not, check whether the target type can represent its min and max values. + CPPBasicType basicSource = null; + if (source instanceof CPPBasicType) { + basicSource = (CPPBasicType) source; + } else if (source instanceof IEnumeration) { + IEnumeration enumSource = (IEnumeration) source; + if (enumSource instanceof ICPPEnumeration) { + IType fixedType = ((ICPPEnumeration) enumSource).getFixedType(); + if (fixedType instanceof CPPBasicType) { + basicSource = (CPPBasicType) fixedType; } } - return true; + if (basicSource == null) { // C enumeration or no fixed type + return !ArithmeticConversion.fitsIntoType(basicTarget, enumSource.getMinValue()) || + !ArithmeticConversion.fitsIntoType(basicTarget, enumSource.getMaxValue()); + } } + + if (basicSource == null) + return false; + + // The standard provides for an exception in some cases where, based on the types only, + // a conversion would be narrowing, but the source expression is a constant-expression + // and its value is exactly representable by the target type. + boolean constantExprExceptionApplies = false; + + if (BuiltinOperators.isFloatingPoint(basicSource) && BuiltinOperators.isIntegral(basicTarget)) { + // From a floating-point type to an integer type + return true; + } else if (basicSource.getKind() == Kind.eDouble + && (basicTarget.getKind() == Kind.eFloat + || (basicTarget.getKind() == Kind.eDouble && !basicTarget.isLong() && basicSource.isLong()))) { + // From long double to double or float, or from double to float + constantExprExceptionApplies = true; + } else if (BuiltinOperators.isIntegral(basicSource) && BuiltinOperators.isFloatingPoint(basicTarget)) { + // From an integer type or unscoped enumeration type to a floating-point type + constantExprExceptionApplies = true; + } else if (BuiltinOperators.isIntegral(basicSource) + && BuiltinOperators.isIntegral(basicTarget) + && !ArithmeticConversion.fitsIntoType(basicTarget, basicSource, point)) { + // From an integer type or unscoped enumeration type to an integer type that + // cannot represent all the values of the original type + constantExprExceptionApplies = true; + } + + if (constantExprExceptionApplies) { + Long val = basicSource.getAssociatedNumericalValue(); + return val == null || !ArithmeticConversion.fitsIntoType(basicTarget, val.longValue()); + } + return false; } From c21f219ab7e8eff57e34845db1020861526fc083 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Fri, 7 Dec 2012 12:29:07 -0800 Subject: [PATCH 12/19] Bug 395875 - Error involving dependent expression in index Change-Id: I2f50373220a02d5856fb88cf040c44de28fb5a79 Reviewed-on: https://git.eclipse.org/r/9064 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../tests/IndexCPPTemplateResolutionTest.java | 15 +++++++++++++++ .../core/dom/parser/cpp/semantics/CPPVisitor.java | 14 ++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 0e8fded9b54..57ffaefda0b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -9,6 +9,7 @@ * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; @@ -2175,4 +2176,18 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testLambdaExpression_395884() throws Exception { checkBindings(); } + + // template int bar(T); + // template struct S { + // template auto foo(T t) const -> decltype(bar(t)); + // }; + + // void f(int); + // void test() { + // S<1> n; + // f(n.foo(0)); + // } + public void testDependentExpression_395875() throws Exception { + getBindingFromASTName("f(n.foo(0))", 1, ICPPFunction.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index bb1138eb81a..7b634dc0f5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -2434,13 +2434,19 @@ public class CPPVisitor extends ASTQueries { * Searches for the function enclosing the given node. May return null. */ public static IBinding findEnclosingFunction(IASTNode node) { - while (node != null && !(node instanceof IASTFunctionDefinition)) { + IASTDeclarator dtor = null; + while (node != null) { + if (node instanceof IASTFunctionDeclarator) { + dtor = (IASTDeclarator) node; + break; + } + if (node instanceof IASTFunctionDefinition) { + dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()); + break; + } node= node.getParent(); } - if (node == null) - return null; - IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()); if (dtor != null) { IASTName name= dtor.getName(); if (name != null) { From 8f09f3af07e0060c5cb9f348364d0557a355fa3f Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 7 Dec 2012 14:32:29 -0800 Subject: [PATCH 13/19] Bug 395875 - An alternative fix that preserves semantics of CPPVisitor.findEnclosingFunction method. --- .../internal/core/dom/parser/cpp/CPPParameter.java | 7 ++++++- .../core/dom/parser/cpp/semantics/CPPVisitor.java | 14 ++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java index e49137afdc1..b576015775a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java @@ -257,7 +257,12 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI @Override public IBinding getOwner() { - return CPPVisitor.findEnclosingFunction(fDeclarations[0]); + IASTFunctionDeclarator decl = + CPPVisitor.findAncestorWithType(fDeclarations[0], IASTFunctionDeclarator.class); + if (decl == null) + return null; + IASTName name= decl.getName(); + return name != null ? name.resolveBinding() : null; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 7b634dc0f5d..bb1138eb81a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -2434,19 +2434,13 @@ public class CPPVisitor extends ASTQueries { * Searches for the function enclosing the given node. May return null. */ public static IBinding findEnclosingFunction(IASTNode node) { - IASTDeclarator dtor = null; - while (node != null) { - if (node instanceof IASTFunctionDeclarator) { - dtor = (IASTDeclarator) node; - break; - } - if (node instanceof IASTFunctionDefinition) { - dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()); - break; - } + while (node != null && !(node instanceof IASTFunctionDefinition)) { node= node.getParent(); } + if (node == null) + return null; + IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()); if (dtor != null) { IASTName name= dtor.getName(); if (name != null) { From 880ac74b2675055c328285c15a2b8879707e6949 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 7 Dec 2012 16:56:36 -0800 Subject: [PATCH 14/19] Revert "Bug 395243 - Error involving dependent expressions" This reverts commit f429bd5482da5a034e0dab8752e68bf8304b8f72. --- .../parser/tests/ast2/AST2TemplateTests.java | 2 +- .../dom/parser/cpp/CPPDeferredFunction.java | 31 +++++----------- .../dom/parser/cpp/CPPUnknownConstructor.java | 8 +--- .../parser/cpp/semantics/CPPFunctionSet.java | 9 ++--- .../parser/cpp/semantics/CPPSemantics.java | 9 ++--- .../parser/cpp/semantics/CPPTemplates.java | 32 ++++++++++------ .../parser/cpp/semantics/EvalFunctionSet.java | 3 +- .../core/dom/parser/cpp/semantics/EvalID.java | 37 +++++++------------ 8 files changed, 54 insertions(+), 77 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 915a4c94767..1b3079dfc0f 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 @@ -6938,7 +6938,7 @@ public class AST2TemplateTests extends AST2BaseTest { // static const int value = sizeof(waldo(f)); // }; // typedef identity::value>>::type reference; - public void testDependentExpressions_395243() throws Exception { + public void _testDependentExpressions_395243() throws Exception { parseAndCheckBindings(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java index 108f60c3d83..daf282b6106 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java @@ -8,11 +8,12 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -29,33 +30,19 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY); - /** - * Creates a CPPDeferredFunction given a set of overloaded functions - * (some of which may be templates) that the function might resolve to. - * At least one candidate must be provided. - * - * @param candidates a set of overloaded functions, some of which may be templates - * @return the constructed CPPDeferredFunction - */ - public static ICPPFunction createForCandidates(ICPPFunction... candidates) { - if (candidates[0] instanceof ICPPConstructor) - return new CPPUnknownConstructor(((ICPPConstructor) candidates[0]).getClassOwner(), candidates); - - final IBinding owner = candidates[0].getOwner(); - return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates); + public static ICPPFunction createForSample(IFunction sample) throws DOMException { + if (sample instanceof ICPPConstructor) + return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner()); + + final IBinding owner = sample.getOwner(); + return new CPPDeferredFunction(owner, sample.getNameCharArray()); } private final IBinding fOwner; - private final ICPPFunction[] fCandidates; - public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) { + public CPPDeferredFunction(IBinding owner, char[] name) { super(name); fOwner= owner; - fCandidates = candidates; - } - - public ICPPFunction[] getCandidates() { - return fCandidates; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java index 94b59961cfa..0dd63fc488a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownConstructor.java @@ -8,13 +8,11 @@ * Contributors: * Markus Schorn - initial API and implementation * Thomas Corbat (IFS) - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ICPPFunction; /** * Represents a reference to a constructor (instance), which cannot be resolved because @@ -23,11 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; public class CPPUnknownConstructor extends CPPDeferredFunction implements ICPPConstructor { public CPPUnknownConstructor(ICPPClassType owner) { - super(owner, owner.getNameCharArray(), null); - } - - public CPPUnknownConstructor(ICPPClassType owner, ICPPFunction[] candidates) { - super(owner, owner.getNameCharArray(), candidates); + super(owner, owner.getNameCharArray()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java index 0eef3cfa56e..8d1842259e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,7 +7,6 @@ * * Contributors: * Markus Schorn - initial API and implementation - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -32,7 +31,7 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { private final ICPPFunction[] fBindings; private final IASTName fName; private final ICPPTemplateArgument[] fTemplateArguments; - + public CPPFunctionSet(ICPPFunction[] bindingList, ICPPTemplateArgument[] args, IASTName name) { fBindings = ArrayUtil.removeNulls(bindingList); fTemplateArguments= args; @@ -90,10 +89,10 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { fName.setBinding(selectedFunction); } } - + public void setToUnknown() { if (fName != null) { - fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray(), fBindings)); + fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray())); } } } 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 a447998e76e..247603215af 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 @@ -13,7 +13,6 @@ * Sergey Prigogin (Google) * Mike Kucera (IBM) * Thomas Corbat (IFS) - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -452,7 +451,7 @@ public class CPPSemantics { final ASTNodeProperty namePropertyInParent = name.getPropertyInParent(); if (binding == null && data.skippedScope != null) { if (data.hasFunctionArguments()) { - binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID(), null); + binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID()); } else { if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) { binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID()); @@ -2396,7 +2395,7 @@ public class CPPSemantics { if (viableCount == 1) return fns[0]; setTargetedFunctionsToUnknown(argTypes); - return CPPDeferredFunction.createForCandidates(fns); + return CPPDeferredFunction.createForSample(fns[0]); } IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good @@ -2404,7 +2403,7 @@ public class CPPSemantics { // Loop over all functions List potentialCosts= null; - ICPPFunction unknownFunction= null; + IFunction unknownFunction= null; final CPPASTTranslationUnit tu = data.getTranslationUnit(); for (ICPPFunction fn : fns) { if (fn == null) @@ -2456,7 +2455,7 @@ public class CPPSemantics { return null; setTargetedFunctionsToUnknown(argTypes); - return CPPDeferredFunction.createForCandidates(fns); + return CPPDeferredFunction.createForSample(unknownFunction); } if (ambiguousFunctions != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 39e5db03281..877e605ba48 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -11,7 +11,6 @@ * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) * Thomas Corbat (IFS) - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -164,6 +163,7 @@ public class CPPTemplates { static final int PACK_SIZE_DEFER = -1; static final int PACK_SIZE_FAIL = -2; static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; + private static final ICPPFunction[] NO_FUNCTIONS = {}; static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } /** @@ -1726,12 +1726,18 @@ public class CPPTemplates { requireTemplate= false; if (func instanceof ICPPFunctionTemplate) { - if (containsDependentType(fnArgs)) - return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)}; + ICPPFunctionTemplate template= (ICPPFunctionTemplate) func; + try { + if (containsDependentType(fnArgs)) + return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)}; - if (requireTemplate && hasDependentArgument(tmplArgs)) - return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)}; - + if (requireTemplate) { + if (hasDependentArgument(tmplArgs)) + return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)}; + } + } catch (DOMException e) { + return NO_FUNCTIONS; + } haveTemplate= true; break; } @@ -1797,11 +1803,15 @@ public class CPPTemplates { // Extract template arguments and parameter types. if (!checkedForDependentType) { - if (isDependentType(conversionType)) { - inst= CPPDeferredFunction.createForCandidates(functions); - done= true; + try { + if (isDependentType(conversionType)) { + inst= CPPDeferredFunction.createForSample(template); + done= true; + } + checkedForDependentType= true; + } catch (DOMException e) { + return functions; } - checkedForDependentType= true; } CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); try { @@ -1859,7 +1869,7 @@ public class CPPTemplates { ICPPTemplateArgument[] args, IASTNode point) { try { if (target != null && isDependentType(target)) { - return CPPDeferredFunction.createForCandidates(template); + return CPPDeferredFunction.createForSample(template); } if (template instanceof ICPPConstructor || args == null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index a31627bcb5d..4e16f5a0751 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -145,8 +145,7 @@ public class EvalFunctionSet extends CPPEvaluation { ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments(); ICPPTemplateArgument[] arguments = originalArguments; - if (originalArguments != null) - arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); + arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); IBinding originalOwner = fFunctionSet.getOwner(); IBinding owner = originalOwner; 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 9a055e968d2..501189404f1 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 @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) - * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -49,7 +48,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.Value; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; @@ -186,24 +184,6 @@ public class EvalID extends CPPEvaluation { return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr)); } if (binding instanceof ICPPUnknownBinding) { - ICPPTemplateArgument[] templateArgs = null; - final IASTName lastName = name.getLastName(); - if (lastName instanceof ICPPASTTemplateId) { - try { - templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName); - } catch (DOMException e) { - return EvalFixed.INCOMPLETE; - } - } - - if (binding instanceof CPPDeferredFunction) { - CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding; - if (deferredFunction.getCandidates() != null) { - CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null); - return new EvalFunctionSet(functionSet, isAddressOf(expr)); - } - } - IBinding owner = binding.getOwner(); if (owner instanceof IProblemBinding) return EvalFixed.INCOMPLETE; @@ -213,12 +193,21 @@ public class EvalID extends CPPEvaluation { if (fieldOwnerType != null) { fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN); } - + ICPPTemplateArgument[] templateArgs = null; + final IASTName lastName = name.getLastName(); + if (lastName instanceof ICPPASTTemplateId) { + try { + templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName); + } catch (DOMException e) { + return EvalFixed.INCOMPLETE; + } + } return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), name instanceof ICPPASTQualifiedName, templateArgs); } - - // 9.3.1-3 Transformation to class member access within a non-static member function. + /** + * 9.3.1-3 Transformation to class member access within a non-static member function. + */ if (binding instanceof ICPPMember && !(binding instanceof IType) && !(binding instanceof ICPPConstructor) &&!((ICPPMember) binding).isStatic()) { IType fieldOwnerType= withinNonStaticMethod(expr); @@ -316,7 +305,7 @@ public class EvalID extends CPPEvaluation { if (eval != null) return eval; } - + return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); } From c916dfe4e71389790a361876c4b19a1599b6db10 Mon Sep 17 00:00:00 2001 From: Marc Dumais Date: Mon, 10 Dec 2012 06:40:52 -0500 Subject: [PATCH 15/19] Bug 396076 - [Visualizer] Cores displayed non-optimally when there are multiple CPUs Change-Id: Ib043630b29ba1c25bd5fd8ee08c68e3ca388bb68 Reviewed-on: https://git.eclipse.org/r/9110 Reviewed-by: William Swanson IP-Clean: William Swanson Tested-by: William Swanson --- .../internal/ui/view/MulticoreVisualizerCanvas.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java index 993e2270b65..80adea48a80 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -7,6 +7,7 @@ * * Contributors: * William R. Swanson (Tilera Corporation) - initial API and implementation + * Marc Dumais (Ericsson) - Bug 396076 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -396,6 +397,11 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas } if (m_recacheSizes) { + // avoid doing resize calculations if the model is not ready + if (m_model == null ) { + m_recacheSizes = false; + return; + } // update cached size information // General margin/spacing constants. @@ -418,7 +424,7 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas if (cpu_size < 0) cpu_size = 0; // Calculate area on each CPU for placing cores. - int ncores = m_cores.size(); + int ncores = m_cores.size() / ((ncpus == 0) ? 1 : ncpus); int cpu_width = cpu_size - core_margin * 2 + core_separation; int cpu_height = cpu_size - core_margin * 2 + core_separation; int core_edge = fitSquareItems(ncores, cpu_width, cpu_height); From 601d922e22cb6291511f0d7ff16d9d6e4950bb1f Mon Sep 17 00:00:00 2001 From: Marc Dumais Date: Mon, 10 Dec 2012 11:17:20 -0500 Subject: [PATCH 16/19] Bug 396184 - [visualizer] - m_cpuMap and m_coreMap are not cleared when re-caching Change-Id: I68147082d4c0948b03d3efe7487ec75c8daa7cbf Reviewed-on: https://git.eclipse.org/r/9137 Reviewed-by: William Swanson IP-Clean: William Swanson Tested-by: William Swanson --- .../internal/ui/view/MulticoreVisualizerCanvas.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java index 80adea48a80..59fd6cf3908 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -8,6 +8,7 @@ * Contributors: * William R. Swanson (Tilera Corporation) - initial API and implementation * Marc Dumais (Ericsson) - Bug 396076 + * Marc Dumais (Ericsson) - Bug 396184 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -364,6 +365,8 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas m_cpus.clear(); m_cores.clear(); m_threads.clear(); + m_cpuMap.clear(); + m_coreMap.clear(); // For debugging purposes only, allows us to force a CPU count. //int cpu_count = 0; From 99699d2fd793cc0c5eff966223b3c5deab99887e Mon Sep 17 00:00:00 2001 From: Marc Dumais Date: Mon, 10 Dec 2012 11:38:54 -0500 Subject: [PATCH 17/19] Bug 396200 - [Visualizer] m_recache is never reset to false Change-Id: I910f422f6548639ff3ca3189f1e2995ed9bda22c Reviewed-on: https://git.eclipse.org/r/9142 Reviewed-by: William Swanson IP-Clean: William Swanson Tested-by: William Swanson --- .../internal/ui/view/MulticoreVisualizerCanvas.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java index 59fd6cf3908..3a7eb59e2aa 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -9,6 +9,7 @@ * William R. Swanson (Tilera Corporation) - initial API and implementation * Marc Dumais (Ericsson) - Bug 396076 * Marc Dumais (Ericsson) - Bug 396184 + * Marc Dumais (Ericsson) - Bug 396200 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -460,6 +461,7 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas m_recacheSizes = false; } + m_recache = false; } /** Invoked when canvas repaint event is raised. From ca6f6aa2aa33773cc9727be4f538ad339610b0f2 Mon Sep 17 00:00:00 2001 From: Marc Dumais Date: Tue, 11 Dec 2012 11:24:57 -0500 Subject: [PATCH 18/19] Bug 396293 - [Visualizer] right side cpu_margin not taken into account when deciding if a new line of cores is needed Change-Id: I60eb0f138e1cfea9fd539cc52b83f51a7c300e67 Reviewed-on: https://git.eclipse.org/r/9158 Reviewed-by: William Swanson IP-Clean: William Swanson Tested-by: William Swanson --- .../internal/ui/view/MulticoreVisualizerCanvas.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java index 3a7eb59e2aa..291a5a95a8d 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -10,6 +10,7 @@ * Marc Dumais (Ericsson) - Bug 396076 * Marc Dumais (Ericsson) - Bug 396184 * Marc Dumais (Ericsson) - Bug 396200 + * Marc Dumais (Ericsson) - Bug 396293 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -446,7 +447,7 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas core.setBounds(cx, cy, core_size, core_size); cx += core_size + core_separation; - if (cx + core_size > x + cpu_size) { + if (cx + core_size + core_margin > x + cpu_size) { cx = left; cy += core_size + core_separation; } From cce302595e39c9c8b562bb81f5a193c659035120 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Tue, 11 Dec 2012 12:42:55 -0500 Subject: [PATCH 19/19] bug 396411: JUnit failure: cdt.managedbuilder.core.tests.ManagedBuildCoreTests20.testScannerInfoInterface --- .../testplugin/BuildSystemTestHelper.java | 18 ++++----- .../core/tests/ManagedBuildCoreTests20.java | 40 ++++++++++++------- .../MBSLanguageSettingsProvider.java | 9 ++++- .../providers/LanguageSettingsManager.java | 6 +-- .../settings/model/ICLanguageSetting.java | 3 ++ .../model/util/PathEntryTranslator.java | 6 ++- .../LanguageSettingsScannerInfoProvider.java | 7 +++- .../providers/LanguageSettingsEntriesTab.java | 11 +++-- 8 files changed, 66 insertions(+), 34 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/testplugin/BuildSystemTestHelper.java b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/testplugin/BuildSystemTestHelper.java index 06bcd4b69ca..368139642e3 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/testplugin/BuildSystemTestHelper.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/managedbuilder/testplugin/BuildSystemTestHelper.java @@ -122,22 +122,22 @@ public class BuildSystemTestHelper { return project; } - static public void checkDiff(Object[] arr1, Object[] arr2){ - LinkedHashSet set1 = new LinkedHashSet(Arrays.asList(arr1)); - LinkedHashSet set2 = new LinkedHashSet(Arrays.asList(arr2)); + static public void checkDiff(Object[] expected, Object[] actual){ + LinkedHashSet set1 = new LinkedHashSet(Arrays.asList(expected)); + LinkedHashSet set2 = new LinkedHashSet(Arrays.asList(actual)); LinkedHashSet set1Copy = new LinkedHashSet(set1); set1.removeAll(set2); set2.removeAll(set1Copy); String set1String = collectionToString(set1); String set2String = collectionToString(set2); - String diffMsg = "array1 entries: " + set1String + ",\n array2 entries: " + set2String + "\n"; - Assert.assertEquals("arrays have different size\n" + diffMsg, arr1.length, arr2.length); - Assert.assertEquals("arrays have different contents\n" + diffMsg, 0, set1.size()); - Assert.assertEquals("arrays have different contents\n" + diffMsg, 0, set2.size()); + String diffMsg = "expected entries: " + set1String + ",\n actual entries: " + set2String + "\n"; + Assert.assertEquals("arrays have different size\n" + diffMsg, expected.length, actual.length); + Assert.assertTrue("arrays have different contents\n" + diffMsg, set1.size() == 0); + Assert.assertTrue("arrays have different contents\n" + diffMsg, set2.size() == 0); - if(!Arrays.equals(arr1, arr2)){ - Assert.fail("different element order, dumping..\n array1 entries: " + arrayToString(arr1) + "\n array2 entries: " + arrayToString(arr2) + "\n"); + if(!Arrays.equals(expected, actual)){ + Assert.fail("different element order, dumping..\n expected entries: " + arrayToString(expected) + "\n actual entries: " + arrayToString(actual) + "\n"); } } diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java index 4d86f955298..805d83df23d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.core.tests; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Properties; @@ -22,6 +24,7 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsScannerInfoProvider; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; @@ -48,11 +51,9 @@ import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; /* @@ -198,6 +199,19 @@ public class ManagedBuildCoreTests20 extends TestCase { } + /** + * Convert path to OS specific representation + */ + private String toOSString(String path) { + File file = new File(path); + try { + path = file.getCanonicalPath(); + } catch (IOException e) { + } + + return path; + } + /** * The purpose of this test is to exercise the build path info interface. * To get to that point, a new project/config has to be created in the test @@ -218,18 +232,15 @@ public class ManagedBuildCoreTests20 extends TestCase { } //These are the expected path settings - final String[] expectedPaths = new String[5]; - - // This first path is a built-in, so it will not be manipulated by build manager - expectedPaths[0] = (new Path("/usr/include")).toOSString(); - expectedPaths[1] = (new Path("/opt/gnome/include")).toOSString(); - IPath path = new Path("C:\\home\\tester/include"); - if(path.isAbsolute()) // for win32 path is treated as absolute - expectedPaths[2] = path.toOSString(); - else // for Linux path is relative - expectedPaths[2] = project.getLocation().append("Sub Config").append(path).toOSString(); - expectedPaths[3] = project.getLocation().append( "includes" ).toOSString(); - expectedPaths[4] = (new Path("/usr/gnu/include")).toOSString(); + final String[] expectedPaths = { + toOSString("/usr/include"), + toOSString("/opt/gnome/include"), + toOSString("C:\\home\\tester/include"), + // relative path makes 2 entries + project.getLocation().append("includes").toOSString(), + "includes", + "/usr/gnu/include", // This one set to ICSettingEntry.RESOLVED + }; // Create a new managed project based on the sub project type IProjectType projType = ManagedBuildManager.getExtensionProjectType("test.sub"); @@ -281,6 +292,7 @@ public class ManagedBuildCoreTests20 extends TestCase { // Find the first IScannerInfoProvider that supplies build info for the project IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); assertNotNull(provider); + assertTrue(provider instanceof LanguageSettingsScannerInfoProvider); // Now subscribe (note that the method will be called after a change provider.subscribe(project, new IScannerInfoChangeListener () { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java index 1026f2e5f56..24616f8eeb7 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java @@ -56,11 +56,16 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase for (ICLanguageSetting langSetting : languageSettings) { if (langSetting != null) { String id = langSetting.getLanguageId(); - if (id != null && id.equals(languageId)) { + if (id == languageId || (id != null && id.equals(languageId))) { int kindsBits = langSetting.getSupportedEntryKinds(); for (int kind=1; kind <= kindsBits; kind <<= 1) { if ((kindsBits & kind) != 0) { - list.addAll(langSetting.getSettingEntriesList(kind)); + List additions = langSetting.getSettingEntriesList(kind); + for (ICLanguageSettingEntry entry : additions) { + if (! list.contains(entry)) { + list.add(entry); + } + } } } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java index e9cdcd93bca..124ee5506fe 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java @@ -208,7 +208,7 @@ public class LanguageSettingsManager { * commonly come from the input type(s). * * @param rcDescription - resource description - * @return list of language IDs for the resource. + * @return list of language IDs for the resource. The list can contain {@code null} ID. * Never returns {@code null} but empty list if no languages can be found. * */ @@ -226,9 +226,9 @@ public class LanguageSettingsManager { List languageIds = new ArrayList(); if (languageSettings != null) { for (ICLanguageSetting languageSetting : languageSettings) { - if (languageSetting!=null) { + if (languageSetting != null) { String languageId = languageSetting.getLanguageId(); - if (languageId != null && !languageId.isEmpty()) { + if (! languageIds.contains(languageId)) { languageIds.add(languageId); } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICLanguageSetting.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICLanguageSetting.java index c3a386121b2..3aa900e05d4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICLanguageSetting.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICLanguageSetting.java @@ -21,6 +21,9 @@ public interface ICLanguageSetting extends ICSettingObject { // String[] getHeaderExtensions(); + /** + * @return language id. Note that that id can be {@code null}. + */ String getLanguageId(); // ICLanguageSettingEntry[] getSettingEntries(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java index 4758393d90d..ac36287fb73 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/PathEntryTranslator.java @@ -2051,8 +2051,10 @@ public class PathEntryTranslator { IProject project = cfgDescription.getProjectDescription().getProject(); if (ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project)) { IResource rc = findResourceInWorkspace(project, rcData.getPath()); - for (CLanguageData lData : lDatas) { - list.addAll(LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, lData.getLanguageId(), kind)); + if (rc != null) { + for (CLanguageData lData : lDatas) { + list.addAll(LanguageSettingsProvidersSerializer.getSettingEntriesByKind(cfgDescription, rc, lData.getLanguageId(), kind)); + } } return list.size()>0; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index fc782dc3ab5..b00b3b639b0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -159,7 +159,12 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider // still, MBS does that and we need to handle that String buildPathString = buildCWD.toString(); buildPathString = mngr.resolveValue(buildPathString, "", null, cfgDescription); //$NON-NLS-1$ - buildCWD = new Path(buildPathString); + if (!buildPathString.isEmpty()) { + buildCWD = new Path(buildPathString); + } else { + IProject project = cfgDescription.getProjectDescription().getProject(); + buildCWD = project.getLocation(); + } } catch (CdtVariableException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java index 9a0e10b9276..dd41893d473 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsEntriesTab.java @@ -968,6 +968,8 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab { currentLanguageId = null; List languageIds = LanguageSettingsManager.getLanguages(rcDes); + // Not sure what to do with null language ID, ignoring for now + languageIds.remove(null); Collections.sort(languageIds); for (String langId : languageIds) { ILanguage language = LanguageManager.getInstance().getLanguage(langId); @@ -1124,9 +1126,12 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab { if (page.isForFile()) { List languageIds = LanguageSettingsManager.getLanguages(getResDesc()); for (String langId : languageIds) { - ILanguage language = LanguageManager.getInstance().getLanguage(langId); - if (language != null) - return true; + if (langId != null) { + ILanguage language = LanguageManager.getInstance().getLanguage(langId); + if (language != null) { + return true; + } + } } return false; }