Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] FIXED - refactoring Operator ID


This patch includes:
- ICPPASTConversionName that represents C++ conversion member functions
 -> also keeps track of the IASTTypeId for the conversion member function
- ICPPASTOperatorName that represents C++ overloaded operator member function
- a couple tests

Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada


Index: parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java,v
retrieving revision 1.6
diff -u -r1.6 ICPPASTQualifiedName.java
--- parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java	31 Mar 2005 19:01:44 -0000	1.6
+++ parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java	4 Apr 2005 17:21:50 -0000
@@ -56,4 +56,12 @@
 	 *            boolean
 	 */
 	public void setFullyQualified(boolean value);
+	
+	/**
+	 * This is used to check if the ICPPASTQualifiedName's last segment is
+	 * an ICPPASTConversionName or an ICPPASTOperatorName.
+	 * 
+	 * @return
+	 */
+	public boolean isConversionOrOperator();
 }
Index: parser/org/eclipse/cdt/core/parser/ITokenDuple.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java,v
retrieving revision 1.21
diff -u -r1.21 ITokenDuple.java
--- parser/org/eclipse/cdt/core/parser/ITokenDuple.java	19 Nov 2004 21:16:52 -0000	1.21
+++ parser/org/eclipse/cdt/core/parser/ITokenDuple.java	4 Apr 2005 17:21:50 -0000
@@ -69,8 +69,4 @@
 	
 	public void freeReferences( );
 	public void acceptElement( ISourceElementRequestor requestor );
-    /**
-     * @return
-     */
-    public abstract boolean isConversion();
 }
\ No newline at end of file
Index: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java,v
retrieving revision 1.9
diff -u -r1.9 CPPASTQualifiedName.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java	23 Mar 2005 21:06:59 -0000	1.9
+++ parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java	4 Apr 2005 17:21:50 -0000
@@ -15,7 +15,10 @@
 import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
 import org.eclipse.cdt.core.dom.ast.IASTNode;
 import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
 
 /**
  * @author jcamelon
@@ -259,4 +262,22 @@
 		names[names.length - 1].setBinding( binding );
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName#isConversionOrOperator()
+	 */
+	public boolean isConversionOrOperator() {
+		IASTName[] nonNullNames = getNames(); // ensure no null names
+		
+		int len=nonNullNames.length;
+		if (nonNullNames[len-1] instanceof ICPPASTConversionName || nonNullNames[len-1] instanceof ICPPASTOperatorName) return true;
+		
+		// check templateId's name
+		if (nonNullNames[len-1] instanceof ICPPASTTemplateId) {
+			IASTName tempName = ((ICPPASTTemplateId)nonNullNames[len-1]).getTemplateName();
+			if (tempName instanceof ICPPASTConversionName || tempName instanceof ICPPASTOperatorName) return true;
+		}
+		
+		return false;
+	}
+
 }
\ No newline at end of file
Index: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java,v
retrieving revision 1.49
diff -u -r1.49 GNUCPPSourceParser.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java	31 Mar 2005 16:00:32 -0000	1.49
+++ parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java	4 Apr 2005 17:21:51 -0000
@@ -81,6 +81,7 @@
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
@@ -130,12 +131,13 @@
 import org.eclipse.cdt.core.parser.ITokenDuple;
 import org.eclipse.cdt.core.parser.ParseError;
 import org.eclipse.cdt.core.parser.ParserMode;
-import org.eclipse.cdt.core.parser.util.CharArrayUtils;
 import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
 import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
 import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
 import org.eclipse.cdt.internal.core.parser.SimpleDeclarationStrategy;
 import org.eclipse.cdt.internal.core.parser.TemplateParameterManager;
+import org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple;
+import org.eclipse.cdt.internal.core.parser.token.OperatorTokenDuple;
 import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
 
 /**
@@ -148,6 +150,7 @@
  */
 public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
 
+   private static final String COMPL = "~"; //$NON-NLS-1$
    private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
    private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
    private static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
