1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 402878 - Visibility information for nested types

Change-Id: Ifd134d9cb573aecd4714c296f38eda6b13a80f06
Reviewed-on: https://git.eclipse.org/r/11901
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Thomas Corbat 2013-05-14 17:39:54 -07:00 committed by Sergey Prigogin
parent 06bcfad238
commit c4da5d94a2
32 changed files with 981 additions and 167 deletions

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Thomas Corbat - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import junit.framework.Assert;
public class VisibilityAsserts {
public static void assertVisibility(int expected, int actual) {
Assert.assertEquals(visibilityName(expected), visibilityName(actual));
}
public static String visibilityName(int visibility) {
switch (visibility) {
case ICPPClassType.v_private:
return "private";
case ICPPClassType.v_protected:
return "protected";
case ICPPClassType.v_public:
return "public";
default:
throw new IllegalArgumentException("Illegal visibility: " + visibility);
}
}
}

View file

@ -20,6 +20,7 @@ package org.eclipse.cdt.core.parser.tests.ast2;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
import static org.eclipse.cdt.core.parser.tests.VisibilityAsserts.assertVisibility;
import java.io.BufferedReader;
import java.io.IOException;
@ -10267,10 +10268,60 @@ public class AST2CPPTests extends AST2TestBase {
parseAndCheckBindings(code);
BindingAssertionHelper bh = new BindingAssertionHelper(code, true);
ICPPNamespace NamespaceNS = bh.assertNonProblem("NS {", 2);
ICPPClassType Inner = bh.assertNonProblem("Inner;", 5);
assertEquals(NamespaceNS.getNamespaceScope(), Inner.getScope());
}
// class AClass {
// int defaultMemberVariable;
// void defaultMemberFunction();
// class defaultNestedClass {};
// public:
// int publicMemberVariable;
// void publicMemberFunction();
// class publicNestedClass {};
// protected:
// int protectedMemberVariable;
// void protectedMemberFunction();
// class protectedNestedClass {};
// private:
// int privateMemberVariable;
// void privateMemberFunction();
// class privateNestedClass {};
// };
public void testMemberAccessibilities() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
ICPPClassType aClass = bh.assertNonProblem("AClass");
ICPPField defaultMemberVariable = bh.assertNonProblem("defaultMemberVariable");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(defaultMemberVariable));
ICPPMethod defaultMemberFunction = bh.assertNonProblem("defaultMemberFunction");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(defaultMemberFunction));
ICPPClassType defaultNestedClass = bh.assertNonProblem("defaultNestedClass");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(defaultNestedClass));
ICPPField publicMemberVariable = bh.assertNonProblem("publicMemberVariable");
assertVisibility(ICPPClassType.v_public, aClass.getVisibility(publicMemberVariable));
ICPPMethod publicMemberFunction = bh.assertNonProblem("publicMemberFunction");
assertVisibility(ICPPClassType.v_public, aClass.getVisibility(publicMemberFunction));
ICPPClassType publicNestedClass = bh.assertNonProblem("publicNestedClass");
assertVisibility(ICPPClassType.v_public, aClass.getVisibility(publicNestedClass));
ICPPField protectedMemberVariable = bh.assertNonProblem("protectedMemberVariable");
assertVisibility(ICPPClassType.v_protected, aClass.getVisibility(protectedMemberVariable));
ICPPMethod protectedMemberFunction = bh.assertNonProblem("protectedMemberFunction");
assertVisibility(ICPPClassType.v_protected, aClass.getVisibility(protectedMemberFunction));
ICPPClassType protectedNestedClass = bh.assertNonProblem("protectedNestedClass");
assertVisibility(ICPPClassType.v_protected, aClass.getVisibility(protectedNestedClass));
ICPPField privateMemberVariable = bh.assertNonProblem("privateMemberVariable");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(privateMemberVariable));
ICPPMethod privateMemberFunction = bh.assertNonProblem("privateMemberFunction");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(privateMemberFunction));
ICPPClassType privateNestedClass = bh.assertNonProblem("privateNestedClass");
assertVisibility(ICPPClassType.v_private, aClass.getVisibility(privateNestedClass));
}
}

View file

@ -20,6 +20,7 @@ import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType;
import static org.eclipse.cdt.core.parser.tests.VisibilityAsserts.assertVisibility;
import java.io.IOException;
@ -7653,4 +7654,65 @@ public class AST2TemplateTests extends AST2TestBase {
public void testTemplateBaseClassConstructorCall_402602() throws Exception {
parseAndCheckBindings();
}
// template<typename T>
// class ATemplate {
// int defaultMemberVariable;
// public:
// int publicMemberVariable;
// protected:
// int protectedMemberVariable;
// private:
// int privateMemberVariable;
// };
public void testTemplateMemberAccessibilities() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
ICPPClassTemplate aTemplate = bh.assertNonProblem("ATemplate");
ICPPField defaultMemberVariable = bh.assertNonProblem("defaultMemberVariable");
assertVisibility(ICPPClassType.v_private, aTemplate.getVisibility(defaultMemberVariable));
ICPPField publicMemberVariable = bh.assertNonProblem("publicMemberVariable");
assertVisibility(ICPPClassType.v_public, aTemplate.getVisibility(publicMemberVariable));
ICPPField protectedMemberVariable = bh.assertNonProblem("protectedMemberVariable");
assertVisibility(ICPPClassType.v_protected, aTemplate.getVisibility(protectedMemberVariable));
ICPPField privateMemberVariable = bh.assertNonProblem("privateMemberVariable");
assertVisibility(ICPPClassType.v_private, aTemplate.getVisibility(privateMemberVariable));
}
// template<typename T>
// class ATemplate {};
//
// class A{};
//
// template<>
// class ATemplate<A> {
// int specializedDefaultVariable;
// public:
// int specializedPublicVariable;
// protected:
// int specializedProtectedVariable;
// private:
// int specializedPrivateVariable;
// };
public void testTemplateSpecializationMemberAccessibilities() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
ICPPClassSpecialization aTemplateSpecialization = bh.assertNonProblem("ATemplate<A>");
ICPPField defaultMemberVariable = bh.assertNonProblem("specializedDefaultVariable");
assertVisibility(ICPPClassType.v_private, aTemplateSpecialization.getVisibility(defaultMemberVariable));
ICPPField publicMemberVariable = bh.assertNonProblem("specializedPublicVariable");
assertVisibility(ICPPClassType.v_public, aTemplateSpecialization.getVisibility(publicMemberVariable));
ICPPField protectedMemberVariable = bh.assertNonProblem("specializedProtectedVariable");
assertVisibility(ICPPClassType.v_protected, aTemplateSpecialization.getVisibility(protectedMemberVariable));
ICPPField privateMemberVariable = bh.assertNonProblem("specializedPrivateVariable");
assertVisibility(ICPPClassType.v_private, aTemplateSpecialization.getVisibility(privateMemberVariable));
}
}

