mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 09:15:38 +02:00
Merge branch 'master' into sd90
This commit is contained in:
commit
862d87074c
36 changed files with 577 additions and 456 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2010 IBM Corporation and others.
|
* Copyright (c) 2004, 2011 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
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
* Martin Oberhuber (Wind River Systems) - bug 155096
|
* Martin Oberhuber (Wind River Systems) - bug 155096
|
||||||
* Gerhard Schaber (Wind River Systems)
|
* Gerhard Schaber (Wind River Systems)
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Martin Oberhuber (Wind River) - bug 345750: discover drive-relative paths
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
|
package org.eclipse.cdt.make.internal.core.scannerconfig.gnu;
|
||||||
|
|
||||||
|
@ -225,16 +226,14 @@ public class GCCPerFileBOPConsoleParserUtility extends AbstractGCCBOPConsolePars
|
||||||
public IPath getAbsolutePath(String filePath) {
|
public IPath getAbsolutePath(String filePath) {
|
||||||
IPath pFilePath;
|
IPath pFilePath;
|
||||||
if (filePath.startsWith("/")) { //$NON-NLS-1$
|
if (filePath.startsWith("/")) { //$NON-NLS-1$
|
||||||
return convertCygpath(new Path(filePath));
|
pFilePath = convertCygpath(new Path(filePath));
|
||||||
}
|
} else if (filePath.startsWith("\\") || //$NON-NLS-1$
|
||||||
else if (filePath.startsWith("\\") || //$NON-NLS-1$
|
|
||||||
(!filePath.startsWith(".") && //$NON-NLS-1$
|
(!filePath.startsWith(".") && //$NON-NLS-1$
|
||||||
filePath.length() > 2 && filePath.charAt(1) == ':' &&
|
filePath.length() > 2 && filePath.charAt(1) == ':' &&
|
||||||
(filePath.charAt(2) == '\\' || filePath.charAt(2) == '/'))) {
|
(filePath.charAt(2) == '\\' || filePath.charAt(2) == '/'))) {
|
||||||
// absolute path
|
// absolute path
|
||||||
pFilePath = new Path(filePath);
|
pFilePath = new Path(filePath);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// relative path
|
// relative path
|
||||||
IPath cwd = getWorkingDirectory();
|
IPath cwd = getWorkingDirectory();
|
||||||
if (!cwd.isAbsolute()) {
|
if (!cwd.isAbsolute()) {
|
||||||
|
@ -250,6 +249,10 @@ public class GCCPerFileBOPConsoleParserUtility extends AbstractGCCBOPConsolePars
|
||||||
}
|
}
|
||||||
pFilePath = cwd.append(filePath);
|
pFilePath = cwd.append(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pFilePath.getDevice()==null) {
|
||||||
|
pFilePath = pFilePath.setDevice(getWorkingDirectory().getDevice());
|
||||||
|
}
|
||||||
return pFilePath;
|
return pFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,10 @@ public class CCommandDSC {
|
||||||
IPath ppath = new Path(path);
|
IPath ppath = new Path(path);
|
||||||
if (project != null && !ppath.isAbsolute()) {
|
if (project != null && !ppath.isAbsolute()) {
|
||||||
IResource res = project.findMember(ppath);
|
IResource res = project.findMember(ppath);
|
||||||
|
if (res == null) {
|
||||||
|
// To calculate path only; this does not create any file
|
||||||
|
res = project.getFile(path);
|
||||||
|
}
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
ppath = res.getLocation();
|
ppath = res.getLocation();
|
||||||
if (ppath != null) {
|
if (ppath != null) {
|
||||||
|
|
|
@ -135,6 +135,8 @@ public class CfgScannerConfigInfoFactory2 {
|
||||||
boolean isPerRcType = cfg.isPerRcTypeDiscovery();
|
boolean isPerRcType = cfg.isPerRcTypeDiscovery();
|
||||||
Map<InfoContext, IScannerConfigBuilderInfo2> baseMap = container.getInfoMap();
|
Map<InfoContext, IScannerConfigBuilderInfo2> baseMap = container.getInfoMap();
|
||||||
if(!isPerRcType){
|
if(!isPerRcType){
|
||||||
|
// Discovery profile scope = configuration wide
|
||||||
|
|
||||||
CfgInfoContext c = new CfgInfoContext(cfg);
|
CfgInfoContext c = new CfgInfoContext(cfg);
|
||||||
InfoContext baseContext = c.toInfoContext();
|
InfoContext baseContext = c.toInfoContext();
|
||||||
IScannerConfigBuilderInfo2 info = container.getInfo(baseContext);
|
IScannerConfigBuilderInfo2 info = container.getInfo(baseContext);
|
||||||
|
@ -164,6 +166,8 @@ public class CfgScannerConfigInfoFactory2 {
|
||||||
}
|
}
|
||||||
map.put(new CfgInfoContext(cfg), info);
|
map.put(new CfgInfoContext(cfg), info);
|
||||||
} else {
|
} else {
|
||||||
|
// Discovery profile scope = per language
|
||||||
|
|
||||||
Map<CfgInfoContext, IScannerConfigBuilderInfo2> configMap = getConfigInfoMap(baseMap);
|
Map<CfgInfoContext, IScannerConfigBuilderInfo2> configMap = getConfigInfoMap(baseMap);
|
||||||
|
|
||||||
IResourceInfo[] rcInfos = cfg.getResourceInfos();
|
IResourceInfo[] rcInfos = cfg.getResourceInfos();
|
||||||
|
@ -188,7 +192,26 @@ public class CfgScannerConfigInfoFactory2 {
|
||||||
if(superContext != null && superContext.getResourceInfo() != null){
|
if(superContext != null && superContext.getResourceInfo() != null){
|
||||||
info = configMap.get(superContext);
|
info = configMap.get(superContext);
|
||||||
}
|
}
|
||||||
String id = CfgScannerConfigUtil.getDefaultProfileId(context, true);
|
|
||||||
|
// Files with custom properties don't have a persisted entry in the config
|
||||||
|
// info map; we create an ephemeral entry instead. We need to assign that file
|
||||||
|
// the scanner profile that's used for non-custom files of the same
|
||||||
|
// inputType/tool (and configuration, of course). Unfortunately, identifying
|
||||||
|
// a match is inefficient, but in practice, projects don't have tons of
|
||||||
|
// customized files. See Bug 354194
|
||||||
|
String id = null;
|
||||||
|
for (Entry<CfgInfoContext, IScannerConfigBuilderInfo2> entry : configMap.entrySet()) {
|
||||||
|
CfgInfoContext cfgInfoCxt = entry.getKey();
|
||||||
|
if (match(cfgInfoCxt.getInputType(), context.getInputType()) &&
|
||||||
|
match(cfgInfoCxt.getTool(), context.getTool().getSuperClass()) &&
|
||||||
|
cfgInfoCxt.getConfiguration().equals(context.getConfiguration())) {
|
||||||
|
id = entry.getValue().getSelectedProfileId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id == null) {
|
||||||
|
id = CfgScannerConfigUtil.getDefaultProfileId(context, true);
|
||||||
|
}
|
||||||
|
|
||||||
InfoContext baseContext = context.toInfoContext();
|
InfoContext baseContext = context.toInfoContext();
|
||||||
if(info == null){
|
if(info == null){
|
||||||
if(id != null){
|
if(id != null){
|
||||||
|
@ -203,6 +226,13 @@ public class CfgScannerConfigInfoFactory2 {
|
||||||
info = container.createInfo(baseContext, info);
|
info = container.createInfo(baseContext, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Make sure to remove the ephemeral info map entry from the
|
||||||
|
// container, otherwise it will not be ephemeral but rather a
|
||||||
|
// permanent and stagnant part of the project description. It was
|
||||||
|
// added to the container only so we could obtain an
|
||||||
|
// IScannerConfigBuilderInfo2. Now that we have the info object,
|
||||||
|
// revert the container. See Bug 354194
|
||||||
|
container.removeInfo(context.toInfoContext());
|
||||||
}
|
}
|
||||||
if(info != null){
|
if(info != null){
|
||||||
map.put(context, info);
|
map.put(context, info);
|
||||||
|
@ -347,4 +377,25 @@ public class CfgScannerConfigInfoFactory2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean match(ITool t1, ITool t2){
|
||||||
|
if (t1 == null || t2 == null)
|
||||||
|
return false;
|
||||||
|
if (t1.getId().equals(t2.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match(t1.getSuperClass(), t2.getSuperClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean match(IInputType i1, IInputType i2){
|
||||||
|
if (i1 == null || i2 == null)
|
||||||
|
return false;
|
||||||
|
if (i1.getId().equals(i2.getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match(i1.getSuperClass(), i2.getSuperClass());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,13 +419,40 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
|
|
||||||
IASTImplicitName[] names = bh.getImplicitNames("delete a;", 6);
|
IASTImplicitName[] names = bh.getImplicitNames("delete a;", 6);
|
||||||
assertEquals(2, names.length);
|
assertEquals(2, names.length);
|
||||||
|
assertTrue(((ICPPMethod) names[0].resolveBinding()).isDestructor());
|
||||||
assertSame(m, names[1].resolveBinding());
|
assertSame(m, names[1].resolveBinding());
|
||||||
|
|
||||||
names = bh.getImplicitNames("delete b;", 6);
|
names = bh.getImplicitNames("delete b;", 6);
|
||||||
|
assertTrue(((ICPPMethod) names[0].resolveBinding()).isDestructor());
|
||||||
assertEquals(2, names.length);
|
assertEquals(2, names.length);
|
||||||
assertSame(f, names[1].resolveBinding());
|
assertSame(f, names[1].resolveBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// typedef int size_t;
|
||||||
|
// struct A {
|
||||||
|
// void* operator new(size_t a);
|
||||||
|
// };
|
||||||
|
// struct B {};
|
||||||
|
// void* operator new(size_t b);
|
||||||
|
//
|
||||||
|
// void test() {
|
||||||
|
// A *a = new A;
|
||||||
|
// B* b = new B;
|
||||||
|
// }
|
||||||
|
public void testOverloadedNew_Bug354585() throws Exception {
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IBinding m= bh.assertNonProblem("operator new(size_t a)", 12);
|
||||||
|
IBinding f= bh.assertNonProblem("operator new(size_t b)", 12);
|
||||||
|
|
||||||
|
IASTImplicitName[] names = bh.getImplicitNames("new A;", 3);
|
||||||
|
assertEquals(1, names.length);
|
||||||
|
assertSame(m, names[0].resolveBinding());
|
||||||
|
|
||||||
|
names = bh.getImplicitNames("new B;", 3);
|
||||||
|
assertEquals(1, names.length);
|
||||||
|
assertSame(f, names[0].resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
// struct X {}
|
// struct X {}
|
||||||
// int test(X* x) {
|
// int test(X* x) {
|
||||||
// X* xs = new X[5];
|
// X* xs = new X[5];
|
||||||
|
|
|
@ -9463,4 +9463,21 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
public void testTypedefAsClassNameWithFunctionPtrArgument_350345() throws Exception {
|
public void testTypedefAsClassNameWithFunctionPtrArgument_350345() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int func1(int input) {
|
||||||
|
// return input;
|
||||||
|
// }
|
||||||
|
// void dut() {
|
||||||
|
// int const_zero;
|
||||||
|
// int lll = (func1(func1(const_zero))) + func1(const_zero);
|
||||||
|
// int kkk = (func1(func1(const_zero))) + func1(const_zero);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void f3(int (x), int y=x);
|
||||||
|
// void f2(int (x), int y=x) {
|
||||||
|
// x= 1;
|
||||||
|
// }
|
||||||
|
public void testAmbiguityResolution_Bug354599() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,4 +327,18 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
||||||
validateProblemCount(0);
|
validateProblemCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define foo(x) (## x)
|
||||||
|
// void test foo(void); // Valid for Microsoft's compiler, expands to (void)
|
||||||
|
public void testInvalidTokenPasting_Bug354553() throws Exception {
|
||||||
|
initializeScanner();
|
||||||
|
validateToken(IToken.t_void);
|
||||||
|
validateIdentifier("test");
|
||||||
|
validateToken(IToken.tLPAREN);
|
||||||
|
validateToken(IToken.t_void);
|
||||||
|
validateToken(IToken.tRPAREN);
|
||||||
|
validateToken(IToken.tSEMI);
|
||||||
|
validateEOF();
|
||||||
|
validateProblem(0, IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, "foo");
|
||||||
|
validateProblemCount(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,6 +227,8 @@ public class PreprocessorTests extends PreprocessorTestsBase {
|
||||||
validateString("a");
|
validateString("a");
|
||||||
validateToken(IToken.tSEMI);
|
validateToken(IToken.tSEMI);
|
||||||
|
|
||||||
|
validateString("a");
|
||||||
|
validateIdentifier("b");
|
||||||
validateToken(IToken.tSEMI);
|
validateToken(IToken.tSEMI);
|
||||||
validateEOF();
|
validateEOF();
|
||||||
validateProblemCount(1);
|
validateProblemCount(1);
|
||||||
|
|
|
@ -551,6 +551,7 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
fIndex.releaseReadLock();
|
fIndex.releaseReadLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test164360_1() throws Exception {
|
public void test164360_1() throws Exception {
|
||||||
waitForIndexer();
|
waitForIndexer();
|
||||||
IFile include= TestSourceReader.createFile(fCProject.getProject(), "test164360.h", "");
|
IFile include= TestSourceReader.createFile(fCProject.getProject(), "test164360.h", "");
|
||||||
|
@ -696,8 +697,7 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
if (bindings[0] instanceof ICompositeType) {
|
if (bindings[0] instanceof ICompositeType) {
|
||||||
struct= bindings[0];
|
struct= bindings[0];
|
||||||
typedef= bindings[1];
|
typedef= bindings[1];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
struct= bindings[1];
|
struct= bindings[1];
|
||||||
typedef= bindings[0];
|
typedef= bindings[0];
|
||||||
}
|
}
|
||||||
|
@ -730,8 +730,7 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
if (bindings[0] instanceof ICPPClassType) {
|
if (bindings[0] instanceof ICPPClassType) {
|
||||||
struct= bindings[0];
|
struct= bindings[0];
|
||||||
typedef= bindings[1];
|
typedef= bindings[1];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
struct= bindings[1];
|
struct= bindings[1];
|
||||||
typedef= bindings[0];
|
typedef= bindings[0];
|
||||||
}
|
}
|
||||||
|
@ -1149,8 +1148,7 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
assertEquals(1, bindings.length);
|
assertEquals(1, bindings.length);
|
||||||
IIndexBinding binding = bindings[0];
|
IIndexBinding binding = bindings[0];
|
||||||
assertTrue(binding instanceof IVariable);
|
assertTrue(binding instanceof IVariable);
|
||||||
IIndexName[] names = index.findNames(binding,
|
IIndexName[] names = index.findNames(binding, IIndex.FIND_ALL_OCCURRENCES);
|
||||||
IIndex.FIND_ALL_OCCURRENCES);
|
|
||||||
assertEquals(1, names.length);
|
assertEquals(1, names.length);
|
||||||
assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath());
|
assertEquals(f4.getFullPath().toString(), names[0].getFile().getLocation().getFullPath());
|
||||||
|
|
||||||
|
|
|
@ -48,24 +48,18 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
suite.addTest(ProjectWithDepProj.suite());
|
suite.addTest(ProjectWithDepProj.suite());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #include <stdio.h>
|
// #include <stdio.h>
|
||||||
// void func1(void)
|
// void func1(void) {
|
||||||
// {
|
|
||||||
// int i = 0;
|
// int i = 0;
|
||||||
// for (i=0; i<10;i++)
|
// for (i=0; i<10;i++) {
|
||||||
// {
|
|
||||||
// printf("%i", i);
|
// printf("%i", i);
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #include "header.h"
|
// #include "header.h"
|
||||||
//
|
//
|
||||||
// int main(void)
|
// int main(void) {
|
||||||
// {
|
// while (1) {
|
||||||
// while (1)
|
|
||||||
// {
|
|
||||||
// func1();
|
// func1();
|
||||||
// }
|
// }
|
||||||
// return 0;
|
// return 0;
|
||||||
|
@ -86,8 +80,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
|
|
||||||
// #include "header.h"
|
// #include "header.h"
|
||||||
//
|
//
|
||||||
// int main(void)
|
// int main(void) {
|
||||||
// {
|
|
||||||
// void* v= func1;
|
// void* v= func1;
|
||||||
// }
|
// }
|
||||||
public void testBug181735() throws DOMException {
|
public void testBug181735() throws DOMException {
|
||||||
|
@ -151,7 +144,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
IVariable v= (IVariable) b0;
|
IVariable v= (IVariable) b0;
|
||||||
IType type= v.getType();
|
IType type= v.getType();
|
||||||
assertTrue(type instanceof IBasicType);
|
assertTrue(type instanceof IBasicType);
|
||||||
assertTrue(((IBasicType) type).getType() == IBasicType.t_char);
|
assertTrue(((IBasicType) type).getKind() == IBasicType.Kind.eChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int globalFunc();
|
// int globalFunc();
|
||||||
|
@ -165,7 +158,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
IFunction f= (IFunction) b0;
|
IFunction f= (IFunction) b0;
|
||||||
IType type= f.getType().getReturnType();
|
IType type= f.getType().getReturnType();
|
||||||
assertTrue(type instanceof IBasicType);
|
assertTrue(type instanceof IBasicType);
|
||||||
assertTrue(((IBasicType) type).getType() == IBasicType.t_char);
|
assertTrue(((IBasicType) type).getKind() == IBasicType.Kind.eChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct astruct {
|
// struct astruct {
|
||||||
|
@ -193,7 +186,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
assertEquals("additionalMember", additionalMember.getName());
|
assertEquals("additionalMember", additionalMember.getName());
|
||||||
IType type= member.getType();
|
IType type= member.getType();
|
||||||
assertTrue(type instanceof IBasicType);
|
assertTrue(type instanceof IBasicType);
|
||||||
assertTrue(((IBasicType) type).getType() == IBasicType.t_char);
|
assertTrue(((IBasicType) type).getKind() == IBasicType.Kind.eChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum anenum {
|
// enum anenum {
|
||||||
|
@ -224,7 +217,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
ITypedef t= (ITypedef) b0;
|
ITypedef t= (ITypedef) b0;
|
||||||
IType type= t.getType();
|
IType type= t.getType();
|
||||||
assertTrue(type instanceof IBasicType);
|
assertTrue(type instanceof IBasicType);
|
||||||
assertTrue(((IBasicType) type).getType() == IBasicType.t_char);
|
assertTrue(((IBasicType) type).getKind() == IBasicType.Kind.eChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct st_20070703 {
|
// struct st_20070703 {
|
||||||
|
@ -395,7 +388,7 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
||||||
IParameter[] params= f.getParameters();
|
IParameter[] params= f.getParameters();
|
||||||
assertEquals(1, params.length);
|
assertEquals(1, params.length);
|
||||||
assertTrue(params[0].getType() instanceof IBasicType);
|
assertTrue(params[0].getType() instanceof IBasicType);
|
||||||
assertEquals(IBasicType.t_int, ((IBasicType)params[0].getType()).getType());
|
assertEquals(IBasicType.Kind.eInt, ((IBasicType) params[0].getType()).getKind());
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct S S;
|
// typedef struct S S;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IField;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
@ -1829,5 +1830,40 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
assertTrue(reference instanceof ICPPSpecialization);
|
assertTrue(reference instanceof ICPPSpecialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename T> struct Base {
|
||||||
|
// int bfield;
|
||||||
|
// void bmethod();
|
||||||
|
// };
|
||||||
|
// template<typename T> struct XT : Base<T> {
|
||||||
|
// int field;
|
||||||
|
// void method() {};
|
||||||
|
// friend void f();
|
||||||
|
// struct Nested {};
|
||||||
|
// };
|
||||||
|
// struct TXT : XT<int> {};
|
||||||
|
|
||||||
|
// TXT x;
|
||||||
|
public void testClassSpecialization_Bug354086() throws Exception {
|
||||||
|
ICPPClassType ct= getBindingFromASTName("TXT", 0, ICPPClassType.class);
|
||||||
|
ICPPMethod[] methods = ct.getAllDeclaredMethods();
|
||||||
|
assertEquals(2, methods.length);
|
||||||
|
|
||||||
|
methods= ct.getConstructors();
|
||||||
|
assertEquals(2, methods.length);
|
||||||
|
|
||||||
|
methods= ct.getMethods();
|
||||||
|
assertEquals(14, methods.length);
|
||||||
|
|
||||||
|
ICPPBase[] bases = ct.getBases();
|
||||||
|
assertEquals(1, bases.length);
|
||||||
|
|
||||||
|
IField field = ct.findField("bfield");
|
||||||
|
assertNotNull(field);
|
||||||
|
|
||||||
|
IField[] fields = ct.getFields();
|
||||||
|
assertEquals(2, fields.length);
|
||||||
|
|
||||||
|
IBinding[] friends = ct.getFriends();
|
||||||
|
assertEquals(0, friends.length); // not yet supported
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,8 +227,6 @@ public class IndexCompositeTests extends BaseTestCase {
|
||||||
CharSequence[] contents = getContentsForTest(3);
|
CharSequence[] contents = getContentsForTest(3);
|
||||||
List projects = new ArrayList();
|
List projects = new ArrayList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ProjectBuilder pb = new ProjectBuilder("projB"+System.currentTimeMillis(), true);
|
ProjectBuilder pb = new ProjectBuilder("projB"+System.currentTimeMillis(), true);
|
||||||
pb.addFile("h2.h", contents[1]);
|
pb.addFile("h2.h", contents[1]);
|
||||||
|
@ -388,11 +386,9 @@ public class IndexCompositeTests extends BaseTestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts binding counts, and returns the index tested against
|
* Asserts binding counts, and returns the index tested against
|
||||||
* @param cprojA the project to obtain the index for
|
|
||||||
* @param options the options to obtain the index for
|
|
||||||
* @param global the number of bindings expected to be found at global scope
|
* @param global the number of bindings expected to be found at global scope
|
||||||
* @param all the number of bindings expected to be found at all scopes
|
* @param all the number of bindings expected to be found at all scopes
|
||||||
* @return
|
* @return the index
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
private IIndex assertBCount(int global, int all) throws CoreException {
|
private IIndex assertBCount(int global, int all) throws CoreException {
|
||||||
|
@ -456,8 +452,9 @@ class ProjectBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
ICProject create() throws CoreException {
|
ICProject create() throws CoreException {
|
||||||
ICProject result = cpp ? CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER)
|
ICProject result = cpp ?
|
||||||
: CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER);
|
CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER) :
|
||||||
|
CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER);
|
||||||
|
|
||||||
for (Iterator i = path2content.entrySet().iterator(); i.hasNext();) {
|
for (Iterator i = path2content.entrySet().iterator(); i.hasNext();) {
|
||||||
Map.Entry entry = (Map.Entry) i.next();
|
Map.Entry entry = (Map.Entry) i.next();
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
|
||||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
|
@ -111,7 +110,7 @@ public class CASTTranslationUnit extends ASTTranslationUnit implements IASTAmbig
|
||||||
/**
|
/**
|
||||||
* Maps structs from the index into this AST.
|
* Maps structs from the index into this AST.
|
||||||
*/
|
*/
|
||||||
public IType mapToASTType(ICompositeType type) {
|
public ICompositeType mapToASTType(ICompositeType type) {
|
||||||
return fStructMapper.mapToAST(type);
|
return fStructMapper.mapToAST(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,7 +55,7 @@ public class CStructMapper {
|
||||||
fTranslationUnit= tu;
|
fTranslationUnit= tu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType mapToAST(ICompositeType type) {
|
public ICompositeType mapToAST(ICompositeType type) {
|
||||||
if (fStructs == null) {
|
if (fStructs == null) {
|
||||||
fStructs= new CharArrayMap<IASTName>();
|
fStructs= new CharArrayMap<IASTName>();
|
||||||
fTranslationUnit.accept(new Visitor());
|
fTranslationUnit.accept(new Visitor());
|
||||||
|
|
|
@ -607,9 +607,9 @@ public class CVisitor extends ASTQueries {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != null && type instanceof ICompositeType) {
|
if (type != null && type instanceof ICompositeType) {
|
||||||
final ICompositeType ct = (ICompositeType) type;
|
ICompositeType ct = (ICompositeType) type;
|
||||||
if (type instanceof IIndexBinding) {
|
if (ct instanceof IIndexBinding) {
|
||||||
type= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType(ct);
|
ct= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType(ct);
|
||||||
}
|
}
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
char[] p = fieldReference.getFieldName().toCharArray();
|
char[] p = fieldReference.getFieldName().toCharArray();
|
||||||
|
|
|
@ -64,7 +64,16 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node instanceof IASTParameterDeclaration) {
|
if (node instanceof IASTParameterDeclaration) {
|
||||||
|
// If the parameter declaration belongs to a function declaration or
|
||||||
|
// function definition we need to update the scope.
|
||||||
|
IASTNode parent= node.getParent();
|
||||||
|
if (parent instanceof IASTDeclarator) {
|
||||||
|
IASTDeclarator dtor= (IASTDeclarator) parent;
|
||||||
|
if (dtor == ASTQueries.findTypeRelevantDeclarator(dtor) &&
|
||||||
|
ASTQueries.findOutermostDeclarator(dtor).getParent() instanceof IASTDeclaration) {
|
||||||
repopulateScope((IASTParameterDeclaration) node);
|
repopulateScope((IASTParameterDeclaration) node);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node instanceof IASTExpression) {
|
if (node instanceof IASTExpression) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
|
|
||||||
public final void incResolutionDepth() {
|
public final void incResolutionDepth() {
|
||||||
if (fBinding == null && ++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
if (fBinding == null && ++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
||||||
fBinding = new RecursionResolvingBinding(this);
|
setBinding(new RecursionResolvingBinding(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
public IBinding resolvePreBinding() {
|
public IBinding resolvePreBinding() {
|
||||||
if (fBinding == null) {
|
if (fBinding == null) {
|
||||||
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
||||||
fBinding= new RecursionResolvingBinding(this);
|
setBinding(new RecursionResolvingBinding(this));
|
||||||
} else {
|
} else {
|
||||||
fBinding= createIntermediateBinding();
|
setBinding(createIntermediateBinding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fBinding;
|
return fBinding;
|
||||||
|
@ -80,7 +80,7 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
public IBinding resolveBinding() {
|
public IBinding resolveBinding() {
|
||||||
if (fBinding == null) {
|
if (fBinding == null) {
|
||||||
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
||||||
fBinding= new RecursionResolvingBinding(this);
|
setBinding(new RecursionResolvingBinding(this));
|
||||||
} else {
|
} else {
|
||||||
fIsFinal= false;
|
fIsFinal= false;
|
||||||
final IBinding b= createIntermediateBinding();
|
final IBinding b= createIntermediateBinding();
|
||||||
|
@ -91,7 +91,7 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
pb.setASTNode(this);
|
pb.setASTNode(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fBinding= b;
|
setBinding(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!fIsFinal)
|
if (!fIsFinal)
|
||||||
|
@ -106,13 +106,14 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
* @see ICPPTwoPhaseBinding
|
* @see ICPPTwoPhaseBinding
|
||||||
*/
|
*/
|
||||||
public IBinding getPreBinding() {
|
public IBinding getPreBinding() {
|
||||||
final IBinding cand= fBinding;
|
|
||||||
if (cand == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return fBinding;
|
return fBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this name has not yet been resolved at all, <code>null</code> will be returned.
|
||||||
|
* Otherwise the final binding for this name is returned.
|
||||||
|
* @see ICPPTwoPhaseBinding
|
||||||
|
*/
|
||||||
public IBinding getBinding() {
|
public IBinding getBinding() {
|
||||||
final IBinding cand= fBinding;
|
final IBinding cand= fBinding;
|
||||||
if (cand == null)
|
if (cand == null)
|
||||||
|
@ -128,15 +129,12 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
||||||
if (fBinding instanceof ICPPTwoPhaseBinding) {
|
if (fBinding instanceof ICPPTwoPhaseBinding) {
|
||||||
ICPPTwoPhaseBinding intermediateBinding= (ICPPTwoPhaseBinding) fBinding;
|
ICPPTwoPhaseBinding intermediateBinding= (ICPPTwoPhaseBinding) fBinding;
|
||||||
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
|
||||||
fBinding= new RecursionResolvingBinding(this);
|
setBinding(new RecursionResolvingBinding(this));
|
||||||
} else {
|
} else {
|
||||||
IBinding finalBinding= intermediateBinding.resolveFinalBinding(astName);
|
setBinding(intermediateBinding.resolveFinalBinding(astName));
|
||||||
fBinding= finalBinding;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fIsFinal= true;
|
fIsFinal= true;
|
||||||
fResolutionDepth= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBinding(IBinding binding) {
|
public void setBinding(IBinding binding) {
|
||||||
|
|
|
@ -425,7 +425,7 @@ public class ClassTypeHelper {
|
||||||
IField[] fields = ct.getDeclaredFields();
|
IField[] fields = ct.getDeclaredFields();
|
||||||
ICPPClassType[] bases = getAllBases(ct);
|
ICPPClassType[] bases = getAllBases(ct);
|
||||||
for (ICPPClassType base : bases) {
|
for (ICPPClassType base : bases) {
|
||||||
fields = (IField[]) ArrayUtil.addAll(IField.class, fields, base.getFields());
|
fields = (IField[]) ArrayUtil.addAll(IField.class, fields, base.getDeclaredFields());
|
||||||
}
|
}
|
||||||
return (IField[]) ArrayUtil.trim(IField.class, fields);
|
return (IField[]) ArrayUtil.trim(IField.class, fields);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2941,20 +2941,19 @@ public class CPPSemantics {
|
||||||
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
|
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression expr) {
|
||||||
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromNewExpression(expr);
|
||||||
|
IType type = getTypeOfPointer(expr.getExpressionType());
|
||||||
IType type = exp.getExpressionType();
|
if (type == null)
|
||||||
if (!(type instanceof IPointerType))
|
|
||||||
return null;
|
return null;
|
||||||
type = ((IPointerType) type).getType();
|
|
||||||
|
|
||||||
IASTTypeId typeId = exp.getTypeId().copy();
|
IASTTypeId typeId = expr.getTypeId().copy();
|
||||||
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
||||||
sizeExpression.setParent(exp);
|
sizeExpression.setParent(expr);
|
||||||
|
|
||||||
IASTInitializerClause[] placement = exp.getPlacementArguments();
|
IASTInitializerClause[] placement = expr.getPlacementArguments();
|
||||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||||
|
args.add(createArgForType(expr, type));
|
||||||
args.add(sizeExpression);
|
args.add(sizeExpression);
|
||||||
if (placement != null) {
|
if (placement != null) {
|
||||||
for (IASTInitializerClause p : placement) {
|
for (IASTInitializerClause p : placement) {
|
||||||
|
@ -2962,23 +2961,23 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]);
|
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]);
|
||||||
return findOverloadedOperator(exp, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
|
return findOverloadedOperator(expr, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
|
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression expr) {
|
||||||
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
|
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(expr);
|
||||||
IType classType = getNestedClassType(exp);
|
IType type = getTypeOfPointer(expr.getOperand().getExpressionType());
|
||||||
IASTExpression[] args = new IASTExpression[] {createArgForType(exp, classType), exp.getOperand()};
|
if (type == null)
|
||||||
return findOverloadedOperator(exp, args, classType, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
|
return null;
|
||||||
|
|
||||||
|
IASTExpression[] args = {createArgForType(expr, type), expr.getOperand()};
|
||||||
|
return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
|
private static IType getTypeOfPointer(IType type) {
|
||||||
IType type = exp.getOperand().getExpressionType();
|
type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF | SemanticUtil.REF | SemanticUtil.CVTYPE);
|
||||||
type = SemanticUtil.getUltimateTypeUptoPointers(type);
|
|
||||||
if (type instanceof IPointerType) {
|
if (type instanceof IPointerType) {
|
||||||
IType classType = ((IPointerType) type).getType();
|
return getNestedType(((IPointerType) type).getType(), TDEF | REF | CVTYPE);
|
||||||
if (classType instanceof ICPPClassType)
|
|
||||||
return (ICPPClassType) classType;
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -3101,10 +3100,11 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
||||||
ICPPClassType cls = getNestedClassType(expr);
|
IType t = getTypeOfPointer(expr.getOperand().getExpressionType());
|
||||||
if (cls == null)
|
if (!(t instanceof ICPPClassType))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
ICPPClassType cls = (ICPPClassType) t;
|
||||||
IScope scope = cls.getCompositeScope();
|
IScope scope = cls.getCompositeScope();
|
||||||
if (scope == null)
|
if (scope == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -3281,8 +3281,15 @@ public class CPPSemantics {
|
||||||
funcName.setParent(parent);
|
funcName.setParent(parent);
|
||||||
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
LookupData funcData = new LookupData(funcName);
|
LookupData funcData = new LookupData(funcName);
|
||||||
if (operator == OverloadableOperator.DELETE || operator == OverloadableOperator.DELETE_ARRAY) {
|
|
||||||
|
// Global new and delete operators do not take an argument for the this pointer.
|
||||||
|
switch (operator) {
|
||||||
|
case DELETE: case DELETE_ARRAY:
|
||||||
|
case NEW: case NEW_ARRAY:
|
||||||
args= ArrayUtil.removeFirst(args);
|
args= ArrayUtil.removeFirst(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
funcData.setFunctionArguments(true, args);
|
funcData.setFunctionArguments(true, args);
|
||||||
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
package org.eclipse.cdt.internal.core.index.composite.cpp;
|
package org.eclipse.cdt.internal.core.index.composite.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IField;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
|
@ -25,7 +24,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
|
@ -105,7 +103,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPBase[] getBases() {
|
public final ICPPBase[] getBases() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getBases();
|
return ((ICPPClassSpecializationScope) scope).getBases();
|
||||||
|
@ -114,7 +112,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPConstructor[] getConstructors() {
|
public final ICPPConstructor[] getConstructors() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getConstructors();
|
return ((ICPPClassSpecializationScope) scope).getConstructors();
|
||||||
|
@ -123,7 +121,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPMethod[] getDeclaredMethods() {
|
public final ICPPMethod[] getDeclaredMethods() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods();
|
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods();
|
||||||
|
@ -132,7 +130,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPField[] getDeclaredFields() {
|
public final ICPPField[] getDeclaredFields() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getDeclaredFields();
|
return ((ICPPClassSpecializationScope) scope).getDeclaredFields();
|
||||||
|
@ -141,7 +139,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinding[] getFriends() {
|
public final IBinding[] getFriends() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getFriends();
|
return ((ICPPClassSpecializationScope) scope).getFriends();
|
||||||
|
@ -150,7 +148,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPClassType[] getNestedClasses() {
|
public final ICPPClassType[] getNestedClasses() {
|
||||||
IScope scope= getCompositeScope();
|
IScope scope= getCompositeScope();
|
||||||
if (scope instanceof ICPPClassSpecializationScope) {
|
if (scope instanceof ICPPClassSpecializationScope) {
|
||||||
return ((ICPPClassSpecializationScope) scope).getNestedClasses();
|
return ((ICPPClassSpecializationScope) scope).getNestedClasses();
|
||||||
|
@ -158,26 +156,6 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
|
||||||
return super.getNestedClasses();
|
return super.getNestedClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IField findField(String name) {
|
|
||||||
return ClassTypeHelper.findField(this, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ICPPMethod[] getAllDeclaredMethods() {
|
|
||||||
return ClassTypeHelper.getAllDeclaredMethods(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IField[] getFields() {
|
|
||||||
return ClassTypeHelper.getFields(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ICPPMethod[] getMethods() {
|
|
||||||
return ClassTypeHelper.getMethods(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public ObjectMap getArgumentMap() {
|
public ObjectMap getArgumentMap() {
|
||||||
return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
|
return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexType;
|
import org.eclipse.cdt.internal.core.index.IIndexType;
|
||||||
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
||||||
|
@ -35,17 +36,12 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
|
||||||
fail(); return null;
|
fail(); return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IField findField(String name) {
|
public final IField findField(String name) {
|
||||||
IField preResult = ((ICPPClassType)rbinding).findField(name);
|
return ClassTypeHelper.findField(this, name);
|
||||||
return (IField) cf.getCompositeBinding((IIndexFragmentBinding)preResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPMethod[] getAllDeclaredMethods() {
|
public final ICPPMethod[] getAllDeclaredMethods() {
|
||||||
ICPPMethod[] result = ((ICPPClassType)rbinding).getAllDeclaredMethods();
|
return ClassTypeHelper.getAllDeclaredMethods(this);
|
||||||
for(int i=0; i<result.length; i++) {
|
|
||||||
result[i] = (ICPPMethod) cf.getCompositeBinding((IIndexFragmentBinding)result[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CPPBaseDelegate implements ICPPBase {
|
private class CPPBaseDelegate implements ICPPBase {
|
||||||
|
@ -129,12 +125,8 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IField[] getFields() {
|
public final IField[] getFields() {
|
||||||
IField[] result = ((ICPPClassType)rbinding).getFields();
|
return ClassTypeHelper.getFields(this);
|
||||||
for(int i=0; i<result.length; i++) {
|
|
||||||
result[i]= (IField) cf.getCompositeBinding((IIndexFragmentBinding)result[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBinding[] getFriends() {
|
public IBinding[] getFriends() {
|
||||||
|
@ -146,12 +138,8 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPMethod[] getMethods() {
|
public final ICPPMethod[] getMethods() {
|
||||||
ICPPMethod[] result = ((ICPPClassType)rbinding).getMethods();
|
return ClassTypeHelper.getMethods(this);
|
||||||
for(int i=0; i<result.length; i++) {
|
|
||||||
result[i] = (ICPPMethod) cf.getCompositeBinding((IIndexFragmentBinding) result[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPClassType[] getNestedClasses() {
|
public ICPPClassType[] getNestedClasses() {
|
||||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.parser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@ -154,6 +155,20 @@ public class InternalParserUtil extends ParserFactory {
|
||||||
InputStream in;
|
InputStream in;
|
||||||
try {
|
try {
|
||||||
in= file.getContents(true);
|
in= file.getContents(true);
|
||||||
|
if (!(in instanceof FileInputStream)) {
|
||||||
|
/*
|
||||||
|
* In general, non-local file-systems will not use FileInputStream. Instead make a
|
||||||
|
* cached copy of the file and open an input stream to that.
|
||||||
|
*/
|
||||||
|
IFileStore store = EFS.getStore(file.getLocationURI());
|
||||||
|
File fileCache = store.toLocalFile(EFS.CACHE, null);
|
||||||
|
try {
|
||||||
|
in = new FileInputStream(fileCache);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return createFileContent(path, file.getCharset(), in);
|
return createFileContent(path, file.getCharset(), in);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -168,6 +183,7 @@ public class InternalParserUtil extends ParserFactory {
|
||||||
case IResourceStatus.NO_LOCATION_LOCAL:
|
case IResourceStatus.NO_LOCATION_LOCAL:
|
||||||
case IResourceStatus.FAILED_READ_LOCAL:
|
case IResourceStatus.FAILED_READ_LOCAL:
|
||||||
case IResourceStatus.RESOURCE_NOT_LOCAL:
|
case IResourceStatus.RESOURCE_NOT_LOCAL:
|
||||||
|
case IResourceStatus.RESOURCE_NOT_FOUND:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
|
@ -221,6 +237,9 @@ public class InternalParserUtil extends ParserFactory {
|
||||||
private static InternalFileContent createFileContent(String path, String charset, InputStream in) {
|
private static InternalFileContent createFileContent(String path, String charset, InputStream in) {
|
||||||
try {
|
try {
|
||||||
AbstractCharArray chars= FileCharArray.create(path, charset, in);
|
AbstractCharArray chars= FileCharArray.create(path, charset, in);
|
||||||
|
if (chars == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
return new InternalFileContent(path, chars);
|
return new InternalFileContent(path, chars);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
|
|
|
@ -77,8 +77,7 @@ class LocationCtxContainer extends LocationCtx {
|
||||||
final LocationCtx child= fChildren.get(i);
|
final LocationCtx child= fChildren.get(i);
|
||||||
if (child.fEndOffsetInParent > offset) { // child was inserted behind the offset, adjust sequence number
|
if (child.fEndOffsetInParent > offset) { // child was inserted behind the offset, adjust sequence number
|
||||||
result-= child.getSequenceLength();
|
result-= child.getSequenceLength();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,8 +207,7 @@ class LocationCtxContainer extends LocationCtx {
|
||||||
}
|
}
|
||||||
if (childSequenceNumber <= sequenceNumber) {
|
if (childSequenceNumber <= sequenceNumber) {
|
||||||
lower= middle + 1;
|
lower= middle + 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
upper= middle;
|
upper= middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,8 +225,7 @@ class LocationCtxContainer extends LocationCtx {
|
||||||
for (LocationCtx ctx : fChildren) {
|
for (LocationCtx ctx : fChildren) {
|
||||||
if (ctx.getInclusionStatement() != null) {
|
if (ctx.getInclusionStatement() != null) {
|
||||||
result.add(new ASTInclusionNode(ctx));
|
result.add(new ASTInclusionNode(ctx));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ctx.getInclusions(result);
|
ctx.getInclusions(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,9 +25,9 @@ class LocationCtxFile extends LocationCtxContainer {
|
||||||
private final ASTInclusionStatement fASTInclude;
|
private final ASTInclusionStatement fASTInclude;
|
||||||
private final boolean fIsSource;
|
private final boolean fIsSource;
|
||||||
|
|
||||||
public LocationCtxFile(LocationCtxContainer parent, String filename, AbstractCharArray source, int parentOffset,
|
public LocationCtxFile(LocationCtxContainer parent, String filename, AbstractCharArray source,
|
||||||
int parentEndOffset, int sequenceNumber, ASTInclusionStatement inclusionStatement,
|
int parentOffset, int parentEndOffset, int sequenceNumber,
|
||||||
boolean isSource) {
|
ASTInclusionStatement inclusionStatement, boolean isSource) {
|
||||||
super(parent, source, parentOffset, parentEndOffset, sequenceNumber);
|
super(parent, source, parentOffset, parentEndOffset, sequenceNumber);
|
||||||
fFilename= new String(filename);
|
fFilename= new String(filename);
|
||||||
fASTInclude= inclusionStatement;
|
fASTInclude= inclusionStatement;
|
||||||
|
@ -49,9 +50,11 @@ class LocationCtxFile extends LocationCtxContainer {
|
||||||
final int testEnd= length > 1 ? sequenceNumber + length - 1 : sequenceNumber;
|
final int testEnd= length > 1 ? sequenceNumber + length - 1 : sequenceNumber;
|
||||||
final int sequenceEnd= sequenceNumber+length;
|
final int sequenceEnd= sequenceNumber+length;
|
||||||
final LocationCtx child1= findChildLessOrEqualThan(sequenceNumber, false);
|
final LocationCtx child1= findChildLessOrEqualThan(sequenceNumber, false);
|
||||||
final LocationCtx child2= testEnd == sequenceNumber ? child1 : findChildLessOrEqualThan(testEnd, false);
|
final LocationCtx child2= testEnd == sequenceNumber ?
|
||||||
|
child1 : findChildLessOrEqualThan(testEnd, false);
|
||||||
|
|
||||||
if (child1 == child2 && child1 != null && child1.fSequenceNumber + child1.getSequenceLength() > testEnd) {
|
if (child1 == child2 && child1 != null &&
|
||||||
|
child1.fSequenceNumber + child1.getSequenceLength() > testEnd) {
|
||||||
return child1.findMappedFileLocation(sequenceNumber, length);
|
return child1.findMappedFileLocation(sequenceNumber, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,25 +64,21 @@ class LocationCtxFile extends LocationCtxContainer {
|
||||||
|
|
||||||
if (child1 == null) {
|
if (child1 == null) {
|
||||||
startOffset= sequenceNumber-fSequenceNumber;
|
startOffset= sequenceNumber-fSequenceNumber;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int childSequenceEnd= child1.fSequenceNumber + child1.getSequenceLength();
|
int childSequenceEnd= child1.fSequenceNumber + child1.getSequenceLength();
|
||||||
if (sequenceNumber < childSequenceEnd) {
|
if (sequenceNumber < childSequenceEnd) {
|
||||||
startOffset= child1.fOffsetInParent;
|
startOffset= child1.fOffsetInParent;
|
||||||
}
|
} else { // start beyond child1
|
||||||
else { // start beyond child1
|
|
||||||
startOffset= child1.fEndOffsetInParent + sequenceNumber - childSequenceEnd;
|
startOffset= child1.fEndOffsetInParent + sequenceNumber - childSequenceEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (child2 == null) {
|
if (child2 == null) {
|
||||||
endOffset= sequenceEnd - fSequenceNumber;
|
endOffset= sequenceEnd - fSequenceNumber;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int childSequenceEnd= child2.fSequenceNumber + child2.getSequenceLength();
|
int childSequenceEnd= child2.fSequenceNumber + child2.getSequenceLength();
|
||||||
if (childSequenceEnd < sequenceEnd) { // beyond child2
|
if (childSequenceEnd < sequenceEnd) { // beyond child2
|
||||||
endOffset= child2.fEndOffsetInParent + sequenceEnd - childSequenceEnd;
|
endOffset= child2.fEndOffsetInParent + sequenceEnd - childSequenceEnd;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
endOffset= child2.fEndOffsetInParent;
|
endOffset= child2.fEndOffsetInParent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +108,8 @@ class LocationCtxFile extends LocationCtxContainer {
|
||||||
return sequenceNumber >= child.fSequenceNumber + child.getSequenceLength();
|
return sequenceNumber >= child.fSequenceNumber + child.getSequenceLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collectMacroExpansions(int offset, int length, ArrayList<IASTPreprocessorMacroExpansion> list) {
|
public void collectMacroExpansions(int offset, int length,
|
||||||
|
ArrayList<IASTPreprocessorMacroExpansion> list) {
|
||||||
Collection<LocationCtx> children= getChildren();
|
Collection<LocationCtx> children= getChildren();
|
||||||
for (LocationCtx ctx : children) {
|
for (LocationCtx ctx : children) {
|
||||||
// context must start before the end of the search range
|
// context must start before the end of the search range
|
||||||
|
@ -119,7 +119,9 @@ class LocationCtxFile extends LocationCtxContainer {
|
||||||
if (ctx instanceof LocationCtxMacroExpansion) {
|
if (ctx instanceof LocationCtxMacroExpansion) {
|
||||||
// expansion must end after the search start
|
// expansion must end after the search start
|
||||||
if (ctx.fEndOffsetInParent > offset) {
|
if (ctx.fEndOffsetInParent > offset) {
|
||||||
list.add((IASTPreprocessorMacroExpansion) ((LocationCtxMacroExpansion)ctx).getMacroReference().getParent());
|
IASTNode macroExpansion =
|
||||||
|
((LocationCtxMacroExpansion) ctx).getMacroReference().getParent();
|
||||||
|
list.add((IASTPreprocessorMacroExpansion) macroExpansion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,18 +87,15 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
||||||
if (info.fTokenOffsetInExpansion == nextToCheck) {
|
if (info.fTokenOffsetInExpansion == nextToCheck) {
|
||||||
if (firstInfo == null || lastInfo == null) {
|
if (firstInfo == null || lastInfo == null) {
|
||||||
firstInfo= lastInfo= info;
|
firstInfo= lastInfo= info;
|
||||||
}
|
} else if (lastInfo.canConcatenate(info)) {
|
||||||
else if (lastInfo.canConcatenate(info)) {
|
|
||||||
lastInfo= info;
|
lastInfo= info;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (++nextToCheck == end) {
|
if (++nextToCheck == end) {
|
||||||
return firstInfo.createLocation(fLocationMap, lastInfo);
|
return firstInfo.createLocation(fLocationMap, lastInfo);
|
||||||
}
|
}
|
||||||
}
|
} else if (info.fTokenOffsetInExpansion > nextToCheck) {
|
||||||
else if (info.fTokenOffsetInExpansion > nextToCheck) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,5 +106,3 @@ class LocationCtxMacroExpansion extends LocationCtx {
|
||||||
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
|
return fLocationMap.getNestedMacroReferences((ASTMacroExpansion) fExpansionName.getParent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,11 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTProblem;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the offsets relative to various contexts to the global sequence number. Also creates and stores
|
* Converts the offsets relative to various contexts to the global sequence number. Also creates
|
||||||
* objects that are needed to conform with the IAST... interfaces.
|
* and stores objects that are needed to conform with the IAST... interfaces.
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public class LocationMap implements ILocationResolver {
|
public class LocationMap implements ILocationResolver {
|
||||||
private static final IASTName[] EMPTY_NAMES = {};
|
|
||||||
|
|
||||||
private final LexerOptions fLexerOptions;
|
private final LexerOptions fLexerOptions;
|
||||||
private String fTranslationUnitPath;
|
private String fTranslationUnitPath;
|
||||||
private IASTTranslationUnit fTranslationUnit;
|
private IASTTranslationUnit fTranslationUnit;
|
||||||
|
@ -82,8 +80,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
ASTMacroDefinition astmacro;
|
ASTMacroDefinition astmacro;
|
||||||
if (macro.isFunctionStyle()) {
|
if (macro.isFunctionStyle()) {
|
||||||
astmacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
astmacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
astmacro= new ASTMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
astmacro= new ASTMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
||||||
}
|
}
|
||||||
fBuiltinMacros.add(astmacro);
|
fBuiltinMacros.add(astmacro);
|
||||||
|
@ -179,7 +176,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
final int length= endNumber - nameNumber;
|
final int length= endNumber - nameNumber;
|
||||||
|
|
||||||
ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber);
|
ASTMacroExpansion expansion= new ASTMacroExpansion(fTranslationUnit, nameNumber, endNumber);
|
||||||
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion, IASTPreprocessorMacroExpansion.EXPANSION_NAME, nameNumber, nameEndNumber, macro, null);
|
ASTMacroReferenceName explicitRef= new ASTMacroReferenceName(expansion,
|
||||||
|
IASTPreprocessorMacroExpansion.EXPANSION_NAME, nameNumber, nameEndNumber, macro, null);
|
||||||
addMacroReference(explicitRef);
|
addMacroReference(explicitRef);
|
||||||
for (IASTName implicitMacroReference : implicitMacroReferences) {
|
for (IASTName implicitMacroReference : implicitMacroReferences) {
|
||||||
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReference;
|
ASTMacroReferenceName name = (ASTMacroReferenceName) implicitMacroReference;
|
||||||
|
@ -188,7 +186,9 @@ public class LocationMap implements ILocationResolver {
|
||||||
addMacroReference(name);
|
addMacroReference(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this, (LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber, contextLength, imageLocations, explicitRef);
|
LocationCtxMacroExpansion expansionCtx= new LocationCtxMacroExpansion(this,
|
||||||
|
(LocationCtxContainer) fCurrentContext, nameOffset, endOffset, endNumber,
|
||||||
|
contextLength, imageLocations, explicitRef);
|
||||||
expansion.setContext(expansionCtx);
|
expansion.setContext(expansionCtx);
|
||||||
fCurrentContext= expansionCtx;
|
fCurrentContext= expansionCtx;
|
||||||
fLastChildInsertionOffset= 0;
|
fLastChildInsertionOffset= 0;
|
||||||
|
@ -232,7 +232,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||||
endOffset= getSequenceNumberForOffset(endOffset);
|
endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
fDirectives.add(new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset, nameEndOffset, endOffset, name, filename, userInclude, active, heuristic));
|
fDirectives.add(new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset,
|
||||||
|
nameEndOffset, endOffset, name, filename, userInclude, active, heuristic));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
||||||
|
@ -244,7 +245,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
public void encounterProblem(int id, char[] arg, int offset, int endOffset) {
|
public void encounterProblem(int id, char[] arg, int offset, int endOffset) {
|
||||||
offset= getSequenceNumberForOffset(offset);
|
offset= getSequenceNumberForOffset(offset);
|
||||||
endOffset= getSequenceNumberForOffset(endOffset);
|
endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
ASTProblem problem = new ASTProblem(fTranslationUnit, IASTTranslationUnit.SCANNER_PROBLEM, id, arg, false, offset, endOffset);
|
ASTProblem problem = new ASTProblem(fTranslationUnit, IASTTranslationUnit.SCANNER_PROBLEM,
|
||||||
|
id, arg, false, offset, endOffset);
|
||||||
fProblems.add(problem);
|
fProblems.add(problem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +304,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
fDirectives.add(new ASTPragmaOperator(fTranslationUnit, startNumber, condNumber, condEndNumber, endNumber));
|
fDirectives.add(new ASTPragmaOperator(fTranslationUnit, startNumber, condNumber, condEndNumber, endNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTIfdef encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
public ASTIfdef encounterPoundIfdef(int startOffset, int condOffset, int condEndOffset,
|
||||||
|
int endOffset, boolean taken, IMacroBinding macro) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
condOffset= getSequenceNumberForOffset(condOffset);
|
condOffset= getSequenceNumberForOffset(condOffset);
|
||||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||||
|
@ -313,7 +316,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
return ifdef;
|
return ifdef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTIfndef encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken, IMacroBinding macro) {
|
public ASTIfndef encounterPoundIfndef(int startOffset, int condOffset, int condEndOffset,
|
||||||
|
int endOffset, boolean taken, IMacroBinding macro) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
condOffset= getSequenceNumberForOffset(condOffset);
|
condOffset= getSequenceNumberForOffset(condOffset);
|
||||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||||
|
@ -324,8 +328,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
return ifndef;
|
return ifndef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTIf encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset, boolean taken,
|
public ASTIf encounterPoundIf(int startOffset, int condOffset, int condEndOffset, int endOffset,
|
||||||
IASTName[] macrosInDefinedExpression) {
|
boolean taken, IASTName[] macrosInDefinedExpression) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
condOffset= getSequenceNumberForOffset(condOffset);
|
condOffset= getSequenceNumberForOffset(condOffset);
|
||||||
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
condEndOffset= getSequenceNumberForOffset(condEndOffset);
|
||||||
|
@ -341,7 +345,8 @@ public class LocationMap implements ILocationResolver {
|
||||||
return astif;
|
return astif;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, boolean isActive, IMacroBinding macrodef) {
|
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset,
|
||||||
|
int expansionOffset, int endOffset, boolean isActive, IMacroBinding macrodef) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||||
|
@ -349,20 +354,23 @@ public class LocationMap implements ILocationResolver {
|
||||||
endOffset= getSequenceNumberForOffset(endOffset);
|
endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
ASTPreprocessorNode astMacro;
|
ASTPreprocessorNode astMacro;
|
||||||
if (!macrodef.isFunctionStyle()) {
|
if (!macrodef.isFunctionStyle()) {
|
||||||
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset, isActive);
|
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset,
|
||||||
}
|
nameEndOffset, expansionOffset, endOffset, isActive);
|
||||||
else {
|
} else {
|
||||||
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset, isActive);
|
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset,
|
||||||
|
nameOffset, nameEndOffset, expansionOffset, endOffset, isActive);
|
||||||
}
|
}
|
||||||
fDirectives.add(astMacro);
|
fDirectives.add(astMacro);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encounterPoundUndef(IMacroBinding definition, int startOffset, int nameOffset, int nameEndOffset, int endOffset, char[] name, boolean isActive) {
|
public void encounterPoundUndef(IMacroBinding definition, int startOffset, int nameOffset,
|
||||||
|
int nameEndOffset, int endOffset, char[] name, boolean isActive) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||||
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
// not using endOffset, compatible with 4.0: endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
final ASTUndef undef = new ASTUndef(fTranslationUnit, name, startOffset, nameOffset, nameEndOffset, definition, isActive);
|
final ASTUndef undef = new ASTUndef(fTranslationUnit, name, startOffset, nameOffset,
|
||||||
|
nameEndOffset, definition, isActive);
|
||||||
fDirectives.add(undef);
|
fDirectives.add(undef);
|
||||||
addMacroReference(undef.getMacroName());
|
addMacroReference(undef.getMacroName());
|
||||||
}
|
}
|
||||||
|
@ -559,8 +567,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
ASTPreprocessorNode candidate= nodes.get(middle);
|
ASTPreprocessorNode candidate= nodes.get(middle);
|
||||||
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
||||||
upper= middle - 1;
|
upper= middle - 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
lower= middle;
|
lower= middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,8 +586,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
}
|
}
|
||||||
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
if (candidate.getOffset() + candidate.getLength() >= sequenceStart) {
|
||||||
upper= middle - 1;
|
upper= middle - 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
lower= middle;
|
lower= middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,8 +606,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
contexts.addAll(ctx.getChildren());
|
contexts.addAll(ctx.getChildren());
|
||||||
if (contexts.isEmpty()) {
|
if (contexts.isEmpty()) {
|
||||||
ctx= null;
|
ctx= null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ctx= contexts.removeFirst();
|
ctx= contexts.removeFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,7 +681,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
|
|
||||||
public IASTName[] getDeclarations(IMacroBinding binding) {
|
public IASTName[] getDeclarations(IMacroBinding binding) {
|
||||||
IASTPreprocessorMacroDefinition def = getMacroDefinition(binding);
|
IASTPreprocessorMacroDefinition def = getMacroDefinition(binding);
|
||||||
return def == null ? EMPTY_NAMES : new IASTName[] {def.getName()};
|
return def == null ? IASTName.EMPTY_NAME_ARRAY: new IASTName[] { def.getName() };
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTPreprocessorMacroDefinition getMacroDefinition(IMacroBinding binding) {
|
IASTPreprocessorMacroDefinition getMacroDefinition(IMacroBinding binding) {
|
||||||
|
|
|
@ -65,8 +65,7 @@ public class MacroExpander {
|
||||||
public void execute(IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
|
public void execute(IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
|
||||||
if (fIsStart) {
|
if (fIsStart) {
|
||||||
forbidden.put(fMacro, fMacro);
|
forbidden.put(fMacro, fMacro);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
forbidden.remove(fMacro);
|
forbidden.remove(fMacro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,18 +302,15 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
tracker.endFunctionStyleMacro();
|
tracker.endFunctionStyleMacro();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (tracker == null) {
|
if (tracker == null) {
|
||||||
objStyleTokenPaste(macro, result);
|
objStyleTokenPaste(macro, result);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (tracker.isRequestedStep()) {
|
if (tracker.isRequestedStep()) {
|
||||||
TokenList replacement= new TokenList();
|
TokenList replacement= new TokenList();
|
||||||
objStyleTokenPaste(macro, replacement);
|
objStyleTokenPaste(macro, replacement);
|
||||||
tracker.storeObjectStyleMacroReplacement(macro, lastConsumed, replacement, result);
|
tracker.storeObjectStyleMacroReplacement(macro, lastConsumed, replacement, result);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
objStyleTokenPaste(macro, result);
|
objStyleTokenPaste(macro, result);
|
||||||
}
|
}
|
||||||
tracker.endObjectStyleMacro();
|
tracker.endObjectStyleMacro();
|
||||||
|
@ -349,21 +345,17 @@ public class MacroExpander {
|
||||||
PreprocessorMacro macro= fDictionary.get(image);
|
PreprocessorMacro macro= fDictionary.get(image);
|
||||||
if (protect || (tracker != null && tracker.isDone())) {
|
if (protect || (tracker != null && tracker.isDone())) {
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
} else if (protectDefinedConstructs && Arrays.equals(image, Keywords.cDEFINED)) {
|
||||||
else if (protectDefinedConstructs && Arrays.equals(image, Keywords.cDEFINED)) {
|
|
||||||
t.setType(CPreprocessor.tDEFINED);
|
t.setType(CPreprocessor.tDEFINED);
|
||||||
result.append(t);
|
result.append(t);
|
||||||
protect= true;
|
protect= true;
|
||||||
}
|
} else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
|
||||||
// tricky: don't mark function-style macros if you don't find the left parenthesis
|
// Tricky: Don't mark function-style macros if you don't find the left parenthesis
|
||||||
else if (macro == null || (macro.isFunctionStyle() && !input.findLParenthesis())) {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
} else if (forbidden.containsKey(macro)) {
|
||||||
else if (forbidden.containsKey(macro)) {
|
|
||||||
t.setType(CPreprocessor.tEXPANDED_IDENTIFIER); // prevent any further expansion
|
t.setType(CPreprocessor.tEXPANDED_IDENTIFIER); // prevent any further expansion
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fLocationMap != null) {
|
if (fLocationMap != null) {
|
||||||
ImageLocationInfo info= null;
|
ImageLocationInfo info= null;
|
||||||
if (fLexOptions.fCreateImageLocations) {
|
if (fLexOptions.fCreateImageLocations) {
|
||||||
|
@ -403,8 +395,7 @@ public class MacroExpander {
|
||||||
final Object s= t.fSource;
|
final Object s= t.fSource;
|
||||||
if (s instanceof ObjectStyleMacro) {
|
if (s instanceof ObjectStyleMacro) {
|
||||||
return new MacroImageLocationInfo((ObjectStyleMacro) s, t.getOffset(), t.getEndOffset());
|
return new MacroImageLocationInfo((ObjectStyleMacro) s, t.getOffset(), t.getEndOffset());
|
||||||
}
|
} else if (s instanceof CPreprocessor) {
|
||||||
else if (s instanceof CPreprocessor) {
|
|
||||||
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(t.getOffset());
|
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(t.getOffset());
|
||||||
int sequenceEndNumber= fLocationMap.getSequenceNumberForOffset(t.getEndOffset());
|
int sequenceEndNumber= fLocationMap.getSequenceNumberForOffset(t.getEndOffset());
|
||||||
return new ParameterImageLocationInfo(sequenceNumber, sequenceEndNumber);
|
return new ParameterImageLocationInfo(sequenceNumber, sequenceEndNumber);
|
||||||
|
@ -514,8 +505,7 @@ public class MacroExpander {
|
||||||
spaceMarkers.clear();
|
spaceMarkers.clear();
|
||||||
idx++;
|
idx++;
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
} else if (!hasVarargs) {
|
||||||
else if (!hasVarargs) {
|
|
||||||
tooManyArgs= true;
|
tooManyArgs= true;
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
|
@ -525,8 +515,7 @@ public class MacroExpander {
|
||||||
case CPreprocessor.tSCOPE_MARKER:
|
case CPreprocessor.tSCOPE_MARKER:
|
||||||
if (argCount == 0) {
|
if (argCount == 0) {
|
||||||
((ExpansionBoundary) t).execute(forbidden);
|
((ExpansionBoundary) t).execute(forbidden);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result[idx].append(t);
|
result[idx].append(t);
|
||||||
}
|
}
|
||||||
continue loop;
|
continue loop;
|
||||||
|
@ -556,9 +545,9 @@ public class MacroExpander {
|
||||||
throw new AbortMacroExpansionException();
|
throw new AbortMacroExpansionException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooManyArgs)
|
if (tooManyArgs) {
|
||||||
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
||||||
else if (idx+1 < requiredArgs) {
|
} else if (idx+1 < requiredArgs) {
|
||||||
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
||||||
}
|
}
|
||||||
return lastToken;
|
return lastToken;
|
||||||
|
@ -589,8 +578,7 @@ public class MacroExpander {
|
||||||
result.appendAllButLast(arg);
|
result.appendAllButLast(arg);
|
||||||
addSpacemarker(result.last(), pasteArg1, result); // start token paste
|
addSpacemarker(result.last(), pasteArg1, result); // start token paste
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
TokenList arg= clone(expandedArgs[idx]);
|
TokenList arg= clone(expandedArgs[idx]);
|
||||||
result.appendAll(arg);
|
result.appendAll(arg);
|
||||||
addSpacemarker(t, n, result); // end argument replacement
|
addSpacemarker(t, n, result); // end argument replacement
|
||||||
|
@ -618,8 +606,7 @@ public class MacroExpander {
|
||||||
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
|
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
|
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
|
||||||
pasteArg1= generated;
|
pasteArg1= generated;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(generated);
|
result.append(generated);
|
||||||
addSpacemarker(t, n, result); // end stringify
|
addSpacemarker(t, n, result); // end stringify
|
||||||
}
|
}
|
||||||
|
@ -654,13 +641,23 @@ public class MacroExpander {
|
||||||
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
|
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
|
||||||
|
|
||||||
generated= tokenpaste(pasteArg1, pasteArg2, macro);
|
generated= tokenpaste(pasteArg1, pasteArg2, macro);
|
||||||
|
if (generated == null) {
|
||||||
|
// Cannot perform token paste.
|
||||||
|
// Use the two tokens instead, see bug 354553.
|
||||||
|
generated= pasteArg1;
|
||||||
|
if (rest == null)
|
||||||
|
rest= new TokenList();
|
||||||
|
|
||||||
|
rest.prepend(pasteArg2);
|
||||||
|
spaceDef0= generated;
|
||||||
|
spaceDef1= pasteArg2;
|
||||||
|
}
|
||||||
pasteArg1= null;
|
pasteArg1= null;
|
||||||
|
|
||||||
if (generated != null) {
|
if (generated != null) {
|
||||||
if (pasteNext && rest == null) {
|
if (pasteNext && rest == null) {
|
||||||
pasteArg1= generated; // no need to mark spaces, done ahead
|
pasteArg1= generated; // no need to mark spaces, done ahead
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(generated);
|
result.append(generated);
|
||||||
addSpacemarker(spaceDef0, spaceDef1, result); // end token paste
|
addSpacemarker(spaceDef0, spaceDef1, result); // end token paste
|
||||||
}
|
}
|
||||||
|
@ -672,8 +669,7 @@ public class MacroExpander {
|
||||||
result.appendAllButLast(rest);
|
result.appendAllButLast(rest);
|
||||||
addSpacemarker(result.last(), pasteArg1, result); // start token paste
|
addSpacemarker(result.last(), pasteArg1, result); // start token paste
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.appendAll(rest);
|
result.appendAll(rest);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
addSpacemarker(t, n, result); // end argument replacement
|
addSpacemarker(t, n, result); // end argument replacement
|
||||||
|
@ -697,8 +693,7 @@ public class MacroExpander {
|
||||||
if (arg.isEmpty()) {
|
if (arg.isEmpty()) {
|
||||||
addSpacemarker(l, t, result);
|
addSpacemarker(l, t, result);
|
||||||
addSpacemarker(nn, nnn, result);
|
addSpacemarker(nn, nnn, result);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
addSpacemarker(t, n, result);
|
addSpacemarker(t, n, result);
|
||||||
result.appendAll(arg);
|
result.appendAll(arg);
|
||||||
|
@ -712,8 +707,7 @@ public class MacroExpander {
|
||||||
|
|
||||||
addSpacemarker(l, t, result);
|
addSpacemarker(l, t, result);
|
||||||
pasteArg1= t;
|
pasteArg1= t;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -722,8 +716,7 @@ public class MacroExpander {
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
addSpacemarker(l, t, result); // start token paste
|
addSpacemarker(l, t, result); // start token paste
|
||||||
pasteArg1= t;
|
pasteArg1= t;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -767,8 +760,7 @@ public class MacroExpander {
|
||||||
if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
|
if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
|
||||||
idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
|
idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
|
||||||
result.set(2*idx+1);
|
result.set(2*idx+1);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.set(2*idx);
|
result.set(2*idx);
|
||||||
}
|
}
|
||||||
t= n; n= (Token) n.getNext();
|
t= n; n= (Token) n.getNext();
|
||||||
|
@ -801,8 +793,7 @@ public class MacroExpander {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
pasteArg1= t;
|
pasteArg1= t;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
addSpacemarker(pasteArg2, n, result); // end token paste
|
addSpacemarker(pasteArg2, n, result); // end token paste
|
||||||
}
|
}
|
||||||
|
@ -814,8 +805,7 @@ public class MacroExpander {
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
addSpacemarker(l, t, result); // start token paste
|
addSpacemarker(l, t, result); // start token paste
|
||||||
pasteArg1= t;
|
pasteArg1= t;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -58,6 +58,18 @@ class TokenList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void prepend(Token t) {
|
||||||
|
final Token first= t;
|
||||||
|
if (first != null) {
|
||||||
|
final Token last= t;
|
||||||
|
last.setNext(fFirst);
|
||||||
|
fFirst= first;
|
||||||
|
if (fLast == null) {
|
||||||
|
fLast= last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void prepend(TokenList prepend) {
|
public final void prepend(TokenList prepend) {
|
||||||
final Token first= prepend.fFirst;
|
final Token first= prepend.fFirst;
|
||||||
if (first != null) {
|
if (first != null) {
|
||||||
|
|
|
@ -80,6 +80,7 @@ abstract public class PDOMWriter {
|
||||||
ArrayList<IASTPreprocessorStatement> fMacros= new ArrayList<IASTPreprocessorStatement>();
|
ArrayList<IASTPreprocessorStatement> fMacros= new ArrayList<IASTPreprocessorStatement>();
|
||||||
ArrayList<IASTPreprocessorIncludeStatement> fIncludes= new ArrayList<IASTPreprocessorIncludeStatement>();
|
ArrayList<IASTPreprocessorIncludeStatement> fIncludes= new ArrayList<IASTPreprocessorIncludeStatement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fShowProblems;
|
private boolean fShowProblems;
|
||||||
protected boolean fShowInclusionProblems;
|
protected boolean fShowInclusionProblems;
|
||||||
private boolean fShowScannerProblems;
|
private boolean fShowScannerProblems;
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class PDOMASTAdapter {
|
||||||
public int getEndingLineNumber() {
|
public int getEndingLineNumber() {
|
||||||
return loc.getStartingLineNumber();
|
return loc.getStartingLineNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return loc.getFileName();
|
return loc.getFileName();
|
||||||
}
|
}
|
||||||
|
@ -73,7 +74,6 @@ public class PDOMASTAdapter {
|
||||||
public int getNodeOffset() {
|
public int getNodeOffset() {
|
||||||
return loc.getNodeOffset();
|
return loc.getNodeOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,8 +197,7 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
if (e.getStatus().equals(Status.OK_STATUS)) {
|
if (e.getStatus().equals(Status.OK_STATUS)) {
|
||||||
result= visitor.getField();
|
result= visitor.getField();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,15 +72,11 @@ public class CModelUtil {
|
||||||
public static ICContainer getSourceFolder(ICElement element) {
|
public static ICContainer getSourceFolder(ICElement element) {
|
||||||
ICContainer folder = null;
|
ICContainer folder = null;
|
||||||
if (element != null) {
|
if (element != null) {
|
||||||
boolean foundSourceRoot = false;
|
|
||||||
ICElement curr = element;
|
ICElement curr = element;
|
||||||
while (curr != null && !foundSourceRoot) {
|
while (curr != null && !(curr instanceof ISourceRoot)) {
|
||||||
if (curr instanceof ICContainer && folder == null) {
|
|
||||||
folder = (ICContainer)curr;
|
|
||||||
}
|
|
||||||
foundSourceRoot = (curr instanceof ISourceRoot);
|
|
||||||
curr = curr.getParent();
|
curr = curr.getParent();
|
||||||
}
|
}
|
||||||
|
folder = (ISourceRoot)curr;
|
||||||
if (folder == null) {
|
if (folder == null) {
|
||||||
ICProject cproject = element.getCProject();
|
ICProject cproject = element.getCProject();
|
||||||
folder = cproject.findSourceRoot(cproject.getProject());
|
folder = cproject.findSourceRoot(cproject.getProject());
|
||||||
|
|
|
@ -56,23 +56,19 @@ import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||||
* Handles the extraction of expression nodes, like return type determination.
|
* Handles the extraction of expression nodes, like return type determination.
|
||||||
*
|
*
|
||||||
* @author Mirko Stocker
|
* @author Mirko Stocker
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
|
|
||||||
final static char[] ZERO= { '0' };
|
final static char[] ZERO= { '0' };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void constructMethodBody(IASTCompoundStatement compound,
|
public void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> list,
|
||||||
List<IASTNode> list, ASTRewrite rewrite, TextEditGroup group) {
|
ASTRewrite rewrite, TextEditGroup group) {
|
||||||
|
|
||||||
CPPASTReturnStatement statement = new CPPASTReturnStatement();
|
CPPASTReturnStatement statement = new CPPASTReturnStatement();
|
||||||
IASTExpression nullReturnExp = new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, ZERO);
|
IASTExpression nullReturnExp = new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, ZERO);
|
||||||
statement.setReturnValue(nullReturnExp);
|
statement.setReturnValue(nullReturnExp);
|
||||||
ASTRewrite nestedRewrite = rewrite.insertBefore(compound, null, statement, group);
|
ASTRewrite nestedRewrite = rewrite.insertBefore(compound, null, statement, group);
|
||||||
|
|
||||||
nestedRewrite.replace(nullReturnExp, getExpression(list), group);
|
nestedRewrite.replace(nullReturnExp, getExpression(list), group);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTExpression getExpression(List<IASTNode> list) {
|
private IASTExpression getExpression(List<IASTNode> list) {
|
||||||
|
@ -86,18 +82,17 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
} else {
|
} else {
|
||||||
return (IASTExpression) list.get(0).copy(CopyStyle.withLocations);
|
return (IASTExpression) list.get(0).copy(CopyStyle.withLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation _) {
|
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode, NameInformation _) {
|
||||||
List<ITypedef> typdefs = getTypdefs(extractedNode);
|
List<ITypedef> typedefs = getTypedefs(extractedNode);
|
||||||
if (extractedNode instanceof IASTExpression) {
|
if (extractedNode instanceof IASTExpression) {
|
||||||
IASTExpression exp = (IASTExpression) extractedNode;
|
IASTExpression exp = (IASTExpression) extractedNode;
|
||||||
INodeFactory factory = extractedNode.getTranslationUnit().getASTNodeFactory();
|
INodeFactory factory = extractedNode.getTranslationUnit().getASTNodeFactory();
|
||||||
DeclarationGenerator generator = DeclarationGenerator.create(factory);
|
DeclarationGenerator generator = DeclarationGenerator.create(factory);
|
||||||
IType expressionType = exp.getExpressionType();
|
IType expressionType = exp.getExpressionType();
|
||||||
for (ITypedef typedef : typdefs) {
|
for (ITypedef typedef : typedefs) {
|
||||||
if (typedef.getType().isSameType(expressionType)) {
|
if (typedef.getType().isSameType(expressionType)) {
|
||||||
return generator.createDeclSpecFromType(typedef);
|
return generator.createDeclSpecFromType(typedef);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +103,7 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ITypedef> getTypdefs(IASTNode extractedNode) {
|
private List<ITypedef> getTypedefs(IASTNode extractedNode) {
|
||||||
final ArrayList<ITypedef> typeDefs = new ArrayList<ITypedef>();
|
final ArrayList<ITypedef> typeDefs = new ArrayList<ITypedef>();
|
||||||
extractedNode.accept(new ASTVisitor() {
|
extractedNode.accept(new ASTVisitor() {
|
||||||
{
|
{
|
||||||
|
@ -181,7 +176,8 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
IASTNode parent = function.getDeclarations()[0].getParent();
|
IASTNode parent = function.getDeclarations()[0].getParent();
|
||||||
if (parent instanceof CPPASTSimpleDeclaration) {
|
if (parent instanceof CPPASTSimpleDeclaration) {
|
||||||
CPPASTSimpleDeclaration declaration = (CPPASTSimpleDeclaration) parent;
|
CPPASTSimpleDeclaration declaration = (CPPASTSimpleDeclaration) parent;
|
||||||
return declaration.getDeclarators().length > 0 && declaration.getDeclarators()[0].getPointerOperators().length > 0;
|
return declaration.getDeclarators().length > 0 &&
|
||||||
|
declaration.getDeclarators()[0].getPointerOperators().length > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,12 @@ import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||||
|
|
||||||
final class SimilarFinderVisitor extends ASTVisitor {
|
final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
|
|
||||||
private final ExtractFunctionRefactoring refactoring;
|
private final ExtractFunctionRefactoring refactoring;
|
||||||
|
|
||||||
private final Vector<IASTNode> trail;
|
private final Vector<IASTNode> trail;
|
||||||
private final IASTName name;
|
private final IASTName name;
|
||||||
private final List<IASTNode> stmts;
|
private final List<IASTNode> stmts;
|
||||||
private int i = 0;
|
private int i;
|
||||||
private NodeContainer similarContainer;
|
private NodeContainer similarContainer;
|
||||||
private final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
private final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
||||||
|
|
||||||
|
@ -51,15 +50,11 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
this.stmts = stmts;
|
this.stmts = stmts;
|
||||||
this.collector = collector;
|
this.collector = collector;
|
||||||
this.similarContainer = new NodeContainer();
|
this.similarContainer = new NodeContainer();
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
shouldVisitStatements = true;
|
shouldVisitStatements = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTStatement stmt) {
|
public int visit(IASTStatement stmt) {
|
||||||
|
|
||||||
boolean isAllreadyInMainRefactoring = isInSelection(stmt);
|
boolean isAllreadyInMainRefactoring = isInSelection(stmt);
|
||||||
|
|
||||||
if ((!isAllreadyInMainRefactoring)
|
if ((!isAllreadyInMainRefactoring)
|
||||||
|
@ -69,7 +64,7 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if (i == stmts.size()) {
|
if (i == stmts.size()) {
|
||||||
//found similar code
|
// Found similar code
|
||||||
|
|
||||||
boolean similarOnReturnWays = true;
|
boolean similarOnReturnWays = true;
|
||||||
for (NameInformation nameInfo : similarContainer.getAllAfterUsedNames()) {
|
for (NameInformation nameInfo : similarContainer.getAllAfterUsedNames()) {
|
||||||
|
@ -102,8 +97,8 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
IASTNode call = refactoring.getMethodCall(name,
|
IASTNode call = refactoring.getMethodCall(name,
|
||||||
this.refactoring.nameTrail, this.refactoring.names,
|
this.refactoring.nameTrail, this.refactoring.names,
|
||||||
this.refactoring.container, similarContainer);
|
this.refactoring.container, similarContainer);
|
||||||
ASTRewrite rewrite = collector.rewriterForTranslationUnit(stmtToReplace.get(0)
|
ASTRewrite rewrite =
|
||||||
.getTranslationUnit());
|
collector.rewriterForTranslationUnit(stmtToReplace.get(0).getTranslationUnit());
|
||||||
TextEditGroup editGroup = new TextEditGroup(Messages.SimilarFinderVisitor_replaceDuplicateCode);
|
TextEditGroup editGroup = new TextEditGroup(Messages.SimilarFinderVisitor_replaceDuplicateCode);
|
||||||
rewrite.replace(stmtToReplace.get(0), call, editGroup);
|
rewrite.replace(stmtToReplace.get(0), call, editGroup);
|
||||||
if (stmtToReplace.size() > 1) {
|
if (stmtToReplace.size() > 1) {
|
||||||
|
@ -112,16 +107,13 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
} else {
|
} else {
|
||||||
clear();
|
clear();
|
||||||
return super.visit(stmt);
|
return super.visit(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInSelection(IASTStatement stmt) {
|
private boolean isInSelection(IASTStatement stmt) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2008 IBM Corporation and others.
|
* Copyright (c) 2000, 2011 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
|
||||||
|
@ -71,14 +71,12 @@ public abstract class AbstractWizardDropDownAction extends Action implements IMe
|
||||||
|
|
||||||
public Menu getMenu(Control parent) {
|
public Menu getMenu(Control parent) {
|
||||||
synchronized(fLock) {
|
synchronized(fLock) {
|
||||||
if (fMenu == null) {
|
|
||||||
fMenu= new Menu(parent);
|
fMenu= new Menu(parent);
|
||||||
IAction[] actions= getActions();
|
IAction[] actions= getActions();
|
||||||
for (int i= 0; i < actions.length; i++) {
|
for (int i= 0; i < actions.length; i++) {
|
||||||
ActionContributionItem item= new ActionContributionItem(actions[i]);
|
ActionContributionItem item= new ActionContributionItem(actions[i]);
|
||||||
item.fill(fMenu, -1);
|
item.fill(fMenu, -1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return fMenu;
|
return fMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,13 +108,12 @@ public abstract class AbstractWizardDropDownAction extends Action implements IMe
|
||||||
|
|
||||||
private IAction[] getActions() {
|
private IAction[] getActions() {
|
||||||
synchronized(fLock) {
|
synchronized(fLock) {
|
||||||
if (fActions == null) {
|
|
||||||
fActions = getWizardActions();
|
fActions = getWizardActions();
|
||||||
if (fActions == null)
|
if (fActions == null)
|
||||||
fActions = NO_ACTIONS;
|
fActions = NO_ACTIONS;
|
||||||
|
|
||||||
//TODO provide a way to sort the actions
|
//TODO provide a way to sort the actions
|
||||||
}
|
|
||||||
return fActions;
|
return fActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue