1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix for 205567: Implement an assembly model builder

This commit is contained in:
Anton Leherbauer 2007-10-23 11:20:30 +00:00
parent 587bbaf41a
commit 57d7ac7888
10 changed files with 733 additions and 4 deletions

View file

@ -51,6 +51,7 @@ public class AllCoreTests {
//which includes the CConfigurationDescriptionReferenceTests //which includes the CConfigurationDescriptionReferenceTests
suite.addTest(AllCProjectDescriptionTests.suite()); suite.addTest(AllCProjectDescriptionTests.suite());
suite.addTest(ASTCacheTests.suite()); suite.addTest(ASTCacheTests.suite());
suite.addTest(AsmModelBuilderTest.suite());
return suite; return suite;
} }

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* Copyright (c) 2007 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.model.tests;
import junit.framework.Test;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.IAsmLabel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IParent;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
/**
* Tests for the default assembly model builder.
*
* @since 5.0
*/
public class AsmModelBuilderTest extends BaseTestCase {
public static Test suite() {
return suite(AsmModelBuilderTest.class, "_");
}
private ICProject fCProject;
private ITranslationUnit fTU;
public AsmModelBuilderTest(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
fCProject= CProjectHelper.createCProject(getName(), null, IPDOMManager.ID_FAST_INDEXER);
assertNotNull(fCProject);
CProjectHelper.importSourcesFromPlugin(fCProject, CTestPlugin.getDefault().getBundle(), "/resources/asmTests");
fTU= (ITranslationUnit) CProjectHelper.findElement(fCProject, "AsmTest.S");
assertNotNull(fTU);
}
protected void tearDown() throws Exception {
CProjectHelper.delete(fCProject);
super.tearDown();
}
public void testAsmModelElements() throws Exception {
ICElement[] children= fTU.getChildren();
assertEquals(7, children.length);
assertEquals(ICElement.C_INCLUDE, children[0].getElementType());
assertEquals("include.h", children[0].getElementName());
assertEquals(ICElement.ASM_LABEL, children[1].getElementType());
assertEquals("nonGlobalLabel", children[1].getElementName());
assertFalse(((IAsmLabel)children[1]).isGlobal());
assertEquals(0, ((IParent)children[1]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[2].getElementType());
assertEquals("globalLabel1", children[2].getElementName());
assertTrue(((IAsmLabel)children[2]).isGlobal());
assertEquals(2, ((IParent)children[2]).getChildren().length);
assertEquals(ICElement.C_MACRO, children[3].getElementType());
assertEquals("MACRO", children[3].getElementName());
assertEquals(ICElement.ASM_LABEL, children[4].getElementType());
assertEquals("globalLabel2", children[4].getElementName());
assertTrue(((IAsmLabel)children[4]).isGlobal());
assertEquals(1, ((IParent)children[4]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[5].getElementType());
assertEquals("globalLabel3", children[5].getElementName());
assertTrue(((IAsmLabel)children[5]).isGlobal());
assertEquals(1, ((IParent)children[5]).getChildren().length);
assertEquals(ICElement.ASM_LABEL, children[6].getElementType());
assertEquals("alloca", children[6].getElementName());
assertTrue(((IAsmLabel)children[6]).isGlobal());
assertEquals(0, ((IParent)children[6]).getChildren().length);
}
public void testAsmLabelRanges() throws Exception {
String source= fTU.getBuffer().getContents();
ICElement[] labels= (ICElement[]) fTU.getChildrenOfType(ICElement.ASM_LABEL).toArray(new ICElement[0]);
for (int i = 0; i < labels.length; i++) {
String name= labels[i].getElementName();
ISourceReference label= (ISourceReference)labels[i];
ISourceRange range= label.getSourceRange();
assertEquals(source.substring(range.getIdStartPos(), range.getIdStartPos() + range.getIdLength()), name);
int endOfLabel= source.indexOf("/* end */", range.getIdStartPos());
assertEquals(range.getIdStartPos(), range.getStartPos());
assertEquals(endOfLabel, range.getStartPos() + range.getLength());
}
}
}

View file

@ -0,0 +1,63 @@
/*
* AsmTest.S
*/
#include <include.h>
.globl globalLabel1
.global globalLabel2, globalLabel3
nonGlobalLabel:
nop
ret @ arm style comment
/* end */
globalLabel1:
movl %esp, %eax
movl %eax, storage
otherLabel1:
movb $0x81, %ah # end-of-line comment
jmp globalLabel2
; data
storage:
.long 0
/* end */
#define MACRO mmm
/*
* block comment
*/
globalLabel2:
movl %esp, %eax
movl %eax, storage
; line comment
otherLabel2:
movb $0x81, %ah ; end-of-line comment
jmp globalLabel3 # comment
/* end */
globalLabel3:
movl %esp, %eax
movl %eax, storage
otherLabel3:
movb $0x81, %ah
jmp globalLabel3
/* end */
.global alloca
alloca:
popl %edx
popl %eax
addl $3,%eax
andl $0xfffffffc,%eax
subl %eax,%esp
movl %esp,%eax
pushl %eax
pushl %edx
ret
/* end */

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2007 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.model;
/**
* Represents a label in assembly code.
*
* @since 5.0
*/
public interface IAsmLabel extends ICElement, ISourceManipulation, ISourceReference {
/**
* Test whether this label is declared global.
* A global label is available to the linker.
*
* @return <code>true</code> if the label is global
*/
boolean isGlobal();
}

View file

@ -226,6 +226,13 @@ public interface ICElement extends IAdaptable {
*/ */
static final int C_UNKNOWN_DECLARATION = 93; static final int C_UNKNOWN_DECLARATION = 93;
/**
* Assembly label.
*
* @since 5.0
*/
static final int ASM_LABEL= 94;
/** /**
* Modifier indicating a class constructor * Modifier indicating a class constructor
* @deprecated use {@link IMethodDeclaration#isConstructor()} * @deprecated use {@link IMethodDeclaration#isConstructor()}
@ -243,9 +250,10 @@ public interface ICElement extends IAdaptable {
* @deprecated use {@link IDeclaration#isStatic()} * @deprecated use {@link IDeclaration#isStatic()}
*/ */
static final int C_STORAGE_STATIC = 0x400; static final int C_STORAGE_STATIC = 0x400;
/** /**
* Modifier indicating an extern storage attribute * Modifier indicating an extern storage attribute
* @deprecated not used anymore
*/ */
static final int C_STORAGE_EXTERN = 0x800; static final int C_STORAGE_EXTERN = 0x800;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others. * Copyright (c) 2005, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,9 +7,11 @@
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.model; package org.eclipse.cdt.core.model;
/** /**
* Interface supported by model builders for contributed languages. * Interface supported by model builders for contributed languages.
* *
@ -25,6 +27,22 @@ package org.eclipse.cdt.core.model;
* @author Jeff Overbey * @author Jeff Overbey
*/ */
public interface IContributedModelBuilder { public interface IContributedModelBuilder {
/**
* A factory to create a model builder for a translation unit.
*
* @since 5.0
*/
public interface Factory {
/**
* Create a model builder for the given translation unit.
*
* @param tu the translation unit
* @return the model builder or <code>null</code> if no model builder could be created
*/
IContributedModelBuilder create(ITranslationUnit tu);
}
/** /**
* Callback used when a <code>TranslationUnit</code> needs to be parsed. * Callback used when a <code>TranslationUnit</code> needs to be parsed.
* *

View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2007 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.core.model.IAsmLabel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IParent;
/**
* A label in assembly code.
*
* @since 5.0
*/
public class AsmLabel extends SourceManipulation implements IAsmLabel, IParent {
private final int fIndex;
private final boolean fIsGlobal;
/**
* Create a new assembly label.
*
* @param parent the parent element (must be ITranslationUnit)
* @param name the name of the label
* @param global if <code>true</code>, the label is declared global (visible to the linker)
* @param index numbering of labels with the same name
*/
public AsmLabel(ICElement parent, String name, boolean global, int index) {
super(parent, name, ICElement.ASM_LABEL);
fIsGlobal= global;
fIndex= index;
}
/*
* @see org.eclipse.cdt.core.model.IAsmLabel#isGlobal()
*/
public final boolean isGlobal() {
return fIsGlobal;
}
/*
* @see org.eclipse.cdt.internal.core.model.CElement#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o instanceof AsmLabel) {
return equals(this, (AsmLabel) o);
}
return false;
}
public static boolean equals(AsmLabel lhs, AsmLabel rhs) {
if (CElement.equals(lhs, rhs)) {
return lhs.fIndex == rhs.fIndex && lhs.fIsGlobal == rhs.fIsGlobal;
}
return false;
}
}

View file

@ -0,0 +1,414 @@
/*******************************************************************************
* Copyright (c) 2007 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.HashMap;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
import org.eclipse.cdt.internal.formatter.scanner.Token;
/**
* A simple model builder for assembly translation units.
* Recognizes preprocessor directives (#include and #define)
* and labels.
*
* @see AssemblyLanguage
* @since 5.0
*/
public class AsmModelBuilder implements IContributedModelBuilder {
private static final class Counter {
int fCount;
}
private final static class Tokenizer extends Scanner {
public Tokenizer(char[] source) {
setSource(source);
}
public Token nextToken() {
Token t= super.nextToken();
while (t != null && (t.isWhiteSpace())) {
t= super.nextToken();
}
return t;
}
}
private TranslationUnit fTranslationUnit;
private char fLineSeparatorChar;
private HashMap fGlobals;
private HashMap fLabels;
private int fLastLabelEndOffset;
private AsmLabel fLastGlobalLabel;
private SourceManipulation fLastLabel;
/**
* Creates a model builder for the given assembly translation unit.
*
* @param tu the translation unit
*/
public AsmModelBuilder(ITranslationUnit tu) {
fTranslationUnit= (TranslationUnit)tu;
}
/**
* Configure the line separator character (in addition to normal newlines).
*
* @param lineSeparatorChar
*/
public void setLineSeparatorChar(char lineSeparatorChar) {
fLineSeparatorChar= lineSeparatorChar;
}
/*
* @see org.eclipse.cdt.core.model.IContributedModelBuilder#parse(boolean)
*/
public void parse(boolean quickParseMode) throws Exception {
CodeReader reader;
reader = fTranslationUnit.getCodeReader();
if (reader == null) {
return;
}
buildModel(reader.buffer);
// not sure whether this is necessary or not
fTranslationUnit.setIsStructureKnown(true);
fGlobals= null;
fLabels= null;
}
/**
* Build the model.
*
* @param source
* @throws CModelException
*/
private void buildModel(final char[] source) throws CModelException {
fGlobals= new HashMap();
fLabels= new HashMap();
fLastLabel= null;
fLastGlobalLabel= null;
fLastLabelEndOffset= 0;
// TLETODO use new Lexer?
Scanner scanner= new Scanner();
scanner.setSplitPreprocessor(true);
scanner.setSource(source);
// if true the next token is the first on a (logical) line
boolean firstTokenOnLine= true;
// next token can be an instruction or a label
boolean expectInstruction=true;
// inside instruction
boolean inInstruction= false;
Token token= scanner.nextToken();
while (token != null) {
int type= adaptTokenType(token);
switch (type) {
case Token.tPREPROCESSOR_INCLUDE:
parseInclude(fTranslationUnit, token);
break;
case Token.tPREPROCESSOR_DEFINE:
parseDefine(fTranslationUnit, token);
break;
case Token.tFLOATINGPT:
if (token.getText().startsWith(".")) { //$NON-NLS-1$
// move scanner behind '.'
scanner.setCurrentPosition(scanner.getCurrentTokenStartPosition() + 1);
// fallthrough
} else {
break;
}
case Token.tDOT:
// assembly directive?
firstTokenOnLine= false;
if (expectInstruction) {
expectInstruction= false;
int pos= scanner.getCurrentPosition();
token= scanner.nextToken();
if (token != null && adaptTokenType(token) == Token.tIDENTIFIER) {
String text= token.getText();
if (isGlobalDirective(text)) {
firstTokenOnLine= parseGlobalDirective(token, scanner);
} else if (isDataDirective(text)) {
inInstruction= true;
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
}
} else {
scanner.setCurrentPosition(pos);
}
}
break;
case Token.tIDENTIFIER:
// identifier may be a label or part of an instruction
if (firstTokenOnLine) {
int pos= scanner.getCurrentPosition();
int ch= scanner.getNextChar();
if (ch == ':') {
parseLabel(fTranslationUnit, token);
fLastLabelEndOffset= scanner.getCurrentPosition();
expectInstruction= true;
} else {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
scanner.setCurrentPosition(pos);
expectInstruction= false;
inInstruction= true;
}
firstTokenOnLine= false;
} else if (expectInstruction){
expectInstruction= false;
inInstruction= true;
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
} else if (inInstruction) {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
}
break;
case Token.tPREPROCESSOR:
case Token.tWHITESPACE:
if (!firstTokenOnLine) {
int nlIndex= token.getText().indexOf('\n');
firstTokenOnLine= nlIndex >= 0;
if (firstTokenOnLine && inInstruction) {
fLastLabelEndOffset= scanner.getCurrentTokenStartPosition() + nlIndex + 1;
}
}
break;
default:
expectInstruction= false;
firstTokenOnLine= false;
if (fLineSeparatorChar != 0) {
if (token.getLength() == 1 && token.getText().charAt(0) == fLineSeparatorChar) {
firstTokenOnLine= true;
}
}
}
if (firstTokenOnLine) {
expectInstruction= true;
inInstruction= false;
}
token= scanner.nextToken();
}
if (!firstTokenOnLine && inInstruction) {
fLastLabelEndOffset= scanner.getCurrentTokenEndPosition();
}
if (fLastLabel != null) {
fixupLastLabel();
}
if (fLastGlobalLabel != null) {
fixupLastGlobalLabel();
}
}
/**
* Adapt non-identifier tokens to identifier type if they look like valid asm words.
*
* @param token
* @return the adapted token type
*/
private int adaptTokenType(Token token) {
int type= token.getType();
if (type != Token.tIDENTIFIER) {
if (Character.isUnicodeIdentifierStart(token.getText().charAt(0))) {
type= Token.tIDENTIFIER;
}
}
return type;
}
private boolean isDataDirective(String directive) {
return "byte".equals(directive) || "long".equals(directive) || "word".equals(directive) || "ascii".equals(directive); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
}
private boolean parseGlobalDirective(Token token, Scanner scanner) {
boolean eol= false;
do {
Token t= scanner.nextToken();
if (t == null) {
break;
}
switch (adaptTokenType(t)) {
case Token.tIDENTIFIER:
registerGlobalLabel(t.getText());
break;
case Token.tWHITESPACE:
if (token.getText().indexOf('\n') >= 0) {
eol= true;
}
break;
default:
if (fLineSeparatorChar != 0) {
if (token.getLength() == 1 && token.getText().charAt(0) == fLineSeparatorChar) {
eol= true;
}
}
}
} while (!eol);
return eol;
}
private boolean isGlobalDirective(String name) {
return "globl".equals(name) || "global".equals(name); //$NON-NLS-1$ //$NON-NLS-2$
}
private void registerGlobalLabel(String labelName) {
Counter counter= (Counter) fGlobals.get(labelName);
if (counter == null) {
fGlobals.put(labelName, counter= new Counter());
}
counter.fCount++;
}
private int getGlobalLabelIndex(String labelName) {
Counter counter= (Counter) fGlobals.get(labelName);
if (counter == null) {
return 0;
}
return counter.fCount;
}
private int registerLabel(String labelName) {
Counter counter= (Counter) fLabels.get(labelName);
if (counter == null) {
fLabels.put(labelName, counter= new Counter());
}
return counter.fCount++;
}
private void parseLabel(CElement parent, Token token) throws CModelException {
String labelName= token.getText();
int index= getGlobalLabelIndex(labelName);
boolean global= index > 0;
if (!global) {
index= registerLabel(labelName);
}
AsmLabel label= new AsmLabel(parent, labelName, global, index);
SourceManipulationInfo labelInfo= label.getSourceManipulationInfo();
labelInfo.setIdPos(token.getOffset(), token.getLength());
labelInfo.setPos(token.getOffset(), token.getLength());
if (fLastLabel != null) {
fixupLastLabel();
}
if (global) {
// new global label
if (fLastGlobalLabel != null) {
fixupLastGlobalLabel();
}
fLastGlobalLabel= label;
} else {
// add under global label if available
if (fLastGlobalLabel != null) {
parent= fLastGlobalLabel;
}
}
fLastLabel= label;
parent.addChild(label);
}
/**
* Set the body position of the last global label.
*
* @throws CModelException
*/
private void fixupLastGlobalLabel() throws CModelException {
if (fLastLabel != null && fLastLabel != fLastGlobalLabel) {
SourceManipulationInfo globalLabelInfo= fLastGlobalLabel.getSourceManipulationInfo();
SourceManipulationInfo labelInfo= fLastLabel.getSourceManipulationInfo();
globalLabelInfo.setPos(globalLabelInfo.getStartPos(), labelInfo.getStartPos() + labelInfo.getLength() - globalLabelInfo.getStartPos());
// TLETODO set line info
}
}
/**
* Set the body position of the last label.
*
* @throws CModelException
*/
private void fixupLastLabel() throws CModelException {
if (fLastLabelEndOffset > 0) {
SourceManipulationInfo labelInfo= fLastLabel.getSourceManipulationInfo();
labelInfo.setPos(labelInfo.getStartPos(), fLastLabelEndOffset - labelInfo.getStartPos());
// TLETODO set line info
fLastLabelEndOffset= 0;
}
}
private void parseDefine(CElement parent, Token token) throws CModelException {
final String tokenText= token.getText();
Scanner defineScanner= new Tokenizer(tokenText.toCharArray());
defineScanner.setCurrentPosition(tokenText.indexOf('#') + 1);
int nameStart= 0;
int nameEnd= 0;
String name= null;
Token t= defineScanner.nextToken();
if (adaptTokenType(t) == Token.tIDENTIFIER && t.getText().equals("define")) { //$NON-NLS-1$
t= defineScanner.nextToken();
if (adaptTokenType(t) == Token.tIDENTIFIER) {
nameStart= defineScanner.getCurrentTokenStartPosition();
nameEnd= defineScanner.getCurrentTokenEndPosition() + 1;
name= t.getText();
}
}
if (name == null) {
return;
}
Macro macro= new Macro(parent, name);
SourceManipulationInfo macroInfo= macro.getSourceManipulationInfo();
macroInfo.setIdPos(token.getOffset() + nameStart, nameEnd - nameStart);
macroInfo.setPos(token.getOffset(), token.getLength());
parent.addChild(macro);
}
private void parseInclude(CElement parent, Token token) throws CModelException {
final String tokenText= token.getText();
Scanner includeScanner= new Tokenizer(tokenText.toCharArray());
includeScanner.setCurrentPosition(tokenText.indexOf('#') + 1);
int nameStart= 0;
int nameEnd= includeScanner.eofPosition + 1;
String name= null;
boolean isStandard= false;
Token t= includeScanner.nextToken();
if (adaptTokenType(t) == Token.tIDENTIFIER) {
t= includeScanner.nextToken();
if (t.type == Token.tLT) {
nameStart= includeScanner.getCurrentTokenStartPosition();
do {
t= includeScanner.nextToken();
} while (t != null && t.type != Token.tGT);
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1;
name= tokenText.substring(nameStart + 1, nameEnd - 1);
} else if (t.type == Token.tSTRING) {
nameStart= includeScanner.getCurrentTokenStartPosition();
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1;
name= t.getText().substring(1, t.getLength() - 1);
isStandard= true;
} else if (adaptTokenType(t) == Token.tIDENTIFIER) {
nameStart= includeScanner.getCurrentTokenStartPosition();
nameEnd= includeScanner.getCurrentTokenEndPosition() + 1;
name= t.getText();
}
}
if (name == null) {
return;
}
Include include= new Include(parent, name, isStandard);
SourceManipulationInfo includeInfo= include.getSourceManipulationInfo();
includeInfo.setIdPos(token.getOffset() + nameStart, nameEnd - nameStart);
includeInfo.setPos(token.getOffset(), token.getLength());
parent.addChild(include);
}
}

View file

@ -36,7 +36,16 @@ public class AssemblyLanguage extends AbstractLanguage {
* @see org.eclipse.cdt.core.model.ILanguage#createModelBuilder(org.eclipse.cdt.core.model.ITranslationUnit) * @see org.eclipse.cdt.core.model.ILanguage#createModelBuilder(org.eclipse.cdt.core.model.ITranslationUnit)
*/ */
public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) { public IContributedModelBuilder createModelBuilder(ITranslationUnit tu) {
return null; IContributedModelBuilder modelBuilder= null;
IContributedModelBuilder.Factory modelBuilderFactory= (IContributedModelBuilder.Factory)getAdapter(IContributedModelBuilder.Factory.class);
if (modelBuilderFactory != null) {
modelBuilder= modelBuilderFactory.create(tu);
}
if (modelBuilder == null) {
// use default
modelBuilder= new AsmModelBuilder(tu);
}
return modelBuilder;
} }
/* /*

View file

@ -48,6 +48,7 @@ import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.ide.IDE; import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
@ -57,6 +58,7 @@ import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IIncludeReference; import org.eclipse.cdt.core.model.IIncludeReference;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.model.IWorkingCopy;
@ -133,8 +135,21 @@ public class EditorUtility {
* Selects a C Element in an editor * Selects a C Element in an editor
*/ */
public static void revealInEditor(IEditorPart part, ICElement element) { public static void revealInEditor(IEditorPart part, ICElement element) {
if (element != null && part instanceof CEditor) { if (element == null) {
return;
}
if (part instanceof CEditor) {
((CEditor) part).setSelection(element); ((CEditor) part).setSelection(element);
} else if (part instanceof ITextEditor) {
if (element instanceof ISourceReference && !(element instanceof ITranslationUnit)) {
ISourceReference reference= (ISourceReference) element;
try {
ISourceRange range= reference.getSourceRange();
((ITextEditor)part).selectAndReveal(range.getIdStartPos(), range.getIdLength());
} catch (CModelException exc) {
CUIPlugin.getDefault().log(exc.getStatus());
}
}
} }
} }