/******************************************************************************* * Copyright (c) 2006, 2010 IBM Corporation. * 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: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; 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.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation; class PDOMCPPAnnotation { // "Mutable" shares the same offset as "inline" because // only fields can be mutable and only functions can be inline. public static final int MUTABLE_OFFSET = PDOMCAnnotation.INLINE_OFFSET; // extern C shares the same offset as visibility because // only members have visibility and cannot be extern C. public static final int EXTERN_C_OFFSET= 6; public static final int VISIBILITY_OFFSET = 6; private static final int VISIBILITY_MASK = 0x03; // Extra C++-specific annotations that don't fit on the first // byte of annotations. public static final int VIRTUAL_OFFSET = 0; public static final int DESTRUCTOR_OFFSET = 1; public static final int IMPLICIT_METHOD_OFFSET = 2; public static final int EXPLICIT_METHOD_OFFSET = 3; public static final int PURE_VIRTUAL_OFFSET = 4; public static final int MAX_EXTRA_OFFSET= PURE_VIRTUAL_OFFSET; /** * Encodes storage class specifiers and other annotation, including * C++-specific annotation, from an IBinding as a bit vector. * * @param binding the IBinding whose annotation will be encoded. * @return a bit vector of the annotation. */ public static byte encodeAnnotation(IBinding binding) { byte modifiers = PDOMCAnnotation.encodeAnnotation(binding); if (binding instanceof ICPPMember) { ICPPMember member = (ICPPMember) binding; int mask = ~(VISIBILITY_MASK << VISIBILITY_OFFSET); modifiers &= mask; modifiers |= (member.getVisibility() & VISIBILITY_MASK) << VISIBILITY_OFFSET; if (binding instanceof ICPPField) { ICPPField variable = (ICPPField) binding; modifiers |= (variable.isMutable() ? 1 : 0) << MUTABLE_OFFSET; } } else { if (binding instanceof ICPPFunction) { if (((ICPPFunction) binding).isExternC()) { modifiers |= 1 << EXTERN_C_OFFSET; } } if (binding instanceof ICPPVariable) { if (((ICPPVariable) binding).isExternC()) { modifiers |= 1 << EXTERN_C_OFFSET; } } } return modifiers; } /** * Encodes C++-specific annotation not already handled by * encodeAnnotation() as a bit vector. * * @param binding the IBinding whose annotation will be encoded. * @return a bit vector of the annotation. * @throws DOMException */ public static byte encodeExtraAnnotation(IBinding binding) throws DOMException { byte modifiers = 0; if (binding instanceof ICPPMethod) { ICPPMethod method = (ICPPMethod) binding; modifiers |= (method.isVirtual() ? 1 : 0) << VIRTUAL_OFFSET; modifiers |= (method.isDestructor() ? 1 : 0) << DESTRUCTOR_OFFSET; modifiers |= (method.isImplicit() ? 1 : 0) << IMPLICIT_METHOD_OFFSET; modifiers |= (method.isPureVirtual() ? 1 : 0) << PURE_VIRTUAL_OFFSET; modifiers |= (method.isExplicit() ? 1 : 0) << EXPLICIT_METHOD_OFFSET; } return modifiers; } /** * Unpacks visibility information from a bit vector of annotation. * @param annotation Annotation containing visibility information. * @return The visibility component of the annotation. */ public static int getVisibility(int annotation) { return (annotation >> VISIBILITY_OFFSET) & VISIBILITY_MASK; } }