View file

@ -13,9 +13,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
@ -68,6 +65,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.List;
/**
* Tests for exercising resolution of template bindings against IIndex
*/

View file

@ -15,19 +15,18 @@ import java.util.Arrays;
import junit.framework.Test;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
@ -35,27 +34,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Path;
/**
* Tests PDOM class template related bindings
*/
public class CPPClassTemplateTests extends PDOMTestBase {
protected PDOM pdom;
protected ICProject cproject;
public class CPPClassTemplateTests extends PDOMInlineCodeTestBase {
public static Test suite() {
return suite(CPPClassTemplateTests.class);
@ -63,31 +51,10 @@ public class CPPClassTemplateTests extends PDOMTestBase {
@Override
public void setUp() throws Exception {
cproject= CProjectHelper.createCCProject("classTemplateTests"+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
super.setUp();
setUpSections(1);
}
protected void setUpSections(int sections) throws Exception {
CharSequence[] contents= TestSourceReader.getContentsForTest(
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), sections);
for (CharSequence content : contents) {
IFile file= TestSourceReader.createFile(cproject.getProject(), new Path("refs.cpp"), content.toString());
}
IndexerPreferences.set(cproject.getProject(), IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
waitForIndexer(cproject);
pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
pdom.acquireReadLock();
}
@Override
protected void tearDown() throws Exception {
if(pdom != null) {
pdom.releaseReadLock();
}
pdom= null;
cproject.getProject().delete(true, npm());
}
/*************************************************************************/
// template<typename T>

View file

@ -79,19 +79,19 @@ public class CPPFieldTests extends PDOMTestBase {
}
public void testDefaultPrivateField() throws Exception {
assertVisibility(pdom, "Class1::defaultField", ICPPMember.v_private);
assertCPPMemberVisibility(pdom, "Class1::defaultField", ICPPMember.v_private);
}
public void testPrivateField() throws Exception {
assertVisibility(pdom, "Class1::privateField", ICPPMember.v_private);
assertCPPMemberVisibility(pdom, "Class1::privateField", ICPPMember.v_private);
}
public void testProtectedField() throws Exception {
assertVisibility(pdom, "Class1::protectedField", ICPPMember.v_protected);
assertCPPMemberVisibility(pdom, "Class1::protectedField", ICPPMember.v_protected);
}
public void testPublicField() throws Exception {
assertVisibility(pdom, "Class1::publicField", ICPPMember.v_public);
assertCPPMemberVisibility(pdom, "Class1::publicField", ICPPMember.v_public);
}
public void testMutableField() throws Exception {

View file

@ -16,59 +16,19 @@ import java.util.List;
import junit.framework.Test;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Path;
public class CPPFunctionTemplateTests extends PDOMTestBase {
protected PDOM pdom;
protected ICProject cproject;
public class CPPFunctionTemplateTests extends PDOMInlineCodeTestBase {
public static Test suite() {
return suite(CPPFunctionTemplateTests.class);
}
@Override
public void setUp() throws Exception {
cproject= CProjectHelper.createCCProject("functionTemplateTests"+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
}
protected void setUpSections(int sections) throws Exception {
StringBuilder[] contents= TestSourceReader.getContentsForTest(
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), sections);
for (StringBuilder content : contents) {
IFile file= TestSourceReader.createFile(cproject.getProject(), new Path("refs.cpp"), content.toString());
}
IndexerPreferences.set(cproject.getProject(), IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
CCorePlugin.getIndexManager().reindex(cproject);
waitForIndexer(cproject);
pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
pdom.acquireReadLock();
}
@Override
protected void tearDown() throws Exception {
if(pdom!=null) {
pdom.releaseReadLock();
}
pdom= null;
cproject.getProject().delete(true, npm());
}
/*************************************************************************/
// template<typename X>

View file

@ -0,0 +1,189 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences.
* 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:
* Thomas Corbat (IFS) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import junit.framework.Test;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.core.runtime.CoreException;
import static org.eclipse.cdt.core.parser.tests.VisibilityAsserts.assertVisibility;
/**
* @author Thomas Corbat
*
* Tests for ensuring the PDOM contains the correct visibility information for class members.
*/
public class ClassMemberVisibilityTests extends PDOMInlineCodeTestBase {
public static Test suite() {
return suite(ClassMemberVisibilityTests.class);
}
public void setUp() throws Exception {
super.setUp();
setUpSections(1);
}
// class A {
// void defaultMemFun();
// public:
// void publicMemFun();
// protected:
// void protectedMemFun();
// private:
// void privateMemFun();
// };
public void testVisibilityDefaultMemberFunction() throws Exception {
IBinding[] defaultFunction = findQualifiedPossiblyImplicit(pdom, "A::defaultMemFun");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(defaultFunction[0]));
IBinding[] publicFunction = findQualifiedPossiblyImplicit(pdom, "A::publicMemFun");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(publicFunction[0]));
IBinding[] protectedFunction = findQualifiedPossiblyImplicit(pdom, "A::protectedMemFun");
assertVisibility(ICPPClassType.v_protected, getMemberVisibility(protectedFunction[0]));
IBinding[] privateFunction = findQualifiedPossiblyImplicit(pdom, "A::privateMemFun");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(privateFunction[0]));
}
// class A {
// int defaultVariable;
// public:
// int publicVariable;
// protected:
// int protectedVariable;
// private:
// int privateVariable;
// };
public void testVisibilityDefaultMemberVariable() throws Exception {
IBinding[] defaultVariable = findQualifiedPossiblyImplicit(pdom, "A::defaultVariable");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(defaultVariable[0]));
IBinding[] publicVariable = findQualifiedPossiblyImplicit(pdom, "A::publicVariable");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(publicVariable[0]));
IBinding[] protectedVariable = findQualifiedPossiblyImplicit(pdom, "A::protectedVariable");
assertVisibility(ICPPClassType.v_protected, getMemberVisibility(protectedVariable[0]));
IBinding[] privateVariable = findQualifiedPossiblyImplicit(pdom, "A::privateVariable");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(privateVariable[0]));
}
// class A {
// class DefaultNested {};
// public:
// class PublicNested {};
// protected:
// class ProtectedNested {};
// private:
// class PrivateNested {};
// };
public void testVisibilityDefaultNestedClass() throws Exception {
IBinding[] defaultNested = findQualifiedPossiblyImplicit(pdom, "A::DefaultNested");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(defaultNested[0]));
IBinding[] publicNested = findQualifiedPossiblyImplicit(pdom, "A::PublicNested");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(publicNested[0]));
IBinding[] protectedNested = findQualifiedPossiblyImplicit(pdom, "A::ProtectedNested");
assertVisibility(ICPPClassType.v_protected, getMemberVisibility(protectedNested[0]));
IBinding[] privateNested = findQualifiedPossiblyImplicit(pdom, "A::PrivateNested");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(privateNested[0]));
}
// class A {
// };
public void testVisibilityImplicitClassMembers() throws Exception {
IBinding[] memberBindings = findQualifiedPossiblyImplicit(pdom, "A::A");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[0]));
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[1]));
}
// template<typename T>
// class Tpl {
// };
// template<>
// class Tpl<int> {
// };
public void testVisibilityImplicitTemplateMembers() throws Exception {
IBinding[] memberBindings = findQualifiedPossiblyImplicit(pdom, "Tpl::Tpl");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[0]));
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[1]));
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[2]));
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[3]));
}
// template<typename T>
// class Tpl {
// };
// template<>
// class Tpl<int> {
// int specializedDefaultVariable;
// };
public void testVisibilitySpecializedDefaultVariable() throws Exception {
IBinding[] memberBindings = findQualifiedPossiblyImplicit(pdom, "Tpl::specializedDefaultVariable");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(memberBindings[0]));
}
// template<typename T>
// class Tpl {
// };
// template<>
// class Tpl<int> {
// public:
// int specializedPublicVariable;
// };
public void testVisibilitySpecializedPublicVariable() throws Exception {
IBinding[] memberBindings = findQualifiedPossiblyImplicit(pdom, "Tpl::specializedPublicVariable");
assertVisibility(ICPPClassType.v_public, getMemberVisibility(memberBindings[0]));
}
// template<typename T>
// class Tpl {
// };
// template<>
// class Tpl<int> {
// protected:
// int specializedProtectedVariable;
// };
public void testVisibilitySpecializedProtectedVariable() throws Exception {
IBinding[] memberBindings = findQualifiedPossiblyImplicit(pdom, "Tpl::specializedProtectedVariable");
assertVisibility(ICPPClassType.v_protected, getMemberVisibility(memberBindings[0]));
}
// template<typename T>
// class Tpl {
// };
// template<>
// class Tpl<int> {
// private:
// int specializedPrivateVariable;
// };
public void testVisibilitySpecializedPrivateVariable() throws Exception {
IBinding[] memberBinding = findQualifiedPossiblyImplicit(pdom, "Tpl::specializedPrivateVariable");
assertVisibility(ICPPClassType.v_private, getMemberVisibility(memberBinding[0]));
}
private int getMemberVisibility(IBinding memberBinding) throws CoreException {
IBinding owner = memberBinding.getOwner();
assertInstance(owner, ICPPClassType.class);
ICPPClassType classBinding = (ICPPClassType) owner;
return classBinding.getVisibility(memberBinding);
}
}

