1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 305980: [C++0x] Inline namespaces

This commit is contained in:
Markus Schorn 2010-08-12 14:50:50 +00:00
parent 4be5e0c3eb
commit 8311576fa8
47 changed files with 1341 additions and 208 deletions

View file

@ -8683,4 +8683,107 @@ public class AST2CPPTests extends AST2BaseTest {
fb= bh.assertNonProblem("g()", 1);
assertTrue(fb.isDeleted());
}
// namespace ns {
// struct S {};
// }
//
// namespace m {
// void h(ns::S);
// }
//
// namespace ns {
// inline namespace a {
// using namespace m;
// struct A {};
// void fa(S s);
// }
// inline namespace b {
// struct B {};
// void fb(S s);
// void gb(a::A);
// }
// void f(S s);
// void g(a::A);
// void g(b::B);
// }
//
// ns::S s;
// ns::A a0;
// ns::B b0;
// ns::a::A a;
// ns::b::B b;
//
// void ok() {
// fa(s); fb(s); f(s);
// ns::h(s);
// g(a);
// gb(a);
// }
public void testInlineNamespace_305980a() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code);
}
// namespace ns {
// inline namespace m {
// int a;
// }
// }
// void test() {
// ns::m::a;
// ns::a;
// }
public void testInlineNamespace_305980b() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code);
}
// namespace out {
// void f(int);
// }
// namespace out2 {
// void g(int);
// }
// using namespace out;
// inline namespace in {
// inline namespace in2 {
// void f(char);
// using namespace out2;
// }
// }
// void test() {
// ::f(1);
// ::g(1);
// }
public void testInlineNamespace_305980c() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction fo= bh.assertNonProblem("f(int)", 1);
IFunction g= bh.assertNonProblem("g(int)", 1);
IFunction fi= bh.assertNonProblem("f(char)", 1);
IFunction ref= bh.assertNonProblem("f(1)", 1);
assertSame(fi, ref);
ref= bh.assertNonProblem("g(1)", 1);
assertSame(g, ref);
}
// namespace ns {
// inline namespace m {
// void f();
// }
// }
// void ns::f() {}
public void testInlineNamespace_305980d() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction f1= bh.assertNonProblem("f();", 1);
IFunction f2= bh.assertNonProblem("f() {", 1);
assertSame(f1, f2);
}
}

View file

@ -63,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
@ -5009,4 +5010,40 @@ public class AST2TemplateTests extends AST2BaseTest {
tu = validateCopy(tu);
assertEquals(1, tu.getDeclarations().length);
}
// namespace N {
// inline namespace M {
// template<class T> void f(T&) { }
//
// }
// template void f<char>(char&);
// template<> void f<short>(short&) {}
// }
//
// template void N::f<int>(int&);
// template<> void N::f<long>(long&) {}
public void testInlineNamespaces_305980() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPFunctionTemplate ft= bh.assertNonProblem("f(T&)", 1);
ICPPNamespace M= (ICPPNamespace) ft.getOwner();
ICPPTemplateInstance inst;
inst= bh.assertNonProblem("f<char>", 0);
assertSame(ft, inst.getTemplateDefinition());
assertSame(M, inst.getOwner());
inst= bh.assertNonProblem("f<short>", 0);
assertSame(ft, inst.getTemplateDefinition());
assertSame(M, inst.getOwner());
inst= bh.assertNonProblem("f<int>", 0);
assertSame(ft, inst.getTemplateDefinition());
assertSame(M, inst.getOwner());
inst= bh.assertNonProblem("f<long>", 0);
assertSame(ft, inst.getTemplateDefinition());
assertSame(M, inst.getOwner());
}
}

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFileSet;
import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@ -148,4 +149,8 @@ public class EmptyIndexFragment implements IIndexFragment {
public void clearResultCache() {
}
public IIndexScope[] getInlineNamespaces() {
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
}

View file

@ -19,6 +19,7 @@ import java.util.Set;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
@ -1408,6 +1409,185 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
getBindingFromASTName("m(a)", 1, IFunction.class);
}
// namespace ns {
// struct S {};
// }
// namespace m {
// void h(ns::S);
// }
// namespace ns {
// inline namespace a {
// using namespace m;
// struct A {};
// void fa(S s);
// }
// inline namespace b {
// struct B {};
// void fb(S s);
// void gb(a::A);
// }
// void f(S s);
// void g(a::A);
// void g(b::B);
// }
// ns::S s;
// ns::A a0;
// ns::B b0;
// ns::a::A a;
// ns::b::B b;
//
// void ok() {
// fa(s); fb(s); f(s);
// g(a);
// gb(a);
// }
public void testInlineNamespace_305980a() throws Exception {
IFunction f= getBindingFromASTName("fa(s)", 2);
f= getBindingFromASTName("fb(s)", 2);
f= getBindingFromASTName("f(s)", 1);
f= getBindingFromASTName("g(a)", 1);
f= getBindingFromASTName("gb(a)", 2);
}
// namespace ns {
// struct S {};
// }
// namespace m {
// void h(ns::S);
// }
// namespace ns {
// inline namespace a {
// using namespace m;
// struct A {};
// void fa(S s);
// }
// inline namespace b {
// struct B {};
// void fb(S s);
// void gb(a::A);
// }
// void f(S s);
// void g(a::A);
// void g(b::B);
// }
// namespace ns {}
// namespace m {}
// ns::S s;
// ns::A a0;
// ns::B b0;
// ns::a::A a;
// ns::b::B b;
//
// void ok() {
// fa(s); fb(s); f(s);
// g(a);
// gb(a);
// }
public void testInlineNamespace_305980am() throws Exception {
IFunction f= getBindingFromASTName("fa(s)", 2);
f= getBindingFromASTName("fb(s)", 2);
f= getBindingFromASTName("f(s)", 1);
f= getBindingFromASTName("g(a)", 1);
f= getBindingFromASTName("gb(a)", 2);
}
// namespace ns {
// inline namespace m {
// int a;
// }
// }
// void test() {
// ns::m::a; //1
// ns::a; //2
// }
public void testInlineNamespace_305980b() throws Exception {
IVariable v1= getBindingFromASTName("a; //1", 1);
IVariable v2= getBindingFromASTName("a; //2", 1);
assertEquals(v1, v2);
}
// namespace ns {
// inline namespace m {
// int a;
// }
// }
// namespace ns {
// void test() {
// m::a; //1
// a; //2
// }
// }
// void test() {
// ns::m::a; //3
// ns::a; //4
// }
public void testInlineNamespace_305980bm() throws Exception {
IVariable v1= getBindingFromASTName("a; //1", 1);
IVariable v2= getBindingFromASTName("a; //2", 1);
IVariable v3= getBindingFromASTName("a; //3", 1);
IVariable v4= getBindingFromASTName("a; //4", 1);
assertEquals(v1, v2);
assertEquals(v2, v3);
assertEquals(v3, v4);
}
// namespace out {
// void f(int);
// }
// namespace out2 {
// void g(int);
// }
// using namespace out;
// inline namespace in {
// inline namespace in2 {
// void f(char);
// using namespace out2;
// }
// }
// #include "header.h"
// void test() {
// ::f(1);
// ::g(1);
// }
public void testInlineNamespace_305980c() throws Exception {
IFunction ref= getBindingFromASTName("f(1)", 1);
assertEquals("void (char)", ASTTypeUtil.getType(ref.getType()));
getBindingFromASTName("g(1)", 1);
}
// namespace out {
// void f(int);
// }
// namespace out2 {
// void g(int);
// }
// using namespace out;
// inline namespace in {
// inline namespace in2 {
// void f(char);
// using namespace out2;
// }
// }
// #include "header.h"
// namespace out {}
// namespace out2 {}
// namespace in {}
// void test() {
// ::f(1);
// ::g(1);
// }
public void testInlineNamespace_305980cm() throws Exception {
IFunction ref= getBindingFromASTName("f(1)", 1);
assertEquals("void (char)", ASTTypeUtil.getType(ref.getType()));
getBindingFromASTName("g(1)", 1);
}
/* CPP assertion helpers */
/* ##################################################################### */

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
@ -1292,4 +1293,50 @@ public class IndexUpdateTests extends IndexTestBase {
}
assertEquals(id1, id2);
}
// namespace ns {
// namespace m {}
// }
// inline namespace ns {
// inline namespace m {}
// }
// namespace ns {
// namespace m {}
// }
public void testInlineNamespaces_305980() throws Exception {
setupFile(3, true);
fIndex.acquireReadLock();
try {
final ICPPNamespace ns = (ICPPNamespace) findBinding("ns");
assertFalse(ns.isInline());
final ICPPNamespace m = (ICPPNamespace) findBinding("ns::m");
assertFalse(ns.isInline());
} finally {
fIndex.releaseReadLock();
}
updateFile();
fIndex.acquireReadLock();
try {
final ICPPNamespace ns = (ICPPNamespace) findBinding("ns");
assertTrue(ns.isInline());
final ICPPNamespace m = (ICPPNamespace) findBinding("ns::m");
assertTrue(ns.isInline());
} finally {
fIndex.releaseReadLock();
}
updateFile();
fIndex.acquireReadLock();
try {
final ICPPNamespace ns = (ICPPNamespace) findBinding("ns");
assertFalse(ns.isInline());
final ICPPNamespace m = (ICPPNamespace) findBinding("ns::m");
assertFalse(ns.isInline());
} finally {
fIndex.releaseReadLock();
}
}
}

