/*******************************************************************************
* 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;
}
}