View file

@ -163,19 +163,19 @@ public class MethodTests extends PDOMTestBase {
}
public void testDefaultPrivateMethod() throws Exception {
assertVisibility(pdom, "Class3::defaultMethod", ICPPMember.v_private);
assertCPPMemberVisibility(pdom, "Class3::defaultMethod", ICPPMember.v_private);
}
public void testPrivateMethod() throws Exception {
assertVisibility(pdom, "Class3::privateMethod", ICPPMember.v_private);
assertCPPMemberVisibility(pdom, "Class3::privateMethod", ICPPMember.v_private);
}
public void testProtectedMethod() throws Exception {
assertVisibility(pdom, "Class3::protectedMethod", ICPPMember.v_protected);
assertCPPMemberVisibility(pdom, "Class3::protectedMethod", ICPPMember.v_protected);
}
public void testPublicMethod() throws Exception {
assertVisibility(pdom, "Class3::publicMethod", ICPPMember.v_public);
assertCPPMemberVisibility(pdom, "Class3::publicMethod", ICPPMember.v_public);
}
public void testInlineMethod() throws Exception {

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences.
* 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:
* Thomas Corbat (IFS) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Path;
/**
* @author Thomas Corbat
*
* Base class for PDOM tests relying on code placed in comments in front
* of the test.
*/
public class PDOMInlineCodeTestBase extends PDOMTestBase {
protected PDOM pdom;
protected ICProject cproject;
public void setUp() throws Exception {
cproject = CProjectHelper.createCCProject("classTemplateTests" + System.currentTimeMillis(),
"bin", IPDOMManager.ID_NO_INDEXER);
}
protected void setUpSections(int sections) throws Exception {
CharSequence[] contents = TestSourceReader.getContentsForTest(
CTestPlugin.getDefault().getBundle(), "parser", getClass(),
getName(), sections);
for (CharSequence content : contents) {
IFile file = TestSourceReader.createFile(cproject.getProject(),
new Path("refs.cpp"), content.toString());
}
IndexerPreferences
.set(cproject.getProject(), IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
waitForIndexer(cproject);
pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
pdom.acquireReadLock();
}
@Override
protected void tearDown() throws Exception {
if (pdom != null) {
pdom.releaseReadLock();
}
pdom = null;
cproject.getProject().delete(true, npm());
}
}

View file

@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.tests.VisibilityAsserts;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
@ -202,11 +203,11 @@ public class PDOMTestBase extends BaseTestCase {
assertTrue(c.isAssignableFrom(bindings[0].getClass()));
}
protected void assertVisibility(PDOM pdom, String name, int visibility) throws CoreException, DOMException {
protected void assertCPPMemberVisibility(PDOM pdom, String name, int visibility) throws CoreException, DOMException {
IBinding[] bindings = findQualifiedName(pdom, name);
assertEquals(1, bindings.length);
ICPPMember member = (ICPPMember) bindings[0];
assertEquals(visibility, member.getVisibility());
VisibilityAsserts.assertVisibility(visibility, member.getVisibility());
}
public static final void assertFunctionRefCount(PDOM pdom, Class[] args, IBinding[] bindingPool, int refCount) throws CoreException {

View file

@ -50,6 +50,7 @@ public class PDOMTests extends TestSuite {
suite.addTest(CPPFunctionTemplateTests.suite());
suite.addTest(MethodTests.suite());
suite.addTest(NamespaceTests.suite());
suite.addTest(ClassMemberVisibilityTests.suite());
suite.addTest(CFunctionTests.suite());
suite.addTest(CVariableTests.suite());

View file

@ -24,6 +24,18 @@ import org.eclipse.cdt.core.dom.ast.IField;
public interface ICPPClassType extends ICompositeType, ICPPBinding {
public static final ICPPClassType[] EMPTY_CLASS_ARRAY = {};
public static final int k_class = ICPPASTCompositeTypeSpecifier.k_class;
/**
* @since 5.5
*/
public static final int v_public = ICPPASTVisibilityLabel.v_public;
/**
* @since 5.5
*/
public static final int v_protected = ICPPASTVisibilityLabel.v_protected;
/**
* @since 5.5
*/
public static final int v_private = ICPPASTVisibilityLabel.v_private;
/**
* Returns an array of base class relationships. The returned array is empty if there
@ -107,4 +119,18 @@ public interface ICPPClassType extends ICompositeType, ICPPBinding {
* @since 5.5
*/
public boolean isFinal();
/**
* Gets the access specifier of the <code>member</code>.
*
* @param member The binding of the member to get the visibility for.
* <code>member</code> must be a member of this type.
*
* @return the visibility of the specified member.
*
* @throws IllegalArgumentException if <code>member</code> is not a member of this type.
*
* @since 5.5
*/
public int getVisibility(IBinding member);
}

View file

@ -447,4 +447,9 @@ public class CPPClassSpecialization extends CPPSpecialization
}
return false;
}
@Override
public int getVisibility(IBinding member) {
return ClassTypeHelper.getVisibility(this, member);
}
}

View file

@ -251,4 +251,9 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass
}
return false;
}
@Override
public int getVisibility(IBinding member) {
return ClassTypeHelper.getVisibility(this, member);
}
}

