/*******************************************************************************
* Copyright (c) 2007, 2015 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.IAdaptable;
/**
* Models IASTNames as needed for the preprocessor statements and macro expansions.
* @since 5.0
*/
public class ASTPreprocessorName extends ASTPreprocessorNode implements IASTName {
private final char[] fName;
private final IBinding fBinding;
public ASTPreprocessorName(IASTNode parent, ASTNodeProperty property, int startNumber,
int endNumber, char[] name, IBinding binding) {
super(parent, property, startNumber, endNumber);
fName= name;
fBinding= binding;
}
@Override
public IBinding resolveBinding() {
return fBinding;
}
@Override
public IBinding resolvePreBinding() {
return fBinding;
}
@Override
public IBinding getBinding() {
return fBinding;
}
@Override
public IBinding getPreBinding() {
return fBinding;
}
@Override
public ILinkage getLinkage() {
final IASTTranslationUnit tu= getTranslationUnit();
return tu == null ? Linkage.NO_LINKAGE : tu.getLinkage();
}
@Override
public IASTCompletionContext getCompletionContext() {
return null;
}
@Override
public boolean isDeclaration() {
return false;
}
@Override
public boolean isDefinition() {
return false;
}
@Override
public boolean isReference() {
return false;
}
@Override
public char[] toCharArray() {
return fName;
}
@Override
public char[] getSimpleID() {
return fName;
}
@Override
public char[] getLookupKey() {
return fName;
}
@Override
public String toString() {
return new String(fName);
}
@Override
public void setBinding(IBinding binding) {assert false;}
@Override
public int getRoleOfName(boolean allowResolution) {
return IASTNameOwner.r_unclear;
}
@Override
public IASTName getLastName() {
return this;
}
@Override
public boolean isQualified() {
return false;
}
@Override
public IASTName copy() {
throw new UnsupportedOperationException();
}
@Override
public IASTName copy(CopyStyle style) {
throw new UnsupportedOperationException();
}
}
class ASTPreprocessorDefinition extends ASTPreprocessorName {
public ASTPreprocessorDefinition(IASTNode parent, ASTNodeProperty property, int startNumber,
int endNumber, char[] name, IBinding binding) {
super(parent, property, startNumber, endNumber, name, binding);
}
@Override
public boolean isDefinition() {
return true;
}
@Override
public int getRoleOfName(boolean allowResolution) {
return IASTNameOwner.r_definition;
}
}
class ASTBuiltinName extends ASTPreprocessorDefinition implements IAdaptable {
private final IName fOriginalDefinition;
public ASTBuiltinName(IASTNode parent, ASTNodeProperty property, IName originalDefinition,
char[] name, IBinding binding) {
super(parent, property, -1, -1, name, binding);
fOriginalDefinition= originalDefinition;
}
@Override
public boolean contains(IASTNode node) {
return node == this;
}
@Override
public String getContainingFilename() {
IASTFileLocation fileLocation = getFileLocation();
return fileLocation == null ? "" : fileLocation.getFileName(); //$NON-NLS-1$
}
@Override
public IASTFileLocation getFileLocation() {
return fOriginalDefinition == null ? null : fOriginalDefinition.getFileLocation();
}
@Override
public IASTNodeLocation[] getNodeLocations() {
IASTFileLocation fileLocation = getFileLocation();
if (fileLocation == null) {
return IASTNodeLocation.EMPTY_ARRAY;
}
return new IASTNodeLocation[] { fileLocation };
}
@Override
public String getRawSignature() {
IASTFileLocation fileLocation = getFileLocation();
return fileLocation == null ? "" : toString(); //$NON-NLS-1$
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(ASTBuiltinName.class)) {
return this;
}
if (fOriginalDefinition != null && adapter.isAssignableFrom(fOriginalDefinition.getClass())) {
return fOriginalDefinition;
}
return null;
}
}
class ASTMacroReferenceName extends ASTPreprocessorName {
private ImageLocationInfo fImageLocationInfo;
public ASTMacroReferenceName(IASTNode parent, ASTNodeProperty property,
int offset, int endOffset, IMacroBinding macro, ImageLocationInfo imgLocationInfo) {
super(parent, property, offset, endOffset, macro.getNameCharArray(), macro);
fImageLocationInfo= imgLocationInfo;
}
@Override
public int getRoleOfName(boolean allowResolution) {
return IASTNameOwner.r_unclear;
}
@Override
public boolean isReference() {
return true;
}
@Override
public IASTImageLocation getImageLocation() {
if (fImageLocationInfo != null) {
IASTTranslationUnit tu= getTranslationUnit();
if (tu != null) {
LocationMap lr= tu.getAdapter(LocationMap.class);
if (lr != null) {
return fImageLocationInfo.createLocation(lr, fImageLocationInfo);
}
}
return null;
}
// ASTNode.getImageLocation() computes an image location based on the node location.
// Macro reference names which are nested references rather than the name of the
// macro being expanded itself, have their node location set to the entire macro
// expansion (see LocationMap.pushMacroExpansion()), which doesn't produce a
// useful image location.
if (getParent() instanceof ASTMacroExpansion) {
if (((ASTMacroExpansion) getParent()).getContext().getMacroReference() == this) {
return super.getImageLocation();
}
}
return null;
}
}