Bug 531701 - ClassCastException in
AttributeWriter.writeGCCAttributeSpecifier()

* Added test to reproduce initial issue.

Change-Id: I72e60fb2244b7d40492bfcdeaa58a8707c39e277
Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
index 23c63a5..2689dd2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/AttributeWriter.java
@@ -21,7 +21,6 @@
 import org.eclipse.cdt.core.dom.ast.gnu.IGCCASTAttributeList;
 import org.eclipse.cdt.core.parser.GCCKeywords;
 import org.eclipse.cdt.core.parser.Keywords;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTAttribute;
 import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
 
 /**
@@ -65,7 +64,11 @@
 		IASTAttribute[] innerAttributes = specifier.getAttributes();
 		for (int i = 0; i < innerAttributes.length; i++) {
 			IASTAttribute innerAttribute = innerAttributes[i];
-			writeAttribute((CPPASTAttribute)innerAttribute);
+			if (innerAttribute instanceof ICPPASTAttribute) {
+				writeAttribute((ICPPASTAttribute) innerAttribute);
+			} else {
+				writeAttribute(innerAttribute);
+			}
 			if (i < innerAttributes.length - 1) {
 				scribe.print(',');
 				scribe.printSpace();
@@ -91,12 +94,7 @@
 		scribe.print(CLOSING_SQUARE_BRACKET);
 	}
 
-	private void writeAttribute(ICPPASTAttribute attribute) {
-		char[] scope = attribute.getScope();
-		if (scope != null) {
-			scribe.print(scope);
-			scribe.print(COLON_COLON);
-		}
+	private void writeAttribute(IASTAttribute attribute) {
 		scribe.print(attribute.getName());
 
 		IASTToken argumentClause = attribute.getArgumentClause();
@@ -105,13 +103,29 @@
 			printTokens(argumentClause);
 			scribe.print(CLOSING_PARENTHESIS);
 		}
+	}
 
+	private void writeAttributeScope(ICPPASTAttribute attribute) {
+		char[] scope = attribute.getScope();
+		if (scope != null) {
+			scribe.print(scope);
+			scribe.print(COLON_COLON);
+		}
+	}
+
+	private void writeAttributeVarArgs(ICPPASTAttribute attribute) {
 		if (attribute.hasPackExpansion()) {
 			scribe.printSpace();
 			scribe.print(VAR_ARGS);
 		}
 	}
 
+	private void writeAttribute(ICPPASTAttribute attribute) {
+		writeAttributeScope(attribute);
+		writeAttribute((IASTAttribute) attribute);
+		writeAttributeVarArgs(attribute);
+	}
+
 	protected void printTokens(IASTToken token) {
 		if (token instanceof IASTTokenList) {
 			for (IASTToken innerToken : ((IASTTokenList) token).getTokens()) {
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/togglefunction/ToggleRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/togglefunction/ToggleRefactoringTest.java
index 0414dcf..f16f3c9 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/togglefunction/ToggleRefactoringTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/togglefunction/ToggleRefactoringTest.java
@@ -3551,4 +3551,21 @@
 	public void testToggleWithTemplateArgumentDependentQualifierInReturnType_399931() throws Exception {
 		assertRefactoringSuccess();
 	}
+
+	//A.c
+	//void /*$*/freefunction/*$$*/(int x __attribute__((unused))) {
+	//	return;
+	//}
+	//====================
+	//#include "A.h"
+	//
+
+	//A.h
+	//====================
+	//void freefunction(int x __attribute__((unused))) {
+	//	return;
+	//}
+	public void testFreeFunctionFromHeaderToImplInC_531701() throws Exception {
+		assertRefactoringSuccess();
+	}
 }