diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMScannerTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMScannerTests.java index 72f4ca2a053..f562414e94e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMScannerTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMScannerTests.java @@ -10,6 +10,7 @@ **********************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.internal.core.parser.ParserException; @@ -24,6 +25,8 @@ public class DOMScannerTests extends AST2BaseTest { public void testSimpleLocation() throws ParserException { IASTTranslationUnit tu = parse( "int x;", ParserLanguage.C ); //$NON-NLS-1$ assertEquals( tu.getDeclarations()[0].getNodeLocations().length, 1 ); + assertTrue( tu.getDeclarations()[0].getNodeLocations()[0] instanceof IASTFileLocation ); + } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser deleted file mode 100644 index 821cd0f1676..00000000000 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ /dev/null @@ -1,1530 +0,0 @@ -2004-07-30 Alain Magloire - - In the StrutureParseCallback add the - IASTUsingDirective - IASTUsingDeclaration - part of the return declarations - * org/eclipse/cdt/internal/core/parser/ast/StructuralParseCallback.java - -2004-07-07 Andrew Niefer - Symbol Table Refactoring: - - TypeInfo._typeDeclaration is no longer used for forward declarations, instead BasicSymbol._instantiatedSymbol - has been renamed to _symbolDef and is used for forwarding and also for its original template purpose. - - TypeInfo._operatorExpressions has been removed. You now apply operator expressions directly to the TypeInfo - with TypeInfo.applyOperatorExpression. - - a new interface ITypeInfo has been created. This interface should now be used instead of TypeInfo. - - the old TypeInfo has been separated into BasicTypeInfo, TypeInfo, and TemplateParameterTypeInfo, as well as dynamic - overrides of these classes. - - all construction of TypeInfo objects should now be done through TypeInfoProvider.newTypeInfo( ... ) functions - to ensure the object obtain has the needed fields. - The sum total of these changes is a reduction of memory used while parsing the combination of stdio.h, - iostream, and windows.h by about 4 Megs. - -2004-06-22 Alain Magloire - - Part of PR 68246. - Close the inputstream to release resource handle - when we done with it, we can not rely on the GC to do it for us. - - * parser/org/eclipse/cdt/core/parser/CodeReader.java - -2004-04-23 Andrew Niefer - - fixed up CompleteParseASTFactory.lookupQualifiedName in the case where the - tokenDuple has 1 segement - - fixed CompleteParseASTFactory.createMethod to handle template ids - - fixed instantiation of member templates - - fixed up handling of explicit specializations - -2004-04-22 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=47926 - -2004-04-22 John Camelon - Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=59686 - -2004-04-22 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=59507 - -2004-04-22 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=59179 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=59143 - -2004-04-22 Andrew Niefer - - modify how ASTTemplateDeclaration.getOwnedDeclaration works - - fix bug in TemplateEngine.selectTemplateFunctions() - -2004-04-21 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39703 - Removed method IScanner.addIncludePath() as it wasn't being used. - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39698 - -2004-04-21 Andrew Niefer - fixing 52695 & 45372 - - updated CompleteParseASTFactory.createUsingDirective & createUsingDeclaration - - added CompleteParseASTFactory.attachSymbolExtension( IExtensibleSymbol symbol, ASTNode astNode ) - - updated ContainerSymbol.addUsingDeclaration - - modified ISymbolASTExtension and added ExtensibleSymbolExtension.java - -2004-04-21 John Camelon - Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=59468 - -2004-04-20 Andrew Niefer - fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=59302 - Nested friend mishandled - -2004-04-20 Andrew Niefer - - implement IContainerSymbol.lookupFunctionTemplateId - - handle explicit template argument specification - - better handling of explicit specializations that use argument deduction - -2004-04-20 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58717 - -2004-04-20 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=59134 - Partially fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58858 - Added in additional CompletionKind's for STRUCT_REFERENCE, UNION_REFERENCE and ENUM_REFERENCE. - -2004-04-20 John Camelon - Restructuring of the parser extension packages. - Introduce IParserExtension and IASTFactory mechanisms w/partial implementation for GCC. - Introduce IGCCToken and GCCKeywords and fleshed out GCCScannerExtension implementation and interworking with Scanner. - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39697 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39695 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39684 - -2004-04-19 Andrew Niefer - fix bug 59149 [Parser] Redundant friend declaration fails parse - -2004-04-19 Andrew Niefer - fix problems with explicit specialization - -2004-04-16 Andrew Niefer - refactor ASTNode.lookup, partially addressing bug 50807 - -2004-04-15 David Daoust - Modified Scanner Performance by - 1. Moved ScannerContext sentinal to ContextStack - 2. Delay Stringizing macro parameter until needed - 3. Removed the sentinal from the scanner constructor - - Effect on #include - - total bytes objs time(ms)tokens - orig 59905960 1455079 1593 83812 - move sentinel 53824616 1262428 1462 83812 - delay stringizing 40868312 950355 1322 83812 - remove sentinal 38598848 910909 1312 83812 - -2004-04-15 Andrew Niefer - fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58492 - -2004-04-15 John Camelon - Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=39697 - -2004-04-15 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58175 - -2004-04-15 Andrew Niefer - fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=57791 - Parser infinite loop - -2004-04-14 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=52253 - -2004-04-14 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=44249 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=52004 - -2004-04-14 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58500 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58178 - -2004-04-14 Andrew Niefer - friends in the AST (bugs 45235 & 53759 ) - - added acceptFriendDeclaration to ISourceElementRequestor - - added isFriendDeclaration to IASTAbstractTypeSpecifierDeclaration - - modified isFriend on IASTFunction - - functions, methods & abstractTypeSpecifierDeclarations callback with acceptFriendDeclaration - instead of their normal accept* if isFriend() or isFriendDeclaration() is true. - - added getFriends to IASTClassSpecifier - -2004-04-13 Andrew Niefer - fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=46246 - modified symbol table sorting to use a collator instead of String.compare() - -2004-04-11 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=55785. - Fix required update to ISourceElementRequestor interface : clients updated accordingly. - -2004-04-11 John Camelon - Updated errorhandling in Parser::translationUnit(). - -2004-04-10 John Camelon - Removed unused methods from IToken. - Restructured Token implementation to be more memory efficient. - Tightened up visibility of different members in the implementation. - Added TokenFactory construct to isolate Token clients from the particulars of which IToken implementation to instantiate. - -2004-04-10 John Camelon - Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=57898 - -2004-04-09 Andrew Niefer - handle NPE during template argument deduction - fix bug in definitions of certain template member templates (fixes a ClassCastException encountered in ) - -2004-04-09 Andrew Niefer - fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=57754 - Fixed problems found after parsing iostream with discovered symbols, once 57754 was fixed: - fixed some problems with explicit specializations - handle using declarations of templates - handle typedefs in ASTCompleteParseFactory.queryIsTypeName - fixed instantiating constructors - -2004-04-08 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=57800. - -2004-04-07 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=50808. - Provided partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=50807. - Provided partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=52988. - Introduced EMPTY_STRING, a single constant that replaced > 100'S O literal "" in the code. - Updated IASTCompletionNode interface to provide better support for FUNCTION_REFERENCE and CONSTRUCTOR_REFERENCE. - Implemented IASTTypeId.getFullSignature() for both QUICK_PARSE and COMPLETE_PARSE. - Tweaked ASTNode.lookup() so that it would work for FUNCTION_REFERENCE. - -2004-04-07 Andrew Niefer - fix lookup in parents when the parent is a deferred template instance, enables content assist on list (from ) - -2004-04-07 Andrew Niefer - fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=44338 - -2004-04-07 Andrew Niefer - small changes to get through iostream under standard make with discovered symbols - - check null pointer in GCCScannerExtension.handlePreprocessorDirective, the null is probably a symptom of whatever - is giving us an unbalanced preprocessor directive - - catch exceptions during our 3rd attempt at a template argument in ExpressionParser.templateArgumentList - -2004-04-07 John Camelon - Provided a partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=50152 - Updated IExpressionParser::expression() interface necessitated by this fix, and updated its clients appropriately. - -2004-04-06 David Daoust - Removed some temporary objects that the scanner was producing. - Fixed small bug in GCCScannerExtension. - -2004-04-06 Andrew Niefer - Small changes to help with template parsing - - report line numbers with some problems - - don't throw on SEMANTIC_INVALID_TYPE while doing templates - - handle some NPEs - -2004-04-06 Andrew Niefer - fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=47625 - -2004-04-06 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39704 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=29060 - -2004-04-06 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=47797 - -2004-04-05 Andrew Niefer - - performance improvements originally from Dave Daoust: - - create new TraceUtil to handle logging trace messages - - postpone building Problem message until it is asked for - - only ask for problem message if it will actually be traced - - added more problem strings for problems coming from the symbol table - - added CompleteParseASTFactory.shouldThrowException, so we can ignore certain problems - encountered while parsing templates - - fix NPEs caused by bad type info objects - -2004-04-05 John Camelon - Fixed NPE in CompleteParseASTFactory::createUsingDeclaration(). - -2004-04-05 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=54029 - -2004-04-04 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=56516 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=53786 - -2004-04-02 Andrew Niefer - - partial handling template explicit instantiations - - bug 56834 - Symbols not available until end of parameter list, fixed for templates using temporary code block - - change IASTFactory.createTemplateParameter to take an IASTTypeId for the default value - - handle instantiating templates using default value that is a deferred instance - -2004-04-02 John Camelon - Updated SelectionSearch to work for functions, variables with initializers, etc. - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39705 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=44336 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=36770 - Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=51428 - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39694 - -2004-03-30 John Camelon - Partial fix for Bug 56614 - Content Assist] Global variables do not appear in a global completion list - -2004-03-29 Andrew Niefer - fixed bug 56620 - Outline view stops on error on last line of block - (errorHandling() goes to far) - -2004-03-29 John Camelon - Fixed Bug 56517 - Preprocessor skipping doesn't ignore the contents of string literals. - -2004-03-28 John Camelon - Remove warnings. - -2004-03-26 Andrew Niefer - - handle template template parameters - -2004-03-26 Andrew Niefer - -report references to symbols used in a template-id. - - - -2004-03-25 Andrew Niefer - -modify IASTFactory.createField & .createVariable to take ITokenDuple's for the name - -modify ITokenDuple to support manipulating TokenDuples that have template arguments in them - -fix NullPointer & ClassCast exceptions found while parsing - -2004-03-25 Hoda Amer - Joined effort with Bogdan: Added a parserTimeout() method to ISourceElementRequestor - and the ability for the parser to timeout. - -2004-03-23 Andrew Niefer - -fix recursive loop leading to StackOverFlowException during template instantiation - -fix copy constructors for templated classes - -fix bug 55673 - -2004-03-22 Andrew Niefer - -handling of Typedefs - -handle unbalanced preprocessor condition in scanner - -fix concurrent modification exception while processing unresolved references in a Class Specifier - -report correct owner class for templated methods - -some work on template explicit specializations - -handle templated class forward declarations - -2004-03-18 Andrew Niefer - parsing template-ids: enables clas template partial specializations and fixes 54778 indirectly - - add ITokenDuple.getTemplateIdArgLists - - Added ExpressionParser.templateArgumentList & ExpressionParser.consumeTemplateArguments - - modifications to ExpressionParser & Parser to parse template argument lists - - modified lookups to lookup with template-id if the token duple has argument lists - - modified TemplateFactory to handle partial specializations - -2004-03-17 Andrew Niefer - fix bug 55163 - - in for-init-statement, try expression-statement before simple-declaration since if it actually is a statement instead of a - declaration, the simple-declaration fails hard and can actually enter an infinite loop. - -2004-03-16 Dave Daoust - refactor scanner for performance improvements - -changes to accountForUndo, now named readFromStream - -changes to checking for valid macros - -2004-03-15 Andrew Niefer - Templates: - - added ISourceElementRequestor.acceptTemplateParameterReference - - added throws ASTSemanticException to IASTFactory.createTemplateDeclaration & createTemplateParameter - - IASTTemplateDeclaration extends IASTScope, IASTTemplateParameter extends ISourceElementCallbackDelegate - - modified DeclarationWrapper.createASTNode & createMethodASTNode to handle member templates - - Add functionality to ASTTemplateDeclaration - - implemented CompleteParseASTFactory.createTemplateDeclaration & createTemplateParameter - - changes to symbol table to make it easier for the parser to use - -2004-03-12 Andrew Niefer - handle case causing NPE in CompleteParseASTFactory.createElaboratedTypeSpecifier - -2004-03-12 Andrew Niefer - bug 54639 fix NPE in CompleteParseASTFactory.cloneSimpleTypeSymbol - -2004-03-11 John Camelon - Refactoring of Scanner to allow reuse in GCCScannerExtension - -2004-03-10 John Camelon - Further performance improvements in Scanner. - -2004-03-09 Andrew Niefer - bug 52948 - modified CompleteParseASTFactory.createTypedef() to set the typeSymbol of the typedef symbol - modified TypeFilter to handle LookupKind.TYPES and LookupKind.TYPEDEFS - -2004-03-09 John Camelon - Put back the work to reconcile relative paths w/IResource readers which was lost upon merge. - -2004-03-09 Dave Daoust - Removed the Strings associated with constant value tokens and keywords -- it looks cleaner, and reduces the number of objects created (only by 30 to 40 K) (about 2% quicker) - Buffered the File I/O associated with reading inclusions. - Restructured the scanner into a large case statement with a few - helper functions -- this is the start of removing the strings (or - providing a preallocated buffer for string manipulation) (about 2% quicker) - -2004-03-04 Andrew Niefer - bug 53213 externalize strings - -2004-03-03 John Camelon - Refactored parser for further content assist work. - -2004-03-03 John Camelon - Added some trace statements to CompleteParseASTFactory. - Cleaned up usage of Enum.getValue() wrt encapsulation of enumerator value. - Refactored CompleteParseASTFactory for correctness and abstraction. - Added preliminary IProblem support to CompleteParseASTFactory. - Added (commented out unfortunately) assertions into CompleteParseASTFactory. - Updated IASTUsingDeclaration to return an Iterator for declarations mapped rather than just a single declaration. - -2004-03-01 Andrew Niefer - bug 52695 : ast.complete.IASTClassSpecifier#getDeclarations returns an empty iterator - - take ASTNode.SymbolIterator and move it to org.eclipse.cdt.internal.core.parser.ast - - hook up ASTScope.getDeclarations to IContainerSymbol.getContentsIterator() using SymbolIterator - - create ExtensibleSymbol to implement IExtensibleSymbol and derive BasicSymbol, UsingDeclarationSymbol and UsingDirectiveSymbol from it. - - -2004-02-26 Andrew Niefer - mark strings that don't need to be externalized for translation - -2004-02-25 Bogdan Gheorghe - Added a check to make sure that the parser is in the top context before throwing - an EOF exception in SeletionParser. - -2004-02-25 John Camelon - Fixed Bug 43051 : Search: cannot specify relative search paths - Fixed Bug 45140 : refactor IScanner to allow use of Readers of IResource - -2004-02-25 John Camelon - Updated Scanner to allow for invalid identifier names despite C++'s best efforts at maintaining its honour. - -2004-02-24 John Camelon - Refactoring Scanner.handleInclusion to be more modular. - -2004-02-24 Andrew Niefer - Template Explicit Specializations (bug 51485) - adding basic symbol table functionality for non-nested template specializations - -2004-02-24 John Camelon - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=52823 - -2004-02-24 John Camelon - Partial Fix for Bug 52534 - Selection Search offset limit reached is broken - -2004-02-18 Andrew Niefer - added IUsingDeclarationSymbol and UsingDeclarationSymbol - changed IContainerSymbol.addUsingDeclaration to return a IUsingDeclarationSymbol - -2004-02-17 Andrew Niefer - bug 52111 : added IContainerSymbol.removeSymbol() which is implemented as ContainerSymbol.removeSymbol() - -2004-02-16 Andrew Niefer - bug 52120 document symbol table use of ParserSymbolTableException - also clean up a couple of exceptions - -2004-02-12 Andrew Niefer - Fixed up symbol table handling of const & volatile - fixed bug 47628 - signed char is parsed as char - fixed bug 47636 - char* and char[] are treated as different types - fixed bug 45697 - Parser/Symbol table: Mismatched declaration & definition - -2004-02-12 John Camelon - Removed IASTCompletionKind.SCOPED_REFERENCE as it was obsolete. - Did preliminary work to support content assist within qualified names. - -2004-02-11 John Camelon - Restructured Parser implementation to allow for better support of Selection Search. - Restructured Parser implementation to allow for separation between parsing expressions (Scanner) and complete C/C++ source. - -2004-02-10 John Camelon - Workaround for Bug 51502 - Parser spins on particular file (Scalability) - -2004-02-10 Andrew Niefer - Templates in the symbol table (org.eclipse.cdt.internal.core.parser.pst) - ITemplateFactory.java - ITemplateSymbol.java - DeferredTemplateInstance.java - ParserSymbolTableError.java - TemplateEngine.java - TemplateFactory.java - TemplateSymbol.java - Most of the other main symbol table files (BasicSymbol, ContainerSymbol, etc) were modified - -2004-02-10 John Camelon - Fixed Bug 51302 - Content Assist: No completion list available following namespace declaration. - -2004-02-10 John Camelon - Refactored Parser.java to allow inline small functions and tightened the signatures for statement(). - Refactored Scanner.java to allow for data to be encapsulated to allow for IScannerExtension to act upon it. - Partially fixed Bug 47628 - signed char is parsed as char (affects the outline view) - -2004-02-08 John Camelon - Added support for inline method x-references. - Fixed Bug 44340 - Inline functions fail to resolve references - Fixed Bug 51243 - Content Assist in an empty document causes a NPE - -2004-02-06 Andrew Niefer - fixed bug51260 - Content Assist: Completion inside a class method silently fails with a ClassCastException - filter symbols without attached AST nodes out of the completion results so the iterator doesn't sometimes return null. - -2004-02-04 John Camelon - Added preliminary (crude) bSelectionParser IParser implementation for SELECTION_PARSE clients. - -2004-02-01 John Camelon - Added CompletionKind.UNREACHABLE_CODE to IASTCompletionNode. - Updated Scanner to handle unreachable code scenarios in content assist. - Added Directives class to centralize preprocessor directive strings. - Added keyword completion for preprocessor lines that start with #. - -2004-01-30 John Camelon - Partial fix for Bug 47752 - Outline does not recognize functions with full body try/catch blocks - -2004-01-30 John Camelon - Updated Scanner to allow for more robust completion in #if directives. - -2004-01-30 John Camelon - Fixed Bug 50487 - Wrong completion kind and prefix after "#ifdef" - -2004-01-29 Hoda Amer - Removed CompletionKind.KEYWORD. - -2004-01-29 John Camelon - Fixed 50642 - Wrong completion kind when declaring an argument type - Updated using declarations for more accurate keywords and closure. - -2004-01-29 Hoda Amer - Put CompletionKind.FUNCTION_REFERENCE back. - -2004-01-28 John Camelon - Fixed Bug 50821 - Freezes when opening / saving .c file - -2004-01-28 John Camelon - Fixed Bug 50711 - Wrong completion kind in a new expression - -2004-01-28 John Camelon - Updated Scanner to add ANSI built-in defined macros for C and C++. - Updated GCCScannerExtension to add GCC specific defined macros for C++. - Added factory infrastructure to allow for C/C++ dialect extensions to be added and contained. - Added IASTExpressionExtension w/implementation to allow for GCC specific leniency on evaluating expressions. - -2004-01-28 Andrew Niefer - Fixed bug#50729: Visibility is incorrectly decided in inheritance - -2004-01-27 John Camelon - Refactored parser to allow for cleaner content assist implementation. - Removed IASTCompletionNode.CompletionKind.STATEMENT_START as it is redundant. - Fixed bug 50640 - Wrong completion kind when expecting an exception - Fixed bug 50471 - Wrong completion kind after the "using" keyword - Fixed bug 50621 - Wrong completion kind in a class declaration - -2004-01-17 Hoda Amer - Added IASTCompletionNode.CompletionKind.New_Type_Reference - for a completion kind after a new expression. - -2004-01-27 Andrew Niefer - Updates to handle _Bool - - modified CompleteParseASTFactory.getParameterTypeInfo - CompleteParseASTFactory.createReference - CompleteParseASTFactory.usualArithmeticConversions - CompleteParseASTFactory.getTypeKind - Parser.typeId - TypeFilter.shouldAccept - TypeInfo.equals - -2004-01-26 John Camelon - Added traceLogs into Scanner. - Fixed Bug 46402 : expression evaluation error on branch not taken - Added beginning of IScannerExtension and GCCScannerExtension support for gcc specific aspects. - Added separate Scanner log category for tracing and updated clients to use it. - -2004-01-26 Andrew Niefer - Handle the C types _Complex, _Imaginary, _Bool, & long long int: - modified ParserSymbolTable.promotion() & conversion() - added TypeInfo.isLongLong - modified TypeInfo.canHold() - -2004-01-23 John Camelon - Added support for content assist in the scanner.. - -2004-01-22 John Camelon - Added token, scanner and problem subpackages to org.eclipse.cdt.internal.core.parser. - -2004-01-22 Hoda Amer - Solved a small problem in the ASTCompleteParseASTFactory sent to me by Dave. - -2004-01-20 John Camelon - Added traceLog() call into Scanner.handleProblem() and updated ParserFactory.createPreprocessor() for extra error handling. - -2004-01-20 John Camelon - Tidied up Scanner implementation for unused fields, inefficient String manipulations and redundant parameters. - -2004-01-19 John Camelon - Added IToken.getLineNumber() to facilitate adding line numbers to AST. - Added line number support into IASTOffsetableElement. Updated all implementations to use this. - Updated Parser and IASTFactory to populate IASTOffsetableElement with the values retrieved from IToken. - Removed IScanner.getLineNumberForOffset(). - -2004-01-16 Andrew Niefer - Created IExtensibleSymbol, which is a new base class for the symbol interfaces - Created IUsingDirectiveSymbol and UsingDirectiveSymbol - Modified ASTUsingDirective to use IUsingDirectiveSymbol - Modified CompleteParseASTFactory.createUsingDirective - Added IContainerSymbol.getContentsIterator() - Implemented getContentsIterator in ContainerSymbol - -2004-01-16 John Camelon - Changed IASTNode.LookupException to IASTNode.LookupError. - Updated IASTElaboratedTypeSpecifier to remove redundant extends relationships. - -2004-01-15 Andrew Niefer - Modified symbol table constructor to take a ParseMode as a parameter. - Modified symbol table to use a TreeMap instead of HashMap when ParseMode is CONTEXTUAL_PARSE - Modified ASTNode.lookup to throw ASTNotImplementedException if called when ParseMode is not CONTEXTUAL_PARSE - -2004-01-15 Hoda Amer - -2004-01-15 John Camelon - Renamed IASTNode.LookupResult IASTNode.ILookupResult. - Introduced new ParseError exception for contextual parse() methods. - Renamed ParserFactoryException ParserFactoryError. - Replaced ParserNotImplementedException with a variant of ParseError. - Updated IScanner & IParser to not reference OffsetLimitReachedException explicitly. - Renamed ParserMode.CONTEXTUAL_PARSE to COMPLETION_PARSE. - Cleaned up IMacroDescriptor and made Scanner definitions table consistent. - Added IScanner.getDefinitions() to return the entire Map of definitions to a client. - Removed most of the warnings from parser source directory. - Removed the unused SyntaxErrorException. - Provided partial fix for Bug 44370 IASTMacro requires more information for clients. - -2004-01-12 John Camelon - Fixed bug 48909 - Wrong completion node after a . or an -> - Fixed bug 49702 - Wrong completion kind sent in const/dest and code blocks - Added new CompletionKind - STATEMENT_START to indicate the beginning of a statement line. - -2004-01-08 Andrew Niefer - fixing bug 43110 - Parser support needed for functions with ellipses - Added IParameterizedSymbol.setHasVariableArgs() & hasVariableArgs() - Modified ParserSymbolTable.resolveFunction & reduceToViable - Modified CompleteParseASTFactory.createMethod & createFunction - -2004-01-08 Andrew Niefer - Fixing 48307 - PST: Friendship needs to be handled better - Added IDerivableContainerSymbol.lookupFunctionForFriendship. - Modified IASTFactory.createMethod to take an ITokenDuple for the method name. - Added LookupType.FORFRIENDSHIP and use it in LookupElement. - Modified CompleteParseASTFactory.createMethod to handle friend functions. - -2004-01-06 Andrew Niefer - For Content Assist, support lookup using LookupKind.THIS (lookup in the class of the this pointer ) - Fix bug where forward declared method/functions appeared twice in the content assist lookup results. - -2004-01-06 John Camelon - Renamed IToken::tELIPSE to IToken::tELLIPSIS - Partially fixed Bug 43110 : Parser support needed for functions with ellipses - -2004-01-05 John Camelon - Removed warnings. - Moved StructuralParseCallback from model to parser directory to facilitate building the parser standalone. - -2003-12-31 Hoda Amer - - Changed ASTUtil.getType to include parameter initializer clause in returned string. - -2003-12-22 Hoda Amer - Content Assist Work : Returned the results size of the IASTNode lookup - to help in determining the scope relevance - - Added the variable type to a search match result to be compatible with the - results found by the completion engine - -2003-12-17 Andrew Niefer - Content Assist work: - - change parser & symbol table to handle handle friend classes - - change visibility filtering to check for friendship - - fix finding function parameters in prefix lookup - -2003-12-17 Hoda Amer - Content Assist work : Integrated with Parser and Symbol table modifications - -2003-12-15 Andrew Niefer - Changed IASTNode.lookup to take the context as a parameter - created ASTNode to implement IASTNode, ASTSymbolOwner extends it. - Set Completion Scope for statements - Set Completion context for . and -> expressions - -2003-12-15 Hoda Amer - Fixed [Bug 47234] new ParserMode required for a better CModel : - - Added a core plugin preference to build the CModel in Structural mode - - Added StructuralParseCallBack class - - Added lists of declarations to AST Scopes in the complete AST - -2003-12-12 John Camelon - Added preliminary keyword support into IASTCompletionNode::getKeywords(). - Refactored parser to put keyword string literals in one utility class. - -2003-12-11 John Camelon - Added OffsetLimitReachedException and restructured Parser exceptions. - Continued support for code assist/selection search parser. - Ensured all source in parser/ have copyright notices. - -2003-12-09 Andrew Niefer - -created TypeFilter to support support filtering of what kind of symbols to find (for prefix lookup 48306) - -added IContainerSymbol.isVisible for bug 48294 - -2003-12-09 Hoda Amer - Modified IASTCompletionNode.CompletionKind - modified IASTNode.LookupKind - Changed IASTScope to extend IASTNode - -2003-15-09 John Camelon - Fixed Bug 47234 : new ParserMode required for a better CModel - Updated IASTCompletionNode to include a scope as well as a context. - Begun parser updates to support code assist & selection search. - -2003-12-05 John Camelon - Broke the Parser up into separate classes per ParserMode. - -2003-12-04 John Camelon - Removed some warnings. - Fixed Bug 39678 : Scanner doesn't support concatenation of different-type string literals (GCC) - Refactored ScannerContext to use constructors rather than initializers. - Refactored IScannerContext to use enumeration-esque kinds. - Added code assist/selection search support to Scanner. - -2003-12-03 Andrew Niefer - - Symbol table - modify prefix lookup handling of ambiguities - - fix up qualified lookup - - add IContainerSymbol.lookupMethodForDefinition - - Parser - modify Complete parse AST factory to use the correct lookups in different situations - - Created a LookupType enum to specify what kind of lookup is needed (Qualified, unqualified, for definition) - - -2003-11-27 Andrew Niefer - fix bug 47264: Parse fails when using struct s foo; and int s; in function bodies - -2003-11-18 Andrew Niefer - Refactor PST: Split Declaration into 4 classes : ContainerSymbol, DerivableContainerSymbol, ParameterizedContainerSymbol, - SpecializedSymbol. Move these along with BasicSymbol & TemplateInstance to no longer be nested in ParserSymbolTable. - -2003-11-13 Hoda Amer - Changed the getExpressionResultType() in the complete factory to return - an object of type ExpressionResult. - Solved bug#44342: Failure to dereference function calls after a . or an -> - -2003-11-07 John Camelon - Fixed Bug 39554 : _Pragma directive is not supported (ANSI C99) - -2003-11-06 John Camelon - Removed one last remainder of core.model.Util in parser to unbreak 2.0 build. - -2003-11-05 John Camelon - Fixed Bug 44838 : exception when resolving parameter references in a constructor - Fixed Bug 46165 : fields referenced in constructor chains are not called back upon - Fixed Bug 45551 : Macro replacement in #include directives - -2003-11-05 John Camelon - Cleaned up the ParserFactory interface to check for validity of input arguments. - Moved NullSourceElementRequestor and ScannerInfo to public interface as requested. - Restructured code so that no Eclipse/CDT source outside the parser source directory is used. - Updated parser clients to use new ParserFactory (stand-alone parser work item). - -2003-11-05 John Camelon - Removed warnings from parser source tree. - Removed preliminary task tags support to clean up parser interfaces and implementation. - Added preliminary IProblem support to - -2003-11-03 John Camelon - Added in preliminary interface for code completion mode. - -2003-10-28 Andrew Niefer - Fixed Bug 44925 : Search: Elaborated type specifier - Patially fixed Bug 44510 : C/C++ Search gives wrong results - -2003-10-24 John Camelon - Fixed Bug 45476 : preprocessor macro "defined" not handled correctly - Fixed Bug 45477 : macro redefines prevent further parsing - -2003-10-24 John Camelon - Fixed Bug 39542 : Parser fails on 'struct' parameter types - Fixed Bug 39549 : Designated initializers are not supported (ANSI C99) - Fixed Bug 39551 : Complex and imaginary numbers are not supported (ANSI C99) - -2003-10-21 John Camelon - Fixed Bug 40007 : Parser reports success when it fails - Fixed Bug 44305 : Scanner/preprocessor fails on conditionals using hexidecimal - Fixed Bug 41935 : parser provides wrong name on namespace aliases - Fixed Bug 39525 : Parser fails on expressions that take address of overloaded operators - Fixed Bug 45287 : Scanner does not accept character sequence literals - Fixed Bug 36550 : Error recovery with unterminated string is weak - Fixed Bug 41063 : Remove unused K&R C support from ANSI Parser - Fixed Bug 39528 : Function try-blocks are not supported by the parser (ANSI C++) - Fixed Bug 39538 : Parser fails on explicit instantiation of templated operators - Fixed Bug 39536 : Parser fails on templated constructors/conversion operators - Refactored Scanner to make it easier to debug. - -2003-10-01 John Camelon - Fixed Bug 43987 : Search results: Declaration of class not highlighted when selected - Fixed Bug 43997 : Search results: selection includes preceding whitespace - Fixed Bug 44034 : Scanner failure on #undef - -2003-10-01 Andrew Niefer - bug43951 - search on ctor declarations returns definition too. - PST changes: - - modify lookupConstructor to copy the constructor list before resolving on it - - modify checkUserDefinedConversionSequence the same way - - modify isValidFunctionOverload to check for forward declarations - -2003-10-01 Bogdan Gheorghe - Modified CDT log dump in Parser.fetchToken to include error message - -2003-10-01 Andrew Niefer - bug43450 - Scanner needs to handle include paths that contain quotes - -2003-09-30 Bogdan Gheorghe - Added CDT log dump in Parser.fetchToken to catch HandleInclusion failures - -2003-09-30 John Camelon - Fixed Bug 43503 : Search:f_SD_01 cannot be found in ManyClasses20 Project - Fixed Bug 43680 : Fix Parser Error Handling - -2003-09-30 Hoda Amer - -Solution to [Bug 43053] require reference cleanup for expressions - Added purgeReferences() at the end of ASTExpression::acceptElement() - -2003-09-30 Andrew Niefer - PST changes for bug 43503 - parser needs to know the different between ambiguous functions - and no functions when no parameter information is provided - - throw r_UnableToResolveFunction if we have more than 1 function and no parameter info was given - - handle this case in addUsingDeclaration. - * note that r_UnableToResolveFunction doesn't necessarily mean ambiguous if we had enough information - -2003-09-29 Hoda Amer - Solution to bug#43679 : Exceptions in indexer - -2003-09-29 Andrew Niefer - fixed bug 43834 : Empty Parameter list and parameter list taking one void do not match - -2003-09-29 John Camelon - Continued work on Bug 43062 : Outline is confused on operator methods containing spaces - Partial fix for Bug 43680 : Fix Parser Error Handling - -2003-09-26 John Camelon - Fixed Bug 43644 : 6 triangle icons appearing in outline viewer when typing an error - Fixed Bug 43062 : Outline is confused on operator methods containing spaces - Fixed Bug 39531 : Problems with type conversion operators - -2003-09-25 Hoda Amer - - Last part of solution to bug#42453: Expression result types not computed - Added the handling of POSTFIX_TYPENAME_IDENTIFIER - Completed bug#43221: POSTFIX_TYPENAME_IDENTIFIER not implemented - - Solution to bug#43644 : 6 triangle icons appearing in outline viewer when typing ... - -2003-09-24 Hoda Amer - Partial solution to bug#42453: Expression result types not computed - Added the handling of the NEW_TYPEID, CASTEXPRESSION, POSTFIX_DYNAMIC_CAST, - POSTFIX_REINTERPRET_CAST, POSTFIX_STATIC_CAST, and POSTFIX_CONST_CAST - -2003-09-25 John Camelon - Partial fix for Bug 43221 : POSTFIX_TYPENAME_IDENTIFIER not implemented - -2003-09-24 John Camelon - Fixed Bug 43106 : Symbol Table support needed to resolve types - Fixed Bug 43375 : isExtern not returning true for extern declarations - -2003-09-23 John Camelon - Fixed Bug 43084 : need to restructure TypeId to allow dynamic_cast<> type expression references. - Fixed Bug 39504 : sizeof-expressions are not handled properly - -2003-09-23 Hoda Amer - Solution to bug#43373: No reference to static member in definition - Solution to bug#43371: constructor incorrectly marked private - -2003-09-18 Andrew Niefer - - modified Symbol table interfaces to use Lists & Maps instead of LinkedList and HashMap - - fixed warnings in ParserSymbolTable - - fixed bug43106 - Symbol Table support needed to resolve types - - fixed bug43156 - require ability to add implicit inheritance copy constructor - - fixed bug43159 - TypeInfo.equals() not working properly - - fixed bug43238 - Postfix_Subscript expressions confuse function resolution - -2003-09-16 Andrew Niefer - - added setThrowExceptionOnBadCharacterRead to IScanner to help with wildcard bug43063 - -2003-09-17 Hoda Amer - In completeParseASTFactory.getExpressionResultType(): Added the support - for expression types: PM_DOTSTAR, PM_ARROWSTAR, CONDITIONALEXPRESSION - -2003-09-16 John Camelon - Implement CompleteParse IASTFunction::previouslyDeclared(). - -2003-09-16 Hoda Amer - In completeParseASTFactory.getExpressionResultType(): Added the support - for expression type PRIMARY_THIS. - In createMethod(): changed the scope of a method definition to point to - the parent class. - -2003-09-15 John Camelon - Fixed Bug 39556 : 'restrict' qualifier is not supported (ANSI C99) - Fixed Bug 43126 : ISourceElementRequestor.acceptParameterReference accesses internal class - Fixed Bug 43062 : Outline is confused on operator methods containing spaces - Cleaned up some warnings in the parser. - -2003-09-15 Andrew Niefer - bug43106 - added getConditionalOperand to ParserSymbolTable - -2003-09-15 John Camelon - Partially fixed Bug 42979 : Cannot search for operator overloaders - -2003-09-12 Hoda Amer - In completeParseASTFactory.getExpressionResultType() - - Added the handling of some more expression types. - See CompleteParseASTExpressionTest for details. - -2003-09-12 John Camelon - Fixed Bug 42985 : Search: Qualified function call is treated as a declaration - Fixed Bug 40419 : parser fails on heavily templated expressions - -2003-09-12 John Camelon - Fixed Bug 43013 : IASTParameterDeclaration does not derive from IASTOffsetableNamedElement - -2003-09-12 Andrew Niefer - Fixed some NPEs in ParserSymbolTable.getFlatTypeInfo - Added some comments and created some constants to help clarify ranking of conversion sequences - -2003-09-11 John Camelon - Fixed Bug 42840 : Search: Cannot find things after double declarations - Fixed Bug 42798 : Selected #include off by 1 char - Fixed Bug 42872 : dynamic cast not parsed properly - Partially fixed Bug 39504 : sizeof-expressions are not handled properly - Updated SourceElementRequestor callbacks to include IASTParameterReference callbacks. - -2003-09-09 Hoda Amer - - Solved the double reference problem - - solution to bugs #42822, #42823, & #42822B - -2003-09-09 John Camelon - Updated ScannerException to be more precise and include more information. - Updated Parser to be more careful of how it handles particular Scanner errors in COMPLETE_PARSE mode. - -2003-09-08 Bogdan Gheorghe - Added ScannerExceptions in Preprocessor.java to PDE Error - Log - -2003-09-09 Hoda Amer - Added more IASTExpression.Kind handling to CompleteParseASTFactory.getExpressionResultType() - -2003-09-08 John Camelon - Made scoping support more robust in CompleteParse mode. - Refactored ISourceElementRequestor (enter|exit)CodeBlock() to take IASTCodeScope rather than IASTScope. - Removed the now obsolete DOM. -` Added enumerator references to ISourceElementRequestor. - -2003-09-08 Andrew Niefer - - Created ParserLanguage.java - - Updated Factories to take language as parameter when create scanner & parser - - Updated Parser, Scanner & ParserSymbolTable to take language in their constructor - -2003-09-05 Hoda Amer - - Added references to variables with pointers in solution - of bug#42453:Expression result types not computed - - -2003-09-05 John Camelon - Continue to add support for parsing within function bodies. - Add workaround for 1.2 for inline function declaration-before-use chicken-and-egg. - -2003-09-05 John Camelon - Fixed NPE on nested declarations in code blocks. - -2003-09-04 John Camelon - First pass of parsing function bodies with X-Reference information. - Updated IASTFactory/ISourceElementRequestor to include IASTCodeScope - constructs, clients should keep this in mind and update their implementations. - -2003-09-04 Andrew Niefer - Fix bug42541 - Anonymous structures cause NPE in full parse - -2003-09-03 Andrew Niefer - fix bug in PST that prevents > 2 constructors - -2003-09-03 John Camelon - Fixed bug41445 - QualifiedLookup succeeds where it should fail. - -2003-09-02 Andrew Niefer - bug41935 - Modifications to PST to allow for namespace aliases - -2003-08-28 John Camelon - Fixed bug39535 - Parser fails on namesapce aliases - -2003-08-26 Bogdan Gheorghe - Added parser constant to all debugLog tracing statements. - -2003-08-25 John Camelon - Fixed bug39526 - Parser doesn't handle initializers correctly. - Fixed bug41520 - FullParse : Constructor Initializer is mistaken as function prototype - -2003-08-25 John Camelon - Fixed Bug 39530 - More problems with initializers. - Fixed Bug 37424 - Crash when opening big files - Refactored pointerOperators & cvQualifiers to not throw backtracks in optional case. - Added tracing support to cdt.core plugin via .options file. - -2003-08-14 John Camelon - Removed warnings from SymbolTable & QuickParseCallback (removing implicit accessor generation). - Made IASTElaboratedTypeSpecifier derive from IASTOffsetableNamedElement (as it should). - -2003-08-14 John Camelon - Added X-Reference support for ArrayModifiers and Exception Specifications. - Fixed Bug 41551 - HandleInclusion always throws ScannerException on local includes. - -2003-08-13 John Camelon - Added constructor expression support for variables. - Added constructor chain x-reference support for methods. - -2003-08-13 John Camelon - Added Expression x-reference support into Parser. - -2003-08-12 John Camelon - Added X-Ref/Elaborated type support w/element requestor callbacks. - -2003-08-11 John Camelon - Added Complete Parse support for ASM Definitions. - Added isVolatile() to abstract declarations. - Added Complte Parse support for elaborated types / forward declaration of classes. - Fixed some robustness issues. - -2003-08-05 Andrew Niefer - - Refactor symbol table functions to start with lower case letters - - Added better constructor support : - IDerivableContainerSymbol.addConstructor - IDerivableContainerSymbol.lookupConstructor - IDerivableContainerSymbol.getConstructors - - Changed ParserSymbolTableException.r_Unspecified to r_InternalError - - implicit user-defined conversion sequences now only use constructors not marked explicit - - user-defined conversion sequences are now only applied at most once (12.3-4 in spec) - -2003-07-31 Andrew Niefer - Added better support to the parser symbol table for forward declarations - -2003-07-31 Victor Mozgin - Fixed PR 39540 : Parser fails on const qualifier after class specifier. - -2003-07-30 Victor Mozgin - Fixed PR 39532 : Parser fails on fully-qualified class names. - -2003-07-29 John Camelon - Updated AST to better represent pointers to functions/methods. - Implemented typedef declaration/x-ref infrastructure. - -2003-07-29 Victor Mozgin - Fixed PR 39546 : Parser fails on 'signed' casts. - -2003-07-28 John Camelon - Fixed Bug 40842 - Parser: NPE while parsing class declaration in full parse mode - Fixed Bug 40843 - Parser: failParse doesn't set parsePassed = false on EOF. - Fixed Miscellaneous overrides issues involving parameters & functions. - -2003-07-28 John Camelon - Fixed Bug 40730 : Parser is not searching the include path for #include"" - -2003-07-28 Victor Mozgin - Fixed PR 39537 : Parser fails if template parameters contain '>' or '<' characters. - -2003-07-25 Victor Mozgin - Fixed PR 39553 : Macros are not expanded in #include statements. - -2003-07-24 John Camelon - Added COMPLETE_PARSE support for Method and Field declarations and cross-references. - Fixed some small ParserSymbolTable bugs. - Added support for linkage specification under COMPLETE_PARSE. - -2003-07-24 John Camelon - Added CompleteParse - UsingDirective & UsingDeclarations w/namespace/class/field variable references. - Added CompleteParse support for enumeration specifiers and references in variables & fields. - Stubbed out other Scopes/Declarations for COMPLETE_PARSE mode to allow indexer team to switch over ASAP. - -2003-07-22 John Camelon - Added in preliminary support for Field/Variable w/cross references on their types. - -2003-07-21 John Camelon - Addded in support for BaseSpecifier & class/namespace reference callbacks upon those. - -2003-07-21 John Camelon - Fleshed out basic declarations for FullParse AST. - Fixed Bug 40554 - Fields coming back as Vars - Fixed Bug 40555 - Methods come back as Functions - -2003-07-18 John Camelon - Added ISourceElementCallbackDelegate interface for AST constructs to allow the Parser to delegate callback's to the nodes themselves. - Got rid of ParserMode.STRUCTURAL_PARSE for the time being. - Removed org.eclipse.cdt.internal.core.parser.ast.full. - Created org.eclipse.cdt.internal.core.parser.ast.complete. - Updated ParserFactory.createScanner() to force the user to provide a callback and a ParserMode. - Introduced ASTSemanticException for COMPLETE_PARSE mode. - Fleshed out preliminary IASTReference interfaces and added callbacks to ISourceElementRequestor. - Removed acceptElaboratedTypeSpecifier() from ISourceElementRequestor. - -2003-07-18 John Camelon - Removed DeclaratorDuple as it was obsolete. - Fixed offsets in quickParse's IASTTypedefDeclaration implementation. - Fixed Bug 40436 - Fully Qualified Names Needed (for Indexer/Search features) - -2003-07-17 John Camelon - Removed IParserCallback. - Partially converted DOM to ISourceElementRequestor (requires refactoring of CModelBuilder & StuctureComparator modules in near future). - Completely finished ISourceElementRequestor/IASTFactory work for QuickParse mode. - Added pointer to methods/functions into AST callback structure. - Restructured AST class hierarchy. - Removed the old IParserCallback return Objects from every Parser method. - -2003-07-17 Victor Mozgin - Added support for digraphs and trigraphs. - Added support for hex floating point literals. - Fixed stack overflow problem with string literals concatenation. - Fixed problem with token pasting in macros. - This solves PR 39523, 39550, 39552. - -2003-07-15 Victor Mozgin - Fixed PR 39349 : Scanner fails on long long literals. - Fixed PR 39544 : Scanner fails on wide char literals. - -2003-07-10 John Camelon - Added in template support to IAST hierarchy. - Updated instantiation & specialization hierarchy. - Removed ASTTemplateDeclarationType. - Added full requestor callbacks for fields, variables, functions, methods & typedefs. - -2003-07-08 John Camelon - Filled out IASTMethod & IASTFunction & added implementations. - Updated IScanner, clients & implementations to use IScannerInfo. - Finished SimpleDeclaration porting to new architecture, only thing left is templates. - -2003-07-07 John Camelon - Bug 39652 - AST: Nested Classes incorrectly report null qualified Names - Fuller specification of Field/Method interfaces. - -2003-07-04 John Camelon - Fixed NPE in Parser::declarator(). - Bug 39652 - AST: Nested Classes incorrectly report null qualified Names - -2003-07-04 Victor Mozgin - Added CTaskTagsReconciler. - Extended ParserFactory with createProblemReporter() and createTranslationResult(). - -2003-07-02 Victor Mozgin - Fixed PR 39501 : Parser problems with throw clauses. - -2003-06-30 John Camelon - Further restructuring of Parser for ISourceElementRequestor. - Added interfaces/implementation for Simple Declarations. - Cleaned up DOM's representation of Constructor chains. - -2003-06-28 John Camelon - Completed Quickparse expression representation. - Updated ExpressionEvaluation and associated tests. - -2003-06-26 John Camelon - Update IASTExpression. - Move Parser.Backtrack and Parser.EndOfFile to external interface. - -2003-06-26 Victor Mozgin - Task tags support in C/C++ comments (initial revision). - Infrastructure to support problem reporting during translation. - Additional infrastructure for options/preferences handling. - -2003-06-25 John Camelon - Fixed bug39348 - sizeof elaborated types fail in parsing expression - -2003-06-25 John Camelon - Create new interface and support for calculating lineNumber/offset mapping. - Updated IASTClassSpecifier for qualified name query. - Began structuring expressions and declarators in Parser for ISourceElementRequestor. - Updated other packages to use new interfaces. - -2003-06-24 John Camelon - Updates for ISourceElementRequestor - elaborated types & enumerations. - -2003-06-23 John Camelon - Updating SimpleDeclarations to move towards new Callback structure. - -2003-06-23 John Camelon - Updated Factory infrastructure, constructors, etc. - Introduced Preprocessor class for transitive closure calc. client. - -2003-06-20 Victor Mozgin - Fixed PR 36463 : Offsets of macros are incorrect. - -2003-06-17 Victor Mozgin - Implemented correct handling of nested declarators in CModelBuilder. - Added proper support for function pointers as parameters. - This fixes PR 38921 and 39002. - -2003-06-16 Victor Mozgin - Implemented support for old K&R-style C function declarations. - Added oldKRParametersBegin() and oldKRParametersEnd() to IParserCallback. - Added getParameterTypes() with support of K&R to CModelBuilder. - Fixed ExpressionEvaluator and NullSourceElementRequestor for additions to IParserCallback. - Added handling of K&R syntax to the parser. - This fixes PR 7541, 35320 and 38434. - -2003-06-14 Victor Mozgin - Fixed handling of parameter lists for typedefs for functions. - More errorhandling in CModelBuilder. - Added handling of pointers to members. - Added handling of declarations for nested scopes (like A::B::C). - This fixes PR 36290, 36931 and partially 38920. - -2003-06-13 John Camelon - Added Class/Base infrastructure to public interfaces & requestor callback. - Moved many internal interfaces to external packages. - Organized imports. - -2003-06-13 Victor Mozgin - Renamed NullParserCallback into NullSourceElementRequester. - NullSourceElementRequester now dummy-implements both IParserCallback and ISourceElementRequester. - -2003-06-13 John Camelon - Merged ParserSymbolTable branch back into HEAD. - -2003-06-12 John Camelon - Get rest of JUnit tests working, will merge back to HEAD branch. - -2003-06-12 John Camelon - Introduction of ASTFactory strategy, some restructuring of packages and interfaces. - -2003-06-10 John Camelon - Futher pursuit of the golden hammer, symbol table integration. - -2003-06-09 John Camelon - First step in replacing IParserCallback with ISourceElementRequestor. - -2003-06-05 Andrew Niefer - Begin implementation of functions for template specializations: deduceTemplateArgument, - classTemplateSpecializationToFunctionTemplate, transformFunctionTemplateForOrdering - -2003-06-09 Victor Mozgin - Fixed for conversion operator declarations. - This fixes PR 36769 (finally) and PR 38657. - -2003-06-09 Victor Mozgin - Fixed Bug 36932 - RTS: Parser fails on "new" in ctor initializer - Improved handling of new-expressions: placements, arrays and - multiple parameters in initializers are now parsed. - -2003-06-09 Victor Mozgin - Fixed Bug 36701 - Scanner looses non-token chars while macro stringizing - -2003-06-07 Victor Mozgin - Fixes for templated constructor/destructor/operator declarations. - This fixed PR 36766, 36767, 36769 (STL parsing problems). - -2003-06-06 Victor Mozgin - Fixed Bug 38065 - Scanner skipped backslashes inside the code - -2003-06-05 John Camelon - Fix Bug 38380 "Include" class public methods fails JUnit tests - -2003-05-29 Andrew Niefer - new Class eType for stronger type safety in TypeInfo - new class PtrOp for better handling of pointer operators and cv qualifiers - new class TemplateInstance to support templates - Start of implementation for templates & specializations - -2003-05-29 John Camelon - Remove all AST components. - -2003-05-26 John Camelon - Rollback PST/Parser integration. - -2003-05-13 Andrew Niefer - Moved symbol table to org.eclipse.cdt.internal.core.pst - Created interface for symbol table: ISymbol, IContainerSymbol, IDerivableContainerSymbol, - IParameterizedSymbol, and ISpecializedSymbol. These are all implemented by Declaration - The symbol table itself uses this interface instead of using its Declaration directly - (with the exception of the undo command framework) - -2003-05-08 Andrew Niefer - Added a basic command structure to support rollbacks - -2003-05-06 John Camelon - Further integration of SymbolTable into Parser, some refactoring. - -2003-05-05 John Camelon/Andrew Niefer - Added Symboltable infrastructure into main parser. - -2003-05-05 Andrew Niefer - Structural changes to ParserSymbolTable: - - moved TypeInfo & Declaration inside ParserSymbolTable - - removed the stack & push/pop/peek - - moved nonstatic add/lookup fuctions from the table to Declaration - - began undo framework: added AddDeclarationCommand - -2003-05-01 Andrew Niefer - Fixed Bug 36287 - Parser failure with new CDT 1.1 parser - Fixed Bug 37011 - Scanner: #define A "//" not properly handled - -2003-04-30 John Camelon - Added some Javadoc to IParser.java and Parser.java. - -2003-04-28 John Camelon - Fixed Bug 37019 - RTS: Parser fails on variable defn using constructor - Fixed Bug 36767 - STL Testing: Parser is confused and goes into template function body - -2003-04-28 John Camelon - Partial fix for Bug37002 - Order of Offsetables is wrong - -2003-04-27 John Camelon - Partial fix for Bug 36932 - RTS: Parser fails on "new" in ctor initializer - Fixed Bug 36704 - Problem parsing Loki's Reference Typelist.h - Fixed Bug 36699 - Problem parsing Loki's Reference SmartPtr.h Impl - Fixed Bug 36691 - Problem parsing Loki's Reference HierarchyGenerators.h Impl - -2003-04-25 Andrew Niefer - Fixed bug36771 - Outline view shows include with no name - Fixed bug36714 - Parser fails on initial assignment using floating-suffix - Revisted bug36816 - Incomplete #include stops outline view - -2003-04-25 John Camelon - Fixed bug36852 - outline window doesn't show all functions - Fixed bug36764 - Bit fields cause parse errors - Fixed bug36702 - Parser error when having function pointers as parameters - -2003-04-24 John Camelon - Fixed Bug36799 STL Testing: Parser fails on Variable Definition - -2003-04-24 John Camelon - Fixed bug36693 - Problem parsing Loki's Reference SmallObj.cpp Impl - Fixed bug36696 - Problem parsing Loki's Reference SmartPtr.h Impl - Improved our error handling robustness. - Fixed bug36713 - Parser fails on definitions of pointers to functions - Fixed Dave's performance test parse failure. - Fixed bug36811 - The using directive causes parser to fail - Fixed bug36794 - ClassCastException for A template with no parameters - -2003-04-24 Andrew Niefer - Fixed Bug36816 Scanner infinite loop on incomplete #include - Fixed Bug36255 Parser hangs/goes infinite - -2003-04-21 John Camelon - Revisited bug36247 Parser confused by symbols #defined elsewhere - Fixed Bug36708 Problem parsing Loki's Reference TypeTraits.h - Fixed Bug36690 Problem parsing Loki's Reference Functor.h Implementation - Fixed Bug36692 Problem parsing Loki's Reference Singleton.h Impl - Fixed Bug36703 Problem parsing Loki's Reference TypeInfo.h Impl - Fixed Bug36689 Problem parsing Loki's Reference AbstractFactory.h Implementation - Fixed Bug36707 Problem parsing Loki's Reference TypeManip.h - -2003-04-21 Andrew Niefer - Fixed Bug36475 - Scanner does not concatenate strings - Fixed Bug36509 - Scanner turns strings into identifiers when expanding macros - Fixed Bug36521 - Scanner gets confused over commas in function like macros - Fixed Bug36695 - Scanner looses escaping on chars (ie '\4' to '4') - -2003-04-20 John Camelon - Fixed Bug36551 Bad parse on attached file. - Partial Fix for Bug36631 remove linear search algorithm from OffsetMapping - Some debunking of line numbers. - -2003-04-17 John Camelon - Fixed error in Elaborated Enumeration Types. - Fixed Bug36559 - Parsing Templates... - Fixed Bug36634 - Enum start line error - -2003-04-16 John Camelon - Fixed Bug36532 - Hang on partial template definition. - Fixed Bug36432 - Trying to open attached source code hangs Eclipse. - Fixed Bug36594 - Parser Stack Overflow on unaryExpression - Fixed Bug36600 - Elaborated Enumerated Types Parse Incorrectly. - -2003-04-15 John Camelon - Fixed bug36434 - Broken outline in winbase.h - Partial Fix for bug36379 - The parser to set Line informations when scanning. - Fixed CModelManager to include header files with .H extension as C++ headers. - Fixed bug36448 - Parser fails for C programs containing C++ keywords as identifiers - -2003-04-15 Andrew Niefer - Added scanner support to fix Bug36047 - -2003-04-13 John Camelon - Minor cleanup of callbacks due to removal of NewModelBuilder. - Added parser support to partially fix bug36416 & bug36294. Also added minimal C-Model support for these fixes. - -2003-04-11 John Camelon - Minimized the number of objects being returned from Parser callbacks. - Fixed CModelBuilder to handle errors better. - Reorganized the DOM Hierarchy to ensure that nodes were added to the tree on End() callbacks. - Fixed defect 36247(). - -2003-04-11 John Camelon - Fixed Bug 36243 DomBuilder Offsetable List - -2003-04-10 John Camelon - Fixed Bug36237 Parser fails on casts in ctor initializer. - Added AccessSpecifier to TemplateDeclaration. - -2003-04-10 John Camelon - Updated callbacks and parser to add offset information to template declarations, - thus making TemplateDeclaration implement IOffsetable. - -2003-04-09 John Camelon - Removed all the old Code Model Builder source that was no longer being used (NewModelBuilder.java, etc.). - Moved all the files in parser.util directory to the dom. - Organized imports. - Fixed bug36250 Parser ignores functions with default parameters that have no name. - Fixed bug36240 Parser incorrectly parses operator= - Fixed bug36254 Parser doesn't recognize unsigned as a type by itself. - -2003-04-09 John Camelon - Added timing printout for CModelTests. - Provided partial fix for bug36255 to get past infinite loop, will leave defect open. - Fixed bug36045 (Again). - Fixed bug36287. - -2003-04-06 Andrew Niefer - Added ParserSymbolTable::Cost and used it to fix up the conversion sequence ranking - -2003-04-06 John Camelon - Fixed defect 36073. - Fixed error handling for unterminated strings in Scanner. - Significantly updated callback structure to better suite the nature of the Code Model. - Updated all callbacks and parser to accommodate altered callbacks. - -2003-04-04 John Camelon - Fixed defect 35939. Proper CElement::pos() is set on Simple Declarations, - Class Specifications, Namespaces, Enumerations and Enumerators, Macros and Inclusions. - -2003-04-03 John Camelon - Fixed defects 36019, 36020, 36045. - Finished template declarations and their callbacks for the DOM (not the Code Model). - -2003-04-01 John Camelon - Updated Scanner to convert control-characters to ' '. - Fixed logic error in SimpleDeclarationWrapper. - Added operator support to grammar. - Fixed Name.toString() to support non-qualified yet multi-part names. - -2003-04-01 Andrew Niefer - Parser Symbol Table, modified lookup with respect to resolving ambiguous names, - reducing the number of temporary lists/sets. Modified adding using declarations - to properly support overloaded functions. Added initial support for user defined - conversion sequences when resolving overloaded functions. - -2003-04-01 John Camelon - Fixed bug35906 - Udated Scanner to not puke on certain control characters. - -2003-03-31 John Camelon - Fixed unsigned short SimpleDeclarations not showing up in the outline view. - Fixed default visibilities for structs in outline view. - Fixed bug35892. - Added icon-less typedefs and enums to the outline view. - Fixed NPEs relating to anonymous structs, unions, enums in outline view. - -2003-03-31 Andrew Niefer - Parser Symbol Table, better support for function resolution with pointers and - references as parameters. Also support for typedefs as function parameters - -2003-03-31 John Camelon - Updated NewModelBuilder to work for ElaboratedTypeSpecifiers, PointerOperators, Const Methods. - Fixed bug35878. - -2003-03-31 John Camelon - Updated Scanner to work for Strings literals like L"this string" - Updated Scanner to work for floating points literals. - Updated Scanner to be more forgiving on errors in QuickScan mode. - Got template instantiation and specialization working (w/callbacks and DOM). - Updated Parser/Callbacks for handle pure virtual function declarations. - Added callback support for some template declarations (not all branches). - -2003-03-28 John Camelon - Added AccessSpecifier and ClassKind to parser.util package and refactored callbacks. - Better encapsulated ExceptionSpecification in the DOM. - Updated DOM structures to return unmodifiable collections. - Added callback support for asmdefinitions. - Added callback support for constructor initializer chains. - Fixed bug 35781 and updated parser to catch all exceptions from callbacks to ensure best-effort parsing. - Removed Main.java from Parser package. - -2003-03-26 Andrew Niefer - Moved type information and ParameterInfo from Declaration into util.TypeInfo - Initial implementation of standard conversion sequences for function resolution - -2003-03-24 John Camelon - Added callback support for namespace definitions. - Updated Parser exception hierarchy. - Added callback support for linkage specifications. - Added callback support for using declarations and directives. - -2003-03-23 John Camelon - Added callback support for class member visibility. - Added callback support for pointer and reference operators on declarators. - Added callback support for throws clauses an const operations. - Added callback support for array declarators. - -2003-03-20 Andrew Niefer - Parser Symbol Table updates for: - * friends - * "this" pointer - * enumerators - * Argument dependent lookup - * adding parameters to functions & function overloading - -2003-03-19 John Camelon - Updated Parser method visibility to solidify external interface. - Solved and removed TODO's from Scanner implementation. - Updated Parser and callbacks to handle basic expressions. - -2003-03-18 John Camelon - Updated IParserCallback (and implementations) to add a typeName to DeclSpecifier. - Updated IParserCallback and NewModelBuilder to distinguish between Function declarations and definitions. - -2003-03-17 Doug Schaefer - Changed EOF to be a Backtrack exception instead of a token so simplify - error handling. - -2003-03-13 John Camelon - Moved ## token to IScanner from Scanner. - Updated IParserCallback and implementations to deal with Elaborated Type Specifiers. - Moved IScope into the internal DOM package. - -2003-03-11 John Camelon - added ChangeLog to parser directory - updated IParserCallback (and all implementors) for expressions - removed inheritance relationship between ExpressionEvaluator and NullParserCallback - removed redundant assignmentOperator() calls in Parser::initDeclarator - removed class util.DeclarationSpecifier, merged Container interface into util.DeclSpecifier - organized imports on the parser folder - * dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java - * dom/org/eclipse/cdt/internal/core/dom/Declarator.java - * dom/org/eclipse/cdt/internal/core/dom/ParameterDeclaration.java - * dom/org/eclipse/cdt/internal/core/dom/SimpleDeclaration.java - * parser/org/eclipse/cdt/internal/core/model/NewModelBuilder.java - * parser/org/eclipse/cdt/internal/core/model/Parameter.java - * parser/org/eclipse/cdt/internal/core/model/SimpleDeclarationWrapper.java - * parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java - * parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java - * parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java - * parser/org/eclipse/cdt/internal/core/parser/Parser.java - * parser/org/eclipse/cdt/internal/core/parser/util/DeclSpecifier.java - -2003-03-10 John Camelon - added in support for detecting and reporting circular inclusions - added optimization by caching inclusion directories - added macro pasting capabilities - updated inclusion searching algorithm for local inclusions - -2003-03-07 John Camelon - fixed initDeclarators for the outline view. - -2003-03-06 Doug Schaefer - Some minor fixes to get constructors/destructors parsing as well as some minor clean up and robustness. - -2003-03-06 John Camelon - added quickParse heuristic to Scanner for handling #if conditionals to avoid throwing - ScannerExceptions on undefined preprocessor symbols - added minimal enum support to Parser (though not to DOM or CModel) - -2003-03-06 Andrew Niefer - Implementation of Namespaces & using directives in new parser's symbol table - -2003-03-05 Doug Schaefer - Some minor fixes to the parser. - -2003-03-04 Doug Schaefer - Added Parser in the "parser" source folder in cdt.core - Preference in the C/C++ preference page to enable/disable use of the new parser (disabled by default) - Start on the DOM which we are using to test the parser (source folder "dom") - Start on a new Model Builder for creating CElements using the new parser (currently in source folder "parser") diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index 4ab6a36e46a..0dbf4030bbb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -28,14 +28,25 @@ public abstract class ASTNode implements IASTNode { return length; } - public void setOffset(int offset) { + public void setOffset( int offset ) + { this.offset = offset; } - - public void setLength(int length) { + + public void setLength( int length ) + { this.length = length; } - + + public void setOffsetAndLength(int offset, int length) { + this.offset = offset; + } + + public void setOffsetAndLength( ASTNode node ) + { + setOffsetAndLength( node.getOffset(), node.getLength() ); + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTNode#getNodeLocations() */ 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 53acee0df6e..98faa0859b8 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 @@ -67,1737 +67,1786 @@ import org.eclipse.cdt.core.parser.ParserMode; */ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { - protected final IParserLogService log; + protected final IParserLogService log; + protected final IScanner scanner; + protected final ParserMode mode; + protected final boolean supportStatementsInExpressions; + protected final boolean supportTypeOfUnaries; + protected final boolean supportAlignOfUnaries; - protected final IScanner scanner; + protected AbstractGNUSourceCodeParser(IScanner scanner, + IParserLogService logService, ParserMode parserMode, + boolean supportStatementsInExpressions, boolean supportTypeOfUnaries, + boolean supportAlignOfUnaries) { + this.scanner = scanner; + this.log = logService; + this.mode = parserMode; + this.supportStatementsInExpressions = supportStatementsInExpressions; + this.supportTypeOfUnaries = supportTypeOfUnaries; + this.supportAlignOfUnaries = supportAlignOfUnaries; + } - protected final ParserMode mode; + protected boolean parsePassed = true; + protected BacktrackException backtrack = new BacktrackException(); - protected final boolean supportStatementsInExpressions; + protected int backtrackCount = 0; - protected final boolean supportTypeOfUnaries; + protected final void throwBacktrack(int offset, int length) + throws BacktrackException { + ++backtrackCount; + backtrack.initialize(offset, (length < 0) ? 0 : length); + throw backtrack; + } - protected final boolean supportAlignOfUnaries; + protected IToken currToken; + protected IToken lastToken; + protected IToken prevLastToken; - protected AbstractGNUSourceCodeParser(IScanner scanner, - IParserLogService logService, ParserMode parserMode, - boolean supportStatementsInExpressions, boolean supportTypeOfUnaries, - boolean supportAlignOfUnaries) { - this.scanner = scanner; - this.log = logService; - this.mode = parserMode; - this.supportStatementsInExpressions = supportStatementsInExpressions; - this.supportTypeOfUnaries = supportTypeOfUnaries; - this.supportAlignOfUnaries = supportAlignOfUnaries; - } + /** + * Look Ahead in the token list to see what is coming. + * + * @param i + * How far ahead do you wish to peek? + * @return the token you wish to observe + * @throws EndOfFileException + * if looking ahead encounters EOF, throw EndOfFile + */ + protected IToken LA(int i) throws EndOfFileException { - protected boolean parsePassed = true; + if (isCancelled) { + throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED); + } - protected BacktrackException backtrack = new BacktrackException(); + if (i < 1) // can't go backwards + return null; + if (currToken == null) + currToken = fetchToken(); + IToken retToken = currToken; + for (; i > 1; --i) { + retToken = retToken.getNext(); + if (retToken == null) + retToken = fetchToken(); + } + return retToken; + } - protected int backtrackCount = 0; + /** + * Look ahead in the token list and return the token type. + * + * @param i + * How far ahead do you wish to peek? + * @return The type of that token + * @throws EndOfFileException + * if looking ahead encounters EOF, throw EndOfFile + */ + protected int LT(int i) throws EndOfFileException { + return LA(i).getType(); + } - protected final void throwBacktrack(int offset, int length ) throws BacktrackException { - ++backtrackCount; - backtrack.initialize(offset, ( length < 0 ) ? 0 : length ); - throw backtrack; - } + protected int calculateEndOffset( IASTNode n ) + { + ASTNode node = (ASTNode) n; + return node.getOffset() + node.getLength(); + } + + /** + * Consume the next token available, regardless of the type. + * + * @return The token that was consumed and removed from our buffer. + * @throws EndOfFileException + * If there is no token to consume. + */ + protected IToken consume() throws EndOfFileException { - protected IToken currToken; + if (currToken == null) + currToken = fetchToken(); + if (currToken != null) { + prevLastToken = lastToken; + lastToken = currToken; + } + currToken = currToken.getNext(); + return lastToken; + } - protected IToken lastToken; + /** + * Consume the next token available only if the type is as specified. + * + * @param type + * The type of token that you are expecting. + * @return the token that was consumed and removed from our buffer. + * @throws BacktrackException + * If LT(1) != type + */ + protected IToken consume(int type) throws EndOfFileException, + BacktrackException { + if (LT(1) == type) + return consume(); + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getLength()); + return null; + } - /** - * Look Ahead in the token list to see what is coming. - * - * @param i - * How far ahead do you wish to peek? - * @return the token you wish to observe - * @throws EndOfFileException - * if looking ahead encounters EOF, throw EndOfFile - */ - protected IToken LA(int i) throws EndOfFileException { + /** + * Fetches a token from the scanner. + * + * @return the next token from the scanner + * @throws EndOfFileException + * thrown when the scanner.nextToken() yields no tokens + */ + protected IToken fetchToken() throws EndOfFileException { + try { + IToken value = scanner.nextToken(); + return value; + } catch (OffsetLimitReachedException olre) { + handleOffsetLimitException(olre); + return null; + } + } - if (isCancelled) { - throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED); - } + protected boolean isCancelled = false; - if (i < 1) // can't go backwards - return null; - if (currToken == null) - currToken = fetchToken(); - IToken retToken = currToken; - for (; i > 1; --i) { - retToken = retToken.getNext(); - if (retToken == null) - retToken = fetchToken(); - } - return retToken; - } + protected static final int DEFAULT_DESIGNATOR_LIST_SIZE = 4; - /** - * Look ahead in the token list and return the token type. - * - * @param i - * How far ahead do you wish to peek? - * @return The type of that token - * @throws EndOfFileException - * if looking ahead encounters EOF, throw EndOfFile - */ - protected int LT(int i) throws EndOfFileException { - return LA(i).getType(); - } + protected static int parseCount = 0; - /** - * Consume the next token available, regardless of the type. - * - * @return The token that was consumed and removed from our buffer. - * @throws EndOfFileException - * If there is no token to consume. - */ - protected IToken consume() throws EndOfFileException { + protected void handleOffsetLimitException( + OffsetLimitReachedException exception) throws EndOfFileException { + if (mode != ParserMode.COMPLETION_PARSE) + throw new EndOfFileException(); + throw exception; + } - if (currToken == null) - currToken = fetchToken(); - if (currToken != null) - lastToken = currToken; - currToken = currToken.getNext(); - return lastToken; - } + protected static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$ - /** - * Consume the next token available only if the type is as specified. - * - * @param type - * The type of token that you are expecting. - * @return the token that was consumed and removed from our buffer. - * @throws BacktrackException - * If LT(1) != type - */ - protected IToken consume(int type) throws EndOfFileException, - BacktrackException { - if (LT(1) == type) - return consume(); - IToken la = LA(1); - throwBacktrack(la.getOffset(), la.getLength()); - return null; - } + /** + * Mark our place in the buffer so that we could return to it should we have + * to. + * + * @return The current token. + * @throws EndOfFileException + * If there are no more tokens. + */ + protected IToken mark() throws EndOfFileException { + if (currToken == null) + currToken = fetchToken(); + return currToken; + } - /** - * Fetches a token from the scanner. - * - * @return the next token from the scanner - * @throws EndOfFileException - * thrown when the scanner.nextToken() yields no tokens - */ - protected IToken fetchToken() throws EndOfFileException { - try { - IToken value = scanner.nextToken(); - return value; - } catch (OffsetLimitReachedException olre) { - handleOffsetLimitException(olre); - return null; - } - } + /** + * Rollback to a previous point, reseting the queue of tokens. + * + * @param mark + * The point that we wish to restore to. + * + */ + protected void backup(IToken mark) { + currToken = mark; + lastToken = prevLastToken; + } - protected boolean isCancelled = false; + /** + * This is the single entry point for setting parsePassed to false, and also + * making note what token offset we failed upon. + * + * @throws EndOfFileException + */ + protected void failParse() { + parsePassed = false; + } - protected static final int DEFAULT_DESIGNATOR_LIST_SIZE = 4; + /** + * /* (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IParser#cancel() + */ + public synchronized void cancel() { + isCancelled = true; + scanner.cancel(); + } - protected static int parseCount = 0; + /** + * Parse an identifier. + * + * @throws BacktrackException + * request a backtrack + */ + protected IToken identifier() throws EndOfFileException, BacktrackException { + return consume(IToken.tIDENTIFIER); + } - protected void handleOffsetLimitException( - OffsetLimitReachedException exception) throws EndOfFileException { - if (mode != ParserMode.COMPLETION_PARSE) - throw new EndOfFileException(); - throw exception; - } + /** + * @return Returns the backtrackCount. + */ + public final int getBacktrackCount() { + return backtrackCount; + } - protected static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$ + /** + * @param bt + */ + protected void throwBacktrack(BacktrackException bt) + throws BacktrackException { + throw bt; + } - /** - * Mark our place in the buffer so that we could return to it should we have - * to. - * - * @return The current token. - * @throws EndOfFileException - * If there are no more tokens. - */ - protected IToken mark() throws EndOfFileException { - if (currToken == null) - currToken = fetchToken(); - return currToken; - } + protected IASTProblem failParse(BacktrackException bt) { + IASTProblem result = null; - /** - * Rollback to a previous point, reseting the queue of tokens. - * - * @param mark - * The point that we wish to restore to. - * - */ - protected void backup(IToken mark) { - currToken = mark; - lastToken = null; // this is not entirely right ... - } + if (bt.getProblem() == null) + result = createProblem(IASTProblem.SYNTAX_ERROR, bt.getOffset(), bt + .getLength()); + else + result = bt.getProblem(); - /** - * This is the single entry point for setting parsePassed to false, and also - * making note what token offset we failed upon. - * - * @throws EndOfFileException - */ - protected void failParse() { - parsePassed = false; - } + failParse(); + return result; + } - /** - * /* (non-Javadoc) - * - * @see org.eclipse.cdt.core.parser.IParser#cancel() - */ - public synchronized void cancel() { - isCancelled = true; - scanner.cancel(); - } + /** + * @param syntax_error + * @param offset + * @param length + * @return + */ + protected abstract IASTProblem createProblem(int signal, int offset, + int length); - /** - * Parse an identifier. - * - * @throws BacktrackException - * request a backtrack - */ - protected IToken identifier() throws EndOfFileException, BacktrackException { - return consume(IToken.tIDENTIFIER); - } + /** + * @param string + * @param e + */ + protected void logThrowable(String methodName, Throwable e) { + if (e != null && log.isTracing()) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Parser: Unexpected throwable in "); //$NON-NLS-1$ + buffer.append(methodName); + buffer.append(":"); //$NON-NLS-1$ + buffer.append(e.getClass().getName()); + buffer.append("::"); //$NON-NLS-1$ + buffer.append(e.getMessage()); + buffer.append(". w/"); //$NON-NLS-1$ + buffer.append(scanner.toString()); + log.traceLog(buffer.toString()); + // log.errorLog( buffer.toString() ); + } + } - /** - * @return Returns the backtrackCount. - */ - public final int getBacktrackCount() { - return backtrackCount; - } + public String toString() { + return scanner.toString(); //$NON-NLS-1$ + } - /** - * @param bt - */ - protected void throwBacktrack(BacktrackException bt) - throws BacktrackException { - throw bt; - } + /** + * @param methodName + * @param e + */ + protected void logException(String methodName, Exception e) { + if (!(e instanceof EndOfFileException) && e != null && log.isTracing()) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Parser: Unexpected exception in "); //$NON-NLS-1$ + buffer.append(methodName); + buffer.append(":"); //$NON-NLS-1$ + buffer.append(e.getClass().getName()); + buffer.append("::"); //$NON-NLS-1$ + buffer.append(e.getMessage()); + buffer.append(". w/"); //$NON-NLS-1$ + buffer.append(scanner.toString()); + log.traceLog(buffer.toString()); + // log.errorLog(buffer.toString()); + } + } - protected IASTProblem failParse(BacktrackException bt) { - IASTProblem result = null; - - if (bt.getProblem() == null) - result = createProblem( IASTProblem.SYNTAX_ERROR, bt.getOffset(), bt.getLength() ); - else - result = bt.getProblem(); - - failParse(); - return result; - } + protected final void throwBacktrack(IASTProblem problem) + throws BacktrackException { + ++backtrackCount; + backtrack.initialize(problem); + throw backtrack; + } - /** - * @param syntax_error - * @param offset - * @param length - * @return - */ - protected abstract IASTProblem createProblem(int signal, int offset, int length); - /** - * @param string - * @param e - */ - protected void logThrowable(String methodName, Throwable e) { - if (e != null && log.isTracing()) { - StringBuffer buffer = new StringBuffer(); - buffer.append("Parser: Unexpected throwable in "); //$NON-NLS-1$ - buffer.append(methodName); - buffer.append(":"); //$NON-NLS-1$ - buffer.append(e.getClass().getName()); - buffer.append("::"); //$NON-NLS-1$ - buffer.append(e.getMessage()); - buffer.append(". w/"); //$NON-NLS-1$ - buffer.append(scanner.toString()); - log.traceLog(buffer.toString()); - // log.errorLog( buffer.toString() ); - } - } + protected IToken simpleDeclarationMark; - public String toString() { - return scanner.toString(); //$NON-NLS-1$ - } + private static final int DEFAULT_COMPOUNDSTATEMENT_LIST_SIZE = 8; - /** - * @param methodName - * @param e - */ - protected void logException(String methodName, Exception e) { - if (!(e instanceof EndOfFileException) && e != null && log.isTracing()) { - StringBuffer buffer = new StringBuffer(); - buffer.append("Parser: Unexpected exception in "); //$NON-NLS-1$ - buffer.append(methodName); - buffer.append(":"); //$NON-NLS-1$ - buffer.append(e.getClass().getName()); - buffer.append("::"); //$NON-NLS-1$ - buffer.append(e.getMessage()); - buffer.append(". w/"); //$NON-NLS-1$ - buffer.append(scanner.toString()); - log.traceLog(buffer.toString()); - // log.errorLog(buffer.toString()); - } - } + /** + * + */ + protected void cleanupLastToken() { + if (lastToken != null) + lastToken.setNext(null); + simpleDeclarationMark = null; + } - protected final void throwBacktrack(IASTProblem problem) - throws BacktrackException { - ++backtrackCount; - backtrack.initialize(problem); - throw backtrack; - } + public IASTTranslationUnit parse() { + long startTime = System.currentTimeMillis(); + translationUnit(); + // For the debuglog to take place, you have to call + // Util.setDebugging(true); + // Or set debug to true in the core plugin preference + log.traceLog("Parse " //$NON-NLS-1$ + + (++parseCount) + ": " //$NON-NLS-1$ + + (System.currentTimeMillis() - startTime) + "ms" //$NON-NLS-1$ + + (parsePassed ? "" : " - parse failure")); //$NON-NLS-1$ //$NON-NLS-2$ + IASTTranslationUnit result = getTranslationUnit(); + nullifyTranslationUnit(); + return result; + } - protected IToken simpleDeclarationMark; + /** + * + */ + protected abstract void nullifyTranslationUnit(); - private static final int DEFAULT_COMPOUNDSTATEMENT_LIST_SIZE = 8; - - /** - * - */ - protected void cleanupLastToken() { - if (lastToken != null) - lastToken.setNext(null); - simpleDeclarationMark = null; - } - - public IASTTranslationUnit parse() { - long startTime = System.currentTimeMillis(); - translationUnit(); - // For the debuglog to take place, you have to call - // Util.setDebugging(true); - // Or set debug to true in the core plugin preference - log.traceLog("Parse " //$NON-NLS-1$ - + (++parseCount) + ": " //$NON-NLS-1$ - + (System.currentTimeMillis() - startTime) + "ms" //$NON-NLS-1$ - + (parsePassed ? "" : " - parse failure")); //$NON-NLS-1$ //$NON-NLS-2$ - IASTTranslationUnit result = getTranslationUnit(); - nullifyTranslationUnit(); - return result; - } - - /** - * - */ - protected abstract void nullifyTranslationUnit(); - - protected void skipOverCompoundStatement() throws BacktrackException, - EndOfFileException { - // speed up the parser by skiping the body - // simply look for matching brace and return - consume(IToken.tLBRACE); - int depth = 1; - while (depth > 0) { - switch (consume().getType()) { + protected void skipOverCompoundStatement() throws BacktrackException, + EndOfFileException { + // speed up the parser by skiping the body + // simply look for matching brace and return + consume(IToken.tLBRACE); + int depth = 1; + while (depth > 0) { + switch (consume().getType()) { case IToken.tRBRACE: - --depth; - break; + --depth; + break; case IToken.tLBRACE: - ++depth; - break; - } - } - } + ++depth; + break; + } + } + } - /** - * @throws EndOfFileException - */ - protected void errorHandling() throws EndOfFileException { - int depth = (LT(1) == IToken.tLBRACE) ? 1 : 0; - int type = consume().getType(); - if (type == IToken.tSEMI) + /** + * @throws EndOfFileException + */ + protected void errorHandling() throws EndOfFileException { + int depth = (LT(1) == IToken.tLBRACE) ? 1 : 0; + int type = consume().getType(); + if (type == IToken.tSEMI) + return; + while (!((LT(1) == IToken.tSEMI && depth == 0) || (LT(1) == IToken.tRBRACE && depth == 1))) { + switch (LT(1)) { + case IToken.tLBRACE: + ++depth; + break; + case IToken.tRBRACE: + --depth; + break; + } + if (depth < 0) return; - while (!((LT(1) == IToken.tSEMI && depth == 0) || (LT(1) == IToken.tRBRACE && depth == 1))) { - switch (LT(1)) { - case IToken.tLBRACE: - ++depth; - break; - case IToken.tRBRACE: - --depth; - break; - } - if (depth < 0) - return; - consume(); - } - // eat the SEMI/RBRACE as well - consume(); - } + consume(); + } + // eat the SEMI/RBRACE as well + consume(); + } - /** - * This function is called whenever we encounter and error that we cannot - * backtrack out of and we still wish to try and continue on with the parse - * to do a best-effort parse for our client. - * - * @throws EndOfFileException - * We can potentially hit EndOfFile here as we are skipping - * ahead. - */ - protected void failParseWithErrorHandling() throws EndOfFileException { - failParse(); - errorHandling(); - } + /** + * This function is called whenever we encounter and error that we cannot + * backtrack out of and we still wish to try and continue on with the parse + * to do a best-effort parse for our client. + * + * @throws EndOfFileException + * We can potentially hit EndOfFile here as we are skipping ahead. + */ + protected void failParseWithErrorHandling() throws EndOfFileException { + failParse(); + errorHandling(); + } - /** - */ - protected void throwAwayMarksForInitializerClause() { - simpleDeclarationMark = null; - } + /** + */ + protected void throwAwayMarksForInitializerClause() { + simpleDeclarationMark = null; + } - /** - * @return TODO - * @throws BacktrackException - */ - protected IASTCompoundStatement compoundStatement() - throws EndOfFileException, BacktrackException { - int startingOffset = consume(IToken.tLBRACE).getOffset(); + /** + * @return TODO + * @throws BacktrackException + */ + protected IASTCompoundStatement compoundStatement() + throws EndOfFileException, BacktrackException { + int startingOffset = consume(IToken.tLBRACE).getOffset(); - List statements = Collections.EMPTY_LIST; - while (LT(1) != IToken.tRBRACE) { - int checkToken = LA(1).hashCode(); - try { - IASTStatement s = statement(); - if (statements == Collections.EMPTY_LIST) - statements = new ArrayList( - DEFAULT_COMPOUNDSTATEMENT_LIST_SIZE); - statements.add(s); - } catch (BacktrackException b) { - IASTProblem p = failParse(b); - IASTProblemStatement ps = createProblemStatement(); - ps.setProblem( p ); - ((ASTNode)ps).setOffset( ((ASTNode)p).getOffset() ); - p.setParent( ps ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - statements.add( ps ); - if (LA(1).hashCode() == checkToken) - failParseWithErrorHandling(); - } - } - consume(IToken.tRBRACE); + List statements = Collections.EMPTY_LIST; + while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + try { + IASTStatement s = statement(); + if (statements == Collections.EMPTY_LIST) + statements = new ArrayList(DEFAULT_COMPOUNDSTATEMENT_LIST_SIZE); + statements.add(s); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemStatement ps = createProblemStatement(); + ps.setProblem(p); + ((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(), + ((ASTNode) p).getLength()); + p.setParent(ps); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + statements.add(ps); + if (LA(1).hashCode() == checkToken) + failParseWithErrorHandling(); + } + } + int lastOffset = consume(IToken.tRBRACE).getEndOffset(); - IASTCompoundStatement result = createCompoundStatement(); - ((ASTNode)result).setOffset(startingOffset); - for (int i = 0; i < statements.size(); ++i) { - IASTStatement s = (IASTStatement) statements.get(i); - result.addStatement(s); - s.setParent(result); - s.setPropertyInParent(IASTCompoundStatement.NESTED_STATEMENT); - } - return result; - } + IASTCompoundStatement result = createCompoundStatement(); + ((ASTNode) result).setOffsetAndLength(startingOffset, lastOffset + - startingOffset); + for (int i = 0; i < statements.size(); ++i) { + IASTStatement s = (IASTStatement) statements.get(i); + result.addStatement(s); + s.setParent(result); + s.setPropertyInParent(IASTCompoundStatement.NESTED_STATEMENT); + } + return result; + } - /** - * @return - */ - protected abstract IASTProblemStatement createProblemStatement(); + /** + * @return + */ + protected abstract IASTProblemStatement createProblemStatement(); - /** - * @return - */ - protected abstract IASTCompoundStatement createCompoundStatement(); + /** + * @return + */ + protected abstract IASTCompoundStatement createCompoundStatement(); - /** - * @return @throws - * EndOfFileException - * @throws BacktrackException - */ - protected IASTExpression compoundStatementExpression() - throws EndOfFileException, BacktrackException { - int startingOffset =consume(IToken.tLPAREN).getOffset(); - IASTCompoundStatement compoundStatement = null; - if (mode == ParserMode.QUICK_PARSE - || mode == ParserMode.STRUCTURAL_PARSE) + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTExpression compoundStatementExpression() + throws EndOfFileException, BacktrackException { + int startingOffset = consume(IToken.tLPAREN).getOffset(); + IASTCompoundStatement compoundStatement = null; + if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) + skipOverCompoundStatement(); + else if (mode == ParserMode.COMPLETION_PARSE + || mode == ParserMode.SELECTION_PARSE) { + if (scanner.isOnTopContext()) + compoundStatement(); + else skipOverCompoundStatement(); - else if (mode == ParserMode.COMPLETION_PARSE - || mode == ParserMode.SELECTION_PARSE) { - if (scanner.isOnTopContext()) - compoundStatement(); - else - skipOverCompoundStatement(); - } else if (mode == ParserMode.COMPLETE_PARSE) - compoundStatement = compoundStatement(); + } else if (mode == ParserMode.COMPLETE_PARSE) + compoundStatement = compoundStatement(); - consume(IToken.tRPAREN); - IGNUASTCompoundStatementExpression resultExpression = createCompoundStatementExpression(); - ((ASTNode)resultExpression).setOffset( startingOffset ); - if( compoundStatement != null ) - { - resultExpression.setCompoundStatement(compoundStatement); - compoundStatement.setParent(resultExpression); - compoundStatement - .setPropertyInParent(IGNUASTCompoundStatementExpression.STATEMENT); - } + int lastOffset = consume(IToken.tRPAREN).getEndOffset(); + IGNUASTCompoundStatementExpression resultExpression = createCompoundStatementExpression(); + ((ASTNode) resultExpression).setOffsetAndLength(startingOffset, + lastOffset - startingOffset); + if (compoundStatement != null) { + resultExpression.setCompoundStatement(compoundStatement); + compoundStatement.setParent(resultExpression); + compoundStatement + .setPropertyInParent(IGNUASTCompoundStatementExpression.STATEMENT); + } - return resultExpression; - } + return resultExpression; + } - /** - * @return - */ - protected abstract IGNUASTCompoundStatementExpression createCompoundStatementExpression(); + /** + * @return + */ + protected abstract IGNUASTCompoundStatementExpression createCompoundStatementExpression(); - protected IASTExpression expression() throws BacktrackException, - EndOfFileException { - IToken la = LA(1); - int startingOffset = la.getOffset(); + protected IASTExpression expression() throws BacktrackException, + EndOfFileException { + IToken la = LA(1); + int startingOffset = la.getOffset(); - if (la.getType() == IToken.tLPAREN && LT(2) == IToken.tLBRACE - && supportStatementsInExpressions) { - IASTExpression resultExpression = compoundStatementExpression(); - if (resultExpression != null) - return resultExpression; - } + if (la.getType() == IToken.tLPAREN && LT(2) == IToken.tLBRACE + && supportStatementsInExpressions) { + IASTExpression resultExpression = compoundStatementExpression(); + if (resultExpression != null) + return resultExpression; + } + IASTExpression assignmentExpression = assignmentExpression(); + if (LT(1) != IToken.tCOMMA) + return assignmentExpression; - IASTExpression assignmentExpression = assignmentExpression(); - if( LT(1) != IToken.tCOMMA ) - return assignmentExpression; - - IASTExpressionList expressionList = createExpressionList(); - ((ASTNode)expressionList).setOffset( startingOffset ); - expressionList.addExpression( assignmentExpression ); - assignmentExpression.setParent( expressionList ); - assignmentExpression.setPropertyInParent( IASTExpressionList.NESTED_EXPRESSION ); - - while (LT(1) == IToken.tCOMMA) { - consume(IToken.tCOMMA); - IASTExpression secondExpression = assignmentExpression(); - expressionList.addExpression( secondExpression ); - secondExpression.setParent( expressionList ); - secondExpression.setPropertyInParent( IASTExpressionList.NESTED_EXPRESSION ); - } - return expressionList; - } + IASTExpressionList expressionList = createExpressionList(); + ((ASTNode) expressionList).setOffset(startingOffset); + expressionList.addExpression(assignmentExpression); + assignmentExpression.setParent(expressionList); + assignmentExpression + .setPropertyInParent(IASTExpressionList.NESTED_EXPRESSION); - /** - * @return - */ - protected abstract IASTExpressionList createExpressionList(); + int lastOffset = 0; + while (LT(1) == IToken.tCOMMA) { + consume(IToken.tCOMMA); + IASTExpression secondExpression = assignmentExpression(); + expressionList.addExpression(secondExpression); + secondExpression.setParent(expressionList); + secondExpression + .setPropertyInParent(IASTExpressionList.NESTED_EXPRESSION); + lastOffset = lastToken.getEndOffset(); + } + ((ASTNode) expressionList).setLength(lastOffset - startingOffset); + return expressionList; + } - protected abstract IASTExpression assignmentExpression() - throws BacktrackException, EndOfFileException; + /** + * @return + */ + protected abstract IASTExpressionList createExpressionList(); - protected abstract IASTExpression relationalExpression() - throws BacktrackException, EndOfFileException; + protected abstract IASTExpression assignmentExpression() + throws BacktrackException, EndOfFileException; - protected abstract IASTExpression multiplicativeExpression() - throws BacktrackException, EndOfFileException; + protected abstract IASTExpression relationalExpression() + throws BacktrackException, EndOfFileException; - protected abstract IASTTypeId typeId(boolean skipArrayMods) - throws BacktrackException, EndOfFileException; + protected abstract IASTExpression multiplicativeExpression() + throws BacktrackException, EndOfFileException; - protected abstract IASTExpression castExpression() - throws BacktrackException, EndOfFileException; + protected abstract IASTTypeId typeId(boolean skipArrayMods) + throws BacktrackException, EndOfFileException; - protected abstract IASTExpression unaryExpression() - throws BacktrackException, EndOfFileException; + protected abstract IASTExpression castExpression() + throws BacktrackException, EndOfFileException; - protected abstract IASTExpression buildTypeIdExpression(int op_sizeof, IASTTypeId typeId, int startingOffset); - - protected abstract void translationUnit(); + protected abstract IASTExpression unaryExpression() + throws BacktrackException, EndOfFileException; - protected abstract IASTTranslationUnit getTranslationUnit(); + protected abstract IASTExpression buildTypeIdExpression(int op, + IASTTypeId typeId, int startingOffset, int endingOffset); - protected IASTExpression assignmentOperatorExpression(int kind, - IASTExpression lhs) throws EndOfFileException, BacktrackException { - consume(); - IASTExpression rhs = assignmentExpression(); - return buildBinaryExpression(kind, lhs, rhs); - } + protected abstract void translationUnit(); - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression constantExpression() throws BacktrackException, - EndOfFileException { - return conditionalExpression(); - } + protected abstract IASTTranslationUnit getTranslationUnit(); - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression logicalOrExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = logicalAndExpression(); - while (LT(1) == IToken.tOR) { - consume(IToken.tOR); - IASTExpression secondExpression = logicalAndExpression(); - firstExpression = buildBinaryExpression( - IASTBinaryExpression.op_logicalOr, firstExpression, - secondExpression); - } - return firstExpression; - } + protected IASTExpression assignmentOperatorExpression(int kind, + IASTExpression lhs) throws EndOfFileException, BacktrackException { + consume(); + IASTExpression rhs = assignmentExpression(); + return buildBinaryExpression(kind, lhs, rhs, lastToken.getEndOffset()); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression logicalAndExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = inclusiveOrExpression(); - while (LT(1) == IToken.tAND) { - consume(IToken.tAND); - IASTExpression secondExpression = inclusiveOrExpression(); - firstExpression = buildBinaryExpression( - IASTBinaryExpression.op_logicalAnd, firstExpression, - secondExpression); - } - return firstExpression; - } + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression constantExpression() throws BacktrackException, + EndOfFileException { + return conditionalExpression(); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression inclusiveOrExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = exclusiveOrExpression(); - while (LT(1) == IToken.tBITOR) { - consume(IToken.tBITOR); - IASTExpression secondExpression = exclusiveOrExpression(); - firstExpression = buildBinaryExpression( - IASTBinaryExpression.op_binaryOr, firstExpression, - secondExpression); - } - return firstExpression; - } + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression logicalOrExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = logicalAndExpression(); + while (LT(1) == IToken.tOR) { + consume(IToken.tOR); + IASTExpression secondExpression = logicalAndExpression(); + firstExpression = buildBinaryExpression( + IASTBinaryExpression.op_logicalOr, firstExpression, + secondExpression, lastToken.getEndOffset()); + } + return firstExpression; + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression exclusiveOrExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = andExpression(); - while (LT(1) == IToken.tXOR) { - consume(IToken.tXOR); - IASTExpression secondExpression = andExpression(); - firstExpression = buildBinaryExpression( - IASTBinaryExpression.op_binaryXor, firstExpression, - secondExpression); - } - return firstExpression; - } + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression logicalAndExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = inclusiveOrExpression(); + while (LT(1) == IToken.tAND) { + consume(IToken.tAND); + IASTExpression secondExpression = inclusiveOrExpression(); + firstExpression = buildBinaryExpression( + IASTBinaryExpression.op_logicalAnd, firstExpression, + secondExpression, lastToken.getEndOffset()); + } + return firstExpression; + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression andExpression() throws EndOfFileException, - BacktrackException { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression inclusiveOrExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = exclusiveOrExpression(); + while (LT(1) == IToken.tBITOR) { + consume(IToken.tBITOR); + IASTExpression secondExpression = exclusiveOrExpression(); + firstExpression = buildBinaryExpression( + IASTBinaryExpression.op_binaryOr, firstExpression, + secondExpression, lastToken.getEndOffset()); + } + return firstExpression; + } - IASTExpression firstExpression = equalityExpression(); - while (LT(1) == IToken.tAMPER) { - consume(); - IASTExpression secondExpression = equalityExpression(); - firstExpression = buildBinaryExpression( - IASTBinaryExpression.op_binaryAnd, firstExpression, - secondExpression); - } - return firstExpression; - } + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression exclusiveOrExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = andExpression(); + while (LT(1) == IToken.tXOR) { + consume(IToken.tXOR); + IASTExpression secondExpression = andExpression(); + firstExpression = buildBinaryExpression( + IASTBinaryExpression.op_binaryXor, firstExpression, + secondExpression, lastToken.getEndOffset()); + } + return firstExpression; + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression equalityExpression() throws EndOfFileException, - BacktrackException { - IASTExpression firstExpression = relationalExpression(); - for (;;) { - switch (LT(1)) { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression andExpression() throws EndOfFileException, + BacktrackException { + + IASTExpression firstExpression = equalityExpression(); + while (LT(1) == IToken.tAMPER) { + consume(); + IASTExpression secondExpression = equalityExpression(); + firstExpression = buildBinaryExpression( + IASTBinaryExpression.op_binaryAnd, firstExpression, + secondExpression, lastToken.getEndOffset()); + } + return firstExpression; + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression equalityExpression() throws EndOfFileException, + BacktrackException { + IASTExpression firstExpression = relationalExpression(); + for (;;) { + switch (LT(1)) { case IToken.tEQUAL: case IToken.tNOTEQUAL: - IToken t = consume(); - int operator = ((t.getType() == IToken.tEQUAL) ? IASTBinaryExpression.op_equals - : IASTBinaryExpression.op_notequals); - IASTExpression secondExpression = relationalExpression(); - firstExpression = buildBinaryExpression(operator, - firstExpression, secondExpression); - break; + IToken t = consume(); + int operator = ((t.getType() == IToken.tEQUAL) ? IASTBinaryExpression.op_equals + : IASTBinaryExpression.op_notequals); + IASTExpression secondExpression = relationalExpression(); + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - protected IASTExpression buildBinaryExpression(int operator, - IASTExpression firstExpression, IASTExpression secondExpression) { - IASTBinaryExpression result = createBinaryExpression(); - result.setOperator(operator); - ((ASTNode)result).setOffset(((ASTNode)firstExpression).getOffset()); - result.setOperand1(firstExpression); - firstExpression.setParent(result); - firstExpression.setPropertyInParent(IASTBinaryExpression.OPERAND_ONE); - result.setOperand2(secondExpression); - secondExpression.setParent(result); - secondExpression.setPropertyInParent(IASTBinaryExpression.OPERAND_TWO); - return result; - } + protected IASTExpression buildBinaryExpression(int operator, + IASTExpression firstExpression, IASTExpression secondExpression, + int lastOffset) { + IASTBinaryExpression result = createBinaryExpression(); + result.setOperator(operator); + int o = ((ASTNode) firstExpression).getOffset(); + ((ASTNode) result).setOffsetAndLength(o, lastOffset - o); + result.setOperand1(firstExpression); + firstExpression.setParent(result); + firstExpression.setPropertyInParent(IASTBinaryExpression.OPERAND_ONE); + result.setOperand2(secondExpression); + secondExpression.setParent(result); + secondExpression.setPropertyInParent(IASTBinaryExpression.OPERAND_TWO); + return result; + } - /** - * @return - */ - protected abstract IASTBinaryExpression createBinaryExpression(); + /** + * @return + */ + protected abstract IASTBinaryExpression createBinaryExpression(); - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression shiftExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = additiveExpression(); - for (;;) { - switch (LT(1)) { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression shiftExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = additiveExpression(); + for (;;) { + switch (LT(1)) { case IToken.tSHIFTL: case IToken.tSHIFTR: - IToken t = consume(); - int operator = t.getType() == IToken.tSHIFTL ? IASTBinaryExpression.op_shiftLeft - : IASTBinaryExpression.op_shiftRight; - IASTExpression secondExpression = additiveExpression(); - firstExpression = buildBinaryExpression(operator, - firstExpression, secondExpression); - break; + IToken t = consume(); + int operator = t.getType() == IToken.tSHIFTL ? IASTBinaryExpression.op_shiftLeft + : IASTBinaryExpression.op_shiftRight; + IASTExpression secondExpression = additiveExpression(); + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression additiveExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = multiplicativeExpression(); - for (;;) { - switch (LT(1)) { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression additiveExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = multiplicativeExpression(); + for (;;) { + switch (LT(1)) { case IToken.tPLUS: case IToken.tMINUS: - IToken t = consume(); - int operator = (t.getType() == IToken.tPLUS) ? IASTBinaryExpression.op_plus - : IASTBinaryExpression.op_minus; - IASTExpression secondExpression = multiplicativeExpression(); - firstExpression = buildBinaryExpression(operator, - firstExpression, secondExpression); - break; + IToken t = consume(); + int operator = (t.getType() == IToken.tPLUS) ? IASTBinaryExpression.op_plus + : IASTBinaryExpression.op_minus; + IASTExpression secondExpression = multiplicativeExpression(); + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @param expression - * @return @throws - * BacktrackException - */ - protected IASTExpression conditionalExpression() throws BacktrackException, - EndOfFileException { - IASTExpression firstExpression = logicalOrExpression(); - if (LT(1) == IToken.tQUESTION) { - consume(IToken.tQUESTION); - IASTExpression secondExpression = expression(); - consume(IToken.tCOLON); - IASTExpression thirdExpression = assignmentExpression(); - IASTConditionalExpression result = createConditionalExpression(); - result.setLogicalConditionExpression(firstExpression); - firstExpression.setParent(result); - firstExpression - .setPropertyInParent(IASTConditionalExpression.LOGICAL_CONDITION); - result.setPositiveResultExpression(secondExpression); - secondExpression.setParent(result); - secondExpression - .setPropertyInParent(IASTConditionalExpression.POSITIVE_RESULT); - result.setNegativeResultExpression(thirdExpression); - thirdExpression.setParent(result); - thirdExpression - .setPropertyInParent(IASTConditionalExpression.NEGATIVE_RESULT); - return result; - } - return firstExpression; - } + /** + * @param expression + * @return @throws + * BacktrackException + */ + protected IASTExpression conditionalExpression() throws BacktrackException, + EndOfFileException { + IASTExpression firstExpression = logicalOrExpression(); + if (LT(1) == IToken.tQUESTION) { + consume(IToken.tQUESTION); + IASTExpression secondExpression = expression(); + consume(IToken.tCOLON); + IASTExpression thirdExpression = assignmentExpression(); + IASTConditionalExpression result = createConditionalExpression(); + result.setLogicalConditionExpression(firstExpression); + firstExpression.setParent(result); + firstExpression + .setPropertyInParent(IASTConditionalExpression.LOGICAL_CONDITION); + result.setPositiveResultExpression(secondExpression); + secondExpression.setParent(result); + secondExpression + .setPropertyInParent(IASTConditionalExpression.POSITIVE_RESULT); + result.setNegativeResultExpression(thirdExpression); + thirdExpression.setParent(result); + thirdExpression + .setPropertyInParent(IASTConditionalExpression.NEGATIVE_RESULT); + return result; + } + return firstExpression; + } - /** - * @return - */ - protected abstract IASTConditionalExpression createConditionalExpression(); + /** + * @return + */ + protected abstract IASTConditionalExpression createConditionalExpression(); - protected IASTExpression unaryOperatorCastExpression(int operator) - throws EndOfFileException, BacktrackException { - int offset = consume().getOffset(); - IASTExpression castExpression = castExpression(); - return buildUnaryExpression(operator, castExpression, offset); - } + protected IASTExpression unaryOperatorCastExpression(int operator) + throws EndOfFileException, BacktrackException { + int offset = consume().getOffset(); + IASTExpression castExpression = castExpression(); + return buildUnaryExpression(operator, castExpression, offset, lastToken + .getEndOffset()); + } - /** - * @param operator - * @param operand - * @param offset - * TODO - * @return - */ - protected IASTExpression buildUnaryExpression(int operator, - IASTExpression operand, int offset) { - IASTUnaryExpression result = createUnaryExpression(); - ((ASTNode)result).setOffset(offset); - result.setOperator(operator); - if( operand != null ) - { - result.setOperand(operand); - operand.setParent(result); - operand.setPropertyInParent(IASTUnaryExpression.OPERAND); - } - return result; - } + /** + * @param operator + * @param operand + * @param offset + * TODO + * @param lastOffset + * TODO + * @return + */ + protected IASTExpression buildUnaryExpression(int operator, + IASTExpression operand, int offset, int lastOffset) { + IASTUnaryExpression result = createUnaryExpression(); + ((ASTNode) result).setOffsetAndLength(offset, lastOffset - offset); + result.setOperator(operator); + if (operand != null) { + result.setOperand(operand); + operand.setParent(result); + operand.setPropertyInParent(IASTUnaryExpression.OPERAND); + } + return result; + } - /** - * @return - */ - protected abstract IASTUnaryExpression createUnaryExpression(); + /** + * @return + */ + protected abstract IASTUnaryExpression createUnaryExpression(); - /** - * @return @throws - * BacktrackException - * @throws EndOfFileException - */ - protected IASTExpression unaryAlignofExpression() - throws EndOfFileException, BacktrackException { - int offset = consume(IGCCToken.t___alignof__).getOffset(); - IASTTypeId d = null; - IASTExpression unaryExpression = null; + /** + * @return @throws + * BacktrackException + * @throws EndOfFileException + */ + protected IASTExpression unaryAlignofExpression() throws EndOfFileException, + BacktrackException { + int offset = consume(IGCCToken.t___alignof__).getOffset(); + IASTTypeId d = null; + IASTExpression unaryExpression = null; - IToken m = mark(); - if (LT(1) == IToken.tLPAREN) { + IToken m = mark(); + int lastOffset = 0; + if (LT(1) == IToken.tLPAREN) { + try { + consume(IToken.tLPAREN); + d = typeId(false); + lastOffset = consume(IToken.tRPAREN).getEndOffset(); + } catch (BacktrackException bt) { + backup(m); + d = null; + unaryExpression = unaryExpression(); + lastOffset = lastToken.getEndOffset(); + } + } else { + unaryExpression = unaryExpression(); + } + if (d != null & unaryExpression == null) + return buildTypeIdExpression(IGNUASTTypeIdExpression.op_alignof, d, + offset, lastOffset); + else if (unaryExpression != null && d == null) + return buildUnaryExpression(IGNUASTUnaryExpression.op_alignOf, + unaryExpression, offset, lastOffset); + return null; + } + + protected IASTExpression unaryTypeofExpression() throws EndOfFileException, + BacktrackException { + int offset = consume(IGCCToken.t_typeof).getOffset(); + IASTTypeId d = null; + IASTExpression unaryExpression = null; + + IToken m = mark(); + int lastOffset = 0; + if (LT(1) == IToken.tLPAREN) { + if (LT(2) == IToken.tLBRACE) { + unaryExpression = compoundStatementExpression(); + lastOffset = lastToken.getEndOffset(); + } else try { - consume(IToken.tLPAREN); - d = typeId(false); - consume(IToken.tRPAREN); + consume(IToken.tLPAREN); + d = typeId(false); + lastOffset = consume(IToken.tRPAREN).getEndOffset(); } catch (BacktrackException bt) { - backup(m); - d = null; - unaryExpression = unaryExpression(); + backup(m); + d = null; + unaryExpression = unaryExpression(); + lastOffset = lastToken.getEndOffset(); } - } else { - unaryExpression = unaryExpression(); - } - if (d != null & unaryExpression == null) - return buildTypeIdExpression( IGNUASTTypeIdExpression.op_alignof, d, offset ); - else if (unaryExpression != null && d == null) - return buildUnaryExpression( IGNUASTUnaryExpression.op_alignOf, unaryExpression, offset ); - return null; - } + } else { + unaryExpression = unaryExpression(); + } + if (d != null & unaryExpression == null) + return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d, + offset, lastOffset); + else if (unaryExpression != null && d == null) + return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, + unaryExpression, offset, lastOffset); + return null; + } - protected IASTExpression unaryTypeofExpression() throws EndOfFileException, - BacktrackException { - int offset = consume(IGCCToken.t_typeof).getOffset(); - IASTTypeId d = null; - IASTExpression unaryExpression = null; - - IToken m = mark(); - if (LT(1) == IToken.tLPAREN) { - if( LT(2) == IToken.tLBRACE ) - { - unaryExpression = compoundStatementExpression(); - } - else - try { - consume(IToken.tLPAREN); - d = typeId(false); - consume(IToken.tRPAREN); - } catch (BacktrackException bt) { - backup(m); - d = null; - unaryExpression = unaryExpression(); - } - } else { - unaryExpression = unaryExpression(); - } - if (d != null & unaryExpression == null) - return buildTypeIdExpression( IGNUASTTypeIdExpression.op_typeof, d, offset ); - else if (unaryExpression != null && d == null) - return buildUnaryExpression( IGNUASTUnaryExpression.op_typeof, unaryExpression, offset ); - return null; - } - - protected IASTStatement handleFunctionBody() throws BacktrackException, - EndOfFileException { - if (mode == ParserMode.QUICK_PARSE - || mode == ParserMode.STRUCTURAL_PARSE) { - skipOverCompoundStatement(); - return null; - } else if (mode == ParserMode.COMPLETION_PARSE - || mode == ParserMode.SELECTION_PARSE) { - if (scanner.isOnTopContext()) - return functionBody(); - skipOverCompoundStatement(); - return null; - } else if (mode == ParserMode.COMPLETE_PARSE) + protected IASTStatement handleFunctionBody() throws BacktrackException, + EndOfFileException { + if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) { + skipOverCompoundStatement(); + return null; + } else if (mode == ParserMode.COMPLETION_PARSE + || mode == ParserMode.SELECTION_PARSE) { + if (scanner.isOnTopContext()) return functionBody(); - return null; - } + skipOverCompoundStatement(); + return null; + } else if (mode == ParserMode.COMPLETE_PARSE) + return functionBody(); + return null; + } - /** - * Parses a function body. - * - * @return TODO - * - * @throws BacktrackException - * request a backtrack - */ - protected IASTStatement functionBody() throws EndOfFileException, - BacktrackException { - return compoundStatement(); - } + /** + * Parses a function body. + * + * @return TODO + * + * @throws BacktrackException + * request a backtrack + */ + protected IASTStatement functionBody() throws EndOfFileException, + BacktrackException { + return compoundStatement(); + } - /** - * @param flags - * input flags that are used to make our decision - * @return whether or not this looks like a a declarator follows - * @throws EndOfFileException - * we could encounter EOF while looking ahead - */ - protected boolean lookAheadForDeclarator(Flags flags) - throws EndOfFileException { - return flags.haveEncounteredTypename() - && ((LT(2) != IToken.tIDENTIFIER || (LT(3) != IToken.tLPAREN && LT(3) != IToken.tASSIGN)) && !LA( - 2).isPointer()); - } + /** + * @param flags + * input flags that are used to make our decision + * @return whether or not this looks like a a declarator follows + * @throws EndOfFileException + * we could encounter EOF while looking ahead + */ + protected boolean lookAheadForDeclarator(Flags flags) + throws EndOfFileException { + return flags.haveEncounteredTypename() + && ((LT(2) != IToken.tIDENTIFIER || (LT(3) != IToken.tLPAREN && LT(3) != IToken.tASSIGN)) && !LA( + 2).isPointer()); + } - public static class Flags { - private boolean encounteredTypename = false; + public static class Flags { + private boolean encounteredTypename = false; - // have we encountered a typeName yet? - private boolean encounteredRawType = false; + // have we encountered a typeName yet? + private boolean encounteredRawType = false; - // have we encountered a raw type yet? - private final boolean parm; + // have we encountered a raw type yet? + private final boolean parm; - // is this for a simpleDeclaration or parameterDeclaration? - private final boolean constructor; + // is this for a simpleDeclaration or parameterDeclaration? + private final boolean constructor; - // are we attempting the constructor strategy? - public Flags(boolean parm, boolean c) { - this.parm = parm; - constructor = c; - } + // are we attempting the constructor strategy? + public Flags(boolean parm, boolean c) { + this.parm = parm; + constructor = c; + } - public Flags(boolean parm) { - this(parm, false); - } + public Flags(boolean parm) { + this(parm, false); + } - /** - * @return true if we have encountered a simple type up to this point, - * false otherwise - */ - public boolean haveEncounteredRawType() { - return encounteredRawType; - } + /** + * @return true if we have encountered a simple type up to this point, + * false otherwise + */ + public boolean haveEncounteredRawType() { + return encounteredRawType; + } - /** - * @return true if we have encountered a typename up to this point, - * false otherwise - */ - public boolean haveEncounteredTypename() { - return encounteredTypename; - } + /** + * @return true if we have encountered a typename up to this point, false + * otherwise + */ + public boolean haveEncounteredTypename() { + return encounteredTypename; + } - /** - * @param b - - * set to true if we encounter a raw type (int, short, etc.) - */ - public void setEncounteredRawType(boolean b) { - encounteredRawType = b; - } + /** + * @param b - + * set to true if we encounter a raw type (int, short, etc.) + */ + public void setEncounteredRawType(boolean b) { + encounteredRawType = b; + } - /** - * @param b - - * set to true if we encounter a typename - */ - public void setEncounteredTypename(boolean b) { - encounteredTypename = b; - } + /** + * @param b - + * set to true if we encounter a typename + */ + public void setEncounteredTypename(boolean b) { + encounteredTypename = b; + } - /** - * @return true if we are parsing for a ParameterDeclaration - */ - public boolean isForParameterDeclaration() { - return parm; - } + /** + * @return true if we are parsing for a ParameterDeclaration + */ + public boolean isForParameterDeclaration() { + return parm; + } - /** - * @return whether or not we are attempting the constructor strategy or - * not - */ - public boolean isForConstructor() { - return constructor; - } - } + /** + * @return whether or not we are attempting the constructor strategy or + * not + */ + public boolean isForConstructor() { + return constructor; + } + } - /** - * Parse an enumeration specifier, as according to the ANSI specs in C & - * C++. - * - * enumSpecifier: "enum" (name)? "{" (enumerator-list) "}" enumerator-list: - * enumerator-definition enumerator-list , enumerator-definition - * enumerator-definition: enumerator enumerator = constant-expression - * enumerator: identifier - * @param owner - * IParserCallback object that represents the declaration that - * owns this type specifier. - * - * @throws BacktrackException - * request a backtrack - */ - protected IASTEnumerationSpecifier enumSpecifier() - throws BacktrackException, EndOfFileException { - IToken mark = mark(); - IASTName name = null; - int startOffset = consume(IToken.t_enum).getOffset(); - if (LT(1) == IToken.tIDENTIFIER) { - name = createName( identifier() ); - } - else - name = createName(); - if (LT(1) == IToken.tLBRACE) { - - IASTEnumerationSpecifier result = createEnumerationSpecifier(); - ((ASTNode)result).setOffset( startOffset ); - result.setName( name ); - name.setParent( result ); - name.setPropertyInParent( IASTEnumerationSpecifier.ENUMERATION_NAME ); - cleanupLastToken(); - consume(IToken.tLBRACE); - while (LT(1) != IToken.tRBRACE) { - IASTName enumeratorName = null; - if (LT(1) == IToken.tIDENTIFIER) { - enumeratorName = createName( identifier() ); - } else { - IToken la = LA(1); - throwBacktrack(la.getOffset(), la.getLength()); - } - IASTExpression initialValue = null; - if (LT(1) == IToken.tASSIGN) { - consume(IToken.tASSIGN); - initialValue = constantExpression(); - } - IASTEnumerationSpecifier.IASTEnumerator enumerator = null; - if (LT(1) == IToken.tRBRACE) { - enumerator = createEnumerator(); - enumerator.setName( enumeratorName ); - ((ASTNode)enumerator).setOffset( ((ASTNode)enumeratorName).getOffset() ); - enumeratorName.setParent( enumerator ); - enumeratorName.setPropertyInParent( IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_NAME ); - if( initialValue != null ) - { - enumerator.setValue( initialValue ); - initialValue.setParent( enumerator ); - initialValue.setPropertyInParent( IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_VALUE ); - } - result.addEnumerator( enumerator ); - enumerator.setParent( result ); - enumerator.setPropertyInParent( IASTEnumerationSpecifier.ENUMERATOR ); - cleanupLastToken(); - break; - } - if (LT(1) != IToken.tCOMMA) { - throwBacktrack(mark.getOffset(), mark.getLength()); - } + /** + * Parse an enumeration specifier, as according to the ANSI specs in C & C++. + * + * enumSpecifier: "enum" (name)? "{" (enumerator-list) "}" enumerator-list: + * enumerator-definition enumerator-list , enumerator-definition + * enumerator-definition: enumerator enumerator = constant-expression + * enumerator: identifier + * + * @param owner + * IParserCallback object that represents the declaration that owns + * this type specifier. + * + * @throws BacktrackException + * request a backtrack + */ + protected IASTEnumerationSpecifier enumSpecifier() + throws BacktrackException, EndOfFileException { + IToken mark = mark(); + IASTName name = null; + int startOffset = consume(IToken.t_enum).getOffset(); + if (LT(1) == IToken.tIDENTIFIER) { + name = createName(identifier()); + } else + name = createName(); + if (LT(1) == IToken.tLBRACE) { - enumerator = createEnumerator(); - enumerator.setName( enumeratorName ); - ((ASTNode)enumerator).setOffset( ((ASTNode)enumeratorName).getOffset() ); - enumeratorName.setParent( enumerator ); - enumeratorName.setPropertyInParent( IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_NAME ); - if( initialValue != null ) - { - enumerator.setValue( initialValue ); - initialValue.setParent( enumerator ); - initialValue.setPropertyInParent( IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_VALUE ); - } - result.addEnumerator( enumerator ); - enumerator.setParent( result ); - enumerator.setPropertyInParent( IASTEnumerationSpecifier.ENUMERATOR ); - cleanupLastToken(); - - consume(IToken.tCOMMA); + IASTEnumerationSpecifier result = createEnumerationSpecifier(); + ((ASTNode) result).setOffset(startOffset); + result.setName(name); + name.setParent(result); + name.setPropertyInParent(IASTEnumerationSpecifier.ENUMERATION_NAME); + cleanupLastToken(); + consume(IToken.tLBRACE); + while (LT(1) != IToken.tRBRACE) { + IASTName enumeratorName = null; + if (LT(1) == IToken.tIDENTIFIER) { + enumeratorName = createName(identifier()); + } else { + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getLength()); } - consume(IToken.tRBRACE); - return result; - } - // enumSpecifierAbort - backup(mark); - throwBacktrack(mark.getOffset(), mark.getLength()); - return null; - } - - protected abstract IASTStatement statement() throws EndOfFileException, - BacktrackException; - - /** - * @return - */ - protected abstract IASTEnumerator createEnumerator(); - - /** - * @return - */ - protected abstract IASTEnumerationSpecifier createEnumerationSpecifier(); - - /** - * @return - */ - protected abstract IASTName createName(); - - /** - * @param token - * @return - */ - protected abstract IASTName createName(IToken token); - - - /** - * @throws BacktrackException - */ - protected IASTExpression condition() throws BacktrackException, EndOfFileException { - IASTExpression cond = expression(); - cleanupLastToken(); - return cond; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.ISourceCodeParser#encounteredError() - */ - public boolean encounteredError() { - return !parsePassed; - } - - - /** - * @return - */ - protected abstract IASTDeclarationStatement createDeclarationStatement(); - - /** - * @return - */ - protected abstract IASTExpressionStatement createExpressionStatement(); - - /** - * @return - */ - protected abstract IASTLabelStatement createLabelStatement(); - - /** - * @return - */ - protected abstract IASTNullStatement createNullStatement(); - - /** - * @return - */ - protected abstract IASTGotoStatement createGoToStatement(); - - /** - * @return - */ - protected abstract IASTReturnStatement createReturnStatement(); - - /** - * @return - */ - protected abstract IASTContinueStatement createContinueStatement(); - - /** - * @return - */ - protected abstract IASTBreakStatement createBreakStatement(); - - /** - * @return - */ - protected abstract IASTForStatement createForStatement(); - - /** - * @return - */ - protected abstract IASTDoStatement createDoStatement(); - - /** - * @return - */ - protected abstract IASTWhileStatement createWhileStatement(); - - /** - * @return - */ - protected abstract IASTSwitchStatement createSwitchStatement(); - - /** - * @return - */ - protected abstract IASTIfStatement createIfStatement(); - - /** - * @return - */ - protected abstract IASTDefaultStatement createDefaultStatement(); - - /** - * @return - */ - protected abstract IASTCaseStatement createCaseStatement(); - - protected abstract IASTDeclaration declaration() throws BacktrackException, EndOfFileException; - - - protected abstract IASTNode forInitStatement() throws BacktrackException, - EndOfFileException; - - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTDeclaration asmDeclaration() throws EndOfFileException, BacktrackException { - IToken first = consume(IToken.t_asm); - consume(IToken.tLPAREN); - String assembly = consume(IToken.tSTRING).getImage(); - consume(IToken.tRPAREN); - consume(IToken.tSEMI); - cleanupLastToken(); - return buildASMDirective( first.getOffset(), assembly ); - } - - /** - * @param offset - * @param assembly - * @return - */ - protected IASTASMDeclaration buildASMDirective(int offset, String assembly) { - IASTASMDeclaration result = createASMDirective(); - ((ASTNode)result).setOffset( offset ); - result.setAssembly( assembly ); - return result; - } - - /** - * @return - */ - protected abstract IASTASMDeclaration createASMDirective(); - - /** - * @param op - * @param typeId - * @param subExpression - * @param startingOffset - * @return - */ - protected IASTExpression buildTypeIdUnaryExpression(int op, IASTTypeId typeId, IASTExpression subExpression, int startingOffset) { - IASTCastExpression result = createCastExpression(); - result.setOperator( op ); - ((ASTNode)result).setOffset( startingOffset ); - result.setTypeId(typeId); - typeId.setParent( result ); - typeId.setPropertyInParent( IASTCastExpression.TYPE_ID ); - result.setOperand( subExpression ); - subExpression.setParent( result ); - subExpression.setPropertyInParent( IASTCastExpression.OPERAND ); - return result; - } - - /** - * @return - */ - protected abstract IASTCastExpression createCastExpression(); - - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseDeclarationOrExpressionStatement() throws EndOfFileException, BacktrackException { - // expressionStatement - // Note: the function style cast ambiguity is handled in - // expression - // Since it only happens when we are in a statement - IToken mark = mark(); - IASTExpressionStatement expressionStatement = null; - IToken lastTokenOfExpression = null; - BacktrackException savedBt = null; - try { - IASTExpression expression = expression(); - lastTokenOfExpression = consume(IToken.tSEMI); - expressionStatement = createExpressionStatement(); - expressionStatement.setExpression( expression ); - ((ASTNode)expressionStatement).setOffset(mark.getOffset()); - expression.setParent( expressionStatement ); - expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION ); - } catch (BacktrackException b) { - } - - backup( mark ); - - // declarationStatement - IASTDeclarationStatement ds = null; - try - { - IASTDeclaration d = declaration(); - ds = createDeclarationStatement(); - ds.setDeclaration(d); - ((ASTNode)ds).setOffset(mark.getOffset()); - d.setParent( ds ); - d.setPropertyInParent( IASTDeclarationStatement.DECLARATION ); - } - catch( BacktrackException b ) - { - savedBt = b; - backup( mark ); - } - - - if( expressionStatement == null && ds != null ) - { - cleanupLastToken(); - return ds; - } - if( expressionStatement != null && ds == null ) - { - while( true ) - { - if( consume() == lastTokenOfExpression ) - break; + IASTExpression initialValue = null; + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + initialValue = constantExpression(); } - cleanupLastToken(); - return expressionStatement; - } - - if( expressionStatement == null && ds == null ) - throwBacktrack(savedBt); - //resolve ambiguities - //A * B = C; - //A & B = C; - if( expressionStatement.getExpression() instanceof IASTBinaryExpression ) - { - IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement.getExpression(); - if( exp.getOperator() == IASTBinaryExpression.op_assign ) - { - IASTExpression lhs = exp.getOperand1(); - if( lhs instanceof IASTBinaryExpression && ((IASTBinaryExpression)lhs).getOperator() == IASTBinaryExpression.op_multiply ) - { - cleanupLastToken(); - return ds; - } - if( lhs instanceof IASTBinaryExpression && ((IASTBinaryExpression)lhs).getOperator() == IASTBinaryExpression.op_binaryAnd ) - { - cleanupLastToken(); - return ds; - } + IASTEnumerationSpecifier.IASTEnumerator enumerator = null; + if (LT(1) == IToken.tRBRACE) { + enumerator = createEnumerator(); + enumerator.setName(enumeratorName); + ((ASTNode) enumerator).setOffsetAndLength( + ((ASTNode) enumeratorName).getOffset(), lastToken + .getEndOffset() + - ((ASTNode) enumeratorName).getOffset()); + enumeratorName.setParent(enumerator); + enumeratorName + .setPropertyInParent(IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_NAME); + if (initialValue != null) { + enumerator.setValue(initialValue); + initialValue.setParent(enumerator); + initialValue + .setPropertyInParent(IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_VALUE); + } + result.addEnumerator(enumerator); + enumerator.setParent(result); + enumerator + .setPropertyInParent(IASTEnumerationSpecifier.ENUMERATOR); + cleanupLastToken(); + break; } - } - - // x = y; // default to int - // valid @ Translation Unit scope - // but not valid as a statement in a function body - if( ds.getDeclaration() instanceof IASTSimpleDeclaration && - ((IASTSimpleDeclaration)ds.getDeclaration()).getDeclSpecifier() instanceof IASTSimpleDeclSpecifier && - ((IASTSimpleDeclSpecifier)((IASTSimpleDeclaration)ds.getDeclaration()).getDeclSpecifier() ).getType() == IASTSimpleDeclSpecifier.t_unspecified) - { - backup( mark ); - while( true ) - { - if( consume() == lastTokenOfExpression ) - break; + if (LT(1) != IToken.tCOMMA) { + throwBacktrack(mark.getOffset(), mark.getLength()); } + + enumerator = createEnumerator(); + enumerator.setName(enumeratorName); + ((ASTNode) enumerator).setOffsetAndLength( + ((ASTNode) enumeratorName).getOffset(), lastToken + .getEndOffset() + - ((ASTNode) enumeratorName).getOffset()); + enumeratorName.setParent(enumerator); + enumeratorName + .setPropertyInParent(IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_NAME); + if (initialValue != null) { + enumerator.setValue(initialValue); + initialValue.setParent(enumerator); + initialValue + .setPropertyInParent(IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_VALUE); + } + result.addEnumerator(enumerator); + enumerator.setParent(result); + enumerator.setPropertyInParent(IASTEnumerationSpecifier.ENUMERATOR); cleanupLastToken(); - return expressionStatement; - } - backup( mark ); - while( true ) - { - if( consume() == lastTokenOfExpression ) - break; - } - cleanupLastToken(); - return expressionStatement; - } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException { - IToken labelName = consume(IToken.tIDENTIFIER); - consume(IToken.tCOLON); - IASTLabelStatement label_statement = createLabelStatement(); - ((ASTNode)label_statement).setOffset( labelName.getOffset() ); - IASTName name = createName( labelName ); - label_statement.setName( name ); - name.setParent( label_statement ); - name.setPropertyInParent( IASTLabelStatement.NAME ); - return label_statement; - } + consume(IToken.tCOMMA); + } + int lastOffset = consume(IToken.tRBRACE).getEndOffset(); + ((ASTNode) result).setLength(lastOffset - startOffset); + return result; + } + // enumSpecifierAbort + backup(mark); + throwBacktrack(mark.getOffset(), mark.getLength()); + return null; + } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseNullStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.tSEMI ).getOffset(); - cleanupLastToken(); - IASTNullStatement null_statement = createNullStatement(); - ((ASTNode)null_statement).setOffset( startOffset ); - return null_statement; - } + protected abstract IASTStatement statement() throws EndOfFileException, + BacktrackException; - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_goto).getOffset(); - IToken identifier = consume(IToken.tIDENTIFIER); - consume(IToken.tSEMI); - cleanupLastToken(); - IASTName goto_label_name = createName( identifier ); - IASTGotoStatement goto_statement = createGoToStatement(); - ((ASTNode)goto_statement).setOffset( startOffset ); - goto_statement.setName( goto_label_name ); - goto_label_name.setParent( goto_statement ); - goto_label_name.setPropertyInParent( IASTGotoStatement.NAME ); - return goto_statement; - } + /** + * @return + */ + protected abstract IASTEnumerator createEnumerator(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseBreakStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_break).getOffset(); - consume(IToken.tSEMI); - cleanupLastToken(); - IASTBreakStatement break_statement = createBreakStatement(); - ((ASTNode)break_statement).setOffset( startOffset ); - return break_statement; - } + /** + * @return + */ + protected abstract IASTEnumerationSpecifier createEnumerationSpecifier(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseContinueStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_continue).getOffset(); - consume(IToken.tSEMI); - cleanupLastToken(); - IASTContinueStatement continue_statement = createContinueStatement(); - ((ASTNode)continue_statement).setOffset( startOffset ); - return continue_statement; - } + /** + * @return + */ + protected abstract IASTName createName(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseReturnStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_return).getOffset(); - IASTExpression result = null; - if (LT(1) != IToken.tSEMI) { - result = expression(); - cleanupLastToken(); - } - consume(IToken.tSEMI); - cleanupLastToken(); - IASTReturnStatement return_statement = createReturnStatement(); - ((ASTNode)return_statement).setOffset( startOffset ); - if( result != null ) - { - return_statement.setReturnValue( result ); - result.setParent( return_statement ); - result.setPropertyInParent( IASTReturnStatement.RETURNVALUE ); - } - return return_statement; - } + /** + * @param token + * @return + */ + protected abstract IASTName createName(IToken token); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume( IToken.t_for ).getOffset(); - consume(IToken.tLPAREN); - IASTNode init = forInitStatement(); - IASTExpression for_condition = null; - if (LT(1) != IToken.tSEMI) - for_condition = condition(); - consume(IToken.tSEMI); - IASTExpression iterationExpression = null; - if (LT(1) != IToken.tRPAREN) { - iterationExpression = expression(); - cleanupLastToken(); - } - consume(IToken.tRPAREN); - IASTStatement for_body = statement(); - cleanupLastToken(); - IASTForStatement for_statement = createForStatement(); - ((ASTNode)for_statement).setOffset( startOffset ); - if( init instanceof IASTDeclaration ) - { - for_statement.setInit((IASTDeclaration) init); - ((IASTDeclaration) init).setParent( for_statement ); - ((IASTDeclaration) init).setPropertyInParent( IASTForStatement.INITDECLARATION ); - } - else if( init instanceof IASTExpression ) - { - for_statement.setInit((IASTExpression) init); - ((IASTExpression) init).setParent( for_statement ); - ((IASTExpression) init).setPropertyInParent( IASTForStatement.INITEXPRESSION ); - } - if( for_condition != null ) - { - for_statement.setCondition( for_condition ); - for_condition.setParent( for_statement ); - for_condition.setPropertyInParent( IASTForStatement.CONDITION ); - } - if( iterationExpression != null ) - { - for_statement.setIterationExpression( iterationExpression ); - iterationExpression.setParent( for_statement ); - iterationExpression.setPropertyInParent( IASTForStatement.ITERATION ); - } - for_statement.setBody( for_body ); - for_body.setParent( for_statement ); - for_body.setPropertyInParent( IASTForStatement.BODY ); - return for_statement; - } + /** + * @throws BacktrackException + */ + protected IASTExpression condition() throws BacktrackException, + EndOfFileException { + IASTExpression cond = expression(); + cleanupLastToken(); + return cond; + } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseDoStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_do).getOffset(); - IASTStatement do_body = statement(); - consume(IToken.t_while); - consume(IToken.tLPAREN); - IASTExpression do_condition = condition(); - consume(IToken.tRPAREN); - cleanupLastToken(); - IASTDoStatement do_statement = createDoStatement(); - ((ASTNode)do_statement).setOffset( startOffset ); - do_statement.setBody( do_body ); - do_body.setParent( do_statement ); - do_body.setPropertyInParent( IASTDoStatement.BODY ); - do_statement.setCondition( do_condition ); - do_condition.setParent( do_statement ); - do_condition.setPropertyInParent( IASTDoStatement.CONDITION ); - return do_statement; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.ISourceCodeParser#encounteredError() + */ + public boolean encounteredError() { + return !parsePassed; + } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseWhileStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_while).getOffset(); - consume(IToken.tLPAREN); - IASTExpression while_condition = condition(); - consume(IToken.tRPAREN); - IASTStatement while_body = statement(); - cleanupLastToken(); - IASTWhileStatement while_statement = createWhileStatement(); - ((ASTNode)while_statement).setOffset( startOffset ); - while_statement.setCondition( while_condition ); - while_condition.setParent( while_statement ); - while_condition.setPropertyInParent( IASTWhileStatement.CONDITION ); - while_statement.setBody( while_body ); - while_condition.setParent( while_statement ); - while_condition.setPropertyInParent( IASTWhileStatement.BODY ); - while_body.setParent( while_statement ); - return while_statement; - } + /** + * @return + */ + protected abstract IASTDeclarationStatement createDeclarationStatement(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseSwitchStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume( IToken.t_switch ).getOffset(); - consume(IToken.tLPAREN); - IASTExpression switch_condition = condition(); - consume(IToken.tRPAREN); - IASTStatement switch_body = statement(); - cleanupLastToken(); - IASTSwitchStatement switch_statement = createSwitchStatement(); - ((ASTNode)switch_statement).setOffset( startOffset ); - switch_statement.setController( switch_condition ); - switch_condition.setParent( switch_statement ); - switch_condition.setPropertyInParent( IASTSwitchStatement.CONTROLLER ); - switch_statement.setBody( switch_body ); - switch_body.setParent( switch_statement ); - switch_body.setPropertyInParent( IASTSwitchStatement.BODY ); - return switch_statement; - } + /** + * @return + */ + protected abstract IASTExpressionStatement createExpressionStatement(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException { - IASTIfStatement if_statement = null; - if_loop: while( true ){ - int so = consume(IToken.t_if).getOffset(); - consume(IToken.tLPAREN); - boolean passedCondition = true; - IASTExpression condition = null; - try { - condition = condition(); - consume(IToken.tRPAREN); - } catch (BacktrackException b) { - IASTProblem p = failParse(b); - IASTProblemExpression ps = createProblemExpression(); - ps.setProblem( p ); - ((ASTNode)ps).setOffset( ((ASTNode)p).getOffset() ); - p.setParent( ps ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - condition = ps; - failParseWithErrorHandling(); - passedCondition = false; - } - - IASTStatement thenClause = null; - if( passedCondition ){ - thenClause = statement(); - } - - IASTIfStatement new_if_statement = createIfStatement(); - ((ASTNode)new_if_statement).setOffset( so ); - new_if_statement.setCondition( condition ); - condition.setParent( new_if_statement ); - condition.setPropertyInParent( IASTIfStatement.CONDITION ); - if( thenClause != null ) - { - new_if_statement.setThenClause( thenClause ); - thenClause.setParent( new_if_statement ); - thenClause.setPropertyInParent(IASTIfStatement.THEN ); - } - if (LT(1) == IToken.t_else) { - consume(IToken.t_else); - if (LT(1) == IToken.t_if) { - //an else if, don't recurse, just loop and do another if - cleanupLastToken(); - if( if_statement != null ) - { - if_statement.setElseClause( new_if_statement ); - new_if_statement.setParent( if_statement ); - new_if_statement.setPropertyInParent( IASTIfStatement.ELSE ); - } - if_statement = new_if_statement; - continue if_loop; - } - IASTStatement elseStatement = statement(); - new_if_statement.setElseClause( elseStatement ); - elseStatement.setParent( new_if_statement ); - elseStatement.setPropertyInParent( IASTIfStatement.ELSE ); - if( if_statement != null ) - { - if_statement.setElseClause( new_if_statement ); - new_if_statement.setParent( if_statement ); - new_if_statement.setPropertyInParent( IASTIfStatement.ELSE ); - } - else - if_statement = new_if_statement; - } - else - if_statement = new_if_statement; - break if_loop; - } - cleanupLastToken(); - return if_statement; - } + /** + * @return + */ + protected abstract IASTLabelStatement createLabelStatement(); - /** - * @return - */ - protected abstract IASTProblemExpression createProblemExpression(); + /** + * @return + */ + protected abstract IASTNullStatement createNullStatement(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseCompoundStatement() throws EndOfFileException, BacktrackException { - IASTCompoundStatement compound = compoundStatement(); - cleanupLastToken(); - return compound; - } + /** + * @return + */ + protected abstract IASTGotoStatement createGoToStatement(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseDefaultStatement() throws EndOfFileException, BacktrackException { - int startOffset; - startOffset = consume(IToken.t_default).getOffset(); - consume(IToken.tCOLON); - cleanupLastToken(); - IASTDefaultStatement df = createDefaultStatement(); - ((ASTNode)df).setOffset( startOffset ); - return df; - } + /** + * @return + */ + protected abstract IASTReturnStatement createReturnStatement(); - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseCaseStatement() throws EndOfFileException, BacktrackException { - int startOffset = consume(IToken.t_case).getOffset(); - IASTExpression case_exp = constantExpression(); - consume(IToken.tCOLON); - cleanupLastToken(); - IASTCaseStatement cs = createCaseStatement(); - ((ASTNode)cs).setOffset( startOffset ); - cs.setExpression( case_exp ); - case_exp.setParent( cs ); - case_exp.setPropertyInParent( IASTCaseStatement.EXPRESSION ); - return cs; - } + /** + * @return + */ + protected abstract IASTContinueStatement createContinueStatement(); + + /** + * @return + */ + protected abstract IASTBreakStatement createBreakStatement(); + + /** + * @return + */ + protected abstract IASTForStatement createForStatement(); + + /** + * @return + */ + protected abstract IASTDoStatement createDoStatement(); + + /** + * @return + */ + protected abstract IASTWhileStatement createWhileStatement(); + + /** + * @return + */ + protected abstract IASTSwitchStatement createSwitchStatement(); + + /** + * @return + */ + protected abstract IASTIfStatement createIfStatement(); + + /** + * @return + */ + protected abstract IASTDefaultStatement createDefaultStatement(); + + /** + * @return + */ + protected abstract IASTCaseStatement createCaseStatement(); + + protected abstract IASTDeclaration declaration() throws BacktrackException, + EndOfFileException; + + protected abstract IASTNode forInitStatement() throws BacktrackException, + EndOfFileException; + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTDeclaration asmDeclaration() throws EndOfFileException, + BacktrackException { + IToken first = consume(IToken.t_asm); + consume(IToken.tLPAREN); + String assembly = consume(IToken.tSTRING).getImage(); + consume(IToken.tRPAREN); + int lastOffset = consume(IToken.tSEMI).getEndOffset(); + cleanupLastToken(); + return buildASMDirective(first.getOffset(), assembly, lastOffset); + } + + /** + * @param offset + * @param assembly + * @param lastOffset + * TODO + * @return + */ + protected IASTASMDeclaration buildASMDirective(int offset, String assembly, + int lastOffset) { + IASTASMDeclaration result = createASMDirective(); + ((ASTNode) result).setOffsetAndLength(offset, lastOffset - offset); + result.setAssembly(assembly); + return result; + } + + /** + * @return + */ + protected abstract IASTASMDeclaration createASMDirective(); + + /** + * @param op + * @param typeId + * @param subExpression + * @param startingOffset + * @param lastOffset + * @return + */ + protected IASTExpression buildTypeIdUnaryExpression(int op, + IASTTypeId typeId, IASTExpression subExpression, int startingOffset, + int lastOffset) { + IASTCastExpression result = createCastExpression(); + result.setOperator(op); + ((ASTNode) result).setOffsetAndLength(startingOffset, lastOffset + - startingOffset); + result.setTypeId(typeId); + typeId.setParent(result); + typeId.setPropertyInParent(IASTCastExpression.TYPE_ID); + result.setOperand(subExpression); + subExpression.setParent(result); + subExpression.setPropertyInParent(IASTCastExpression.OPERAND); + return result; + } + + /** + * @return + */ + protected abstract IASTCastExpression createCastExpression(); + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseDeclarationOrExpressionStatement() + throws EndOfFileException, BacktrackException { + // expressionStatement + // Note: the function style cast ambiguity is handled in + // expression + // Since it only happens when we are in a statement + IToken mark = mark(); + IASTExpressionStatement expressionStatement = null; + IToken lastTokenOfExpression = null; + BacktrackException savedBt = null; + try { + IASTExpression expression = expression(); + lastTokenOfExpression = consume(IToken.tSEMI); + expressionStatement = createExpressionStatement(); + expressionStatement.setExpression(expression); + ((ASTNode) expressionStatement).setOffsetAndLength(mark.getOffset(), + lastTokenOfExpression.getEndOffset() - mark.getOffset()); + expression.setParent(expressionStatement); + expression.setPropertyInParent(IASTExpressionStatement.EXPFRESSION); + } catch (BacktrackException b) { + } + + backup(mark); + + // declarationStatement + IASTDeclarationStatement ds = null; + try { + IASTDeclaration d = declaration(); + ds = createDeclarationStatement(); + ds.setDeclaration(d); + ((ASTNode) ds).setOffsetAndLength(((ASTNode) d).getOffset(), + ((ASTNode) d).getLength()); + d.setParent(ds); + d.setPropertyInParent(IASTDeclarationStatement.DECLARATION); + } catch (BacktrackException b) { + savedBt = b; + backup(mark); + } + + if (expressionStatement == null && ds != null) { + cleanupLastToken(); + return ds; + } + if (expressionStatement != null && ds == null) { + while (true) { + if (consume() == lastTokenOfExpression) + break; + } + cleanupLastToken(); + return expressionStatement; + } + + if (expressionStatement == null && ds == null) + throwBacktrack(savedBt); + //resolve ambiguities + //A * B = C; + //A & B = C; + if (expressionStatement.getExpression() instanceof IASTBinaryExpression) { + IASTBinaryExpression exp = (IASTBinaryExpression) expressionStatement + .getExpression(); + if (exp.getOperator() == IASTBinaryExpression.op_assign) { + IASTExpression lhs = exp.getOperand1(); + if (lhs instanceof IASTBinaryExpression + && ((IASTBinaryExpression) lhs).getOperator() == IASTBinaryExpression.op_multiply) { + cleanupLastToken(); + return ds; + } + if (lhs instanceof IASTBinaryExpression + && ((IASTBinaryExpression) lhs).getOperator() == IASTBinaryExpression.op_binaryAnd) { + cleanupLastToken(); + return ds; + } + } + } + + // x = y; // default to int + // valid @ Translation Unit scope + // but not valid as a statement in a function body + if (ds.getDeclaration() instanceof IASTSimpleDeclaration + && ((IASTSimpleDeclaration) ds.getDeclaration()).getDeclSpecifier() instanceof IASTSimpleDeclSpecifier + && ((IASTSimpleDeclSpecifier) ((IASTSimpleDeclaration) ds + .getDeclaration()).getDeclSpecifier()).getType() == IASTSimpleDeclSpecifier.t_unspecified) { + backup(mark); + while (true) { + if (consume() == lastTokenOfExpression) + break; + } + cleanupLastToken(); + return expressionStatement; + } + backup(mark); + while (true) { + if (consume() == lastTokenOfExpression) + break; + } + cleanupLastToken(); + return expressionStatement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseLabelStatement() throws EndOfFileException, + BacktrackException { + IToken labelName = consume(IToken.tIDENTIFIER); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + IASTLabelStatement label_statement = createLabelStatement(); + ((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), + lastOffset - labelName.getOffset()); + IASTName name = createName(labelName); + label_statement.setName(name); + name.setParent(label_statement); + name.setPropertyInParent(IASTLabelStatement.NAME); + return label_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseNullStatement() throws EndOfFileException, + BacktrackException { + IToken t = consume(IToken.tSEMI); + cleanupLastToken(); + IASTNullStatement null_statement = createNullStatement(); + ((ASTNode) null_statement).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return null_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseGotoStatement() throws EndOfFileException, + BacktrackException { + int startOffset = consume(IToken.t_goto).getOffset(); + IToken identifier = consume(IToken.tIDENTIFIER); + int lastOffset = consume(IToken.tSEMI).getEndOffset(); + cleanupLastToken(); + IASTName goto_label_name = createName(identifier); + IASTGotoStatement goto_statement = createGoToStatement(); + ((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset + - startOffset); + goto_statement.setName(goto_label_name); + goto_label_name.setParent(goto_statement); + goto_label_name.setPropertyInParent(IASTGotoStatement.NAME); + return goto_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseBreakStatement() throws EndOfFileException, + BacktrackException { + int startOffset = consume(IToken.t_break).getOffset(); + int lastOffset = consume(IToken.tSEMI).getEndOffset(); + cleanupLastToken(); + IASTBreakStatement break_statement = createBreakStatement(); + ((ASTNode) break_statement).setOffsetAndLength(startOffset, lastOffset + - startOffset); + return break_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseContinueStatement() throws EndOfFileException, + BacktrackException { + int startOffset = consume(IToken.t_continue).getOffset(); + int lastOffset = consume(IToken.tSEMI).getEndOffset(); + cleanupLastToken(); + IASTContinueStatement continue_statement = createContinueStatement(); + ((ASTNode) continue_statement).setOffsetAndLength(startOffset, lastOffset + - startOffset); + return continue_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseReturnStatement() throws EndOfFileException, + BacktrackException { + int startOffset; + startOffset = consume(IToken.t_return).getOffset(); + IASTExpression result = null; + if (LT(1) != IToken.tSEMI) { + result = expression(); + cleanupLastToken(); + } + int lastOffset = consume(IToken.tSEMI).getEndOffset(); + cleanupLastToken(); + IASTReturnStatement return_statement = createReturnStatement(); + ((ASTNode) return_statement).setOffsetAndLength(startOffset, lastOffset + - startOffset); + if (result != null) { + return_statement.setReturnValue(result); + result.setParent(return_statement); + result.setPropertyInParent(IASTReturnStatement.RETURNVALUE); + } + return return_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseForStatement() throws EndOfFileException, + BacktrackException { + int startOffset; + startOffset = consume(IToken.t_for).getOffset(); + consume(IToken.tLPAREN); + IASTNode init = forInitStatement(); + IASTExpression for_condition = null; + if (LT(1) != IToken.tSEMI) + for_condition = condition(); + consume(IToken.tSEMI); + IASTExpression iterationExpression = null; + if (LT(1) != IToken.tRPAREN) { + iterationExpression = expression(); + cleanupLastToken(); + } + consume(IToken.tRPAREN); + IASTStatement for_body = statement(); + IASTForStatement for_statement = createForStatement(); + ((ASTNode) for_statement).setOffsetAndLength(startOffset, lastToken + .getEndOffset() + - startOffset); + cleanupLastToken(); + if (init instanceof IASTDeclaration) { + for_statement.setInit((IASTDeclaration) init); + ((IASTDeclaration) init).setParent(for_statement); + ((IASTDeclaration) init) + .setPropertyInParent(IASTForStatement.INITDECLARATION); + } else if (init instanceof IASTExpression) { + for_statement.setInit((IASTExpression) init); + ((IASTExpression) init).setParent(for_statement); + ((IASTExpression) init) + .setPropertyInParent(IASTForStatement.INITEXPRESSION); + } + if (for_condition != null) { + for_statement.setCondition(for_condition); + for_condition.setParent(for_statement); + for_condition.setPropertyInParent(IASTForStatement.CONDITION); + } + if (iterationExpression != null) { + for_statement.setIterationExpression(iterationExpression); + iterationExpression.setParent(for_statement); + iterationExpression.setPropertyInParent(IASTForStatement.ITERATION); + } + for_statement.setBody(for_body); + for_body.setParent(for_statement); + for_body.setPropertyInParent(IASTForStatement.BODY); + return for_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseDoStatement() throws EndOfFileException, + BacktrackException { + int startOffset; + startOffset = consume(IToken.t_do).getOffset(); + IASTStatement do_body = statement(); + consume(IToken.t_while); + consume(IToken.tLPAREN); + IASTExpression do_condition = condition(); + int lastOffset = consume(IToken.tRPAREN).getEndOffset(); + cleanupLastToken(); + IASTDoStatement do_statement = createDoStatement(); + ((ASTNode) do_statement).setOffsetAndLength(startOffset, lastOffset + - startOffset); + do_statement.setBody(do_body); + do_body.setParent(do_statement); + do_body.setPropertyInParent(IASTDoStatement.BODY); + do_statement.setCondition(do_condition); + do_condition.setParent(do_statement); + do_condition.setPropertyInParent(IASTDoStatement.CONDITION); + return do_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseWhileStatement() throws EndOfFileException, + BacktrackException { + int startOffset; + startOffset = consume(IToken.t_while).getOffset(); + consume(IToken.tLPAREN); + IASTExpression while_condition = condition(); + consume(IToken.tRPAREN); + IASTStatement while_body = statement(); + cleanupLastToken(); + IASTWhileStatement while_statement = createWhileStatement(); + ((ASTNode) while_statement).setOffsetAndLength(startOffset, lastToken + .getEndOffset() + - startOffset); + while_statement.setCondition(while_condition); + while_condition.setParent(while_statement); + while_condition.setPropertyInParent(IASTWhileStatement.CONDITION); + while_statement.setBody(while_body); + while_condition.setParent(while_statement); + while_condition.setPropertyInParent(IASTWhileStatement.BODY); + while_body.setParent(while_statement); + return while_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseSwitchStatement() throws EndOfFileException, + BacktrackException { + int startOffset; + startOffset = consume(IToken.t_switch).getOffset(); + consume(IToken.tLPAREN); + IASTExpression switch_condition = condition(); + consume(IToken.tRPAREN); + IASTStatement switch_body = statement(); + cleanupLastToken(); + IASTSwitchStatement switch_statement = createSwitchStatement(); + ((ASTNode) switch_statement).setOffsetAndLength(startOffset, lastToken + .getEndOffset() + - startOffset); + switch_statement.setController(switch_condition); + switch_condition.setParent(switch_statement); + switch_condition.setPropertyInParent(IASTSwitchStatement.CONTROLLER); + switch_statement.setBody(switch_body); + switch_body.setParent(switch_statement); + switch_body.setPropertyInParent(IASTSwitchStatement.BODY); + return switch_statement; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseIfStatement() throws EndOfFileException, + BacktrackException { + IASTIfStatement if_statement = null; + int start = LA(1).getOffset(); + if_loop: while (true) { + int so = consume(IToken.t_if).getOffset(); + consume(IToken.tLPAREN); + boolean passedCondition = true; + IASTExpression condition = null; + try { + condition = condition(); + consume(IToken.tRPAREN); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemExpression ps = createProblemExpression(); + ps.setProblem(p); + ((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(), + ((ASTNode) p).getLength()); + p.setParent(ps); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + condition = ps; + failParseWithErrorHandling(); + passedCondition = false; + } + + IASTStatement thenClause = null; + if (passedCondition) { + thenClause = statement(); + } + + IASTIfStatement new_if_statement = createIfStatement(); + ((ASTNode) new_if_statement).setOffset(so); + new_if_statement.setCondition(condition); + condition.setParent(new_if_statement); + condition.setPropertyInParent(IASTIfStatement.CONDITION); + if (thenClause != null) { + new_if_statement.setThenClause(thenClause); + thenClause.setParent(new_if_statement); + thenClause.setPropertyInParent(IASTIfStatement.THEN); + } + if (LT(1) == IToken.t_else) { + consume(IToken.t_else); + if (LT(1) == IToken.t_if) { + //an else if, don't recurse, just loop and do another if + cleanupLastToken(); + if (if_statement != null) { + if_statement.setElseClause(new_if_statement); + new_if_statement.setParent(if_statement); + new_if_statement.setPropertyInParent(IASTIfStatement.ELSE); + } + if_statement = new_if_statement; + continue if_loop; + } + IASTStatement elseStatement = statement(); + new_if_statement.setElseClause(elseStatement); + elseStatement.setParent(new_if_statement); + elseStatement.setPropertyInParent(IASTIfStatement.ELSE); + if (if_statement != null) { + if_statement.setElseClause(new_if_statement); + new_if_statement.setParent(if_statement); + new_if_statement.setPropertyInParent(IASTIfStatement.ELSE); + } else + if_statement = new_if_statement; + } else + if_statement = new_if_statement; + break if_loop; + } + cleanupLastToken(); + ((ASTNode) if_statement).setLength(lastToken.getEndOffset() - start); + return if_statement; + } + + /** + * @return + */ + protected abstract IASTProblemExpression createProblemExpression(); + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseCompoundStatement() throws EndOfFileException, + BacktrackException { + IASTCompoundStatement compound = compoundStatement(); + cleanupLastToken(); + return compound; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseDefaultStatement() throws EndOfFileException, + BacktrackException { + int startOffset = consume(IToken.t_default).getOffset(); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + cleanupLastToken(); + IASTDefaultStatement df = createDefaultStatement(); + ((ASTNode) df).setOffsetAndLength(startOffset, lastOffset - startOffset); + return df; + } + + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseCaseStatement() throws EndOfFileException, + BacktrackException { + int startOffset = consume(IToken.t_case).getOffset(); + IASTExpression case_exp = constantExpression(); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + cleanupLastToken(); + IASTCaseStatement cs = createCaseStatement(); + ((ASTNode) cs).setOffsetAndLength(startOffset, lastOffset - startOffset); + cs.setExpression(case_exp); + case_exp.setParent(cs); + case_exp.setPropertyInParent(IASTCaseStatement.EXPRESSION); + return cs; + } } \ No newline at end of file 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 43aa631c610..08829acba87 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 @@ -101,981 +101,999 @@ import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; */ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { - private final boolean supportGCCStyleDesignators; + private final boolean supportGCCStyleDesignators; - private static final int DEFAULT_DECLARATOR_LIST_SIZE = 4; + private static final int DEFAULT_DECLARATOR_LIST_SIZE = 4; - /** - * @param scanner - * @param parserMode - * @param logService - */ - public GNUCSourceParser(IScanner scanner, ParserMode parserMode, - IParserLogService logService, ICParserExtensionConfiguration config) { - super(scanner, logService, parserMode, config - .supportStatementsInExpressions(), config - .supportTypeofUnaryExpressions(), config - .supportAlignOfUnaryExpression()); - supportGCCStyleDesignators = config.supportGCCStyleDesignators(); - } + /** + * @param scanner + * @param parserMode + * @param logService + */ + public GNUCSourceParser(IScanner scanner, ParserMode parserMode, + IParserLogService logService, ICParserExtensionConfiguration config) { + super(scanner, logService, parserMode, config + .supportStatementsInExpressions(), config + .supportTypeofUnaryExpressions(), config + .supportAlignOfUnaryExpression()); + supportGCCStyleDesignators = config.supportGCCStyleDesignators(); + } - /** - * @param d - */ - protected void throwAwayMarksForInitializerClause() { - simpleDeclarationMark = null; - } + /** + * @param d + */ + protected void throwAwayMarksForInitializerClause() { + simpleDeclarationMark = null; + } - protected IASTInitializer optionalCInitializer() throws EndOfFileException, - BacktrackException { - if (LT(1) == IToken.tASSIGN) { - consume(IToken.tASSIGN); - throwAwayMarksForInitializerClause(); - return cInitializerClause(Collections.EMPTY_LIST); - } - return null; - } + protected IASTInitializer optionalCInitializer() throws EndOfFileException, + BacktrackException { + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + throwAwayMarksForInitializerClause(); + return cInitializerClause(Collections.EMPTY_LIST); + } + return null; + } - /** - * @param scope - * @return - */ - protected IASTInitializer cInitializerClause(List designators) - throws EndOfFileException, BacktrackException { - IToken la = LA(1); - int startingOffset = la.getOffset(); - la = null; - if (LT(1) == IToken.tLBRACE) { - consume(IToken.tLBRACE); - IASTInitializerList result = createInitializerList(); - ((ASTNode) result).setOffset(startingOffset); - for (;;) { - int checkHashcode = LA(1).hashCode(); - // required at least one initializer list - // get designator list - List newDesignators = designatorList(); - if (newDesignators.size() != 0) - if (LT(1) == IToken.tASSIGN) - consume(IToken.tASSIGN); + /** + * @param scope + * @return + */ + protected IASTInitializer cInitializerClause(List designators) + throws EndOfFileException, BacktrackException { + IToken la = LA(1); + int startingOffset = la.getOffset(); + la = null; + if (LT(1) == IToken.tLBRACE) { + consume(IToken.tLBRACE); + IASTInitializerList result = createInitializerList(); + ((ASTNode) result).setOffset(startingOffset); + for (;;) { + int checkHashcode = LA(1).hashCode(); + // required at least one initializer list + // get designator list + List newDesignators = designatorList(); + if (newDesignators.size() != 0) + if (LT(1) == IToken.tASSIGN) + consume(IToken.tASSIGN); - IASTInitializer initializer = cInitializerClause(newDesignators); + IASTInitializer initializer = cInitializerClause(newDesignators); - if (newDesignators.isEmpty()) { - result.addInitializer(initializer); - initializer.setParent(result); - initializer - .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER); - } else { - ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); - ((CASTNode) desigInitializer) - .setOffset(((CASTNode) newDesignators.get(0)) - .getOffset()); - for (int i = 0; i < newDesignators.size(); ++i) { - ICASTDesignator d = (ICASTDesignator) newDesignators - .get(i); - d.setParent(desigInitializer); - d - .setPropertyInParent(ICASTDesignatedInitializer.DESIGNATOR); - desigInitializer.addDesignator(d); - } - desigInitializer.setOperandInitializer(initializer); - initializer.setParent(desigInitializer); - initializer - .setPropertyInParent(ICASTDesignatedInitializer.OPERAND); - result.addInitializer(desigInitializer); - desigInitializer.setParent(result); - desigInitializer - .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER); - } - // can end with just a '}' - if (LT(1) == IToken.tRBRACE) - break; - // can end with ", }" - if (LT(1) == IToken.tCOMMA) - consume(IToken.tCOMMA); - if (LT(1) == IToken.tRBRACE) - break; - if (checkHashcode == LA(1).hashCode()) { - IToken l2 = LA(1); - throwBacktrack(startingOffset, l2.getEndOffset() - - startingOffset); - return null; - } - - // otherwise, its another initializer in the list + if (newDesignators.isEmpty()) { + result.addInitializer(initializer); + initializer.setParent(result); + initializer + .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER); + } else { + ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); + ((CASTNode) desigInitializer).setOffsetAndLength( + ((CASTNode) newDesignators.get(0)).getOffset(), + ((CASTNode) newDesignators.get(0)).getLength()); + for (int i = 0; i < newDesignators.size(); ++i) { + ICASTDesignator d = (ICASTDesignator) newDesignators.get(i); + d.setParent(desigInitializer); + d.setPropertyInParent(ICASTDesignatedInitializer.DESIGNATOR); + desigInitializer.addDesignator(d); + } + desigInitializer.setOperandInitializer(initializer); + initializer.setParent(desigInitializer); + initializer + .setPropertyInParent(ICASTDesignatedInitializer.OPERAND); + result.addInitializer(desigInitializer); + desigInitializer.setParent(result); + desigInitializer + .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER); } - // consume the closing brace - consume(IToken.tRBRACE); - return result; - } - // if we get this far, it means that we have not yet succeeded - // try this now instead - // assignmentExpression - try { - IASTExpression assignmentExpression = assignmentExpression(); - IASTInitializerExpression result = createInitializerExpression(); - result.setExpression(assignmentExpression); - ((ASTNode) result).setOffset(((ASTNode) assignmentExpression) - .getOffset()); - assignmentExpression.setParent(result); - assignmentExpression - .setPropertyInParent(IASTInitializerExpression.INITIALIZER_EXPRESSION); - return result; - } catch (BacktrackException b) { - // do nothing - } - int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; - throwBacktrack(startingOffset, endOffset - startingOffset); - return null; - } - - /** - * @return - */ - protected ICASTDesignatedInitializer createDesignatorInitializer() { - return new CASTDesignatedInitializer(); - } - - /** - * @return - */ - protected IASTInitializerList createInitializerList() { - return new CASTInitializerList(); - } - - /** - * @return - */ - protected IASTInitializerExpression createInitializerExpression() { - return new CASTInitializerExpression(); - } - - protected List designatorList() throws EndOfFileException, - BacktrackException { - //designated initializers for C - List designatorList = Collections.EMPTY_LIST; - - if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { - while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { - if (LT(1) == IToken.tDOT) { - int offset = consume(IToken.tDOT).getOffset(); - IToken id = identifier(); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffset(offset); - IASTName n = createName(id); - designator.setName(n); - n.setParent(designator); - n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } else if (LT(1) == IToken.tLBRACKET) { - IToken mark = consume(IToken.tLBRACKET); - int offset = mark.getOffset(); - IASTExpression constantExpression = expression(); - if (LT(1) == IToken.tRBRACKET) { - consume(IToken.tRBRACKET); - ICASTArrayDesignator designator = createArrayDesignator(); - ((ASTNode) designator).setOffset(offset); - designator.setSubscriptExpression(constantExpression); - constantExpression.setParent(designator); - constantExpression - .setPropertyInParent(ICASTArrayDesignator.SUBSCRIPT_EXPRESSION); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - continue; - } - backup(mark); - if (supportGCCStyleDesignators) { - int startOffset = consume(IToken.tLBRACKET).getOffset(); - IASTExpression constantExpression1 = expression(); - consume(IToken.tELLIPSIS); - IASTExpression constantExpression2 = expression(); - consume(IToken.tRBRACKET); - IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); - ((ASTNode) designator).setOffset(startOffset); - designator.setRangeFloor(constantExpression1); - constantExpression1.setParent(designator); - constantExpression1 - .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_FLOOR_EXPRESSION); - designator.setRangeCeiling(constantExpression2); - constantExpression2.setParent(designator); - constantExpression2 - .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_CEILING_EXPRESSION); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } - } else if (supportGCCStyleDesignators - && LT(1) == IToken.tIDENTIFIER) { - IToken identifier = identifier(); - consume(IToken.tCOLON); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffset(identifier.getOffset()); - IASTName n = createName(identifier); - designator.setName(n); - n.setParent(designator); - n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } + // can end with just a '}' + if (LT(1) == IToken.tRBRACE) + break; + // can end with ", }" + if (LT(1) == IToken.tCOMMA) + consume(IToken.tCOMMA); + if (LT(1) == IToken.tRBRACE) + break; + if (checkHashcode == LA(1).hashCode()) { + IToken l2 = LA(1); + throwBacktrack(startingOffset, l2.getEndOffset() + - startingOffset); + return null; } - } else { - if (supportGCCStyleDesignators - && (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { - if (LT(1) == IToken.tIDENTIFIER) { - IToken identifier = identifier(); - consume(IToken.tCOLON); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffset(identifier.getOffset()); - IASTName n = createName(identifier); - designator.setName(n); - n.setParent(designator); - n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } else if (LT(1) == IToken.tLBRACKET) { - int startOffset = consume(IToken.tLBRACKET).getOffset(); - IASTExpression constantExpression1 = expression(); - consume(IToken.tELLIPSIS); - IASTExpression constantExpression2 = expression(); - consume(IToken.tRBRACKET); - IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); - ((ASTNode) designator).setOffset(startOffset); - designator.setRangeFloor(constantExpression1); - constantExpression1.setParent(designator); - constantExpression1 - .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_FLOOR_EXPRESSION); - designator.setRangeCeiling(constantExpression2); - constantExpression2.setParent(designator); - constantExpression2 - .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_CEILING_EXPRESSION); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList( - DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } + // otherwise, its another initializer in the list + } + // consume the closing brace + int lastOffset = consume(IToken.tRBRACE).getEndOffset(); + ((ASTNode) result).setLength(lastOffset - startingOffset); + return result; + } + // if we get this far, it means that we have not yet succeeded + // try this now instead + // assignmentExpression + try { + IASTExpression assignmentExpression = assignmentExpression(); + IASTInitializerExpression result = createInitializerExpression(); + result.setExpression(assignmentExpression); + ((ASTNode) result).setOffsetAndLength(((ASTNode) assignmentExpression) + .getOffset(), ((ASTNode) assignmentExpression).getLength()); + assignmentExpression.setParent(result); + assignmentExpression + .setPropertyInParent(IASTInitializerExpression.INITIALIZER_EXPRESSION); + return result; + } catch (BacktrackException b) { + // do nothing + } + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + throwBacktrack(startingOffset, endOffset - startingOffset); + return null; + } + + /** + * @return + */ + protected ICASTDesignatedInitializer createDesignatorInitializer() { + return new CASTDesignatedInitializer(); + } + + /** + * @return + */ + protected IASTInitializerList createInitializerList() { + return new CASTInitializerList(); + } + + /** + * @return + */ + protected IASTInitializerExpression createInitializerExpression() { + return new CASTInitializerExpression(); + } + + protected List designatorList() throws EndOfFileException, + BacktrackException { + //designated initializers for C + List designatorList = Collections.EMPTY_LIST; + + if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { + while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { + if (LT(1) == IToken.tDOT) { + int offset = consume(IToken.tDOT).getOffset(); + IToken id = identifier(); + ICASTFieldDesignator designator = createFieldDesignator(); + ((ASTNode) designator).setOffsetAndLength(offset, id + .getEndOffset() + - offset); + IASTName n = createName(id); + designator.setName(n); + n.setParent(designator); + n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + } else if (LT(1) == IToken.tLBRACKET) { + IToken mark = consume(IToken.tLBRACKET); + int offset = mark.getOffset(); + IASTExpression constantExpression = expression(); + if (LT(1) == IToken.tRBRACKET) { + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + ICASTArrayDesignator designator = createArrayDesignator(); + ((ASTNode) designator).setOffsetAndLength(offset, lastOffset + - offset); + designator.setSubscriptExpression(constantExpression); + constantExpression.setParent(designator); + constantExpression + .setPropertyInParent(ICASTArrayDesignator.SUBSCRIPT_EXPRESSION); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList( + DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + continue; + } + backup(mark); + if (supportGCCStyleDesignators) { + int startOffset = consume(IToken.tLBRACKET).getOffset(); + IASTExpression constantExpression1 = expression(); + consume(IToken.tELLIPSIS); + IASTExpression constantExpression2 = expression(); + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); + ((ASTNode) designator).setOffsetAndLength(startOffset, + lastOffset - startOffset); + designator.setRangeFloor(constantExpression1); + constantExpression1.setParent(designator); + constantExpression1 + .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_FLOOR_EXPRESSION); + designator.setRangeCeiling(constantExpression2); + constantExpression2.setParent(designator); + constantExpression2 + .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_CEILING_EXPRESSION); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList( + DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + } + } else if (supportGCCStyleDesignators + && LT(1) == IToken.tIDENTIFIER) { + IToken identifier = identifier(); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + ICASTFieldDesignator designator = createFieldDesignator(); + ((ASTNode) designator).setOffsetAndLength( + identifier.getOffset(), lastOffset + - identifier.getOffset()); + IASTName n = createName(identifier); + designator.setName(n); + n.setParent(designator); + n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); } - } - return designatorList; - } + } + } else { + if (supportGCCStyleDesignators + && (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { - /** - * @return - */ - protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { - return new CASTArrayRangeDesignator(); - } + if (LT(1) == IToken.tIDENTIFIER) { + IToken identifier = identifier(); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + ICASTFieldDesignator designator = createFieldDesignator(); + ((ASTNode) designator).setOffsetAndLength( + identifier.getOffset(), lastOffset + - identifier.getOffset()); + IASTName n = createName(identifier); + designator.setName(n); + n.setParent(designator); + n.setPropertyInParent(ICASTFieldDesignator.FIELD_NAME); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + } else if (LT(1) == IToken.tLBRACKET) { + int startOffset = consume(IToken.tLBRACKET).getOffset(); + IASTExpression constantExpression1 = expression(); + consume(IToken.tELLIPSIS); + IASTExpression constantExpression2 = expression(); + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); + ((ASTNode) designator).setOffsetAndLength(startOffset, + lastOffset - startOffset); + designator.setRangeFloor(constantExpression1); + constantExpression1.setParent(designator); + constantExpression1 + .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_FLOOR_EXPRESSION); + designator.setRangeCeiling(constantExpression2); + constantExpression2.setParent(designator); + constantExpression2 + .setPropertyInParent(IGCCASTArrayRangeDesignator.SUBSCRIPT_CEILING_EXPRESSION); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + } + } + } + return designatorList; + } - /** - * @return - */ - protected ICASTArrayDesignator createArrayDesignator() { - return new CASTArrayDesignator(); - } + /** + * @return + */ + protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { + return new CASTArrayRangeDesignator(); + } - /** - * @return - */ - protected ICASTFieldDesignator createFieldDesignator() { - return new CASTFieldDesignator(); - } + /** + * @return + */ + protected ICASTArrayDesignator createArrayDesignator() { + return new CASTArrayDesignator(); + } - protected IASTDeclaration declaration() throws EndOfFileException, - BacktrackException { - switch (LT(1)) { - case IToken.t_asm: + /** + * @return + */ + protected ICASTFieldDesignator createFieldDesignator() { + return new CASTFieldDesignator(); + } + + protected IASTDeclaration declaration() throws EndOfFileException, + BacktrackException { + switch (LT(1)) { + case IToken.t_asm: return asmDeclaration(); - default: + default: IASTDeclaration d = simpleDeclaration(); cleanupLastToken(); return d; - } + } - } + } - /** - * @throws BacktrackException - * @throws EndOfFileException - */ - protected IASTDeclaration simpleDeclaration() throws BacktrackException, - EndOfFileException { - IToken firstToken = LA(1); - int firstOffset = firstToken.getOffset(); - if (firstToken.getType() == IToken.tLBRACE) - throwBacktrack(firstToken.getOffset(), firstToken.getLength()); + /** + * @throws BacktrackException + * @throws EndOfFileException + */ + protected IASTDeclaration simpleDeclaration() throws BacktrackException, + EndOfFileException { + IToken firstToken = LA(1); + int firstOffset = firstToken.getOffset(); + if (firstToken.getType() == IToken.tLBRACE) + throwBacktrack(firstToken.getOffset(), firstToken.getLength()); - firstToken = null; // necessary for scalability + firstToken = null; // necessary for scalability - IASTDeclSpecifier declSpec = declSpecifierSeq(false); + IASTDeclSpecifier declSpec = declSpecifierSeq(false); - List declarators = Collections.EMPTY_LIST; - if (LT(1) != IToken.tSEMI) { - declarators = new ArrayList(DEFAULT_DECLARATOR_LIST_SIZE); + List declarators = Collections.EMPTY_LIST; + if (LT(1) != IToken.tSEMI) { + declarators = new ArrayList(DEFAULT_DECLARATOR_LIST_SIZE); + declarators.add(initDeclarator()); + + while (LT(1) == IToken.tCOMMA) { + consume(IToken.tCOMMA); declarators.add(initDeclarator()); + } + } - while (LT(1) == IToken.tCOMMA) { - consume(IToken.tCOMMA); - declarators.add(initDeclarator()); - } - } + boolean hasFunctionBody = false; + boolean hasFunctionTryBlock = false; + boolean consumedSemi = false; - boolean hasFunctionBody = false; - boolean hasFunctionTryBlock = false; - boolean consumedSemi = false; - - switch (LT(1)) { - case IToken.tSEMI: + switch (LT(1)) { + case IToken.tSEMI: consume(IToken.tSEMI); consumedSemi = true; break; - case IToken.tLBRACE: + case IToken.tLBRACE: break; - default: + default: throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); - } + } - if (!consumedSemi) { - if (LT(1) == IToken.tLBRACE) { - hasFunctionBody = true; + if (!consumedSemi) { + if (LT(1) == IToken.tLBRACE) { + hasFunctionBody = true; + } + + if (hasFunctionTryBlock && !hasFunctionBody) + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); + } + + if (hasFunctionBody) { + if (declarators.size() != 1) + throwBacktrack(firstOffset, LA(1).getEndOffset()); + + IASTDeclarator declarator = (IASTDeclarator) declarators.get(0); + if (!(declarator instanceof IASTFunctionDeclarator)) + throwBacktrack(firstOffset, LA(1).getEndOffset()); + + IASTFunctionDefinition funcDefinition = createFunctionDefinition(); + ((ASTNode) funcDefinition).setOffset(firstOffset); + funcDefinition.setDeclSpecifier(declSpec); + declSpec.setParent(funcDefinition); + declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER); + + funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator); + declarator.setParent(funcDefinition); + declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR); + + IASTStatement s = handleFunctionBody(); + if (s != null) { + funcDefinition.setBody(s); + s.setParent(funcDefinition); + s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY); + } + ((ASTNode) funcDefinition).setLength(lastToken.getEndOffset() + - firstOffset); + return funcDefinition; + } + + IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration(); + ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, lastToken + .getEndOffset() + - firstOffset); + simpleDeclaration.setDeclSpecifier(declSpec); + declSpec.setParent(simpleDeclaration); + declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER); + + for (int i = 0; i < declarators.size(); ++i) { + IASTDeclarator declarator = (IASTDeclarator) declarators.get(i); + simpleDeclaration.addDeclarator(declarator); + declarator.setParent(simpleDeclaration); + declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR); + } + return simpleDeclaration; + } + + /** + * @return + */ + protected IASTFunctionDefinition createFunctionDefinition() { + return new CASTFunctionDefinition(); + } + + /** + * @return + */ + protected CASTSimpleDeclaration createSimpleDeclaration() { + return new CASTSimpleDeclaration(); + } + + protected CASTTranslationUnit translationUnit; + + private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; + + private static final int DEFAULT_PARAMETERS_LIST_SIZE = 4; + + protected CASTTranslationUnit createTranslationUnit() { + CASTTranslationUnit t = new CASTTranslationUnit(); + t.setOffset(0); + t.setParent(null); + t.setPropertyInParent(null); + return t; + } + + /** + * This is the top-level entry point into the ANSI C++ grammar. + * + * translationUnit : (declaration)* + */ + protected void translationUnit() { + try { + translationUnit = createTranslationUnit(); + } catch (Exception e2) { + logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$ + return; + } + + translationUnit.setLocationResolver(scanner.getLocationResolver()); + + int lastBacktrack = -1; + while (true) { + try { + int checkOffset = LA(1).hashCode(); + IASTDeclaration d = declaration(); + d.setParent(translationUnit); + d.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); + translationUnit.addDeclaration(d); + if (LA(1).hashCode() == checkOffset) + failParseWithErrorHandling(); + } catch (EndOfFileException e) { + // As expected + if( translationUnit.getDeclarations().length != 0 ) + { + CASTNode d = (CASTNode) translationUnit.getDeclarations()[ translationUnit.getDeclarations().length - 1 ]; + ((CASTNode) translationUnit).setLength( d.getOffset() + d.getLength() ); } - - if (hasFunctionTryBlock && !hasFunctionBody) - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); - } - - if (hasFunctionBody) { - if (declarators.size() != 1) - throwBacktrack(firstOffset, LA(1).getEndOffset()); - - IASTDeclarator declarator = (IASTDeclarator) declarators.get(0); - if (!(declarator instanceof IASTFunctionDeclarator)) - throwBacktrack(firstOffset, LA(1).getEndOffset()); - - IASTFunctionDefinition funcDefinition = createFunctionDefinition(); - ((ASTNode) funcDefinition).setOffset(firstOffset); - funcDefinition.setDeclSpecifier(declSpec); - declSpec.setParent(funcDefinition); - declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER); - - funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator); - declarator.setParent(funcDefinition); - declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR); - - IASTStatement s = handleFunctionBody(); - if (s != null) { - funcDefinition.setBody(s); - s.setParent(funcDefinition); - s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY); - } - return funcDefinition; - } - - IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration(); - ((ASTNode) simpleDeclaration).setOffset(firstOffset); - simpleDeclaration.setDeclSpecifier(declSpec); - declSpec.setParent(simpleDeclaration); - declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER); - - for (int i = 0; i < declarators.size(); ++i) { - IASTDeclarator declarator = (IASTDeclarator) declarators.get(i); - simpleDeclaration.addDeclarator(declarator); - declarator.setParent(simpleDeclaration); - declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR); - } - return simpleDeclaration; - } - - /** - * @return - */ - protected IASTFunctionDefinition createFunctionDefinition() { - return new CASTFunctionDefinition(); - } - - /** - * @return - */ - protected CASTSimpleDeclaration createSimpleDeclaration() { - return new CASTSimpleDeclaration(); - } - - protected CASTTranslationUnit translationUnit; - - private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; - - private static final int DEFAULT_PARAMETERS_LIST_SIZE = 4; - - protected CASTTranslationUnit createTranslationUnit() { - CASTTranslationUnit t = new CASTTranslationUnit(); - t.setOffset(0); - t.setParent(null); - t.setPropertyInParent(null); - return t; - } - - /** - * This is the top-level entry point into the ANSI C++ grammar. - * - * translationUnit : (declaration)* - */ - protected void translationUnit() { - try { - translationUnit = createTranslationUnit(); - } catch (Exception e2) { - logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$ - return; - } - - translationUnit.setLocationResolver(scanner.getLocationResolver()); - - int lastBacktrack = -1; - while (true) { + else + ((CASTNode)translationUnit).setLength( 0 ); + break; + } catch (BacktrackException b) { try { - int checkOffset = LA(1).hashCode(); - IASTDeclaration d = declaration(); - d.setParent(translationUnit); - d.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); - translationUnit.addDeclaration(d); - if (LA(1).hashCode() == checkOffset) - failParseWithErrorHandling(); + // Mark as failure and try to reach a recovery point + IASTProblem p = failParse(b); + IASTProblemDeclaration pd = createProblemDeclaration(); + pd.setProblem(p); + ((CASTNode) pd).setOffsetAndLength(((CASTNode) p).getOffset(), + ((CASTNode) p).getLength()); + p.setParent(pd); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + pd.setParent(translationUnit); + pd.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); + translationUnit.addDeclaration(pd); + errorHandling(); + if (lastBacktrack != -1 && lastBacktrack == LA(1).hashCode()) { + // we haven't progressed from the + // last backtrack + // try and find tne next definition + failParseWithErrorHandling(); + } else { + // start again from here + lastBacktrack = LA(1).hashCode(); + } } catch (EndOfFileException e) { - // Good - break; - } catch (BacktrackException b) { - try { - // Mark as failure and try to reach a recovery point - IASTProblem p = failParse(b); - IASTProblemDeclaration pd = createProblemDeclaration(); - pd.setProblem(p); - ((CASTNode) pd).setOffset(((CASTNode) p).getOffset()); - p.setParent(pd); - p.setPropertyInParent(IASTProblemHolder.PROBLEM); - pd.setParent(translationUnit); - pd - .setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); - translationUnit.addDeclaration(pd); - errorHandling(); - if (lastBacktrack != -1 - && lastBacktrack == LA(1).hashCode()) { - // we haven't progressed from the - // last backtrack - // try and find tne next definition - failParseWithErrorHandling(); - } else { - // start again from here - lastBacktrack = LA(1).hashCode(); - } - } catch (EndOfFileException e) { - break; - } - } catch (OutOfMemoryError oome) { - logThrowable("translationUnit", oome); //$NON-NLS-1$ - throw oome; - } catch (Exception e) { - logException("translationUnit", e); //$NON-NLS-1$ - try { - failParseWithErrorHandling(); - } catch (EndOfFileException e3) { - //nothing - } - } catch (ParseError perr) { - throw perr; - } catch (Throwable e) { - logThrowable("translationUnit", e); //$NON-NLS-1$ - try { - failParseWithErrorHandling(); - } catch (EndOfFileException e3) { - //break; - } + break; } - } - // compilationUnit.exitScope( requestor ); - } + } catch (OutOfMemoryError oome) { + logThrowable("translationUnit", oome); //$NON-NLS-1$ + throw oome; + } catch (Exception e) { + logException("translationUnit", e); //$NON-NLS-1$ + try { + failParseWithErrorHandling(); + } catch (EndOfFileException e3) { + //nothing + } + } catch (ParseError perr) { + throw perr; + } catch (Throwable e) { + logThrowable("translationUnit", e); //$NON-NLS-1$ + try { + failParseWithErrorHandling(); + } catch (EndOfFileException e3) { + //break; + } + } + } + // compilationUnit.exitScope( requestor ); + } - /** - * @return - */ - protected IASTProblemDeclaration createProblemDeclaration() { - return new CASTProblemDeclaration(); - } + /** + * @return + */ + protected IASTProblemDeclaration createProblemDeclaration() { + return new CASTProblemDeclaration(); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression assignmentExpression() throws EndOfFileException, - BacktrackException { - IASTExpression conditionalExpression = conditionalExpression(); - // if the condition not taken, try assignment operators - if (conditionalExpression != null - && conditionalExpression instanceof IASTConditionalExpression) //&& - return conditionalExpression; - switch (LT(1)) { - case IToken.tASSIGN: + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression assignmentExpression() throws EndOfFileException, + BacktrackException { + IASTExpression conditionalExpression = conditionalExpression(); + // if the condition not taken, try assignment operators + if (conditionalExpression != null + && conditionalExpression instanceof IASTConditionalExpression) //&& + return conditionalExpression; + switch (LT(1)) { + case IToken.tASSIGN: return assignmentOperatorExpression(IASTBinaryExpression.op_assign, - conditionalExpression); - case IToken.tSTARASSIGN: + conditionalExpression); + case IToken.tSTARASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_multiplyAssign, - conditionalExpression); - case IToken.tDIVASSIGN: + IASTBinaryExpression.op_multiplyAssign, conditionalExpression); + case IToken.tDIVASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_divideAssign, conditionalExpression); - case IToken.tMODASSIGN: + IASTBinaryExpression.op_divideAssign, conditionalExpression); + case IToken.tMODASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_moduloAssign, conditionalExpression); - case IToken.tPLUSASSIGN: + IASTBinaryExpression.op_moduloAssign, conditionalExpression); + case IToken.tPLUSASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_plusAssign, conditionalExpression); - case IToken.tMINUSASSIGN: + IASTBinaryExpression.op_plusAssign, conditionalExpression); + case IToken.tMINUSASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_minusAssign, conditionalExpression); - case IToken.tSHIFTRASSIGN: + IASTBinaryExpression.op_minusAssign, conditionalExpression); + case IToken.tSHIFTRASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_shiftRightAssign, - conditionalExpression); - case IToken.tSHIFTLASSIGN: + IASTBinaryExpression.op_shiftRightAssign, + conditionalExpression); + case IToken.tSHIFTLASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_shiftLeftAssign, - conditionalExpression); - case IToken.tAMPERASSIGN: + IASTBinaryExpression.op_shiftLeftAssign, + conditionalExpression); + case IToken.tAMPERASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_binaryAndAssign, - conditionalExpression); - case IToken.tXORASSIGN: + IASTBinaryExpression.op_binaryAndAssign, + conditionalExpression); + case IToken.tXORASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_binaryXorAssign, - conditionalExpression); - case IToken.tBITORASSIGN: + IASTBinaryExpression.op_binaryXorAssign, + conditionalExpression); + case IToken.tBITORASSIGN: return assignmentOperatorExpression( - IASTBinaryExpression.op_binaryOrAssign, - conditionalExpression); - } - return conditionalExpression; - } + IASTBinaryExpression.op_binaryOrAssign, conditionalExpression); + } + return conditionalExpression; + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression relationalExpression() throws BacktrackException, - EndOfFileException { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression relationalExpression() throws BacktrackException, + EndOfFileException { - IASTExpression firstExpression = shiftExpression(); - for (;;) { - switch (LT(1)) { + IASTExpression firstExpression = shiftExpression(); + for (;;) { + switch (LT(1)) { case IToken.tGT: case IToken.tLT: case IToken.tLTEQUAL: case IToken.tGTEQUAL: - int t = consume().getType(); - IASTExpression secondExpression = shiftExpression(); - int operator = 0; - switch (t) { - case IToken.tGT: - operator = IASTBinaryExpression.op_greaterThan; - break; - case IToken.tLT: - operator = IASTBinaryExpression.op_lessThan; - break; - case IToken.tLTEQUAL: - operator = IASTBinaryExpression.op_lessEqual; - break; - case IToken.tGTEQUAL: - operator = IASTBinaryExpression.op_greaterEqual; - break; - } - firstExpression = buildBinaryExpression(operator, - firstExpression, secondExpression); - break; + int t = consume().getType(); + IASTExpression secondExpression = shiftExpression(); + int operator = 0; + switch (t) { + case IToken.tGT: + operator = IASTBinaryExpression.op_greaterThan; + break; + case IToken.tLT: + operator = IASTBinaryExpression.op_lessThan; + break; + case IToken.tLTEQUAL: + operator = IASTBinaryExpression.op_lessEqual; + break; + case IToken.tGTEQUAL: + operator = IASTBinaryExpression.op_greaterEqual; + break; + } + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken.getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression multiplicativeExpression() - throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = castExpression(); - for (;;) { - switch (LT(1)) { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression multiplicativeExpression() + throws BacktrackException, EndOfFileException { + IASTExpression firstExpression = castExpression(); + for (;;) { + switch (LT(1)) { case IToken.tSTAR: case IToken.tDIV: case IToken.tMOD: - IToken t = consume(); - IASTExpression secondExpression = castExpression(); - int operator = 0; - switch (t.getType()) { - case IToken.tSTAR: - operator = IASTBinaryExpression.op_multiply; - break; - case IToken.tDIV: - operator = IASTBinaryExpression.op_divide; - break; - case IToken.tMOD: - operator = IASTBinaryExpression.op_modulo; - break; - } - firstExpression = buildBinaryExpression(operator, - firstExpression, secondExpression); - break; + IToken t = consume(); + IASTExpression secondExpression = castExpression(); + int operator = 0; + switch (t.getType()) { + case IToken.tSTAR: + operator = IASTBinaryExpression.op_multiply; + break; + case IToken.tDIV: + operator = IASTBinaryExpression.op_divide; + break; + case IToken.tMOD: + operator = IASTBinaryExpression.op_modulo; + break; + } + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken.getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * castExpression : unaryExpression | "(" typeId ")" castExpression - */ - protected IASTExpression castExpression() throws EndOfFileException, - BacktrackException { - // TO DO: we need proper symbol checkint to ensure type name - if (LT(1) == IToken.tLPAREN) { - IToken mark = mark(); - int startingOffset = mark.getOffset(); - consume(); - IASTTypeId typeId = null; - IASTExpression castExpression = null; - // If this isn't a type name, then we shouldn't be here + /** + * castExpression : unaryExpression | "(" typeId ")" castExpression + */ + protected IASTExpression castExpression() throws EndOfFileException, + BacktrackException { + // TO DO: we need proper symbol checkint to ensure type name + if (LT(1) == IToken.tLPAREN) { + IToken mark = mark(); + int startingOffset = mark.getOffset(); + consume(); + IASTTypeId typeId = null; + IASTExpression castExpression = null; + // If this isn't a type name, then we shouldn't be here + try { try { - try { - typeId = typeId(false); - consume(IToken.tRPAREN); - castExpression = castExpression(); - } catch (BacktrackException bte) { - backup(mark); - throwBacktrack(bte); - } - - return buildTypeIdUnaryExpression(IASTCastExpression.op_cast, - typeId, castExpression, startingOffset); - } catch (BacktrackException b) { + typeId = typeId(false); + consume(IToken.tRPAREN); + castExpression = castExpression(); + } catch (BacktrackException bte) { + backup(mark); + throwBacktrack(bte); } - } - return unaryExpression(); - } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression unaryExpression() throws EndOfFileException, - BacktrackException { - int startingOffset = LA(1).getOffset(); - switch (LT(1)) { - case IToken.tSTAR: + return buildTypeIdUnaryExpression(IASTCastExpression.op_cast, + typeId, castExpression, startingOffset, calculateEndOffset(castExpression)); + } catch (BacktrackException b) { + } + } + return unaryExpression(); + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression unaryExpression() throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + switch (LT(1)) { + case IToken.tSTAR: return unaryOperatorCastExpression(IASTUnaryExpression.op_star); - case IToken.tAMPER: + case IToken.tAMPER: return unaryOperatorCastExpression(IASTUnaryExpression.op_amper); - case IToken.tPLUS: + case IToken.tPLUS: return unaryOperatorCastExpression(IASTUnaryExpression.op_plus); - case IToken.tMINUS: + case IToken.tMINUS: return unaryOperatorCastExpression(IASTUnaryExpression.op_minus); - case IToken.tNOT: + case IToken.tNOT: return unaryOperatorCastExpression(IASTUnaryExpression.op_not); - case IToken.tCOMPL: + case IToken.tCOMPL: return unaryOperatorCastExpression(IASTUnaryExpression.op_tilde); - case IToken.tINCR: + case IToken.tINCR: return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixIncr); - case IToken.tDECR: + case IToken.tDECR: return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr); - case IToken.t_sizeof: + case IToken.t_sizeof: startingOffset = consume(IToken.t_sizeof).getOffset(); IToken mark = LA(1); IASTExpression unaryExpression = null; IASTTypeId typeId = null; + int lastOffset = 0; if (LT(1) == IToken.tLPAREN) { - try { - consume(IToken.tLPAREN); - typeId = typeId(false); - consume(IToken.tRPAREN); - } catch (BacktrackException bt) { - backup(mark); - typeId = null; - unaryExpression = unaryExpression(); - } + try { + consume(IToken.tLPAREN); + typeId = typeId(false); + lastOffset = consume(IToken.tRPAREN).getEndOffset(); + } catch (BacktrackException bt) { + backup(mark); + typeId = null; + unaryExpression = unaryExpression(); + } } else { - unaryExpression = unaryExpression(); + unaryExpression = unaryExpression(); + lastOffset = lastToken.getEndOffset(); } mark = null; if (typeId == null && unaryExpression != null) - return buildUnaryExpression(IASTUnaryExpression.op_sizeof, - unaryExpression, startingOffset); + return buildUnaryExpression(IASTUnaryExpression.op_sizeof, + unaryExpression, startingOffset, lastToken.getEndOffset()); return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof, - typeId, startingOffset); + typeId, startingOffset, lastOffset); - default: + default: if (LT(1) == IGCCToken.t_typeof && supportTypeOfUnaries) { - IASTExpression unary = unaryTypeofExpression(); - if (unary != null) - return unary; + IASTExpression unary = unaryTypeofExpression(); + if (unary != null) + return unary; } if (LT(1) == IGCCToken.t___alignof__ && supportAlignOfUnaries) { - IASTExpression align = unaryAlignofExpression(); - if (align != null) - return align; + IASTExpression align = unaryAlignofExpression(); + if (align != null) + return align; } return postfixExpression(); - } - } + } + } - /** - * @param op_sizeof - * @param typeId - * @param startingOffset - * @return - */ - protected IASTExpression buildTypeIdExpression(int op_sizeof, - IASTTypeId typeId, int startingOffset) { - IASTTypeIdExpression result = createTypeIdExpression(); - result.setOperator(op_sizeof); - ((ASTNode) result).setOffset(startingOffset); - result.setTypeId(typeId); - typeId.setParent(result); - typeId.setPropertyInParent(IASTTypeIdExpression.TYPE_ID); - return result; - } + /** + * @param typeId + * @param startingOffset + * @param op + * @return + */ + protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId, + int startingOffset, int endingOffset) { + IASTTypeIdExpression result = createTypeIdExpression(); + result.setOperator(op); + ((ASTNode) result).setOffsetAndLength(startingOffset, endingOffset - startingOffset); + ((ASTNode) result).setLength(endingOffset - startingOffset); + result.setTypeId(typeId); + typeId.setParent(result); + typeId.setPropertyInParent(IASTTypeIdExpression.TYPE_ID); + return result; + } - /** - * @return - */ - protected IASTTypeIdExpression createTypeIdExpression() { - return new CASTTypeIdExpression(); - } + /** + * @return + */ + protected IASTTypeIdExpression createTypeIdExpression() { + return new CASTTypeIdExpression(); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression postfixExpression() throws EndOfFileException, - BacktrackException { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression postfixExpression() throws EndOfFileException, + BacktrackException { - IASTExpression firstExpression = null; - switch (LT(1)) { - case IToken.tLPAREN: + IASTExpression firstExpression = null; + switch (LT(1)) { + case IToken.tLPAREN: // ( type-name ) { initializer-list } // ( type-name ) { initializer-list , } IToken m = mark(); try { - int offset = consume(IToken.tLPAREN).getOffset(); - IASTTypeId t = typeId(false); - consume(IToken.tRPAREN); - IASTInitializer i = cInitializerClause(Collections.EMPTY_LIST); - firstExpression = buildTypeIdInitializerExpression(t, i, offset); - break; + int offset = consume(IToken.tLPAREN).getOffset(); + IASTTypeId t = typeId(false); + int lastOffset = consume(IToken.tRPAREN).getEndOffset(); + IASTInitializer i = cInitializerClause(Collections.EMPTY_LIST); + firstExpression = buildTypeIdInitializerExpression(t, i, offset, lastOffset); + break; } catch (BacktrackException bt) { - backup(m); + backup(m); } - default: + default: firstExpression = primaryExpression(); - } + } - IASTExpression secondExpression = null; - for (;;) { - switch (LT(1)) { + IASTExpression secondExpression = null; + for (;;) { + switch (LT(1)) { case IToken.tLBRACKET: - // array access - consume(IToken.tLBRACKET); - secondExpression = expression(); - consume(IToken.tRBRACKET); - IASTArraySubscriptExpression s = createArraySubscriptExpression(); - ((ASTNode) s) - .setOffset(((ASTNode) firstExpression).getOffset()); - s.setArrayExpression(firstExpression); - firstExpression.setParent(s); - firstExpression - .setPropertyInParent(IASTArraySubscriptExpression.ARRAY); - s.setSubscriptExpression(secondExpression); - secondExpression.setParent(s); - secondExpression - .setPropertyInParent(IASTArraySubscriptExpression.SUBSCRIPT); - firstExpression = s; - break; + // array access + consume(IToken.tLBRACKET); + secondExpression = expression(); + int last = consume(IToken.tRBRACKET).getEndOffset(); + IASTArraySubscriptExpression s = createArraySubscriptExpression(); + ((ASTNode) s).setOffsetAndLength(((ASTNode) firstExpression) + .getOffset(), last - ((ASTNode) firstExpression) + .getOffset()); + s.setArrayExpression(firstExpression); + firstExpression.setParent(s); + firstExpression + .setPropertyInParent(IASTArraySubscriptExpression.ARRAY); + s.setSubscriptExpression(secondExpression); + secondExpression.setParent(s); + secondExpression + .setPropertyInParent(IASTArraySubscriptExpression.SUBSCRIPT); + firstExpression = s; + break; case IToken.tLPAREN: - // function call - consume(IToken.tLPAREN); - if (LT(1) != IToken.tRPAREN) - secondExpression = expression(); - consume(IToken.tRPAREN); - IASTFunctionCallExpression f = createFunctionCallExpression(); - ((ASTNode) f) - .setOffset(((ASTNode) firstExpression).getOffset()); - f.setFunctionNameExpression(firstExpression); - firstExpression.setParent(f); - firstExpression - .setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME); + // function call + consume(IToken.tLPAREN); + if (LT(1) != IToken.tRPAREN) + secondExpression = expression(); + last = consume(IToken.tRPAREN).getEndOffset(); + IASTFunctionCallExpression f = createFunctionCallExpression(); + ((ASTNode) f).setOffsetAndLength(((ASTNode) firstExpression) + .getOffset(), last - ((ASTNode) firstExpression) + .getOffset()); + f.setFunctionNameExpression(firstExpression); + firstExpression.setParent(f); + firstExpression + .setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME); - if (secondExpression != null) { - f.setParameterExpression(secondExpression); - secondExpression.setParent(f); - secondExpression - .setPropertyInParent(IASTFunctionCallExpression.PARAMETERS); - } - firstExpression = f; - break; + if (secondExpression != null) { + f.setParameterExpression(secondExpression); + secondExpression.setParent(f); + secondExpression + .setPropertyInParent(IASTFunctionCallExpression.PARAMETERS); + } + firstExpression = f; + break; case IToken.tINCR: - int offset = consume(IToken.tINCR).getOffset(); - firstExpression = buildUnaryExpression( - IASTUnaryExpression.op_postFixIncr, firstExpression, - offset); - break; + int offset = consume(IToken.tINCR).getEndOffset(); + firstExpression = buildUnaryExpression( + IASTUnaryExpression.op_postFixIncr, firstExpression, + ((CASTNode)firstExpression).getOffset(), offset); + break; case IToken.tDECR: - offset = consume().getOffset(); - firstExpression = buildUnaryExpression( - IASTUnaryExpression.op_postFixDecr, firstExpression, - offset); - break; + offset = consume().getEndOffset(); + firstExpression = buildUnaryExpression( + IASTUnaryExpression.op_postFixDecr, firstExpression, + ((CASTNode)firstExpression).getOffset(), offset); + break; case IToken.tDOT: - // member access - consume(IToken.tDOT); - IASTName name = createName(identifier()); - IASTFieldReference result = createFieldReference(); - ((ASTNode) result).setOffset(((ASTNode) firstExpression) - .getOffset()); - result.setFieldOwner(firstExpression); - result.setIsPointerDereference(false); - firstExpression.setParent(result); - firstExpression - .setPropertyInParent(IASTFieldReference.FIELD_OWNER); - result.setFieldName(name); - name.setParent(result); - name.setPropertyInParent(IASTFieldReference.FIELD_NAME); - firstExpression = result; - break; + // member access + consume(IToken.tDOT); + IASTName name = createName(identifier()); + IASTFieldReference result = createFieldReference(); + ((ASTNode) result).setOffsetAndLength( + ((ASTNode) firstExpression).getOffset(), lastToken.getEndOffset() - ((ASTNode) firstExpression).getOffset()); + result.setFieldOwner(firstExpression); + result.setIsPointerDereference(false); + firstExpression.setParent(result); + firstExpression + .setPropertyInParent(IASTFieldReference.FIELD_OWNER); + result.setFieldName(name); + name.setParent(result); + name.setPropertyInParent(IASTFieldReference.FIELD_NAME); + firstExpression = result; + break; case IToken.tARROW: - // member access - consume(IToken.tARROW); - name = createName(identifier()); - result = createFieldReference(); - ((ASTNode) result).setOffset(((ASTNode) firstExpression) - .getOffset()); - result.setFieldOwner(firstExpression); - result.setIsPointerDereference(true); - firstExpression.setParent(result); - firstExpression - .setPropertyInParent(IASTFieldReference.FIELD_OWNER); - result.setFieldName(name); - name.setParent(result); - name.setPropertyInParent(IASTFieldReference.FIELD_NAME); - firstExpression = result; - break; + // member access + consume(IToken.tARROW); + name = createName(identifier()); + result = createFieldReference(); + ((ASTNode) result).setOffsetAndLength( + ((ASTNode) firstExpression).getOffset(), lastToken.getEndOffset() - ((ASTNode) firstExpression).getOffset()); + result.setFieldOwner(firstExpression); + result.setIsPointerDereference(true); + firstExpression.setParent(result); + firstExpression + .setPropertyInParent(IASTFieldReference.FIELD_OWNER); + result.setFieldName(name); + name.setParent(result); + name.setPropertyInParent(IASTFieldReference.FIELD_NAME); + firstExpression = result; + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @return - */ - protected IASTFunctionCallExpression createFunctionCallExpression() { - return new CASTFunctionCallExpression(); - } + /** + * @return + */ + protected IASTFunctionCallExpression createFunctionCallExpression() { + return new CASTFunctionCallExpression(); + } - /** - * @return - */ - protected IASTArraySubscriptExpression createArraySubscriptExpression() { - return new CASTArraySubscriptExpression(); - } + /** + * @return + */ + protected IASTArraySubscriptExpression createArraySubscriptExpression() { + return new CASTArraySubscriptExpression(); + } - /** - * @param t - * @param i - * @param offset - * @return - */ - protected ICASTTypeIdInitializerExpression buildTypeIdInitializerExpression( - IASTTypeId t, IASTInitializer i, int offset) { - ICASTTypeIdInitializerExpression result = createTypeIdInitializerExpression(); - ((ASTNode) result).setOffset(offset); - result.setTypeId(t); - t.setParent(result); - t.setPropertyInParent(ICASTTypeIdInitializerExpression.TYPE_ID); - result.setInitializer(i); - i.setParent(result); - i.setPropertyInParent(ICASTTypeIdInitializerExpression.INITIALIZER); - return result; - } + /** + * @param t + * @param i + * @param offset + * @param lastOffset TODO + * @return + */ + protected ICASTTypeIdInitializerExpression buildTypeIdInitializerExpression( + IASTTypeId t, IASTInitializer i, int offset, int lastOffset) { + ICASTTypeIdInitializerExpression result = createTypeIdInitializerExpression(); + ((ASTNode) result).setOffsetAndLength(offset, lastOffset - offset); + result.setTypeId(t); + t.setParent(result); + t.setPropertyInParent(ICASTTypeIdInitializerExpression.TYPE_ID); + result.setInitializer(i); + i.setParent(result); + i.setPropertyInParent(ICASTTypeIdInitializerExpression.INITIALIZER); + return result; + } - /** - * @return - */ - protected ICASTTypeIdInitializerExpression createTypeIdInitializerExpression() { - return new CASTTypeIdInitializerExpression(); - } + /** + * @return + */ + protected ICASTTypeIdInitializerExpression createTypeIdInitializerExpression() { + return new CASTTypeIdInitializerExpression(); + } - /** - * @return - */ - protected IASTFieldReference createFieldReference() { - return new CASTFieldReference(); - } + /** + * @return + */ + protected IASTFieldReference createFieldReference() { + return new CASTFieldReference(); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression primaryExpression() throws EndOfFileException, - BacktrackException { - IToken t = null; - IASTLiteralExpression literalExpression = null; - switch (LT(1)) { - // TO DO: we need more literals... - case IToken.tINTEGER: + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression primaryExpression() throws EndOfFileException, + BacktrackException { + IToken t = null; + IASTLiteralExpression literalExpression = null; + switch (LT(1)) { + // TO DO: we need more literals... + case IToken.tINTEGER: t = consume(); literalExpression = createLiteralExpression(); literalExpression - .setKind(IASTLiteralExpression.lk_integer_constant); + .setKind(IASTLiteralExpression.lk_integer_constant); literalExpression.setValue(t.getImage()); - ((ASTNode) literalExpression).setOffset(t.getOffset()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); return literalExpression; - case IToken.tFLOATINGPT: + case IToken.tFLOATINGPT: t = consume(); literalExpression = createLiteralExpression(); literalExpression.setKind(IASTLiteralExpression.lk_float_constant); literalExpression.setValue(t.getImage()); - ((ASTNode) literalExpression).setOffset(t.getOffset()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); return literalExpression; - case IToken.tSTRING: - case IToken.tLSTRING: + case IToken.tSTRING: + case IToken.tLSTRING: t = consume(); literalExpression = createLiteralExpression(); literalExpression.setKind(IASTLiteralExpression.lk_string_literal); literalExpression.setValue(t.getImage()); - ((ASTNode) literalExpression).setOffset(t.getOffset()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); return literalExpression; - case IToken.tCHAR: - case IToken.tLCHAR: + case IToken.tCHAR: + case IToken.tLCHAR: t = consume(); literalExpression = createLiteralExpression(); literalExpression.setKind(IASTLiteralExpression.lk_char_constant); literalExpression.setValue(t.getImage()); - ((ASTNode) literalExpression).setOffset(t.getOffset()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); return literalExpression; - case IToken.tLPAREN: + case IToken.tLPAREN: t = consume(); //TODO - do we need to return a wrapper? IASTExpression lhs = expression(); consume(IToken.tRPAREN); return lhs; - case IToken.tIDENTIFIER: + case IToken.tIDENTIFIER: int startingOffset = LA(1).getOffset(); IToken t1 = identifier(); @@ -1085,1149 +1103,1150 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { name.setParent(idExpression); name.setPropertyInParent(IASTIdExpression.ID_NAME); return idExpression; - default: + default: IToken la = LA(1); startingOffset = la.getOffset(); throwBacktrack(startingOffset, la.getLength()); return null; - } + } - } + } - /** - * @return - */ - protected IASTLiteralExpression createLiteralExpression() { - return new CASTLiteralExpression(); - } + /** + * @return + */ + protected IASTLiteralExpression createLiteralExpression() { + return new CASTLiteralExpression(); + } - /** - * @return - */ - protected IASTIdExpression createIdExpression() { - return new CASTIdExpression(); - } + /** + * @return + */ + protected IASTIdExpression createIdExpression() { + return new CASTIdExpression(); + } - protected IASTTypeId typeId(boolean skipArrayModifiers) - throws EndOfFileException, BacktrackException { - IToken mark = mark(); - int startingOffset = mark.getOffset(); - IASTDeclSpecifier declSpecifier = null; - IASTDeclarator declarator = null; + protected IASTTypeId typeId(boolean skipArrayModifiers) + throws EndOfFileException, BacktrackException { + IToken mark = mark(); + int startingOffset = mark.getOffset(); + IASTDeclSpecifier declSpecifier = null; + IASTDeclarator declarator = null; - try { - declSpecifier = declSpecifierSeq(false); - declarator = declarator(); - } catch (BacktrackException bt) { - int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); + try { + declSpecifier = declSpecifierSeq(false); + declarator = declarator(); + } catch (BacktrackException bt) { + int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); + backup(mark); + throwBacktrack(startingOffset, endingOffset - startingOffset); + } + if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$ + { + int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); + backup(mark); + throwBacktrack(startingOffset, endingOffset - startingOffset); + } + + IASTTypeId result = createTypeId(); + int length = (lastToken != null ) ? lastToken.getEndOffset() - startingOffset : 0; + ((ASTNode) result).setOffsetAndLength(startingOffset, length); + + result.setDeclSpecifier(declSpecifier); + declSpecifier.setParent(result); + declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER); + + result.setAbstractDeclarator(declarator); + declarator.setParent(result); + declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR); + + return result; + } + + /** + * @return + */ + protected IASTTypeId createTypeId() { + return new CASTTypeId(); + } + + /** + * Parse a Pointer Operator. + * + * ptrOperator : "*" (cvQualifier)* | "&" | ::? nestedNameSpecifier "*" + * (cvQualifier)* + * + * @param owner + * Declarator that this pointer operator corresponds to. + * @throws BacktrackException + * request a backtrack + */ + protected void consumePointerOperators(List pointerOps) + throws EndOfFileException, BacktrackException { + for (;;) { + IToken mark = mark(); + + boolean isConst = false, isVolatile = false, isRestrict = false; + + if (LT(1) != IToken.tSTAR) { backup(mark); - throwBacktrack(startingOffset, endingOffset - startingOffset); - } - if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$ - { - int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); - backup(mark); - throwBacktrack(startingOffset, endingOffset - startingOffset); - } + break; + } - IASTTypeId result = createTypeId(); - ((ASTNode) result).setOffset(startingOffset); - - result.setDeclSpecifier(declSpecifier); - declSpecifier.setParent(result); - declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER); - - result.setAbstractDeclarator(declarator); - declarator.setParent(result); - declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR); - - return result; - } - - /** - * @return - */ - protected IASTTypeId createTypeId() { - return new CASTTypeId(); - } - - /** - * Parse a Pointer Operator. - * - * ptrOperator : "*" (cvQualifier)* | "&" | ::? nestedNameSpecifier "*" - * (cvQualifier)* - * - * @param owner - * Declarator that this pointer operator corresponds to. - * @throws BacktrackException - * request a backtrack - */ - protected void consumePointerOperators(List pointerOps) - throws EndOfFileException, BacktrackException { - for (;;) { - IToken mark = mark(); - - boolean isConst = false, isVolatile = false, isRestrict = false; - - if (LT(1) != IToken.tSTAR) { - backup(mark); - break; - } - - consume(IToken.tSTAR); - int startOffset = mark.getOffset(); - for (;;) { - IToken t = LA(1); - switch (LT(1)) { - case IToken.t_const: - consume(IToken.t_const); - isConst = true; - break; - case IToken.t_volatile: - consume(IToken.t_volatile); - isVolatile = true; - break; - case IToken.t_restrict: - consume(IToken.t_restrict); - isRestrict = true; - break; - } - - if (t == LA(1)) - break; - } - - IASTPointerOperator po = createPointer(); - ((ASTNode) po).setOffset(startOffset); - ((ICASTPointer) po).setConst(isConst); - ((ICASTPointer) po).setVolatile(isVolatile); - ((ICASTPointer) po).setRestrict(isRestrict); - pointerOps.add(po); - } - } - - /** - * @return - */ - protected ICASTPointer createPointer() { - return new CASTPointer(); - } - - protected IASTDeclSpecifier declSpecifierSeq(boolean parm) - throws BacktrackException, EndOfFileException { - Flags flags = new Flags(parm); - - int startingOffset = LA(1).getOffset(); - int storageClass = IASTDeclSpecifier.sc_unspecified; - boolean isInline = false; - boolean isConst = false, isRestrict = false, isVolatile = false; - boolean isShort = false, isLong = false, isUnsigned = false, isIdentifier = false, isSigned = false, isLongLong = false; - int simpleType = IASTSimpleDeclSpecifier.t_unspecified; - IToken identifier = null; - IASTCompositeTypeSpecifier structSpec = null; - IASTElaboratedTypeSpecifier elabSpec = null; - IASTEnumerationSpecifier enumSpec = null; - boolean isTypedef = false; - - declSpecifiers: for (;;) { + consume(IToken.tSTAR); + int startOffset = mark.getOffset(); + for (;;) { + IToken t = LA(1); switch (LT(1)) { + case IToken.t_const: + consume(IToken.t_const); + isConst = true; + break; + case IToken.t_volatile: + consume(IToken.t_volatile); + isVolatile = true; + break; + case IToken.t_restrict: + consume(IToken.t_restrict); + isRestrict = true; + break; + } + + if (t == LA(1)) + break; + } + + IASTPointerOperator po = createPointer(); + ((ASTNode) po).setOffsetAndLength(startOffset, lastToken.getEndOffset() - startOffset); + ((ICASTPointer) po).setConst(isConst); + ((ICASTPointer) po).setVolatile(isVolatile); + ((ICASTPointer) po).setRestrict(isRestrict); + pointerOps.add(po); + } + } + + /** + * @return + */ + protected ICASTPointer createPointer() { + return new CASTPointer(); + } + + protected IASTDeclSpecifier declSpecifierSeq(boolean parm) + throws BacktrackException, EndOfFileException { + Flags flags = new Flags(parm); + + int startingOffset = LA(1).getOffset(); + int storageClass = IASTDeclSpecifier.sc_unspecified; + boolean isInline = false; + boolean isConst = false, isRestrict = false, isVolatile = false; + boolean isShort = false, isLong = false, isUnsigned = false, isIdentifier = false, isSigned = false, isLongLong = false; + int simpleType = IASTSimpleDeclSpecifier.t_unspecified; + IToken identifier = null; + IASTCompositeTypeSpecifier structSpec = null; + IASTElaboratedTypeSpecifier elabSpec = null; + IASTEnumerationSpecifier enumSpec = null; + boolean isTypedef = false; + + declSpecifiers: for (;;) { + switch (LT(1)) { //Storage Class Specifiers case IToken.t_auto: - consume(); - storageClass = IASTDeclSpecifier.sc_auto; - break; + consume(); + storageClass = IASTDeclSpecifier.sc_auto; + break; case IToken.t_register: - storageClass = IASTDeclSpecifier.sc_register; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_register; + consume(); + break; case IToken.t_static: - storageClass = IASTDeclSpecifier.sc_static; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_static; + consume(); + break; case IToken.t_extern: - storageClass = IASTDeclSpecifier.sc_extern; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_extern; + consume(); + break; case IToken.t_typedef: - isTypedef = true; - storageClass = IASTDeclSpecifier.sc_typedef; - consume(); - break; + isTypedef = true; + storageClass = IASTDeclSpecifier.sc_typedef; + consume(); + break; //Function Specifier case IToken.t_inline: - isInline = true; - consume(); - break; + isInline = true; + consume(); + break; //Type Qualifiers case IToken.t_const: - isConst = true; - consume(); - break; + isConst = true; + consume(); + break; case IToken.t_volatile: - isVolatile = true; - consume(); - break; + isVolatile = true; + consume(); + break; case IToken.t_restrict: - isRestrict = true; - consume(); - break; + isRestrict = true; + consume(); + break; //Type Specifiers case IToken.t_void: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_void; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_void; + break; case IToken.t_char: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_char; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_char; + break; case IToken.t_short: - flags.setEncounteredRawType(true); - consume(); - isShort = true; - break; + flags.setEncounteredRawType(true); + consume(); + isShort = true; + break; case IToken.t_int: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_int; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_int; + break; case IToken.t_long: - flags.setEncounteredRawType(true); - consume(); - if (isLong) { - isLongLong = true; - isLong = false; - } else - isLong = true; - break; + flags.setEncounteredRawType(true); + consume(); + if (isLong) { + isLongLong = true; + isLong = false; + } else + isLong = true; + break; case IToken.t_float: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_float; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_float; + break; case IToken.t_double: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_double; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_double; + break; case IToken.t_signed: - flags.setEncounteredRawType(true); - consume(); - isSigned = true; - break; + flags.setEncounteredRawType(true); + consume(); + isSigned = true; + break; case IToken.t_unsigned: - flags.setEncounteredRawType(true); - consume(); - isUnsigned = true; - break; + flags.setEncounteredRawType(true); + consume(); + isUnsigned = true; + break; case IToken.t__Bool: - flags.setEncounteredRawType(true); - consume(); - simpleType = ICASTSimpleDeclSpecifier.t_Bool; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = ICASTSimpleDeclSpecifier.t_Bool; + break; case IToken.t__Complex: - consume(IToken.t__Complex); - simpleType = ICASTSimpleDeclSpecifier.t_Complex; - break; + consume(IToken.t__Complex); + simpleType = ICASTSimpleDeclSpecifier.t_Complex; + break; case IToken.t__Imaginary: - consume(IToken.t__Imaginary); - simpleType = ICASTSimpleDeclSpecifier.t_Imaginary; - break; + consume(IToken.t__Imaginary); + simpleType = ICASTSimpleDeclSpecifier.t_Imaginary; + break; case IToken.tIDENTIFIER: - // TODO - Kludgy way to handle constructors/destructors - if (flags.haveEncounteredRawType()) { - break declSpecifiers; - } - if (parm && flags.haveEncounteredTypename()) { - break declSpecifiers; - } - if (lookAheadForDeclarator(flags)) { - break declSpecifiers; - } - switch (LT(2)) { - case IToken.tLPAREN: - if (isTypedef) + // TODO - Kludgy way to handle constructors/destructors + if (flags.haveEncounteredRawType()) { + break declSpecifiers; + } + if (parm && flags.haveEncounteredTypename()) { + break declSpecifiers; + } + if (lookAheadForDeclarator(flags)) { + break declSpecifiers; + } + switch (LT(2)) { + case IToken.tLPAREN: + if (isTypedef) break; - case IToken.tSEMI: - case IToken.tASSIGN: - //TODO more - break declSpecifiers; - } + case IToken.tSEMI: + case IToken.tASSIGN: + //TODO more + break declSpecifiers; + } - identifier = identifier(); - isIdentifier = true; - flags.setEncounteredTypename(true); - break; + identifier = identifier(); + isIdentifier = true; + flags.setEncounteredTypename(true); + break; case IToken.t_struct: case IToken.t_union: - try { - structSpec = structOrUnionSpecifier(); - flags.setEncounteredTypename(true); - break; - } catch (BacktrackException bt) { - elabSpec = elaboratedTypeSpecifier(); - flags.setEncounteredTypename(true); - break; - } + try { + structSpec = structOrUnionSpecifier(); + flags.setEncounteredTypename(true); + break; + } catch (BacktrackException bt) { + elabSpec = elaboratedTypeSpecifier(); + flags.setEncounteredTypename(true); + break; + } case IToken.t_enum: - try { - enumSpec = enumSpecifier(); - flags.setEncounteredTypename(true); - break; - } catch (BacktrackException bt) { - // this is an elaborated class specifier - elabSpec = elaboratedTypeSpecifier(); - flags.setEncounteredTypename(true); - break; - } + try { + enumSpec = enumSpecifier(); + flags.setEncounteredTypename(true); + break; + } catch (BacktrackException bt) { + // this is an elaborated class specifier + elabSpec = elaboratedTypeSpecifier(); + flags.setEncounteredTypename(true); + break; + } default: - if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { - Object expression = unaryTypeofExpression(); - if (expression != null) { - flags.setEncounteredTypename(true); - } - } - break declSpecifiers; - } - } + if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { + Object expression = unaryTypeofExpression(); + if (expression != null) { + flags.setEncounteredTypename(true); + } + } + break declSpecifiers; + } + } - if (structSpec != null) { - ((ASTNode) structSpec).setOffset(startingOffset); - structSpec.setConst(isConst); - ((ICASTCompositeTypeSpecifier) structSpec).setRestrict(isRestrict); - structSpec.setVolatile(isVolatile); - structSpec.setInline(isInline); - structSpec.setStorageClass(storageClass); + if (structSpec != null) { + ((ASTNode) structSpec).setOffsetAndLength(startingOffset, lastToken.getEndOffset() - startingOffset); + structSpec.setConst(isConst); + ((ICASTCompositeTypeSpecifier) structSpec).setRestrict(isRestrict); + structSpec.setVolatile(isVolatile); + structSpec.setInline(isInline); + structSpec.setStorageClass(storageClass); - return structSpec; - } + return structSpec; + } - if (enumSpec != null) { - ((ASTNode) enumSpec).setOffset(startingOffset); - enumSpec.setConst(isConst); - ((CASTEnumerationSpecifier) enumSpec).setRestrict(isRestrict); - enumSpec.setVolatile(isVolatile); - enumSpec.setInline(isInline); - enumSpec.setStorageClass(storageClass); - return enumSpec; + if (enumSpec != null) { + ((ASTNode) enumSpec).setOffsetAndLength(startingOffset, lastToken.getEndOffset() - startingOffset); + enumSpec.setConst(isConst); + ((CASTEnumerationSpecifier) enumSpec).setRestrict(isRestrict); + enumSpec.setVolatile(isVolatile); + enumSpec.setInline(isInline); + enumSpec.setStorageClass(storageClass); + return enumSpec; - } - if (elabSpec != null) { - ((ASTNode) elabSpec).setOffset(startingOffset); - elabSpec.setConst(isConst); - ((CASTElaboratedTypeSpecifier) elabSpec).setRestrict(isRestrict); - elabSpec.setVolatile(isVolatile); - elabSpec.setInline(isInline); - elabSpec.setStorageClass(storageClass); + } + if (elabSpec != null) { + ((ASTNode) elabSpec).setOffsetAndLength(startingOffset, lastToken.getEndOffset() - startingOffset); + elabSpec.setConst(isConst); + ((CASTElaboratedTypeSpecifier) elabSpec).setRestrict(isRestrict); + elabSpec.setVolatile(isVolatile); + elabSpec.setInline(isInline); + elabSpec.setStorageClass(storageClass); - return elabSpec; - } - if (isIdentifier) { - ICASTTypedefNameSpecifier declSpec = createNamedTypeSpecifier(); - declSpec.setConst(isConst); - declSpec.setRestrict(isRestrict); - declSpec.setVolatile(isVolatile); - declSpec.setInline(isInline); - declSpec.setStorageClass(storageClass); + return elabSpec; + } + if (isIdentifier) { + ICASTTypedefNameSpecifier declSpec = createNamedTypeSpecifier(); + declSpec.setConst(isConst); + declSpec.setRestrict(isRestrict); + declSpec.setVolatile(isVolatile); + declSpec.setInline(isInline); + declSpec.setStorageClass(storageClass); - ((ASTNode) declSpec).setOffset(startingOffset); - IASTName name = createName(identifier); - declSpec.setName(name); - name.setParent(declSpec); - name.setPropertyInParent(IASTNamedTypeSpecifier.NAME); - return declSpec; - } - ICASTSimpleDeclSpecifier declSpec = createSimpleTypeSpecifier(); - declSpec.setConst(isConst); - declSpec.setRestrict(isRestrict); - declSpec.setVolatile(isVolatile); - declSpec.setInline(isInline); - declSpec.setStorageClass(storageClass); + ((ASTNode) declSpec).setOffsetAndLength(startingOffset, lastToken.getEndOffset() - startingOffset); + IASTName name = createName(identifier); + declSpec.setName(name); + name.setParent(declSpec); + name.setPropertyInParent(IASTNamedTypeSpecifier.NAME); + return declSpec; + } + ICASTSimpleDeclSpecifier declSpec = createSimpleTypeSpecifier(); + declSpec.setConst(isConst); + declSpec.setRestrict(isRestrict); + declSpec.setVolatile(isVolatile); + declSpec.setInline(isInline); + declSpec.setStorageClass(storageClass); - declSpec.setType(simpleType); - declSpec.setLong(isLong); - declSpec.setLongLong(isLongLong); - declSpec.setUnsigned(isUnsigned); - declSpec.setSigned(isSigned); - declSpec.setShort(isShort); + declSpec.setType(simpleType); + declSpec.setLong(isLong); + declSpec.setLongLong(isLongLong); + declSpec.setUnsigned(isUnsigned); + declSpec.setSigned(isSigned); + declSpec.setShort(isShort); + int length = ( lastToken != null ) ? lastToken.getEndOffset() - startingOffset : 0 ; + ((ASTNode) declSpec).setOffsetAndLength(startingOffset, length ); + return declSpec; + } - ((ASTNode) declSpec).setOffset(startingOffset); - return declSpec; - } + /** + * @return + */ + protected ICASTSimpleDeclSpecifier createSimpleTypeSpecifier() { + return new CASTSimpleDeclSpecifier(); + } - /** - * @return - */ - protected ICASTSimpleDeclSpecifier createSimpleTypeSpecifier() { - return new CASTSimpleDeclSpecifier(); - } + /** + * @return + */ + protected ICASTTypedefNameSpecifier createNamedTypeSpecifier() { + return new CASTTypedefNameSpecifier(); + } - /** - * @return - */ - protected ICASTTypedefNameSpecifier createNamedTypeSpecifier() { - return new CASTTypedefNameSpecifier(); - } + /** + * Parse a class/struct/union definition. + * + * classSpecifier : classKey name (baseClause)? "{" (memberSpecification)* + * "}" + * + * @param owner + * IParserCallback object that represents the declaration that owns + * this classSpecifier + * + * @return TODO + * @throws BacktrackException + * request a backtrack + */ + protected ICASTCompositeTypeSpecifier structOrUnionSpecifier() + throws BacktrackException, EndOfFileException { - /** - * Parse a class/struct/union definition. - * - * classSpecifier : classKey name (baseClause)? "{" (memberSpecification)* - * "}" - * - * @param owner - * IParserCallback object that represents the declaration that - * owns this classSpecifier - * - * @return TODO - * @throws BacktrackException - * request a backtrack - */ - protected ICASTCompositeTypeSpecifier structOrUnionSpecifier() - throws BacktrackException, EndOfFileException { + int classKind = 0; + IToken classKey = null; + IToken mark = mark(); - int classKind = 0; - IToken classKey = null; - IToken mark = mark(); - - // class key - switch (LT(1)) { - case IToken.t_struct: + // class key + switch (LT(1)) { + case IToken.t_struct: classKey = consume(); classKind = IASTCompositeTypeSpecifier.k_struct; break; - case IToken.t_union: + case IToken.t_union: classKey = consume(); classKind = IASTCompositeTypeSpecifier.k_union; break; - default: + default: throwBacktrack(mark.getOffset(), mark.getLength()); - } + } - IToken nameToken = null; - // class name - if (LT(1) == IToken.tIDENTIFIER) { - nameToken = identifier(); - } + IToken nameToken = null; + // class name + if (LT(1) == IToken.tIDENTIFIER) { + nameToken = identifier(); + } - if (LT(1) != IToken.tLBRACE) { - IToken errorPoint = LA(1); - backup(mark); - throwBacktrack(errorPoint.getOffset(), errorPoint.getLength()); - } + if (LT(1) != IToken.tLBRACE) { + IToken errorPoint = LA(1); + backup(mark); + throwBacktrack(errorPoint.getOffset(), errorPoint.getLength()); + } - consume(IToken.tLBRACE); - cleanupLastToken(); + consume(IToken.tLBRACE); + cleanupLastToken(); - IASTName name = null; - if (nameToken != null) - name = createName(nameToken); - else - name = createName(); + IASTName name = null; + if (nameToken != null) + name = createName(nameToken); + else + name = createName(); - ICASTCompositeTypeSpecifier result = createCompositeTypeSpecifier(); + ICASTCompositeTypeSpecifier result = createCompositeTypeSpecifier(); - result.setKey(classKind); - ((ASTNode) result).setOffset(classKey.getOffset()); + result.setKey(classKind); + ((ASTNode) result).setOffset(classKey.getOffset()); - result.setName(name); - if (name != null) { - name.setParent(result); - name.setPropertyInParent(IASTCompositeTypeSpecifier.TYPE_NAME); - } + result.setName(name); + if (name != null) { + name.setParent(result); + name.setPropertyInParent(IASTCompositeTypeSpecifier.TYPE_NAME); + } - memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) { - int checkToken = LA(1).hashCode(); - switch (LT(1)) { + memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + switch (LT(1)) { case IToken.tRBRACE: - consume(IToken.tRBRACE); - break memberDeclarationLoop; + consume(IToken.tRBRACE); + break memberDeclarationLoop; default: - try { - IASTDeclaration d = declaration(); - d.setParent(result); - d - .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION); - result.addMemberDeclaration(d); - } catch (BacktrackException bt) { - if (checkToken == LA(1).hashCode()) - failParseWithErrorHandling(); - } - } - if (checkToken == LA(1).hashCode()) - failParseWithErrorHandling(); - } - // consume the } - consume(IToken.tRBRACE); - return result; - } + try { + IASTDeclaration d = declaration(); + d.setParent(result); + d + .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION); + result.addMemberDeclaration(d); + } catch (BacktrackException bt) { + if (checkToken == LA(1).hashCode()) + failParseWithErrorHandling(); + } + } + if (checkToken == LA(1).hashCode()) + failParseWithErrorHandling(); + } + // consume the } + int endOffset = consume(IToken.tRBRACE).getEndOffset(); + ((CASTNode)result).setLength( endOffset - classKey.getOffset() ); + return result; + } - /** - * @return - */ - protected IASTName createName() { - return new CASTName(); - } + /** + * @return + */ + protected IASTName createName() { + return new CASTName(); + } - /** - * @return - */ - protected ICASTCompositeTypeSpecifier createCompositeTypeSpecifier() { - return new CASTCompositeTypeSpecifier(); - } + /** + * @return + */ + protected ICASTCompositeTypeSpecifier createCompositeTypeSpecifier() { + return new CASTCompositeTypeSpecifier(); + } - protected ICASTElaboratedTypeSpecifier elaboratedTypeSpecifier() - throws BacktrackException, EndOfFileException { - // this is an elaborated class specifier - IToken t = consume(); - int eck = 0; + protected ICASTElaboratedTypeSpecifier elaboratedTypeSpecifier() + throws BacktrackException, EndOfFileException { + // this is an elaborated class specifier + IToken t = consume(); + int eck = 0; - switch (t.getType()) { - case IToken.t_struct: + switch (t.getType()) { + case IToken.t_struct: eck = IASTElaboratedTypeSpecifier.k_struct; break; - case IToken.t_union: + case IToken.t_union: eck = IASTElaboratedTypeSpecifier.k_union; break; - case IToken.t_enum: + case IToken.t_enum: eck = IASTElaboratedTypeSpecifier.k_enum; break; - default: + default: backup(t); throwBacktrack(t.getOffset(), t.getLength()); - } + } - IToken identifier = identifier(); - IASTName name = createName(identifier); - ICASTElaboratedTypeSpecifier result = createElaboratedTypeSpecifier(); - result.setName(name); - name.setParent(result); - name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME); - result.setKind(eck); - return result; - } + IToken identifier = identifier(); + IASTName name = createName(identifier); + ICASTElaboratedTypeSpecifier result = createElaboratedTypeSpecifier(); + result.setName(name); + name.setParent(result); + name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME); + result.setKind(eck); + return result; + } - /** - * @return - */ - protected ICASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() { - return new CASTElaboratedTypeSpecifier(); - } + /** + * @return + */ + protected ICASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() { + return new CASTElaboratedTypeSpecifier(); + } - protected IASTDeclarator initDeclarator() throws EndOfFileException, - BacktrackException { - IASTDeclarator d = declarator(); + protected IASTDeclarator initDeclarator() throws EndOfFileException, + BacktrackException { + IASTDeclarator d = declarator(); - try { - // astFactory.constructExpressions(constructInitializers); - IASTInitializer i = optionalCInitializer(); - if (i != null) { - d.setInitializer(i); - i.setParent(d); - i.setPropertyInParent(IASTDeclarator.INITIALIZER); - } - return d; - } finally { - // astFactory.constructExpressions(true); - } - } + try { + // astFactory.constructExpressions(constructInitializers); + IASTInitializer i = optionalCInitializer(); + if (i != null) { + d.setInitializer(i); + i.setParent(d); + i.setPropertyInParent(IASTDeclarator.INITIALIZER); + } + return d; + } finally { + // astFactory.constructExpressions(true); + } + } - protected IASTDeclarator declarator() throws EndOfFileException, - BacktrackException { - IASTDeclarator innerDecl = null; - IASTName declaratorName = null; - IToken la = LA(1); - int startingOffset = la.getOffset(); - la = null; - List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); - List parameters = Collections.EMPTY_LIST; - List arrayMods = Collections.EMPTY_LIST; - boolean encounteredVarArgs = false; - IASTExpression bitField = null; - boolean isFunction = false; - overallLoop: do { + protected IASTDeclarator declarator() throws EndOfFileException, + BacktrackException { + IASTDeclarator innerDecl = null; + IASTName declaratorName = null; + IToken la = LA(1); + int startingOffset = la.getOffset(); + la = null; + List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); + List parameters = Collections.EMPTY_LIST; + List arrayMods = Collections.EMPTY_LIST; + boolean encounteredVarArgs = false; + IASTExpression bitField = null; + boolean isFunction = false; + overallLoop: do { - consumePointerOperators(pointerOps); + consumePointerOperators(pointerOps); - if (LT(1) == IToken.tLPAREN) { - consume(); - innerDecl = declarator(); - consume(IToken.tRPAREN); - declaratorName = createName(); - } else if (LT(1) == IToken.tIDENTIFIER) { - declaratorName = createName(identifier()); - } else - declaratorName = createName(); + if (LT(1) == IToken.tLPAREN) { + consume(); + innerDecl = declarator(); + consume(IToken.tRPAREN); + declaratorName = createName(); + } else if (LT(1) == IToken.tIDENTIFIER) { + declaratorName = createName(identifier()); + } else + declaratorName = createName(); - for (;;) { - switch (LT(1)) { - case IToken.tLPAREN: - // parameterDeclarationClause - // d.setIsFunction(true); - // TODO need to create a temporary scope object here - consume(IToken.tLPAREN); - isFunction = true; - boolean seenParameter = false; - parameterDeclarationLoop: for (;;) { - switch (LT(1)) { + for (;;) { + switch (LT(1)) { + case IToken.tLPAREN: + // parameterDeclarationClause + // d.setIsFunction(true); + // TODO need to create a temporary scope object here + consume(IToken.tLPAREN); + isFunction = true; + boolean seenParameter = false; + parameterDeclarationLoop: for (;;) { + switch (LT(1)) { case IToken.tRPAREN: - consume(); - break parameterDeclarationLoop; + consume(); + break parameterDeclarationLoop; case IToken.tELLIPSIS: - consume(); - encounteredVarArgs = true; - break; + consume(); + encounteredVarArgs = true; + break; case IToken.tCOMMA: - consume(); - seenParameter = false; - break; + consume(); + seenParameter = false; + break; default: - int endOffset = (lastToken != null) ? lastToken - .getEndOffset() : 0; - if (seenParameter) - throwBacktrack(startingOffset, endOffset - - startingOffset); - IASTParameterDeclaration pd = parameterDeclaration(); - if (parameters == Collections.EMPTY_LIST) - parameters = new ArrayList( - DEFAULT_PARAMETERS_LIST_SIZE); - parameters.add(pd); - seenParameter = true; - } - } + int endOffset = (lastToken != null) ? lastToken + .getEndOffset() : 0; + if (seenParameter) + throwBacktrack(startingOffset, endOffset + - startingOffset); + IASTParameterDeclaration pd = parameterDeclaration(); + if (parameters == Collections.EMPTY_LIST) + parameters = new ArrayList( + DEFAULT_PARAMETERS_LIST_SIZE); + parameters.add(pd); + seenParameter = true; + } + } - break; - case IToken.tLBRACKET: - if (arrayMods == Collections.EMPTY_LIST) - arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); - consumeArrayModifiers(arrayMods); - continue; - case IToken.tCOLON: - consume(IToken.tCOLON); - bitField = constantExpression(); - default: - break; - } - break; + break; + case IToken.tLBRACKET: + if (arrayMods == Collections.EMPTY_LIST) + arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); + consumeArrayModifiers(arrayMods); + continue; + case IToken.tCOLON: + consume(IToken.tCOLON); + bitField = constantExpression(); + default: + break; } - if (LA(1).getType() != IToken.tIDENTIFIER) - break; + break; + } + if (LA(1).getType() != IToken.tIDENTIFIER) + break; - } while (true); + } while (true); - IASTDeclarator d = null; - if (isFunction) { - IASTFunctionDeclarator fc = createFunctionDeclarator(); - fc.setVarArgs(encounteredVarArgs); - for (int i = 0; i < parameters.size(); ++i) { - IASTParameterDeclaration p = (IASTParameterDeclaration) parameters - .get(i); - p.setParent(fc); - p - .setPropertyInParent(IASTFunctionDeclarator.FUNCTION_PARAMETER); - fc.addParameterDeclaration(p); + IASTDeclarator d = null; + if (isFunction) { + IASTFunctionDeclarator fc = createFunctionDeclarator(); + fc.setVarArgs(encounteredVarArgs); + for (int i = 0; i < parameters.size(); ++i) { + IASTParameterDeclaration p = (IASTParameterDeclaration) parameters + .get(i); + p.setParent(fc); + p.setPropertyInParent(IASTFunctionDeclarator.FUNCTION_PARAMETER); + fc.addParameterDeclaration(p); + } + d = fc; + } else if (arrayMods != Collections.EMPTY_LIST) { + d = createArrayDeclarator(); + for (int i = 0; i < arrayMods.size(); ++i) { + IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i); + m.setParent(d); + m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER); + ((IASTArrayDeclarator) d).addArrayModifier(m); + } + } else if (bitField != null) { + IASTFieldDeclarator fl = createFieldDeclarator(); + fl.setBitFieldSize(bitField); + d = fl; + } else { + d = createDeclarator(); + } + for (int i = 0; i < pointerOps.size(); ++i) { + IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i); + d.addPointerOperator(po); + po.setParent(d); + po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR); + } + if (innerDecl != null) { + d.setNestedDeclarator(innerDecl); + innerDecl.setParent(d); + innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR); + } + if (declaratorName != null) { + d.setName(declaratorName); + declaratorName.setParent(d); + declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); + } + + return d; + } + + protected IASTArrayDeclarator createArrayDeclarator() { + return new CASTArrayDeclarator(); + } + + /** + * @return + */ + protected IASTFieldDeclarator createFieldDeclarator() { + return new CASTFieldDeclarator(); + } + + /** + * @return + */ + protected IASTFunctionDeclarator createFunctionDeclarator() { + return new CASTFunctionDeclarator(); + } + + /** + * @param t + * @return + */ + protected IASTName createName(IToken t) { + IASTName n = new CASTName(t.getCharImage()); + ((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset()); + return n; + } + + /** + * @return + */ + protected IASTDeclarator createDeclarator() { + return new CASTDeclarator(); + } + + protected void consumeArrayModifiers(List arrayMods) + throws EndOfFileException, BacktrackException { + + while (LT(1) == IToken.tLBRACKET) { + //eat the '[' + int startOffset = consume(IToken.tLBRACKET).getOffset(); + + boolean isStatic = false; + boolean isConst = false; + boolean isRestrict = false; + boolean isVolatile = false; + boolean isVarSized = false; + + outerLoop: do { + switch (LT(1)) { + case IToken.t_static: + isStatic = true; + consume(); + break; + case IToken.t_const: + isConst = true; + consume(); + break; + case IToken.t_volatile: + isVolatile = true; + consume(); + break; + case IToken.t_restrict: + isRestrict = true; + consume(); + break; + case IToken.tSTAR: + isVarSized = true; + consume(); + //deliberate fall through + default: + break outerLoop; } - d = fc; - } else if (arrayMods != Collections.EMPTY_LIST) { - d = createArrayDeclarator(); - for (int i = 0; i < arrayMods.size(); ++i) { - IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i); - m.setParent(d); - m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER); - ((IASTArrayDeclarator) d).addArrayModifier(m); - } - } else if (bitField != null) { - IASTFieldDeclarator fl = createFieldDeclarator(); - fl.setBitFieldSize(bitField); - d = fl; - } else { - d = createDeclarator(); - } - for (int i = 0; i < pointerOps.size(); ++i) { - IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i); - d.addPointerOperator(po); - po.setParent(d); - po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR); - } - if (innerDecl != null) { - d.setNestedDeclarator(innerDecl); - innerDecl.setParent(d); - innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR); - } - if (declaratorName != null) { - d.setName(declaratorName); - declaratorName.setParent(d); - declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); - } + } while (true); - return d; - } + IASTExpression exp = null; - protected IASTArrayDeclarator createArrayDeclarator() { - return new CASTArrayDeclarator(); - } - - /** - * @return - */ - protected IASTFieldDeclarator createFieldDeclarator() { - return new CASTFieldDeclarator(); - } - - /** - * @return - */ - protected IASTFunctionDeclarator createFunctionDeclarator() { - return new CASTFunctionDeclarator(); - } - - /** - * @param t - * @return - */ - protected IASTName createName(IToken t) { - IASTName n = new CASTName(t.getCharImage()); - ((ASTNode) n).setOffset(t.getOffset()); - return n; - } - - /** - * @return - */ - protected IASTDeclarator createDeclarator() { - return new CASTDeclarator(); - } - - protected void consumeArrayModifiers(List arrayMods) - throws EndOfFileException, BacktrackException { - - while (LT(1) == IToken.tLBRACKET) { - //eat the '[' - int startOffset = consume(IToken.tLBRACKET).getOffset(); - - boolean isStatic = false; - boolean isConst = false; - boolean isRestrict = false; - boolean isVolatile = false; - boolean isVarSized = false; - - outerLoop: do { - switch (LT(1)) { - case IToken.t_static: - isStatic = true; - consume(); - break; - case IToken.t_const: - isConst = true; - consume(); - break; - case IToken.t_volatile: - isVolatile = true; - consume(); - break; - case IToken.t_restrict: - isRestrict = true; - consume(); - break; - case IToken.tSTAR: - isVarSized = true; - consume(); - //deliberate fall through - default: - break outerLoop; - } - } while (true); - - IASTExpression exp = null; - - if (LT(1) != IToken.tRBRACKET) { - if (!(isStatic || isRestrict || isConst || isVolatile)) - exp = assignmentExpression(); - else - exp = constantExpression(); - } - consume(IToken.tRBRACKET); - - IASTArrayModifier arrayMod = null; + if (LT(1) != IToken.tRBRACKET) { if (!(isStatic || isRestrict || isConst || isVolatile)) - arrayMod = createArrayModifier(); - else { - ICASTArrayModifier temp = createCArrayModifier(); - temp.setStatic(isStatic); - temp.setConst(isConst); - temp.setVolatile(isVolatile); - temp.setRestrict(isRestrict); - temp.setVariableSized(isVarSized); - arrayMod = temp; - } - ((ASTNode) arrayMod).setOffset(startOffset); - if (exp != null) { - arrayMod.setConstantExpression(exp); - exp.setParent(arrayMod); - exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION); - } - arrayMods.add(arrayMod); - } - } + exp = assignmentExpression(); + else + exp = constantExpression(); + } + consume(IToken.tRBRACKET); - /** - * @return - */ - protected ICASTArrayModifier createCArrayModifier() { - return new CASTModifiedArrayModifier(); - } + IASTArrayModifier arrayMod = null; + if (!(isStatic || isRestrict || isConst || isVolatile)) + arrayMod = createArrayModifier(); + else { + ICASTArrayModifier temp = createCArrayModifier(); + temp.setStatic(isStatic); + temp.setConst(isConst); + temp.setVolatile(isVolatile); + temp.setRestrict(isRestrict); + temp.setVariableSized(isVarSized); + arrayMod = temp; + } + ((ASTNode) arrayMod).setOffsetAndLength(startOffset, lastToken.getEndOffset() - startOffset); + if (exp != null) { + arrayMod.setConstantExpression(exp); + exp.setParent(arrayMod); + exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION); + } + arrayMods.add(arrayMod); + } + } - /** - * @return - */ - protected IASTArrayModifier createArrayModifier() { - return new CASTArrayModifier(); - } + /** + * @return + */ + protected ICASTArrayModifier createCArrayModifier() { + return new CASTModifiedArrayModifier(); + } - protected IASTParameterDeclaration parameterDeclaration() - throws BacktrackException, EndOfFileException { - IToken current = LA(1); - int startingOffset = current.getOffset(); - IASTDeclSpecifier declSpec = declSpecifierSeq(true); + /** + * @return + */ + protected IASTArrayModifier createArrayModifier() { + return new CASTArrayModifier(); + } - IASTDeclarator declarator = null; - if (LT(1) != IToken.tSEMI) - declarator = initDeclarator(); + protected IASTParameterDeclaration parameterDeclaration() + throws BacktrackException, EndOfFileException { + IToken current = LA(1); + int startingOffset = current.getOffset(); + IASTDeclSpecifier declSpec = declSpecifierSeq(true); - if (current == LA(1)) { - int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; - throwBacktrack(current.getOffset(), endOffset - current.getOffset()); - } + IASTDeclarator declarator = null; + if (LT(1) != IToken.tSEMI) + declarator = initDeclarator(); - IASTParameterDeclaration result = createParameterDeclaration(); - ((ASTNode) result).setOffset(startingOffset); - result.setDeclSpecifier(declSpec); - declSpec.setParent(result); - declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER); - result.setDeclarator(declarator); - declarator.setParent(result); - declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR); + if (current == LA(1)) { + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + throwBacktrack(current.getOffset(), endOffset - current.getOffset()); + } - return result; - } + IASTParameterDeclaration result = createParameterDeclaration(); + ((ASTNode) result).setOffsetAndLength(startingOffset, lastToken.getEndOffset() - startingOffset); + result.setDeclSpecifier(declSpec); + declSpec.setParent(result); + declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER); + result.setDeclarator(declarator); + declarator.setParent(result); + declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR); - /** - * @return - */ - protected IASTParameterDeclaration createParameterDeclaration() { - return new CASTParameterDeclaration(); - } + return result; + } - /** - * @throws BacktrackException - */ - protected IASTNode forInitStatement() throws BacktrackException, - EndOfFileException { - IToken mark = mark(); - try { - IASTExpression e = expression(); - consume(IToken.tSEMI); - return e; - } catch (BacktrackException bt) { - backup(mark); - try { - return simpleDeclaration(); - } catch (BacktrackException b) { - IASTProblem p = failParse(b); - IASTProblemExpression pe = createProblemExpression(); - ((CASTNode) pe).setOffset(((CASTNode) p).getOffset()); - pe.setProblem(p); - p.setParent(pe); - p.setPropertyInParent(IASTProblemHolder.PROBLEM); - return pe; - } - } - } + /** + * @return + */ + protected IASTParameterDeclaration createParameterDeclaration() { + return new CASTParameterDeclaration(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit() - */ - protected IASTTranslationUnit getTranslationUnit() { - return translationUnit; - } + /** + * @throws BacktrackException + */ + protected IASTNode forInitStatement() throws BacktrackException, + EndOfFileException { + IToken mark = mark(); + try { + IASTExpression e = expression(); + consume(IToken.tSEMI); + //TODO is this a problem? Should we wrap this in an expression statement? + return e; + } catch (BacktrackException bt) { + backup(mark); + try { + return simpleDeclaration(); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemExpression pe = createProblemExpression(); + ((CASTNode) pe).setOffsetAndLength(((CASTNode) p)); + pe.setProblem(p); + p.setParent(pe); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + return pe; + } + } + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement() - */ - protected IASTCompoundStatement createCompoundStatement() { - return new CASTCompoundStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit() + */ + protected IASTTranslationUnit getTranslationUnit() { + return translationUnit; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression() - */ - protected IASTBinaryExpression createBinaryExpression() { - return new CASTBinaryExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement() + */ + protected IASTCompoundStatement createCompoundStatement() { + return new CASTCompoundStatement(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression() - */ - protected IASTConditionalExpression createConditionalExpression() { - return new CASTConditionalExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression() + */ + protected IASTBinaryExpression createBinaryExpression() { + return new CASTBinaryExpression(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression() - */ - protected IASTUnaryExpression createUnaryExpression() { - return new CASTUnaryExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression() + */ + protected IASTConditionalExpression createConditionalExpression() { + return new CASTConditionalExpression(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression() - */ - protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() { - return new CASTCompoundStatementExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression() + */ + protected IASTUnaryExpression createUnaryExpression() { + return new CASTUnaryExpression(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList() - */ - protected IASTExpressionList createExpressionList() { - return new CASTExpressionList(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression() + */ + protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() { + return new CASTCompoundStatementExpression(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator() - */ - protected IASTEnumerator createEnumerator() { - return new CASTEnumerator(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList() + */ + protected IASTExpressionList createExpressionList() { + return new CASTExpressionList(); + } - /** - * @return - */ - protected IASTLabelStatement createLabelStatement() { - return new CASTLabelStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator() + */ + protected IASTEnumerator createEnumerator() { + return new CASTEnumerator(); + } - /** - * @return - */ - protected IASTGotoStatement createGoToStatement() { - return new CASTGotoStatement(); - } + /** + * @return + */ + protected IASTLabelStatement createLabelStatement() { + return new CASTLabelStatement(); + } - /** - * @return - */ - protected IASTReturnStatement createReturnStatement() { - return new CASTReturnStatement(); - } + /** + * @return + */ + protected IASTGotoStatement createGoToStatement() { + return new CASTGotoStatement(); + } - /** - * @return - */ - protected IASTForStatement createForStatement() { - return new CASTForStatement(); - } + /** + * @return + */ + protected IASTReturnStatement createReturnStatement() { + return new CASTReturnStatement(); + } - /** - * @return - */ - protected IASTContinueStatement createContinueStatement() { - return new CASTContinueStatement(); - } + /** + * @return + */ + protected IASTForStatement createForStatement() { + return new CASTForStatement(); + } - /** - * @return - */ - protected IASTDoStatement createDoStatement() { - return new CASTDoStatement(); - } + /** + * @return + */ + protected IASTContinueStatement createContinueStatement() { + return new CASTContinueStatement(); + } - /** - * @return - */ - protected IASTBreakStatement createBreakStatement() { - return new CASTBreakStatement(); - } + /** + * @return + */ + protected IASTDoStatement createDoStatement() { + return new CASTDoStatement(); + } - /** - * @return - */ - protected IASTWhileStatement createWhileStatement() { - return new CASTWhileStatement(); - } + /** + * @return + */ + protected IASTBreakStatement createBreakStatement() { + return new CASTBreakStatement(); + } - /** - * @return - */ - protected IASTNullStatement createNullStatement() { - return new CASTNullStatement(); - } + /** + * @return + */ + protected IASTWhileStatement createWhileStatement() { + return new CASTWhileStatement(); + } - /** - * @return - */ - protected IASTSwitchStatement createSwitchStatement() { - return new CASTSwitchStatement(); - } + /** + * @return + */ + protected IASTNullStatement createNullStatement() { + return new CASTNullStatement(); + } - /** - * @return - */ - protected IASTIfStatement createIfStatement() { - return new CASTIfStatement(); - } + /** + * @return + */ + protected IASTSwitchStatement createSwitchStatement() { + return new CASTSwitchStatement(); + } - /** - * @return - */ - protected IASTDefaultStatement createDefaultStatement() { - return new CASTDefaultStatement(); - } + /** + * @return + */ + protected IASTIfStatement createIfStatement() { + return new CASTIfStatement(); + } - /** - * @return - */ - protected IASTCaseStatement createCaseStatement() { - return new CASTCaseStatement(); - } + /** + * @return + */ + protected IASTDefaultStatement createDefaultStatement() { + return new CASTDefaultStatement(); + } - /** - * @return - */ - protected IASTExpressionStatement createExpressionStatement() { - return new CASTExpressionStatement(); - } + /** + * @return + */ + protected IASTCaseStatement createCaseStatement() { + return new CASTCaseStatement(); + } - /** - * @return - */ - protected IASTDeclarationStatement createDeclarationStatement() { - return new CASTDeclarationStatement(); - } + /** + * @return + */ + protected IASTExpressionStatement createExpressionStatement() { + return new CASTExpressionStatement(); + } - /** - * @return - */ - protected IASTASMDeclaration createASMDirective() { - return new CASTASMDeclaration(); - } + /** + * @return + */ + protected IASTDeclarationStatement createDeclarationStatement() { + return new CASTDeclarationStatement(); + } - protected IASTEnumerationSpecifier createEnumerationSpecifier() { - return new CASTEnumerationSpecifier(); - } + /** + * @return + */ + protected IASTASMDeclaration createASMDirective() { + return new CASTASMDeclaration(); + } - /** - * @return - */ - protected IASTCastExpression createCastExpression() { - return new CASTCastExpression(); - } + protected IASTEnumerationSpecifier createEnumerationSpecifier() { + return new CASTEnumerationSpecifier(); + } - protected IASTStatement statement() throws EndOfFileException, - BacktrackException { - switch (LT(1)) { - // labeled statements - case IToken.t_case: + /** + * @return + */ + protected IASTCastExpression createCastExpression() { + return new CASTCastExpression(); + } + + protected IASTStatement statement() throws EndOfFileException, + BacktrackException { + switch (LT(1)) { + // labeled statements + case IToken.t_case: return parseCaseStatement(); - case IToken.t_default: + case IToken.t_default: return parseDefaultStatement(); - // compound statement - case IToken.tLBRACE: + // compound statement + case IToken.tLBRACE: return parseCompoundStatement(); - // selection statement - case IToken.t_if: + // selection statement + case IToken.t_if: return parseIfStatement(); - case IToken.t_switch: + case IToken.t_switch: return parseSwitchStatement(); - //iteration statements - case IToken.t_while: + //iteration statements + case IToken.t_while: return parseWhileStatement(); - case IToken.t_do: + case IToken.t_do: return parseDoStatement(); - case IToken.t_for: + case IToken.t_for: return parseForStatement(); - //jump statement - case IToken.t_break: + //jump statement + case IToken.t_break: return parseBreakStatement(); - case IToken.t_continue: + case IToken.t_continue: return parseContinueStatement(); - case IToken.t_return: + case IToken.t_return: return parseReturnStatement(); - case IToken.t_goto: + case IToken.t_goto: return parseGotoStatement(); - case IToken.tSEMI: + case IToken.tSEMI: return parseNullStatement(); - default: + default: // can be many things: // label if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { - return parseLabelStatement(); + return parseLabelStatement(); } return parseDeclarationOrExpressionStatement(); - } + } - } + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit() - */ - protected void nullifyTranslationUnit() { - translationUnit = null; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit() + */ + protected void nullifyTranslationUnit() { + translationUnit = null; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement() - */ - protected IASTProblemStatement createProblemStatement() { - return new CASTProblemStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement() + */ + protected IASTProblemStatement createProblemStatement() { + return new CASTProblemStatement(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression() - */ - protected IASTProblemExpression createProblemExpression() { - return new CASTProblemExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression() + */ + protected IASTProblemExpression createProblemExpression() { + return new CASTProblemExpression(); + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int, - * int, int) - */ - protected IASTProblem createProblem(int signal, int offset, int length) { - IASTProblem result = new CASTProblem(signal, EMPTY_STRING, false, true); - ((ASTNode) result).setOffset(offset); - ((ASTNode) result).setLength(length); - return result; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int, + * int, int) + */ + protected IASTProblem createProblem(int signal, int offset, int length) { + IASTProblem result = new CASTProblem(signal, EMPTY_STRING, false, true); + ((ASTNode) result).setOffsetAndLength(offset, length); + return result; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index f63338a6189..c5a0256acf7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -112,8 +112,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier; -import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction; -import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CollectProblemsAction; /** * @author aniefer 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 d021a22c543..cc5892ff810 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 @@ -138,4374 +138,4518 @@ import org.eclipse.cdt.internal.core.parser.TemplateParameterManager; import org.eclipse.cdt.internal.core.parser.token.TokenFactory; /** - * This is our implementation of the IParser interface, serving as a - * parser for GNU C and C++. + * This is our implementation of the IParser interface, serving as a parser for + * GNU C and C++. * * From time to time we will make reference to the ANSI ISO specifications. * * @author jcamelon */ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { - - private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE = 4; - private ScopeStack templateIdScopes = new ScopeStack(); - protected CPPASTTranslationUnit translationUnit; - private static class ScopeStack { - private int[] stack; - private int index = -1; + private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE = 4; + private ScopeStack templateIdScopes = new ScopeStack(); + protected CPPASTTranslationUnit translationUnit; - public ScopeStack() { - stack = new int[8]; - } + private static class ScopeStack { + private int[] stack; - private void grow() { - int[] newStack = new int[stack.length << 1]; - System.arraycopy(stack, 0, newStack, 0, stack.length); - stack = newStack; - } + private int index = -1; - final public void push(int i) { - if (++index == stack.length) - grow(); - stack[index] = i; - } + public ScopeStack() { + stack = new int[8]; + } - final public int pop() { - if (index >= 0) - return stack[index--]; - return -1; - } + private void grow() { + int[] newStack = new int[stack.length << 1]; + System.arraycopy(stack, 0, newStack, 0, stack.length); + stack = newStack; + } - final public int peek() { - if (index >= 0) - return stack[index]; - return -1; - } + final public void push(int i) { + if (++index == stack.length) + grow(); + stack[index] = i; + } - final public int size() { - return index + 1; - } - } + final public int pop() { + if (index >= 0) + return stack[index--]; + return -1; + } - /** - * Consumes template parameters. - * - * @param previousLast - * Previous "last" token (returned if nothing was consumed) - * @return Last consumed token, or previousLast if nothing - * was consumed - * @throws BacktrackException - * request a backtrack - */ - protected IToken consumeTemplateParameters(IToken previousLast) - throws EndOfFileException, BacktrackException { - int startingOffset = previousLast == null ? lastToken.getOffset() - : previousLast.getOffset(); - IToken last = previousLast; - if (LT(1) == IToken.tLT) { - last = consume(IToken.tLT); - // until we get all the names sorted out - ScopeStack scopes = new ScopeStack(); - scopes.push(IToken.tLT); + final public int peek() { + if (index >= 0) + return stack[index]; + return -1; + } - while (scopes.size() > 0) { - int top; - last = consume(); + final public int size() { + return index + 1; + } + } - switch (last.getType()) { - case IToken.tGT: - if (scopes.peek() == IToken.tLT) { - scopes.pop(); - } - break; - case IToken.tRBRACKET: - do { - top = scopes.pop(); - } while (scopes.size() > 0 - && (top == IToken.tGT || top == IToken.tLT)); - if (top != IToken.tLBRACKET) - throwBacktrack(startingOffset, last.getEndOffset() - startingOffset ); + /** + * Consumes template parameters. + * + * @param previousLast + * Previous "last" token (returned if nothing was consumed) + * @return Last consumed token, or previousLast if nothing was + * consumed + * @throws BacktrackException + * request a backtrack + */ + protected IToken consumeTemplateParameters(IToken previousLast) + throws EndOfFileException, BacktrackException { + int startingOffset = previousLast == null ? lastToken.getOffset() + : previousLast.getOffset(); + IToken last = previousLast; + if (LT(1) == IToken.tLT) { + last = consume(IToken.tLT); + // until we get all the names sorted out + ScopeStack scopes = new ScopeStack(); + scopes.push(IToken.tLT); - break; - case IToken.tRPAREN: - do { - top = scopes.pop(); - } while (scopes.size() > 0 - && (top == IToken.tGT || top == IToken.tLT)); - if (top != IToken.tLPAREN) - throwBacktrack(startingOffset, last.getEndOffset() - startingOffset ); + while (scopes.size() > 0) { + int top; + last = consume(); - break; - case IToken.tLT: - case IToken.tLBRACKET: - case IToken.tLPAREN: - scopes.push(last.getType()); - break; - } + switch (last.getType()) { + case IToken.tGT: + if (scopes.peek() == IToken.tLT) { + scopes.pop(); + } + break; + case IToken.tRBRACKET: + do { + top = scopes.pop(); + } while (scopes.size() > 0 + && (top == IToken.tGT || top == IToken.tLT)); + if (top != IToken.tLBRACKET) + throwBacktrack(startingOffset, last.getEndOffset() + - startingOffset); + + break; + case IToken.tRPAREN: + do { + top = scopes.pop(); + } while (scopes.size() > 0 + && (top == IToken.tGT || top == IToken.tLT)); + if (top != IToken.tLPAREN) + throwBacktrack(startingOffset, last.getEndOffset() + - startingOffset); + + break; + case IToken.tLT: + case IToken.tLBRACKET: + case IToken.tLPAREN: + scopes.push(last.getType()); + break; } - } - return last; - } + } + } + return last; + } - protected List templateArgumentList() - throws EndOfFileException, BacktrackException { - IToken start = LA(1); - int startingOffset = start.getOffset(); - int endOffset = 0; - start = null; - List list = new ArrayList(); + protected List templateArgumentList() throws EndOfFileException, + BacktrackException { + IToken start = LA(1); + int startingOffset = start.getOffset(); + int endOffset = 0; + start = null; + List list = new ArrayList(); - boolean completedArg = false; - boolean failed = false; + boolean completedArg = false; + boolean failed = false; - templateIdScopes.push(IToken.tLT); + templateIdScopes.push(IToken.tLT); - while (LT(1) != IToken.tGT) { - completedArg = false; + while (LT(1) != IToken.tGT) { + completedArg = false; - IToken mark = mark(); + IToken mark = mark(); + try { + IASTTypeId typeId = typeId(false); + list.add(typeId); + completedArg = true; + } catch (BacktrackException e) { + backup(mark); + } /* + * catch (ASTSemanticException e) { backup(mark); } + */ + + if (!completedArg) { try { - IASTTypeId typeId = typeId(false); - list.add(typeId); - completedArg = true; + IASTExpression expression = assignmentExpression(); + list.add(expression); + completedArg = true; } catch (BacktrackException e) { - backup(mark); - } /* - * catch (ASTSemanticException e) { backup(mark); } - */ - - if (!completedArg) { - try { - IASTExpression expression = assignmentExpression(); - list.add(expression); - completedArg = true; - } catch (BacktrackException e) { - backup(mark); - } + backup(mark); } + } - if (LT(1) == IToken.tCOMMA) { - consume(); - } else if (LT(1) != IToken.tGT) { - failed = true; - endOffset = LA(1).getEndOffset(); - break; - } - } + if (LT(1) == IToken.tCOMMA) { + consume(); + } else if (LT(1) != IToken.tGT) { + failed = true; + endOffset = LA(1).getEndOffset(); + break; + } + } - templateIdScopes.pop(); + templateIdScopes.pop(); - if (failed) - throwBacktrack(startingOffset, endOffset - startingOffset ); + if (failed) + throwBacktrack(startingOffset, endOffset - startingOffset); + return list; + } - return list; - } + /** + * Parse a name. + * + * name : ("::")? name2 ("::" name2)* + * + * name2 : IDENTIFER : template-id + * + * @throws BacktrackException + * request a backtrack + */ + protected ITokenDuple name() throws BacktrackException, EndOfFileException { - /** - * Parse a name. - * - * name : ("::")? name2 ("::" name2)* - * - * name2 : IDENTIFER : template-id - * - * @throws BacktrackException - * request a backtrack - */ - protected ITokenDuple name() throws BacktrackException, - EndOfFileException { + TemplateParameterManager argumentList = TemplateParameterManager + .getInstance(); - TemplateParameterManager argumentList = TemplateParameterManager - .getInstance(); + try { + IToken first = LA(1); + IToken last = null; + IToken mark = mark(); - try { - IToken first = LA(1); - IToken last = null; - IToken mark = mark(); + boolean hasTemplateId = false; - boolean hasTemplateId = false; + if (LT(1) == IToken.tCOLONCOLON) { + argumentList.addSegment(null); + last = consume(IToken.tCOLONCOLON); + } - if (LT(1) == IToken.tCOLONCOLON) { - argumentList.addSegment(null); - last = consume(IToken.tCOLONCOLON); - } + if (LT(1) == IToken.tCOMPL) + consume(); - if (LT(1) == IToken.tCOMPL) - consume(); - - switch (LT(1)) { + switch (LT(1)) { case IToken.tIDENTIFIER: - last = consume(IToken.tIDENTIFIER); - last = consumeTemplateArguments(last, argumentList); - if (last.getType() == IToken.tGT) - hasTemplateId = true; - break; + last = consume(IToken.tIDENTIFIER); + last = consumeTemplateArguments(last, argumentList); + if (last.getType() == IToken.tGT) + hasTemplateId = true; + break; default: - IToken l = LA(1); - backup(mark); - throwBacktrack(first.getOffset(), l.getEndOffset() - first.getOffset() ); - } + IToken l = LA(1); + backup(mark); + throwBacktrack(first.getOffset(), l.getEndOffset() + - first.getOffset()); + } - while (LT(1) == IToken.tCOLONCOLON) { - last = consume(IToken.tCOLONCOLON); + while (LT(1) == IToken.tCOLONCOLON) { + last = consume(IToken.tCOLONCOLON); - if (LT(1) == IToken.t_template) - consume(); + if (LT(1) == IToken.t_template) + consume(); - if (LT(1) == IToken.tCOMPL) - consume(); + if (LT(1) == IToken.tCOMPL) + consume(); - switch (LT(1)) { - case IToken.t_operator: - IToken l = LA(1); - backup(mark); - throwBacktrack(first.getOffset(), l.getEndOffset() - first.getOffset() ); - case IToken.tIDENTIFIER: - last = consume(); - last = consumeTemplateArguments(last, argumentList); - if (last.getType() == IToken.tGT) - hasTemplateId = true; - } - } - - ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last, - (hasTemplateId ? argumentList.getTemplateArgumentsList() - : null)); - return tokenDuple; - } finally { - TemplateParameterManager.returnInstance(argumentList); - } - - } - - /** - * @param last - * @param argumentList - * @return @throws - * EndOfFileException - * @throws BacktrackException - */ - protected IToken consumeTemplateArguments(IToken last, TemplateParameterManager argumentList) throws EndOfFileException, - BacktrackException { -// if (language != ParserLanguage.CPP) -// return last; - if (LT(1) == IToken.tLT) { - IToken secondMark = mark(); - consume(IToken.tLT); - try { - List list = templateArgumentList(); - argumentList.addSegment(list); - last = consume(IToken.tGT); - } catch (BacktrackException bt) { - argumentList.addSegment(null); - backup(secondMark); - } - } else { - argumentList.addSegment(null); - } - return last; - } - - protected ITokenDuple operatorId(IToken originalToken, TemplateParameterManager templateArgs) throws BacktrackException, - EndOfFileException { - // we know this is an operator - IToken operatorToken = consume(IToken.t_operator); - IToken toSend = null; - if (LA(1).isOperator() || LT(1) == IToken.tLPAREN - || LT(1) == IToken.tLBRACKET) { - if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete) - && LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) { - consume(); - consume(IToken.tLBRACKET); - toSend = consume(IToken.tRBRACKET); - // vector new and delete operators - } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) { - // operator () - consume(IToken.tLPAREN); - toSend = consume(IToken.tRPAREN); - } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) { - consume(IToken.tLBRACKET); - toSend = consume(IToken.tRBRACKET); - } else if (LA(1).isOperator()) - toSend = consume(); - else - throwBacktrack(operatorToken.getOffset(), - toSend != null ? toSend.getEndOffset() - operatorToken.getOffset(): 0 ); - } else { - // must be a conversion function - typeId(true); - toSend = lastToken; - } - - boolean hasTemplateId = (templateArgs != null); - boolean grabbedNewInstance = false; - if (templateArgs == null) { - templateArgs = TemplateParameterManager.getInstance(); - grabbedNewInstance = true; - } - - try { - toSend = consumeTemplateArguments(toSend, templateArgs); - if (toSend.getType() == IToken.tGT) { - hasTemplateId = true; - } - - ITokenDuple duple = TokenFactory.createTokenDuple( - originalToken == null ? operatorToken : originalToken, - toSend, (hasTemplateId ? templateArgs - .getTemplateArgumentsList() : null)); - - return duple; - } finally { - if (grabbedNewInstance) - TemplateParameterManager.returnInstance(templateArgs); - } - } - - /** - * Parse a Pointer Operator. - * - * ptrOperator : "*" (cvQualifier)* | "&" | ::? nestedNameSpecifier "*" - * (cvQualifier)* - * - * @param owner - * Declarator that this pointer operator corresponds to. - * @throws BacktrackException - * request a backtrack - */ - protected void consumePointerOperators(List collection) - throws EndOfFileException, BacktrackException { - - - for (;;) { - if (LT(1) == IToken.tAMPER) { - int o = consume(IToken.tAMPER).getOffset(); - ICPPASTReferenceOperator refOp = createReferenceOperator(); - ((ASTNode)refOp).setOffset( o ); - collection.add( refOp ); - return; - } - IToken mark = mark(); - ITokenDuple nameDuple = null; - boolean isConst = false, isVolatile = false, isRestrict = false; - if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) { - try { - nameDuple = name(); - } catch (BacktrackException bt) { - backup(mark); - return; - } - } - if (LT(1) == IToken.tSTAR) { - int starOffset = consume(IToken.tSTAR).getOffset(); - - - for (;;) { - IToken t = LA(1); - int startingOffset = LA(1).getOffset(); - switch (LT(1)) { - case IToken.t_const: - consume(IToken.t_const); - isConst = true; - break; - case IToken.t_volatile: - consume(IToken.t_volatile); - isVolatile = true; - break; - case IToken.t_restrict: - if (allowCPPRestrict) { - consume(IToken.t_restrict); - isRestrict = true; - break; - } - IToken la = LA(1); - throwBacktrack(startingOffset, la.getEndOffset() - startingOffset ); - - } - if( t == LA(1) ) - break; - } - - IASTPointerOperator po = null; - if (nameDuple != null) { - IASTName name = createName( nameDuple ); - ICPPASTPointerToMember p2m = createPointerToMember(isRestrict); - ((ASTNode)p2m).setOffset( starOffset ); - p2m.setConst(isConst); - p2m.setVolatile(isVolatile); - p2m.setName( name ); - name.setParent( p2m ); - name.setPropertyInParent( ICPPASTPointerToMember.NAME ); - if( isRestrict ) - { - IGPPASTPointerToMember newPo = (IGPPASTPointerToMember) p2m; - newPo.setRestrict( isRestrict ); - p2m = newPo; - } - po = p2m; - - } else { - po = createPointer(isRestrict); - ((ASTNode)po).setOffset( starOffset ); - ((IASTPointer) po).setConst(isConst); - ((IASTPointer) po).setVolatile(isVolatile); - if( isRestrict ) - { - IGPPASTPointer newPo = (IGPPASTPointer) po; - newPo.setRestrict( isRestrict ); - po = newPo; - } - } - if (po != null) - collection.add(po); - - continue; - } - - backup(mark); - return; - } - } - - - - - /** - * @param isRestrict - * @return - */ - protected ICPPASTPointerToMember createPointerToMember(boolean gnu) { - if( gnu ) return new GPPASTPointerToMember(); - return new CPPASTPointerToMember(); - } - - /** - * @param isRestrict - * @return - */ - protected IASTPointerOperator createPointer(boolean gnu) { - if( gnu ) return new GPPASTPointer(); - return new CPPASTPointer(); - } - - /** - * @return - */ - protected ICPPASTReferenceOperator createReferenceOperator() { - return new CPPASTReferenceOperator(); - } - - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression assignmentExpression() - throws EndOfFileException, BacktrackException { - if (LT(1) == IToken.t_throw) { - return throwExpression(); - } - - if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tLBRACE - && supportStatementsInExpressions) { - IASTExpression resultExpression = compoundStatementExpression(); - if (resultExpression != null) - return resultExpression; - } - - - IASTExpression conditionalExpression = conditionalExpression(); - // if the condition not taken, try assignment operators - if (conditionalExpression != null && conditionalExpression instanceof IASTConditionalExpression ) //&& - return conditionalExpression; - - switch (LT(1)) { - case IToken.tASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_assign, - conditionalExpression); - case IToken.tSTARASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_multiplyAssign, - conditionalExpression); - case IToken.tDIVASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_divideAssign, - conditionalExpression); - case IToken.tMODASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_moduloAssign, - conditionalExpression); - case IToken.tPLUSASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_plusAssign, - conditionalExpression); - case IToken.tMINUSASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_minusAssign, - conditionalExpression); - case IToken.tSHIFTRASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_shiftRightAssign, - conditionalExpression); - case IToken.tSHIFTLASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_shiftLeftAssign, - conditionalExpression); - case IToken.tAMPERASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_binaryAndAssign, - conditionalExpression); - case IToken.tXORASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_binaryXorAssign, - conditionalExpression); - case IToken.tBITORASSIGN: - return assignmentOperatorExpression(IASTBinaryExpression.op_binaryOrAssign, - conditionalExpression); - } - return conditionalExpression; - } - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression throwExpression() throws EndOfFileException, - BacktrackException { - IToken throwToken = consume(IToken.t_throw); - IASTExpression throwExpression = null; - try - { - throwExpression = expression(); - } - catch( BacktrackException bte ) - { - } - return buildUnaryExpression( ICPPASTUnaryExpression.op_throw, throwExpression, throwToken.getOffset() ); - } - - - - - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression relationalExpression() - throws BacktrackException, EndOfFileException { - - IASTExpression firstExpression = shiftExpression(); - for (;;) { switch (LT(1)) { + case IToken.t_operator: + IToken l = LA(1); + backup(mark); + throwBacktrack(first.getOffset(), l.getEndOffset() + - first.getOffset()); + case IToken.tIDENTIFIER: + last = consume(); + last = consumeTemplateArguments(last, argumentList); + if (last.getType() == IToken.tGT) + hasTemplateId = true; + } + } + + ITokenDuple tokenDuple = TokenFactory + .createTokenDuple(first, last, (hasTemplateId ? argumentList + .getTemplateArgumentsList() : null)); + return tokenDuple; + } finally { + TemplateParameterManager.returnInstance(argumentList); + } + + } + + /** + * @param last + * @param argumentList + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IToken consumeTemplateArguments(IToken last, + TemplateParameterManager argumentList) throws EndOfFileException, + BacktrackException { + // if (language != ParserLanguage.CPP) + // return last; + if (LT(1) == IToken.tLT) { + IToken secondMark = mark(); + consume(IToken.tLT); + try { + List list = templateArgumentList(); + argumentList.addSegment(list); + last = consume(IToken.tGT); + } catch (BacktrackException bt) { + argumentList.addSegment(null); + backup(secondMark); + } + } else { + argumentList.addSegment(null); + } + return last; + } + + protected ITokenDuple operatorId(IToken originalToken, + TemplateParameterManager templateArgs) throws BacktrackException, + EndOfFileException { + // we know this is an operator + IToken operatorToken = consume(IToken.t_operator); + IToken toSend = null; + if (LA(1).isOperator() || LT(1) == IToken.tLPAREN + || LT(1) == IToken.tLBRACKET) { + if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete) + && LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) { + consume(); + consume(IToken.tLBRACKET); + toSend = consume(IToken.tRBRACKET); + // vector new and delete operators + } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) { + // operator () + consume(IToken.tLPAREN); + toSend = consume(IToken.tRPAREN); + } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) { + consume(IToken.tLBRACKET); + toSend = consume(IToken.tRBRACKET); + } else if (LA(1).isOperator()) + toSend = consume(); + else + throwBacktrack(operatorToken.getOffset(), toSend != null ? toSend + .getEndOffset() + - operatorToken.getOffset() : 0); + } else { + // must be a conversion function + typeId(true); + toSend = lastToken; + } + + boolean hasTemplateId = (templateArgs != null); + boolean grabbedNewInstance = false; + if (templateArgs == null) { + templateArgs = TemplateParameterManager.getInstance(); + grabbedNewInstance = true; + } + + try { + toSend = consumeTemplateArguments(toSend, templateArgs); + if (toSend.getType() == IToken.tGT) { + hasTemplateId = true; + } + + ITokenDuple duple = TokenFactory + .createTokenDuple(originalToken == null ? operatorToken + : originalToken, toSend, (hasTemplateId ? templateArgs + .getTemplateArgumentsList() : null)); + + return duple; + } finally { + if (grabbedNewInstance) + TemplateParameterManager.returnInstance(templateArgs); + } + } + + /** + * Parse a Pointer Operator. + * + * ptrOperator : "*" (cvQualifier)* | "&" | ::? nestedNameSpecifier "*" + * (cvQualifier)* + * + * @param owner + * Declarator that this pointer operator corresponds to. + * @throws BacktrackException + * request a backtrack + */ + protected void consumePointerOperators(List collection) + throws EndOfFileException, BacktrackException { + + for (;;) { + if (LT(1) == IToken.tAMPER) { + int length = LA(1).getEndOffset() - LA(1).getOffset(); + int o = consume(IToken.tAMPER).getOffset(); + ICPPASTReferenceOperator refOp = createReferenceOperator(); + ((ASTNode) refOp).setOffsetAndLength(o, length); + collection.add(refOp); + return; + } + IToken mark = mark(); + ITokenDuple nameDuple = null; + boolean isConst = false, isVolatile = false, isRestrict = false; + if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) { + try { + nameDuple = name(); + } catch (BacktrackException bt) { + backup(mark); + return; + } + } + if (LT(1) == IToken.tSTAR) { + int starOffset = consume(IToken.tSTAR).getOffset(); + + for (;;) { + IToken t = LA(1); + int startingOffset = LA(1).getOffset(); + switch (LT(1)) { + case IToken.t_const: + consume(IToken.t_const); + isConst = true; + break; + case IToken.t_volatile: + consume(IToken.t_volatile); + isVolatile = true; + break; + case IToken.t_restrict: + if (allowCPPRestrict) { + consume(IToken.t_restrict); + isRestrict = true; + break; + } + IToken la = LA(1); + throwBacktrack(startingOffset, la.getEndOffset() + - startingOffset); + + } + if (t == LA(1)) + break; + } + + IASTPointerOperator po = null; + if (nameDuple != null) { + IASTName name = createName(nameDuple); + ICPPASTPointerToMember p2m = createPointerToMember(isRestrict); + ((ASTNode) p2m).setOffsetAndLength(starOffset, nameDuple + .getEndOffset() + - starOffset); + p2m.setConst(isConst); + p2m.setVolatile(isVolatile); + p2m.setName(name); + name.setParent(p2m); + name.setPropertyInParent(ICPPASTPointerToMember.NAME); + if (isRestrict) { + IGPPASTPointerToMember newPo = (IGPPASTPointerToMember) p2m; + newPo.setRestrict(isRestrict); + p2m = newPo; + } + po = p2m; + + } else { + po = createPointer(isRestrict); + ((ASTNode) po).setOffsetAndLength(starOffset, lastToken + .getEndOffset() + - starOffset); + ((IASTPointer) po).setConst(isConst); + ((IASTPointer) po).setVolatile(isVolatile); + if (isRestrict) { + IGPPASTPointer newPo = (IGPPASTPointer) po; + newPo.setRestrict(isRestrict); + po = newPo; + } + } + if (po != null) + collection.add(po); + + continue; + } + + backup(mark); + return; + } + } + + /** + * @param isRestrict + * @return + */ + protected ICPPASTPointerToMember createPointerToMember(boolean gnu) { + if (gnu) + return new GPPASTPointerToMember(); + return new CPPASTPointerToMember(); + } + + /** + * @param isRestrict + * @return + */ + protected IASTPointerOperator createPointer(boolean gnu) { + if (gnu) + return new GPPASTPointer(); + return new CPPASTPointer(); + } + + /** + * @return + */ + protected ICPPASTReferenceOperator createReferenceOperator() { + return new CPPASTReferenceOperator(); + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression assignmentExpression() throws EndOfFileException, + BacktrackException { + if (LT(1) == IToken.t_throw) { + return throwExpression(); + } + + if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tLBRACE + && supportStatementsInExpressions) { + IASTExpression resultExpression = compoundStatementExpression(); + if (resultExpression != null) + return resultExpression; + } + + IASTExpression conditionalExpression = conditionalExpression(); + // if the condition not taken, try assignment operators + if (conditionalExpression != null + && conditionalExpression instanceof IASTConditionalExpression) //&& + return conditionalExpression; + + switch (LT(1)) { + case IToken.tASSIGN: + return assignmentOperatorExpression(IASTBinaryExpression.op_assign, + conditionalExpression); + case IToken.tSTARASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_multiplyAssign, conditionalExpression); + case IToken.tDIVASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_divideAssign, conditionalExpression); + case IToken.tMODASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_moduloAssign, conditionalExpression); + case IToken.tPLUSASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_plusAssign, conditionalExpression); + case IToken.tMINUSASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_minusAssign, conditionalExpression); + case IToken.tSHIFTRASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_shiftRightAssign, + conditionalExpression); + case IToken.tSHIFTLASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_shiftLeftAssign, + conditionalExpression); + case IToken.tAMPERASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_binaryAndAssign, + conditionalExpression); + case IToken.tXORASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_binaryXorAssign, + conditionalExpression); + case IToken.tBITORASSIGN: + return assignmentOperatorExpression( + IASTBinaryExpression.op_binaryOrAssign, conditionalExpression); + } + return conditionalExpression; + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression throwExpression() throws EndOfFileException, + BacktrackException { + IToken throwToken = consume(IToken.t_throw); + IASTExpression throwExpression = null; + try { + throwExpression = expression(); + } catch (BacktrackException bte) { + } + return buildUnaryExpression(ICPPASTUnaryExpression.op_throw, + throwExpression, throwToken.getOffset(), lastToken.getEndOffset() + - throwToken.getOffset()); + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression relationalExpression() throws BacktrackException, + EndOfFileException { + + IASTExpression firstExpression = shiftExpression(); + for (;;) { + switch (LT(1)) { case IToken.tGT: - if (templateIdScopes.size() > 0 - && templateIdScopes.peek() == IToken.tLT) { - return firstExpression; - } + if (templateIdScopes.size() > 0 + && templateIdScopes.peek() == IToken.tLT) { + return firstExpression; + } case IToken.tLT: case IToken.tLTEQUAL: case IToken.tGTEQUAL: - IToken m = mark(); - int t = consume().getType(); - - IASTExpression secondExpression = null; - try - { - secondExpression = shiftExpression(); - } - catch( BacktrackException bte ) - { - backup( m ); - return firstExpression; - } - int expressionKind = 0; - switch (t) { - case IToken.tGT: - expressionKind = IASTBinaryExpression.op_greaterThan; - break; - case IToken.tLT: - expressionKind = IASTBinaryExpression.op_lessThan; - break; - case IToken.tLTEQUAL: - expressionKind = IASTBinaryExpression.op_lessEqual; - break; - case IToken.tGTEQUAL: - expressionKind = IASTBinaryExpression.op_greaterEqual; - break; - } - firstExpression = buildBinaryExpression( expressionKind, firstExpression, secondExpression ); - break; - default: - if ( supportMinAndMaxOperators - && (LT(1) == IGCCToken.tMIN || LT(1) == IGCCToken.tMAX)) { - int new_operator = 0; - switch (LT(1)) { - case IGCCToken.tMAX: - consume(); - new_operator = IGPPASTBinaryExpression.op_max; - break; - case IGCCToken.tMIN: - consume(); - new_operator = IGPPASTBinaryExpression.op_min; - } - - secondExpression = shiftExpression(); - - firstExpression =buildBinaryExpression( new_operator, firstExpression, secondExpression ); - break; - } - return firstExpression; - } - } - } + IToken m = mark(); + int t = consume().getType(); - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression multiplicativeExpression() - throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = pmExpression(); - for (;;) { - switch (LT(1)) { + IASTExpression secondExpression = null; + try { + secondExpression = shiftExpression(); + } catch (BacktrackException bte) { + backup(m); + return firstExpression; + } + int expressionKind = 0; + switch (t) { + case IToken.tGT: + expressionKind = IASTBinaryExpression.op_greaterThan; + break; + case IToken.tLT: + expressionKind = IASTBinaryExpression.op_lessThan; + break; + case IToken.tLTEQUAL: + expressionKind = IASTBinaryExpression.op_lessEqual; + break; + case IToken.tGTEQUAL: + expressionKind = IASTBinaryExpression.op_greaterEqual; + break; + } + firstExpression = buildBinaryExpression(expressionKind, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; + default: + if (supportMinAndMaxOperators + && (LT(1) == IGCCToken.tMIN || LT(1) == IGCCToken.tMAX)) { + int new_operator = 0; + switch (LT(1)) { + case IGCCToken.tMAX: + consume(); + new_operator = IGPPASTBinaryExpression.op_max; + break; + case IGCCToken.tMIN: + consume(); + new_operator = IGPPASTBinaryExpression.op_min; + } + + secondExpression = shiftExpression(); + + firstExpression = buildBinaryExpression(new_operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; + } + return firstExpression; + } + } + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression multiplicativeExpression() + throws BacktrackException, EndOfFileException { + IASTExpression firstExpression = pmExpression(); + for (;;) { + switch (LT(1)) { case IToken.tSTAR: case IToken.tDIV: case IToken.tMOD: - IToken t = consume(); - IASTExpression secondExpression = pmExpression(); - int operator = 0; - switch (t.getType()) { - case IToken.tSTAR: - operator = IASTBinaryExpression.op_multiply; - break; - case IToken.tDIV: - operator = IASTBinaryExpression.op_divide; - break; - case IToken.tMOD: - operator = IASTBinaryExpression.op_modulo; - break; - } - firstExpression = buildBinaryExpression( operator, firstExpression, secondExpression ); - break; + IToken t = consume(); + IASTExpression secondExpression = pmExpression(); + int operator = 0; + switch (t.getType()) { + case IToken.tSTAR: + operator = IASTBinaryExpression.op_multiply; + break; + case IToken.tDIV: + operator = IASTBinaryExpression.op_divide; + break; + case IToken.tMOD: + operator = IASTBinaryExpression.op_modulo; + break; + } + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression pmExpression() throws EndOfFileException, - BacktrackException { + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression pmExpression() throws EndOfFileException, + BacktrackException { - IASTExpression firstExpression = castExpression(); - for (;;) { - switch (LT(1)) { + IASTExpression firstExpression = castExpression(); + for (;;) { + switch (LT(1)) { case IToken.tDOTSTAR: case IToken.tARROWSTAR: - IToken t = consume(); - IASTExpression secondExpression = castExpression(); - int operator = 0; - switch( t.getType() ) - { - case IToken.tDOTSTAR: - operator = ICPPASTBinaryExpression.op_pmdot; - break; - case IToken.tARROWSTAR: - operator = ICPPASTBinaryExpression.op_pmarrow; - break; - } - firstExpression = buildBinaryExpression( operator, firstExpression, secondExpression ); - break; + IToken t = consume(); + IASTExpression secondExpression = castExpression(); + int operator = 0; + switch (t.getType()) { + case IToken.tDOTSTAR: + operator = ICPPASTBinaryExpression.op_pmdot; + break; + case IToken.tARROWSTAR: + operator = ICPPASTBinaryExpression.op_pmarrow; + break; + } + firstExpression = buildBinaryExpression(operator, + firstExpression, secondExpression, lastToken + .getEndOffset()); + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * castExpression : unaryExpression | "(" typeId ")" castExpression - */ - protected IASTExpression castExpression() throws EndOfFileException, - BacktrackException { - // TO DO: we need proper symbol checkint to ensure type name - if (LT(1) == IToken.tLPAREN) { - IToken la = LA(1); - int startingOffset = la.getOffset(); - IToken mark = mark(); - consume(); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); - } - boolean popped = false; - IASTTypeId typeId = null; - // If this isn't a type name, then we shouldn't be here + /** + * castExpression : unaryExpression | "(" typeId ")" castExpression + */ + protected IASTExpression castExpression() throws EndOfFileException, + BacktrackException { + // TO DO: we need proper symbol checkint to ensure type name + if (LT(1) == IToken.tLPAREN) { + IToken la = LA(1); + int startingOffset = la.getOffset(); + IToken mark = mark(); + consume(); + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLPAREN); + } + boolean popped = false; + IASTTypeId typeId = null; + // If this isn't a type name, then we shouldn't be here + try { try { - try { - typeId = typeId(false); - consume(IToken.tRPAREN); - } catch (BacktrackException bte) { - backup(mark); - throwBacktrack(bte); - } - - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - popped = true; - } - IASTExpression castExpression = castExpression(); - mark = null; // clean up mark so that we can garbage collect - return buildTypeIdUnaryExpression( IASTCastExpression.op_cast, typeId, castExpression, startingOffset ); - } catch (BacktrackException b) { - if (templateIdScopes.size() > 0 && !popped) { - templateIdScopes.pop(); - } + typeId = typeId(false); + consume(IToken.tRPAREN); + } catch (BacktrackException bte) { + backup(mark); + throwBacktrack(bte); } - } - return unaryExpression(); - } - - /** - * @throws BacktrackException - */ - protected IASTTypeId typeId(boolean skipArrayModifiers) - throws EndOfFileException, BacktrackException { - IToken mark = mark(); - int startingOffset = mark.getOffset(); - IASTDeclSpecifier declSpecifier = null; - IASTDeclarator declarator = null; - - try - { - declSpecifier = declSpecifierSeq(false, false); - declarator = declarator( SimpleDeclarationStrategy.TRY_CONSTRUCTOR, true ); - } - catch( BacktrackException bt ) - { - int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); - backup( mark ); - throwBacktrack( startingOffset, endingOffset - startingOffset ); - } - if( declarator == null || declarator.getName().toString() != null ) //$NON-NLS-1$ - { - int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); - backup( mark ); - throwBacktrack( startingOffset, endingOffset - startingOffset ); - } - - IASTTypeId result = createTypeId(); - ((ASTNode)result).setOffset( startingOffset ); - - result.setDeclSpecifier( declSpecifier ); - declSpecifier.setParent( result ); - declSpecifier.setPropertyInParent( IASTTypeId.DECL_SPECIFIER ); - - result.setAbstractDeclarator( declarator ); - declarator.setParent( result ); - declarator.setPropertyInParent( IASTTypeId.ABSTRACT_DECLARATOR ); - - return result; - - } - - /** - * @return - */ - protected IASTTypeId createTypeId() { - return new CPPASTTypeId(); - } - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression deleteExpression() throws EndOfFileException, - BacktrackException { - int startingOffset = LA(1).getOffset(); - boolean global = false; - if (LT(1) == IToken.tCOLONCOLON) { - // global scope - consume(IToken.tCOLONCOLON); - global = true; - } - - consume(IToken.t_delete); - - boolean vectored = false; - if (LT(1) == IToken.tLBRACKET) { - // array delete - consume(); - consume(IToken.tRBRACKET); - vectored = true; - } - IASTExpression castExpression = castExpression(); - ICPPASTDeleteExpression deleteExpression = createDeleteExpression(); - ((ASTNode)deleteExpression).setOffset( startingOffset ); - deleteExpression.setIsGlobal( global ); - deleteExpression.setIsVectored( vectored ); - deleteExpression.setOperand( castExpression ); - castExpression.setParent( deleteExpression ); - castExpression.setPropertyInParent( ICPPASTDeleteExpression.OPERAND ); - return deleteExpression; - } - - /** - * @return - */ - protected ICPPASTDeleteExpression createDeleteExpression() { - return new CPPASTDeleteExpression(); - } - - /** - * Pazse a new-expression. - * @param expression - * - * @throws BacktrackException - * - * - * newexpression: ::? new newplacement? newtypeid newinitializer? ::? new - * newplacement? ( typeid ) newinitializer? newplacement: ( expressionlist ) - * newtypeid: typespecifierseq newdeclarator? newdeclarator: ptroperator - * newdeclarator? | directnewdeclarator directnewdeclarator: [ expression ] - * directnewdeclarator [ constantexpression ] newinitializer: ( - * expressionlist? ) - */ - protected IASTExpression newExpression() throws BacktrackException, - EndOfFileException { - IToken la = LA(1); - int startingOffset = la.getOffset(); - - boolean isGlobal = false; - if (LT(1) == IToken.tCOLONCOLON) { - consume(IToken.tCOLONCOLON); - isGlobal = true; - } - consume(IToken.t_new); - boolean typeIdInParen = false; - boolean placementParseFailure = true; - IToken beforeSecondParen = null; - IToken backtrackMarker = null; - IASTTypeId typeId = null; - IASTExpression newPlacementExpressions = null; - IASTExpression newInitializerExpressions = null; - boolean isNewTypeId = false; - - if (LT(1) == IToken.tLPAREN) { - consume(IToken.tLPAREN); if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); + templateIdScopes.pop(); + popped = true; } - try { - // Try to consume placement list - // Note: since expressionList and expression are the same... - backtrackMarker = mark(); - newPlacementExpressions = expression(); - consume(IToken.tRPAREN); - if( LT(1) == IToken.tLBRACKET ) - { - backup( backtrackMarker ); - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } //pop 1st Parent - placementParseFailure = true; - throwBacktrack( backtrackMarker.getOffset(), backtrackMarker.getLength() ); - } - else - placementParseFailure = false; - if (LT(1) == IToken.tLPAREN) { - beforeSecondParen = mark(); - consume(IToken.tLPAREN); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); - } //push 2nd Paren - typeIdInParen = true; - } - } catch (BacktrackException e) { - backup(backtrackMarker); + IASTExpression castExpression = castExpression(); + mark = null; // clean up mark so that we can garbage collect + return buildTypeIdUnaryExpression(IASTCastExpression.op_cast, + typeId, castExpression, startingOffset, lastToken + .getEndOffset()); + } catch (BacktrackException b) { + if (templateIdScopes.size() > 0 && !popped) { + templateIdScopes.pop(); } - if (placementParseFailure) { - // CASE: new (typeid-not-looking-as-placement) ... - // the first expression in () is not a placement - // - then it has to be typeId - typeId = typeId(true); - consume(IToken.tRPAREN); - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } //pop 1st Paren - } else { - if (!typeIdInParen) { - if (LT(1) == IToken.tLBRACKET) { - // CASE: new (typeid-looking-as-placement) [expr]... - // the first expression in () has been parsed as a - // placement; - // however, we assume that it was in fact typeId, and - // this - // new statement creates an array. - // Do nothing, fallback to array/initializer processing - } else { - // CASE: new (placement) typeid ... - // the first expression in () is parsed as a placement, - // and the next expression doesn't start with '(' or '[' - // - then it has to be typeId - try { - backtrackMarker = mark(); - typeId = typeId(true); - } catch (BacktrackException e) { - // Hmmm, so it wasn't typeId after all... Then it is - // CASE: new (typeid-looking-as-placement) - backup(backtrackMarker); - // TODO fix this - return null; - } - } - } else { - // Tricky cases: first expression in () is parsed as a - // placement, - // and the next expression starts with '('. - // The problem is, the first expression might as well be a - // typeid - try { - typeId = typeId(true); - consume(IToken.tRPAREN); - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } //popping the 2nd Paren + } + } + return unaryExpression(); - if (LT(1) == IToken.tLPAREN - || LT(1) == IToken.tLBRACKET) { - // CASE: new (placement)(typeid)(initializer) - // CASE: new (placement)(typeid)[] ... - // Great, so far all our assumptions have been - // correct - // Do nothing, fallback to array/initializer - // processing - } else { - // CASE: new (placement)(typeid) - // CASE: new - // (typeid-looking-as-placement)(initializer-looking-as-typeid) - // Worst-case scenario - this cannot be resolved w/o - // more semantic information. - // Luckily, we don't need to know what was that - we - // only know that - // new-expression ends here. - ICPPASTNewExpression result = createNewExpression(); - ((ASTNode)result).setOffset( startingOffset ); - result.setIsGlobal( isGlobal ); - result.setIsNewTypeId( isNewTypeId ); - result.setTypeId( typeId ); - typeId.setParent( result ); - typeId.setPropertyInParent( ICPPASTNewExpression.TYPE_ID ); - if( newPlacementExpressions != null ) - { - result.setNewPlacement( newPlacementExpressions ); - newPlacementExpressions.setParent( result ); - newPlacementExpressions.setPropertyInParent( ICPPASTNewExpression.NEW_PLACEMENT ); - } - return result; - } - } catch (BacktrackException e) { - // CASE: new - // (typeid-looking-as-placement)(initializer-not-looking-as-typeid) - // Fallback to initializer processing - backup(beforeSecondParen); - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - }//pop that 2nd paren - } - } + } + + /** + * @throws BacktrackException + */ + protected IASTTypeId typeId(boolean skipArrayModifiers) + throws EndOfFileException, BacktrackException { + IToken mark = mark(); + int startingOffset = mark.getOffset(); + IASTDeclSpecifier declSpecifier = null; + IASTDeclarator declarator = null; + + try { + declSpecifier = declSpecifierSeq(false, false); + declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR, + true); + } catch (BacktrackException bt) { + int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); + backup(mark); + throwBacktrack(startingOffset, endingOffset - startingOffset); + } + if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$ + { + int endingOffset = lastToken == null ? 0 : lastToken.getEndOffset(); + backup(mark); + throwBacktrack(startingOffset, endingOffset - startingOffset); + } + + IASTTypeId result = createTypeId(); + int l = lastToken != null ? lastToken.getEndOffset() - startingOffset + : ((ASTNode) declarator).getOffset() + + ((ASTNode) declarator).getLength() - startingOffset; + ((ASTNode) result).setOffsetAndLength(startingOffset, l); + + result.setDeclSpecifier(declSpecifier); + declSpecifier.setParent(result); + declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER); + + result.setAbstractDeclarator(declarator); + declarator.setParent(result); + declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR); + + return result; + + } + + /** + * @return + */ + protected IASTTypeId createTypeId() { + return new CPPASTTypeId(); + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression deleteExpression() throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + boolean global = false; + if (LT(1) == IToken.tCOLONCOLON) { + // global scope + consume(IToken.tCOLONCOLON); + global = true; + } + + consume(IToken.t_delete); + + boolean vectored = false; + if (LT(1) == IToken.tLBRACKET) { + // array delete + consume(); + consume(IToken.tRBRACKET); + vectored = true; + } + IASTExpression castExpression = castExpression(); + ICPPASTDeleteExpression deleteExpression = createDeleteExpression(); + ((ASTNode) deleteExpression).setOffsetAndLength(startingOffset, lastToken + .getEndOffset() + - startingOffset); + deleteExpression.setIsGlobal(global); + deleteExpression.setIsVectored(vectored); + deleteExpression.setOperand(castExpression); + castExpression.setParent(deleteExpression); + castExpression.setPropertyInParent(ICPPASTDeleteExpression.OPERAND); + return deleteExpression; + } + + /** + * @return + */ + protected ICPPASTDeleteExpression createDeleteExpression() { + return new CPPASTDeleteExpression(); + } + + /** + * Pazse a new-expression. + * + * @param expression + * + * @throws BacktrackException + * + * + * newexpression: ::? new newplacement? newtypeid newinitializer? ::? new + * newplacement? ( typeid ) newinitializer? newplacement: ( expressionlist ) + * newtypeid: typespecifierseq newdeclarator? newdeclarator: ptroperator + * newdeclarator? | directnewdeclarator directnewdeclarator: [ expression ] + * directnewdeclarator [ constantexpression ] newinitializer: ( + * expressionlist? ) + */ + protected IASTExpression newExpression() throws BacktrackException, + EndOfFileException { + IToken la = LA(1); + int startingOffset = la.getOffset(); + + boolean isGlobal = false; + if (LT(1) == IToken.tCOLONCOLON) { + consume(IToken.tCOLONCOLON); + isGlobal = true; + } + consume(IToken.t_new); + boolean typeIdInParen = false; + boolean placementParseFailure = true; + IToken beforeSecondParen = null; + IToken backtrackMarker = null; + IASTTypeId typeId = null; + IASTExpression newPlacementExpressions = null; + IASTExpression newInitializerExpressions = null; + boolean isNewTypeId = false; + + if (LT(1) == IToken.tLPAREN) { + consume(IToken.tLPAREN); + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLPAREN); + } + try { + // Try to consume placement list + // Note: since expressionList and expression are the same... + backtrackMarker = mark(); + newPlacementExpressions = expression(); + consume(IToken.tRPAREN); + if (LT(1) == IToken.tLBRACKET) { + backup(backtrackMarker); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } //pop 1st Parent + placementParseFailure = true; + throwBacktrack(backtrackMarker.getOffset(), backtrackMarker + .getLength()); + } else + placementParseFailure = false; + if (LT(1) == IToken.tLPAREN) { + beforeSecondParen = mark(); + consume(IToken.tLPAREN); + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLPAREN); + } //push 2nd Paren + typeIdInParen = true; } - } else { - // CASE: new typeid ... - // new parameters do not start with '(' - // i.e it has to be a plain typeId + } catch (BacktrackException e) { + backup(backtrackMarker); + } + if (placementParseFailure) { + // CASE: new (typeid-not-looking-as-placement) ... + // the first expression in () is not a placement + // - then it has to be typeId typeId = typeId(true); - isNewTypeId = true; - } - ICPPASTNewExpression result = createNewExpression(); - ((ASTNode)result).setOffset( startingOffset ); - result.setIsGlobal( isGlobal ); - result.setIsNewTypeId( isNewTypeId ); - result.setTypeId( typeId ); - typeId.setParent( result ); - typeId.setPropertyInParent( ICPPASTNewExpression.TYPE_ID ); - if( newPlacementExpressions != null ) - { - result.setNewPlacement( newPlacementExpressions ); - newPlacementExpressions.setParent( result ); - newPlacementExpressions.setPropertyInParent( ICPPASTNewExpression.NEW_PLACEMENT ); - } - - while (LT(1) == IToken.tLBRACKET) { - // array new - consume(); - - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLBRACKET); - } - - IASTExpression a = assignmentExpression() ; - consume(IToken.tRBRACKET); - result.addNewTypeIdArrayExpression( a ); - a.setParent( result ); - a.setPropertyInParent( ICPPASTNewExpression.NEW_TYPEID_ARRAY_EXPRESSION ); - - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } - } - // newinitializer - if (LT(1) == IToken.tLPAREN) { - consume(IToken.tLPAREN); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); - } - - //we want to know the difference between no newInitializer and an - // empty new Initializer - //if the next token is the RPAREN, then we have an Empty expression - // in our list. - newInitializerExpressions = expression(); - consume(IToken.tRPAREN); if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); + templateIdScopes.pop(); + } //pop 1st Paren + } else { + if (!typeIdInParen) { + if (LT(1) == IToken.tLBRACKET) { + // CASE: new (typeid-looking-as-placement) [expr]... + // the first expression in () has been parsed as a + // placement; + // however, we assume that it was in fact typeId, and + // this + // new statement creates an array. + // Do nothing, fallback to array/initializer processing + } else { + // CASE: new (placement) typeid ... + // the first expression in () is parsed as a placement, + // and the next expression doesn't start with '(' or '[' + // - then it has to be typeId + try { + backtrackMarker = mark(); + typeId = typeId(true); + } catch (BacktrackException e) { + // Hmmm, so it wasn't typeId after all... Then it is + // CASE: new (typeid-looking-as-placement) + backup(backtrackMarker); + // TODO fix this + return null; + } + } + } else { + // Tricky cases: first expression in () is parsed as a + // placement, + // and the next expression starts with '('. + // The problem is, the first expression might as well be a + // typeid + try { + typeId = typeId(true); + consume(IToken.tRPAREN); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } //popping the 2nd Paren + + if (LT(1) == IToken.tLPAREN || LT(1) == IToken.tLBRACKET) { + // CASE: new (placement)(typeid)(initializer) + // CASE: new (placement)(typeid)[] ... + // Great, so far all our assumptions have been + // correct + // Do nothing, fallback to array/initializer + // processing + } else { + // CASE: new (placement)(typeid) + // CASE: new + // (typeid-looking-as-placement)(initializer-looking-as-typeid) + // Worst-case scenario - this cannot be resolved w/o + // more semantic information. + // Luckily, we don't need to know what was that - we + // only know that + // new-expression ends here. + ICPPASTNewExpression result = createNewExpression(); + ((ASTNode) result).setOffsetAndLength(startingOffset, + lastToken.getEndOffset() - startingOffset); + result.setIsGlobal(isGlobal); + result.setIsNewTypeId(isNewTypeId); + result.setTypeId(typeId); + typeId.setParent(result); + typeId.setPropertyInParent(ICPPASTNewExpression.TYPE_ID); + if (newPlacementExpressions != null) { + result.setNewPlacement(newPlacementExpressions); + newPlacementExpressions.setParent(result); + newPlacementExpressions + .setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT); + } + return result; + } + } catch (BacktrackException e) { + // CASE: new + // (typeid-looking-as-placement)(initializer-not-looking-as-typeid) + // Fallback to initializer processing + backup(beforeSecondParen); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + }//pop that 2nd paren + } } - result.setNewInitializer( newInitializerExpressions ); - newInitializerExpressions.setParent( result ); - newInitializerExpressions.setPropertyInParent( ICPPASTNewExpression.NEW_INITIALIZER ); - } - return result; - } + } + } else { + // CASE: new typeid ... + // new parameters do not start with '(' + // i.e it has to be a plain typeId + typeId = typeId(true); + isNewTypeId = true; + } + ICPPASTNewExpression result = createNewExpression(); + ((ASTNode) result).setOffset(startingOffset); + result.setIsGlobal(isGlobal); + result.setIsNewTypeId(isNewTypeId); + result.setTypeId(typeId); + typeId.setParent(result); + typeId.setPropertyInParent(ICPPASTNewExpression.TYPE_ID); + if (newPlacementExpressions != null) { + result.setNewPlacement(newPlacementExpressions); + newPlacementExpressions.setParent(result); + newPlacementExpressions + .setPropertyInParent(ICPPASTNewExpression.NEW_PLACEMENT); + } - /** - * @return - */ - protected ICPPASTNewExpression createNewExpression() { - return new CPPASTNewExpression(); - } + while (LT(1) == IToken.tLBRACKET) { + // array new + consume(); - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression unaryExpression() throws EndOfFileException, - BacktrackException { - IToken la = LA(1); - int startingOffset = la.getOffset(); - switch (LT(1)) { - case IToken.tSTAR: - return unaryOperatorCastExpression(IASTUnaryExpression.op_star );//IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION); - case IToken.tAMPER: + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLBRACKET); + } + + IASTExpression a = assignmentExpression(); + consume(IToken.tRBRACKET); + result.addNewTypeIdArrayExpression(a); + a.setParent(result); + a + .setPropertyInParent(ICPPASTNewExpression.NEW_TYPEID_ARRAY_EXPRESSION); + + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } + } + // newinitializer + if (LT(1) == IToken.tLPAREN) { + consume(IToken.tLPAREN); + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLPAREN); + } + + //we want to know the difference between no newInitializer and an + // empty new Initializer + //if the next token is the RPAREN, then we have an Empty expression + // in our list. + newInitializerExpressions = expression(); + + int lo = consume(IToken.tRPAREN).getEndOffset(); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } + result.setNewInitializer(newInitializerExpressions); + newInitializerExpressions.setParent(result); + newInitializerExpressions + .setPropertyInParent(ICPPASTNewExpression.NEW_INITIALIZER); + ((CPPASTNode) result).setLength(lo - startingOffset); + } + + return result; + } + + /** + * @return + */ + protected ICPPASTNewExpression createNewExpression() { + return new CPPASTNewExpression(); + } + + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression unaryExpression() throws EndOfFileException, + BacktrackException { + IToken la = LA(1); + int startingOffset = la.getOffset(); + switch (LT(1)) { + case IToken.tSTAR: + return unaryOperatorCastExpression(IASTUnaryExpression.op_star);//IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION); + case IToken.tAMPER: return unaryOperatorCastExpression(IASTUnaryExpression.op_amper);//IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION); - case IToken.tPLUS: - return unaryOperatorCastExpression(IASTUnaryExpression.op_plus );//IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION); - case IToken.tMINUS: - return unaryOperatorCastExpression(IASTUnaryExpression.op_minus );//IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION); - case IToken.tNOT: - return unaryOperatorCastExpression(IASTUnaryExpression.op_not );//IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION); - case IToken.tCOMPL: + case IToken.tPLUS: + return unaryOperatorCastExpression(IASTUnaryExpression.op_plus);//IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION); + case IToken.tMINUS: + return unaryOperatorCastExpression(IASTUnaryExpression.op_minus);//IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION); + case IToken.tNOT: + return unaryOperatorCastExpression(IASTUnaryExpression.op_not);//IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION); + case IToken.tCOMPL: return unaryOperatorCastExpression(IASTUnaryExpression.op_tilde);//IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION); - case IToken.tINCR: + case IToken.tINCR: return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixIncr);//IASTExpression.Kind.UNARY_INCREMENT); - case IToken.tDECR: + case IToken.tDECR: return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr);//IASTExpression.Kind.UNARY_DECREMENT); - case IToken.t_sizeof: + case IToken.t_sizeof: consume(IToken.t_sizeof); IToken mark = LA(1); IASTTypeId typeId = null; + int lastOffset = 0; IASTExpression unaryExpression = null; if (LT(1) == IToken.tLPAREN) { - try { - consume(IToken.tLPAREN); - typeId = typeId(false); - consume(IToken.tRPAREN); - } catch (BacktrackException bt) { - backup(mark); - unaryExpression = unaryExpression(); - } + try { + consume(IToken.tLPAREN); + typeId = typeId(false); + lastOffset = consume(IToken.tRPAREN).getEndOffset(); + } catch (BacktrackException bt) { + backup(mark); + unaryExpression = unaryExpression(); + lastOffset = lastToken.getEndOffset(); + } } else { - unaryExpression = unaryExpression(); + unaryExpression = unaryExpression(); + lastOffset = lastToken.getEndOffset(); } - if (typeId == null && unaryExpression != null ) - return buildUnaryExpression( IASTUnaryExpression.op_sizeof, unaryExpression, startingOffset ); - return buildTypeIdExpression( IASTTypeIdExpression.op_sizeof, typeId, startingOffset ); - case IToken.t_new: + if (typeId == null && unaryExpression != null) + return buildUnaryExpression(IASTUnaryExpression.op_sizeof, + unaryExpression, startingOffset, lastOffset); + return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof, + typeId, startingOffset, lastOffset); + case IToken.t_new: return newExpression(); - case IToken.t_delete: + case IToken.t_delete: return deleteExpression(); - case IToken.tCOLONCOLON: - switch (LT(2)) { - case IToken.t_new: - return newExpression(); - case IToken.t_delete: - return deleteExpression(); - default: - return postfixExpression(); - } - default: + case IToken.tCOLONCOLON: + switch (LT(2)) { + case IToken.t_new: + return newExpression(); + case IToken.t_delete: + return deleteExpression(); + default: + return postfixExpression(); + } + default: if (LT(1) == IGCCToken.t_typeof && supportTypeOfUnaries) { - IASTExpression unary = unaryTypeofExpression(); - if (unary != null) - return unary; + IASTExpression unary = unaryTypeofExpression(); + if (unary != null) + return unary; } if (LT(1) == IGCCToken.t___alignof__ && supportAlignOfUnaries) { - IASTExpression align = unaryAlignofExpression(); - if (align != null) - return align; + IASTExpression align = unaryAlignofExpression(); + if (align != null) + return align; } return postfixExpression(); - } - } + } + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression postfixExpression() throws EndOfFileException, - BacktrackException { - IASTExpression firstExpression = null; - boolean isTemplate = false; + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression postfixExpression() throws EndOfFileException, + BacktrackException { + IASTExpression firstExpression = null; + boolean isTemplate = false; - switch (LT(1)) { - case IToken.t_typename: + switch (LT(1)) { + case IToken.t_typename: int o = consume(IToken.t_typename).getOffset(); boolean templateTokenConsumed = false; if (LT(1) == IToken.t_template) { - consume(IToken.t_template); - templateTokenConsumed = true; + consume(IToken.t_template); + templateTokenConsumed = true; } ITokenDuple nestedName = name(); - IASTName name = createName( nestedName ); + IASTName name = createName(nestedName); consume(IToken.tLPAREN); if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); + templateIdScopes.push(IToken.tLPAREN); } IASTExpression expressionList = expression(); - consume(IToken.tRPAREN); + int lastOffset = consume(IToken.tRPAREN).getEndOffset(); if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); + templateIdScopes.pop(); } ICPPASTTypenameExpression result = createTypenameExpression(); - ((ASTNode)result).setOffset( o ); - result.setIsTemplate(templateTokenConsumed ); - result.setName( name ); - name.setParent( result ); - name.setPropertyInParent( ICPPASTTypenameExpression.TYPENAME); - result.setInitialValue( expressionList ); - expressionList.setParent( result ); - expressionList.setPropertyInParent( ICPPASTTypenameExpression.INITIAL_VALUE ); + ((ASTNode) result).setOffsetAndLength(o, lastOffset - o); + result.setIsTemplate(templateTokenConsumed); + result.setName(name); + name.setParent(result); + name.setPropertyInParent(ICPPASTTypenameExpression.TYPENAME); + result.setInitialValue(expressionList); + expressionList.setParent(result); + expressionList + .setPropertyInParent(ICPPASTTypenameExpression.INITIAL_VALUE); firstExpression = result; break; - // simple-type-specifier ( assignment-expression , .. ) - case IToken.t_char: + // simple-type-specifier ( assignment-expression , .. ) + case IToken.t_char: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_char); break; - case IToken.t_wchar_t: - firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_wchar_t ); + case IToken.t_wchar_t: + firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_wchar_t); break; - case IToken.t_bool: + case IToken.t_bool: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_bool); break; - case IToken.t_short: + case IToken.t_short: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_short); break; - case IToken.t_int: + case IToken.t_int: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_int); break; - case IToken.t_long: + case IToken.t_long: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_long); break; - case IToken.t_signed: + case IToken.t_signed: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_signed); break; - case IToken.t_unsigned: + case IToken.t_unsigned: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_unsigned); break; - case IToken.t_float: + case IToken.t_float: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_float); break; - case IToken.t_double: + case IToken.t_double: firstExpression = simpleTypeConstructorExpression(ICPPASTSimpleTypeConstructorExpression.t_double); break; - case IToken.t_dynamic_cast: - firstExpression = specialCastExpression( ICPPASTCastExpression.op_dynamic_cast ); + case IToken.t_dynamic_cast: + firstExpression = specialCastExpression(ICPPASTCastExpression.op_dynamic_cast); break; - case IToken.t_static_cast: - firstExpression = specialCastExpression( ICPPASTCastExpression.op_static_cast ); + case IToken.t_static_cast: + firstExpression = specialCastExpression(ICPPASTCastExpression.op_static_cast); break; - case IToken.t_reinterpret_cast: - firstExpression = specialCastExpression(ICPPASTCastExpression.op_reinterpret_cast ); + case IToken.t_reinterpret_cast: + firstExpression = specialCastExpression(ICPPASTCastExpression.op_reinterpret_cast); break; - case IToken.t_const_cast: + case IToken.t_const_cast: firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast); break; - case IToken.t_typeid: + case IToken.t_typeid: int so = consume().getOffset(); consume(IToken.tLPAREN); if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); + templateIdScopes.push(IToken.tLPAREN); } boolean isTypeId = true; IASTExpression lhs = null; IASTTypeId typeId = null; + try { - typeId = typeId(false); + typeId = typeId(false); } catch (BacktrackException b) { - isTypeId = false; - lhs = expression(); + isTypeId = false; + lhs = expression(); } - consume(IToken.tRPAREN); + lastOffset = consume(IToken.tRPAREN).getOffset(); if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); + templateIdScopes.pop(); } - if( isTypeId && typeId != null ) - firstExpression = buildTypeIdExpression( ICPPASTTypeIdExpression.op_typeid, typeId, so ); + if (isTypeId && typeId != null) + firstExpression = buildTypeIdExpression( + ICPPASTTypeIdExpression.op_typeid, typeId, so, lastOffset); else - firstExpression = buildUnaryExpression( ICPPASTUnaryExpression.op_typeid, lhs, so ); + firstExpression = buildUnaryExpression( + ICPPASTUnaryExpression.op_typeid, lhs, so, lastOffset); break; - default: + default: firstExpression = primaryExpression(); - } - IASTExpression secondExpression = null; - for (;;) { - switch (LT(1)) { - case IToken.tLBRACKET: - // array access - consume(IToken.tLBRACKET); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLBRACKET); - } - secondExpression = expression(); - consume(IToken.tRBRACKET); - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } + } + IASTExpression secondExpression = null; + for (;;) { + switch (LT(1)) { + case IToken.tLBRACKET: + // array access + consume(IToken.tLBRACKET); + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLBRACKET); + } + secondExpression = expression(); + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } - IASTArraySubscriptExpression s = createArraySubscriptExpression(); - ((ASTNode)s).setOffset( ((ASTNode)firstExpression).getOffset() ); - s.setArrayExpression( firstExpression ); - firstExpression.setParent( s ); - firstExpression.setPropertyInParent( IASTArraySubscriptExpression.ARRAY ); - s.setSubscriptExpression( secondExpression ); - secondExpression.setParent( s ); - secondExpression.setPropertyInParent( IASTArraySubscriptExpression.SUBSCRIPT ); - firstExpression = s; - break; + IASTArraySubscriptExpression s = createArraySubscriptExpression(); + ((ASTNode) s).setOffsetAndLength(((ASTNode) firstExpression) + .getOffset(), lastOffset + - ((ASTNode) firstExpression).getOffset()); + s.setArrayExpression(firstExpression); + firstExpression.setParent(s); + firstExpression + .setPropertyInParent(IASTArraySubscriptExpression.ARRAY); + s.setSubscriptExpression(secondExpression); + secondExpression.setParent(s); + secondExpression + .setPropertyInParent(IASTArraySubscriptExpression.SUBSCRIPT); + firstExpression = s; + break; case IToken.tLPAREN: - // function call - consume(IToken.tLPAREN); + // function call + consume(IToken.tLPAREN); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); - } - if( LT(1) != IToken.tRPAREN ) - secondExpression = expression(); - else - secondExpression = null; - consume(IToken.tRPAREN); - - if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); - } - - IASTFunctionCallExpression fce = createFunctionCallExpression(); - ((ASTNode)fce).setOffset( ((ASTNode)firstExpression).getOffset()); - fce.setFunctionNameExpression( firstExpression ); - firstExpression.setParent( fce ); - firstExpression.setPropertyInParent( IASTFunctionCallExpression.FUNCTION_NAME ); - if( secondExpression != null ) - { - fce.setParameterExpression( secondExpression ); - secondExpression.setParent( fce ); - secondExpression.setPropertyInParent( IASTFunctionCallExpression.PARAMETERS ); - } - firstExpression = fce; - break; + if (templateIdScopes.size() > 0) { + templateIdScopes.push(IToken.tLPAREN); + } + if (LT(1) != IToken.tRPAREN) + secondExpression = expression(); + else + secondExpression = null; + lastOffset = consume(IToken.tRPAREN).getEndOffset(); + + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } + + IASTFunctionCallExpression fce = createFunctionCallExpression(); + ((ASTNode) fce).setOffsetAndLength(((ASTNode) firstExpression) + .getOffset(), lastOffset + - ((ASTNode) firstExpression).getOffset()); + fce.setFunctionNameExpression(firstExpression); + firstExpression.setParent(fce); + firstExpression + .setPropertyInParent(IASTFunctionCallExpression.FUNCTION_NAME); + if (secondExpression != null) { + fce.setParameterExpression(secondExpression); + secondExpression.setParent(fce); + secondExpression + .setPropertyInParent(IASTFunctionCallExpression.PARAMETERS); + } + firstExpression = fce; + break; case IToken.tINCR: - int offset = consume(IToken.tINCR).getOffset(); - firstExpression = buildUnaryExpression( IASTUnaryExpression.op_postFixIncr, firstExpression, offset ); - break; + int offset = consume(IToken.tINCR).getEndOffset(); + firstExpression = buildUnaryExpression( + IASTUnaryExpression.op_postFixIncr, firstExpression, + ((ASTNode) firstExpression).getOffset(), offset); + break; case IToken.tDECR: - offset = consume().getOffset(); - firstExpression = buildUnaryExpression( IASTUnaryExpression.op_postFixDecr, firstExpression, offset ); - break; + offset = consume().getEndOffset(); + firstExpression = buildUnaryExpression( + IASTUnaryExpression.op_postFixDecr, firstExpression, + ((ASTNode) firstExpression).getOffset(), offset); + break; case IToken.tDOT: - // member access - consume(IToken.tDOT); - if (LT(1) == IToken.t_template) { - consume(IToken.t_template); - isTemplate = true; - } + // member access + consume(IToken.tDOT); + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + isTemplate = true; + } - IASTName name = createName( idExpression() ); + IASTName name = createName(idExpression()); - ICPPASTFieldReference fieldReference = createFieldReference(); - ((ASTNode)fieldReference).setOffset( ((ASTNode)firstExpression).getOffset()); - fieldReference.setIsTemplate( isTemplate ); - fieldReference.setIsPointerDereference(false); - fieldReference.setFieldName( name ); - name.setParent( fieldReference ); - name.setPropertyInParent( IASTFieldReference.FIELD_NAME ); - - fieldReference.setFieldOwner( firstExpression ); - firstExpression.setParent( fieldReference ); - firstExpression.setPropertyInParent( IASTFieldReference.FIELD_OWNER ); - firstExpression = fieldReference; - break; + ICPPASTFieldReference fieldReference = createFieldReference(); + ((ASTNode) fieldReference).setOffsetAndLength( + ((ASTNode) firstExpression).getOffset(), lastToken + .getEndOffset() + - ((ASTNode) firstExpression).getOffset()); + fieldReference.setIsTemplate(isTemplate); + fieldReference.setIsPointerDereference(false); + fieldReference.setFieldName(name); + name.setParent(fieldReference); + name.setPropertyInParent(IASTFieldReference.FIELD_NAME); + + fieldReference.setFieldOwner(firstExpression); + firstExpression.setParent(fieldReference); + firstExpression + .setPropertyInParent(IASTFieldReference.FIELD_OWNER); + firstExpression = fieldReference; + break; case IToken.tARROW: - // member access - consume(IToken.tARROW); + // member access + consume(IToken.tARROW); - if (LT(1) == IToken.t_template) { - consume(IToken.t_template); - isTemplate = true; - } - - name = createName( idExpression() ); - - fieldReference = createFieldReference(); - ((ASTNode)fieldReference).setOffset( ((ASTNode)firstExpression).getOffset()); - fieldReference.setIsTemplate( isTemplate ); - fieldReference.setIsPointerDereference(true); - fieldReference.setFieldName( name ); - name.setParent( fieldReference ); - name.setPropertyInParent( IASTFieldReference.FIELD_NAME ); - - fieldReference.setFieldOwner( firstExpression ); - firstExpression.setParent( fieldReference ); - firstExpression.setPropertyInParent( IASTFieldReference.FIELD_OWNER ); - firstExpression = fieldReference; - break; + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + isTemplate = true; + } + + name = createName(idExpression()); + + fieldReference = createFieldReference(); + ((ASTNode) fieldReference).setOffsetAndLength( + ((ASTNode) firstExpression).getOffset(), lastToken + .getEndOffset() + - ((ASTNode) firstExpression).getOffset()); + fieldReference.setIsTemplate(isTemplate); + fieldReference.setIsPointerDereference(true); + fieldReference.setFieldName(name); + name.setParent(fieldReference); + name.setPropertyInParent(IASTFieldReference.FIELD_NAME); + + fieldReference.setFieldOwner(firstExpression); + firstExpression.setParent(fieldReference); + firstExpression + .setPropertyInParent(IASTFieldReference.FIELD_OWNER); + firstExpression = fieldReference; + break; default: - return firstExpression; - } - } - } + return firstExpression; + } + } + } - /** - * @return - */ - protected IASTArraySubscriptExpression createArraySubscriptExpression() { - return new CPPASTArraySubscriptExpression(); - } + /** + * @return + */ + protected IASTArraySubscriptExpression createArraySubscriptExpression() { + return new CPPASTArraySubscriptExpression(); + } - /** - * @return - */ - protected ICPPASTTypenameExpression createTypenameExpression() { - return new CPPASTTypenameExpression(); - } + /** + * @return + */ + protected ICPPASTTypenameExpression createTypenameExpression() { + return new CPPASTTypenameExpression(); + } - /** - * @return - */ - protected IASTFunctionCallExpression createFunctionCallExpression() { - return new CPPASTFunctionCallExpression(); - } + /** + * @return + */ + protected IASTFunctionCallExpression createFunctionCallExpression() { + return new CPPASTFunctionCallExpression(); + } - /** - * @return - */ - protected ICPPASTFieldReference createFieldReference() { - return new CPPASTFieldReference(); - } + /** + * @return + */ + protected ICPPASTFieldReference createFieldReference() { + return new CPPASTFieldReference(); + } - protected IASTExpression simpleTypeConstructorExpression(int operator) - throws EndOfFileException, BacktrackException { - int startingOffset = LA(1).getOffset(); - consume(); - consume(IToken.tLPAREN); - IASTExpression operand = expression(); - consume(IToken.tRPAREN); - ICPPASTSimpleTypeConstructorExpression result = createSimpleTypeConstructorExpression(); - ((ASTNode)result).setOffset( startingOffset ); - result.setSimpleType( operator ); - result.setInitialValue( operand ); - operand.setParent( result ); - operand.setPropertyInParent( ICPPASTSimpleTypeConstructorExpression.INITIALIZER_VALUE ); - return result; - } + protected IASTExpression simpleTypeConstructorExpression(int operator) + throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + consume(); + consume(IToken.tLPAREN); + IASTExpression operand = expression(); + consume(IToken.tRPAREN); + ICPPASTSimpleTypeConstructorExpression result = createSimpleTypeConstructorExpression(); + ((ASTNode) result).setOffsetAndLength(startingOffset, lastToken + .getEndOffset() + - startingOffset); + result.setSimpleType(operator); + result.setInitialValue(operand); + operand.setParent(result); + operand + .setPropertyInParent(ICPPASTSimpleTypeConstructorExpression.INITIALIZER_VALUE); + return result; + } - /** - * @return - */ - protected ICPPASTSimpleTypeConstructorExpression createSimpleTypeConstructorExpression() { - return new CPPASTSimpleTypeConstructorExpression(); - } + /** + * @return + */ + protected ICPPASTSimpleTypeConstructorExpression createSimpleTypeConstructorExpression() { + return new CPPASTSimpleTypeConstructorExpression(); + } - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression primaryExpression() throws EndOfFileException, - BacktrackException { - IToken t = null; - ICPPASTLiteralExpression literalExpression = null; - switch (LT(1)) { - // TO DO: we need more literals... - case IToken.tINTEGER: + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression primaryExpression() throws EndOfFileException, + BacktrackException { + IToken t = null; + ICPPASTLiteralExpression literalExpression = null; + switch (LT(1)) { + // TO DO: we need more literals... + case IToken.tINTEGER: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( IASTLiteralExpression.lk_integer_constant); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.tFLOATINGPT: + literalExpression = createLiteralExpression(); + literalExpression + .setKind(IASTLiteralExpression.lk_integer_constant); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.tFLOATINGPT: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( IASTLiteralExpression.lk_float_constant ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.tSTRING: - case IToken.tLSTRING: + literalExpression = createLiteralExpression(); + literalExpression.setKind(IASTLiteralExpression.lk_float_constant); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.tSTRING: + case IToken.tLSTRING: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( IASTLiteralExpression.lk_string_literal ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.tCHAR: - case IToken.tLCHAR: + literalExpression = createLiteralExpression(); + literalExpression.setKind(IASTLiteralExpression.lk_string_literal); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.tCHAR: + case IToken.tLCHAR: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( IASTLiteralExpression.lk_char_constant ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.t_false: + literalExpression = createLiteralExpression(); + literalExpression.setKind(IASTLiteralExpression.lk_char_constant); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.t_false: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( ICPPASTLiteralExpression.lk_false ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.t_true: + literalExpression = createLiteralExpression(); + literalExpression.setKind(ICPPASTLiteralExpression.lk_false); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.t_true: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( ICPPASTLiteralExpression.lk_true ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; + literalExpression = createLiteralExpression(); + literalExpression.setKind(ICPPASTLiteralExpression.lk_true); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; - case IToken.t_this: + case IToken.t_this: t = consume(); - literalExpression = createLiteralExpression(); - literalExpression.setKind( ICPPASTLiteralExpression.lk_this ); - literalExpression.setValue( t.getImage() ); - ((ASTNode)literalExpression).setOffset( t.getOffset() ); - return literalExpression; - case IToken.tLPAREN: + literalExpression = createLiteralExpression(); + literalExpression.setKind(ICPPASTLiteralExpression.lk_this); + literalExpression.setValue(t.getImage()); + ((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t + .getEndOffset() + - t.getOffset()); + return literalExpression; + case IToken.tLPAREN: t = consume(); - if (templateIdScopes.size() > 0) { - templateIdScopes.push(IToken.tLPAREN); - } - //TODO - do we need to return a wrapper? - IASTExpression lhs = expression(); - consume(IToken.tRPAREN); if (templateIdScopes.size() > 0) { - templateIdScopes.pop(); + templateIdScopes.push(IToken.tLPAREN); } - return lhs; - case IToken.tIDENTIFIER: - case IToken.tCOLONCOLON: - case IToken.t_operator: - case IToken.tCOMPL: - ITokenDuple duple =idExpression(); - IASTName name = createName( duple ); - IASTIdExpression idExpression = createIdExpression(); - ((ASTNode)idExpression).setOffset( duple.getStartOffset() ); - idExpression.setName( name ); - name.setParent( idExpression ); - name.setPropertyInParent( IASTIdExpression.ID_NAME ); + //TODO We need to wrap this + IASTExpression lhs = expression(); + consume(IToken.tRPAREN).getEndOffset(); + if (templateIdScopes.size() > 0) { + templateIdScopes.pop(); + } + return lhs; + case IToken.tIDENTIFIER: + case IToken.tCOLONCOLON: + case IToken.t_operator: + case IToken.tCOMPL: + ITokenDuple duple = idExpression(); + IASTName name = createName(duple); + IASTIdExpression idExpression = createIdExpression(); + ((ASTNode) idExpression).setOffsetAndLength(duple.getStartOffset(), + duple.getEndOffset() - duple.getStartOffset()); + idExpression.setName(name); + name.setParent(idExpression); + name.setPropertyInParent(IASTIdExpression.ID_NAME); return idExpression; - default: + default: IToken la = LA(1); int startingOffset = la.getOffset(); throwBacktrack(startingOffset, la.getLength()); return null; - } + } - } - - /** - * @return - */ - protected ICPPASTLiteralExpression createLiteralExpression() { - return new CPPASTLiteralExpression(); - } + } - /** - * @return - */ - protected IASTIdExpression createIdExpression() { - return new CPPASTIdExpression(); - } + /** + * @return + */ + protected ICPPASTLiteralExpression createLiteralExpression() { + return new CPPASTLiteralExpression(); + } - protected ITokenDuple idExpression() throws EndOfFileException, BacktrackException - { - ITokenDuple duple = null; - try { - duple = name(); - } catch (BacktrackException bt) { - IToken mark = mark(); - if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { - IToken start = consume(); - IToken end = null; - if (start.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); - while (LT(1) == IToken.tCOLONCOLON - || LT(1) == IToken.tIDENTIFIER) { - end = consume(); - if (end.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); - } - - if (LT(1) == IToken.t_operator) - duple = operatorId(start, null); - else { - backup(mark); - throwBacktrack(start.getOffset(), end.getEndOffset() - start.getOffset() ); - } - } else if (LT(1) == IToken.t_operator) - duple = operatorId(null, null); - } - return duple; + /** + * @return + */ + protected IASTIdExpression createIdExpression() { + return new CPPASTIdExpression(); + } - } + protected ITokenDuple idExpression() throws EndOfFileException, + BacktrackException { + ITokenDuple duple = null; + try { + duple = name(); + } catch (BacktrackException bt) { + IToken mark = mark(); + if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { + IToken start = consume(); + IToken end = null; + if (start.getType() == IToken.tIDENTIFIER) + end = consumeTemplateParameters(end); + while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { + end = consume(); + if (end.getType() == IToken.tIDENTIFIER) + end = consumeTemplateParameters(end); + } - protected IASTExpression specialCastExpression(int kind) throws EndOfFileException, - BacktrackException { - int startingOffset = LA(1).getOffset(); - consume(); - consume(IToken.tLT); - IASTTypeId typeID = typeId(false); - consume(IToken.tGT); - consume(IToken.tLPAREN); - IASTExpression lhs = expression(); - consume(IToken.tRPAREN); - IASTCastExpression result = createCastExpression(); - ((ASTNode)result).setOffset( startingOffset ); - result.setTypeId( typeID ); - typeID.setParent( result ); - typeID.setPropertyInParent( IASTCastExpression.TYPE_ID ); - result.setOperand( lhs ); - lhs.setParent( result ); - lhs.setPropertyInParent( IASTCastExpression.OPERAND ); - return result; - } + if (LT(1) == IToken.t_operator) + duple = operatorId(start, null); + else { + backup(mark); + throwBacktrack(start.getOffset(), end.getEndOffset() + - start.getOffset()); + } + } else if (LT(1) == IToken.t_operator) + duple = operatorId(null, null); + } + return duple; - private final boolean allowCPPRestrict; + } + protected IASTExpression specialCastExpression(int kind) + throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + consume(); + consume(IToken.tLT); + IASTTypeId typeID = typeId(false); + consume(IToken.tGT); + consume(IToken.tLPAREN); + IASTExpression lhs = expression(); + consume(IToken.tRPAREN); + IASTCastExpression result = createCastExpression(); + ((ASTNode) result).setOffsetAndLength(startingOffset, lastToken + .getEndOffset() + - startingOffset); + result.setTypeId(typeID); + typeID.setParent(result); + typeID.setPropertyInParent(IASTCastExpression.TYPE_ID); + result.setOperand(lhs); + lhs.setParent(result); + lhs.setPropertyInParent(IASTCastExpression.OPERAND); + return result; + } - private final boolean supportExtendedTemplateSyntax; - private final boolean supportMinAndMaxOperators; - private final boolean supportComplex; - private final boolean supportRestrict; - private final boolean supportLongLong; - - private static final int DEFAULT_PARM_LIST_SIZE = 4; - private static final int DEFAULT_DECLARATOR_LIST_SIZE = 4; - private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; - private static final int DEFAULT_SIZE_EXCEPTIONS_LIST = 2; - private static final int DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE = 4; - + private final boolean allowCPPRestrict; - /** - * This is the standard cosntructor that we expect the Parser to be - * instantiated with. - * @param mode - * TODO - * - */ - public GNUCPPSourceParser(IScanner scanner, ParserMode mode, - IParserLogService log, ICPPParserExtensionConfiguration config) { - super( scanner, log, mode, config.supportStatementsInExpressions(), config.supportTypeofUnaryExpressions(), - config.supportAlignOfUnaryExpression() ); - allowCPPRestrict = config.allowRestrictPointerOperators(); - supportExtendedTemplateSyntax = config - .supportExtendedTemplateSyntax(); - supportMinAndMaxOperators = config.supportMinAndMaxOperators(); - supportRestrict = config.supportRestrictKeyword(); - supportComplex = config.supportComplexNumbers(); - supportLongLong = config.supportLongLongs(); - } + private final boolean supportExtendedTemplateSyntax; + private final boolean supportMinAndMaxOperators; + private final boolean supportComplex; + private final boolean supportRestrict; + private final boolean supportLongLong; - - /** - * The merger of using-declaration and using-directive in ANSI C++ grammar. - * - * using-declaration: using typename? ::? nested-name-specifier - * unqualified-id ; using :: unqualified-id ; using-directive: using - * namespace ::? nested-name-specifier? namespace-name ; - * - * @param container - * Callback object representing the scope these definitions fall - * into. - * @return TODO - * @throws BacktrackException - * request for a backtrack - */ - protected IASTDeclaration usingClause() throws EndOfFileException, - BacktrackException { - IToken firstToken = consume(IToken.t_using); + private static final int DEFAULT_PARM_LIST_SIZE = 4; + private static final int DEFAULT_DECLARATOR_LIST_SIZE = 4; + private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4; + private static final int DEFAULT_SIZE_EXCEPTIONS_LIST = 2; + private static final int DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE = 4; - if (LT(1) == IToken.t_namespace) { - // using-directive - consume(IToken.t_namespace); + /** + * This is the standard cosntructor that we expect the Parser to be + * instantiated with. + * + * @param mode + * TODO + * + */ + public GNUCPPSourceParser(IScanner scanner, ParserMode mode, + IParserLogService log, ICPPParserExtensionConfiguration config) { + super(scanner, log, mode, config.supportStatementsInExpressions(), config + .supportTypeofUnaryExpressions(), config + .supportAlignOfUnaryExpression()); + allowCPPRestrict = config.allowRestrictPointerOperators(); + supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax(); + supportMinAndMaxOperators = config.supportMinAndMaxOperators(); + supportRestrict = config.supportRestrictKeyword(); + supportComplex = config.supportComplexNumbers(); + supportLongLong = config.supportLongLongs(); + } - int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; - IASTName name = null; - if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) - name = createName( name() ); - else - throwBacktrack(firstToken.getOffset(), endOffset - firstToken.getOffset() ); - - consume(IToken.tSEMI); - ICPPASTUsingDirective astUD = createUsingDirective(); - ((ASTNode)astUD).setOffset( firstToken.getOffset() ); - astUD.setQualifiedName( name ); - name.setParent( astUD ); - name.setPropertyInParent( ICPPASTUsingDirective.QUALIFIED_NAME ); - return astUD; - } - - boolean typeName = false; + /** + * The merger of using-declaration and using-directive in ANSI C++ grammar. + * + * using-declaration: using typename? ::? nested-name-specifier + * unqualified-id ; using :: unqualified-id ; using-directive: using + * namespace ::? nested-name-specifier? namespace-name ; + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ + protected IASTDeclaration usingClause() throws EndOfFileException, + BacktrackException { + IToken firstToken = consume(IToken.t_using); - if (LT(1) == IToken.t_typename) { - typeName = true; - consume(IToken.t_typename); - } + if (LT(1) == IToken.t_namespace) { + // using-directive + consume(IToken.t_namespace); - IASTName name = createName( name() ); - consume( IToken.tSEMI ); - ICPPASTUsingDeclaration result = createUsingDeclaration(); - ((ASTNode)result).setOffset( firstToken.getOffset() ); - result.setIsTypename( typeName ); - result.setName( name ); - name.setPropertyInParent( ICPPASTUsingDeclaration.NAME ); - name.setParent( result ); - return result; - } + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + IASTName name = null; + if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) + name = createName(name()); + else + throwBacktrack(firstToken.getOffset(), endOffset + - firstToken.getOffset()); - /** - * @return - */ - protected ICPPASTUsingDeclaration createUsingDeclaration() { - return new CPPASTUsingDeclaration(); - } + consume(IToken.tSEMI); + ICPPASTUsingDirective astUD = createUsingDirective(); + ((ASTNode) astUD).setOffsetAndLength(firstToken.getOffset(), lastToken + .getEndOffset() + - firstToken.getOffset()); + astUD.setQualifiedName(name); + name.setParent(astUD); + name.setPropertyInParent(ICPPASTUsingDirective.QUALIFIED_NAME); + return astUD; + } - /** - * @return - */ - protected ICPPASTUsingDirective createUsingDirective() { - return new CPPASTUsingDirective(); - } + boolean typeName = false; - /** - * Implements Linkage specification in the ANSI C++ grammar. - * - * linkageSpecification : extern "string literal" declaration | extern - * "string literal" { declaration-seq } - * - * @param container - * Callback object representing the scope these definitions fall - * into. - * @return TODO - * @throws BacktrackException - * request for a backtrack - */ - protected ICPPASTLinkageSpecification linkageSpecification() - throws EndOfFileException, BacktrackException { - IToken firstToken = consume(IToken.t_extern); - IToken spec = consume(IToken.tSTRING); - ICPPASTLinkageSpecification linkage = createLinkageSpecification(); - ((ASTNode)linkage).setOffset( firstToken.getOffset() ); - linkage.setLiteral( spec.getImage() ); + if (LT(1) == IToken.t_typename) { + typeName = true; + consume(IToken.t_typename); + } - if (LT(1) == IToken.tLBRACE) { - consume(IToken.tLBRACE); + IASTName name = createName(name()); + consume(IToken.tSEMI); + ICPPASTUsingDeclaration result = createUsingDeclaration(); + ((ASTNode) result).setOffsetAndLength(firstToken.getOffset(), lastToken + .getEndOffset() + - firstToken.getOffset()); + result.setIsTypename(typeName); + result.setName(name); + name.setPropertyInParent(ICPPASTUsingDeclaration.NAME); + name.setParent(result); + return result; + } - linkageDeclarationLoop: while (LT(1) != IToken.tRBRACE) { - int checkToken = LA(1).hashCode(); - switch (LT(1)) { - case IToken.tRBRACE: - break linkageDeclarationLoop; - default: - try { - IASTDeclaration d = declaration(); - linkage.addDeclaration(d); - d.setParent( linkage ); - d.setPropertyInParent( ICPPASTLinkageSpecification.OWNED_DECLARATION ); - } catch (BacktrackException bt) { - IASTProblem p = failParse(bt); - IASTProblemDeclaration pd = createProblemDeclaration(); - p.setParent( pd ); - pd.setProblem( p ); - ((CPPASTNode)pd).setOffset( ((CPPASTNode)p).getOffset() ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - linkage.addDeclaration( pd ); - pd.setParent( linkage ); - pd.setPropertyInParent( ICPPASTLinkageSpecification.OWNED_DECLARATION ); + /** + * @return + */ + protected ICPPASTUsingDeclaration createUsingDeclaration() { + return new CPPASTUsingDeclaration(); + } + + /** + * @return + */ + protected ICPPASTUsingDirective createUsingDirective() { + return new CPPASTUsingDirective(); + } + + /** + * Implements Linkage specification in the ANSI C++ grammar. + * + * linkageSpecification : extern "string literal" declaration | extern + * "string literal" { declaration-seq } + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ + protected ICPPASTLinkageSpecification linkageSpecification() + throws EndOfFileException, BacktrackException { + IToken firstToken = consume(IToken.t_extern); + IToken spec = consume(IToken.tSTRING); + ICPPASTLinkageSpecification linkage = createLinkageSpecification(); + ((ASTNode) linkage).setOffset(firstToken.getOffset()); + linkage.setLiteral(spec.getImage()); + + if (LT(1) == IToken.tLBRACE) { + consume(IToken.tLBRACE); + + linkageDeclarationLoop: while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + switch (LT(1)) { + case IToken.tRBRACE: + break linkageDeclarationLoop; + default: + try { + IASTDeclaration d = declaration(); + linkage.addDeclaration(d); + d.setParent(linkage); + d + .setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION); + } catch (BacktrackException bt) { + IASTProblem p = failParse(bt); + IASTProblemDeclaration pd = createProblemDeclaration(); + p.setParent(pd); + pd.setProblem(p); + ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p)); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + linkage.addDeclaration(pd); + pd.setParent(linkage); + pd + .setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION); + errorHandling(); + if (checkToken == LA(1).hashCode()) errorHandling(); - if (checkToken == LA(1).hashCode()) - errorHandling(); - } - } - if (checkToken == LA(1).hashCode()) - failParseWithErrorHandling(); + } } - // consume the } - consume(IToken.tRBRACE); - return linkage; - } - // single declaration + if (checkToken == LA(1).hashCode()) + failParseWithErrorHandling(); + } + // consume the } + int endOffset = consume(IToken.tRBRACE).getEndOffset(); + ((CPPASTNode) linkage).setOffset(endOffset - firstToken.getOffset()); + return linkage; + } + // single declaration - IASTDeclaration d = declaration(); - linkage.addDeclaration(d); - d.setParent( linkage ); - d.setPropertyInParent( ICPPASTLinkageSpecification.OWNED_DECLARATION ); - return linkage; - } + IASTDeclaration d = declaration(); + linkage.addDeclaration(d); + d.setParent(linkage); + d.setPropertyInParent(ICPPASTLinkageSpecification.OWNED_DECLARATION); + return linkage; + } - /** - * @return - */ - protected ICPPASTLinkageSpecification createLinkageSpecification() { - return new CPPASTLinkageSpecification(); - } + /** + * @return + */ + protected ICPPASTLinkageSpecification createLinkageSpecification() { + return new CPPASTLinkageSpecification(); + } - /** - * - * Represents the emalgamation of template declarations, template - * instantiations and specializations in the ANSI C++ grammar. - * - * template-declaration: export? template < template-parameter-list > - * declaration explicit-instantiation: template declaration - * explicit-specialization: template <>declaration - * - * @param container - * Callback object representing the scope these definitions fall - * into. - * @return TODO - * @throws BacktrackException - * request for a backtrack - */ - protected IASTDeclaration templateDeclaration() - throws EndOfFileException, BacktrackException { - IToken mark = mark(); - IToken firstToken = null; - boolean exported = false; - boolean encounteredExtraMod = false; - if (LT(1) == IToken.t_export) { - exported = true; - firstToken = consume(IToken.t_export); - consume(IToken.t_template); - } else { - if (supportExtendedTemplateSyntax) { - switch (LT(1)) { - case IToken.t_static: - case IToken.t_extern: - case IToken.t_inline: - firstToken = consume(); - consume(IToken.t_template); - encounteredExtraMod = true; - break; - default: - firstToken = consume(IToken.t_template); - break; - } - } else - firstToken = consume(IToken.t_template); - } - if (LT(1) != IToken.tLT) { - // explicit-instantiation - ICPPASTExplicitTemplateInstantiation templateInstantiation = null; - if( encounteredExtraMod && supportExtendedTemplateSyntax ) + /** + * + * Represents the emalgamation of template declarations, template + * instantiations and specializations in the ANSI C++ grammar. + * + * template-declaration: export? template < template-parameter-list > + * declaration explicit-instantiation: template declaration + * explicit-specialization: template <>declaration + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ + protected IASTDeclaration templateDeclaration() throws EndOfFileException, + BacktrackException { + IToken mark = mark(); + IToken firstToken = null; + boolean exported = false; + boolean encounteredExtraMod = false; + if (LT(1) == IToken.t_export) { + exported = true; + firstToken = consume(IToken.t_export); + consume(IToken.t_template); + } else { + if (supportExtendedTemplateSyntax) { + switch (LT(1)) { + case IToken.t_static: + case IToken.t_extern: + case IToken.t_inline: + firstToken = consume(); + consume(IToken.t_template); + encounteredExtraMod = true; + break; + default: + firstToken = consume(IToken.t_template); + break; + } + } else + firstToken = consume(IToken.t_template); + } + if (LT(1) != IToken.tLT) { + // explicit-instantiation + ICPPASTExplicitTemplateInstantiation templateInstantiation = null; + if (encounteredExtraMod && supportExtendedTemplateSyntax) { + IGPPASTExplicitTemplateInstantiation temp = createGnuTemplateInstantiation(); + switch (firstToken.getType()) { + case IToken.t_static: + temp + .setModifier(IGPPASTExplicitTemplateInstantiation.ti_static); + break; + case IToken.t_extern: + temp + .setModifier(IGPPASTExplicitTemplateInstantiation.ti_extern); + break; + case IToken.t_inline: + temp + .setModifier(IGPPASTExplicitTemplateInstantiation.ti_inline); + break; + } + templateInstantiation = temp; + } else + templateInstantiation = createTemplateInstantiation(); + IASTDeclaration d = declaration(); + ((ASTNode) templateInstantiation).setOffsetAndLength(firstToken + .getOffset(), lastToken.getEndOffset() - firstToken.getOffset()); + templateInstantiation.setDeclaration(d); + d.setParent(templateInstantiation); + d + .setPropertyInParent(ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION); + return templateInstantiation; + } + consume(IToken.tLT); + if (LT(1) == IToken.tGT) { + // explicit-specialization + consume(IToken.tGT); + + ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization(); + IASTDeclaration d = declaration(); + ((ASTNode) templateSpecialization).setOffsetAndLength(firstToken + .getOffset(), lastToken.getEndOffset() - firstToken.getOffset()); + templateSpecialization.setDeclaration(d); + d.setParent(templateSpecialization); + d.setPropertyInParent(ICPPASTTemplateSpecialization.OWNED_DECLARATION); + return templateSpecialization; + } + + try { + List parms = templateParameterList(); + consume(IToken.tGT); + IASTDeclaration d = declaration(); + ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration(); + ((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(), + lastToken.getEndOffset() - firstToken.getOffset()); + templateDecl.setExported(exported); + templateDecl.setDeclaration(d); + d.setParent(templateDecl); + d.setPropertyInParent(ICPPASTTemplateDeclaration.OWNED_DECLARATION); + for (int i = 0; i < parms.size(); ++i) { + ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms + .get(i); + templateDecl.addTemplateParamter(parm); + parm.setParent(templateDecl); + parm.setPropertyInParent(ICPPASTTemplateDeclaration.PARAMETER); + } + + return templateDecl; + } catch (BacktrackException bt) { + backup(mark); + throw bt; + } + } + + /** + * @return + */ + protected ICPPASTTemplateDeclaration createTemplateDeclaration() { + return new CPPASTTemplateDeclaration(); + } + + /** + * @return + */ + protected ICPPASTTemplateSpecialization createTemplateSpecialization() { + return new CPPASTTemplateSpecialization(); + } + + /** + * @return + */ + protected IGPPASTExplicitTemplateInstantiation createGnuTemplateInstantiation() { + return new GPPASTExplicitTemplateInstantiation(); + } + + /** + * @return + */ + protected ICPPASTExplicitTemplateInstantiation createTemplateInstantiation() { + return new CPPASTExplicitTemplateInstantiation(); + } + + /** + * + * + * + * template-parameter-list: template-parameter template-parameter-list , + * template-parameter template-parameter: type-parameter + * parameter-declaration type-parameter: class identifier? class identifier? = + * type-id typename identifier? typename identifier? = type-id template < + * template-parameter-list > class identifier? template < + * template-parameter-list > class identifier? = id-expression template-id: + * template-name < template-argument-list?> template-name: identifier + * template-argument-list: template-argument template-argument-list , + * template-argument template-argument: assignment-expression type-id + * id-expression + * + * @param templateDeclaration + * Callback's templateDeclaration which serves as a scope to this + * list. + * @throws BacktrackException + * request for a backtrack + */ + protected List templateParameterList() throws BacktrackException, + EndOfFileException { + // if we have gotten this far then we have a true template-declaration + // iterate through the template parameter list + List returnValue = new ArrayList(DEFAULT_PARM_LIST_SIZE); + + for (;;) { + if (LT(1) == IToken.tGT) + return returnValue; + if (LT(1) == IToken.t_class || LT(1) == IToken.t_typename) { + IToken startingToken = LA(1); + int type = (LT(1) == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class + : ICPPASTSimpleTypeTemplateParameter.st_typename); + consume(); + IASTName identifierName = null; + IASTTypeId typeId = null; + + if (LT(1) == IToken.tIDENTIFIER) // optional identifier { - IGPPASTExplicitTemplateInstantiation temp = createGnuTemplateInstantiation(); - switch( firstToken.getType() ) - { - case IToken.t_static: - temp.setModifier( IGPPASTExplicitTemplateInstantiation.ti_static ); - break; - case IToken.t_extern: - temp.setModifier( IGPPASTExplicitTemplateInstantiation.ti_extern ); - break; - case IToken.t_inline: - temp.setModifier( IGPPASTExplicitTemplateInstantiation.ti_inline ); - break; - } - templateInstantiation = temp; - } - else - templateInstantiation = createTemplateInstantiation(); - ((ASTNode)templateInstantiation).setOffset( firstToken.getOffset() ); - IASTDeclaration d = declaration(); - templateInstantiation.setDeclaration( d ); - d.setParent( templateInstantiation ); - d.setPropertyInParent( ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION ); - return templateInstantiation; - } - consume(IToken.tLT); - if (LT(1) == IToken.tGT) { - // explicit-specialization - consume(IToken.tGT); + identifierName = createName(identifier()); - ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization(); - ((ASTNode)templateSpecialization).setOffset( firstToken.getOffset() ); - IASTDeclaration d = declaration(); - templateSpecialization.setDeclaration( d ); - d.setParent( templateSpecialization ); - d.setPropertyInParent( ICPPASTTemplateSpecialization.OWNED_DECLARATION ); - return templateSpecialization; - } - - try { - List parms = templateParameterList(); - consume(IToken.tGT); - IASTDeclaration d = declaration(); - ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration(); - ((ASTNode)templateDecl).setOffset( firstToken.getOffset() ); - templateDecl.setExported( exported ); - templateDecl.setDeclaration( d ); - d.setParent( templateDecl ); - d.setPropertyInParent( ICPPASTTemplateDeclaration.OWNED_DECLARATION ); - for( int i = 0; i < parms.size(); ++i ) - { - ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms.get(i); - templateDecl.addTemplateParamter( parm ); - parm.setParent( templateDecl ); - parm.setPropertyInParent( ICPPASTTemplateDeclaration.PARAMETER ); - } - - return templateDecl; - } catch (BacktrackException bt) { - backup(mark); - throw bt; - } - } - - /** - * @return - */ - protected ICPPASTTemplateDeclaration createTemplateDeclaration() { - return new CPPASTTemplateDeclaration(); - } - - /** - * @return - */ - protected ICPPASTTemplateSpecialization createTemplateSpecialization() { - return new CPPASTTemplateSpecialization(); - } - - /** - * @return - */ - protected IGPPASTExplicitTemplateInstantiation createGnuTemplateInstantiation() { - return new GPPASTExplicitTemplateInstantiation(); - } - - /** - * @return - */ - protected ICPPASTExplicitTemplateInstantiation createTemplateInstantiation() { - return new CPPASTExplicitTemplateInstantiation(); - } - - /** - * - * - * - * template-parameter-list: template-parameter template-parameter-list , - * template-parameter template-parameter: type-parameter - * parameter-declaration type-parameter: class identifier? class identifier? = - * type-id typename identifier? typename identifier? = type-id template < - * template-parameter-list > class identifier? template < - * template-parameter-list > class identifier? = id-expression template-id: - * template-name < template-argument-list?> template-name: identifier - * template-argument-list: template-argument template-argument-list , - * template-argument template-argument: assignment-expression type-id - * id-expression - * - * @param templateDeclaration - * Callback's templateDeclaration which serves as a scope to this - * list. - * @throws BacktrackException - * request for a backtrack - */ - protected List templateParameterList() - throws BacktrackException, EndOfFileException { - // if we have gotten this far then we have a true template-declaration - // iterate through the template parameter list - List returnValue = new ArrayList( DEFAULT_PARM_LIST_SIZE ); - - for (;;) { - if (LT(1) == IToken.tGT) - return returnValue; - if (LT(1) == IToken.t_class || LT(1) == IToken.t_typename) { - IToken startingToken = LA(1); - int type = ( LT(1) == IToken.t_class ? ICPPASTSimpleTypeTemplateParameter.st_class : ICPPASTSimpleTypeTemplateParameter.st_typename ); - consume(); - IASTName identifierName = null; - IASTTypeId typeId = null; - - if (LT(1) == IToken.tIDENTIFIER) // optional identifier - { - identifierName = createName( identifier() ); - - if (LT(1) == IToken.tASSIGN) // optional = type-id - { - consume(IToken.tASSIGN); - typeId = typeId(false); // type-id - } - } - else - { - identifierName = createName(); - } - - ICPPASTSimpleTypeTemplateParameter parm = createSimpleTemplateParameter(); - ((ASTNode)parm).setOffset( startingToken.getOffset() ); - parm.setParameterType(type); - parm.setName( identifierName ); - identifierName.setParent( parm ); - identifierName.setPropertyInParent( ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME ); - if( typeId != null ) - { - parm.setDefaultType( typeId ); - typeId.setParent( parm ); - typeId.setPropertyInParent( ICPPASTSimpleTypeTemplateParameter.DEFAULT_TYPE ); - } - returnValue.add( parm ); - - } else if (LT(1) == IToken.t_template) { - IToken firstToken = consume(IToken.t_template); - consume(IToken.tLT); - - List subResult = templateParameterList(); - consume(IToken.tGT); - consume(IToken.t_class); - IASTName identifierName = null; - IASTExpression optionalExpression = null; - - if (LT(1) == IToken.tIDENTIFIER) // optional identifier - { - identifierName = createName( identifier() ); - - if (LT(1) == IToken.tASSIGN) // optional = type-id - { - consume(IToken.tASSIGN); - optionalExpression = primaryExpression(); - } - } - else - identifierName = createName(); - - ICPPASTTemplatedTypeTemplateParameter parm = createTemplatedTemplateParameter(); - ((ASTNode)parm).setOffset( firstToken.getOffset() ); - parm.setName( identifierName ); - identifierName.setParent( parm ); - identifierName.setPropertyInParent( ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME ); - if( optionalExpression != null ) - { - parm.setDefaultValue( optionalExpression ); - optionalExpression.setParent( parm ); - optionalExpression.setPropertyInParent( ICPPASTTemplatedTypeTemplateParameter.DEFAULT_VALUE ); - } - - for( int i = 0; i < subResult.size(); ++i ) - { - ICPPASTTemplateParameter p = (ICPPASTTemplateParameter) subResult.get(i); - parm.addTemplateParamter( p ); - p.setParent( parm ); - p.setPropertyInParent( ICPPASTTemplatedTypeTemplateParameter.PARAMETER ); - } - returnValue.add( parm ); - - } else if (LT(1) == IToken.tCOMMA) { - consume(IToken.tCOMMA); - continue; + if (LT(1) == IToken.tASSIGN) // optional = type-id + { + consume(IToken.tASSIGN); + typeId = typeId(false); // type-id + } } else { - ICPPASTParameterDeclaration parm = parameterDeclaration(); - returnValue.add( parm ); + identifierName = createName(); } - } - } - /** - * @return - */ - protected ICPPASTTemplatedTypeTemplateParameter createTemplatedTemplateParameter() { - return new CPPASTTemplatedTypeTemplateParameter(); - } + ICPPASTSimpleTypeTemplateParameter parm = createSimpleTemplateParameter(); + int l = lastToken != null ? lastToken.getEndOffset() + - startingToken.getOffset() : 0; + ((ASTNode) parm).setOffsetAndLength(startingToken.getOffset(), l); + parm.setParameterType(type); + parm.setName(identifierName); + identifierName.setParent(parm); + identifierName + .setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME); + if (typeId != null) { + parm.setDefaultType(typeId); + typeId.setParent(parm); + typeId + .setPropertyInParent(ICPPASTSimpleTypeTemplateParameter.DEFAULT_TYPE); + } + returnValue.add(parm); - /** - * @return - */ - protected ICPPASTSimpleTypeTemplateParameter createSimpleTemplateParameter() { - return new CPPASTSimpleTypeTemplateParameter(); - } + } else if (LT(1) == IToken.t_template) { + IToken firstToken = consume(IToken.t_template); + consume(IToken.tLT); - /** - * The most abstract construct within a translationUnit : a declaration. - * - * declaration : {"asm"} asmDefinition | {"namespace"} namespaceDefinition | - * {"using"} usingDeclaration | {"export"|"template"} templateDeclaration | - * {"extern"} linkageSpecification | simpleDeclaration - * - * Notes: - folded in blockDeclaration - merged alternatives that required - * same LA - functionDefinition into simpleDeclaration - - * namespaceAliasDefinition into namespaceDefinition - usingDirective into - * usingDeclaration - explicitInstantiation and explicitSpecialization into - * templateDeclaration - * - * @param container - * IParserCallback object which serves as the owner scope for - * this declaration. - * - * @throws BacktrackException - * request a backtrack - */ - protected IASTDeclaration declaration() - throws EndOfFileException, BacktrackException { - switch (LT(1)) { - case IToken.t_asm: + List subResult = templateParameterList(); + consume(IToken.tGT); + consume(IToken.t_class); + IASTName identifierName = null; + IASTExpression optionalExpression = null; + + if (LT(1) == IToken.tIDENTIFIER) // optional identifier + { + identifierName = createName(identifier()); + + if (LT(1) == IToken.tASSIGN) // optional = type-id + { + consume(IToken.tASSIGN); + optionalExpression = primaryExpression(); + } + } else + identifierName = createName(); + + ICPPASTTemplatedTypeTemplateParameter parm = createTemplatedTemplateParameter(); + ((ASTNode) parm).setOffsetAndLength(firstToken.getOffset(), + lastToken.getEndOffset() - firstToken.getOffset()); + parm.setName(identifierName); + identifierName.setParent(parm); + identifierName + .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME); + if (optionalExpression != null) { + parm.setDefaultValue(optionalExpression); + optionalExpression.setParent(parm); + optionalExpression + .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.DEFAULT_VALUE); + } + + for (int i = 0; i < subResult.size(); ++i) { + ICPPASTTemplateParameter p = (ICPPASTTemplateParameter) subResult + .get(i); + parm.addTemplateParamter(p); + p.setParent(parm); + p + .setPropertyInParent(ICPPASTTemplatedTypeTemplateParameter.PARAMETER); + } + returnValue.add(parm); + + } else if (LT(1) == IToken.tCOMMA) { + consume(IToken.tCOMMA); + continue; + } else { + ICPPASTParameterDeclaration parm = parameterDeclaration(); + returnValue.add(parm); + } + } + } + + /** + * @return + */ + protected ICPPASTTemplatedTypeTemplateParameter createTemplatedTemplateParameter() { + return new CPPASTTemplatedTypeTemplateParameter(); + } + + /** + * @return + */ + protected ICPPASTSimpleTypeTemplateParameter createSimpleTemplateParameter() { + return new CPPASTSimpleTypeTemplateParameter(); + } + + /** + * The most abstract construct within a translationUnit : a declaration. + * + * declaration : {"asm"} asmDefinition | {"namespace"} namespaceDefinition | + * {"using"} usingDeclaration | {"export"|"template"} templateDeclaration | + * {"extern"} linkageSpecification | simpleDeclaration + * + * Notes: - folded in blockDeclaration - merged alternatives that required + * same LA - functionDefinition into simpleDeclaration - + * namespaceAliasDefinition into namespaceDefinition - usingDirective into + * usingDeclaration - explicitInstantiation and explicitSpecialization into + * templateDeclaration + * + * @param container + * IParserCallback object which serves as the owner scope for this + * declaration. + * + * @throws BacktrackException + * request a backtrack + */ + protected IASTDeclaration declaration() throws EndOfFileException, + BacktrackException { + switch (LT(1)) { + case IToken.t_asm: return asmDeclaration(); - case IToken.t_namespace: + case IToken.t_namespace: return namespaceDefinitionOrAlias(); - case IToken.t_using: + case IToken.t_using: return usingClause(); - case IToken.t_export: - case IToken.t_template: + case IToken.t_export: + case IToken.t_template: return templateDeclaration(); - case IToken.t_extern: + case IToken.t_extern: if (LT(2) == IToken.tSTRING) - return linkageSpecification(); - default: + return linkageSpecification(); + default: if (supportExtendedTemplateSyntax - && (LT(1) == IToken.t_static || LT(1) == IToken.t_inline || LT(1) == IToken.t_extern) - && LT(2) == IToken.t_template) - return templateDeclaration(); + && (LT(1) == IToken.t_static || LT(1) == IToken.t_inline || LT(1) == IToken.t_extern) + && LT(2) == IToken.t_template) + return templateDeclaration(); return simpleDeclarationStrategyUnion(); - } - } + } + } - protected IASTDeclaration simpleDeclarationStrategyUnion() throws EndOfFileException, BacktrackException { - simpleDeclarationMark = mark(); - IASTProblem firstFailure = null; - IASTProblem secondFailure = null; - try { - return simpleDeclaration(SimpleDeclarationStrategy.TRY_CONSTRUCTOR, - false); - // try it first with the original strategy - } catch (BacktrackException bt) { - if (simpleDeclarationMark == null) - throwBacktrack(bt); - firstFailure = bt.getProblem(); - // did not work + protected IASTDeclaration simpleDeclarationStrategyUnion() + throws EndOfFileException, BacktrackException { + simpleDeclarationMark = mark(); + IASTProblem firstFailure = null; + IASTProblem secondFailure = null; + try { + return simpleDeclaration(SimpleDeclarationStrategy.TRY_CONSTRUCTOR, + false); + // try it first with the original strategy + } catch (BacktrackException bt) { + if (simpleDeclarationMark == null) + throwBacktrack(bt); + firstFailure = bt.getProblem(); + // did not work + backup(simpleDeclarationMark); + + try { + return simpleDeclaration(SimpleDeclarationStrategy.TRY_FUNCTION, + false); + } catch (BacktrackException bt2) { + if (simpleDeclarationMark == null) { + if (firstFailure != null && (bt2.getProblem() == null)) + throwBacktrack(firstFailure); + else + throwBacktrack(bt2); + } + + secondFailure = bt2.getProblem(); backup(simpleDeclarationMark); try { - return simpleDeclaration( - SimpleDeclarationStrategy.TRY_FUNCTION, false); - } catch (BacktrackException bt2) { - if (simpleDeclarationMark == null) { - if (firstFailure != null && (bt2.getProblem() == null)) - throwBacktrack(firstFailure); - else - throwBacktrack(bt2); - } + return simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, + false); + } catch (BacktrackException b3) { + backup(simpleDeclarationMark); //TODO - necessary? - secondFailure = bt2.getProblem(); - backup(simpleDeclarationMark); - - try { - return simpleDeclaration( - SimpleDeclarationStrategy.TRY_VARIABLE, false); - } catch (BacktrackException b3) { - backup(simpleDeclarationMark); //TODO - necessary? - - if (firstFailure != null) - throwBacktrack(firstFailure); - else if (secondFailure != null) - throwBacktrack(secondFailure); - else - throwBacktrack(b3); - return null; - } + if (firstFailure != null) + throwBacktrack(firstFailure); + else if (secondFailure != null) + throwBacktrack(secondFailure); + else + throwBacktrack(b3); + return null; } + } - } - } + } + } - /** - * Serves as the namespace declaration portion of the ANSI C++ grammar. - * - * namespace-definition: namespace identifier { namespace-body } | namespace { - * namespace-body } namespace-body: declaration-seq? - * - * @param container - * IParserCallback object which serves as the owner scope for - * this declaration. - * @return TODO - * @throws BacktrackException - * request a backtrack - * - */ - protected IASTDeclaration namespaceDefinitionOrAlias() - throws BacktrackException, EndOfFileException { + /** + * Serves as the namespace declaration portion of the ANSI C++ grammar. + * + * namespace-definition: namespace identifier { namespace-body } | namespace { + * namespace-body } namespace-body: declaration-seq? + * + * @param container + * IParserCallback object which serves as the owner scope for this + * declaration. + * @return TODO + * @throws BacktrackException + * request a backtrack + * + */ + protected IASTDeclaration namespaceDefinitionOrAlias() + throws BacktrackException, EndOfFileException { - IToken first = consume(IToken.t_namespace); - IASTName name = null; - // optional name - if (LT(1) == IToken.tIDENTIFIER) - name = createName( identifier() ); - else - name = createName(); + IToken first = consume(IToken.t_namespace); + IASTName name = null; + // optional name + if (LT(1) == IToken.tIDENTIFIER) + name = createName(identifier()); + else + name = createName(); - if (LT(1) == IToken.tLBRACE) { - consume(); - ICPPASTNamespaceDefinition namespaceDefinition = createNamespaceDefinition(); - ((ASTNode)namespaceDefinition).setOffset( first.getOffset() ); - namespaceDefinition.setName( name ); - name.setParent( namespaceDefinition ); - name.setPropertyInParent( ICPPASTNamespaceDefinition.NAMESPACE_NAME ); - - cleanupLastToken(); - namespaceDeclarationLoop: while (LT(1) != IToken.tRBRACE) { - int checkToken = LA(1).hashCode(); - switch (LT(1)) { - case IToken.tRBRACE: - break namespaceDeclarationLoop; - default: - try { - IASTDeclaration d = declaration(); - d.setParent( namespaceDefinition ); - d.setPropertyInParent( ICPPASTNamespaceDefinition.OWNED_DECLARATION ); - namespaceDefinition.addDeclaration( d ); - } catch (BacktrackException bt) { - IASTProblem p = failParse(bt); - IASTProblemDeclaration pd = createProblemDeclaration(); - p.setParent( pd ); - pd.setProblem( p ); - ((CPPASTNode)pd).setOffset( ((CPPASTNode)p).getOffset() ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - namespaceDefinition.addDeclaration( pd ); - pd.setParent( namespaceDefinition ); - pd.setPropertyInParent( ICPPASTNamespaceDefinition.OWNED_DECLARATION ); + if (LT(1) == IToken.tLBRACE) { + consume(); + ICPPASTNamespaceDefinition namespaceDefinition = createNamespaceDefinition(); + ((ASTNode) namespaceDefinition).setOffset(first.getOffset()); + namespaceDefinition.setName(name); + name.setParent(namespaceDefinition); + name.setPropertyInParent(ICPPASTNamespaceDefinition.NAMESPACE_NAME); + + cleanupLastToken(); + namespaceDeclarationLoop: while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + switch (LT(1)) { + case IToken.tRBRACE: + break namespaceDeclarationLoop; + default: + try { + IASTDeclaration d = declaration(); + d.setParent(namespaceDefinition); + d + .setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION); + namespaceDefinition.addDeclaration(d); + } catch (BacktrackException bt) { + IASTProblem p = failParse(bt); + IASTProblemDeclaration pd = createProblemDeclaration(); + p.setParent(pd); + pd.setProblem(p); + ((CPPASTNode) pd).setOffsetAndLength((CPPASTNode) p); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + namespaceDefinition.addDeclaration(pd); + pd.setParent(namespaceDefinition); + pd + .setPropertyInParent(ICPPASTNamespaceDefinition.OWNED_DECLARATION); + errorHandling(); + if (checkToken == LA(1).hashCode()) errorHandling(); - if (checkToken == LA(1).hashCode()) - errorHandling(); - } - } - if (checkToken == LA(1).hashCode()) - failParseWithErrorHandling(); + } } - // consume the } - consume(IToken.tRBRACE); + if (checkToken == LA(1).hashCode()) + failParseWithErrorHandling(); + } + // consume the } + int end = consume(IToken.tRBRACE).getEndOffset(); + ((CPPASTNode) namespaceDefinition).setLength(end - first.getOffset()); + return namespaceDefinition; + } else if (LT(1) == IToken.tASSIGN) { + IToken assign = consume(IToken.tASSIGN); - return namespaceDefinition; - } else if (LT(1) == IToken.tASSIGN) { - IToken assign = consume(IToken.tASSIGN); - - if (name.toString() == null) { - throwBacktrack(first.getOffset(), assign.getEndOffset() - first.getOffset() ); - return null; - } - - ITokenDuple duple = name(); - IASTName qualifiedName = createName( duple ); - consume(IToken.tSEMI); - - ICPPASTNamespaceAlias alias = createNamespaceAlias(); - ((ASTNode)alias).setOffset( first.getOffset() ); - alias.setAlias( name ); - name.setParent( alias ); - name.setPropertyInParent( ICPPASTNamespaceAlias.ALIAS_NAME ); - alias.setQualifiedName( qualifiedName ); - qualifiedName.setParent( alias ); - qualifiedName.setPropertyInParent( ICPPASTNamespaceAlias.MAPPING_NAME ); - return alias; - } else { - int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; - throwBacktrack(first.getOffset(), endOffset - first.getOffset() ); + if (name.toString() == null) { + throwBacktrack(first.getOffset(), assign.getEndOffset() + - first.getOffset()); return null; - } - } + } - /** - * @return - */ - protected ICPPASTNamespaceAlias createNamespaceAlias() { - return new CPPASTNamespaceAlias(); - } + ITokenDuple duple = name(); + IASTName qualifiedName = createName(duple); + int end = consume(IToken.tSEMI).getEndOffset(); - /** - * @param duple - * @return - */ - protected ICPPASTQualifiedName createQualifiedName(ITokenDuple duple) { - CPPASTQualifiedName result = new CPPASTQualifiedName(); - result.setOffset( duple.getStartOffset()); - ITokenDuple [] segments = duple.getSegments(); - for( int i = 0; i < segments.length; ++i ) - { - IASTName subName = null; - // take each name and add it to the result - if( segments[i] instanceof IToken ) - subName = createName( (IToken)segments[i]); - else if( segments[i].getTemplateIdArgLists() == null ) - subName = createName( segments[i] ); - else // templateID - subName = createTemplateID( segments[i] ); - subName.setParent( result ); - subName.setPropertyInParent( ICPPASTQualifiedName.SEGMENT_NAME ); - ((ASTNode)subName).setOffset( segments[i].getStartOffset() ); - result.addName( subName ); - } - - return result; - } + ICPPASTNamespaceAlias alias = createNamespaceAlias(); + ((ASTNode) alias).setOffsetAndLength(first.getOffset(), end + - first.getOffset()); + alias.setAlias(name); + name.setParent(alias); + name.setPropertyInParent(ICPPASTNamespaceAlias.ALIAS_NAME); + alias.setQualifiedName(qualifiedName); + qualifiedName.setParent(alias); + qualifiedName.setPropertyInParent(ICPPASTNamespaceAlias.MAPPING_NAME); + return alias; + } else { + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + throwBacktrack(first.getOffset(), endOffset - first.getOffset()); + return null; + } + } - - - /** - * @param duple - * @return - */ - protected ICPPASTTemplateId createTemplateID(ITokenDuple duple) { - ICPPASTTemplateId result = new CPPASTTemplateId(); - ((ASTNode)result).setOffset( duple.getStartOffset() ); - char [] image = duple.extractNameFromTemplateId(); - CPPASTName templateIdName = (CPPASTName) createName(); - templateIdName.setOffset(duple.getStartOffset()); - templateIdName.setName( image ); - result.setTemplateName( templateIdName ); - templateIdName.setParent( result ); - templateIdName.setPropertyInParent( ICPPASTTemplateId.TEMPLATE_NAME ); - if( duple.getTemplateIdArgLists() != null ) - { - List args = duple.getTemplateIdArgLists()[0]; - if( args != null ) - for( int i = 0; i < args.size(); ++i ) - { - IASTNode n = (IASTNode) args.get(i); - if( n instanceof IASTTypeId || n instanceof IASTExpression ) - { - n.setParent( result ); - n.setPropertyInParent( ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT ); - if( n instanceof IASTTypeId ) - result.addTemplateArgument((IASTTypeId) n); - else - result.addTemplateArgument((IASTExpression)n); - } - } - } - return result; - } + /** + * @return + */ + protected ICPPASTNamespaceAlias createNamespaceAlias() { + return new CPPASTNamespaceAlias(); + } - /** - * @param duple - * @return - */ - protected IASTName createName(ITokenDuple duple) { - if( duple == null ) return createName(); - if( duple.getSegmentCount() != 1 ) return createQualifiedName( duple ); - CPPASTName name = new CPPASTName( duple.toCharArray() ); - name.setOffset( duple.getStartOffset()); - return name; - } + /** + * @param duple + * @return + */ + protected ICPPASTQualifiedName createQualifiedName(ITokenDuple duple) { + CPPASTQualifiedName result = new CPPASTQualifiedName(); + result.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset() + - duple.getStartOffset()); + ITokenDuple[] segments = duple.getSegments(); + for (int i = 0; i < segments.length; ++i) { + IASTName subName = null; + // take each name and add it to the result + if (segments[i] instanceof IToken) + subName = createName((IToken) segments[i]); + else if (segments[i].getTemplateIdArgLists() == null) + subName = createName(segments[i]); + else + // templateID + subName = createTemplateID(segments[i]); + subName.setParent(result); + subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME); + ((ASTNode) subName).setOffsetAndLength(segments[i].getStartOffset(), + segments[i].getEndOffset() - segments[i].getStartOffset()); + result.addName(subName); + } - /** - * @return - */ - protected ICPPASTNamespaceDefinition createNamespaceDefinition() { - return new CPPASTNamespaceDefinition(); - } + return result; + } - /** - * Serves as the catch-all for all complicated declarations, including - * function-definitions. - * - * simpleDeclaration : (declSpecifier)* (initDeclarator ("," - * initDeclarator)*)? (";" | { functionBody } - * - * Notes: - append functionDefinition stuff to end of this rule - * - * To do: - work in functionTryBlock - * @param container - * IParserCallback object which serves as the owner scope for - * this declaration. - * @param tryConstructor - * true == take strategy1 (constructor ) : false == take strategy - * 2 ( pointer to function) - * @return TODO - * @throws BacktrackException - * request a backtrack - */ - protected IASTDeclaration simpleDeclaration(SimpleDeclarationStrategy strategy, - boolean fromCatchHandler) - throws BacktrackException, EndOfFileException { - IToken firstToken = LA(1); - int firstOffset = firstToken.getOffset(); - if (firstToken.getType() == IToken.tLBRACE) - throwBacktrack(firstOffset, firstToken.getLength() ); - firstToken = null; // necessary for scalability - - ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR); - List declarators = Collections.EMPTY_LIST; - if (LT(1) != IToken.tSEMI) { - declarators = new ArrayList(DEFAULT_DECLARATOR_LIST_SIZE); - declarators.add(initDeclarator(strategy)); - while (LT(1) == IToken.tCOMMA) { - consume(IToken.tCOMMA); - declarators.add( initDeclarator(strategy ) ); + /** + * @param duple + * @return + */ + protected ICPPASTTemplateId createTemplateID(ITokenDuple duple) { + ICPPASTTemplateId result = new CPPASTTemplateId(); + ((ASTNode) result).setOffsetAndLength(duple.getStartOffset(), duple + .getEndOffset() + - duple.getStartOffset()); + char[] image = duple.extractNameFromTemplateId(); + CPPASTName templateIdName = (CPPASTName) createName(); + templateIdName.setOffsetAndLength(duple.getStartOffset(), image.length); + templateIdName.setName(image); + result.setTemplateName(templateIdName); + templateIdName.setParent(result); + templateIdName.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_NAME); + if (duple.getTemplateIdArgLists() != null) { + List args = duple.getTemplateIdArgLists()[0]; + if (args != null) + for (int i = 0; i < args.size(); ++i) { + IASTNode n = (IASTNode) args.get(i); + if (n instanceof IASTTypeId || n instanceof IASTExpression) { + n.setParent(result); + n.setPropertyInParent(ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT); + if (n instanceof IASTTypeId) + result.addTemplateArgument((IASTTypeId) n); + else + result.addTemplateArgument((IASTExpression) n); + } } - } - - boolean hasFunctionBody = false; - boolean hasFunctionTryBlock = false; - boolean consumedSemi = false; - List constructorChain = Collections.EMPTY_LIST; + } + return result; + } - switch (LT(1)) { - case IToken.tSEMI: + /** + * @param duple + * @return + */ + protected IASTName createName(ITokenDuple duple) { + if (duple == null) + return createName(); + if (duple.getSegmentCount() != 1) + return createQualifiedName(duple); + CPPASTName name = new CPPASTName(duple.toCharArray()); + name.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset() + - duple.getStartOffset()); + return name; + } + + /** + * @return + */ + protected ICPPASTNamespaceDefinition createNamespaceDefinition() { + return new CPPASTNamespaceDefinition(); + } + + /** + * Serves as the catch-all for all complicated declarations, including + * function-definitions. + * + * simpleDeclaration : (declSpecifier)* (initDeclarator ("," + * initDeclarator)*)? (";" | { functionBody } + * + * Notes: - append functionDefinition stuff to end of this rule + * + * To do: - work in functionTryBlock + * + * @param container + * IParserCallback object which serves as the owner scope for this + * declaration. + * @param tryConstructor + * true == take strategy1 (constructor ) : false == take strategy 2 ( + * pointer to function) + * @return TODO + * @throws BacktrackException + * request a backtrack + */ + protected IASTDeclaration simpleDeclaration( + SimpleDeclarationStrategy strategy, boolean fromCatchHandler) + throws BacktrackException, EndOfFileException { + IToken firstToken = LA(1); + int firstOffset = firstToken.getOffset(); + if (firstToken.getType() == IToken.tLBRACE) + throwBacktrack(firstOffset, firstToken.getLength()); + firstToken = null; // necessary for scalability + + ICPPASTDeclSpecifier declSpec = declSpecifierSeq(false, + strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR); + List declarators = Collections.EMPTY_LIST; + if (LT(1) != IToken.tSEMI) { + declarators = new ArrayList(DEFAULT_DECLARATOR_LIST_SIZE); + declarators.add(initDeclarator(strategy)); + while (LT(1) == IToken.tCOMMA) { + consume(IToken.tCOMMA); + declarators.add(initDeclarator(strategy)); + } + } + + boolean hasFunctionBody = false; + boolean hasFunctionTryBlock = false; + boolean consumedSemi = false; + List constructorChain = Collections.EMPTY_LIST; + + switch (LT(1)) { + case IToken.tSEMI: consume(IToken.tSEMI); consumedSemi = true; break; - case IToken.t_try: + case IToken.t_try: consume(IToken.t_try); - if (LT(1) == IToken.tCOLON) - { - constructorChain = new ArrayList( DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE ); - ctorInitializer(constructorChain); + if (LT(1) == IToken.tCOLON) { + constructorChain = new ArrayList( + DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE); + ctorInitializer(constructorChain); } hasFunctionTryBlock = true; break; - case IToken.tCOLON: - constructorChain = new ArrayList( DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE ); + case IToken.tCOLON: + constructorChain = new ArrayList( + DEFAULT_CONSTRUCTOR_CHAIN_LIST_SIZE); ctorInitializer(constructorChain); break; - case IToken.tLBRACE: + case IToken.tLBRACE: break; - case IToken.tRPAREN: + case IToken.tRPAREN: if (!fromCatchHandler) - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset ); + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); break; - default: - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset ); - } + default: + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); + } - if (!consumedSemi) { - if (LT(1) == IToken.tLBRACE) { - hasFunctionBody = true; + if (!consumedSemi) { + if (LT(1) == IToken.tLBRACE) { + hasFunctionBody = true; + } + + if (hasFunctionTryBlock && !hasFunctionBody) + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); + } + + if (hasFunctionBody) { + if (declarators.size() != 1) + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); + + IASTDeclarator declarator = (IASTDeclarator) declarators.get(0); + if (!(declarator instanceof IASTFunctionDeclarator)) + throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); + + if (!constructorChain.isEmpty() + && declarator instanceof ICPPASTFunctionDeclarator) { + ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator; + for (int i = 0; i < constructorChain.size(); ++i) { + ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) constructorChain + .get(i); + fd.addConstructorToChain(initializer); + initializer.setParent(fd); + initializer + .setPropertyInParent(ICPPASTFunctionDeclarator.CONSTRUCTOR_CHAIN_MEMBER); } + } - if (hasFunctionTryBlock && !hasFunctionBody) - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset ); - } - - if (hasFunctionBody) { - if (declarators.size() != 1) - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset ); + IASTFunctionDefinition funcDefinition = createFunctionDefinition(); + ((ASTNode) funcDefinition).setOffset(firstOffset); + funcDefinition.setDeclSpecifier(declSpec); + declSpec.setParent(funcDefinition); + declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER); - IASTDeclarator declarator = (IASTDeclarator) declarators.get(0); - if (!(declarator instanceof IASTFunctionDeclarator)) - throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset ); + funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator); + declarator.setParent(funcDefinition); + declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR); - if( ! constructorChain.isEmpty() && declarator instanceof ICPPASTFunctionDeclarator ) - { - ICPPASTFunctionDeclarator fd = (ICPPASTFunctionDeclarator) declarator; - for( int i = 0; i < constructorChain.size(); ++i ) - { - ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) constructorChain.get(i); - fd.addConstructorToChain( initializer ); - initializer.setParent( fd ); - initializer.setPropertyInParent( ICPPASTFunctionDeclarator.CONSTRUCTOR_CHAIN_MEMBER ); - } + IASTStatement s = handleFunctionBody(); + if (s != null) { + funcDefinition.setBody(s); + s.setParent(funcDefinition); + s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY); + } + + if (hasFunctionTryBlock + && declarator instanceof ICPPASTFunctionTryBlockDeclarator) { + List handlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE); + catchHandlerSequence(handlers); + for (int i = 0; i < handlers.size(); ++i) { + ICPPASTCatchHandler handler = (ICPPASTCatchHandler) handlers + .get(i); + ((ICPPASTFunctionTryBlockDeclarator) declarator) + .addCatchHandler(handler); + handler.setParent(declarator); + handler + .setPropertyInParent(ICPPASTFunctionTryBlockDeclarator.CATCH_HANDLER); } - - IASTFunctionDefinition funcDefinition = createFunctionDefinition(); - ((ASTNode)funcDefinition).setOffset(firstOffset); - funcDefinition.setDeclSpecifier(declSpec); - declSpec.setParent(funcDefinition); - declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER); + } + ((CPPASTNode) funcDefinition).setLength(lastToken.getEndOffset() + - firstOffset); + return funcDefinition; + } - funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator); - declarator.setParent(funcDefinition); - declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR); + IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration(); + ((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, lastToken + .getEndOffset() + - firstOffset); + simpleDeclaration.setDeclSpecifier(declSpec); + declSpec.setParent(simpleDeclaration); + declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER); - IASTStatement s = handleFunctionBody(); - if (s != null) { - funcDefinition.setBody(s); - s.setParent(funcDefinition); - s.setPropertyInParent(IASTFunctionDefinition.FUNCTION_BODY); - } - - if( hasFunctionTryBlock && declarator instanceof ICPPASTFunctionTryBlockDeclarator ) - { - List handlers = new ArrayList( DEFAULT_CATCH_HANDLER_LIST_SIZE ); - catchHandlerSequence( handlers); - for( int i = 0; i < handlers.size(); ++i ) - { - ICPPASTCatchHandler handler = (ICPPASTCatchHandler) handlers.get(i); - ((ICPPASTFunctionTryBlockDeclarator)declarator).addCatchHandler( handler ); - handler.setParent( declarator ); - handler.setPropertyInParent( ICPPASTFunctionTryBlockDeclarator.CATCH_HANDLER ); - } - } - return funcDefinition; - } + for (int i = 0; i < declarators.size(); ++i) { + IASTDeclarator declarator = (IASTDeclarator) declarators.get(i); + simpleDeclaration.addDeclarator(declarator); + declarator.setParent(simpleDeclaration); + declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR); + } + return simpleDeclaration; + } - IASTSimpleDeclaration simpleDeclaration = createSimpleDeclaration(); - ((ASTNode)simpleDeclaration).setOffset(firstOffset); - simpleDeclaration.setDeclSpecifier(declSpec); - declSpec.setParent(simpleDeclaration); - declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER); + /** + * @return + */ + protected IASTFunctionDefinition createFunctionDefinition() { + return new CPPASTFunctionDefinition(); + } - for (int i = 0; i < declarators.size(); ++i) { - IASTDeclarator declarator = (IASTDeclarator) declarators.get(i); - simpleDeclaration.addDeclarator(declarator); - declarator.setParent(simpleDeclaration); - declarator.setPropertyInParent(IASTSimpleDeclaration.DECLARATOR); - } - return simpleDeclaration; - } + /** + * @return + */ + protected IASTSimpleDeclaration createSimpleDeclaration() { + return new CPPASTSimpleDeclaration(); + } - /** - * @return - */ - protected IASTFunctionDefinition createFunctionDefinition() { - return new CPPASTFunctionDefinition(); - } + /** + * This method parses a constructor chain ctorinitializer: : + * meminitializerlist meminitializerlist: meminitializer | meminitializer , + * meminitializerlist meminitializer: meminitializerid | ( expressionlist? ) + * meminitializerid: ::? nestednamespecifier? classname identifier + * + * @param declarator + * IParserCallback object that represents the declarator + * (constructor) that owns this initializer + * + * @throws BacktrackException + * request a backtrack + */ + protected void ctorInitializer(List collection) throws EndOfFileException, + BacktrackException { + consume(IToken.tCOLON); + for (;;) { + if (LT(1) == IToken.tLBRACE) + break; + ITokenDuple duple = name(); + IASTName name = createName(duple); - /** - * @return - */ - protected IASTSimpleDeclaration createSimpleDeclaration() { - return new CPPASTSimpleDeclaration(); - } + consume(IToken.tLPAREN); + IASTExpression expressionList = null; - /** - * This method parses a constructor chain ctorinitializer: : - * meminitializerlist meminitializerlist: meminitializer | meminitializer , - * meminitializerlist meminitializer: meminitializerid | ( expressionlist? ) - * meminitializerid: ::? nestednamespecifier? classname identifier - * @param declarator - * IParserCallback object that represents the declarator - * (constructor) that owns this initializer - * - * @throws BacktrackException - * request a backtrack - */ - protected void ctorInitializer( List collection ) throws EndOfFileException, - BacktrackException { - consume(IToken.tCOLON); - for (;;) { - if (LT(1) == IToken.tLBRACE) - break; - ITokenDuple duple = name(); - IASTName name = createName( duple ); + if (LT(1) != IToken.tRPAREN) + expressionList = expression(); - consume(IToken.tLPAREN); - IASTExpression expressionList = null; + int end = consume(IToken.tRPAREN).getEndOffset(); + ICPPASTConstructorChainInitializer ctorInitializer = createConstructorChainInitializer(); + ((ASTNode) ctorInitializer).setOffsetAndLength(duple.getStartOffset(), + end - duple.getStartOffset()); + ctorInitializer.setMemberInitializerId(name); + name.setParent(ctorInitializer); + name.setPropertyInParent(ICPPASTConstructorChainInitializer.MEMBER_ID); - if (LT(1) != IToken.tRPAREN) - expressionList = expression(); + if (expressionList != null) { + ctorInitializer.setInitializerValue(expressionList); + expressionList.setParent(ctorInitializer); + expressionList + .setPropertyInParent(ICPPASTConstructorChainInitializer.INITIALIZER); + } + collection.add(ctorInitializer); + if (LT(1) == IToken.tLBRACE) + break; + consume(IToken.tCOMMA); + } - consume(IToken.tRPAREN); - ICPPASTConstructorChainInitializer ctorInitializer = createConstructorChainInitializer(); - ((ASTNode)ctorInitializer).setOffset( duple.getStartOffset() ); - ctorInitializer.setMemberInitializerId( name ); - name.setParent( ctorInitializer ); - name.setPropertyInParent( ICPPASTConstructorChainInitializer.MEMBER_ID); + } - if( expressionList != null ) - { - ctorInitializer.setInitializerValue( expressionList ); - expressionList.setParent( ctorInitializer ); - expressionList.setPropertyInParent( ICPPASTConstructorChainInitializer.INITIALIZER ); - } - collection.add( ctorInitializer ); - if (LT(1) == IToken.tLBRACE) - break; - consume(IToken.tCOMMA); - } + /** + * @return + */ + protected ICPPASTConstructorChainInitializer createConstructorChainInitializer() { + return new CPPASTConstructorChainInitializer(); + } - } + /** + * This routine parses a parameter declaration + * + * @param containerObject + * The IParserCallback object representing the + * parameterDeclarationClause owning the parm. + * + * @return TODO + * @throws BacktrackException + * request a backtrack + */ + protected ICPPASTParameterDeclaration parameterDeclaration() + throws BacktrackException, EndOfFileException { + IToken current = LA(1); + IASTDeclSpecifier declSpec = declSpecifierSeq(true, false); + IASTDeclarator declarator = null; + if (LT(1) != IToken.tSEMI) + declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION); + if (current == LA(1)) { + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + throwBacktrack(current.getOffset(), endOffset - current.getOffset()); + } + ICPPASTParameterDeclaration parm = createParameterDeclaration(); + int length = (lastToken != null) ? lastToken.getEndOffset() + - current.getOffset() : ((ASTNode) declSpec).getLength() + + ((ASTNode) declarator).getLength(); + ((ASTNode) parm).setOffsetAndLength(current.getOffset(), length); + parm.setDeclSpecifier(declSpec); + declSpec.setParent(parm); + declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER); + if (declarator != null) { + parm.setDeclarator(declarator); + declarator.setParent(parm); + declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR); + } + return parm; + } - /** - * @return - */ - protected ICPPASTConstructorChainInitializer createConstructorChainInitializer() { - return new CPPASTConstructorChainInitializer(); - } + /** + * @return + */ + protected ICPPASTParameterDeclaration createParameterDeclaration() { + return new CPPASTParameterDeclaration(); + } - /** - * This routine parses a parameter declaration - * @param containerObject - * The IParserCallback object representing the - * parameterDeclarationClause owning the parm. - * - * @return TODO - * @throws BacktrackException - * request a backtrack - */ - protected ICPPASTParameterDeclaration parameterDeclaration() throws BacktrackException, EndOfFileException { - IToken current = LA(1); - IASTDeclSpecifier declSpec = declSpecifierSeq(true, false); - IASTDeclarator declarator = null; - if (LT(1) != IToken.tSEMI) - declarator = initDeclarator(SimpleDeclarationStrategy.TRY_FUNCTION); + /** + * @param flags + * input flags that are used to make our decision + * @return whether or not this looks like a constructor (true or false) + * @throws EndOfFileException + * we could encounter EOF while looking ahead + */ + protected boolean lookAheadForConstructorOrConversion(Flags flags) + throws EndOfFileException { + if (flags.isForParameterDeclaration()) + return false; + if (LT(2) == IToken.tLPAREN && flags.isForConstructor()) + return true; - if (current == LA(1)) { - int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; - throwBacktrack(current.getOffset(), endOffset - current.getOffset() ); - } - ICPPASTParameterDeclaration parm = createParameterDeclaration(); - ((ASTNode)parm).setOffset( current.getOffset() ); - parm.setDeclSpecifier( declSpec ); - declSpec.setParent( parm ); - declSpec.setPropertyInParent( IASTParameterDeclaration.DECL_SPECIFIER ); - if( declarator != null ) - { - parm.setDeclarator( declarator ); - declarator.setParent( parm ); - declarator.setPropertyInParent( IASTParameterDeclaration.DECLARATOR ); - } - return parm; - } + IToken mark = mark(); + ITokenDuple duple = null; + try { + duple = consumeTemplatedOperatorName(); + } catch (BacktrackException e) { + backup(mark); + return false; + } catch (EndOfFileException eof) { + backup(mark); + return false; + } - /** - * @return - */ - protected ICPPASTParameterDeclaration createParameterDeclaration() { - return new CPPASTParameterDeclaration(); - } + if (duple == null) { + backup(mark); + return false; + } - /** - * @param flags - * input flags that are used to make our decision - * @return whether or not this looks like a constructor (true or false) - * @throws EndOfFileException - * we could encounter EOF while looking ahead - */ - protected boolean lookAheadForConstructorOrConversion(Flags flags) throws EndOfFileException { - if (flags.isForParameterDeclaration()) - return false; - if (LT(2) == IToken.tLPAREN - && flags.isForConstructor()) - return true; + 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; + } - IToken mark = mark(); - ITokenDuple duple = null; - try { - duple = consumeTemplatedOperatorName(); - } catch (BacktrackException e) { - backup(mark); - return false; - } catch (EndOfFileException eof) { - 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)) { + backup(mark); + return false; + } - if (duple == null) { - backup(mark); - return false; - } + if (lastSegment.isConversion()) { + backup(mark); + return true; + } - 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; - } + 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; + } - ITokenDuple secondlastSegment = leadingSegments.getLastSegment(); - if (secondlastSegment == null) { - backup(mark); - return false; - } - char[] otherName = secondlastSegment.extractNameFromTemplateId(); - if (otherName == null || CharArrayUtils.equals(otherName, EMPTY_STRING)) { - backup(mark); - return false; - } + 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; - } + /** + * This function parses a declaration specifier sequence, as according to the + * ANSI C++ spec. + * + * declSpecifier : "auto" | "register" | "static" | "extern" | "mutable" | + * "inline" | "virtual" | "explicit" | "char" | "wchar_t" | "bool" | "short" | + * "int" | "long" | "signed" | "unsigned" | "float" | "double" | "void" | + * "const" | "volatile" | "friend" | "typedef" | ("typename")? name | + * {"class"|"struct"|"union"} classSpecifier | {"enum"} enumSpecifier + * + * Notes: - folded in storageClassSpecifier, typeSpecifier, functionSpecifier - + * folded elaboratedTypeSpecifier into classSpecifier and enumSpecifier - + * find template names in name + * + * @param parm + * Is this for a parameter declaration (true) or simple declaration + * (false) + * @param tryConstructor + * true for constructor, false for pointer to function strategy + * + * @return TODO + * @throws BacktrackException + * request a backtrack + */ + protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm, + boolean tryConstructor) throws BacktrackException, EndOfFileException { + IToken firstToken = LA(1); + Flags flags = new Flags(parm, tryConstructor); - backup(mark); - return false; - } + boolean isInline = false, isVirtual = false, isExplicit = false, isFriend = false; + boolean isConst = false, isVolatile = false, isRestrict = false; + boolean isLong = false, isShort = false, isUnsigned = false, isSigned = false, isLongLong = false; + boolean isTypename = false; - /** - * This function parses a declaration specifier sequence, as according to - * the ANSI C++ spec. - * - * declSpecifier : "auto" | "register" | "static" | "extern" | "mutable" | - * "inline" | "virtual" | "explicit" | "char" | "wchar_t" | "bool" | "short" | - * "int" | "long" | "signed" | "unsigned" | "float" | "double" | "void" | - * "const" | "volatile" | "friend" | "typedef" | ("typename")? name | - * {"class"|"struct"|"union"} classSpecifier | {"enum"} enumSpecifier - * - * Notes: - folded in storageClassSpecifier, typeSpecifier, - * functionSpecifier - folded elaboratedTypeSpecifier into classSpecifier - * and enumSpecifier - find template names in name - * @param parm - * Is this for a parameter declaration (true) or simple - * declaration (false) - * @param tryConstructor - * true for constructor, false for pointer to function strategy - * - * @return TODO - * @throws BacktrackException - * request a backtrack - */ - protected ICPPASTDeclSpecifier declSpecifierSeq(boolean parm, boolean tryConstructor) throws BacktrackException, - EndOfFileException { - IToken firstToken = LA(1); - Flags flags = new Flags(parm, tryConstructor); - - boolean isInline= false, isVirtual= false, isExplicit= false, isFriend= false; - boolean isConst = false, isVolatile= false, isRestrict= false; - boolean isLong= false, isShort= false, isUnsigned= false, isSigned= false, isLongLong = false; - boolean isTypename= false; - - int storageClass = IASTDeclSpecifier.sc_unspecified; - int simpleType = IASTSimpleDeclSpecifier.t_unspecified; - ITokenDuple duple = null; - - ICPPASTCompositeTypeSpecifier classSpec = null; - ICPPASTElaboratedTypeSpecifier elabSpec = null; - IASTEnumerationSpecifier enumSpec = null; - IASTExpression typeofExpression = null; - declSpecifiers: for (;;) { - switch (LT(1)) { + int storageClass = IASTDeclSpecifier.sc_unspecified; + int simpleType = IASTSimpleDeclSpecifier.t_unspecified; + ITokenDuple duple = null; + + ICPPASTCompositeTypeSpecifier classSpec = null; + ICPPASTElaboratedTypeSpecifier elabSpec = null; + IASTEnumerationSpecifier enumSpec = null; + IASTExpression typeofExpression = null; + declSpecifiers: for (;;) { + switch (LT(1)) { case IToken.t_inline: - consume(); - isInline = true; - break; + consume(); + isInline = true; + break; case IToken.t_typedef: - storageClass = IASTDeclSpecifier.sc_typedef; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_typedef; + consume(); + break; case IToken.t_auto: - consume(); - storageClass = IASTDeclSpecifier.sc_auto; - break; + consume(); + storageClass = IASTDeclSpecifier.sc_auto; + break; case IToken.t_register: - consume(); - storageClass = IASTDeclSpecifier.sc_register; - break; + consume(); + storageClass = IASTDeclSpecifier.sc_register; + break; case IToken.t_static: - storageClass = IASTDeclSpecifier.sc_static; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_static; + consume(); + break; case IToken.t_extern: - storageClass = IASTDeclSpecifier.sc_extern; - consume(); - break; + storageClass = IASTDeclSpecifier.sc_extern; + consume(); + break; case IToken.t_mutable: - storageClass = ICPPASTDeclSpecifier.sc_mutable; - consume(); - break; + storageClass = ICPPASTDeclSpecifier.sc_mutable; + consume(); + break; case IToken.t_virtual: - isVirtual = true; - consume(); - break; + isVirtual = true; + consume(); + break; case IToken.t_explicit: - isExplicit = true; - consume(); - break; + isExplicit = true; + consume(); + break; case IToken.t_friend: - isFriend = true; - consume(); - break; + isFriend = true; + consume(); + break; case IToken.t_const: - isConst = true; - consume(); - break; + isConst = true; + consume(); + break; case IToken.t_volatile: - isVolatile = true; - consume(); - break; + isVolatile = true; + consume(); + break; case IToken.t_restrict: - if( !supportRestrict ) - { - IToken la = LA(1); - throwBacktrack( la.getOffset(), la.getEndOffset() - la.getOffset() ); - } - isRestrict = true; - consume(); - break; + if (!supportRestrict) { + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getEndOffset() + - la.getOffset()); + } + isRestrict = true; + consume(); + break; case IToken.t_signed: - isSigned = true; - flags.setEncounteredRawType(true); - consume(); - break; + isSigned = true; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_unsigned: - isUnsigned = true; - flags.setEncounteredRawType(true); - consume(); - break; + isUnsigned = true; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_short: - isShort = true; - flags.setEncounteredRawType(true); - consume(); - break; + isShort = true; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_long: - if( isLong && supportLongLong ) - { - isLong = false; - isLongLong = true; - } - else - isLong = true; - flags.setEncounteredRawType(true); - consume(); - break; + if (isLong && supportLongLong) { + isLong = false; + isLongLong = true; + } else + isLong = true; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t__Complex: - if( ! supportComplex ) - { - IToken la = LA(1); - throwBacktrack( la.getOffset(), la.getEndOffset() - la.getOffset() ); - } - consume(IToken.t__Complex); - simpleType = IGPPASTSimpleDeclSpecifier.t_Complex; - break; + if (!supportComplex) { + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getEndOffset() + - la.getOffset()); + } + consume(IToken.t__Complex); + simpleType = IGPPASTSimpleDeclSpecifier.t_Complex; + break; case IToken.t__Imaginary: - if( ! supportComplex ) - { - IToken la = LA(1); - throwBacktrack( la.getOffset(), la.getLength() ); - } - consume(IToken.t__Imaginary); - simpleType = IGPPASTSimpleDeclSpecifier.t_Imaginary; - break; + if (!supportComplex) { + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getLength()); + } + consume(IToken.t__Imaginary); + simpleType = IGPPASTSimpleDeclSpecifier.t_Imaginary; + break; case IToken.t_char: - simpleType = IASTSimpleDeclSpecifier.t_char; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = IASTSimpleDeclSpecifier.t_char; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_wchar_t: - simpleType = ICPPASTSimpleDeclSpecifier.t_wchar_t; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = ICPPASTSimpleDeclSpecifier.t_wchar_t; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_bool: - simpleType = ICPPASTSimpleDeclSpecifier.t_bool; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = ICPPASTSimpleDeclSpecifier.t_bool; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_int: - flags.setEncounteredRawType(true); - consume(); - simpleType = IASTSimpleDeclSpecifier.t_int; - break; + flags.setEncounteredRawType(true); + consume(); + simpleType = IASTSimpleDeclSpecifier.t_int; + break; case IToken.t_float: - simpleType = IASTSimpleDeclSpecifier.t_float; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = IASTSimpleDeclSpecifier.t_float; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_double: - simpleType = IASTSimpleDeclSpecifier.t_double; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = IASTSimpleDeclSpecifier.t_double; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_void: - simpleType = IASTSimpleDeclSpecifier.t_void; - flags.setEncounteredRawType(true); - consume(); - break; + simpleType = IASTSimpleDeclSpecifier.t_void; + flags.setEncounteredRawType(true); + consume(); + break; case IToken.t_typename: - isTypename = true; - consume(IToken.t_typename); - duple = name(); - flags.setEncounteredTypename(true); - break; + isTypename = true; + consume(IToken.t_typename); + duple = name(); + flags.setEncounteredTypename(true); + break; case IToken.tCOLONCOLON: case IToken.tIDENTIFIER: - // TODO - Kludgy way to handle constructors/destructors - if (flags.haveEncounteredRawType()) - break declSpecifiers; - - if (parm && flags.haveEncounteredTypename()) - break declSpecifiers; + // TODO - Kludgy way to handle constructors/destructors + if (flags.haveEncounteredRawType()) + break declSpecifiers; - if (lookAheadForConstructorOrConversion(flags)) - break declSpecifiers; - - if (lookAheadForDeclarator(flags)) - break declSpecifiers; - - duple = name(); - flags.setEncounteredTypename(true); - break; + if (parm && flags.haveEncounteredTypename()) + break declSpecifiers; + + if (lookAheadForConstructorOrConversion(flags)) + break declSpecifiers; + + if (lookAheadForDeclarator(flags)) + break declSpecifiers; + + duple = name(); + flags.setEncounteredTypename(true); + break; case IToken.t_class: case IToken.t_struct: case IToken.t_union: - try { - classSpec = classSpecifier(); - flags.setEncounteredTypename(true); - break; - } catch (BacktrackException bt) { - elabSpec = elaboratedTypeSpecifier(); - flags.setEncounteredTypename(true); - break; - } + try { + classSpec = classSpecifier(); + flags.setEncounteredTypename(true); + break; + } catch (BacktrackException bt) { + elabSpec = elaboratedTypeSpecifier(); + flags.setEncounteredTypename(true); + break; + } case IToken.t_enum: - try { - enumSpec = enumSpecifier(); - flags.setEncounteredTypename(true); - break; - } catch (BacktrackException bt) { - // this is an elaborated class specifier - elabSpec = elaboratedTypeSpecifier(); - flags.setEncounteredTypename(true); - break; - } + try { + enumSpec = enumSpecifier(); + flags.setEncounteredTypename(true); + break; + } catch (BacktrackException bt) { + // this is an elaborated class specifier + elabSpec = elaboratedTypeSpecifier(); + flags.setEncounteredTypename(true); + break; + } default: - if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { - typeofExpression = unaryTypeofExpression(); - if (typeofExpression != null) { - flags.setEncounteredTypename(true); - } - } - break declSpecifiers; - } - } - - if( elabSpec != null ) - { - elabSpec.setConst( isConst ); - elabSpec.setVolatile( isVolatile ); - if( elabSpec instanceof IGPPASTDeclSpecifier ) - ((IGPPASTDeclSpecifier)elabSpec).setRestrict( isRestrict ); - elabSpec.setFriend( isFriend ); - elabSpec.setInline( isInline ); - elabSpec.setStorageClass( storageClass ); - elabSpec.setVirtual( isVirtual ); - elabSpec.setExplicit( isExplicit ); - return elabSpec; - } - if( enumSpec != null ) - { - enumSpec.setConst( isConst ); - enumSpec.setVolatile( isVolatile ); - if( enumSpec instanceof IGPPASTDeclSpecifier ) - ((IGPPASTDeclSpecifier)enumSpec).setRestrict( isRestrict ); - ((ICPPASTDeclSpecifier)enumSpec).setFriend( isFriend ); - ((ICPPASTDeclSpecifier)enumSpec).setVirtual( isVirtual ); - ((ICPPASTDeclSpecifier)enumSpec).setExplicit( isExplicit ); - enumSpec.setInline( isInline ); - enumSpec.setStorageClass( storageClass ); - return (ICPPASTDeclSpecifier) enumSpec; - } - if( classSpec != null ) - { - classSpec.setConst( isConst ); - classSpec.setVolatile( isVolatile ); - if( classSpec instanceof IGPPASTDeclSpecifier ) - ((IGPPASTDeclSpecifier)classSpec).setRestrict( isRestrict ); - classSpec.setFriend( isFriend ); - classSpec.setInline( isInline ); - classSpec.setStorageClass( storageClass ); - classSpec.setVirtual( isVirtual ); - classSpec.setExplicit( isExplicit ); - return classSpec; - } - if( duple != null ) - { - ICPPASTNamedTypeSpecifier nameSpec = createNamedTypeSpecifier(); - nameSpec.setIsTypename( isTypename ); - IASTName name = createName( duple ); - nameSpec.setName( name ); - name.setParent( nameSpec ); - name.setPropertyInParent( IASTNamedTypeSpecifier.NAME ); - - nameSpec.setConst( isConst ); - nameSpec.setVolatile( isVolatile ); - if( nameSpec instanceof IGPPASTDeclSpecifier ) - ((IGPPASTDeclSpecifier)nameSpec).setRestrict( isRestrict ); - nameSpec.setFriend( isFriend ); - nameSpec.setInline( isInline ); - nameSpec.setStorageClass( storageClass ); - nameSpec.setVirtual( isVirtual ); - nameSpec.setExplicit( isExplicit ); - return nameSpec; - } - ICPPASTSimpleDeclSpecifier simpleDeclSpec = null; - if( isLongLong || typeofExpression != null ) - { - simpleDeclSpec = createGPPSimpleDeclSpecifier(); - ((IGPPASTSimpleDeclSpecifier)simpleDeclSpec).setLongLong( isLongLong ); - if( typeofExpression != null ) - { - ((IGPPASTSimpleDeclSpecifier)simpleDeclSpec).setTypeofExpression( typeofExpression ); - typeofExpression.setParent( simpleDeclSpec ); - typeofExpression.setPropertyInParent( IGPPASTSimpleDeclSpecifier.TYPEOF_EXPRESSION ); - } - } - else - simpleDeclSpec = createSimpleDeclSpecifier(); - ((ASTNode)simpleDeclSpec).setOffset( firstToken.getOffset() ); - simpleDeclSpec.setConst( isConst ); - simpleDeclSpec.setVolatile( isVolatile ); - if( simpleDeclSpec instanceof IGPPASTDeclSpecifier ) - ((IGPPASTDeclSpecifier)simpleDeclSpec).setRestrict( isRestrict ); - - simpleDeclSpec.setFriend( isFriend ); - simpleDeclSpec.setInline( isInline ); - simpleDeclSpec.setStorageClass( storageClass ); - simpleDeclSpec.setVirtual( isVirtual ); - simpleDeclSpec.setExplicit( isExplicit ); - - simpleDeclSpec.setType( simpleType ); - simpleDeclSpec.setLong( isLong ); - simpleDeclSpec.setShort( isShort ); - simpleDeclSpec.setUnsigned( isUnsigned ); - simpleDeclSpec.setSigned( isSigned ); - - return simpleDeclSpec; - } + if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { + typeofExpression = unaryTypeofExpression(); + if (typeofExpression != null) { + flags.setEncounteredTypename(true); + } + } + break declSpecifiers; + } + } - /** - * @return - */ - protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() { - return new GPPASTSimpleDeclSpecifier(); - } + if (elabSpec != null) { + elabSpec.setConst(isConst); + elabSpec.setVolatile(isVolatile); + if (elabSpec instanceof IGPPASTDeclSpecifier) + ((IGPPASTDeclSpecifier) elabSpec).setRestrict(isRestrict); + elabSpec.setFriend(isFriend); + elabSpec.setInline(isInline); + elabSpec.setStorageClass(storageClass); + elabSpec.setVirtual(isVirtual); + elabSpec.setExplicit(isExplicit); + return elabSpec; + } + if (enumSpec != null) { + enumSpec.setConst(isConst); + enumSpec.setVolatile(isVolatile); + if (enumSpec instanceof IGPPASTDeclSpecifier) + ((IGPPASTDeclSpecifier) enumSpec).setRestrict(isRestrict); + ((ICPPASTDeclSpecifier) enumSpec).setFriend(isFriend); + ((ICPPASTDeclSpecifier) enumSpec).setVirtual(isVirtual); + ((ICPPASTDeclSpecifier) enumSpec).setExplicit(isExplicit); + enumSpec.setInline(isInline); + enumSpec.setStorageClass(storageClass); + return (ICPPASTDeclSpecifier) enumSpec; + } + if (classSpec != null) { + classSpec.setConst(isConst); + classSpec.setVolatile(isVolatile); + if (classSpec instanceof IGPPASTDeclSpecifier) + ((IGPPASTDeclSpecifier) classSpec).setRestrict(isRestrict); + classSpec.setFriend(isFriend); + classSpec.setInline(isInline); + classSpec.setStorageClass(storageClass); + classSpec.setVirtual(isVirtual); + classSpec.setExplicit(isExplicit); + return classSpec; + } + if (duple != null) { + ICPPASTNamedTypeSpecifier nameSpec = createNamedTypeSpecifier(); + nameSpec.setIsTypename(isTypename); + IASTName name = createName(duple); + nameSpec.setName(name); + name.setParent(nameSpec); + name.setPropertyInParent(IASTNamedTypeSpecifier.NAME); - /** - * @return - */ - protected ICPPASTSimpleDeclSpecifier createSimpleDeclSpecifier() { - return new CPPASTSimpleDeclSpecifier(); - } + nameSpec.setConst(isConst); + nameSpec.setVolatile(isVolatile); + if (nameSpec instanceof IGPPASTDeclSpecifier) + ((IGPPASTDeclSpecifier) nameSpec).setRestrict(isRestrict); + nameSpec.setFriend(isFriend); + nameSpec.setInline(isInline); + nameSpec.setStorageClass(storageClass); + nameSpec.setVirtual(isVirtual); + nameSpec.setExplicit(isExplicit); + return nameSpec; + } + ICPPASTSimpleDeclSpecifier simpleDeclSpec = null; + if (isLongLong || typeofExpression != null) { + simpleDeclSpec = createGPPSimpleDeclSpecifier(); + ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec).setLongLong(isLongLong); + if (typeofExpression != null) { + ((IGPPASTSimpleDeclSpecifier) simpleDeclSpec) + .setTypeofExpression(typeofExpression); + typeofExpression.setParent(simpleDeclSpec); + typeofExpression + .setPropertyInParent(IGPPASTSimpleDeclSpecifier.TYPEOF_EXPRESSION); + } + } else + simpleDeclSpec = createSimpleDeclSpecifier(); - /** - * @return - */ - protected ICPPASTNamedTypeSpecifier createNamedTypeSpecifier() { - return new CPPASTNamedTypeSpecifier(); - } + int l = lastToken != null ? lastToken.getEndOffset() + - firstToken.getOffset() : 0; + ((ASTNode) simpleDeclSpec).setOffsetAndLength(firstToken.getOffset(), l); + simpleDeclSpec.setConst(isConst); + simpleDeclSpec.setVolatile(isVolatile); + if (simpleDeclSpec instanceof IGPPASTDeclSpecifier) + ((IGPPASTDeclSpecifier) simpleDeclSpec).setRestrict(isRestrict); - /** - * Parse an elaborated type specifier. - * @param decl - * Declaration which owns the elaborated type - * @return TODO - * - * @throws BacktrackException - * request a backtrack - */ - protected ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier() - throws BacktrackException, EndOfFileException { - // this is an elaborated class specifier - IToken t = consume(); - int eck = 0; + simpleDeclSpec.setFriend(isFriend); + simpleDeclSpec.setInline(isInline); + simpleDeclSpec.setStorageClass(storageClass); + simpleDeclSpec.setVirtual(isVirtual); + simpleDeclSpec.setExplicit(isExplicit); - switch (t.getType()) { - case IToken.t_class: - eck = ICPPASTElaboratedTypeSpecifier.k_class; + simpleDeclSpec.setType(simpleType); + simpleDeclSpec.setLong(isLong); + simpleDeclSpec.setShort(isShort); + simpleDeclSpec.setUnsigned(isUnsigned); + simpleDeclSpec.setSigned(isSigned); + + return simpleDeclSpec; + } + + /** + * @return + */ + protected ICPPASTSimpleDeclSpecifier createGPPSimpleDeclSpecifier() { + return new GPPASTSimpleDeclSpecifier(); + } + + /** + * @return + */ + protected ICPPASTSimpleDeclSpecifier createSimpleDeclSpecifier() { + return new CPPASTSimpleDeclSpecifier(); + } + + /** + * @return + */ + protected ICPPASTNamedTypeSpecifier createNamedTypeSpecifier() { + return new CPPASTNamedTypeSpecifier(); + } + + /** + * Parse an elaborated type specifier. + * + * @param decl + * Declaration which owns the elaborated type + * @return TODO + * + * @throws BacktrackException + * request a backtrack + */ + protected ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier() + throws BacktrackException, EndOfFileException { + // this is an elaborated class specifier + IToken t = consume(); + int eck = 0; + + switch (t.getType()) { + case IToken.t_class: + eck = ICPPASTElaboratedTypeSpecifier.k_class; break; - case IToken.t_struct: + case IToken.t_struct: eck = IASTElaboratedTypeSpecifier.k_struct; break; - case IToken.t_union: + case IToken.t_union: eck = IASTElaboratedTypeSpecifier.k_union; break; - case IToken.t_enum: + case IToken.t_enum: eck = IASTElaboratedTypeSpecifier.k_enum; break; - default: + default: backup(t); - throwBacktrack(t.getOffset(), t.getLength() ); - } + throwBacktrack(t.getOffset(), t.getLength()); + } - IASTName name = createName( name() ); - - ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = createElaboratedTypeSpecifier(); - ((ASTNode)elaboratedTypeSpec).setOffset( t.getOffset() ); - elaboratedTypeSpec.setKind( eck ); - elaboratedTypeSpec.setName( name ); - name.setParent( elaboratedTypeSpec ); - name.setPropertyInParent( IASTElaboratedTypeSpecifier.TYPE_NAME ); - return elaboratedTypeSpec; - } + IASTName name = createName(name()); - /** - * @return - */ - protected ICPPASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() { - return new CPPASTElaboratedTypeSpecifier(); - } + ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = createElaboratedTypeSpecifier(); + ((ASTNode) elaboratedTypeSpec).setOffsetAndLength(t.getOffset(), + lastToken.getEndOffset() - t.getOffset()); + elaboratedTypeSpec.setKind(eck); + elaboratedTypeSpec.setName(name); + name.setParent(elaboratedTypeSpec); + name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME); + return elaboratedTypeSpec; + } - /** - * Parses the initDeclarator construct of the ANSI C++ spec. - * - * initDeclarator : declarator ("=" initializerClause | "(" expressionList - * ")")? - * @param constructInitializers - * TODO - * @param owner - * IParserCallback object that represents the owner declaration - * object. - * - * @return declarator that this parsing produced. - * @throws BacktrackException - * request a backtrack - */ - protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy ) - throws EndOfFileException, BacktrackException { - IASTDeclarator d = declarator(strategy, false); + /** + * @return + */ + protected ICPPASTElaboratedTypeSpecifier createElaboratedTypeSpecifier() { + return new CPPASTElaboratedTypeSpecifier(); + } - IASTInitializer initializer = optionalCPPInitializer(); - if( initializer != null ) - { - d.setInitializer( initializer ); - initializer.setParent( d ); - initializer.setPropertyInParent( IASTDeclarator.INITIALIZER ); - } - - return d; - } + /** + * Parses the initDeclarator construct of the ANSI C++ spec. + * + * initDeclarator : declarator ("=" initializerClause | "(" expressionList + * ")")? + * + * @param constructInitializers + * TODO + * @param owner + * IParserCallback object that represents the owner declaration + * object. + * + * @return declarator that this parsing produced. + * @throws BacktrackException + * request a backtrack + */ + protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy) + throws EndOfFileException, BacktrackException { + IASTDeclarator d = declarator(strategy, false); - protected IASTInitializer optionalCPPInitializer() throws EndOfFileException, - BacktrackException { - // handle initializer + IASTInitializer initializer = optionalCPPInitializer(); + if (initializer != null) { + d.setInitializer(initializer); + initializer.setParent(d); + initializer.setPropertyInParent(IASTDeclarator.INITIALIZER); + } - if (LT(1) == IToken.tASSIGN) { - consume(IToken.tASSIGN); - throwAwayMarksForInitializerClause(); - try { - return initializerClause(); - } catch (EndOfFileException eof) { - failParse(); - throw eof; - } - } else if (LT(1) == IToken.tLPAREN) { - // initializer in constructor - int o = consume(IToken.tLPAREN).getOffset(); // EAT IT! - IASTExpression astExpression = expression(); - consume(IToken.tRPAREN); - ICPPASTConstructorInitializer result = createConstructorInitializer(); - ((ASTNode)result).setOffset( o ); - result.setExpression( astExpression ); - astExpression.setParent( result ); - astExpression.setPropertyInParent( ICPPASTConstructorInitializer.EXPRESSION ); - return result; - } - return null; - } + return d; + } - /** - * @return - */ - protected ICPPASTConstructorInitializer createConstructorInitializer() { - return new CPPASTConstructorInitializer(); - } + protected IASTInitializer optionalCPPInitializer() + throws EndOfFileException, BacktrackException { + // handle initializer - /** - * - */ - protected IASTInitializer initializerClause() throws EndOfFileException, - BacktrackException { - if (LT(1) == IToken.tLBRACE) { - int startingOffset = consume(IToken.tLBRACE).getOffset(); - - IASTInitializerList result = createInitializerList(); - ((ASTNode)result).setOffset( startingOffset ); + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + throwAwayMarksForInitializerClause(); + try { + return initializerClause(); + } catch (EndOfFileException eof) { + failParse(); + throw eof; + } + } else if (LT(1) == IToken.tLPAREN) { + // initializer in constructor + int o = consume(IToken.tLPAREN).getOffset(); // EAT IT! + IASTExpression astExpression = expression(); + consume(IToken.tRPAREN); + ICPPASTConstructorInitializer result = createConstructorInitializer(); + ((ASTNode) result).setOffsetAndLength(o, lastToken.getEndOffset() - o); + result.setExpression(astExpression); + astExpression.setParent(result); + astExpression + .setPropertyInParent(ICPPASTConstructorInitializer.EXPRESSION); + return result; + } + return null; + } - if (LT(1) == (IToken.tRBRACE)) { - consume(IToken.tRBRACE); - return result; - } + /** + * @return + */ + protected ICPPASTConstructorInitializer createConstructorInitializer() { + return new CPPASTConstructorInitializer(); + } - // otherwise it is a list of initializer clauses + /** + * + */ + protected IASTInitializer initializerClause() throws EndOfFileException, + BacktrackException { + if (LT(1) == IToken.tLBRACE) { + int startingOffset = consume(IToken.tLBRACE).getOffset(); + IASTInitializerList result = createInitializerList(); + ((ASTNode) result).setOffset(startingOffset); - for (;;) { - if (LT(1) == IToken.tRBRACE) - break; - - IASTInitializer clause = initializerClause( ); - if (clause != null) { - result.addInitializer( clause ); - clause.setParent( result ); - clause.setPropertyInParent( IASTInitializerList.NESTED_INITIALIZER ); - } - if (LT(1) == IToken.tRBRACE) - break; - consume(IToken.tCOMMA); - } + if (LT(1) == (IToken.tRBRACE)) { consume(IToken.tRBRACE); + ((ASTNode) result).setLength(lastToken.getEndOffset() + - startingOffset); return result; - } + } - // if we get this far, it means that we did not - // try this now instead - // assignmentExpression - IASTExpression assignmentExpression = assignmentExpression(); - IASTInitializerExpression result = createInitializerExpression(); - ((ASTNode)result).setOffset( ((ASTNode)assignmentExpression).getOffset() ); - result.setExpression( assignmentExpression ); - assignmentExpression.setParent( result ); - assignmentExpression.setPropertyInParent( IASTInitializerExpression.INITIALIZER_EXPRESSION ); - return result; - } + // otherwise it is a list of initializer clauses + for (;;) { + if (LT(1) == IToken.tRBRACE) + break; - /** - * @return - */ - protected IASTInitializerList createInitializerList() { - return new CPPASTInitializerList(); - } - - /** - * @return - */ - protected IASTInitializerExpression createInitializerExpression() { - return new CPPASTInitializerExpression(); - } - - /** - * Parse a declarator, as according to the ANSI C++ specification. - * - * declarator : (ptrOperator)* directDeclarator - * - * directDeclarator : declaratorId | directDeclarator "(" - * parameterDeclarationClause ")" (cvQualifier)* (exceptionSpecification)* | - * directDeclarator "[" (constantExpression)? "]" | "(" declarator")" | - * directDeclarator "(" parameterDeclarationClause ")" - * (oldKRParameterDeclaration)* - * - * declaratorId : name - * @param forTypeID TODO - * @param container - * IParserCallback object that represents the owner declaration. - * @return declarator that this parsing produced. - * @throws BacktrackException - * request a backtrack - */ - protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy, boolean forTypeID) throws EndOfFileException, - BacktrackException { - - IToken la = LA(1); - int startingOffset = la.getOffset(); - la = null; - IASTDeclarator innerDecl = null; - IASTName declaratorName = null; - List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); - List parameters = Collections.EMPTY_LIST; - List arrayMods = Collections.EMPTY_LIST; - List exceptionSpecIds = Collections.EMPTY_LIST; - boolean encounteredVarArgs = false; - boolean tryEncountered = false; - IASTExpression bitField = null; - boolean isFunction = false; - boolean isPureVirtual = false, isConst = false, isVolatile = false; - - overallLoop: do { - - consumePointerOperators(pointerOps); - - if (!forTypeID && LT(1) == IToken.tLPAREN) { - IToken mark = mark(); - try - { - consume(); - innerDecl = declarator(strategy, forTypeID); - consume(IToken.tRPAREN); - } - catch( BacktrackException bte ) - { - backup( mark ); - } - declaratorName = createName(); - } else - { - try - { - ITokenDuple d = consumeTemplatedOperatorName(); - declaratorName = createName( d ); - if( d.isConversion() ) - isFunction = true; - } - catch( BacktrackException bt ) - { - declaratorName = createName(); - } + IASTInitializer clause = initializerClause(); + if (clause != null) { + result.addInitializer(clause); + clause.setParent(result); + clause + .setPropertyInParent(IASTInitializerList.NESTED_INITIALIZER); } + if (LT(1) == IToken.tRBRACE) + break; + consume(IToken.tCOMMA); + } + consume(IToken.tRBRACE); + ((ASTNode) result) + .setLength(lastToken.getEndOffset() - startingOffset); + return result; + } - for (;;) { - switch (LT(1)) { - case IToken.tLPAREN: + // if we get this far, it means that we did not + // try this now instead + // assignmentExpression + IASTExpression assignmentExpression = assignmentExpression(); + IASTInitializerExpression result = createInitializerExpression(); + ((ASTNode) result).setOffsetAndLength(((ASTNode) assignmentExpression)); + result.setExpression(assignmentExpression); + assignmentExpression.setParent(result); + assignmentExpression + .setPropertyInParent(IASTInitializerExpression.INITIALIZER_EXPRESSION); + return result; + } - boolean failed = false; - - // temporary fix for initializer/function declaration - // ambiguity - if ( !LA(2).looksLikeExpression() - && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) { - if (LT(2) == IToken.tIDENTIFIER) { - IToken newMark = mark(); - consume(IToken.tLPAREN); - try { - try { - name(); - //TODO - we need to lookup/resolve this name - //see if its a type ... - //if it is a type, failed = false - //else failed = true - failed = false; - } catch (Exception e) { - int endOffset = (lastToken != null) ? lastToken - .getEndOffset() - : 0; - logException( - "declarator:queryIsTypeName", e); //$NON-NLS-1$ - throwBacktrack(startingOffset, endOffset - startingOffset ); - } - } catch (BacktrackException b) { - failed = true; - } + /** + * @return + */ + protected IASTInitializerList createInitializerList() { + return new CPPASTInitializerList(); + } - backup(newMark); - } - } - if ((!LA(2).looksLikeExpression() - && strategy != SimpleDeclarationStrategy.TRY_VARIABLE && !failed) - ) { - // parameterDeclarationClause - isFunction = true; - // TODO need to create a temporary scope object here - consume(IToken.tLPAREN); - boolean seenParameter = false; - parameterDeclarationLoop: for (;;) { - switch (LT(1)) { - case IToken.tRPAREN: - consume(); - break parameterDeclarationLoop; - case IToken.tELLIPSIS: - consume(); - encounteredVarArgs = true; - break; - case IToken.tCOMMA: - consume(); - seenParameter = false; - break; - default: - int endOffset = (lastToken != null) ? lastToken - .getEndOffset() : 0; - if (seenParameter) - throwBacktrack(startingOffset, endOffset - startingOffset ); - IASTParameterDeclaration p = parameterDeclaration(); - if( parameters == Collections.EMPTY_LIST ) - parameters = new ArrayList( DEFAULT_PARM_LIST_SIZE ); - parameters.add( p ); - seenParameter = true; - } - } - } + /** + * @return + */ + protected IASTInitializerExpression createInitializerExpression() { + return new CPPASTInitializerExpression(); + } - if (LT(1) == IToken.tCOLON ) - break overallLoop; - - if( LT(1) == IToken.t_try) - { - tryEncountered = true; - break overallLoop; - } - + /** + * Parse a declarator, as according to the ANSI C++ specification. + * + * declarator : (ptrOperator)* directDeclarator + * + * directDeclarator : declaratorId | directDeclarator "(" + * parameterDeclarationClause ")" (cvQualifier)* (exceptionSpecification)* | + * directDeclarator "[" (constantExpression)? "]" | "(" declarator")" | + * directDeclarator "(" parameterDeclarationClause ")" + * (oldKRParameterDeclaration)* + * + * declaratorId : name + * + * @param forTypeID + * TODO + * @param container + * IParserCallback object that represents the owner declaration. + * @return declarator that this parsing produced. + * @throws BacktrackException + * request a backtrack + */ + protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy, + boolean forTypeID) throws EndOfFileException, BacktrackException { - IToken beforeCVModifier = mark(); - IToken[] cvModifiers = new IToken[2]; - int numCVModifiers = 0; - IToken afterCVModifier = beforeCVModifier; - // const-volatile - // 2 options: either this is a marker for the method, - // or it might be the beginning of old K&R style - // parameter declaration, see - // void getenv(name) const char * name; {} - // This will be determined further below - while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile) - && numCVModifiers < 2) { - cvModifiers[numCVModifiers++] = consume(); - afterCVModifier = mark(); - } - //check for throws clause here - - if (LT(1) == IToken.t_throw) { - exceptionSpecIds = new ArrayList( DEFAULT_SIZE_EXCEPTIONS_LIST ); - consume( IToken.t_throw ); // throw - consume(IToken.tLPAREN); // ( - boolean done = false; - while (!done) { - switch (LT(1)) { - case IToken.tRPAREN: - consume(); - done = true; - break; - case IToken.tCOMMA: - consume(); - break; - default: - try { - exceptionSpecIds.add(typeId(false)); - } catch (BacktrackException e) { - IASTProblem p = failParse(e); - IASTProblemTypeId typeIdProblem = createTypeIDProblem(); - typeIdProblem.setProblem( p ); - ((CPPASTNode)typeIdProblem).setOffset( ((CPPASTNode)p).getOffset() ); - p.setParent( typeIdProblem ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - exceptionSpecIds.add( typeIdProblem ); - } - break; - } - } - } - // check for optional pure virtual - if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) { - char[] image = LA(2).getCharImage(); - if (image.length == 1 && image[0] == '0') { - consume(IToken.tASSIGN); - consume(IToken.tINTEGER); - isPureVirtual = true; - } - } - if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI) { - // There were C++-specific clauses after - // const/volatile modifier - // Then it is a marker for the method - if (numCVModifiers > 0) { - for (int i = 0; i < numCVModifiers; i++) { - if (cvModifiers[i].getType() == IToken.t_const) - isConst = true; - if (cvModifiers[i].getType() == IToken.t_volatile) - isVolatile = true; - } - } - afterCVModifier = mark(); - // In this case (method) we can't expect K&R - // parameter declarations, - // but we'll check anyway, for errorhandling - } - break; - case IToken.tLBRACKET: - arrayMods = new ArrayList( DEFAULT_POINTEROPS_LIST_SIZE ); - consumeArrayModifiers(arrayMods); - continue; - case IToken.tCOLON: - consume(IToken.tCOLON); - bitField = constantExpression(); - break; - default: - break; - } - break; - } - if (LA(1).getType() != IToken.tIDENTIFIER) - break; + IToken la = LA(1); + int startingOffset = la.getOffset(); + la = null; + IASTDeclarator innerDecl = null; + IASTName declaratorName = null; + List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); + List parameters = Collections.EMPTY_LIST; + List arrayMods = Collections.EMPTY_LIST; + List exceptionSpecIds = Collections.EMPTY_LIST; + boolean encounteredVarArgs = false; + boolean tryEncountered = false; + IASTExpression bitField = null; + boolean isFunction = false; + boolean isPureVirtual = false, isConst = false, isVolatile = false; - } while (true); - - - IASTDeclarator d = null; - if (isFunction) { - - ICPPASTFunctionDeclarator fc = null; - if( tryEncountered ) - fc = createTryBlockDeclarator(); - else - fc = createFunctionDeclarator(); - fc.setVarArgs(encounteredVarArgs); - for (int i = 0; i < parameters.size(); ++i) - { - IASTParameterDeclaration p = (IASTParameterDeclaration) parameters - .get(i); - p.setParent( fc ); - p.setPropertyInParent( IASTFunctionDeclarator.FUNCTION_PARAMETER ); - fc.addParameterDeclaration(p); - } - fc.setConst( isConst ); - fc.setVolatile( isVolatile ); - fc.setPureVirtual( isPureVirtual ); - for( int i = 0; i < exceptionSpecIds.size(); ++i ) - { - IASTTypeId typeId = (IASTTypeId) exceptionSpecIds.get(i); - fc.addExceptionSpecificationTypeId( typeId ); - typeId.setParent( fc ); - typeId.setPropertyInParent( ICPPASTFunctionDeclarator.EXCEPTION_TYPEID ); - } - d = fc; - } else if( arrayMods != Collections.EMPTY_LIST ) - { - d = createArrayDeclarator(); - for( int i = 0; i < arrayMods.size(); ++i ) - { - IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i); - m.setParent( d ); - m.setPropertyInParent( IASTArrayDeclarator.ARRAY_MODIFIER ); - ((IASTArrayDeclarator)d).addArrayModifier( m ); - } - } - else if (bitField != null) { - IASTFieldDeclarator fl = createFieldDeclarator(); - fl.setBitFieldSize(bitField); - d = fl; - } else - { - d = createDeclarator(); - } - for (int i = 0; i < pointerOps.size(); ++i) { - IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i); - d.addPointerOperator(po); - po.setParent(d); - po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR); - } - if (innerDecl != null) { - d.setNestedDeclarator(innerDecl); - innerDecl.setParent(d); - innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR); - } - if (declaratorName != null) { - d.setName(declaratorName); - declaratorName.setParent(d); - declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); - } + overallLoop: do { - return d; - - } - - /** - * @return - */ - protected IASTProblemTypeId createTypeIDProblem() { - return new CPPASTProblemTypeId(); - } - - /** - * @return - */ - protected ICPPASTFunctionTryBlockDeclarator createTryBlockDeclarator() { - return new CPPASTFunctionTryBlockDeclarator(); - } - - /** - * @return - */ - protected ICPPASTFunctionDeclarator createFunctionDeclarator() { - return new CPPASTFunctionDeclarator(); - } - - /** - * @return - */ - protected IASTFieldDeclarator createFieldDeclarator() { - return new CPPASTFieldDeclarator(); - } - - /** - * @return - */ - protected IASTDeclarator createArrayDeclarator() { - return new CPPASTArrayDeclarator(); - } - - /** - * @return - */ - protected IASTDeclarator createDeclarator() { - return new CPPASTDeclarator(); - } - - protected ITokenDuple consumeTemplatedOperatorName() - throws EndOfFileException, BacktrackException { - TemplateParameterManager argumentList = TemplateParameterManager - .getInstance(); - try { - if (LT(1) == IToken.t_operator) - return operatorId(null, null); - - try { - return name(); - } catch (BacktrackException bt) { - } - IToken start = null; - - boolean hasTemplateId = false; + consumePointerOperators(pointerOps); + if (!forTypeID && LT(1) == IToken.tLPAREN) { IToken mark = mark(); - if (LT(1) == IToken.tCOLONCOLON - || LT(1) == IToken.tIDENTIFIER) { - start = consume(); - IToken end = null; - - 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 = (lastToken != null) ? lastToken - .getEndOffset() : 0; - backup(mark); - throwBacktrack(mark.getOffset(), endOffset - mark.getOffset() ); - } - return TokenFactory.createTokenDuple( start, end, argumentList.getTemplateArgumentsList() ); + try { + consume(); + innerDecl = declarator(strategy, forTypeID); + consume(IToken.tRPAREN); + } catch (BacktrackException bte) { + backup(mark); } - int endOffset = (lastToken != null) ? lastToken - .getEndOffset() : 0; - backup(mark); - throwBacktrack(mark.getOffset(), endOffset - mark.getOffset() ); - - return null; - } finally { - TemplateParameterManager.returnInstance(argumentList); - } - } + declaratorName = createName(); + } else { + try { + ITokenDuple d = consumeTemplatedOperatorName(); + declaratorName = createName(d); + if (d.isConversion()) + isFunction = true; + } catch (BacktrackException bt) { + declaratorName = createName(); + } + } - /** - * Parse a class/struct/union definition. - * - * classSpecifier : classKey name (baseClause)? "{" (memberSpecification)* - * "}" - * @param owner - * IParserCallback object that represents the declaration that - * owns this classSpecifier - * - * @return TODO - * @throws BacktrackException - * request a backtrack - */ - protected ICPPASTCompositeTypeSpecifier classSpecifier() - throws BacktrackException, EndOfFileException { - int classKind = 0; - IToken classKey = null; - IToken mark = mark(); + for (;;) { + switch (LT(1)) { + case IToken.tLPAREN: - // class key - switch (LT(1)) { - case IToken.t_class: - classKey = consume(); - classKind = ICPPASTCompositeTypeSpecifier.k_class; + boolean failed = false; + + // temporary fix for initializer/function declaration + // ambiguity + if (!LA(2).looksLikeExpression() + && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) { + if (LT(2) == IToken.tIDENTIFIER) { + IToken newMark = mark(); + consume(IToken.tLPAREN); + try { + try { + name(); + //TODO - we need to lookup/resolve this name + //see if its a type ... + //if it is a type, failed = false + //else failed = true + failed = false; + } catch (Exception e) { + int endOffset = (lastToken != null) ? lastToken + .getEndOffset() : 0; + logException("declarator:queryIsTypeName", e); //$NON-NLS-1$ + throwBacktrack(startingOffset, endOffset + - startingOffset); + } + } catch (BacktrackException b) { + failed = true; + } + + backup(newMark); + } + } + if ((!LA(2).looksLikeExpression() + && strategy != SimpleDeclarationStrategy.TRY_VARIABLE && !failed)) { + // parameterDeclarationClause + isFunction = true; + // TODO need to create a temporary scope object here + consume(IToken.tLPAREN); + boolean seenParameter = false; + parameterDeclarationLoop: for (;;) { + switch (LT(1)) { + case IToken.tRPAREN: + consume(); + break parameterDeclarationLoop; + case IToken.tELLIPSIS: + consume(); + encounteredVarArgs = true; + break; + case IToken.tCOMMA: + consume(); + seenParameter = false; + break; + default: + int endOffset = (lastToken != null) ? lastToken + .getEndOffset() : 0; + if (seenParameter) + throwBacktrack(startingOffset, endOffset + - startingOffset); + IASTParameterDeclaration p = parameterDeclaration(); + if (parameters == Collections.EMPTY_LIST) + parameters = new ArrayList( + DEFAULT_PARM_LIST_SIZE); + parameters.add(p); + seenParameter = true; + } + } + } + + if (LT(1) == IToken.tCOLON) + break overallLoop; + + if (LT(1) == IToken.t_try) { + tryEncountered = true; + break overallLoop; + } + + IToken beforeCVModifier = mark(); + IToken[] cvModifiers = new IToken[2]; + int numCVModifiers = 0; + IToken afterCVModifier = beforeCVModifier; + // const-volatile + // 2 options: either this is a marker for the method, + // or it might be the beginning of old K&R style + // parameter declaration, see + // void getenv(name) const char * name; {} + // This will be determined further below + while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile) + && numCVModifiers < 2) { + cvModifiers[numCVModifiers++] = consume(); + afterCVModifier = mark(); + } + //check for throws clause here + + if (LT(1) == IToken.t_throw) { + exceptionSpecIds = new ArrayList( + DEFAULT_SIZE_EXCEPTIONS_LIST); + consume(IToken.t_throw); // throw + consume(IToken.tLPAREN); // ( + boolean done = false; + while (!done) { + switch (LT(1)) { + case IToken.tRPAREN: + consume(); + done = true; + break; + case IToken.tCOMMA: + consume(); + break; + default: + try { + exceptionSpecIds.add(typeId(false)); + } catch (BacktrackException e) { + IASTProblem p = failParse(e); + IASTProblemTypeId typeIdProblem = createTypeIDProblem(); + typeIdProblem.setProblem(p); + ((CPPASTNode) typeIdProblem) + .setOffsetAndLength(((CPPASTNode) p)); + p.setParent(typeIdProblem); + p + .setPropertyInParent(IASTProblemHolder.PROBLEM); + exceptionSpecIds.add(typeIdProblem); + } + break; + } + } + } + // check for optional pure virtual + if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER) { + char[] image = LA(2).getCharImage(); + if (image.length == 1 && image[0] == '0') { + consume(IToken.tASSIGN); + consume(IToken.tINTEGER); + isPureVirtual = true; + } + } + if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI) { + // There were C++-specific clauses after + // const/volatile modifier + // Then it is a marker for the method + if (numCVModifiers > 0) { + for (int i = 0; i < numCVModifiers; i++) { + if (cvModifiers[i].getType() == IToken.t_const) + isConst = true; + if (cvModifiers[i].getType() == IToken.t_volatile) + isVolatile = true; + } + } + afterCVModifier = mark(); + // In this case (method) we can't expect K&R + // parameter declarations, + // but we'll check anyway, for errorhandling + } + break; + case IToken.tLBRACKET: + arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); + consumeArrayModifiers(arrayMods); + continue; + case IToken.tCOLON: + consume(IToken.tCOLON); + bitField = constantExpression(); + break; + default: + break; + } break; - case IToken.t_struct: + } + if (LA(1).getType() != IToken.tIDENTIFIER) + break; + + } while (true); + + IASTDeclarator d = null; + if (isFunction) { + + ICPPASTFunctionDeclarator fc = null; + if (tryEncountered) + fc = createTryBlockDeclarator(); + else + fc = createFunctionDeclarator(); + fc.setVarArgs(encounteredVarArgs); + for (int i = 0; i < parameters.size(); ++i) { + IASTParameterDeclaration p = (IASTParameterDeclaration) parameters + .get(i); + p.setParent(fc); + p.setPropertyInParent(IASTFunctionDeclarator.FUNCTION_PARAMETER); + fc.addParameterDeclaration(p); + } + fc.setConst(isConst); + fc.setVolatile(isVolatile); + fc.setPureVirtual(isPureVirtual); + for (int i = 0; i < exceptionSpecIds.size(); ++i) { + IASTTypeId typeId = (IASTTypeId) exceptionSpecIds.get(i); + fc.addExceptionSpecificationTypeId(typeId); + typeId.setParent(fc); + typeId + .setPropertyInParent(ICPPASTFunctionDeclarator.EXCEPTION_TYPEID); + } + d = fc; + } else if (arrayMods != Collections.EMPTY_LIST) { + d = createArrayDeclarator(); + for (int i = 0; i < arrayMods.size(); ++i) { + IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i); + m.setParent(d); + m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER); + ((IASTArrayDeclarator) d).addArrayModifier(m); + } + } else if (bitField != null) { + IASTFieldDeclarator fl = createFieldDeclarator(); + fl.setBitFieldSize(bitField); + d = fl; + } else { + d = createDeclarator(); + } + for (int i = 0; i < pointerOps.size(); ++i) { + IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i); + d.addPointerOperator(po); + po.setParent(d); + po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR); + } + if (innerDecl != null) { + d.setNestedDeclarator(innerDecl); + innerDecl.setParent(d); + innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR); + } + if (declaratorName != null) { + d.setName(declaratorName); + declaratorName.setParent(d); + declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); + } + + return d; + + } + + /** + * @return + */ + protected IASTProblemTypeId createTypeIDProblem() { + return new CPPASTProblemTypeId(); + } + + /** + * @return + */ + protected ICPPASTFunctionTryBlockDeclarator createTryBlockDeclarator() { + return new CPPASTFunctionTryBlockDeclarator(); + } + + /** + * @return + */ + protected ICPPASTFunctionDeclarator createFunctionDeclarator() { + return new CPPASTFunctionDeclarator(); + } + + /** + * @return + */ + protected IASTFieldDeclarator createFieldDeclarator() { + return new CPPASTFieldDeclarator(); + } + + /** + * @return + */ + protected IASTDeclarator createArrayDeclarator() { + return new CPPASTArrayDeclarator(); + } + + /** + * @return + */ + protected IASTDeclarator createDeclarator() { + return new CPPASTDeclarator(); + } + + protected ITokenDuple consumeTemplatedOperatorName() + throws EndOfFileException, BacktrackException { + TemplateParameterManager argumentList = TemplateParameterManager + .getInstance(); + try { + if (LT(1) == IToken.t_operator) + return operatorId(null, null); + + try { + return name(); + } catch (BacktrackException bt) { + } + IToken start = null; + + boolean hasTemplateId = false; + + IToken mark = mark(); + if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) { + start = consume(); + IToken end = null; + + 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 = (lastToken != null) ? lastToken.getEndOffset() + : 0; + backup(mark); + throwBacktrack(mark.getOffset(), endOffset - mark.getOffset()); + } + return TokenFactory.createTokenDuple(start, end, argumentList + .getTemplateArgumentsList()); + } + int endOffset = (lastToken != null) ? lastToken.getEndOffset() : 0; + backup(mark); + throwBacktrack(mark.getOffset(), endOffset - mark.getOffset()); + + return null; + } finally { + TemplateParameterManager.returnInstance(argumentList); + } + } + + /** + * Parse a class/struct/union definition. + * + * classSpecifier : classKey name (baseClause)? "{" (memberSpecification)* + * "}" + * + * @param owner + * IParserCallback object that represents the declaration that owns + * this classSpecifier + * + * @return TODO + * @throws BacktrackException + * request a backtrack + */ + protected ICPPASTCompositeTypeSpecifier classSpecifier() + throws BacktrackException, EndOfFileException { + int classKind = 0; + IToken classKey = null; + IToken mark = mark(); + + // class key + switch (LT(1)) { + case IToken.t_class: + classKey = consume(); + classKind = ICPPASTCompositeTypeSpecifier.k_class; + break; + case IToken.t_struct: classKey = consume(); classKind = IASTCompositeTypeSpecifier.k_struct; break; - case IToken.t_union: + case IToken.t_union: classKey = consume(); classKind = IASTCompositeTypeSpecifier.k_union; break; - default: + default: throwBacktrack(mark.getOffset(), mark.getLength()); - } + } - IASTName name = null; + IASTName name = null; - // class name - if (LT(1) == IToken.tIDENTIFIER) - name = createName( name() ); - else - name = createName(); + // class name + if (LT(1) == IToken.tIDENTIFIER) + name = createName(name()); + else + name = createName(); - if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) { - IToken errorPoint = LA(1); - backup(mark); - throwBacktrack(errorPoint.getOffset(), errorPoint.getLength() ); - } - - ICPPASTCompositeTypeSpecifier astClassSpecifier = createClassSpecifier(); - ((ASTNode)astClassSpecifier).setOffset( classKey.getOffset() ); - astClassSpecifier.setKey( classKind ); - astClassSpecifier.setName( name ); - name.setParent( astClassSpecifier ); - name.setPropertyInParent( IASTCompositeTypeSpecifier.TYPE_NAME ); - - // base clause - if (LT(1) == IToken.tCOLON) { - baseSpecifier(astClassSpecifier); - } + if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) { + IToken errorPoint = LA(1); + backup(mark); + throwBacktrack(errorPoint.getOffset(), errorPoint.getLength()); + } - if (LT(1) == IToken.tLBRACE) { - consume(IToken.tLBRACE); + ICPPASTCompositeTypeSpecifier astClassSpecifier = createClassSpecifier(); + ((ASTNode) astClassSpecifier).setOffset(classKey.getOffset()); + astClassSpecifier.setKey(classKind); + astClassSpecifier.setName(name); + name.setParent(astClassSpecifier); + name.setPropertyInParent(IASTCompositeTypeSpecifier.TYPE_NAME); - cleanupLastToken(); - memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) { - int checkToken = LA(1).hashCode(); - switch (LT(1)) { - case IToken.t_public: - case IToken.t_protected: - case IToken.t_private: - IToken key = consume(); - consume(IToken.tCOLON); - ICPPASTVisiblityLabel label = createVisibilityLabel(); - ((ASTNode)label).setOffset( key.getOffset() ); - label.setVisibility( token2Visibility( key.getType() )); - astClassSpecifier.addMemberDeclaration( label ); - label.setParent( astClassSpecifier ); - label.setPropertyInParent( ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL ); - break; - case IToken.tRBRACE: - consume(IToken.tRBRACE); - break memberDeclarationLoop; - default: - try { - IASTDeclaration d = declaration(); - astClassSpecifier.addMemberDeclaration( d ); - d.setParent( astClassSpecifier ); - d.setPropertyInParent( IASTCompositeTypeSpecifier.MEMBER_DECLARATION ); - } catch (BacktrackException bt) { - IASTProblem p = failParse(bt); - IASTProblemDeclaration pd = createProblemDeclaration(); - pd.setProblem( p ); - ((CPPASTNode)pd).setOffset( ((CPPASTNode)p).getOffset() ); - p.setParent( pd ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - astClassSpecifier.addMemberDeclaration( pd ); - pd.setParent( astClassSpecifier ); - pd.setPropertyInParent( IASTCompositeTypeSpecifier.MEMBER_DECLARATION ); - if (checkToken == LA(1).hashCode()) - errorHandling(); - } - } - if (checkToken == LA(1).hashCode()) - failParseWithErrorHandling(); - } - // consume the } - consume(IToken.tRBRACE); + // base clause + if (LT(1) == IToken.tCOLON) { + baseSpecifier(astClassSpecifier); + } + if (LT(1) == IToken.tLBRACE) { + consume(IToken.tLBRACE); - } - return astClassSpecifier; - } - - /** - * @return - */ - protected ICPPASTCompositeTypeSpecifier createClassSpecifier() { - return new CPPASTCompositeTypeSpecifier(); - } - - /** - * @return - */ - protected ICPPASTVisiblityLabel createVisibilityLabel() { - return new CPPASTVisibilityLabel(); - } - - /** - * @param type - * @return - */ - protected int token2Visibility(int type) { - switch( type ) - { - case IToken.t_public: - return ICPPASTVisiblityLabel.v_public; - case IToken.t_protected: - return ICPPASTVisiblityLabel.v_protected; - case IToken.t_private: - return ICPPASTVisiblityLabel.v_private; - } - return 0; - } - - /** - * Parse the subclass-baseclauses for a class specification. - * - * baseclause: : basespecifierlist - * basespecifierlist: basespecifier - * basespecifierlist, basespecifier - * basespecifier: ::? nestednamespecifier? classname - * virtual accessspecifier? ::? nestednamespecifier? classname - * accessspecifier virtual? ::? nestednamespecifier? classname - * accessspecifier: private | protected | public - * @param classSpecOwner - * @throws BacktrackException - */ - protected void baseSpecifier(ICPPASTCompositeTypeSpecifier astClassSpec) - throws EndOfFileException, BacktrackException { - - consume(IToken.tCOLON); - - boolean isVirtual = false; - int visibility = 0; //ASTAccessVisibility.PUBLIC; - IASTName name = null; - IToken firstToken = null; - baseSpecifierLoop: for (;;) { + cleanupLastToken(); + memberDeclarationLoop: while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); switch (LT(1)) { + case IToken.t_public: + case IToken.t_protected: + case IToken.t_private: + IToken key = consume(); + consume(IToken.tCOLON); + ICPPASTVisiblityLabel label = createVisibilityLabel(); + ((ASTNode) label).setOffsetAndLength(key.getOffset(), + lastToken.getEndOffset() - key.getOffset()); + label.setVisibility(token2Visibility(key.getType())); + astClassSpecifier.addMemberDeclaration(label); + label.setParent(astClassSpecifier); + label + .setPropertyInParent(ICPPASTCompositeTypeSpecifier.VISIBILITY_LABEL); + break; + case IToken.tRBRACE: + consume(IToken.tRBRACE); + break memberDeclarationLoop; + default: + try { + IASTDeclaration d = declaration(); + astClassSpecifier.addMemberDeclaration(d); + d.setParent(astClassSpecifier); + d + .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION); + } catch (BacktrackException bt) { + IASTProblem p = failParse(bt); + IASTProblemDeclaration pd = createProblemDeclaration(); + pd.setProblem(p); + ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p)); + p.setParent(pd); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + astClassSpecifier.addMemberDeclaration(pd); + pd.setParent(astClassSpecifier); + pd + .setPropertyInParent(IASTCompositeTypeSpecifier.MEMBER_DECLARATION); + if (checkToken == LA(1).hashCode()) + errorHandling(); + } + } + if (checkToken == LA(1).hashCode()) + failParseWithErrorHandling(); + } + // consume the } + consume(IToken.tRBRACE); + ((ASTNode) astClassSpecifier).setLength(lastToken.getEndOffset() + - classKey.getOffset()); + + } + return astClassSpecifier; + } + + /** + * @return + */ + protected ICPPASTCompositeTypeSpecifier createClassSpecifier() { + return new CPPASTCompositeTypeSpecifier(); + } + + /** + * @return + */ + protected ICPPASTVisiblityLabel createVisibilityLabel() { + return new CPPASTVisibilityLabel(); + } + + /** + * @param type + * @return + */ + protected int token2Visibility(int type) { + switch (type) { + case IToken.t_public: + return ICPPASTVisiblityLabel.v_public; + case IToken.t_protected: + return ICPPASTVisiblityLabel.v_protected; + case IToken.t_private: + return ICPPASTVisiblityLabel.v_private; + } + return 0; + } + + /** + * Parse the subclass-baseclauses for a class specification. + * + * baseclause: : basespecifierlist basespecifierlist: basespecifier + * basespecifierlist, basespecifier basespecifier: ::? nestednamespecifier? + * classname virtual accessspecifier? ::? nestednamespecifier? classname + * accessspecifier virtual? ::? nestednamespecifier? classname + * accessspecifier: private | protected | public + * + * @param classSpecOwner + * @throws BacktrackException + */ + protected void baseSpecifier(ICPPASTCompositeTypeSpecifier astClassSpec) + throws EndOfFileException, BacktrackException { + + consume(IToken.tCOLON); + + boolean isVirtual = false; + int visibility = 0; //ASTAccessVisibility.PUBLIC; + IASTName name = null; + IToken firstToken = null; + baseSpecifierLoop: for (;;) { + switch (LT(1)) { case IToken.t_virtual: - if( firstToken == null ) - firstToken = consume(IToken.t_virtual); - else - consume(IToken.t_virtual); - isVirtual = true; - break; + if (firstToken == null) + firstToken = consume(IToken.t_virtual); + else + consume(IToken.t_virtual); + isVirtual = true; + break; case IToken.t_public: - visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public; - if( firstToken == null ) - firstToken = consume(); - else - consume(); - break; + visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_public; + if (firstToken == null) + firstToken = consume(); + else + consume(); + break; case IToken.t_protected: - visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected; - if( firstToken == null ) - firstToken = consume(); - else - consume(); - break; + visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_protected; + if (firstToken == null) + firstToken = consume(); + else + consume(); + break; case IToken.t_private: - visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private; - if( firstToken == null ) - firstToken = consume(); - else - consume(); - break; + visibility = ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.v_private; + if (firstToken == null) + firstToken = consume(); + else + consume(); + break; case IToken.tCOLONCOLON: case IToken.tIDENTIFIER: - //to get templates right we need to use the class as the scope - name = createName( name() ); - break; + //to get templates right we need to use the class as the scope + name = createName(name()); + break; case IToken.tCOMMA: - if( name == null ) - name = createName(); - ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = createBaseSpecifier(); - if( firstToken != null ) - ((ASTNode)baseSpec).setOffset( firstToken.getOffset() ); - baseSpec.setVirtual( isVirtual ); - baseSpec.setVisibility( visibility ); - baseSpec.setName( name ); - name.setParent( baseSpec ); - name.setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME ); + if (name == null) + name = createName(); + consume(); + ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = createBaseSpecifier(); + if (firstToken != null) + ((ASTNode) baseSpec).setOffsetAndLength(firstToken + .getOffset(), lastToken.getEndOffset() + - firstToken.getOffset()); + baseSpec.setVirtual(isVirtual); + baseSpec.setVisibility(visibility); + baseSpec.setName(name); + name.setParent(baseSpec); + name + .setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME); - astClassSpec.addBaseSpecifier( baseSpec ); - baseSpec.setParent( astClassSpec ); - baseSpec.setPropertyInParent( ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER ); - - isVirtual = false; - visibility = 0; - name = null; - firstToken = null; - consume(); - continue baseSpecifierLoop; - case IToken.tLBRACE: - if( name == null ) - name = createName(); - baseSpec = createBaseSpecifier(); - if( firstToken != null ) - ((ASTNode)baseSpec).setOffset( firstToken.getOffset() ); - baseSpec.setVirtual( isVirtual ); - baseSpec.setVisibility( visibility ); - baseSpec.setName( name ); - name.setParent( baseSpec ); - name.setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME ); + astClassSpec.addBaseSpecifier(baseSpec); + baseSpec.setParent(astClassSpec); + baseSpec + .setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER); - astClassSpec.addBaseSpecifier( baseSpec ); - baseSpec.setParent( astClassSpec ); - baseSpec.setPropertyInParent( ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER ); - //fall through + isVirtual = false; + visibility = 0; + name = null; + firstToken = null; + + continue baseSpecifierLoop; + case IToken.tLBRACE: + if (name == null) + name = createName(); + baseSpec = createBaseSpecifier(); + if (firstToken != null) + ((ASTNode) baseSpec).setOffsetAndLength(firstToken + .getOffset(), lastToken.getEndOffset() + - firstToken.getOffset()); + baseSpec.setVirtual(isVirtual); + baseSpec.setVisibility(visibility); + baseSpec.setName(name); + name.setParent(baseSpec); + name + .setPropertyInParent(ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME); + + astClassSpec.addBaseSpecifier(baseSpec); + baseSpec.setParent(astClassSpec); + baseSpec + .setPropertyInParent(ICPPASTCompositeTypeSpecifier.BASE_SPECIFIER); + //fall through default: - break baseSpecifierLoop; + break baseSpecifierLoop; + } + } + } + + /** + * @return + */ + protected ICPPASTBaseSpecifier createBaseSpecifier() { + return new CPPASTBaseSpecifier(); + } + + protected void catchHandlerSequence(List collection) + throws EndOfFileException, BacktrackException { + if (LT(1) != IToken.t_catch) { + IToken la = LA(1); + throwBacktrack(la.getOffset(), la.getLength()); // error, need at least + // one of these + } + while (LT(1) == IToken.t_catch) { + int startOffset = consume(IToken.t_catch).getOffset(); + consume(IToken.tLPAREN); + boolean isEllipsis = false; + IASTDeclaration decl = null; + try { + if (LT(1) == IToken.tELLIPSIS) { + consume(IToken.tELLIPSIS); + isEllipsis = true; + } else { + decl = simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, + true); } - } - } + consume(IToken.tRPAREN); + } catch (BacktrackException bte) { + IASTProblem p = failParse(bte); + IASTProblemDeclaration pd = createProblemDeclaration(); + pd.setProblem(p); + ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p)); + p.setParent(pd); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + decl = pd; + } + IASTStatement compoundStatement = catchBlockCompoundStatement(); + ICPPASTCatchHandler handler = createCatchHandler(); + ((ASTNode) handler).setOffsetAndLength(startOffset, lastToken + .getEndOffset() + - startOffset); + handler.setIsCatchAll(isEllipsis); + if (decl != null) { + handler.setDeclaration(decl); + decl.setParent(handler); + decl.setPropertyInParent(ICPPASTCatchHandler.DECLARATION); + } + if (compoundStatement != null) { + handler.setCatchBody(compoundStatement); + compoundStatement.setParent(handler); + compoundStatement + .setPropertyInParent(ICPPASTCatchHandler.CATCH_BODY); + } + collection.add(handler); + } + } - /** - * @return - */ - protected ICPPASTBaseSpecifier createBaseSpecifier() { - return new CPPASTBaseSpecifier(); - } + /** + * @return + */ + protected ICPPASTCatchHandler createCatchHandler() { + return new CPPASTCatchHandler(); + } - protected void catchHandlerSequence(List collection) - throws EndOfFileException, BacktrackException { - if (LT(1) != IToken.t_catch) { - IToken la = LA(1); - throwBacktrack(la.getOffset(), la.getLength()); // error, need at least one of these - } - while (LT(1) == IToken.t_catch) { - int startOffset = consume(IToken.t_catch).getOffset(); - consume(IToken.tLPAREN); - boolean isEllipsis = false; - IASTDeclaration decl = null; - try { - if (LT(1) == IToken.tELLIPSIS) - { - consume(IToken.tELLIPSIS); - isEllipsis = true; - } - else - { - decl = simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, - true); - } - consume(IToken.tRPAREN); - } - catch (BacktrackException bte) { - IASTProblem p = failParse(bte); - IASTProblemDeclaration pd = createProblemDeclaration(); - pd.setProblem( p ); - ((CPPASTNode)pd).setOffset( ((CPPASTNode)p).getOffset() ); - p.setParent( pd ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - decl = pd; - } + protected IASTStatement catchBlockCompoundStatement() + throws BacktrackException, EndOfFileException { + if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) { + skipOverCompoundStatement(); + return null; + } else if (mode == ParserMode.COMPLETION_PARSE + || mode == ParserMode.SELECTION_PARSE) { + if (scanner.isOnTopContext()) + return compoundStatement(); + skipOverCompoundStatement(); + return null; + } + return compoundStatement(); + } - IASTStatement compoundStatement = catchBlockCompoundStatement(); - ICPPASTCatchHandler handler = createCatchHandler(); - ((ASTNode)handler).setOffset( startOffset ); - handler.setIsCatchAll( isEllipsis ); - if( decl != null ) - { - handler.setDeclaration( decl ); - decl.setParent( handler ); - decl.setPropertyInParent( ICPPASTCatchHandler.DECLARATION ); - } - if( compoundStatement != null ) - { - handler.setCatchBody( compoundStatement ); - compoundStatement.setParent( handler ); - compoundStatement.setPropertyInParent( ICPPASTCatchHandler.CATCH_BODY ); - } - collection.add( handler ); - } - } + /** + * @throws BacktrackException + */ + protected IASTNode forInitStatement() throws BacktrackException, + EndOfFileException { + IToken mark = mark(); + try { + IASTExpression e = expression(); + consume(IToken.tSEMI); + return e; - /** - * @return - */ - protected ICPPASTCatchHandler createCatchHandler() { - return new CPPASTCatchHandler(); - } - - protected IASTStatement catchBlockCompoundStatement() - throws BacktrackException, EndOfFileException { - if (mode == ParserMode.QUICK_PARSE - || mode == ParserMode.STRUCTURAL_PARSE) - { - skipOverCompoundStatement(); + } catch (BacktrackException bt) { + backup(mark); + try { + return simpleDeclarationStrategyUnion(); + } catch (BacktrackException b) { + failParse(); + throwBacktrack(b); return null; - } - else if (mode == ParserMode.COMPLETION_PARSE - || mode == ParserMode.SELECTION_PARSE) { - if (scanner.isOnTopContext()) - return compoundStatement(); - skipOverCompoundStatement(); - return null; - } - return compoundStatement(); - } + } + } - /** - * @throws BacktrackException - */ - protected IASTNode forInitStatement() throws BacktrackException, - EndOfFileException { - IToken mark = mark(); - try { - IASTExpression e = expression(); - consume(IToken.tSEMI); - return e; + } - } catch (BacktrackException bt) { - backup(mark); + /** + * This is the top-level entry point into the ANSI C++ grammar. + * + * translationUnit : (declaration)* + */ + protected void translationUnit() { + try { + translationUnit = createTranslationUnit(); + } catch (Exception e2) { + logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$ + return; + } + translationUnit.setLocationResolver(scanner.getLocationResolver()); + + while (true) { + try { + int checkOffset = LA(1).hashCode(); + IASTDeclaration declaration = declaration(); + translationUnit.addDeclaration(declaration); + declaration.setParent(translationUnit); + declaration + .setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); + + if (LA(1).hashCode() == checkOffset) + failParseWithErrorHandling(); + } catch (EndOfFileException e) { + if (translationUnit.getDeclarations().length != 0) { + CPPASTNode d = (CPPASTNode) translationUnit.getDeclarations()[translationUnit + .getDeclarations().length - 1]; + ((CPPASTNode) translationUnit).setLength(d.getOffset() + + d.getLength()); + } else + ((CPPASTNode) translationUnit).setLength(0); + break; + } catch (BacktrackException b) { try { - return simpleDeclarationStrategyUnion(); - } catch (BacktrackException b) { - failParse(); - throwBacktrack(b); - return null; - } - } - - } - - - /** - * This is the top-level entry point into the ANSI C++ grammar. - * - * translationUnit : (declaration)* - */ - protected void translationUnit() { - try { - translationUnit = createTranslationUnit(); - } catch (Exception e2) { - logException("translationUnit::createCompilationUnit()", e2); //$NON-NLS-1$ - return; - } - translationUnit.setLocationResolver(scanner.getLocationResolver()); - - while (true) { - try { - int checkOffset = LA(1).hashCode(); - IASTDeclaration declaration = declaration(); - translationUnit.addDeclaration( declaration ); - declaration.setParent( translationUnit ); - declaration.setPropertyInParent( IASTTranslationUnit.OWNED_DECLARATION ); - - if (LA(1).hashCode() == checkOffset) - failParseWithErrorHandling(); + // Mark as failure and try to reach a recovery point + IASTProblem p = failParse(b); + IASTProblemDeclaration pd = createProblemDeclaration(); + p.setParent(pd); + pd.setProblem(p); + ((CPPASTNode) pd).setOffsetAndLength(((CPPASTNode) p)); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + translationUnit.addDeclaration(pd); + pd.setParent(translationUnit); + pd.setPropertyInParent(IASTTranslationUnit.OWNED_DECLARATION); + errorHandling(); } catch (EndOfFileException e) { - // Good - break; - } catch (BacktrackException b) { - try { - // Mark as failure and try to reach a recovery point - IASTProblem p = failParse(b); - IASTProblemDeclaration pd = createProblemDeclaration(); - p.setParent( pd ); - pd.setProblem( p ); - ((CPPASTNode)pd).setOffset( ((CPPASTNode)p).getOffset() ); - p.setPropertyInParent( IASTProblemHolder.PROBLEM ); - translationUnit.addDeclaration( pd ); - pd.setParent( translationUnit ); - pd.setPropertyInParent( IASTTranslationUnit.OWNED_DECLARATION ); - errorHandling(); - } catch (EndOfFileException e) { - break; - } - } catch (OutOfMemoryError oome) { - logThrowable("translationUnit", oome); //$NON-NLS-1$ - throw oome; - } catch (Exception e) { - logException("translationUnit", e); //$NON-NLS-1$ - try { - failParseWithErrorHandling(); - } catch (EndOfFileException e3) { - //nothing - } - } catch (ParseError perr) { - throw perr; - } catch (Throwable e) { - logThrowable("translationUnit", e); //$NON-NLS-1$ - try { - failParseWithErrorHandling(); - } catch (EndOfFileException e3) { - //break; - } + break; } - } - } - - /** - * @return - */ - protected IASTProblemDeclaration createProblemDeclaration() { - return new CPPASTProblemDeclaration(); - } - - /** - * @return - */ - protected CPPASTTranslationUnit createTranslationUnit() { - return new CPPASTTranslationUnit(); - } - - protected void consumeArrayModifiers(List collection) throws EndOfFileException, BacktrackException { - while (LT(1) == IToken.tLBRACKET) { - int o = consume(IToken.tLBRACKET).getOffset(); // eat the '[' - - IASTExpression exp = null; - if (LT(1) != IToken.tRBRACKET) { - exp = constantExpression(); + } catch (OutOfMemoryError oome) { + logThrowable("translationUnit", oome); //$NON-NLS-1$ + throw oome; + } catch (Exception e) { + logException("translationUnit", e); //$NON-NLS-1$ + try { + failParseWithErrorHandling(); + } catch (EndOfFileException e3) { + //nothing } - consume(IToken.tRBRACKET); - IASTArrayModifier arrayMod = createArrayModifier(); - ((ASTNode)arrayMod).setOffset(o); - if( exp != null ) - { - arrayMod.setConstantExpression( exp ); - exp.setParent( arrayMod ); - exp.setPropertyInParent( IASTArrayModifier.CONSTANT_EXPRESSION ); + } catch (ParseError perr) { + throw perr; + } catch (Throwable e) { + logThrowable("translationUnit", e); //$NON-NLS-1$ + try { + failParseWithErrorHandling(); + } catch (EndOfFileException e3) { + //break; } - collection.add(arrayMod); - } - return; - } + } + } + } - /** - * @return - */ - protected IASTArrayModifier createArrayModifier() { - return new CPPASTArrayModifier(); - } + /** + * @return + */ + protected IASTProblemDeclaration createProblemDeclaration() { + return new CPPASTProblemDeclaration(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit() - */ - protected IASTTranslationUnit getTranslationUnit() { - return translationUnit; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement() - */ - protected IASTCompoundStatement createCompoundStatement() { - return new CPPASTCompoundStatement(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression() - */ - protected IASTBinaryExpression createBinaryExpression() { - return new CPPASTBinaryExpression(); - } + /** + * @return + */ + protected CPPASTTranslationUnit createTranslationUnit() { + return new CPPASTTranslationUnit(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression() - */ - protected IASTConditionalExpression createConditionalExpression() { - return new CPPASTConditionalExpression(); - } + protected void consumeArrayModifiers(List collection) + throws EndOfFileException, BacktrackException { + while (LT(1) == IToken.tLBRACKET) { + int o = consume(IToken.tLBRACKET).getOffset(); // eat the '[' - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression() - */ - protected IASTUnaryExpression createUnaryExpression() { - return new CPPASTUnaryExpression(); - } + IASTExpression exp = null; + if (LT(1) != IToken.tRBRACKET) { + exp = constantExpression(); + } + consume(IToken.tRBRACKET); + IASTArrayModifier arrayMod = createArrayModifier(); + ((ASTNode) arrayMod).setOffsetAndLength(o, lastToken.getEndOffset() + - o); + if (exp != null) { + arrayMod.setConstantExpression(exp); + exp.setParent(arrayMod); + exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION); + } + collection.add(arrayMod); + } + return; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression() - */ - protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() { - return new CPPASTCompoundStatementExpression(); - } + /** + * @return + */ + protected IASTArrayModifier createArrayModifier() { + return new CPPASTArrayModifier(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList() - */ - protected IASTExpressionList createExpressionList() { - return new CPPASTExpressionList(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit() + */ + protected IASTTranslationUnit getTranslationUnit() { + return translationUnit; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken) - */ - protected IASTName createName(IToken token) { - return new CPPASTName( token.getCharImage() ); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement() + */ + protected IASTCompoundStatement createCompoundStatement() { + return new CPPASTCompoundStatement(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName() - */ - protected IASTName createName() { - return new CPPASTName(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression() + */ + protected IASTBinaryExpression createBinaryExpression() { + return new CPPASTBinaryExpression(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator() - */ - protected IASTEnumerator createEnumerator() { - return new CPPASTEnumerator(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression() + */ + protected IASTConditionalExpression createConditionalExpression() { + return new CPPASTConditionalExpression(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#buildTypeIdExpression(int, org.eclipse.cdt.core.dom.ast.IASTTypeId, int) - */ - protected IASTExpression buildTypeIdExpression(int op_sizeof, IASTTypeId typeId, int startingOffset) { - IASTTypeIdExpression typeIdExpression = createTypeIdExpression(); - ((ASTNode)typeIdExpression).setOffset( startingOffset ); - typeIdExpression.setOperator( op_sizeof ); - typeIdExpression.setTypeId( typeId ); - typeId.setParent( typeIdExpression ); - typeId.setPropertyInParent( IASTTypeIdExpression.TYPE_ID ); - return typeIdExpression; - } - - /** - * @return - */ - protected IASTTypeIdExpression createTypeIdExpression() { - return new CPPASTTypeIdExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression() + */ + protected IASTUnaryExpression createUnaryExpression() { + return new CPPASTUnaryExpression(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerationSpecifier() - */ - protected IASTEnumerationSpecifier createEnumerationSpecifier() { - return new CPPASTEnumerationSpecifier(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression() + */ + protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() { + return new CPPASTCompoundStatementExpression(); + } - /** - * @return - */ - protected IASTLabelStatement createLabelStatement() { - return new CPPASTLabelStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList() + */ + protected IASTExpressionList createExpressionList() { + return new CPPASTExpressionList(); + } - /** - * @return - */ - protected IASTGotoStatement createGoToStatement() { - return new CPPASTGotoStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken) + */ + protected IASTName createName(IToken token) { + return new CPPASTName(token.getCharImage()); + } - /** - * @return - */ - protected IASTReturnStatement createReturnStatement() { - return new CPPASTReturnStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName() + */ + protected IASTName createName() { + return new CPPASTName(); + } - /** - * @return - */ - protected IASTForStatement createForStatement() { - return new CPPASTForStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator() + */ + protected IASTEnumerator createEnumerator() { + return new CPPASTEnumerator(); + } - /** - * @return - */ - protected IASTContinueStatement createContinueStatement() { - return new CPPASTContinueStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#buildTypeIdExpression(int, + * org.eclipse.cdt.core.dom.ast.IASTTypeId, int) + */ + protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId, + int startingOffset, int endingOffset) { + IASTTypeIdExpression typeIdExpression = createTypeIdExpression(); + ((ASTNode) typeIdExpression).setOffsetAndLength(startingOffset, + endingOffset - startingOffset); + ((ASTNode) typeIdExpression).setLength(endingOffset - startingOffset); + typeIdExpression.setOperator(op); + typeIdExpression.setTypeId(typeId); + typeId.setParent(typeIdExpression); + typeId.setPropertyInParent(IASTTypeIdExpression.TYPE_ID); + return typeIdExpression; + } - /** - * @return - */ - protected IASTDoStatement createDoStatement() { - return new CPPASTDoStatement(); - } + /** + * @return + */ + protected IASTTypeIdExpression createTypeIdExpression() { + return new CPPASTTypeIdExpression(); + } - /** - * @return - */ - protected IASTBreakStatement createBreakStatement() { - return new CPPASTBreakStatement(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerationSpecifier() + */ + protected IASTEnumerationSpecifier createEnumerationSpecifier() { + return new CPPASTEnumerationSpecifier(); + } - /** - * @return - */ - protected IASTWhileStatement createWhileStatement() { - return new CPPASTWhileStatement(); - } + /** + * @return + */ + protected IASTLabelStatement createLabelStatement() { + return new CPPASTLabelStatement(); + } - /** - * @return - */ - protected IASTNullStatement createNullStatement() { - return new CPPASTNullStatement(); - } + /** + * @return + */ + protected IASTGotoStatement createGoToStatement() { + return new CPPASTGotoStatement(); + } - /** - * @return - */ - protected IASTSwitchStatement createSwitchStatement() { - return new CPPASTSwitchStatement(); - } + /** + * @return + */ + protected IASTReturnStatement createReturnStatement() { + return new CPPASTReturnStatement(); + } - /** - * @return - */ - protected IASTIfStatement createIfStatement() { - return new CPPASTIfStatement(); - } + /** + * @return + */ + protected IASTForStatement createForStatement() { + return new CPPASTForStatement(); + } - /** - * @return - */ - protected IASTDefaultStatement createDefaultStatement() { - return new CPPASTDefaultStatement(); - } + /** + * @return + */ + protected IASTContinueStatement createContinueStatement() { + return new CPPASTContinueStatement(); + } - /** - * @return - */ - protected IASTCaseStatement createCaseStatement() { - return new CPPASTCaseStatement(); - } + /** + * @return + */ + protected IASTDoStatement createDoStatement() { + return new CPPASTDoStatement(); + } - /** - * @return - */ - protected IASTExpressionStatement createExpressionStatement() { - return new CPPASTExpressionStatement(); - } + /** + * @return + */ + protected IASTBreakStatement createBreakStatement() { + return new CPPASTBreakStatement(); + } - /** - * @return - */ - protected IASTDeclarationStatement createDeclarationStatement() { - return new CPPASTDeclarationStatement(); - } + /** + * @return + */ + protected IASTWhileStatement createWhileStatement() { + return new CPPASTWhileStatement(); + } - /** - * @return - */ - protected IASTASMDeclaration createASMDirective() { - return new CPPASTASMDeclaration(); - } + /** + * @return + */ + protected IASTNullStatement createNullStatement() { + return new CPPASTNullStatement(); + } - /** - * @return - */ - protected IASTCastExpression createCastExpression() { - return new CPPASTCastExpression(); - } + /** + * @return + */ + protected IASTSwitchStatement createSwitchStatement() { + return new CPPASTSwitchStatement(); + } - protected IASTStatement statement() throws EndOfFileException, BacktrackException { - - switch (LT(1)) { - // labeled statements - case IToken.t_case: - return parseCaseStatement(); - case IToken.t_default: + /** + * @return + */ + protected IASTIfStatement createIfStatement() { + return new CPPASTIfStatement(); + } + + /** + * @return + */ + protected IASTDefaultStatement createDefaultStatement() { + return new CPPASTDefaultStatement(); + } + + /** + * @return + */ + protected IASTCaseStatement createCaseStatement() { + return new CPPASTCaseStatement(); + } + + /** + * @return + */ + protected IASTExpressionStatement createExpressionStatement() { + return new CPPASTExpressionStatement(); + } + + /** + * @return + */ + protected IASTDeclarationStatement createDeclarationStatement() { + return new CPPASTDeclarationStatement(); + } + + /** + * @return + */ + protected IASTASMDeclaration createASMDirective() { + return new CPPASTASMDeclaration(); + } + + /** + * @return + */ + protected IASTCastExpression createCastExpression() { + return new CPPASTCastExpression(); + } + + protected IASTStatement statement() throws EndOfFileException, + BacktrackException { + + switch (LT(1)) { + // labeled statements + case IToken.t_case: + return parseCaseStatement(); + case IToken.t_default: return parseDefaultStatement(); - // compound statement - case IToken.tLBRACE: + // compound statement + case IToken.tLBRACE: return parseCompoundStatement(); - // selection statement - case IToken.t_if: + // selection statement + case IToken.t_if: return parseIfStatement(); - case IToken.t_switch: + case IToken.t_switch: return parseSwitchStatement(); - //iteration statements - case IToken.t_while: + //iteration statements + case IToken.t_while: return parseWhileStatement(); - case IToken.t_do: + case IToken.t_do: return parseDoStatement(); - case IToken.t_for: + case IToken.t_for: return parseForStatement(); - //jump statement - case IToken.t_break: + //jump statement + case IToken.t_break: return parseBreakStatement(); - case IToken.t_continue: + case IToken.t_continue: return parseContinueStatement(); - case IToken.t_return: + case IToken.t_return: return parseReturnStatement(); - case IToken.t_goto: + case IToken.t_goto: return parseGotoStatement(); - case IToken.tSEMI: + case IToken.tSEMI: return parseNullStatement(); - case IToken.t_try : - return parseTryStatement(); - default: + case IToken.t_try: + return parseTryStatement(); + default: // can be many things: // label if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { - return parseLabelStatement(); + return parseLabelStatement(); } - - return parseDeclarationOrExpressionStatement(); - } - } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseTryStatement() throws EndOfFileException, BacktrackException { - int startO = consume().getOffset(); - IASTStatement tryBlock = compoundStatement(); - List catchHandlers = new ArrayList( DEFAULT_CATCH_HANDLER_LIST_SIZE ); - catchHandlerSequence(catchHandlers); - cleanupLastToken(); - ICPPASTTryBlockStatement tryStatement = createTryBlockStatement(); - ((ASTNode)tryStatement).setOffset( startO ); - tryStatement.setTryBody( tryBlock ); - tryBlock.setParent( tryStatement ); - tryBlock.setPropertyInParent( ICPPASTTryBlockStatement.BODY ); - - for( int i = 0; i < catchHandlers.size(); ++i ) - { - ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers.get(i); - tryStatement.addCatchHandler( handler ); - handler.setParent( tryStatement ); - handler.setPropertyInParent( ICPPASTTryBlockStatement.CATCH_HANDLER ); - } - return tryStatement; - } + return parseDeclarationOrExpressionStatement(); + } + } - /** - * @return - */ - protected ICPPASTTryBlockStatement createTryBlockStatement() { - return new CPPASTTryBlockStatement(); - } + /** + * @return @throws + * EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseTryStatement() throws EndOfFileException, + BacktrackException { + int startO = consume().getOffset(); + IASTStatement tryBlock = compoundStatement(); + List catchHandlers = new ArrayList(DEFAULT_CATCH_HANDLER_LIST_SIZE); + catchHandlerSequence(catchHandlers); + cleanupLastToken(); + ICPPASTTryBlockStatement tryStatement = createTryBlockStatement(); + ((ASTNode) tryStatement).setOffsetAndLength(startO, lastToken + .getEndOffset() + - startO); + tryStatement.setTryBody(tryBlock); + tryBlock.setParent(tryStatement); + tryBlock.setPropertyInParent(ICPPASTTryBlockStatement.BODY); - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit() - */ - protected void nullifyTranslationUnit() { - translationUnit = null; - } + for (int i = 0; i < catchHandlers.size(); ++i) { + ICPPASTCatchHandler handler = (ICPPASTCatchHandler) catchHandlers + .get(i); + tryStatement.addCatchHandler(handler); + handler.setParent(tryStatement); + handler.setPropertyInParent(ICPPASTTryBlockStatement.CATCH_HANDLER); + } + return tryStatement; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement() - */ - protected IASTProblemStatement createProblemStatement() { - return new CPPASTProblemStatement(); - } + /** + * @return + */ + protected ICPPASTTryBlockStatement createTryBlockStatement() { + return new CPPASTTryBlockStatement(); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression() - */ - protected IASTProblemExpression createProblemExpression() { - return new CPPASTProblemExpression(); - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit() + */ + protected void nullifyTranslationUnit() { + translationUnit = null; + } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int, - * int, int) - */ - protected IASTProblem createProblem(int signal, int offset, int length) { - IASTProblem result = new CPPASTProblem(signal, EMPTY_STRING, false, true); - ((ASTNode) result).setOffset(offset); - ((ASTNode) result).setLength(length); - return result; - } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement() + */ + protected IASTProblemStatement createProblemStatement() { + return new CPPASTProblemStatement(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression() + */ + protected IASTProblemExpression createProblemExpression() { + return new CPPASTProblemExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int, + * int, int) + */ + protected IASTProblem createProblem(int signal, int offset, int length) { + IASTProblem result = new CPPASTProblem(signal, EMPTY_STRING, false, true); + ((ASTNode) result).setOffsetAndLength(offset, length); + ((ASTNode) result).setLength(length); + return result; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java index 1304aa476c4..e3ff043ee22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java @@ -95,7 +95,7 @@ abstract class BaseScanner implements IScanner { // The context stack protected static final int bufferInitialSize = 8; - int bufferStackPos = -1; + protected int bufferStackPos = -1; protected char[][] bufferStack = new char[bufferInitialSize][]; protected Object[] bufferData = new Object[bufferInitialSize]; protected int[] bufferPos = new int[bufferInitialSize]; @@ -1269,16 +1269,18 @@ abstract class BaseScanner implements IScanner { } } - protected void popContext() { + protected Object popContext() { bufferStack[bufferStackPos] = null; if( bufferData[bufferStackPos] instanceof InclusionData ) popInclusion(((InclusionData)bufferData[bufferStackPos]).inclusion); + Object result = bufferData[bufferStackPos]; bufferData[bufferStackPos] = null; --bufferStackPos; if( preIncludeFiles.hasNext() ) pushForcedInclusion(); + return result; } /** @@ -2115,7 +2117,7 @@ abstract class BaseScanner implements IScanner { /** * @param scanner_bad_character */ - protected abstract void handleProblem(int id, int startOffset, char [] arg ); + protected abstract void handleProblem(int id, int offset, char [] arg ); /** * @param i diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java index a932d1b579d..91c70ef2181 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DOMScanner.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.internal.core.parser.token.SimpleToken; public class DOMScanner extends BaseScanner { private final ICodeReaderFactory codeReaderFactory; + private int contextStart = 0; private static class DOMInclusion { @@ -128,9 +129,11 @@ public class DOMScanner extends BaseScanner { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#popContext() */ - protected void popContext() { + protected Object popContext() { //TODO calibrate offsets - super.popContext(); + Object result = super.popContext(); + + return result; } /** * @return @@ -200,9 +203,19 @@ public class DOMScanner extends BaseScanner { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int, int, char[]) */ - protected void handleProblem(int id, int startOffset, char[] arg) { + protected void handleProblem(int id, int offset, char[] arg) { IASTProblem problem = new ScannerASTProblem(id, arg, true, false ); + int o = resolveOffset( offset ); + ((ScannerASTProblem)problem).setOffsetAndLength( o, resolveOffset( getCurrentOffset() + 1 ) - o ); locationMap.encounterProblem(problem); } + /** + * @param offset + * @return + */ + private int resolveOffset(int offset) { + return contextStart + offset; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java index 917b86b0810..62b9b5c14e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/IScannerPreprocessorLog.java @@ -17,8 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem; */ public interface IScannerPreprocessorLog { - public void startTranslationUnit(); - public void endTranslationUnit(int finalOffset); public void startInclusion(char[] includePath, int offset); @@ -54,7 +52,7 @@ public interface IScannerPreprocessorLog { public void encounterPoundElse(int startOffset, int endOffset); public void encounterPoundElif(int startOffset, int endOffset); - + public void encounterPoundEndIf(int startOffset, int endOffset); public void encounterProblem( IASTProblem problem ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java index b8f66203701..6f3c89ceefc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java @@ -28,6 +28,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { private List problems = Collections.EMPTY_LIST; private static final IASTProblem[] EMPTY_PROBLEMS_ARRAY = new IASTProblem[0]; + /** + * + */ + public LocationMap() { + startTranslationUnit(); + } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getMacroDefinitions() @@ -72,9 +78,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#startTranslationUnit() */ - public void startTranslationUnit() { - // TODO Auto-generated method stub - + protected void startTranslationUnit() { } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java index bee50cbb9c6..524825483dd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java @@ -242,10 +242,10 @@ public class Scanner2 extends BaseScanner { * @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#handleProblem(int, * int, char[]) */ - protected void handleProblem(int id, int startOffset, char[] arg) { + protected void handleProblem(int id, int offset, char[] arg) { if (parserMode == ParserMode.COMPLETION_PARSE) return; - IProblem p = spf.createProblem(id, startOffset, + IProblem p = spf.createProblem(id, offset, bufferPos[bufferStackPos], getLineNumber(bufferPos[bufferStackPos]), getCurrentFilename(), arg != null ? arg : EMPTY_CHAR_ARRAY, false, true); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java index beea3a85d26..989314e53db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java @@ -106,7 +106,7 @@ public class BasicTokenDuple implements ITokenDuple { if( token.getType() == IToken.tLT ) token = TokenFactory.consumeTemplateIdArguments( token, last ); if( token.getType() == IToken.tCOLONCOLON ){ - ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev ); + ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, ( prev == null ) ? startOfSegment : prev ); r.add( d ); startOfSegment = token.getNext(); continue; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java index 867ae8fd788..387a8d7bc52 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java @@ -155,7 +155,7 @@ public class TemplateTokenDuple extends BasicTokenDuple { newArgs = new ArrayList( 1 ); newArgs.add( argLists[count]); } - ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev, newArgs ); + ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev != null ? prev : startOfSegment, newArgs ); r.add( d ); startOfSegment = token.getNext(); ++count;