@@ -422,12 +425,13 @@
       return last;
    }
 
-   protected ITokenDuple operatorId(IToken originalToken,
+   protected IASTName operatorId(IToken originalToken,
          TemplateParameterManager templateArgs) throws BacktrackException,
          EndOfFileException {
       // we know this is an operator
       IToken operatorToken = consume(IToken.t_operator);
       IToken toSend = null;
+   	  IASTTypeId typeId = null;
       if (LA(1).isOperator() || LT(1) == IToken.tLPAREN
             || LT(1) == IToken.tLBRACKET) {
          if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
@@ -452,7 +456,7 @@
       } else {
          // must be a conversion function
          IToken t = LA(1);
-         typeId(true, false);
+         typeId = typeId(true, false);
          if (t != LA(1)) {
             while (t.getNext() != LA(1)) {
                t = t.getNext();
@@ -474,12 +478,18 @@
             hasTemplateId = true;
          }
 
-         ITokenDuple duple = TokenFactory
+		 ITokenDuple duple = TokenFactory
                .createTokenDuple(originalToken == null ? operatorToken
                      : originalToken, toSend, (hasTemplateId ? templateArgs
                      .getTemplateArgumentsList() : null));
 
-         return duple;
+		 OperatorTokenDuple operator= new OperatorTokenDuple(duple);
+		 if (typeId!=null) { // if it's a conversion operator
+			 operator.setConversionOperator(true);
+			 operator.setTypeId(typeId);
+		 }
+		 
+         return createName(operator);
       } finally {
          if (grabbedNewInstance)
             TemplateParameterManager.returnInstance(templateArgs);
@@ -1528,7 +1538,7 @@
                   isTemplate = true;
                }
 
-               IASTName name = createName(idExpression());
+               IASTName name = idExpression();
 
                ICPPASTFieldReference fieldReference = createFieldReference();
                ((ASTNode) fieldReference).setOffsetAndLength(
@@ -1556,7 +1566,7 @@
                   isTemplate = true;
                }
 
-               name = createName(idExpression());
+               name = idExpression();
 
                fieldReference = createFieldReference();
                ((ASTNode) fieldReference).setOffsetAndLength(
@@ -1728,11 +1738,10 @@
          case IToken.t_operator:
          case IToken.tCOMPL:
 		 {
-            ITokenDuple duple = idExpression();
-            IASTName name = createName(duple);
+            IASTName name = idExpression();
             IASTIdExpression idExpression = createIdExpression();
-            ((ASTNode) idExpression).setOffsetAndLength(duple.getStartOffset(),
-                  duple.getEndOffset() - duple.getStartOffset());
+			((ASTNode) idExpression).setOffsetAndLength(((ASTNode)name).getOffset(),
+                  ((ASTNode)name).getOffset() + ((ASTNode)name).getLength() - ((ASTNode)name).getOffset());
             idExpression.setName(name);
             name.setParent(idExpression);
             name.setPropertyInParent(IASTIdExpression.ID_NAME);
@@ -1772,11 +1781,11 @@
       return new CPPASTIdExpression();
    }
 
-   protected ITokenDuple idExpression() throws EndOfFileException,
+   protected IASTName idExpression() throws EndOfFileException,
          BacktrackException {
-      ITokenDuple duple = null;
+      IASTName name = null;
       try {
-         duple = name();
+		 name = createName(name());
       } catch (BacktrackException bt) {
          IToken mark = mark();
          if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
@@ -1791,16 +1800,16 @@
             }
 
             if (LT(1) == IToken.t_operator)
-               duple = operatorId(start, null);
+               name = operatorId(start, null);
             else {
                backup(mark);
                throwBacktrack(start.getOffset(), end.getEndOffset()
                      - start.getOffset());
             }
          } else if (LT(1) == IToken.t_operator)
-            duple = operatorId(null, null);
+            name = operatorId(null, null);
       }
-      return duple;
+      return name;
 
    }
 
@@ -2543,6 +2552,12 @@
          else
             // templateID
             subName = createTemplateID(segments[i]);
+		 
+		 if (i==segments.length-1 && 
+				 duple instanceof IOperatorTokenDuple) { // make sure the last segment is an OperatorName/ConversionName
+			 subName = createOperatorName((IOperatorTokenDuple)duple, subName);
+		 }
+		 
          subName.setParent(result);
          subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME);
          ((ASTNode) subName).setOffsetAndLength(segments[i].getStartOffset(),
@@ -2599,7 +2614,11 @@
       	return createTemplateID( duple );
 	  
 	  // We're a single token
-      CPPASTName name = new CPPASTName(duple.toCharArray());
+      IASTName name = new CPPASTName(duple.toCharArray());
+	  if (duple instanceof OperatorTokenDuple) {
+		  name = createOperatorName((OperatorTokenDuple)duple, name);
+	  }
+	  
 	  IToken token = duple.getFirstToken();
 	  switch (token.getType()) {
 	  case IToken.tCOMPLETION:
@@ -2608,10 +2627,32 @@
 		  break;
 	  }
 
-      name.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
-            - duple.getStartOffset());
+	  ((ASTNode)name).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
+           - duple.getStartOffset());
+	  
       return name;
    }
