blob: 8d426ae83814f4bf7678053f49ad54abe61fdda6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2014 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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 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.ICPPASTExplicitTemplateInstantiation;
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.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;
import lpg.lpgjavaruntime.IToken;
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) {
IASTPointer gppPointer = nodeFactory.newPointer();
initializePointer((IASTPointer) astStack.pop(), gppPointer);
astStack.push(gppPointer);
}
}
private static void initializePointer(IASTPointer pointer, IASTPointer 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();
ICPPASTPointerToMember gppPointer = nodeFactory.newPointerToMember(pointer.getName());
initializePointer(pointer, gppPointer);
astStack.push(gppPointer);
}
}
public void consumeTemplateExplicitInstantiationGCC(int modifier) {
IASTDeclaration declaration = (IASTDeclaration) astStack.pop();
ICPPASTExplicitTemplateInstantiation instantiation = nodeFactory.newExplicitTemplateInstantiation(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);
}
}