View file

@ -109,6 +109,10 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
public boolean isFinal() {
return false;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}
private IASTName definition;
@ -413,4 +417,9 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
}
return name;
}
@Override
public int getVisibility(IBinding member) {
return ClassTypeHelper.getVisibility(this, member);
}
}

View file

@ -344,6 +344,10 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
return false;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
private final class ClassScope implements ICPPClassScope {
@Override

View file

@ -246,4 +246,9 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPD
}
return new PDOMCPPDeferredClassInstance(fragment, (ICPPClassTemplate) template, args);
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}

View file

@ -246,4 +246,9 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
public boolean isFinal() {
return false;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}

View file

@ -133,4 +133,9 @@ public class CPPUnknownMemberClass extends CPPUnknownMember implements ICPPUnkno
public boolean isFinal() {
return false;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}

View file

@ -16,20 +16,11 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -41,12 +32,16 @@ import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAliasDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -72,6 +67,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Holds common implementation of methods for ICPPClassType implementations that have
* a corresponding textual definition in the source code.
@ -885,6 +890,106 @@ public class ClassTypeHelper {
return resultArray;
}
/**
* Returns the visibility for a given <code>member</code> in the <code>host</code>.
* Throws an IllegalArgumentException if <code>member</code> is not a member of <code>host</code>
*
* @param classType The class to get the member's visibility specifier of.
* @return the visibility of the <code>member</code>.
*/
public static int getVisibility(ICPPInternalClassTypeMixinHost classType, IBinding member) {
if (classType.getDefinition() == null) {
classType.checkForDefinition();
if (classType.getDefinition() == null) {
ICPPClassType backup = getBackupDefinition(classType);
if (backup != null) {
return backup.getVisibility(member);
}
return ICPPClassType.v_public; // Fallback visibility
}
}
int visibility =
classType.getKey() == ICPPClassType.k_class ? ICPPClassType.v_private : ICPPClassType.v_public;
IASTDeclaration[] hostMembers = classType.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration hostMember : hostMembers) {
if (hostMember instanceof ICPPASTVisibilityLabel) {
visibility = ((ICPPASTVisibilityLabel) hostMember).getVisibility();
}
while (hostMember instanceof ICPPASTTemplateDeclaration) {
hostMember = ((ICPPASTTemplateDeclaration) hostMember).getDeclaration();
}
if (hostMember instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration memberDeclaration = (IASTSimpleDeclaration) hostMember;
for (IASTDeclarator memberDeclarator : memberDeclaration.getDeclarators()) {
IBinding memberBinding =
ASTQueries.findInnermostDeclarator(memberDeclarator).getName().resolveBinding();
if (member.equals(memberBinding)){
return visibility;
}
}
IASTDeclSpecifier declSpec = memberDeclaration.getDeclSpecifier();
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
IBinding memberBinding =
((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
if (member.equals(memberBinding)) {
return visibility;
}
if (member instanceof IType && memberBinding instanceof IType &&
((IType) member).isSameType((IType) memberBinding)) {
return visibility;
}
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier
&& memberDeclaration.getDeclarators().length == 0) {
IBinding memberBinding =
((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding();
if (member.equals(memberBinding)) {
return visibility;
}
} else if (declSpec instanceof ICPPASTEnumerationSpecifier) {
IBinding enumerationBinding = ((ICPPASTEnumerationSpecifier) declSpec).getName().resolveBinding();
if (member.equals(enumerationBinding)) {
return visibility;
}
if (member instanceof IType && enumerationBinding instanceof IType &&
((IType) member).isSameType((IType) enumerationBinding)) {
return visibility;
}
}
} else if (hostMember instanceof IASTFunctionDefinition) {
IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) hostMember).getDeclarator();
IBinding functionBinding = declarator.getName().resolveBinding();
if (member.equals(functionBinding)){
return visibility;
}
} else if (hostMember instanceof ICPPASTAliasDeclaration) {
IBinding aliasBinding = ((ICPPASTAliasDeclaration) hostMember).getAlias().resolveBinding();
if (member.equals(aliasBinding)) {
return visibility;
}
} else if (hostMember instanceof ICPPASTUsingDeclaration) {
IBinding usingBinding = ((ICPPASTUsingDeclaration) hostMember).getName().resolveBinding();
if (member.equals(usingBinding)) {
return visibility;
}
} else if (hostMember instanceof ICPPASTNamespaceDefinition) { // Not valid but possible due to the parser
IBinding namespaceBinding = ((ICPPASTNamespaceDefinition) hostMember).getName().resolveBinding();
if (member.equals(namespaceBinding)) {
return visibility;
}
}
}
ICPPMethod[] implicitMethods = getImplicitMethods(classType, null);
for (ICPPMethod implicitMethod : implicitMethods) {
if (member.equals(implicitMethod)) {
return ICPPClassType.v_public;
}
}
throw new IllegalArgumentException(member.getName() + " is not a member of " + classType.getName()); //$NON-NLS-1$
}
private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType,
Map<ICPPClassType, Map<String, List<ICPPMethod>>> cache, IASTNode point) {
Map<String, List<ICPPMethod>> result = cache.get(classType);

View file

@ -22,13 +22,6 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
@ -214,6 +207,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Collection of methods to extract information from a C++ translation unit.
*/
@ -2521,7 +2521,11 @@ public class CPPVisitor extends ASTQueries {
}
if (--i < 0)
break;
return bindingToOwner(qn[i].resolveBinding());
IBinding binding = qn[i].resolveBinding();
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding = ((CPPASTTranslationUnit) name.getTranslationUnit()).mapToAST((ICPPClassType) binding, name);
}
return bindingToOwner(binding);
}
name= (IASTName) node;
node= node.getParent();

