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

Bug 294730: Extern templates.

This commit is contained in:
Markus Schorn 2010-02-08 14:16:28 +00:00
parent c6176c6b67
commit 648f5c9331
10 changed files with 136 additions and 116 deletions

View file

@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -4777,4 +4778,13 @@ public class AST2TemplateTests extends AST2BaseTest {
f= bh.assertNonProblem("f<int,char>();", -3);
assertEquals("<int,char>", ASTTypeUtil.getArgumentListString(f.getTemplateArguments(), true));
}
// template<typename T> class CT {};
// extern template class CT<int>;
public void testExternTemplates_294730() throws Exception {
final String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
ICPPASTExplicitTemplateInstantiation ti= getDeclaration(tu, 1);
assertEquals(ICPPASTExplicitTemplateInstantiation.EXTERN, ti.getModifier());
}
}

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;
@ -14,13 +15,29 @@ import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
/**
* This interface represents an explict template instantiation.
* This interface represents an explicit template instantiation.
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTExplicitTemplateInstantiation extends IASTDeclaration {
/**
* Gnu extension.
* @since 5.2
*/
public static final int STATIC = 1;
/**
* Gnu extension.
* @since 5.2
*/
public static final int INLINE = 2;
/**
* C++0x.
* @since 5.2
*/
public static final int EXTERN = 3;
/**
* <code>OWNED_DECLARATION</code> represents the role of the inner
* declaration that this template refers to.
@ -47,4 +64,16 @@ public interface ICPPASTExplicitTemplateInstantiation extends IASTDeclaration {
* @since 5.1
*/
public ICPPASTExplicitTemplateInstantiation copy();
/**
* Returns {@link #STATIC}, {@link #INLINE}, {@link #EXTERN}, or <code>0</code>.
* @since 5.2
*/
public int getModifier();
/**
* Set the modifier value, not allowed on frozen ast.
* @since 5.2
*/
public void setModifier(int value);
}

View file

