/******************************************************************************* * Copyright (c) 2004, 2011 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 - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent; /** * C++-specific implementation of a translation-unit. */ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPASTTranslationUnit, IASTAmbiguityParent { private CPPNamespaceScope fScope = null; private ICPPNamespace fBinding = null; private final CPPScopeMapper fScopeMapper= new CPPScopeMapper(this); public CPPASTTranslationUnit() { } public CPPASTTranslationUnit copy() { return copy(CopyStyle.withoutLocations); } public CPPASTTranslationUnit copy(CopyStyle style) { CPPASTTranslationUnit copy = new CPPASTTranslationUnit(); copyAbstractTU(copy, style); if (style == CopyStyle.withLocations) { copy.setCopyLocation(this); } return copy; } public CPPNamespaceScope getScope() { if (fScope == null) { fScope = new CPPNamespaceScope(this); addBuiltinOperators(fScope); } return fScope; } private void addBuiltinOperators(CPPScope theScope) { // void IType cpp_void = new CPPBasicType(Kind.eVoid, 0); // void* IType cpp_void_p = new CPPPointerType(new CPPQualifierType(new CPPBasicType(Kind.eVoid, 0), false, false), new CPPASTPointer()); // size_t // assumed: unsigned long int IType cpp_size_t = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG & IBasicType.IS_UNSIGNED); // void* operator new(std::size_t); IBinding temp = null; IType[] newParms = new IType[1]; newParms[0] = cpp_size_t; ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms); ICPPParameter[] newTheParms = new ICPPParameter[1]; newTheParms[0] = new CPPBuiltinParameter(newParms[0]); temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms, false); theScope.addBinding(temp); // void* operator new[](std::size_t); temp = null; temp = new CPPImplicitFunction(OverloadableOperator.NEW_ARRAY.toCharArray(), theScope, newFunctionType, newTheParms, false); theScope.addBinding(temp); // void operator delete(void*); temp = null; IType[] deleteParms = new IType[1]; deleteParms[0] = cpp_void_p; ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms); ICPPParameter[] deleteTheParms = new ICPPParameter[1]; deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]); temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false); theScope.addBinding(temp); // void operator delete[](void*); temp = null; temp = new CPPImplicitFunction(OverloadableOperator.DELETE_ARRAY.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false); theScope.addBinding(temp); } public IASTName[] getDeclarationsInAST(IBinding binding) { if (binding instanceof IMacroBinding) { return getMacroDefinitionsInAST((IMacroBinding) binding); } return CPPVisitor.getDeclarations(this, binding); } public IASTName[] getDefinitionsInAST(IBinding binding) { if (binding instanceof IMacroBinding) { return getMacroDefinitionsInAST((IMacroBinding) binding); } IASTName[] names = CPPVisitor.getDeclarations(this, binding); for (int i = 0; i < names.length; i++) { if (!names[i].isDefinition()) names[i] = null; } // nulls can be anywhere, don't use trim() return (IASTName[]) ArrayUtil.removeNulls(IASTName.class, names); } public IASTName[] getReferences(IBinding binding) { if (binding instanceof IMacroBinding) { return getMacroReferencesInAST((IMacroBinding) binding); } return CPPVisitor.getReferences(this, binding); } public IBinding resolveBinding() { if (fBinding == null) fBinding = new CPPNamespace(this); return fBinding; } @Deprecated public ParserLanguage getParserLanguage() { return ParserLanguage.CPP; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getLinkage() */ public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener#skippedFile(org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent) */ @Override public void skippedFile(int offset, InternalFileContent fileContent) { super.skippedFile(offset, fileContent); fScopeMapper.registerAdditionalDirectives(offset, fileContent.getUsingDirectives()); } // bug 217102: namespace scopes from the index have to be mapped back to the AST. public IScope mapToASTScope(IIndexScope scope) { return fScopeMapper.mapToASTScope(scope); } // bug 262719: class types from the index have to be mapped back to the AST. public ICPPClassType mapToAST(ICPPClassType binding) { return fScopeMapper.mapToAST(binding); } /** * Stores directives from the index into this scope. */ public void handleAdditionalDirectives(ICPPNamespaceScope scope) { fScopeMapper.handleAdditionalDirectives(scope); } @Override public void resolveAmbiguities() { accept(new CPPASTAmbiguityResolver()); } }