View file

@ -17,7 +17,6 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
@ -215,4 +214,9 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
public boolean isFinal() {
return ((ICPPClassType) rbinding).isFinal();
}
@Override
public int getVisibility(IBinding member) {
return ((ICPPClassType) rbinding).getVisibility(member);
}
}

View file

@ -179,4 +179,9 @@ public class CompositeCPPTemplateTemplateParameter extends CompositeCPPBinding
public boolean isFinal() {
return false;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}

View file

@ -16,20 +16,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IPDOMNode;
@ -97,6 +83,20 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Database for storing semantic information for one project.
*/
@ -237,6 +237,7 @@ public class PDOM extends PlatformObject implements IPDOM {
* 143.0 - Store implied object type in EvalFunctionSet, bug 402409.
* 144.0 - Add support for storing function sets with zero functions in EvalFunctionSet, bug 402498.
* 145.0 - Changed marshalling of CPPBasicType to store the associated numerical value, bug 407808.
* 146.0 - Added visibility support on class type level, bug 402878.
*/
private static final int MIN_SUPPORTED_VERSION= version(145, 0);
private static final int MAX_SUPPORTED_VERSION= version(145, Short.MAX_VALUE);

View file

@ -621,6 +621,11 @@ public class PDOMASTAdapter {
public boolean isFinal() {
return false;
}
@Override
public int getVisibility(IBinding member) {
return ((ICPPClassType) fDelegate).getVisibility(member);
}
}

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
/**
@ -32,4 +33,11 @@ public interface IPDOMCPPClassType extends ICPPClassType, IPDOMBinding, IIndexTy
* Returns the scope name, for use in {@link IScope#getScopeName()}
*/
IIndexName getScopeName();
/**
* Sets the visibility specifier of a given member.
* @param member The binding specifying the member.
* @param visibility The visibility of the <code>member</code>.
*/
void addMember(PDOMNode member, int visibility) throws CoreException;
}