@ -23,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.INodeFactory;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.parser.IScanner;
@ -144,8 +143,6 @@ public interface ICPPNodeFactory extends INodeFactory {
public ICPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiation(IASTDeclaration declaration);
public IGPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiationGPP(IASTDeclaration declaration);
public ICPPASTTemplateSpecialization newTemplateSpecialization(IASTDeclaration declaration);
public ICPPASTTryBlockStatement newTryBlockStatement(IASTStatement body);
@ -227,4 +224,12 @@ public interface ICPPNodeFactory extends INodeFactory {
*/
@Deprecated
public org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier newSimpleDeclSpecifierGPP();
/**
* @deprecated Replaced by {@link #newExplicitTemplateInstantiation(IASTDeclaration)}.
*/
@Deprecated
public org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiationGPP(IASTDeclaration declaration);
}

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
@ -14,42 +14,29 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
/**
* G++ allows for instantiations to be qualified w/modifiers for scoping.
* @deprecated Replaced by {@link ICPPASTExplicitTemplateInstantiation}
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
@Deprecated
public interface IGPPASTExplicitTemplateInstantiation extends
ICPPASTExplicitTemplateInstantiation {
/**
* <code>ti_static</code> implies 'static' keyword is used.
*/
public static final int ti_static = 1;
public static final int ti_static = ICPPASTExplicitTemplateInstantiation.STATIC;
/**
* <code>ti_inline</code> implies 'inline' keyword is used.
*/
public static final int ti_inline = 2;
public static final int ti_inline = ICPPASTExplicitTemplateInstantiation.INLINE;
/**
* <code>ti_extern</code> implies 'extern' keyword is used.
*/
public static final int ti_extern = 3;
/**
* Get the modifier.
*
* @return int
*/
public int getModifier();
/**
* Set the modifier value.
*
* @param value
* (int)
*/
public void setModifier(int value);
public static final int ti_extern = ICPPASTExplicitTemplateInstantiation.EXTERN;
/**
* @since 5.1

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -18,12 +19,13 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* @author jcamelon
* Models explicit instantiations.
*/
public class CPPASTExplicitTemplateInstantiation extends ASTNode implements
ICPPASTExplicitTemplateInstantiation, IASTAmbiguityParent {
private IASTDeclaration declaration;
private int modifier;
public CPPASTExplicitTemplateInstantiation() {
@ -36,6 +38,7 @@ public class CPPASTExplicitTemplateInstantiation extends ASTNode implements
public CPPASTExplicitTemplateInstantiation copy() {
CPPASTExplicitTemplateInstantiation copy = new CPPASTExplicitTemplateInstantiation();
copy.setDeclaration(declaration == null ? null : declaration.copy());
copy.setModifier(modifier);
copy.setOffsetAndLength(this);
return copy;
}
@ -53,7 +56,17 @@ public class CPPASTExplicitTemplateInstantiation extends ASTNode implements
}
}
@Override
public int getModifier() {
return modifier;
}
public void setModifier(int mod) {
assertNotFrozen();
modifier= mod;
}
@Override
public boolean accept( ASTVisitor action ){
if( action.shouldVisitDeclarations ){
switch( action.visit( this ) ){

View file

@ -104,7 +104,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.parser.IScanner;
@ -399,10 +398,6 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return new CPPASTExplicitTemplateInstantiation(declaration);
}
public IGPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiationGPP(IASTDeclaration declaration) {
return new GPPASTExplicitTemplateInstantiation(declaration);
}
public ICPPASTTemplateSpecialization newTemplateSpecialization(IASTDeclaration declaration) {
return new CPPASTTemplateSpecialization(declaration);
}
@ -529,4 +524,14 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier newSimpleDeclSpecifierGPP() {
return new GPPASTSimpleDeclSpecifier();
}
/**
* @deprecated Replaced by {@link #newExplicitTemplateInstantiation(IASTDeclaration)}.
*/
@Deprecated
public org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiationGPP(IASTDeclaration declaration) {
return new GPPASTExplicitTemplateInstantiation(declaration);
}
}

View file

@ -111,7 +111,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.dom.parser.IExtensionToken;
@ -1587,63 +1586,50 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* request for a backtrack
*/
protected IASTDeclaration templateDeclaration(DeclarationOptions option) throws EndOfFileException, BacktrackException {
IToken firstToken = null;
final int offset= LA(1).getOffset();
boolean exported = false;
boolean encounteredExtraMod = false;
if (LT(1) == IToken.t_export) {
int explicitInstMod= 0;
switch(LT(1)) {
case IToken.t_export:
exported = true;
firstToken = consume();
consume(IToken.t_template);
} else {
if (supportExtendedTemplateSyntax) {
switch (LT(1)) {
case IToken.t_static:
case IToken.t_extern:
case IToken.t_inline:
firstToken = consume();
consume(IToken.t_template);
encounteredExtraMod = true;
break;
default:
firstToken = consume(IToken.t_template);
break;
}
} else
firstToken = consume(IToken.t_template);
consume();
break;
case IToken.t_extern:
consume();
explicitInstMod= ICPPASTExplicitTemplateInstantiation.EXTERN;
break;
case IToken.t_static:
consume();
explicitInstMod= ICPPASTExplicitTemplateInstantiation.STATIC;
break;
case IToken.t_inline:
consume();
explicitInstMod= ICPPASTExplicitTemplateInstantiation.INLINE;
break;
}
consume(IToken.t_template);
if (LT(1) != IToken.tLT) {
// explicit-instantiation
ICPPASTExplicitTemplateInstantiation templateInstantiation = null;
if (encounteredExtraMod && supportExtendedTemplateSyntax) {
IGPPASTExplicitTemplateInstantiation temp = nodeFactory.newExplicitTemplateInstantiationGPP(null);
switch (firstToken.getType()) {
case IToken.t_static:
temp.setModifier(IGPPASTExplicitTemplateInstantiation.ti_static);
break;
case IToken.t_extern:
temp.setModifier(IGPPASTExplicitTemplateInstantiation.ti_extern);
break;
case IToken.t_inline:
temp.setModifier(IGPPASTExplicitTemplateInstantiation.ti_inline);
break;
}
templateInstantiation = temp;
} else {
templateInstantiation = nodeFactory.newExplicitTemplateInstantiation(null);
}
IASTDeclaration d = declaration(option);
((ASTNode) templateInstantiation).setOffsetAndLength(firstToken
.getOffset(), calculateEndOffset(d) - firstToken.getOffset());
templateInstantiation.setDeclaration(d);
return templateInstantiation;
ICPPASTExplicitTemplateInstantiation ti= nodeFactory.newExplicitTemplateInstantiation(d);
ti.setModifier(explicitInstMod);
setRange(ti, offset, calculateEndOffset(d));
return ti;
}
consume(); // check for LT made before
// Modifiers for explicit instantiations
if (explicitInstMod != 0) {
throwBacktrack(LA(1));
}
consume(IToken.tLT);
if (LT(1) == IToken.tGT) {
// explicit-specialization
consume();
IASTDeclaration d = declaration(option);
ICPPASTTemplateSpecialization templateSpecialization = nodeFactory.newTemplateSpecialization(d);
((ASTNode) templateSpecialization).setOffsetAndLength(firstToken.getOffset(), calculateEndOffset(d) - firstToken.getOffset());
setRange(templateSpecialization, offset, calculateEndOffset(d));
return templateSpecialization;
}
@ -1651,7 +1637,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
IASTDeclaration d = declaration(option);
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(), calculateEndOffset(d) - firstToken.getOffset());
setRange(templateDecl, offset, calculateEndOffset(d));
templateDecl.setExported(exported);
for (int i = 0; i < parms.size(); ++i) {
ICPPASTTemplateParameter parm = parms.get(i);
@ -1806,7 +1792,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.t_extern:
if (LT(2) == IToken.tSTRING)
return linkageSpecification();
if (supportExtendedTemplateSyntax && LT(2) == IToken.t_template)
if (LT(2) == IToken.t_template)
return templateDeclaration(option);
break;
case IToken.t_static:

View file

@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -14,8 +14,9 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
/**
* @author jcamelon
* @deprecated Replaced by {@link CPPASTExplicitTemplateInstantiation}.
*/
@Deprecated
public class GPPASTExplicitTemplateInstantiation extends
CPPASTExplicitTemplateInstantiation implements
IGPPASTExplicitTemplateInstantiation {
@ -28,25 +29,13 @@ public class GPPASTExplicitTemplateInstantiation extends
super(declaration);
}
private int mod;
@Override
public GPPASTExplicitTemplateInstantiation copy() {
GPPASTExplicitTemplateInstantiation copy = new GPPASTExplicitTemplateInstantiation();
IASTDeclaration declaration = getDeclaration();
copy.setDeclaration(declaration == null ? null : declaration.copy());
copy.mod = mod;
copy.setModifier(getModifier());
copy.setOffsetAndLength(this);
return copy;
}
public int getModifier() {
return mod;
}
public void setModifier(int value) {
this.mod = value;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
* Copyright (c) 2008, 2010 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@ -35,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -236,19 +235,16 @@ public class DeclarationWriter extends NodeWriter{
}
private void writeExplicitTemplateInstantiation(ICPPASTExplicitTemplateInstantiation explicitTemplateInstantiation) {
if (explicitTemplateInstantiation instanceof IGPPASTExplicitTemplateInstantiation) {
IGPPASTExplicitTemplateInstantiation gppExplicitTemplateInstantiation = (IGPPASTExplicitTemplateInstantiation) explicitTemplateInstantiation;
switch(gppExplicitTemplateInstantiation.getModifier()){
case IGPPASTExplicitTemplateInstantiation.ti_extern:
scribe.print(EXTERN);
break;
case IGPPASTExplicitTemplateInstantiation.ti_inline:
scribe.print(INLINE);
break;
case IGPPASTExplicitTemplateInstantiation.ti_static:
scribe.print(STATIC);
break;
}
switch(explicitTemplateInstantiation.getModifier()){
case ICPPASTExplicitTemplateInstantiation.EXTERN:
scribe.print(EXTERN);
break;
case ICPPASTExplicitTemplateInstantiation.INLINE:
scribe.print(INLINE);
break;
case ICPPASTExplicitTemplateInstantiation.STATIC:
scribe.print(STATIC);
break;
}
scribe.print(TEMPLATE);

View file

@ -49,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
@ -61,7 +62,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
@ -216,9 +216,9 @@ public class TrailNodeEqualityChecker implements EqualityChecker<IASTNode> {
IASTASMDeclaration asmDecl = (IASTASMDeclaration) node;
return trailASMDecl.getAssembly().equals(asmDecl.getAssembly());
} else if (trailNode instanceof IGPPASTExplicitTemplateInstantiation) {
IGPPASTExplicitTemplateInstantiation trailTempl = (IGPPASTExplicitTemplateInstantiation) trailNode;
IGPPASTExplicitTemplateInstantiation templ = (IGPPASTExplicitTemplateInstantiation) node;
} else if (trailNode instanceof ICPPASTExplicitTemplateInstantiation) {
ICPPASTExplicitTemplateInstantiation trailTempl = (ICPPASTExplicitTemplateInstantiation) trailNode;
ICPPASTExplicitTemplateInstantiation templ = (ICPPASTExplicitTemplateInstantiation) node;
return trailTempl.getModifier() == templ.getModifier();
} else if (trailNode instanceof ICPPASTLinkageSpecification) {