View file

@ -252,7 +252,15 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IAdaptabl
* @since 5.1
*/
IIndexFileSet getIndexFileSet();
/**
* Return the set of files in the index that are superseded by this AST,
* or <code>null</code> if not available.
* Applies only, if AST was created with an index.
* @since 5.3
*/
IIndexFileSet getASTFileSet();
/**
* In case the AST was created in a way that supports comment parsing,
* all comments of the translation unit are returned. Otherwise an

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -54,6 +55,18 @@ public interface ICPPASTNamespaceDefinition extends IASTDeclaration, IASTNameOwn
*/
public void setName(IASTName name);
/**
* Specify whether the namespace definition is inline.
* @since 5.3
*/
public void setIsInline(boolean isInline);
/**
* Returns whether this namespace definition is inline.
* @since 5.3
*/
public boolean isInline();
/**
* A translation unit contains an ordered sequence of declarations.
*

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -32,4 +33,10 @@ public interface ICPPNamespace extends ICPPBinding {
* @throws DOMException
*/
public IBinding[] getMemberBindings() throws DOMException;
/**
* Returns whether this is an inline namespace.
* @since 5.3
*/
public boolean isInline();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -11,7 +11,6 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
/**
* A namespace scope is either a block-scope or a namespace-scope or global scope.
@ -21,14 +20,25 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
*/
public interface ICPPNamespaceScope extends ICPPScope {
/**
* @since 5.3
*/
ICPPNamespaceScope[] EMPTY_NAMESPACE_SCOPE_ARRAY = {};
/**
* Add a directive that nominates another namespace to this scope.
*/
public void addUsingDirective(ICPPUsingDirective usingDirective) throws DOMException;
public void addUsingDirective(ICPPUsingDirective usingDirective);
/**
* Get the using directives that have been added to this scope to nominate other
* namespaces during lookup.
*/
public ICPPUsingDirective[] getUsingDirectives() throws DOMException;
public ICPPUsingDirective[] getUsingDirectives();
/**
* Returns the inline namespaces that are members of this scope.
* @since 5.3
*/
public ICPPNamespaceScope[] getInlineNamespaces();
}

View file