View file

@ -14,12 +14,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -43,7 +37,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@ -51,20 +44,26 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Bryan Wilkinson
*/
class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
ICPPClassSpecialization, IPDOMMemberOwner, IPDOMCPPClassType {
private static final int FIRST_BASE = PDOMCPPSpecialization.RECORD_SIZE + 0;
private static final int MEMBER_LIST = PDOMCPPSpecialization.RECORD_SIZE + 4;
private static final int FINAL = PDOMCPPSpecialization.RECORD_SIZE + 8; // byte
private static final int MEMBERLIST = FIRST_BASE + 4;
private static final int FINAL = MEMBERLIST + PDOMCPPMemberBlock.RECORD_SIZE; // byte
/**
* The size in bytes of a PDOMCPPClassSpecialization record in the database.
*/
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 9;
protected static final int RECORD_SIZE = FINAL + 1;
private volatile ICPPClassScope fScope;
private ObjectMap specializationMap; // Obtained from the synchronized PDOM cache
@ -442,14 +441,13 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
@Override
public void addChild(PDOMNode member) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBER_LIST);
list.addMember(member);
throw new UnsupportedOperationException("addMember method should be called instead."); //$NON-NLS-1$
}
@Override
public void acceptUncached(IPDOMVisitor visitor) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBER_LIST);
list.accept(visitor);
PDOMCPPMemberBlock members = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
members.accept(visitor);
}
@Override
@ -475,4 +473,32 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
private void setFinal(ICPPClassType ct) throws CoreException {
getDB().putByte(record + FINAL, (byte) (ct.isFinal() ? 1 : 0));
}
@Override
public void addMember(PDOMNode member, int visibility) {
try {
PDOMCPPMemberBlock members = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
members.addMember(member, visibility);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
@Override
public int getVisibility(IBinding member) {
try {
PDOMCPPMemberBlock members = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
int visibility = members.getVisibility(member);
if (visibility < 0) {
if (member instanceof ICPPSpecialization) {
return getSpecializedBinding().getVisibility(((ICPPSpecialization) member).getSpecializedBinding());
}
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
return visibility;
} catch (CoreException e) {
CCorePlugin.log(e);
return v_private; // Fallback visibility
}
}
}

View file

@ -35,7 +35,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
@ -50,14 +49,14 @@ import java.util.List;
* @author Doug Schaefer
*/
class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDOMMemberOwner {
private static final int FIRSTBASE = PDOMCPPBinding.RECORD_SIZE + 0;
private static final int MEMBERLIST = PDOMCPPBinding.RECORD_SIZE + 4;
private static final int FIRSTFRIEND = PDOMCPPBinding.RECORD_SIZE + 8;
private static final int KEY = PDOMCPPBinding.RECORD_SIZE + 12; // byte
private static final int ANONYMOUS= PDOMCPPBinding.RECORD_SIZE + 13; // byte
private static final int FINAL = PDOMCPPBinding.RECORD_SIZE + 14; // byte
private static final int FIRSTBASE = PDOMCPPBinding.RECORD_SIZE;
private static final int MEMBERLIST = FIRSTBASE + 4;
private static final int FIRSTFRIEND = MEMBERLIST + PDOMCPPMemberBlock.RECORD_SIZE;
private static final int KEY = FIRSTFRIEND + 4; // byte
private static final int ANONYMOUS = KEY + 1; // byte
private static final int FINAL = ANONYMOUS + 1; // byte
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPBinding.RECORD_SIZE + 15;
protected static final int RECORD_SIZE = FINAL + 1;
private PDOMCPPClassScope fScope; // No need for volatile, all fields of PDOMCPPClassScope are final.
@ -114,9 +113,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
@Override
public final void addChild(PDOMNode member) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST);
list.addMember(member);
PDOMCPPClassScope.updateCache(this, member);
throw new UnsupportedOperationException("addMember method should be called instead."); //$NON-NLS-1$
}
@Override
@ -130,7 +127,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
@Override
public void acceptUncached(IPDOMVisitor visitor) throws CoreException {
super.accept(visitor);
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST);
PDOMCPPMemberBlock list = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
list.accept(visitor);
}
@ -143,7 +140,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
long rec = base != null ? base.getRecord() : 0;
getDB().putRecPtr(record + FIRSTBASE, rec);
}
public void addBases(PDOMName classDefName, ICPPBase[] bases) throws CoreException {
getPDOM().removeCachedResult(record + PDOMCPPLinkage.CACHE_BASES);
final PDOMLinkage linkage = getLinkage();
@ -192,7 +189,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
}
}
public void addFriend(PDOMCPPFriend friend) throws CoreException {
PDOMCPPFriend firstFriend = getFirstFriend();
friend.setNextFriend(firstFriend);
@ -255,7 +252,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
return getDB().getByte(record + ANONYMOUS) != 0;
} catch (CoreException e) {
CCorePlugin.log(e);
return false;
return false;
}
}
@ -263,7 +260,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
public boolean isFinal() {
try {
return getDB().getByte(record + FINAL) != 0;
} catch (CoreException e){
} catch (CoreException e) {
CCorePlugin.log(e);
return false;
}
@ -309,7 +306,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
ICPPBase[] bases= (ICPPBase[]) getPDOM().getCachedResult(key);
if (bases != null)
return bases;
try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase())
@ -388,7 +385,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
@Override
public ICPPMethod[] getMethods() {
public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this, null);
}
@ -396,23 +393,48 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this, null);
}
@Override
public IField[] getFields() {
return ClassTypeHelper.getFields(this, null);
}
@Override
public IField findField(String name) {
return ClassTypeHelper.findField(this, name);
}
@Override
public Object clone() {
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
@Override
public void addMember(PDOMNode member, int visibility) {
try {
PDOMCPPMemberBlock members = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
members.addMember(member, visibility);
PDOMCPPClassScope.updateCache(this, member);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
@Override
public int getVisibility(IBinding member) {
try {
PDOMCPPMemberBlock members = new PDOMCPPMemberBlock(getLinkage(), record + MEMBERLIST);
int visibility = members.getVisibility(member);
if (visibility < 0)
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
return visibility;
} catch (CoreException e) {
CCorePlugin.log(e);
return v_private; // Fallback visibility
}
}
}

View file

@ -14,10 +14,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -87,6 +83,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
@ -133,6 +130,10 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Container for c++-entities.
*/
@ -487,9 +488,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (pdomBinding != null) {
pdomBinding.setLocalToFileRec(fileLocalRec);
parent.addChild(pdomBinding);
addChild(parent, pdomBinding, binding);
if (parent2 != null) {
parent2.addChild(pdomBinding);
addChild(parent2, pdomBinding, binding);
}
if (parent != this && parent2 != this) {
insertIntoNestedBindingsIndex(pdomBinding);
@ -499,6 +500,45 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return pdomBinding;
}
/**
* Returns visibility of the member binding in its containing class, or -1 if the binding is
* not a class member.
*/
private static int getVisibility(IBinding binding) {
while (binding instanceof ICPPSpecialization) {
binding = ((ICPPSpecialization) binding).getSpecializedBinding();
}
if (binding instanceof CPPImplicitMethod)
return ICPPClassType.v_public;
int visibility = -1;
IBinding bindingOwner = binding.getOwner();
if (bindingOwner instanceof ICPPClassType) {
if (bindingOwner instanceof CPPClosureType)
return ICPPClassType.v_public;
visibility = ((ICPPClassType) bindingOwner).getVisibility(binding);
}
return visibility;
}
private static void addChild(PDOMNode parent, PDOMBinding binding, IBinding originalBinding)
throws CoreException {
if (parent instanceof IPDOMCPPClassType) {
if (originalBinding instanceof IEnumerator)
originalBinding = originalBinding.getOwner();
int visibility = getVisibility(originalBinding);
if (visibility >= 0) {
((IPDOMCPPClassType) parent).addMember(binding, visibility);
return;
}
originalBinding.getOwner();
visibility = getVisibility(originalBinding);
}
parent.addChild(binding);
}
@Override
public void addChild(PDOMNode node) throws CoreException {
super.addChild(node);
@ -972,7 +1012,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
file.setLastUsingDirective(ud.getRecord());
}
} else if (parentNode instanceof ICPPASTElaboratedTypeSpecifier) {
ICPPASTElaboratedTypeSpecifier elaboratedSpecifier = (ICPPASTElaboratedTypeSpecifier)parentNode;
ICPPASTElaboratedTypeSpecifier elaboratedSpecifier = (ICPPASTElaboratedTypeSpecifier) parentNode;
if (elaboratedSpecifier.isFriend()) {
pdomName.setIsFriendSpecifier();
PDOMName enclClassName = (PDOMName) pdomName.getEnclosingDefinition();

View file

@ -0,0 +1,197 @@
/*******************************************************************************
* Copyright (c) 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences.
* 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:
* Thomas Corbat (IFS) - Initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
/**
* PDOMCPPMemberBlock stores the members of a composite type and maps every member to
* the corresponding visibility.
*/
public class PDOMCPPMemberBlock {
/*
* The MAX_MEMBER_COUNT was chosen empirically by comparing PDOM file sizes of a real-life
* project. Six members per block resulted in the most compact PDOM.
*/
private static final int MAX_MEMBER_COUNT = 6;
private static final int VISIBILITY_BITS = 2;
private static final int VISIBILITY_MASK = (1 << VISIBILITY_BITS) - 1;
private static final int VISIBILITY_VALUES_PER_BYTE = 8 / VISIBILITY_BITS;
private static final int MEMBER_POINTERS = 0;
private static final int MEMBER_VISIBILITIES =
MEMBER_POINTERS + Database.PTR_SIZE * MAX_MEMBER_COUNT;
private static final int NEXT_MEMBER_BLOCK =
MEMBER_VISIBILITIES + (MAX_MEMBER_COUNT + VISIBILITY_VALUES_PER_BYTE - 1) / VISIBILITY_VALUES_PER_BYTE;
protected static final int RECORD_SIZE = NEXT_MEMBER_BLOCK + Database.PTR_SIZE;
static {
assert (MAX_MEMBER_COUNT > 0);
}
private final PDOMLinkage linkage;
private final long record;
private int nextMemberPosition = -1;
public PDOMCPPMemberBlock(PDOMLinkage linkage, long record) throws CoreException {
this.linkage = linkage;
this.record = record;
}
public PDOMCPPMemberBlock(PDOMLinkage linkage) throws CoreException {
Database db = linkage.getDB();
this.linkage = linkage;
this.record = db.malloc(RECORD_SIZE);
db.clearBytes(record, RECORD_SIZE);
}
private int getNextPosition() throws CoreException {
if (nextMemberPosition < 0) {
nextMemberPosition = 0;
while (nextMemberPosition < MAX_MEMBER_COUNT && getMemberRecord(nextMemberPosition) != 0) {
nextMemberPosition++;
}
}
return nextMemberPosition;
}
private Database getDB() {
return linkage.getDB();
}
public long getRecord() {
return record;
}
public void setNextBlock(PDOMCPPMemberBlock nextBlock) throws CoreException {
long rec = nextBlock != null ? nextBlock.getRecord() : 0;
getDB().putRecPtr(record + NEXT_MEMBER_BLOCK, rec);
}
public PDOMCPPMemberBlock getNextBlock() throws CoreException {
long rec = getDB().getRecPtr(record + NEXT_MEMBER_BLOCK);
return rec != 0 ? new PDOMCPPMemberBlock(linkage, rec) : null;
}
public void addMember(PDOMNode member, int visibility) throws CoreException {
if (getNextPosition() == MAX_MEMBER_COUNT) {
PDOMCPPMemberBlock nextBlock = getNextBlock();
if (nextBlock == null) {
nextBlock = new PDOMCPPMemberBlock(linkage);
setNextBlock(nextBlock);
}
nextBlock.addMember(member, visibility);
} else {
long memberLocationOffset = getMemberOffset(getNextPosition());
long rec = member.getRecord();
getDB().putRecPtr(memberLocationOffset, rec);
setVisibility(getNextPosition(), visibility);
nextMemberPosition++;
}
}
public void accept(IPDOMVisitor visitor) throws CoreException {
PDOMCPPMemberBlock current = this;
do {
current.visitBlock(visitor);
} while ((current = current.getNextBlock()) != null);
}
private void visitBlock(IPDOMVisitor visitor) throws CoreException {
if (record == 0) {
throw new NullPointerException();
}
int item = 0;
long memberRecord;
while (item < MAX_MEMBER_COUNT && (memberRecord = getMemberRecord(item++)) != 0) {
PDOMNode node = linkage.getNode(memberRecord);
if (visitor.visit(node) && node != null) {
node.accept(visitor);
}
visitor.leave(node);
}
}
public void delete() throws CoreException {
getDB().free(record);
}
private long getMemberRecord(int memberIndex) throws CoreException {
return getDB().getRecPtr(getMemberOffset(memberIndex));
}
private long getMemberOffset(int memberIndex) {
return record + MEMBER_POINTERS + Database.PTR_SIZE * memberIndex;
}
private PDOMNode getMember(int memberIndex) throws CoreException {
if (memberIndex < getNextPosition() && memberIndex < MAX_MEMBER_COUNT) {
long memberRecord = getMemberRecord(memberIndex);
if (memberRecord != 0) {
PDOMNode node = linkage.getNode(memberRecord);
return node;
}
}
return null;
}
private void setVisibility(int memberIndex, int newVisibility) throws CoreException {
newVisibility &= VISIBILITY_MASK;
int visibilityBitOffset = memberIndex % VISIBILITY_VALUES_PER_BYTE;
long visibilityOffset = record + MEMBER_VISIBILITIES + memberIndex / VISIBILITY_VALUES_PER_BYTE;
int visibility = getDB().getByte(visibilityOffset);
// Resetting the previous visibility bits of the target member
visibility &= ~(VISIBILITY_MASK << visibilityBitOffset * VISIBILITY_BITS);
// Setting the new visibility bits of the target member
visibility |= newVisibility << visibilityBitOffset * VISIBILITY_BITS;
getDB().putByte(visibilityOffset, (byte) visibility);
}
/**
* Returns visibility of the member, or -1 if the given binding is not a member.
*/
public int getVisibility(IBinding member) throws CoreException {
for (PDOMCPPMemberBlock block = this; block != null; block = block.getNextBlock()) {
for (int memberIndex = 0; memberIndex < block.getNextPosition(); memberIndex++) {
PDOMNode candidate = block.getMember(memberIndex);
if (candidate == null)
return -1;
if (candidate.equals(member))
return block.getVisibility(memberIndex);
}
}
return -1;
}
private int getVisibility(int memberIndex) throws CoreException {
int visibilityBitOffset = memberIndex % VISIBILITY_VALUES_PER_BYTE;
long visibilityOffset = record + MEMBER_VISIBILITIES + memberIndex / VISIBILITY_VALUES_PER_BYTE;
int visibility = getDB().getByte(visibilityOffset);
visibility >>>= visibilityBitOffset * VISIBILITY_BITS;
// Filtering the visibility bits of the target member
visibility &= VISIBILITY_MASK;
return visibility;
}
}

View file

@ -365,4 +365,9 @@ public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding
public ICPPDeferredClassInstance asDeferredInstance() {
return null;
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}