~ubuntu-branches/debian/sid/eclipse-cdt/sid

« back to all changes in this revision

Viewing changes to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2013-10-03 20:30:16 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20131003203016-d4ug6l0xgosasumq
Tags: 8.2.1-1
* New upstream release.
* Updated autotools documentation sources.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
import java.util.Collections;
20
20
import java.util.HashMap;
21
21
import java.util.HashSet;
22
 
import java.util.Iterator;
23
22
import java.util.LinkedList;
24
23
import java.util.List;
25
24
import java.util.Map;
26
 
import java.util.Set;
27
25
 
28
26
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
29
27
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
85
83
 * @see CPPClassTemplate
86
84
 */
87
85
public class ClassTypeHelper {
88
 
        private static final String DESTRUCTOR_OVERRIDE_KEY = "~"; //$NON-NLS-1$
89
 
 
90
86
        public static IBinding[] getFriends(ICPPInternalClassTypeMixinHost host) {
91
87
                if (host.getDefinition() == null) {
92
88
                        host.checkForDefinition();
282
278
        /**
283
279
         * Returns all direct and indirect base classes.
284
280
         * @param classType a class
285
 
         * @return An array of visible base classes in arbitrary order.
 
281
         * @return An array of base classes in arbitrary order.
286
282
         */
287
283
        public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) {
288
284
                HashSet<ICPPClassType> result= new HashSet<ICPPClassType>();
309
305
         * Checks inheritance relationship between two classes.
310
306
         * @return <code>true</code> if {@code subclass} is a subclass of {@code superclass}.
311
307
         */
312
 
        public static boolean isSubclass(ICPPClassType subclass, ICPPClassType superclass) {
313
 
                ICPPBase[] bases= subclass.getBases();
 
308
        public static boolean isSubclass(ICPPClassType subclass, ICPPClassType superclass, IASTNode point) {
 
309
                ICPPBase[] bases= getBases(subclass, point);
314
310
                for (ICPPBase base : bases) {
315
311
                        IBinding b= base.getBaseClass();
316
312
                        if (b instanceof ICPPClassType) {
318
314
                                if (baseClass.isSameType(superclass)) {
319
315
                                        return true;
320
316
                                }
321
 
                                if (isSubclass(baseClass, superclass)) {
 
317
                                if (isSubclass(baseClass, superclass, point)) {
322
318
                                        return true;
323
319
                                }
324
320
                        }
350
346
         * Returns methods either declared by the given class or generated by the compiler. Does not
351
347
         * include methods declared in base classes.
352
348
         */
353
 
        private static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType, IASTNode point) {
 
349
        public static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType, IASTNode point) {
354
350
                ObjectSet<ICPPMethod> set= new ObjectSet<ICPPMethod>(4);
355
351
                set.addAll(ClassTypeHelper.getDeclaredMethods(classType, point));
356
352
                set.addAll(getImplicitMethods(classType, point));
617
613
                if (visitedBefore != null)
618
614
                        return visitedBefore;
619
615
 
620
 
                ICPPMethod[] methods= classType.getDeclaredMethods();
 
616
                ICPPMethod[] methods= ClassTypeHelper.getDeclaredMethods(classType, point);
621
617
                ICPPMethod candidate= null;
622
618
                boolean hasOverridden= false;
623
619
                for (ICPPMethod method : methods) {
624
 
                        if (CharArrayUtils.equals(methodName, method.getNameCharArray()) &&
625
 
                                        functionTypesAllowOverride(methodType, method.getType())) {
 
620
                        if (methodName[0] == '~' && method.isDestructor() 
 
621
                                || (CharArrayUtils.equals(methodName, method.getNameCharArray())
 
622
                                        && functionTypesAllowOverride(methodType, method.getType()))) {
626
623
                                candidate= method;
627
624
                                hasOverridden= method.isVirtual();
628
625
                                break;
833
830
                return null;
834
831
        }
835
832
 
836
 
        private static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
 
833
        public static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) {
837
834
                switch (kind) {
838
835
                case DEFAULT_CTOR:
839
836
                case COPY_CTOR:
865
862
        }
866
863
 
867
864
        /**
868
 
         * Checks whether class is abstract, i.e. has pure virtual functions that were
869
 
         * not implemented in base after declaration.
870
 
         *
871
 
         * NOTE: The method produces complete results for template instantiations
872
 
         * but doesn't take into account base classes and methods dependent on unspecified
873
 
         * template parameters.
874
 
         */
875
 
        public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType, IASTNode point) {
876
 
                Map<String, List<ICPPMethod>> result= collectPureVirtualMethods(classType,
877
 
                                new HashMap<ICPPClassType, Map<String, List<ICPPMethod>>>(), point);
878
 
 
879
 
                int resultArraySize = 0;
880
 
                for (List<ICPPMethod> methods : result.values()) {
881
 
                        resultArraySize += methods.size();
882
 
                }
883
 
                ICPPMethod[] resultArray = new ICPPMethod[resultArraySize];
884
 
                int resultArrayIdx = 0;
885
 
                for (List<ICPPMethod> methods : result.values()) {
886
 
                        for (ICPPMethod method : methods) {
887
 
                                resultArray[resultArrayIdx++] = method;
888
 
                        }
889
 
                }
890
 
                return resultArray;
891
 
        }
892
 
 
893
 
        /**
894
865
         * Returns the visibility for a given <code>member</code> in the <code>host</code>.
895
866
         * Throws an IllegalArgumentException if <code>member</code> is not a member of <code>host</code>
896
867
         *
1035
1006
                        name = "<anonymous>"; //$NON-NLS-1$
1036
1007
                return new IllegalArgumentException(name + " is not a member of " + classType.getName()); //$NON-NLS-1$
1037
1008
        }
1038
 
 
1039
 
        private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType,
1040
 
                        Map<ICPPClassType, Map<String, List<ICPPMethod>>> cache, IASTNode point) {
1041
 
                Map<String, List<ICPPMethod>> result = cache.get(classType);
1042
 
                if (result != null)
1043
 
                        return result;
1044
 
 
1045
 
                result= new HashMap<String, List<ICPPMethod>>();
1046
 
                cache.put(classType, result);
1047
 
 
1048
 
                // Look at the pure virtual methods of the base classes
1049
 
                Set<IBinding> handledBaseClasses= new HashSet<IBinding>();
1050
 
                for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) {
1051
 
                        final IBinding baseClass = base.getBaseClass();
1052
 
                        if (baseClass instanceof ICPPClassType && handledBaseClasses.add(baseClass)) {
1053
 
                                Map<String, List<ICPPMethod>> pureVirtuals = collectPureVirtualMethods((ICPPClassType) baseClass, cache, point);
1054
 
                                // Merge derived pure virtual methods
1055
 
                                for (String key : pureVirtuals.keySet()) {
1056
 
                                        List<ICPPMethod> list = result.get(key);
1057
 
                                        if (list == null) {
1058
 
                                                list= new ArrayList<ICPPMethod>();
1059
 
                                                result.put(key, list);
1060
 
                                        }
1061
 
                                        list.addAll(pureVirtuals.get(key));
1062
 
                                }
1063
 
                        }
1064
 
                }
1065
 
 
1066
 
                // Remove overridden pure-virtual methods and add in new pure virtuals.
1067
 
                final ObjectSet<ICPPMethod> methods = getOwnMethods(classType, point);
1068
 
                for (ICPPMethod method : methods) {
1069
 
                        String key= getMethodNameForOverrideKey(method);
1070
 
                        List<ICPPMethod> list = result.get(key);
1071
 
                        if (list != null) {
1072
 
                                final ICPPFunctionType methodType = method.getType();
1073
 
                                for (Iterator<ICPPMethod> it= list.iterator(); it.hasNext(); ) {
1074
 
                                        ICPPMethod pureVirtual = it.next();
1075
 
                                        if (functionTypesAllowOverride(methodType, pureVirtual.getType())) {
1076
 
                                                it.remove();
1077
 
                                        }
1078
 
                                }
1079
 
                        }
1080
 
                        if (method.isPureVirtual()) {
1081
 
                                if (list == null) {
1082
 
                                        list= new ArrayList<ICPPMethod>();
1083
 
                                        result.put(key, list);
1084
 
                                }
1085
 
                                list.add(method);
1086
 
                        } else if (list != null && list.isEmpty()) {
1087
 
                                result.remove(key);
1088
 
                        }
1089
 
                }
1090
 
                return result;
1091
 
        }
1092
 
 
1093
 
        private static String getMethodNameForOverrideKey(ICPPMethod method) {
1094
 
                if (method.isDestructor()) {
1095
 
                        // Destructor's names may differ but they will override each other.
1096
 
                        return DESTRUCTOR_OVERRIDE_KEY;
1097
 
                } else {
1098
 
                        return method.getName();
1099
 
                }
1100
 
        }
1101
1009
}