/******************************************************************************* * Copyright (c) 2004, 2015 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: * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConstructor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements ICPPASTSimpleTypeConstructorExpression, IASTImplicitNameOwner, ICPPEvaluationOwner { private ICPPASTDeclSpecifier fDeclSpec; private IASTInitializer fInitializer; private ICPPEvaluation fEvaluation; private IASTImplicitDestructorName[] fImplicitDestructorNames; private IASTImplicitName[] fImplicitNames; // for class types: the constructor being called public CPPASTSimpleTypeConstructorExpression() { } public CPPASTSimpleTypeConstructorExpression(ICPPASTDeclSpecifier declSpec, IASTInitializer init) { setDeclSpecifier(declSpec); setInitializer(init); } @Override public CPPASTSimpleTypeConstructorExpression copy() { return copy(CopyStyle.withoutLocations); } @Override public CPPASTSimpleTypeConstructorExpression copy(CopyStyle style) { CPPASTSimpleTypeConstructorExpression copy = new CPPASTSimpleTypeConstructorExpression(); copy.setDeclSpecifier(fDeclSpec == null ? null : fDeclSpec.copy(style)); copy.setInitializer(fInitializer == null ? null : fInitializer.copy(style)); return copy(copy, style); } @Override public ICPPASTDeclSpecifier getDeclSpecifier() { return fDeclSpec; } @Override public IASTInitializer getInitializer() { return fInitializer; } @Override public void setDeclSpecifier(ICPPASTDeclSpecifier declSpec) { assertNotFrozen(); fDeclSpec = declSpec; if (declSpec != null) { declSpec.setParent(this); declSpec.setPropertyInParent(TYPE_SPECIFIER); } } @Override public void setInitializer(IASTInitializer initializer) { assertNotFrozen(); fInitializer = initializer; if (initializer != null) { initializer.setParent(this); initializer.setPropertyInParent(INITIALIZER); } } @Override public ICPPEvaluation getEvaluation() { if (fEvaluation == null) { final IType type = CPPVisitor.createType(fDeclSpec); if (fInitializer instanceof ICPPASTConstructorInitializer || fInitializer instanceof ICPPASTInitializerList) { boolean usesBracedInitList = (fInitializer instanceof ICPPASTInitializerList); fEvaluation= new EvalTypeId(type, this, usesBracedInitList, EvalConstructor.extractArguments(fInitializer)); } else { fEvaluation= EvalFixed.INCOMPLETE; } } return fEvaluation; } @Override public IType getExpressionType() { return getEvaluation().getType(this); } @Override public ValueCategory getValueCategory() { return getEvaluation().getValueCategory(this); } @Override public boolean isLValue() { return false; } @Override public IASTImplicitDestructorName[] getImplicitDestructorNames() { if (fImplicitDestructorNames == null) { fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this); } return fImplicitDestructorNames; } @Override public boolean accept(ASTVisitor action) { if (action.shouldVisitExpressions) { switch (action.visit(this)) { case ASTVisitor.PROCESS_ABORT: return false; case ASTVisitor.PROCESS_SKIP: return true; default: break; } } if (fDeclSpec != null && !fDeclSpec.accept(action)) return false; if (action.shouldVisitImplicitNames) { for (IASTImplicitName implicitName : getImplicitNames()) { if (!implicitName.accept(action)) { return false; } } } if (fInitializer != null && !fInitializer.accept(action)) return false; if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action)) return false; if (action.shouldVisitExpressions) { switch (action.leave(this)) { case ASTVisitor.PROCESS_ABORT: return false; case ASTVisitor.PROCESS_SKIP: return true; default: break; } } return true; } @Deprecated @Override public int getSimpleType() { IType type= getExpressionType(); if (type instanceof ICPPBasicType) { ICPPBasicType bt= (ICPPBasicType) type; Kind kind = bt.getKind(); switch (kind) { case eBoolean: return t_bool; case eChar: return t_char; case eDouble: return t_double; case eFloat: return t_float; case eInt: if (bt.isShort()) return t_short; if (bt.isLong()) return t_long; if (bt.isSigned()) return t_signed; if (bt.isUnsigned()) return t_unsigned; return t_int; case eVoid: return t_void; case eWChar: return t_wchar_t; default: break; } } return t_unspecified; } @Deprecated @Override public void setSimpleType(int value) { CPPASTSimpleDeclSpecifier declspec = new CPPASTSimpleDeclSpecifier(); switch (value) { case t_bool: declspec.setType(Kind.eBoolean); break; case t_char: declspec.setType(Kind.eChar); break; case t_double: declspec.setType(Kind.eDouble); break; case t_float: declspec.setType(Kind.eFloat); break; case t_int: declspec.setType(Kind.eInt); break; case t_long: declspec.setType(Kind.eInt); declspec.setLong(true); break; case t_short: declspec.setType(Kind.eInt); declspec.setShort(true); break; case t_signed: declspec.setType(Kind.eInt); declspec.setSigned(true); break; case t_unsigned: declspec.setType(Kind.eInt); declspec.setUnsigned(true); break; case t_void: declspec.setType(Kind.eVoid); break; case t_wchar_t: declspec.setType(Kind.eWChar); break; default: declspec.setType(Kind.eUnspecified); break; } setDeclSpecifier(declspec); } @Deprecated @Override public IASTExpression getInitialValue() { if (fInitializer instanceof ICPPASTConstructorInitializer) { return ((ICPPASTConstructorInitializer) fInitializer).getExpression(); } return null; } @Deprecated @Override public void setInitialValue(IASTExpression expression) { ICPPASTConstructorInitializer init= new CPPASTConstructorInitializer(); init.setExpression(expression); setInitializer(init); } @Override public IASTImplicitName[] getImplicitNames() { if (fImplicitNames == null) { fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; ICPPEvaluation eval = getEvaluation(); if (eval instanceof EvalTypeId) { ICPPFunction constructor = ((EvalTypeId) eval).getConstructor(this); if (constructor != null && constructor != EvalTypeId.AGGREGATE_INITIALIZATION) { CPPASTImplicitName name = new CPPASTImplicitName(constructor.getNameCharArray(), this); name.setOffsetAndLength((ASTNode) fDeclSpec); name.setBinding(constructor); fImplicitNames = new IASTImplicitName[] { name }; } } } return fImplicitNames; } }