diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java index 6c3c4f8be8f..13725edbf44 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java @@ -51,6 +51,7 @@ public class AllCoreTests { //which includes the CConfigurationDescriptionReferenceTests suite.addTest(AllCProjectDescriptionTests.suite()); suite.addTest(ASTCacheTests.suite()); + suite.addTest(AsmModelBuilderTest.suite()); return suite; } diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AsmModelBuilderTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AsmModelBuilderTest.java new file mode 100644 index 00000000000..6784c62d3de --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AsmModelBuilderTest.java @@ -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()); + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/resources/asmTests/AsmTest.S b/core/org.eclipse.cdt.core.tests/resources/asmTests/AsmTest.S new file mode 100644 index 00000000000..721d2df5da4 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/asmTests/AsmTest.S @@ -0,0 +1,63 @@ +/* + * AsmTest.S + */ + +#include + + .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 */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IAsmLabel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IAsmLabel.java new file mode 100644 index 00000000000..bf76252eb84 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IAsmLabel.java @@ -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 true if the label is global + */ + boolean isGlobal(); + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java index d35b7487b98..f6da4ec9426 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICElement.java @@ -226,6 +226,13 @@ public interface ICElement extends IAdaptable { */ static final int C_UNKNOWN_DECLARATION = 93; + /** + * Assembly label. + * + * @since 5.0 + */ + static final int ASM_LABEL= 94; + /** * Modifier indicating a class constructor * @deprecated use {@link IMethodDeclaration#isConstructor()} @@ -243,9 +250,10 @@ public interface ICElement extends IAdaptable { * @deprecated use {@link IDeclaration#isStatic()} */ static final int C_STORAGE_STATIC = 0x400; - + /** * Modifier indicating an extern storage attribute + * @deprecated not used anymore */ static final int C_STORAGE_EXTERN = 0x800; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java index 1ee55b5fb00..a14d906ba14 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IContributedModelBuilder.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,9 +7,11 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.model; + /** * Interface supported by model builders for contributed languages. * @@ -25,6 +27,22 @@ package org.eclipse.cdt.core.model; * @author Jeff Overbey */ 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 null if no model builder could be created + */ + IContributedModelBuilder create(ITranslationUnit tu); + } + /** * Callback used when a TranslationUnit needs to be parsed. * diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmLabel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmLabel.java new file mode 100644 index 00000000000..063d67ac5df --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmLabel.java @@ -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 true, 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; + } +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmModelBuilder.java new file mode 100644 index 00000000000..f7b05c517fa --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AsmModelBuilder.java @@ -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); + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AssemblyLanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AssemblyLanguage.java index f0bb68d3d15..8b73ecf865a 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AssemblyLanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/AssemblyLanguage.java @@ -36,7 +36,16 @@ public class AssemblyLanguage extends AbstractLanguage { * @see org.eclipse.cdt.core.model.ILanguage#createModelBuilder(org.eclipse.cdt.core.model.ITranslationUnit) */ 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; } /* diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index 134badda1e6..cda8d9a31f0 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -48,6 +48,7 @@ import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.cdt.core.CCorePlugin; 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.ICProject; 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.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; @@ -133,8 +135,21 @@ public class EditorUtility { * Selects a C Element in an editor */ 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); + } 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()); + } + } } }