+   
+   private IASTName createOperatorName(IOperatorTokenDuple duple, IASTName name) {
+	   IASTName aName=null;
+	   
+	   if (duple.isConversionOperator()) {
+		   aName = new CPPASTConversionName(name.toCharArray());
+		   IASTTypeId typeId = duple.getTypeId();
+		   typeId.setParent(aName);
+		   typeId.setPropertyInParent(ICPPASTConversionName.TYPE_ID);
+		   ((CPPASTConversionName)aName).setTypeId(typeId);
+	   } else {
+		   aName = new CPPASTOperatorName(name.toCharArray());
+	   }
+	   
+	   if (name instanceof ICPPASTTemplateId) {
+		   ((ICPPASTTemplateId)name).setTemplateName(aName);
+		   return name;
+	   }
+	   
+	   return aName;
+   }
 
    /**
     * @return
@@ -2923,7 +2964,7 @@
     * @throws EndOfFileException
     *            we could encounter EOF while looking ahead
     */
-   protected boolean lookAheadForConstructorOrConversion(Flags flags)
+   protected boolean lookAheadForConstructorOrOperator(Flags flags)
          throws EndOfFileException {
       if (flags.isForParameterDeclaration())
          return false;
@@ -2931,9 +2972,9 @@
          return true;
 
       IToken mark = mark();
-      ITokenDuple duple = null;
+      IASTName name = null;
       try {
-         duple = consumeTemplatedOperatorName();
+         name = consumeTemplatedOperatorName();
       } catch (BacktrackException e) {
          backup(mark);
          return false;
@@ -2942,50 +2983,48 @@
          return false;
       }
 
-      if (duple == null) {
-         backup(mark);
-         return false;
-      }
-
-      ITokenDuple leadingSegments = duple.getLeadingSegments();
-      if (leadingSegments == null) {
-         backup(mark);
-         return false;
-      }
-      ITokenDuple lastSegment = duple.getLastSegment();
-      char[] className = lastSegment.extractNameFromTemplateId();
-      if (className == null || CharArrayUtils.equals(className, EMPTY_STRING)) {
-         backup(mark);
-         return false;
-      }
-
-      ITokenDuple secondlastSegment = leadingSegments.getLastSegment();
-      if (secondlastSegment == null) {
-         backup(mark);
-         return false;
-      }
-      char[] otherName = secondlastSegment.extractNameFromTemplateId();
-      if (otherName == null || CharArrayUtils.equals(otherName, EMPTY_STRING)) {
+      if (name == null) {
          backup(mark);
          return false;
       }
 
-      if (lastSegment.isConversion()) {
-         backup(mark);
-         return true;
-      }
-
-      if (CharArrayUtils.equals(className, otherName)) {
-         backup(mark);
-         return true;
-      }
-      char[] destructorName = CharArrayUtils.concat(
-            "~".toCharArray(), otherName); //$NON-NLS-1$
-      if (CharArrayUtils.equals(destructorName, className)) {
-         backup(mark);
-         return true;
-      }
-
+	  // constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be defined for the global scope)
+	  if (name instanceof ICPPASTQualifiedName) {
+		  IASTName[] segments = ((ICPPASTQualifiedName)name).getNames();
+		  
+		  int len = segments.length;
+		  if (len >= 2) {
+			  if (segments[0].toString().length() == 0) {
+				  backup(mark);
+				  return false;
+			  }
+			  
+			  if (((ICPPASTQualifiedName)name).isConversionOrOperator()) { // conversion or operator
+				  backup(mark);
+				  return true;
+			  }
+			  
+			  if (segments[len-1].toString().equals(segments[len-2].toString())) { // constructor
+				  backup(mark);
+				  return true;
+			  }
+			  
+			  StringBuffer destructorName = new StringBuffer();
+			  destructorName.append(COMPL);
+			  destructorName.append(segments[len-2]);
+			  if (segments[len-1].toString().equals(destructorName.toString())) { // destructor
+				  backup(mark);
+				  return true;
+			  }  
+		  } else {
+			  backup(mark);
+			  return false;
+		  }
+	  } else {
+		  backup(mark);
+		  return false;
+	  }
+	  
       backup(mark);
       return false;
    }
@@ -3185,7 +3224,7 @@
                if (parm && flags.haveEncounteredTypename())
                   break declSpecifiers;
 
-               if (lookAheadForConstructorOrConversion(flags))
+               if (lookAheadForConstructorOrOperator(flags))
                   break declSpecifiers;
 
                if (lookAheadForDeclarator(flags))
@@ -3600,10 +3639,9 @@
             declaratorName = createName();
          } else {
             try {
-               ITokenDuple d = consumeTemplatedOperatorName();
-               declaratorName = createName(d);
+               declaratorName = consumeTemplatedOperatorName();
                finalOffset = calculateEndOffset(declaratorName);
-               if (d.isConversion())
+               if (declaratorName instanceof ICPPASTQualifiedName && ((ICPPASTQualifiedName)declaratorName).isConversionOrOperator())
                   isFunction = true;
             } catch (BacktrackException bt) {
                declaratorName = createName();
@@ -3899,7 +3937,7 @@
       return new CPPASTDeclarator();
    }
 
-   protected ITokenDuple consumeTemplatedOperatorName()
+   protected IASTName consumeTemplatedOperatorName()
          throws EndOfFileException, BacktrackException {
       TemplateParameterManager argumentList = TemplateParameterManager
             .getInstance();
@@ -3908,13 +3946,11 @@
             return operatorId(null, null);
 
          try {
-            return name();
+            return createName(name());
          } catch (BacktrackException bt) {
          }
          IToken start = null;
 
-         boolean hasTemplateId = false;
-
          IToken mark = mark();
          if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
             start = consume();
@@ -3922,28 +3958,22 @@
 
             if (start.getType() == IToken.tIDENTIFIER) {
                end = consumeTemplateArguments(end, argumentList);
-               if (end != null && end.getType() == IToken.tGT)
-                  hasTemplateId = true;
             }
 
             while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
                end = consume();
                if (end.getType() == IToken.tIDENTIFIER) {
                   end = consumeTemplateArguments(end, argumentList);
-                  if (end.getType() == IToken.tGT)
-                     hasTemplateId = true;
                }
             }
-            if (LT(1) == IToken.t_operator)
-               end = operatorId(start, (hasTemplateId ? argumentList : null))
-                     .getLastToken();
-            else {
-               int endOffset = (end != null) ? end.getEndOffset() : 0;
-               backup(mark);
-               throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
+			
+            if (LT(1) == IToken.t_operator) {
+				return operatorId(start, argumentList );
             }
-            return TokenFactory.createTokenDuple(start, end, argumentList
-                  .getTemplateArgumentsList());
+
+			int endOffset = (end != null) ? end.getEndOffset() : 0;
+            backup(mark);
+            throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
          }
          int endOffset = (mark != null) ? mark.getEndOffset() : 0;
          backup(mark);
@@ -4533,15 +4563,23 @@
     * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken)
     */
    protected IASTName createName(IToken token) {
-      CPPASTName n = new CPPASTName(token.getCharImage());
+      IASTName n = null;
+	  
+	  if (token instanceof IOperatorTokenDuple) {
+		  n = createOperatorName((IOperatorTokenDuple)token, n);
+	  } else {
+		  n = new CPPASTName(token.getCharImage());			  
+	  }
+	  
 	  switch (token.getType()) {
 	  case IToken.tCOMPLETION:
 	  case IToken.tEOC:
 		  createCompletionNode(token).addName(n);
 		  break;
 	  }
-      n.setOffsetAndLength(token.getOffset(), token.getLength());
-      return n;
+	  ((ASTNode)n).setOffsetAndLength(token.getOffset(), token.getLength());
+      
+	  return n;
    }
 
    /*
Index: parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java,v
retrieving revision 1.23
diff -u -r1.23 BasicTokenDuple.java
--- parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java	1 Apr 2005 16:20:52 -0000	1.23
+++ parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java	4 Apr 2005 17:21:52 -0000
@@ -598,15 +598,4 @@
 	public char[] getFilename() {
 		return firstToken.getFilename();
 	}
-
-    /* (non-Javadoc)
-     * @see org.eclipse.cdt.core.parser.ITokenDuple#isConversion()
-     */
-    public boolean isConversion() {
-        int index = findLastTokenType( IToken.t_operator );
-        if( index == -1 ) return false;
-        return true;
-    }
-
-	
 }
