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 { 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/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 0f1faaeba99..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; @@ -577,4 +578,28 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { runOnProject(); checkNoErrors(); } + + // 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.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 c58b157fdcc..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; @@ -9953,8 +9954,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 +9974,109 @@ 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); + } + + // 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.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..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 @@ -12,6 +12,7 @@ * Andrew Ferguson (Symbian) * Sergey Prigogin (Google) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -6883,7 +6884,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(); + } + // struct S { // typedef int a_type; // }; @@ -6895,4 +6912,33 @@ 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(); + } + + // 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.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/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 16b9a000c95..ee1958170e4 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 @@ -2073,8 +2073,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 e7089f419e1..2c6c4317dbb 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 @@ -162,7 +162,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.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; + } +} 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/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; 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/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) { 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 dec5a062f90..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 @@ -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) { @@ -2726,7 +2729,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; } 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; 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. */ 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; 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/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; } 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); } 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; 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..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 @@ -7,6 +7,10 @@ * * Contributors: * William R. Swanson (Tilera Corporation) - initial API and implementation + * 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; @@ -363,6 +367,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; @@ -396,6 +402,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 +429,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); @@ -436,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; } @@ -451,6 +462,7 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas m_recacheSizes = false; } + m_recache = false; } /** Invoked when canvas repaint event is raised.