@ -17,6 +17,7 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@ -393,4 +394,11 @@ public interface IIndex {
* linkages, or in multiple fragments only one of the files will be returned.
*/
public IIndexFile[] getAllFiles() throws CoreException;
/**
* Returns the global inline c++ namespaces.
* @throws CoreException
* @since 5.3
*/
public IScope[] getInlineNamespaces() throws CoreException;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -23,7 +23,7 @@ import org.eclipse.core.runtime.CoreException;
*/
public interface IIndexFileSet {
IIndexFileSet EMPTY = new IndexFileSet();
/**
* Returns whether the given file is part of this file set.
* @since 5.1
@ -43,6 +43,12 @@ public interface IIndexFileSet {
*/
IBinding[] filterFileLocalBindings(IBinding[] bindings);
/**
* Returns an index file set with the inverse meaning.
* @since 5.3
*/
IIndexFileSet invert();
/**
* Adds a file to this set.
* @noreference This method is not intended to be referenced by clients.

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -9,7 +9,6 @@
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.core.index;
import org.eclipse.cdt.core.dom.IName;
@ -72,6 +71,12 @@ public interface IIndexName extends IName {
*/
public boolean couldBePolymorphicMethodCall() throws CoreException;
/**
* Returns whether this name specifies an inline namespace.
* @since 5.3
*/
public boolean isInlineNamespaceDefinition() throws CoreException;
/**
* Returns whether this name is a read-reference to a variable or field.
* The notion of a read-reference may not strictly reflect what your compiler generates,

View file

@ -36,9 +36,11 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.index.IndexBasedFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
import org.eclipse.core.runtime.CoreException;
@ -61,6 +63,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
private IIndex fIndex;
private boolean fIsHeader= true;
private IIndexFileSet fIndexFileSet;
private IIndexFileSet fASTFileSet;
private INodeFactory fNodeFactory;
private boolean fForContentAssist;
@ -300,6 +303,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
this.fIndex = index;
if (index != null) {
fIndexFileSet= index.createFileSet();
fASTFileSet= index.createFileSet();
}
}
@ -364,6 +368,26 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
return fIndexFileSet;
}
public void replacingFile(InternalFileContentProvider provider, InternalFileContent fc) {
if (fASTFileSet != null) {
if (provider instanceof IndexBasedFileContentProvider) {
try {
IIndexFile file= ((IndexBasedFileContentProvider) provider).findIndexFile(fc);
if (file != null) {
fASTFileSet.add(file);
}
} catch (CoreException e) {
// Ignore, tracking of replaced files fails.
}
}
}
}
public final IIndexFileSet getASTFileSet() {
return fASTFileSet;
}
/*
* (non-Javadoc)
*

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -35,6 +35,7 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
private IASTDeclaration[] fAllDeclarations;
private IASTDeclaration[] fActiveDeclarations;
private int fLastDeclaration=-1;
private boolean fIsInline;
public CPPASTNamespaceDefinition() {
}
@ -45,6 +46,7 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
public CPPASTNamespaceDefinition copy() {
CPPASTNamespaceDefinition copy = new CPPASTNamespaceDefinition(fName == null ? null : fName.copy());
copy.fIsInline= fIsInline;
for(IASTDeclaration declaration : getDeclarations())
copy.addDeclaration(declaration == null ? null : declaration.copy());
copy.setOffsetAndLength(this);
@ -64,6 +66,15 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
}
}
public void setIsInline(boolean isInline) {
assertNotFrozen();
fIsInline= isInline;
}
public boolean isInline() {
return fIsInline;
}
public final void addDeclaration(IASTDeclaration decl) {
if (decl != null) {
decl.setParent(this);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -66,6 +66,9 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public boolean isGloballyQualified() throws DOMException {
throw new DOMException(this);
}
public boolean isInline() {
return false;
}
}
private static final char[] EMPTY_CHAR_ARRAY = {};
@ -205,8 +208,8 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
namespaceDef.getTranslationUnit().accept(collector);
namespaceDefinitions = collector.getNamespaces();
for (int i = 0; i < namespaceDefinitions.length; i++) {
namespaceDefinitions[i].setBinding(this);
for (IASTName namespaceDefinition : namespaceDefinitions) {
namespaceDefinition.setBinding(this);
}
}
@ -327,12 +330,12 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public IBinding[] getMemberBindings() {
if (namespaceDefinitions != null) {
NamespaceMemberCollector collector = new NamespaceMemberCollector();
for (int i = 0; i < namespaceDefinitions.length; i++) {
IASTNode parent = namespaceDefinitions[i].getParent();
for (IASTName namespaceDefinition : namespaceDefinitions) {
IASTNode parent = namespaceDefinition.getParent();
if (parent instanceof ICPPASTNamespaceDefinition) {
IASTDeclaration[] decls = ((ICPPASTNamespaceDefinition)parent).getDeclarations();
for (int j = 0; j < decls.length; j++) {
decls[j].accept(collector);
for (IASTDeclaration decl : decls) {
decl.accept(collector);
}
}
}
@ -341,6 +344,14 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
return IBinding.EMPTY_BINDING_ARRAY;
}
public boolean isInline() {
final ICPPNamespaceScope nsScope = getNamespaceScope();
if (nsScope instanceof CPPNamespaceScope) {
return ((CPPNamespaceScope) nsScope).isInlineNamepace();
}
return false;
}
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}

View file

@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 IBM Corporation and others.
* Copyright (c) 2005, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -25,17 +25,12 @@ import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject;
/**
* @author aniefer
*/
public class CPPNamespaceAlias extends PlatformObject implements ICPPNamespaceAlias, ICPPInternalBinding {
private ICPPNamespace namespace;
private IASTName alias;
/**
*
*/
public CPPNamespaceAlias( IASTName aliasName, ICPPNamespace namespace ) {
public CPPNamespaceAlias(IASTName aliasName, ICPPNamespace namespace) {
super();
this.namespace = namespace;
this.alias = aliasName;
@ -104,4 +99,8 @@ public class CPPNamespaceAlias extends PlatformObject implements ICPPNamespaceAl
public IBinding getOwner() throws DOMException {
return CPPVisitor.findDeclarationOwner(alias, false);
}
public boolean isInline() {
return false;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -11,6 +11,12 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
@ -21,19 +27,32 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScopeMapper.InlineNamespaceDirective;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.core.runtime.CoreException;
/**
* Implementation of namespace scopes, including global scope.
*/
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
ICPPUsingDirective[] usings = null;
public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespaceScope {
private static final ICPPInternalNamespaceScope[] NO_NAMESPACE_SCOPES = new ICPPInternalNamespaceScope[0];
private List<ICPPUsingDirective> fUsingDirectives = null;
private boolean fIsInline;
private boolean fIsInlineInitialized;
private ICPPNamespaceScope[] fEnclosingNamespaceSet;
private List<ICPPASTNamespaceDefinition> fInlineNamespaceDefinitions;
private ICPPInternalNamespaceScope[] fInlineNamespaces;
public CPPNamespaceScope( IASTNode physicalNode ) {
super( physicalNode );
public CPPNamespaceScope(IASTNode physicalNode) {
super(physicalNode);
}
public EScopeKind getKind() {
@ -46,15 +65,30 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives()
*/
public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
public ICPPUsingDirective[] getUsingDirectives() {
initUsingDirectives();
populateCache();
return (ICPPUsingDirective[]) ArrayUtil.trim( ICPPUsingDirective.class, usings, true );
return fUsingDirectives.toArray(new ICPPUsingDirective[fUsingDirectives.size()]);
}
private void initUsingDirectives() {
if (fUsingDirectives == null) {
fUsingDirectives= new ArrayList<ICPPUsingDirective>(1);
// Insert a using directive for every inline namespace found in the index
for(ICPPInternalNamespaceScope inline: getIndexInlineNamespaces()) {
if (!(inline instanceof CPPNamespaceScope)) {
fUsingDirectives.add(new InlineNamespaceDirective(this, inline));
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#addUsingDirective(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective)
*/
public void addUsingDirective(ICPPUsingDirective directive) {
usings = (ICPPUsingDirective[]) ArrayUtil.append( ICPPUsingDirective.class, usings, directive );
initUsingDirectives();
fUsingDirectives.add(directive);
}
/* (non-Javadoc)
@ -109,4 +143,165 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
getPhysicalNode().accept(visitor);
return result[0];
}
public boolean isInlineNamepace() {
if (!fIsInlineInitialized) {
fIsInline= computeIsInline();
fIsInlineInitialized= true;
}
return fIsInline;
}
public boolean computeIsInline() {
final IASTNode node= getPhysicalNode();
if (!(node instanceof ICPPASTNamespaceDefinition)) {
return false;
}
if (((ICPPASTNamespaceDefinition) node).isInline())
return true;
IASTTranslationUnit tu= node.getTranslationUnit();
if (tu != null) {
final IIndex index= tu.getIndex();
IIndexFileSet fileSet= tu.getASTFileSet();
if (index != null && fileSet != null) {
fileSet= fileSet.invert();
ICPPNamespace nsBinding = getNamespaceIndexBinding(index);
if (nsBinding != null && nsBinding.isInline()) {
try {
IIndexName[] names = index.findDefinitions(nsBinding);
for (IIndexName name : names) {
if (name.isInlineNamespaceDefinition() && fileSet.contains(name.getFile())) {
return true;
}
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
}
return false;
}
public ICPPNamespaceScope[] getEnclosingNamespaceSet() {
if (fEnclosingNamespaceSet == null) {
return fEnclosingNamespaceSet= computeEnclosingNamespaceSet(this);
}
return fEnclosingNamespaceSet;
}
public ICPPInternalNamespaceScope[] getInlineNamespaces() {
if (getKind() == EScopeKind.eLocal)
return NO_NAMESPACE_SCOPES;
if (fInlineNamespaces == null) {
fInlineNamespaces= computeInlineNamespaces();
}
return fInlineNamespaces;
}
ICPPInternalNamespaceScope[] computeInlineNamespaces() {
populateCache();
Set<ICPPInternalNamespaceScope> result= null;
if (fInlineNamespaceDefinitions != null) {
result= new HashSet<ICPPInternalNamespaceScope>(fInlineNamespaceDefinitions.size());
for (ICPPASTNamespaceDefinition nsdef : fInlineNamespaceDefinitions) {
final IScope scope = nsdef.getScope();
if (scope instanceof ICPPInternalNamespaceScope) {
result.add((ICPPInternalNamespaceScope) scope);
}
}
}
for (ICPPInternalNamespaceScope inline : getIndexInlineNamespaces()) {
if (result == null)
result = new HashSet<ICPPInternalNamespaceScope>();
result.add(inline);
}
if (result == null) {
return NO_NAMESPACE_SCOPES;
}
return result.toArray(new ICPPInternalNamespaceScope[result.size()]);
}
private ICPPInternalNamespaceScope[] getIndexInlineNamespaces() {
IASTTranslationUnit tu= getPhysicalNode().getTranslationUnit();
if (tu instanceof CPPASTTranslationUnit) {
CPPASTTranslationUnit cpptu= (CPPASTTranslationUnit) tu;
IIndex index= tu.getIndex();
if (index != null) {
IScope[] inlineScopes= null;
ICPPNamespace namespace= getNamespaceIndexBinding(index);
try {
if (namespace != null) {
ICPPNamespaceScope scope = namespace.getNamespaceScope();
inlineScopes= scope.getInlineNamespaces();
} else if (getKind() == EScopeKind.eGlobal) {
inlineScopes= index.getInlineNamespaces();
}
} catch (DOMException e) {
} catch (CoreException e) {
}
if (inlineScopes != null) {
List<ICPPInternalNamespaceScope> result= null;
for (IScope scope : inlineScopes) {
if (scope instanceof IIndexScope) {
scope= cpptu.mapToASTScope((IIndexScope) scope);
}
if (scope instanceof ICPPInternalNamespaceScope) {
if (result == null) {
result= new ArrayList<ICPPInternalNamespaceScope>();
}
result.add((ICPPInternalNamespaceScope) scope);
}
}
if (result != null) {
return result.toArray(new ICPPInternalNamespaceScope[result.size()]);
}
}
}
}
return NO_NAMESPACE_SCOPES;
}
/**
* Called while populating scope.
*/
public void addInlineNamespace(ICPPASTNamespaceDefinition nsDef) {
if (fInlineNamespaceDefinitions == null) {
fInlineNamespaceDefinitions= new ArrayList<ICPPASTNamespaceDefinition>();
}
fInlineNamespaceDefinitions.add(nsDef);
}
public static ICPPNamespaceScope[] computeEnclosingNamespaceSet(ICPPInternalNamespaceScope nsScope) {
if (nsScope.isInlineNamepace()) {
try {
IScope parent= nsScope.getParent();
if (parent instanceof ICPPInternalNamespaceScope) {
return ((ICPPInternalNamespaceScope) parent).getEnclosingNamespaceSet();
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
Set<ICPPInternalNamespaceScope> result= new HashSet<ICPPInternalNamespaceScope>();
result.add(nsScope);
addInlineNamespaces(nsScope, result);
return result.toArray(new ICPPNamespaceScope[result.size()]);
}
private static void addInlineNamespaces(ICPPInternalNamespaceScope nsScope, Set<ICPPInternalNamespaceScope> result) {
ICPPInternalNamespaceScope[] inlineNss = nsScope.getInlineNamespaces();
for (ICPPInternalNamespaceScope inlineNs : inlineNss) {
if (result.add(inlineNs)) {
addInlineNamespaces(inlineNs, result);
}
}
}
}

View file

@ -164,8 +164,8 @@ abstract public class CPPScope implements ICPPASTInternalScope {
} catch (CoreException e) {
CCorePlugin.log(e);
}
} else if (physicalNode instanceof ICPPASTNamespaceDefinition) {
ICPPNamespace nsbinding= getNamespaceIndexBinding((ICPPASTNamespaceDefinition)physicalNode, index);
} else {
ICPPNamespace nsbinding= getNamespaceIndexBinding(index);
if (nsbinding != null) {
return nsbinding.getNamespaceScope().getBinding(name, forceResolve, fileSet);
}
@ -175,14 +175,17 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return binding;
}
private ICPPNamespace getNamespaceIndexBinding(ICPPASTNamespaceDefinition nsdef, IIndex index) {
protected ICPPNamespace getNamespaceIndexBinding(IIndex index) {
if (fIndexNamespace == UNINITIALIZED) {
fIndexNamespace= null;
IASTName nsname = nsdef.getName();
IBinding nsbinding= nsname.resolveBinding();
if (nsbinding != null) {
fIndexNamespace= (ICPPNamespace) index.adaptBinding(nsbinding);
}
IASTNode node= getPhysicalNode();
if (node instanceof ICPPASTNamespaceDefinition) {
IASTName nsname = ((ICPPASTNamespaceDefinition) node).getName();
IBinding nsbinding= nsname.resolveBinding();
if (nsbinding != null) {
fIndexNamespace= (ICPPNamespace) index.adaptBinding(nsbinding);
}
}
}
return fIndexNamespace;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -48,15 +48,40 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
* scopes that can be reopened, i.e. namespaces.
*/
public class CPPScopeMapper {
/**
* Used for implicit inline directives for inline namespaces found in the index.
*/
public static final class InlineNamespaceDirective implements ICPPUsingDirective {
private final ICPPInternalNamespaceScope fContainer;
private final ICPPInternalNamespaceScope fNominated;
public InlineNamespaceDirective(ICPPInternalNamespaceScope container, ICPPInternalNamespaceScope inline) {
fContainer= container;
fNominated= inline;
}
public IScope getContainingScope() {
return fContainer;
}
public ICPPNamespaceScope getNominatedScope() throws DOMException {
return fNominated;
}
public int getPointOfDeclaration() {
return 0;
}
}
/**
* Wrapper for namespace-scopes from the index.
*/
private class NamespaceScopeWrapper implements ICPPNamespaceScope {
private class NamespaceScopeWrapper implements ICPPInternalNamespaceScope {
private final ICPPNamespaceScope fScope;
private ArrayList<ICPPUsingDirective> fUsingDirectives;
private ICPPNamespaceScope[] fEnclosingNamespaceSet;
public NamespaceScopeWrapper(ICPPNamespaceScope scope) {
fScope= scope;
assert fScope instanceof IIndexScope;
}
public EScopeKind getKind() {
@ -90,19 +115,50 @@ public class CPPScopeMapper {
return fScope.getScopeName();
}
public void addUsingDirective(ICPPUsingDirective usingDirective) throws DOMException {
if (fUsingDirectives == null) {
fUsingDirectives= new ArrayList<ICPPUsingDirective>(1);
}
public void addUsingDirective(ICPPUsingDirective usingDirective) {
initUsingDirectives();
fUsingDirectives.add(usingDirective);
}
public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
private void initUsingDirectives() {
if (fUsingDirectives == null) {
return ICPPUsingDirective.EMPTY_ARRAY;
fUsingDirectives= new ArrayList<ICPPUsingDirective>(1);
// Insert a using directive for every inline namespace
for (ICPPInternalNamespaceScope inline: getInlineNamespaces()) {
fUsingDirectives.add(new InlineNamespaceDirective(this, inline));
}
}
}
public ICPPUsingDirective[] getUsingDirectives() {
initUsingDirectives();
return fUsingDirectives.toArray(new ICPPUsingDirective[fUsingDirectives.size()]);
}
public ICPPNamespaceScope[] getEnclosingNamespaceSet() {
if (fEnclosingNamespaceSet == null)
return fEnclosingNamespaceSet= CPPNamespaceScope.computeEnclosingNamespaceSet(this);
return fEnclosingNamespaceSet;
}
public boolean isInlineNamepace() {
IIndexBinding binding = ((IIndexScope) fScope).getScopeBinding();
if (binding instanceof ICPPNamespace && ((ICPPNamespace) binding).isInline())
return true;
return false;
}
public ICPPInternalNamespaceScope[] getInlineNamespaces() {
// Obtain the inline namespaces from the index and map them to the ast
ICPPNamespaceScope[] pre = fScope.getInlineNamespaces();
ICPPInternalNamespaceScope[] result= new ICPPInternalNamespaceScope[pre.length];
for (int i = 0; i < result.length; i++) {
result[i]= (ICPPInternalNamespaceScope) mapToASTScope((IIndexScope) pre[i]);
}
return result;
}
}
/**

View file

@ -1810,6 +1810,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.t_inline:
if (supportExtendedTemplateSyntax && LT(2) == IToken.t_template)
return templateDeclaration(option);
if (LT(2) == IToken.t_namespace) {
return namespaceDefinitionOrAlias();
}
break;
case IToken.tSEMI:
IToken t= consume();
@ -1858,8 +1861,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* request a backtrack
*/
protected IASTDeclaration namespaceDefinitionOrAlias() throws BacktrackException, EndOfFileException {
final int offset= consume().getOffset();
final int offset= LA().getOffset();
int endOffset;
boolean isInline= false;
if (LT(1) == IToken.t_inline) {
consume();
isInline= true;
}
consume(IToken.t_namespace);
// optional name
IASTName name = null;
@ -1875,6 +1885,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tLBRACE) {
ICPPASTNamespaceDefinition ns = nodeFactory.newNamespaceDefinition(name);
ns.setIsInline(isInline);
declarationListInBraces(ns, offset, DeclarationOptions.GLOBAL);
return ns;
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
/**
* For namespace scopes from the AST or mapped index namespace scopes.
*/
public interface ICPPInternalNamespaceScope extends ICPPNamespaceScope {
/**
* Returns the enclosing namespace set (7.3.1-9)
*/
public ICPPNamespaceScope[] getEnclosingNamespaceSet();
/**
* Returns whether this namespace scope is inline.
*/
public boolean isInlineNamepace();
/**
* Returns the inline namespace scopes mapped back to the AST.
*/
public ICPPInternalNamespaceScope[] getInlineNamespaces();
}

View file

@ -168,9 +168,6 @@ class BaseClassLookup {
infoMap.put(baseClassScope, result);
try {
IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, fileSet, data);
if (data.typesOnly) {
CPPSemantics.removeObjects(members);
}
if (members != null && members.length > 0 && members[0] != null) {
if (data.prefixLookup) {
matches= members;

View file

@ -20,6 +20,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -175,6 +176,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespaceScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
@ -188,6 +190,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalNamespaceScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
@ -533,9 +536,8 @@ public class CPPSemantics {
private static void doKoenigLookup(LookupData data) throws DOMException {
data.ignoreUsingDirectives = true;
data.forceQualified = true;
ObjectSet<ICPPScope> associated = getAssociatedScopes(data);
for (int i = 0; i < associated.size(); i++) {
final ICPPScope scope = associated.keyAt(i);
Set<ICPPNamespaceScope> associated = getAssociatedScopes(data);
for (ICPPNamespaceScope scope : associated) {
if (!data.visited.containsKey(scope)) {
lookup(data, scope);
}
@ -637,12 +639,12 @@ public class CPPSemantics {
return data;
}
static private ObjectSet<ICPPScope> getAssociatedScopes(LookupData data) {
static private Set<ICPPNamespaceScope> getAssociatedScopes(LookupData data) {
if (!data.hasFunctionArguments())
return ObjectSet.emptySet();
return Collections.emptySet();
IType[] ps = data.getFunctionArgumentTypes();
ObjectSet<ICPPScope> namespaces = new ObjectSet<ICPPScope>(2);
Set<ICPPNamespaceScope> namespaces = new HashSet<ICPPNamespaceScope>(2);
ObjectSet<ICPPClassType> classes = new ObjectSet<ICPPClassType>(2);
for (IType p : ps) {
p = getUltimateType(p, true);
@ -654,16 +656,14 @@ public class CPPSemantics {
return namespaces;
}
static private void getAssociatedScopes(IType t, ObjectSet<ICPPScope> namespaces,
static private void getAssociatedScopes(IType t, Set<ICPPNamespaceScope> namespaces,
ObjectSet<ICPPClassType> classes, CPPASTTranslationUnit tu) throws DOMException {
// 3.4.2-2
if (t instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) t;
if (!classes.containsKey(ct)) {
classes.put(ct);
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
if (scope != null)
namespaces.put(scope);
getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces);
ICPPClassType cls = (ICPPClassType) t;
ICPPBase[] bases = cls.getBases();
@ -676,9 +676,7 @@ public class CPPSemantics {
}
}
} else if (t instanceof IEnumeration) {
ICPPScope scope = getContainingNamespaceScope((IBinding) t, tu);
if (scope!=null)
namespaces.put(scope);
getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces);
} else if (t instanceof IFunctionType) {
IFunctionType ft = (IFunctionType) t;
@ -693,16 +691,32 @@ public class CPPSemantics {
}
return;
}
static private ICPPNamespaceScope getContainingNamespaceScope(IBinding binding,
CPPASTTranslationUnit tu) throws DOMException {
if (binding == null) return null;
if (binding == null)
return null;
IScope scope = binding.getScope();
if (scope instanceof IIndexScope) {
scope= tu.mapToASTScope((IIndexScope) scope);
}
while (scope != null && !(scope instanceof ICPPNamespaceScope)) {
scope = getParentScope(scope, tu);
}
return (ICPPNamespaceScope) scope;
}
public static void getAssociatedNamespaceScopes(ICPPNamespaceScope scope, Set<ICPPNamespaceScope> namespaces) {
if (scope == null || !namespaces.add(scope))
return;
if (scope instanceof ICPPInternalNamespaceScope) {
final ICPPInternalNamespaceScope internalScope = (ICPPInternalNamespaceScope) scope;
for (ICPPNamespaceScope mem : internalScope.getEnclosingNamespaceSet()) {
namespaces.add(mem);
}
}
}
static ICPPScope getLookupScope(IASTName name, LookupData data) throws DOMException {
IASTNode parent = name.getParent();
@ -875,56 +889,44 @@ public class CPPSemantics {
}
if (!data.usingDirectivesOnly && !(data.ignoreMembers && scope instanceof ICPPClassScope)) {
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
if (data.typesOnly) {
removeObjects(bindings);
}
mergeResults(data, bindings, true);
mergeResults(data, getBindingsFromScope(scope, fileSet, data), true);
// store using-directives found in this block or namespace for later use.
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
// Nominate using-directives found in this block or namespace.
if (scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
if (!(blockScope instanceof ICPPBlockScope)) {
data.visited.put(blockScope); // namespace has been searched.
if (data.tu != null) {
data.tu.handleAdditionalDirectives(blockScope);
}
if (data.qualified() && blockScope.getKind() != EScopeKind.eLocal) {
lookupInlineNamespaces(data, fileSet, blockScope);
}
ICPPUsingDirective[] uds= blockScope.getUsingDirectives();
if (uds != null && uds.length > 0) {
HashSet<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>();
for (final ICPPUsingDirective ud : uds) {
if (declaredBefore(ud, data.astName, false)) {
storeUsingDirective(data, blockScope, ud, handled);
}
}
if (data.contentAssist || !data.hasResults() || !data.qualified()) {
// Nominate namespaces
nominateNamespaces(data, blockScope);
}
}
}
// lookup in nominated namespaces
// Lookup in nominated namespaces
if (!data.ignoreUsingDirectives && scope instanceof ICPPNamespaceScope && !(scope instanceof ICPPBlockScope)) {
if (!data.hasResults() || !data.qualified() || data.contentAssist) {
lookupInNominated(data, (ICPPNamespaceScope) scope);
lookupInNominated(data, fileSet, (ICPPNamespaceScope) scope);
}
}
if ((!data.contentAssist && (data.problem != null || data.hasResults())) ||
(friendInLocalClass && !(scope instanceof ICPPClassScope))) {
if (friendInLocalClass && !(scope instanceof ICPPClassScope))
return;
if (!data.contentAssist && data.hasResultOrProblem())
return;
}
// Lookup in base classes
if (!data.usingDirectivesOnly && scope instanceof ICPPClassScope) {
BaseClassLookup.lookupInBaseClasses(data, (ICPPClassScope) scope, fileSet);
if (!data.contentAssist && data.hasResultOrProblem())
return;
}
if (!data.contentAssist && (data.problem != null || data.hasResults()))
return;
// if still not found, loop and check our containing scope
if (data.qualified() && !(scope instanceof ICPPTemplateScope)) {
if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty())
break;
return;
data.usingDirectivesOnly = true;
}
@ -937,6 +939,37 @@ public class CPPSemantics {
}
}
private static void lookupInlineNamespaces(LookupData data, IIndexFileSet fileSet, ICPPNamespaceScope namespace) throws DOMException {
if (namespace instanceof ICPPInternalNamespaceScope) {
ICPPInternalNamespaceScope ns= (ICPPInternalNamespaceScope) namespace;
for (ICPPInternalNamespaceScope inline : ns.getInlineNamespaces()) {
mergeResults(data, getBindingsFromScope(inline, fileSet, data), true);
lookupInlineNamespaces(data, fileSet, inline);
nominateNamespaces(data, inline);
}
}
}
private static void nominateNamespaces(LookupData data, final ICPPNamespaceScope blockScope)
throws DOMException {
final boolean isBlockScope = blockScope.getKind() == EScopeKind.eLocal;
if (!isBlockScope) {
data.visited.put(blockScope); // Mark as searched.
if (data.tu != null) {
data.tu.handleAdditionalDirectives(blockScope);
}
}
ICPPUsingDirective[] uds= blockScope.getUsingDirectives();
if (uds != null && uds.length > 0) {
HashSet<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>();
for (final ICPPUsingDirective ud : uds) {
if (declaredBefore(ud, data.astName, false)) {
storeUsingDirective(data, blockScope, ud, handled);
}
}
}
}
private static boolean lookupDestructor(LookupData data, IScope start) throws DOMException {
IASTName typeDtorName= data.astName;
final char[] typeDtorChars= typeDtorName.getSimpleID();
@ -1018,7 +1051,7 @@ public class CPPSemantics {
private static boolean dependsOnTemplateFieldReference(IASTName astName) {
if (astName.getPropertyInParent() != IASTFieldReference.FIELD_NAME)
return false;
final boolean[] result= {false};
final IASTExpression fieldOwner = ((IASTFieldReference) astName.getParent()).getFieldOwner();
fieldOwner.accept(new ASTVisitor() {
@ -1109,15 +1142,17 @@ public class CPPSemantics {
}
});
return result[0];
}
}
static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException {
IBinding[] bindings;
static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException {
// For internal scopes we need to check the point of declaration
if (scope instanceof ICPPASTInternalScope) {
final IASTName astName = data.astName;
final ICPPASTInternalScope internalScope = (ICPPASTInternalScope) scope;
IBinding[] bindings= internalScope.getBindings(astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl);
bindings= internalScope.getBindings(astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl);
// Bug 103857: Members declared after the point of completion cannot be
// found in the partial AST, we look them up in the index
if (data.checkWholeClassScope && scope instanceof ICPPClassScope) {
@ -1134,15 +1169,20 @@ public class CPPSemantics {
}
}
}
return bindings;
}
} else {
// For index scopes the point of declaration is ignored.
bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
}
// For index scopes the point of declaration is ignored.
return scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
if (data.typesOnly) {
return removeObjects(bindings);
}
return bindings;
}
static void removeObjects(final IBinding[] bindings) {
private static IBinding[] removeObjects(final IBinding[] bindings) {
final int length = bindings.length;
IBinding[] copy= null;
int pos= 0;
for (int i = 0; i < length; i++) {
final IBinding binding= bindings[i];
@ -1153,12 +1193,21 @@ public class CPPSemantics {
check= delegates[0];
}
if (check instanceof IType || check instanceof ICPPNamespace) {
bindings[pos++]= binding;
if (copy != null) {
copy[pos]= binding;
}
pos++;
} else {
if (copy == null) {
copy= new IBinding[length-1];
System.arraycopy(bindings, 0, copy, 0, pos);
}
}
}
while (pos < length) {
bindings[pos++]= null;
}
if (pos == 0)
return IBinding.EMPTY_BINDING_ARRAY;
return copy == null ? bindings : copy;
}
private static ICPPTemplateScope enclosingTemplateScope(IASTNode node) {
@ -1342,22 +1391,23 @@ public class CPPSemantics {
if (scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope nsscope = (ICPPNamespaceScope) scope;
final ICPPASTUsingDirective usingDirective = (ICPPASTUsingDirective) item;
try {
nsscope.addUsingDirective(new CPPUsingDirective(usingDirective));
} catch (DOMException e) {
// directive is not cached.
nsscope.addUsingDirective(new CPPUsingDirective(usingDirective));
}
} else if (item instanceof ICPPASTNamespaceDefinition) {
final ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) item;
final boolean isUnnamed = nsDef.getName().getLookupKey().length == 0;
final boolean isInline = nsDef.isInline();
if (isUnnamed || isInline) {
if (scope instanceof CPPNamespaceScope) {
final CPPNamespaceScope nsscope = (CPPNamespaceScope) scope;
nsscope.addUsingDirective(new CPPUsingDirective(nsDef));
if (isInline) {
nsscope.addInlineNamespace(nsDef);
}
}
}
} else if (item instanceof ICPPASTNamespaceDefinition &&
((ICPPASTNamespaceDefinition) item).getName().getLookupKey().length == 0) {
if (scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope nsscope = (ICPPNamespaceScope) scope;
final ICPPASTNamespaceDefinition nsdef= (ICPPASTNamespaceDefinition) item;
try {
nsscope.addUsingDirective(new CPPUsingDirective(nsdef));
} catch (DOMException e) {
// directive is not cached.
}
if (!isUnnamed) {
populateCache(scope, item);
}
} else {
populateCache(scope, item);
@ -1577,8 +1627,9 @@ public class CPPSemantics {
* Perform lookup in nominated namespaces that appear in the given scope. For unqualified lookups the method assumes
* that transitive directives have been stored in the lookup-data. For qualified lookups the transitive directives
* are considered if the lookup of the original directive returns empty.
* @param fileSet
*/
static private void lookupInNominated(LookupData data, ICPPNamespaceScope scope) throws DOMException {
static private void lookupInNominated(LookupData data, IIndexFileSet fileSet, ICPPNamespaceScope scope) throws DOMException {
List<ICPPNamespaceScope> allNominated= data.usingDirectives.remove(scope);
while (allNominated != null) {
for (ICPPNamespaceScope nominated : allNominated) {
@ -1588,15 +1639,10 @@ public class CPPSemantics {
data.visited.put(nominated);
boolean found = false;
IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup);
IBinding[] bindings= getBindingsFromScope(nominated, fileSet, data);
if (bindings != null && bindings.length > 0) {
if (data.typesOnly) {
removeObjects(bindings);
}
if (bindings[0] != null) {
mergeResults(data, bindings, true);
found = true;
}
mergeResults(data, bindings, true);
found = true;
}
// in the qualified lookup we have to nominate the transitive directives only when

View file

@ -319,6 +319,10 @@ public class LookupData {
return false;
}
public boolean hasResultOrProblem() {
return problem != null || hasResults();
}
public boolean hasResults() {
if (foundItems == null)
return false;

View file

@ -28,8 +28,10 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
@ -638,4 +640,33 @@ public class CIndex implements IIndex {
}
return result.values().toArray(new IIndexFile[result.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.index.IIndex#getInlineNamespaces()
*/
public IIndexScope[] getInlineNamespaces() throws CoreException {
if (SPECIALCASE_SINGLES && fFragments.length == 1) {
return fFragments[0].getInlineNamespaces();
}
IIndexFragmentBinding[][] preresult = new IIndexFragmentBinding[fPrimaryFragmentCount][];
try {
for (int i = 0; i < fPrimaryFragmentCount; i++) {
IIndexScope[] raw = fFragments[i].getInlineNamespaces();
IIndexFragmentBinding[] arr = preresult[i] = new IIndexFragmentBinding[raw.length];
for (int j=0; j<raw.length; j++) {
arr[j]= (IIndexFragmentBinding) raw[j].getScopeBinding();
}
}
IIndexBinding[] compBinding = getCompositesFactory(ILinkage.CPP_LINKAGE_ID).getCompositeBindings(preresult);
IIndexScope[] result = new IIndexScope[compBinding.length];
for(int i=0; i<result.length; i++) {
result[i]= (IIndexScope) ((ICPPNamespace) compBinding[i]).getNamespaceScope();
}
return result;
} catch (DOMException e) {
// Index bindings don't throw DOMExceptions.
return new IIndexScope[0];
}
}
}

View file

@ -18,6 +18,7 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
@ -147,4 +148,8 @@ final public class EmptyCIndex implements IIndex {
public IIndexBinding[] findMacroContainers(Pattern pattern, IndexFilter filter, IProgressMonitor monitor) {
return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY;
}
public IScope[] getInlineNamespaces() {
return new IScope[0];
}
}

View file

@ -284,4 +284,10 @@ public interface IIndexFragment {
* Clears the result cache.
*/
void clearResultCache();
/**
* Returns the global inline namespaces.
* @throws CoreException
*/
IIndexScope[] getInlineNamespaces() throws CoreException;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2010 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -21,6 +21,8 @@ import org.eclipse.cdt.core.index.IIndexName;
* @since 4.0
*/
public interface IIndexScope extends IScope {
IIndexScope[] EMPTY_INDEX_SCOPE_ARRAY = {};
/**
* Get the binding associated with scope
*/

View file

@ -29,8 +29,8 @@ import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.InclusionKind;
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContentProvider;
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask;
import org.eclipse.cdt.internal.core.pdom.AbstractIndexerTask.IndexFileContent;
@ -291,4 +291,12 @@ public final class IndexBasedFileContentProvider extends InternalFileContentProv
}
return true;
}
public IIndexFile findIndexFile(InternalFileContent fc) throws CoreException {
IIndexFileLocation ifl = fPathResolver.resolveASTPath(fc.getFileLocation());
if (ifl != null) {
return fIndex.getFile(fLinkage, ifl);
}
return null;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -19,10 +19,11 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
public class IndexFileSet implements IIndexFileSet {
private IIndexFileSet fInverse;
private HashMap<IIndexFragment, IIndexFragmentFileSet> fSubSets= new HashMap<IIndexFragment, IIndexFragmentFileSet>();
public IndexFileSet() {
@ -40,13 +41,18 @@ public class IndexFileSet implements IIndexFileSet {
}
public boolean containsDeclaration(IIndexBinding binding) {
return containsDeclaration(binding, false);
}
boolean containsDeclaration(IIndexBinding binding, boolean inverse) {
for (Map.Entry<IIndexFragment, IIndexFragmentFileSet> entry : fSubSets.entrySet()) {
try {
IIndexFragmentName[] names =
entry.getKey().findNames(binding, IIndexFragment.FIND_DECLARATIONS_DEFINITIONS);
for (IIndexFragmentName name : names) {
try {
if (entry.getValue().contains((IIndexFragmentFile) name.getFile())) {
final boolean foundDecl = entry.getValue().contains((IIndexFragmentFile) name.getFile());
if (foundDecl != inverse) {
return true;
}
} catch (CoreException e) {
@ -61,10 +67,18 @@ public class IndexFileSet implements IIndexFileSet {
}
public IBinding[] filterFileLocalBindings(IBinding[] bindings) {
return filterFileLocalBindings(bindings, false);
}
public IBinding[] filterFileLocalBindings(IBinding[] bindings, boolean invert) {
if (bindings == null || bindings.length == 0) {
return bindings;
}
BitSet ok= new BitSet(bindings.length);
if (invert) {
ok.set(0, bindings.length);
}
for (int i = 0; i < bindings.length; i++) {
IBinding binding = bindings[i];
if (binding != null) {
@ -90,10 +104,16 @@ public class IndexFileSet implements IIndexFileSet {
}
}
}
if (ok.cardinality() == bindings.length) {
if (invert) {
ok.flip(0, bindings.length);
}
final int cardinality = ok.cardinality();
if (cardinality == bindings.length) {
return bindings;
}
IBinding[] result= new IBinding[ok.cardinality()];
IBinding[] result= new IBinding[cardinality];
int j= ok.nextSetBit(0);
for (int i = 0; i < result.length; i++) {
result[i]= bindings[j];
@ -103,14 +123,48 @@ public class IndexFileSet implements IIndexFileSet {
}
public boolean contains(IIndexFile file) throws CoreException {
return contains(file, false);
}
public boolean contains(IIndexFile file, boolean invert) throws CoreException {
if (!(file instanceof IIndexFragmentFile))
return false;
return invert;
IIndexFragmentFile ifile= (IIndexFragmentFile) file;
IIndexFragmentFileSet subSet= fSubSets.get(ifile.getIndexFragment());
if (subSet != null) {
return subSet.contains(ifile);
if (subSet != null && subSet.contains(ifile)) {
return !invert;
}
return false;
return invert;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.index.IIndexFileSet#invert()
*/
public IIndexFileSet invert() {
if (fInverse == null) {
fInverse= new IIndexFileSet() {
public IIndexFileSet invert() {
return IndexFileSet.this;
}
public IBinding[] filterFileLocalBindings(IBinding[] bindings) {
return IndexFileSet.this.filterFileLocalBindings(bindings, true);
}
public boolean containsDeclaration(IIndexBinding binding) {
return IndexFileSet.this.containsDeclaration(binding, true);
}
public boolean contains(IIndexFile file) throws CoreException {
return IndexFileSet.this.contains(file, true);
}
public void add(IIndexFile indexFile) {
Assert.isLegal(false);
}
};
}
return fInverse;
}
}

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Symbian Software Systems and others.
* Copyright (c) 2006, 2010 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -37,4 +38,12 @@ class CompositeCPPNamespace extends CompositeCPPBinding implements ICPPNamespace
public ICPPNamespaceScope getNamespaceScope() throws DOMException {
return new CompositeCPPNamespaceScope(cf, namespaces);
}
public boolean isInline() {
for (ICPPNamespace namespace : namespaces) {
if (namespace.isInline())
return true;
}
return false;
}
}

View file

@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2010 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -39,4 +39,8 @@ class CompositeCPPNamespaceAlias extends CompositeCPPBinding implements ICPPName
IIndexFragmentBinding ns = (IIndexFragmentBinding) ((ICPPNamespaceAlias)rbinding).getBinding();
return cf.getCompositeBinding(ns);
}
public boolean isInline() {
return false;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2010 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -38,11 +38,11 @@ class CompositeCPPNamespaceScope extends CompositeScope implements ICPPNamespace
return EScopeKind.eNamespace;
}
public void addUsingDirective(ICPPUsingDirective directive) throws DOMException {
public void addUsingDirective(ICPPUsingDirective directive) {
fail();
}
public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
public ICPPUsingDirective[] getUsingDirectives() {
return new ICPPUsingDirective[0]; // same behavior as PDOMCPPNamespace
}
@ -82,9 +82,9 @@ class CompositeCPPNamespaceScope extends CompositeScope implements ICPPNamespace
@Override
public IIndexName getScopeName() {
for(int i=0; i<namespaces.length; i++) {
if(namespaces[i] instanceof IIndexScope) {
IIndexScope s= (IIndexScope) namespaces[i];
for (ICPPNamespace namespace : namespaces) {
if(namespace instanceof IIndexScope) {
IIndexScope s= (IIndexScope) namespace;
IIndexName nm= s.getScopeName();
if(nm!=null)
return nm;
@ -92,4 +92,29 @@ class CompositeCPPNamespaceScope extends CompositeScope implements ICPPNamespace
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getInlineNamespaces()
*/
public ICPPNamespaceScope[] getInlineNamespaces() {
IIndexFragmentBinding[][] preresult = new IIndexFragmentBinding[namespaces.length][];
try {
for(int i=0; i<namespaces.length; i++) {
ICPPNamespaceScope[] raw = namespaces[i].getNamespaceScope().getInlineNamespaces();
IIndexFragmentBinding[] arr = preresult[i] = new IIndexFragmentBinding[raw.length];
for (int j=0; j<raw.length; j++) {
arr[j]= (IIndexFragmentBinding) ((IIndexScope) raw[j]).getScopeBinding();
}
}
IIndexBinding[] compBinding = cf.getCompositeBindings(preresult);
ICPPNamespaceScope[] result = new ICPPNamespaceScope[compBinding.length];
for(int i=0; i<result.length; i++) {
result[i]= ((ICPPNamespace) compBinding[i]).getNamespaceScope();
}
return result;
} catch (DOMException e) {
// Index bindings don't throw DOMExceptions.
return new ICPPNamespaceScope[0];
}
}
}

View file

@ -190,6 +190,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private Token fPrefetchedTokens;
private Token fLastToken;
private InternalFileContent fRootContent;
public CPreprocessor(FileContent fileContent, IScannerInfo info, ParserLanguage language, IParserLogService log,
IScannerExtensionConfiguration configuration, IncludeFileContentProvider readerFactory) {
@ -200,9 +202,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else {
throw new IllegalArgumentException("Illegal reader factory"); //$NON-NLS-1$
}
InternalFileContent content;
if (fileContent instanceof InternalFileContent) {
content= (InternalFileContent) fileContent;
fRootContent= (InternalFileContent) fileContent;
} else {
throw new IllegalArgumentException("Illegal file content object"); //$NON-NLS-1$
}
@ -224,14 +225,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fMacroExpander= new MacroExpander(this, fMacroDictionary, fLocationMap, fLexOptions);
fIncludeFileResolutionHeuristics= fFileContentProvider.getIncludeHeuristics();
final String filePath= content.getFileLocation();
final String filePath= fRootContent.getFileLocation();
configureIncludeSearchPath(new File(filePath).getParentFile(), info);
setupMacroDictionary(configuration, info, language);
ILocationCtx ctx= fLocationMap.pushTranslationUnit(filePath, content.getSource());
ILocationCtx ctx= fLocationMap.pushTranslationUnit(filePath, fRootContent.getSource());
fAllIncludedFiles.add(filePath);
fFileContentProvider.reportTranslationUnitFile(filePath);
fRootLexer= new Lexer(content.getSource(), fLexOptions, this, this);
fRootLexer= new Lexer(fRootContent.getSource(), fLexOptions, this, this);
fRootContext= fCurrentContext= new ScannerContext(ctx, null, fRootLexer);
if (info instanceof IExtendedScannerInfo) {
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
@ -367,6 +368,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
if (content != null && content.getKind() == InclusionKind.FOUND_IN_INDEX) {
processInclusionFromIndex(0, location, content);
}
fLocationMap.replacingFile(fFileContentProvider, fRootContent);
fRootContent= null;
}
private void handlePreIncludedFiles() {
@ -1269,6 +1272,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fctx.setFoundOnPath(fi.getFoundOnPath(), includeDirective);
fCurrentContext= fctx;
}
fLocationMap.replacingFile(fFileContentProvider, fi);
break;
case SKIP_FILE:

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -24,4 +24,9 @@ public interface ISkippedIndexedFilesListener {
* @param fileContent information about the skipped file.
*/
void skippedFile(int offset, InternalFileContent fileContent);
/**
* Notifies the listeners that a file is being parsed.
*/
void replacingFile(InternalFileContentProvider fileContentProvider, InternalFileContent fileContent);
}

View file

@ -28,9 +28,9 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
import org.eclipse.cdt.internal.core.dom.parser.ASTProblem;
@ -730,4 +730,11 @@ public class LocationMap implements ILocationResolver {
l.skippedFile(sequenceNumber, fi);
}
}
public void replacingFile(InternalFileContentProvider fileContentProvider,
InternalFileContent fileContent) {
for (ISkippedIndexedFilesListener l : fSkippedFilesListeners) {
l.replacingFile(fileContentProvider, fileContent);
}
}
}

View file

@ -64,6 +64,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFileSet;
import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.ChunkCache;
import org.eclipse.cdt.internal.core.pdom.db.DBProperties;
@ -200,10 +201,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 110.0 - update index on encoding change, bug 317435.
* 111.0 - correct marshalling of basic types, bug 319186.
* 111.1 - defaulted and deleted functions, bug 305978
* 112.0 - inline namespaces, bug 305980
*/
private static final int MIN_SUPPORTED_VERSION= version(111, 0);
private static final int MAX_SUPPORTED_VERSION= version(111, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(111, 1);
private static final int MIN_SUPPORTED_VERSION= version(112, 0);
private static final int MAX_SUPPORTED_VERSION= version(112, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(112, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
@ -1554,4 +1556,15 @@ public class PDOM extends PlatformObject implements IPDOM {
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.index.IIndexFragment#getInlineNamespaces()
*/
public IIndexScope[] getInlineNamespaces() throws CoreException {
PDOMLinkage linkage = getLinkage(ILinkage.CPP_LINKAGE_ID);
if (linkage == null) {
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
return linkage.getInlineNamespaces();
}
}

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFileSet;
import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.pdom.PDOM.ChangeEvent;
import org.eclipse.cdt.internal.core.pdom.PDOM.DebugLockInfo;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
@ -283,4 +284,13 @@ public class PDOMProxy implements IPDOM {
if (fDelegate != null)
fDelegate.clearResultCache();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.index.IIndexFragment#getInlineNamespaces()
*/
public IIndexScope[] getInlineNamespaces() throws CoreException {
if (fDelegate != null)
return fDelegate.getInlineNamespaces();
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
}

View file

@ -247,11 +247,7 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding
@Override
public final String toString() {
String name = toStringBase();
try {
return name + " " + getConstantNameForValue(getLinkage(), getNodeType()); //$NON-NLS-1$
} catch (CoreException e) {
return name + " " + getNodeType(); //$NON-NLS-1$
}
return name + " " + getConstantNameForValue(getLinkage(), getNodeType()); //$NON-NLS-1$
}
protected String toStringBase() {

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayMap;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.index.IIndexBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
@ -94,7 +95,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
@Override
public final PDOMLinkage getLinkage() throws CoreException {
public final PDOMLinkage getLinkage() {
return this;
}
@ -163,7 +164,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
@Override
public final void addChild(PDOMNode child) throws CoreException {
public void addChild(PDOMNode child) throws CoreException {
getIndex().insert(child.getRecord());
}
@ -284,7 +285,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
IASTDeclSpecifier ds= (IASTDeclSpecifier) parentNode;
if (ds.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
if (pdomName.getEnclosingDefinitionRecord() != 0) {
pdomName.setIsBaseSpecifier(true);
pdomName.setIsBaseSpecifier();
}
}
}
@ -491,4 +492,8 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
return null;
}
public IIndexScope[] getInlineNamespaces() {
return IIndexScope.EMPTY_INDEX_SCOPE_ARRAY;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -68,6 +68,9 @@ class PDOMMacroDefinitionName implements IIndexFragmentName {
public boolean isReference() {
return false;
}
public boolean isInlineNamespaceDefinition() {
return false;
}
@Deprecated
public char[] toCharArray() {

View file

@ -163,6 +163,10 @@ public final class PDOMMacroReferenceName implements IIndexFragmentName, IASTFil
return false;
}
public boolean isInlineNamespaceDefinition() {
return false;
}
public boolean isReadAccess() throws CoreException {
return false;
}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
* Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
@ -28,9 +28,7 @@ import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
/**
* @author Doug Schaefer
*/
public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
private final PDOMLinkage linkage;
private final long record;
@ -51,8 +49,10 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
public static final int IS_DEFINITION = 0x02;
public static final int IS_REFERENCE = IS_DECLARATION | IS_DEFINITION;
public static final int DECL_DEF_REF_MASK = IS_DECLARATION | IS_DEFINITION | IS_REFERENCE;
public static final int INHERIT_FRIEND_INLINE_MASK = 0x0C;
public static final int IS_INHERITANCE_SPEC = 0x04;
public static final int IS_FRIEND_SPEC = 0x08;
public static final int IS_INLINE_NAMESPACE = 0x0C;
public static final int COULD_BE_POLYMORPHIC_METHOD_CALL = 0x10;
public static final int READ_ACCESS = 0x20;
public static final int WRITE_ACCESS = 0x40;
@ -222,32 +222,36 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
return linkage.getDB().getByte(record + FLAGS) & mask;
}
public void setIsFriendSpecifier(boolean val) throws CoreException {
public void setIsFriendSpecifier() throws CoreException {
int flags= linkage.getDB().getByte(record + FLAGS) & 0xff;
if (val)
flags |= IS_FRIEND_SPEC;
else
flags &= ~IS_FRIEND_SPEC;
flags |= IS_FRIEND_SPEC;
linkage.getDB().putByte(record + FLAGS, (byte) flags);
}
public void setIsBaseSpecifier(boolean val) throws CoreException {
public void setIsBaseSpecifier() throws CoreException {
int flags= linkage.getDB().getByte(record + FLAGS) & 0xff;
if (val)
flags |= IS_INHERITANCE_SPEC;
else
flags &= ~IS_INHERITANCE_SPEC;
flags |= IS_INHERITANCE_SPEC;
linkage.getDB().putByte(record + FLAGS, (byte) flags);
}
public void setIsInlineNamespace() throws CoreException {
int flags= linkage.getDB().getByte(record + FLAGS) & 0xff;
flags |= IS_INLINE_NAMESPACE;
linkage.getDB().putByte(record + FLAGS, (byte) flags);
}
public boolean isFriendSpecifier() throws CoreException {
return getFlags(IS_FRIEND_SPEC) == IS_FRIEND_SPEC;
return getFlags(INHERIT_FRIEND_INLINE_MASK) == IS_FRIEND_SPEC;
}
public boolean isBaseSpecifier() throws CoreException {
return getFlags(IS_INHERITANCE_SPEC) == IS_INHERITANCE_SPEC;
return getFlags(INHERIT_FRIEND_INLINE_MASK) == IS_INHERITANCE_SPEC;
}
public boolean isInlineNamespaceDefinition() throws CoreException {
return getFlags(INHERIT_FRIEND_INLINE_MASK) == IS_INLINE_NAMESPACE;
}
public boolean couldBePolymorphicMethodCall() throws CoreException {
return getFlags(COULD_BE_POLYMORPHIC_METHOD_CALL) == COULD_BE_POLYMORPHIC_METHOD_CALL;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2009 QNX Software Systems and others.
* Copyright (c) 2005, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -70,7 +70,7 @@ public abstract class PDOMNode implements IInternalPDOMNode {
return fLinkage.getPDOM();
}
public PDOMLinkage getLinkage() throws CoreException {
public PDOMLinkage getLinkage() {
return fLinkage;
}

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
@ -86,6 +87,7 @@ import org.eclipse.cdt.internal.core.index.composite.CompositeIndexBinding;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter;
@ -104,6 +106,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
public final static int CACHE_BASES= 1;
public final static int CACHE_INSTANCES= 2;
public final static int CACHE_INSTANCE_SCOPE= 3;
private final static int FIRST_NAMESPACE_CHILD_OFFSET= PDOMLinkage.RECORD_SIZE;
@SuppressWarnings("hiding")
private final static int RECORD_SIZE= FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE;
private LinkedList<Runnable> postProcesses = new LinkedList<Runnable>();
@ -396,6 +403,14 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return pdomBinding;
}
@Override
public void addChild(PDOMNode node) throws CoreException {
super.addChild(node);
if (node instanceof PDOMCPPNamespace) {
((PDOMCPPNamespace) node).addToList(record + FIRST_NAMESPACE_CHILD_OFFSET);
}
}
private PDOMBinding createSpecialization(PDOMNode parent, PDOMBinding orig, IBinding special)
throws CoreException, DOMException {
PDOMBinding result= null;
@ -594,6 +609,22 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return result;
}
@Override
public PDOMCPPNamespace[] getInlineNamespaces() {
final Long key = record + CACHE_BASES;
PDOMCPPNamespace[] result= (PDOMCPPNamespace[]) getPDOM().getCachedResult(key);
if (result == null) {
List<PDOMCPPNamespace> nslist = PDOMCPPNamespace.collectInlineNamespaces(getDB(), getLinkage(), record+FIRST_NAMESPACE_CHILD_OFFSET);
if (nslist == null) {
result= new PDOMCPPNamespace[0];
} else {
result= nslist.toArray(new PDOMCPPNamespace[nslist.size()]);
}
getPDOM().putCachedResult(key, result, true);
}
return result;
}
/**
* Find the equivalent binding, or binding place holder within this PDOM
*/
@ -814,13 +845,13 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMCPPBase pdomBase = new PDOMCPPBase(this, pdomName, baseNode.isVirtual(),
baseNode.getVisibility());
ownerClass.addBase(pdomBase);
pdomName.setIsBaseSpecifier(true);
pdomName.setIsBaseSpecifier();
} else if (derivedClassBinding instanceof PDOMCPPClassSpecialization) {
PDOMCPPClassSpecialization ownerClass = (PDOMCPPClassSpecialization) derivedClassBinding;
PDOMCPPBase pdomBase = new PDOMCPPBase(this, pdomName, baseNode.isVirtual(),
baseNode.getVisibility());
ownerClass.addBase(pdomBase);
pdomName.setIsBaseSpecifier(true);
pdomName.setIsBaseSpecifier();
}
}
} else if (parentNode instanceof ICPPASTUsingDirective) {
@ -860,7 +891,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} else if (parentNode instanceof ICPPASTElaboratedTypeSpecifier) {
ICPPASTElaboratedTypeSpecifier elaboratedSpecifier = (ICPPASTElaboratedTypeSpecifier)parentNode;
if (elaboratedSpecifier.isFriend()) {
pdomName.setIsFriendSpecifier(true);
pdomName.setIsFriendSpecifier();
PDOMName enclClassName = (PDOMName) pdomName.getEnclosingDefinition();
if (enclClassName != null) {
PDOMBinding enclClassBinding = enclClassName.getBinding();
@ -874,7 +905,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
IASTSimpleDeclaration grandparentNode = (IASTSimpleDeclaration) parentNode.getParent();
if (grandparentNode.getDeclSpecifier() instanceof ICPPASTDeclSpecifier) {
if (((ICPPASTDeclSpecifier) grandparentNode.getDeclSpecifier()).isFriend()) {
pdomName.setIsFriendSpecifier(true);
pdomName.setIsFriendSpecifier();
PDOMName enclClassName = (PDOMName) pdomName.getEnclosingDefinition();
if (enclClassName != null) {
PDOMBinding enclClassBinding = enclClassName.getBinding();
@ -885,6 +916,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
}
}
} else if (parentNode instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition nsdef= (ICPPASTNamespaceDefinition) parentNode;
if (nsdef.isInline()) {
pdomName.setIsInlineNamespace();
}
}
}

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.model.ASTStringUtil;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.cdt.internal.core.pdom.dom.BindingCollector;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
@ -49,18 +50,40 @@ import org.eclipse.core.runtime.CoreException;
class PDOMCPPNamespace extends PDOMCPPBinding
implements ICPPNamespace, ICPPNamespaceScope, IIndexScope {
private static final int INDEX_OFFSET = PDOMBinding.RECORD_SIZE + 0;
private static final int INDEX_OFFSET = PDOMCPPBinding.RECORD_SIZE;
private static final int FIRST_NAMESPACE_CHILD_OFFSET = INDEX_OFFSET + Database.PTR_SIZE;
private static final int NEXT_NAMESPACE_SIBBLING_OFFSET = FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE;
private static final int FLAG_OFFSET = NEXT_NAMESPACE_SIBBLING_OFFSET + Database.PTR_SIZE;
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 4;
protected static final int RECORD_SIZE = FLAG_OFFSET + 1;
private static int INLINE_FLAG= 0x1;
private int fFlag= -1;
private ICPPNamespaceScope[] fInlineNamespaces;
public PDOMCPPNamespace(PDOMLinkage linkage, PDOMNode parent, ICPPNamespace namespace) throws CoreException {
super(linkage, parent, namespace.getNameCharArray());
updateFlag(namespace);
}
public PDOMCPPNamespace(PDOMLinkage linkage, long record) throws CoreException {
super(linkage, record);
}
@Override
public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException {
updateFlag((ICPPNamespace) newBinding);
}
private void updateFlag(ICPPNamespace namespace) throws CoreException {
int flag= 0;
if (namespace.isInline())
flag |= INLINE_FLAG;
getDB().putByte(record + FLAG_OFFSET, (byte) flag);
}
public EScopeKind getKind() {
return EScopeKind.eNamespace;
@ -104,14 +127,25 @@ class PDOMCPPNamespace extends PDOMCPPBinding
@Override
public void addChild(PDOMNode child) throws CoreException {
getIndex().insert(child.getRecord());
final long childRec = child.getRecord();
getIndex().insert(childRec);
if (child instanceof PDOMCPPNamespace) {
((PDOMCPPNamespace) child).addToList(record + FIRST_NAMESPACE_CHILD_OFFSET);
}
}
public ICPPNamespaceScope getNamespaceScope() throws DOMException {
public void addToList(final long listRecord) throws CoreException {
final Database db= getDB();
final long nextRec= db.getRecPtr(listRecord);
db.putRecPtr(record + NEXT_NAMESPACE_SIBBLING_OFFSET, nextRec);
db.putRecPtr(listRecord, record);
}
public ICPPNamespaceScope getNamespaceScope() {
return this;
}
public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
public ICPPUsingDirective[] getUsingDirectives() {
return new ICPPUsingDirective[0];
}
@ -203,7 +237,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding
return result;
}
public void addUsingDirective(ICPPUsingDirective directive) throws DOMException { fail(); }
public void addUsingDirective(ICPPUsingDirective directive) { fail(); }
public IIndexBinding getScopeBinding() {
return this;
@ -217,4 +251,49 @@ class PDOMCPPNamespace extends PDOMCPPBinding
}
return ASTStringUtil.join(names, String.valueOf(Keywords.cpCOLONCOLON));
}
public ICPPNamespaceScope[] getInlineNamespaces() {
if (fInlineNamespaces == null) {
List<PDOMCPPNamespace> nslist = collectInlineNamespaces(getDB(), getLinkage(), record+FIRST_NAMESPACE_CHILD_OFFSET);
if (nslist == null) {
fInlineNamespaces= new PDOMCPPNamespace[0];
} else {
fInlineNamespaces= nslist.toArray(new PDOMCPPNamespace[nslist.size()]);
}
}
return fInlineNamespaces;
}
public static List<PDOMCPPNamespace> collectInlineNamespaces(Database db,
PDOMLinkage linkage, long listRecord) {
List<PDOMCPPNamespace> nslist= null;
try {
long rec= db.getRecPtr(listRecord);
while (rec != 0) {
PDOMCPPNamespace ns= new PDOMCPPNamespace(linkage, rec);
if (ns.isInline()) {
if (nslist == null) {
nslist= new ArrayList<PDOMCPPNamespace>();
}
nslist.add(ns);
}
rec= db.getRecPtr(rec + NEXT_NAMESPACE_SIBBLING_OFFSET);
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
return nslist;
}
public boolean isInline() {
if (fFlag == -1) {
try {
fFlag= getDB().getByte(record + FLAG_OFFSET);
} catch (CoreException e) {
CCorePlugin.log(e);
fFlag= 0;
}
}
return (fFlag & INLINE_FLAG) != 0;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 QNX Software Systems and others.
* Copyright (c) 2006, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -101,4 +101,7 @@ class PDOMCPPNamespaceAlias extends PDOMCPPBinding implements ICPPNamespaceAlias
return null;
}
public boolean isInline() {
return false;
}
}