/******************************************************************************* * Copyright (c) 2009, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.lrparser.action.gnu; import static org.eclipse.cdt.core.parser.util.CollectionUtils.findFirstAndRemove; import java.util.List; import lpg.lpgjavaruntime.IToken; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTPointer; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.lrparser.action.ITokenMap; import org.eclipse.cdt.core.dom.lrparser.action.ITokenStream; import org.eclipse.cdt.core.dom.lrparser.action.ParserUtil; import org.eclipse.cdt.core.dom.lrparser.action.ScopedStack; import org.eclipse.cdt.core.dom.lrparser.action.TokenMap; import org.eclipse.cdt.core.dom.lrparser.action.cpp.CPPBuildASTParserAction; import org.eclipse.cdt.core.dom.lrparser.action.cpp.ICPPSecondaryParserFactory; import org.eclipse.cdt.internal.core.dom.lrparser.gpp.GPPParsersym; public class GPPBuildASTParserAction extends CPPBuildASTParserAction { private final ICPPNodeFactory nodeFactory; private final ITokenMap gppTokenMap; public GPPBuildASTParserAction(ITokenStream stream, ScopedStack<Object> astStack, ICPPNodeFactory nodeFactory, ICPPSecondaryParserFactory parserFactory) { super(stream, astStack, nodeFactory, parserFactory); this.nodeFactory = nodeFactory; this.gppTokenMap = new TokenMap(GPPParsersym.orderedTerminalSymbols, stream.getOrderedTerminalSymbols()); } /** * typeof_type_specifier * ::= 'typeof' unary_expression * * typeof_declaration_specifiers * ::= typeof_type_specifier * | no_type_declaration_specifiers typeof_type_specifier * | typeof_declaration_specifiers no_type_declaration_specifier * * declaration_specifiers * ::= <openscope-ast> typeof_declaration_specifiers */ public void consumeDeclarationSpecifiersTypeof() { List<Object> topScope = astStack.closeScope(); // There's an expression somewhere on the stack, find it IASTExpression expr = findFirstAndRemove(topScope, IASTExpression.class); //CDT_70_FIX_FROM_50-#7 ICPPASTSimpleDeclSpecifier declSpec = nodeFactory.newSimpleDeclSpecifier(); declSpec.setDeclTypeExpression(expr); // now apply the rest of the specifiers for(Object token : topScope) { setSpecifier(declSpec, token); } setOffsetAndLength(declSpec); astStack.push(declSpec); } /** * Replacement for the same method in CPPBuildASTParserAction */ @Override public void consumeDeclarationSpecifiersSimple() { boolean isComplex = false; boolean isImaginary = false; int numLong = 0; List<Object> tokens = astStack.closeScope(); for(Object o : tokens) { if(o instanceof IToken) { IToken token = (IToken)o; switch(gppTokenMap.mapKind(token.getKind())) { case GPPParsersym.TK__Complex: isComplex = true; break; case GPPParsersym.TK__Imaginary: isImaginary = true; break; case GPPParsersym.TK_long : numLong++; break; } } } //CDT_70_FIX_FROM_50-#7 ICPPASTSimpleDeclSpecifier declSpec = nodeFactory.newSimpleDeclSpecifier(); if(isComplex || isImaginary || numLong > 1) { // IGPPASTSimpleDeclSpecifier gppDeclSpec = nodeFactory.newSimpleDeclSpecifierGPP(); declSpec.setComplex(isComplex); declSpec.setImaginary(isImaginary); declSpec.setLongLong(numLong > 1); declSpec.setLong(numLong == 1); //declSpec = gppDeclSpec; } else { declSpec = nodeFactory.newSimpleDeclSpecifier(); } for(Object token : tokens) { setSpecifier(declSpec, token); } setOffsetAndLength(declSpec); astStack.push(declSpec); } private boolean hasRestrict(List<Object> tokens) { for(Object o : tokens) { IToken t = (IToken)o; if(gppTokenMap.mapKind(t.getKind()) == GPPParsersym.TK_restrict) { return true; } } return false; } /** * Restrict is allowed as a keyword. */ @Override public void consumePointer() { boolean hasRestrict = hasRestrict(astStack.topScope()); super.consumePointer(); if(hasRestrict) { IGPPASTPointer gppPointer = nodeFactory.newPointerGPP(); initializeGPPPointer((IASTPointer)astStack.pop(), gppPointer); astStack.push(gppPointer); } } private static void initializeGPPPointer(IASTPointer pointer, IGPPASTPointer gppPointer) { gppPointer.setConst(pointer.isConst()); gppPointer.setVolatile(pointer.isVolatile()); gppPointer.setRestrict(true); ParserUtil.setOffsetAndLength(gppPointer, pointer); } @Override public void consumePointerToMember() { boolean hasRestrict = hasRestrict(astStack.topScope()); super.consumePointerToMember(); if(hasRestrict) { ICPPASTPointerToMember pointer = (ICPPASTPointerToMember) astStack.pop(); IGPPASTPointerToMember gppPointer = nodeFactory.newPointerToMemberGPP(pointer.getName()); initializeGPPPointer(pointer, gppPointer); astStack.push(gppPointer); } } public void consumeTemplateExplicitInstantiationGCC(int modifier) { IASTDeclaration declaration = (IASTDeclaration) astStack.pop(); IGPPASTExplicitTemplateInstantiation instantiation = nodeFactory.newExplicitTemplateInstantiationGPP(declaration); instantiation.setModifier(modifier); setOffsetAndLength(instantiation); astStack.push(instantiation); } /** * postfix_expression ::= '(' type_id ')' initializer_list */ public void consumeExpressionTypeIdInitializer() { IASTInitializerList list = (IASTInitializerList) astStack.pop(); IASTTypeId typeId = (IASTTypeId) astStack.pop(); IASTTypeIdInitializerExpression expr = nodeFactory.newTypeIdInitializerExpression(typeId, list); setOffsetAndLength(expr); astStack.push(expr); } }