/**
   * Returns the signature for the binding. Returns an empty string if a signature is not required
   * for the binding.
   *
   * @param binding
   * @return the signature or an empty string
   * @throws CoreException
   * @throws DOMException
   */
  public static String getSignature(IBinding binding) throws CoreException, DOMException {
    StringBuilder buffer = new StringBuilder();
    if (binding instanceof ICPPDeferredClassInstance) {
      buffer.append(getSignature(((ICPPDeferredClassInstance) binding).getTemplateDefinition()));
    }
    if (binding instanceof ICPPTemplateInstance) {
      ICPPTemplateInstance inst = (ICPPTemplateInstance) binding;
      buffer.append(getTemplateArgString(inst.getTemplateArguments(), true));
    } else if (binding instanceof ICPPUnknownMemberClassInstance) {
      ICPPUnknownMemberClassInstance inst = (ICPPUnknownMemberClassInstance) binding;
      buffer.append(getTemplateArgString(inst.getArguments(), true));
    } else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
      ICPPClassTemplatePartialSpecialization partial =
          (ICPPClassTemplatePartialSpecialization) binding;
      buffer.append(getTemplateArgString(partial.getTemplateArguments(), false));
    }

    if (binding instanceof ICPPFunction) {
      IFunction function = (ICPPFunction) binding;
      final IFunctionType ftype = function.getType();
      buffer.append(getFunctionParameterString(ftype));
      if (binding instanceof ICPPTemplateDefinition) {
        ICPPTemplateDefinition tdef = (ICPPTemplateDefinition) binding;
        appendTemplateParameters(tdef.getTemplateParameters(), buffer);
        ASTTypeUtil.appendType(ftype.getReturnType(), true, buffer);
      }
    }
    if (binding instanceof ICPPMethod && !(binding instanceof ICPPConstructor)) {
      ICPPFunctionType ft = ((ICPPMethod) binding).getType();
      if (ft.isConst()) buffer.append('c');
      if (ft.isVolatile()) buffer.append('v');
    }

    return buffer.toString();
  }
 protected void assertCompositeTypeParam(
     int index, int compositeTypeKey, IType function, String qn) throws DOMException {
   // assert function is IFunctionType
   IFunctionType ft = (IFunctionType) function;
   assertTrue(ICPPClassType.class.isInstance((ft.getParameterTypes()[index])));
   assertEquals(compositeTypeKey, ((ICPPClassType) ft.getParameterTypes()[index]).getKey());
   assertEquals(qn, ASTTypeUtil.getQualifiedName((ICPPClassType) ft.getParameterTypes()[index]));
 }
 /** Constructs a string in the format: (paramName1,paramName2,...) */
 private static String getFunctionParameterString(IFunctionType functionType) throws DOMException {
   IType[] types = functionType.getParameterTypes();
   if (types.length == 1 && SemanticUtil.isVoidType(types[0])) {
     types = new IType[0];
   }
   StringBuilder result = new StringBuilder();
   result.append('(');
   for (int i = 0; i < types.length; i++) {
     if (i > 0) {
       result.append(',');
     }
     ASTTypeUtil.appendType(types[i], true, result);
   }
   if (functionType instanceof ICPPFunctionType
       && ((ICPPFunctionType) functionType).takesVarArgs()) {
     if (types.length != 0) {
       result.append(',');
     }
     result.append("..."); // $NON-NLS-1$
   }
   result.append(')');
   return result.toString();
 }
 protected void assertParamType(int index, Class type, IType function) throws DOMException {
   // assert function is IFunctionType
   IFunctionType ft = (IFunctionType) function;
   assertTrue(type.isInstance((ft.getParameterTypes()[index])));
 }