From 2076eb6dc532194b11784f30bdaa961d2e360a39 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 6 Jun 2007 11:16:10 +0000 Subject: [PATCH] Fix for 190799 by Richard Miskin, functions with multiple attributes. --- .../parser/AbstractGNUSourceCodeParser.java | 21 ++++++++++++ .../core/dom/parser/c/GNUCSourceParser.java | 34 +++++++------------ .../dom/parser/cpp/GNUCPPSourceParser.java | 34 ++++++++----------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 7b02f5506e7..17ca72e4eb1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -2230,6 +2230,27 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return parseDeclarationOrExpressionStatement(); } + /** + * Accept a sequence of __attribute__ or __declspec + * + * @param allowAttrib if true accept any number of __attribute__ + * @param allowDeclspec if true accept any number of __declspec + * @throws BacktrackException + * @throws EndOfFileException + */ + protected void __attribute_decl_seq(boolean allowAttrib, boolean allowDeclspec) throws BacktrackException, EndOfFileException { + while (true) { + IToken token = LA(1); + if ( allowAttrib && (token.getType() == IGCCToken.t__attribute__)) { + __attribute__(); + } else if (allowDeclspec && (token.getType() == IGCCToken.t__declspec)) { + __declspec(); + } else { + break; + } + } + } + protected void __attribute__() throws BacktrackException, EndOfFileException { IToken token = LA(1); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index a6248dfe114..8008635dd9e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -1591,13 +1591,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { } case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec if (supportAttributeSpecifiers) - __attribute__(); + __attribute_decl_seq(true, false); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; case IGCCToken.t__declspec: // __declspec precedes the identifier if (identifier == null && supportDeclspecSpecifiers) - __declspec(); + __attribute_decl_seq(false, true); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; @@ -1755,10 +1755,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { throwBacktrack(mark.getOffset(), mark.getLength()); } - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class and before the identifier - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec occurs after struct/union/class and before the identifier - __declspec(); + // if __attribute__ or __declspec occurs after struct/union/class and before the identifier + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); IToken nameToken = null; // class name @@ -1766,10 +1764,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { nameToken = identifier(); } - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class identifier and before the { or ; - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec occurs after struct/union/class and before the identifier - __declspec(); + // if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ; + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); if (LT(1) != IToken.tLBRACE) { IToken errorPoint = LA(1); @@ -1914,11 +1910,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { consumePointerOperators(pointerOps); - // if __attribute__ is after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo(); - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec is after the parameters - __declspec(); + // Accept __attribute__ or __declspec after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo(); + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); if (!pointerOps.isEmpty()) { finalOffset = calculateEndOffset((IASTPointerOperator) pointerOps @@ -2083,13 +2076,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { break; case IGCCToken.t__attribute__: // if __attribute__ is after the declarator if(supportAttributeSpecifiers) - __attribute__(); + __attribute_decl_seq(true, false); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; case IGCCToken.t__declspec: if(supportDeclspecSpecifiers) - __declspec(); + __attribute_decl_seq(false, true); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; @@ -2101,11 +2094,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { } while (false); - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters - __attribute__(); - - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __attribute__ is after the parameters - __declspec(); + // Consume any number of __attribute__ and __declspec tokens after the parameters + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); IASTDeclarator d = null; if (numKnRCParms > 0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 1bd818528f8..2c731f42764 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -3501,13 +3501,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec if (supportAttributeSpecifiers) - __attribute__(); + __attribute_decl_seq(true, false); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; case IGCCToken.t__declspec: // if __declspec appears before identifier if (duple == null && supportDeclspecSpecifiers) - __declspec(); + __attribute_decl_seq(false, true); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; @@ -3895,10 +3895,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consumePointerOperators(pointerOps); // if __attribute__ is after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo(); - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec occurs after struct/union/class and before the identifier - __declspec(); + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); if (!pointerOps.isEmpty()) finalOffset = calculateEndOffset((IASTNode) pointerOps @@ -4012,9 +4009,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { tryEncountered = true; break overallLoop; } - - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters - __attribute__(); + + // Consume any number of __attribute__ tokens after the parameters + __attribute_decl_seq(supportAttributeSpecifiers, false); + IToken beforeCVModifier = mark(); IToken[] cvModifiers = new IToken[2]; @@ -4116,7 +4114,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; case IGCCToken.t__attribute__: // if __attribute__ is after the declarator if(supportAttributeSpecifiers) - __attribute__(); + __attribute_decl_seq(supportAttributeSpecifiers, false); else throwBacktrack(LA(1).getOffset(), LA(1).getLength()); break; @@ -4324,22 +4322,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTName name = null; - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class and before the identifier - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec occurs after struct/union/class and before the identifier - __declspec(); - + // if __attribute__ or __declspec occurs after struct/union/class and before the identifier + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); + // class name if (LT(1) == IToken.tIDENTIFIER) name = createName(name()); else name = createName(); - if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class identifier and before the { or ; - __attribute__(); - if (LT(1) == IGCCToken.t__declspec && supportDeclspecSpecifiers) // if __declspec occurs after struct/union/class and before the identifier - __declspec(); - + // if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ; + __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); + if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) { IToken errorPoint = LA(1); backup(mark);