Index: parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java
diff -N parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,41 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+
+/**
+ * This interface represents a C++ conversion member function.
+ *  
+ * @author dsteffle
+ */
+public interface ICPPASTConversionName extends IASTName {
+	public static final ASTNodeProperty TYPE_ID=new ASTNodeProperty(
+	"IASTArrayDeclarator.TYPE_ID - IASTTypeId for ICPPASTConversionName"); //$NON-NLS-1$
+	
+	/**
+	 * Returns the IASTTypeId for the ICPPASTConversionName.
+	 * 
+	 * i.e. getTypeId() on operator int(); would return the IASTTypeId for "int" 
+	 * 
+	 * @return
+	 */
+	public IASTTypeId getTypeId();
+	
+	/**
+	 * Sets the IASTTypeId for the ICPPASTConversionName.
+	 * 
+	 * @param typeId
+	 */
+	public void setTypeId(IASTTypeId typeId);
+}
Index: parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java
diff -N parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,22 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IASTName;
+
+/**
+ * This interface represents a C++ overloaded operator member function.
+ * 
+ * @author dsteffle
+ */
+public interface ICPPASTOperatorName extends IASTName {
+
+}
Index: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
diff -N parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,39 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
+
+/**
+ * The implemented ICPPASTConversionName.
+ *  
+ * @author dsteffle
+ */
+public class CPPASTConversionName extends CPPASTName implements ICPPASTConversionName {
+	private IASTTypeId typeId=null;
+	
+	public CPPASTConversionName() {
+		super();
+	}
+	
+	public CPPASTConversionName(char[] name) {
+		super(name);
+	}
+	
+	public IASTTypeId getTypeId() {
+		return typeId;
+	}
+
+	public void setTypeId(IASTTypeId typeId) {
+		this.typeId=typeId;
+	}
+}
Index: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTOperatorName.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTOperatorName.java
diff -N parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTOperatorName.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTOperatorName.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
+
+/**
+ * The imlemented ICPPASTOperatorName.
+ * 
+ * @author dsteffle
+ */
+public class CPPASTOperatorName extends CPPASTName implements ICPPASTOperatorName {
+	public CPPASTOperatorName() {
+		super();
+	}
+	
+	public CPPASTOperatorName(char[] name) {
+		super(name);
+	}
+}
Index: parser/org/eclipse/cdt/internal/core/parser/token/IOperatorTokenDuple.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/token/IOperatorTokenDuple.java
diff -N parser/org/eclipse/cdt/internal/core/parser/token/IOperatorTokenDuple.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/token/IOperatorTokenDuple.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,47 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.internal.core.parser.token;
+
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+
+/**
+ * This interface is used by GNUCPPSourceParser to determine if a token duple is
+ * an operator/conversion member function or not.
+ * 
+ * @author dsteffle
+ */
+public interface IOperatorTokenDuple {
+	/**
+	 * true if the IOperatorTokenDuple is a conversion member function
+	 * false if the IOperatorTokenDuple is an overloaded operator member function
+	 * @return
+	 */
+	public boolean isConversionOperator();
+
+	/**
+	 * Sets whether the IOperatorTokenDuple is a conversion member function or not.
+	 * @param isConversionOperator
+	 */
+	public void setConversionOperator(boolean isConversionOperator);
+
+	/**
+	 * Will return the IASTTypeId if the IOperatorTokenDuple is a valid
+	 * conversion member function.  null is returned otherwise.
+	 * @return
+	 */
+	public IASTTypeId getTypeId();
+
+	/**
+	 * Sets the IASTTypeId that corresponds to a conversion member function.
+	 * @param typeId
+	 */
+	public void setTypeId(IASTTypeId typeId);
+}
Index: parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java
===================================================================
RCS file: parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java
diff -N parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/internal/core/parser/token/OperatorTokenDuple.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,220 @@
+/**********************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.internal.core.parser.token;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.parser.ISourceElementRequestor;
+import org.eclipse.cdt.core.parser.IToken;
+import org.eclipse.cdt.core.parser.ITokenDuple;
+
+/**
+ * This class is used by the GNUCPPSourceParser as an intermediate determinant of whether a 
+ * BasicTokenDuple represents an IASTConversionFunction or an IASTOperatorFunction. 
+ *  
+ * @author dsteffle
+ */
+public class OperatorTokenDuple implements ITokenDuple, IOperatorTokenDuple {
+
+	private ITokenDuple token = null;
+	private IASTTypeId typeId = null;
+	private boolean isConversionOperator=false;
+	
+	/**
+	 * Simple constructor.  token is wrapped by this class.
+	 * @param token
+	 */
+	public OperatorTokenDuple(ITokenDuple token) {
+		this.token=token;
+	}
+
+	// below are functions used by GNUCPPSourceParser, see IOperatorTokenDuple
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#isConversionOperator()
+     */
+	public boolean isConversionOperator() {
+		return isConversionOperator;
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#setConversionOperator(boolean)
+     */
+	public void setConversionOperator(boolean isConversionOperator) {
+		this.isConversionOperator = isConversionOperator;
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#getTypeId()
+     */
+	public IASTTypeId getTypeId() {
+		return typeId;
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#
+     * isConversionOperator(org.eclipse.cdt.core.dom.ast.IASTTypeId)
+     */
+	public void setTypeId(IASTTypeId typeId) {
+		this.typeId = typeId;
+	}
+
+	// below are ITokenDuple functions
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getFirstToken()
+     */
+	public IToken getFirstToken() {
+		return token.getFirstToken();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getLastToken()
+     */
+	public IToken getLastToken() {
+		return token.getLastToken();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
+     */
+	public List[] getTemplateIdArgLists() {
+		return token.getTemplateIdArgLists();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getLastSegment()
+     */
+	public ITokenDuple getLastSegment() {
+		return token.getLastSegment();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getLeadingSegments()
+     */
+	public ITokenDuple getLeadingSegments() {
+		return token.getLeadingSegments();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
+     */
+	public int getSegmentCount() {
+		return token.getSegmentCount();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#iterator()
+     */
+	public Iterator iterator() {
+		return token.iterator();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#toCharArray()
+     */
+	public char[] toCharArray() {
+		return token.toCharArray();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getFilename()
+     */
+	public char[] getFilename() {
+		return token.getFilename();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#isIdentifier()
+     */
+	public boolean isIdentifier() {
+		return token.isIdentifier();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#length()
+     */
+	public int length() {
+		return token.length();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getSubrange(int, int)
+     */
+	public ITokenDuple getSubrange(int startIndex, int endIndex) {
+		return token.getSubrange(startIndex, endIndex);
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getToken(int)
+     */
+	public IToken getToken(int index) {
+		return token.getToken(index);
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getSegments()
+     */
+	public ITokenDuple[] getSegments() {
+		return token.getSegments();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#findLastTokenType(int)
+     */
+	public int findLastTokenType(int type) {
+		return token.findLastTokenType(type);
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getStartOffset()
+     */
+	public int getStartOffset() {
+		return token.getStartOffset();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()
+     */
+	public int getEndOffset() {
+		return token.getEndOffset();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#getLineNumber()
+     */
+	public int getLineNumber() {
+		return token.getLineNumber();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#syntaxOfName()
+     */
+	public boolean syntaxOfName() {
+		return token.syntaxOfName();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#extractNameFromTemplateId()
+     */
+	public char[] extractNameFromTemplateId() {
+		return token.extractNameFromTemplateId();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#contains(org.eclipse.cdt.core.parser.ITokenDuple)
+     */
+	public boolean contains(ITokenDuple duple) {
+		return token.contains(duple);
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#toQualifiedName()
+     */
+	public String[] toQualifiedName() {
+		return token.toQualifiedName();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#freeReferences()
+     */
+	public void freeReferences() {
+		token.freeReferences();
+	}
+	/* (non-Javadoc)
+     * @see org.eclipse.cdt.core.parser.ITokenDuple#
+     * acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
+     */
+	public void acceptElement(ISourceElementRequestor requestor) {
+		token.acceptElement(requestor);
+	}
+	/* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+	public String toString() {
+		return token.toString();
+	}
+}
Index: src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java,v
retrieving revision 1.1
diff -u -r1.1 DOMASTNodeLeaf.java
--- src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java	29 Mar 2005 21:40:34 -0000	1.1
+++ src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java	4 Apr 2005 17:22:51 -0000
@@ -309,6 +309,7 @@
 	}
 	
 	private static class ASTPropertySource implements IPropertySource {
+		private static final IPropertyDescriptor[] BLANK_DESCRIPTORS = new IPropertyDescriptor[0];
 		private static final String OPEN_PAREN = " ("; //$NON-NLS-1$
 		private static final String CLOSE_PAREN = ")"; //$NON-NLS-1$
 		private static final String L_BRACKET_STRING = "["; //$NON-NLS-1$
@@ -360,6 +361,7 @@
 		
 		private IPropertyDescriptor[] getPropertyDescriptors(Object obj) {
 			IPropertyDescriptor[] desc = new IPropertyDescriptor[DEFAULT_DESCRIPTOR_SIZE];
+			if (obj==null) return BLANK_DESCRIPTORS;
 			Class objClass = obj.getClass();
 			Class[] interfaces = objClass.getInterfaces();
 			
Index: parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java,v
retrieving revision 1.80
diff -u -r1.80 AST2CPPTests.java
--- parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java	2 Apr 2005 01:22:36 -0000	1.80
+++ parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java	4 Apr 2005 17:21:50 -0000
@@ -28,8 +28,10 @@
 import org.eclipse.cdt.core.dom.ast.IASTName;
 import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
 import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
 import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
 import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
 import org.eclipse.cdt.core.dom.ast.IArrayType;
 import org.eclipse.cdt.core.dom.ast.IBasicType;
@@ -49,6 +51,8 @@
 import org.eclipse.cdt.core.dom.ast.ITypedef;
 import org.eclipse.cdt.core.dom.ast.IVariable;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
 import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
@@ -3178,5 +3182,72 @@
         assertInstances( col, f, 2 );
         assertInstances( col, t1, 3 );
     }
+	
+	public void testOperatorConversionNames() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+    	buffer.append("class Foo {\n"); //$NON-NLS-1$
+		buffer.append("public:\n"); //$NON-NLS-1$
+		buffer.append("operator int();\n"); //$NON-NLS-1$
+		buffer.append("char& operator[](unsigned int);\n"); //$NON-NLS-1$
+		buffer.append("};\n"); //$NON-NLS-1$
+		
+		IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
+		CPPNameCollector col = new CPPNameCollector();
+    	tu.accept( col );
+		
+		IASTName name1 = col.getName(1);
+		IASTName name2 = col.getName(2);
+		
+		assertNotNull(name1);
+		assertNotNull(name2);
+		
+		assertTrue(name1 instanceof ICPPASTConversionName);
+		assertTrue(name2 instanceof ICPPASTOperatorName);
+		
+		IASTTypeId typeId = ((ICPPASTConversionName)name1).getTypeId();
+		assertNotNull(typeId);
+		assertEquals( ((IASTSimpleDeclSpecifier)typeId.getDeclSpecifier()).getType(), IASTSimpleDeclSpecifier.t_int );
+		
+	}
+	
+    public void testBug36769B() throws Exception {
+		StringBuffer buffer = new StringBuffer();
+    	buffer.append("class X { operator int(); }; \n"); //$NON-NLS-1$
+		buffer.append("X::operator int() { } \n"); //$NON-NLS-1$
+		buffer.append("template <class A,B> class X<A,C> { operator int(); }; \n"); //$NON-NLS-1$
+		buffer.append("template <class A,B> X<A,C>::operator int() { } \n"); //$NON-NLS-1$
+		
+		IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
+		CPPNameCollector col = new CPPNameCollector();
+    	tu.accept( col );
+		
+		// 1,4,12,21  - conversion
+		// 2, 16 .isConversion
+		
+		assertEquals(col.size(), 22);
+		
+		assertNotNull(col.getName(1));
+		assertNotNull(col.getName(4));
+		assertNotNull(col.getName(12));
+		assertNotNull(col.getName(21));
+		assertNotNull(col.getName(2));
+		assertNotNull(col.getName(16));
+		
+		// ensure the conversions are conversions
+		assertTrue(col.getName(1) instanceof ICPPASTConversionName);
+		assertTrue(col.getName(4) instanceof ICPPASTConversionName);
+		assertTrue(col.getName(12) instanceof ICPPASTConversionName);
+		assertTrue(col.getName(21) instanceof ICPPASTConversionName);
+		assertNotNull(((ICPPASTConversionName)col.getName(1)).getTypeId());
+		assertNotNull(((ICPPASTConversionName)col.getName(4)).getTypeId());
+		assertNotNull(((ICPPASTConversionName)col.getName(12)).getTypeId());
+		assertNotNull(((ICPPASTConversionName)col.getName(21)).getTypeId());
+		
+		// ensure qualified name isConversionOrOperator
+		assertTrue(col.getName(2) instanceof ICPPASTQualifiedName);
+		assertTrue(col.getName(16) instanceof ICPPASTQualifiedName);
+		assertTrue(((ICPPASTQualifiedName)col.getName(2)).isConversionOrOperator());
+		assertTrue(((ICPPASTQualifiedName)col.getName(16)).isConversionOrOperator());
+    }
 }
 

Back to the top