mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-28 19:35:36 +02:00
Patch for Victor Mozgin.
implemented support for pointers to class members; added handling of declarations for nested scopes (like A::B::C); fixed handling of parameter lists for typedefs for functions; some errorhandling in CModelBuilder;
This commit is contained in:
parent
138588dd26
commit
15f0d21085
9 changed files with 259 additions and 62 deletions
|
@ -6,6 +6,11 @@
|
||||||
with skeleton classes based on the JDT search as a beginning for
|
with skeleton classes based on the JDT search as a beginning for
|
||||||
implementing C/CPP search.
|
implementing C/CPP search.
|
||||||
|
|
||||||
|
2003-06-14 Victor Mozgin
|
||||||
|
Added support for pointers to members to DOMBuilder.
|
||||||
|
Added new kind of pointer operator : t_pointer_to_member (PointerOperator).
|
||||||
|
Added nameSpecifier field and set/get operations to PointerOperator.
|
||||||
|
|
||||||
2003-06-06 Sean Evoy
|
2003-06-06 Sean Evoy
|
||||||
|
|
||||||
Added new interface, IResourceBuildInfo, so clients could
|
Added new interface, IResourceBuildInfo, so clients could
|
||||||
|
|
|
@ -446,7 +446,7 @@ public class DOMBuilder implements IParserCallback, ISourceElementRequestor
|
||||||
* @see org.eclipse.cdt.internal.core.parser.IParserCallback#pointerOperatorName(java.lang.Object)
|
* @see org.eclipse.cdt.internal.core.parser.IParserCallback#pointerOperatorName(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
public void pointerOperatorName(Object ptrOperator) {
|
public void pointerOperatorName(Object ptrOperator) {
|
||||||
// TODO Auto-generated method stub
|
((PointerOperator)ptrOperator).setNameSpecifier(currName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -462,6 +462,10 @@ public class DOMBuilder implements IParserCallback, ISourceElementRequestor
|
||||||
case IToken.tAMPER:
|
case IToken.tAMPER:
|
||||||
ptrOp.setType( PointerOperator.t_reference );
|
ptrOp.setType( PointerOperator.t_reference );
|
||||||
break;
|
break;
|
||||||
|
case IToken.tCOLONCOLON:
|
||||||
|
case IToken.tIDENTIFIER:
|
||||||
|
ptrOp.setType( PointerOperator.t_pointer_to_member );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom;
|
package org.eclipse.cdt.internal.core.dom;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.parser.Name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*
|
*
|
||||||
|
@ -20,7 +22,8 @@ public class PointerOperator {
|
||||||
|
|
||||||
public final static int t_undefined = 0;
|
public final static int t_undefined = 0;
|
||||||
public final static int t_pointer = 1;
|
public final static int t_pointer = 1;
|
||||||
public final static int t_reference = 2;
|
public final static int t_reference = 2;
|
||||||
|
public final static int t_pointer_to_member = 3;
|
||||||
private int type = t_undefined;
|
private int type = t_undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,5 +86,23 @@ public class PointerOperator {
|
||||||
public Declarator getOwnerDeclarator() {
|
public Declarator getOwnerDeclarator() {
|
||||||
return ownerDeclarator;
|
return ownerDeclarator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This is not a complete name, it is something like A::B::, i.e. ends with ::
|
||||||
|
private Name nameSpecifier = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Class name specifier for pointers to members
|
||||||
|
*/
|
||||||
|
public Name getNameSpecifier() {
|
||||||
|
return nameSpecifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the class name specifier for pointers to members.
|
||||||
|
* @param name The name specifier to set
|
||||||
|
*/
|
||||||
|
public void setNameSpecifier(Name name) {
|
||||||
|
this.nameSpecifier = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2003-06-14 Victor Mozgin
|
||||||
|
Fixed handling of parameter lists for typedefs for functions.
|
||||||
|
More errorhandling in CModelBuilder.
|
||||||
|
Added handling of pointers to members.
|
||||||
|
Added handling of declarations for nested scopes (like A::B::C).
|
||||||
|
This fixes PR 36290, 36931 and partially 38920.
|
||||||
|
|
||||||
2003-06-13 John Camelon
|
2003-06-13 John Camelon
|
||||||
Added Class/Base infrastructure to public interfaces & requestor callback.
|
Added Class/Base infrastructure to public interfaces & requestor callback.
|
||||||
Moved many internal interfaces to external packages.
|
Moved many internal interfaces to external packages.
|
||||||
|
|
|
@ -203,11 +203,11 @@ public class CModelBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createElement(Parent parent, SimpleDeclaration simpleDeclaration, Declarator declarator){
|
protected void createElement(Parent parent, SimpleDeclaration simpleDeclaration, Declarator declarator){
|
||||||
|
ParameterDeclarationClause pdc = declarator.getParms();
|
||||||
// typedef
|
// typedef
|
||||||
if(simpleDeclaration.getDeclSpecifier().isTypedef()){
|
if(simpleDeclaration.getDeclSpecifier().isTypedef()){
|
||||||
createTypeDef(parent, declarator, simpleDeclaration);
|
createTypeDef(parent, declarator, simpleDeclaration, pdc);
|
||||||
} else {
|
} else {
|
||||||
ParameterDeclarationClause pdc = declarator.getParms();
|
|
||||||
// variable or field
|
// variable or field
|
||||||
if (pdc == null){
|
if (pdc == null){
|
||||||
createVariableSpecification(parent, simpleDeclaration, declarator, false);
|
createVariableSpecification(parent, simpleDeclaration, declarator, false);
|
||||||
|
@ -400,15 +400,40 @@ public class CModelBuilder {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TypeDef createTypeDef(Parent parent, Declarator declarator, SimpleDeclaration simpleDeclaration){
|
protected TypeDef createTypeDef(Parent parent, Declarator declarator, SimpleDeclaration simpleDeclaration, ParameterDeclarationClause pdc){
|
||||||
// create the element
|
// create the element
|
||||||
Name domName = ( declarator.getDeclarator() != null ) ? declarator.getDeclarator().getName() :
|
Name domName = ( declarator.getDeclarator() != null ) ? declarator.getDeclarator().getName() :
|
||||||
declarator.getName();
|
declarator.getName();
|
||||||
String declaratorName = domName.toString();
|
String declaratorName = domName.toString();
|
||||||
|
|
||||||
TypeDef element = new TypeDef( parent, declaratorName );
|
TypeDef element = new TypeDef( parent, declaratorName );
|
||||||
String type = getType(simpleDeclaration, declarator);
|
StringBuffer typeName = new StringBuffer(getType(simpleDeclaration, declarator));
|
||||||
element.setTypeName(type);
|
|
||||||
|
if (pdc != null) {
|
||||||
|
// getParameterTypes
|
||||||
|
List parameterList = pdc.getDeclarations();
|
||||||
|
String[] parameterTypes = new String[parameterList.size()];
|
||||||
|
|
||||||
|
for (int j = 0; j < parameterList.size(); ++j) {
|
||||||
|
ParameterDeclaration param = (ParameterDeclaration) parameterList.get(j);
|
||||||
|
parameterTypes[j] = new String(getType(param, (Declarator) param.getDeclarators().get(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameterTypes.length > 0) {
|
||||||
|
typeName.append("(");
|
||||||
|
int i = 0;
|
||||||
|
typeName.append(parameterTypes[i++]);
|
||||||
|
while (i < parameterTypes.length) {
|
||||||
|
typeName.append(", ");
|
||||||
|
typeName.append(parameterTypes[i++]);
|
||||||
|
}
|
||||||
|
typeName.append(")");
|
||||||
|
} else {
|
||||||
|
typeName.append("()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.setTypeName(typeName.toString());
|
||||||
|
|
||||||
// add to parent
|
// add to parent
|
||||||
parent.addChild((CElement)element);
|
parent.addChild((CElement)element);
|
||||||
|
@ -428,6 +453,23 @@ public class CModelBuilder {
|
||||||
declarator.getDeclarator().getName() :
|
declarator.getDeclarator().getName() :
|
||||||
declarator.getName();
|
declarator.getName();
|
||||||
|
|
||||||
|
if (domName == null) {
|
||||||
|
// TODO : improve errorhandling
|
||||||
|
// When parsing syntactically incorrect code, we might
|
||||||
|
// end up here. Most often, function/method declaration
|
||||||
|
// misses return type, and is neither a constructor nor
|
||||||
|
// a conversion operator. Like
|
||||||
|
// A::B() {}
|
||||||
|
// Parser sees A::B, understands that it is not a constructor
|
||||||
|
// /conversion, then considers it a declaration. So its
|
||||||
|
// type is read as A::B, no name, and a list of declarations
|
||||||
|
// in ().
|
||||||
|
// For now, we just ignore this scenario (and create no
|
||||||
|
// model elements), but in the future we can process this
|
||||||
|
// declaration as a function (with undefined/no type)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String variableName = domName.toString();
|
String variableName = domName.toString();
|
||||||
DeclSpecifier declSpecifier = simpleDeclaration.getDeclSpecifier();
|
DeclSpecifier declSpecifier = simpleDeclaration.getDeclSpecifier();
|
||||||
|
|
||||||
|
@ -682,12 +724,22 @@ public class CModelBuilder {
|
||||||
StringBuffer type = new StringBuffer();
|
StringBuffer type = new StringBuffer();
|
||||||
// get type from declaration
|
// get type from declaration
|
||||||
type.append(getDeclarationType(declaration));
|
type.append(getDeclarationType(declaration));
|
||||||
// add pointerr or reference from declarator if any
|
// add pointer or reference from declarator if any
|
||||||
type.append(getDeclaratorPointerOperation(declarator));
|
String declaratorPointerOperation = getDeclaratorPointerOperation(declarator);
|
||||||
|
try {
|
||||||
|
switch (declaratorPointerOperation.charAt(0)) {
|
||||||
|
case '*':
|
||||||
|
case '&':
|
||||||
|
break; // pointer/reference
|
||||||
|
default:
|
||||||
|
type.append(" "); // pointer to member
|
||||||
|
}
|
||||||
|
} catch (Exception e) {} // Empty/null strings
|
||||||
|
type.append(declaratorPointerOperation);
|
||||||
if(declarator.getDeclarator() != null){
|
if(declarator.getDeclarator() != null){
|
||||||
// pointer to function or array of functions
|
// pointer to function or array of functions
|
||||||
type.append("(");
|
type.append("(");
|
||||||
// add pointerr or reference from declarator if any
|
// add pointer or reference from declarator if any
|
||||||
type.append(getDeclaratorPointerOperation(declarator.getDeclarator()));
|
type.append(getDeclaratorPointerOperation(declarator.getDeclarator()));
|
||||||
type.append(")");
|
type.append(")");
|
||||||
}
|
}
|
||||||
|
@ -763,6 +815,9 @@ public class CModelBuilder {
|
||||||
while(i.hasNext()){
|
while(i.hasNext()){
|
||||||
PointerOperator po = (PointerOperator) i.next();
|
PointerOperator po = (PointerOperator) i.next();
|
||||||
switch (po.getType()){
|
switch (po.getType()){
|
||||||
|
case PointerOperator.t_pointer_to_member:
|
||||||
|
pointerString.append(po.getNameSpecifier());
|
||||||
|
// Intentional fall-through
|
||||||
case PointerOperator.t_pointer:
|
case PointerOperator.t_pointer:
|
||||||
pointerString.append("*");
|
pointerString.append("*");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -972,52 +972,70 @@ c, quickParse);
|
||||||
{
|
{
|
||||||
if (flags.isForParameterDeclaration()) return false;
|
if (flags.isForParameterDeclaration()) return false;
|
||||||
if (LT(2) == IToken.tLPAREN && flags.isForConstructor()) return true;
|
if (LT(2) == IToken.tLPAREN && flags.isForConstructor()) return true;
|
||||||
|
|
||||||
|
boolean continueProcessing = true;
|
||||||
|
|
||||||
|
// Portions of qualified name
|
||||||
|
// ...::secondLastID<template-args>::lastID ...
|
||||||
|
int secondLastIDTokenPos = -1;
|
||||||
|
int lastIDTokenPos = 1;
|
||||||
|
|
||||||
int posTokenAfterTemplateParameters = 2;
|
int tokenPos = 2;
|
||||||
|
|
||||||
if (LT(posTokenAfterTemplateParameters) == IToken.tLT) {
|
do {
|
||||||
// a case for template constructor, like CFoobar<A,B>::CFoobar
|
if (LT(tokenPos) == IToken.tLT) {
|
||||||
|
// a case for template instantiation, like CFoobar<A,B>::CFoobar
|
||||||
posTokenAfterTemplateParameters++;
|
|
||||||
|
|
||||||
// until we get all the names sorted out
|
|
||||||
int depth = 1;
|
|
||||||
|
|
||||||
while (depth > 0) {
|
|
||||||
switch (LT(posTokenAfterTemplateParameters++)) {
|
|
||||||
case IToken.tGT :
|
|
||||||
--depth;
|
|
||||||
break;
|
|
||||||
case IToken.tLT :
|
|
||||||
++depth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for constructors
|
tokenPos++;
|
||||||
return
|
|
||||||
(
|
// until we get all the names sorted out
|
||||||
(
|
int depth = 1;
|
||||||
(LT(posTokenAfterTemplateParameters) == IToken.tCOLONCOLON)
|
|
||||||
&&
|
while (depth > 0) {
|
||||||
(
|
switch (LT(tokenPos++)) {
|
||||||
LA(posTokenAfterTemplateParameters+1).getImage().equals( LA(1).getImage() ) ||
|
case IToken.tGT :
|
||||||
LT(posTokenAfterTemplateParameters+1) == IToken.tCOMPL
|
--depth;
|
||||||
)
|
break;
|
||||||
)
|
case IToken.tLT :
|
||||||
||
|
++depth;
|
||||||
(
|
break;
|
||||||
// for conversion operators
|
}
|
||||||
(LT(posTokenAfterTemplateParameters) == IToken.tCOLONCOLON)
|
}
|
||||||
&&
|
}
|
||||||
(
|
|
||||||
LT(posTokenAfterTemplateParameters+1) == IToken.t_operator
|
if (LT(tokenPos) == IToken.tCOLONCOLON) {
|
||||||
)
|
tokenPos++;
|
||||||
)
|
|
||||||
);
|
switch (LT(tokenPos)) {
|
||||||
}
|
case IToken.tCOMPL : // for destructors
|
||||||
|
case IToken.t_operator : // for conversion operators
|
||||||
|
return true;
|
||||||
|
case IToken.tIDENTIFIER :
|
||||||
|
secondLastIDTokenPos = lastIDTokenPos;
|
||||||
|
lastIDTokenPos = tokenPos;
|
||||||
|
tokenPos++;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
// Something unexpected after ::
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continueProcessing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (continueProcessing);
|
||||||
|
|
||||||
|
// for constructors
|
||||||
|
|
||||||
|
if (secondLastIDTokenPos < 0) return false;
|
||||||
|
|
||||||
|
String secondLastID = LA(secondLastIDTokenPos).getImage();
|
||||||
|
String lastID = LA(lastIDTokenPos).getImage();
|
||||||
|
|
||||||
|
return secondLastID.equals(lastID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param flags input flags that are used to make our decision
|
* @param flags input flags that are used to make our decision
|
||||||
* @return whether or not this looks like a a declarator follows
|
* @return whether or not this looks like a a declarator follows
|
||||||
|
@ -1772,7 +1790,7 @@ c, quickParse);
|
||||||
* ptrOperator
|
* ptrOperator
|
||||||
* : "*" (cvQualifier)*
|
* : "*" (cvQualifier)*
|
||||||
* | "&"
|
* | "&"
|
||||||
* | name "*" (cvQualifier)*
|
* | class-qualifier "*" (cvQualifier)*
|
||||||
*
|
*
|
||||||
* @param owner Declarator that this pointer operator corresponds to.
|
* @param owner Declarator that this pointer operator corresponds to.
|
||||||
* @throws Backtrack request a backtrack
|
* @throws Backtrack request a backtrack
|
||||||
|
@ -1789,19 +1807,28 @@ c, quickParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
IToken mark = mark();
|
IToken mark = mark();
|
||||||
|
IToken tokenType = LA(1);
|
||||||
|
|
||||||
boolean hasName = false;
|
boolean hasName = false;
|
||||||
if (t == IToken.tIDENTIFIER || t == IToken.tCOLONCOLON)
|
if (t == IToken.tIDENTIFIER || t == IToken.tCOLONCOLON)
|
||||||
{
|
{
|
||||||
|
callback.nameBegin(tokenType);
|
||||||
name();
|
name();
|
||||||
|
callback.nameEnd(lastToken);
|
||||||
hasName = true;
|
hasName = true;
|
||||||
|
t = LT(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == IToken.tSTAR) {
|
if (t == IToken.tSTAR) {
|
||||||
if( hasName )
|
if( hasName ) {
|
||||||
try{ callback.pointerOperatorName( ptrOp );} catch( Exception e ) {}
|
try{ callback.pointerOperatorName( ptrOp );} catch( Exception e ) {}
|
||||||
|
// just consume "*", so tokenType is left as "::" or Id
|
||||||
|
consume();
|
||||||
|
} else {
|
||||||
|
tokenType = consume(); // tokenType = "*"
|
||||||
|
}
|
||||||
|
|
||||||
try{ callback.pointerOperatorType( ptrOp, consume());} catch( Exception e ) {}
|
try{ callback.pointerOperatorType(ptrOp, tokenType);} catch( Exception e ) {}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2003-06-14 Victor Mozgin
|
||||||
|
Moved testBugSingleton192() from LokiFailures to DOMTests.
|
||||||
|
Added testPointersToMembers() and testPointersToMemberFunctions() to DOMTests.
|
||||||
|
Added testBug36290() and testBug36931() to DOMTests.
|
||||||
|
|
||||||
2003-06-13 John Camelon
|
2003-06-13 John Camelon
|
||||||
Added Class/Base infrastructure to public interfaces & requestor callback.
|
Added Class/Base infrastructure to public interfaces & requestor callback.
|
||||||
Moved many internal interfaces to external packages.
|
Moved many internal interfaces to external packages.
|
||||||
|
|
|
@ -25,10 +25,6 @@ public class LokiFailures extends BaseDOMTest {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBugSingleton192() {
|
|
||||||
failTest("int Test::* pMember_;" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBugTypeManip151()
|
public void testBugTypeManip151()
|
||||||
{
|
{
|
||||||
Writer code = new StringWriter();
|
Writer code = new StringWriter();
|
||||||
|
|
|
@ -2082,4 +2082,81 @@ public class DOMTests extends BaseDOMTest {
|
||||||
parse("template <class A,B> X<A,C>::operator A*() { } \n");
|
parse("template <class A,B> X<A,C>::operator A*() { } \n");
|
||||||
parse("template <class A,B> X<A,C>::operator A&() { } \n");
|
parse("template <class A,B> X<A,C>::operator A&() { } \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBugSingleton192() throws Exception {
|
||||||
|
parse("int Test::* pMember_;" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointersToMembers() throws Exception {
|
||||||
|
// Parse and get the translaton unit
|
||||||
|
TranslationUnit translationUnit = parse("int A::* x = 0;");
|
||||||
|
|
||||||
|
List tudeclarations = translationUnit.getDeclarations();
|
||||||
|
assertEquals(1, tudeclarations.size());
|
||||||
|
SimpleDeclaration decl1 = (SimpleDeclaration) tudeclarations.get(0);
|
||||||
|
assertEquals(decl1.getDeclSpecifier().getType(), DeclSpecifier.t_int);
|
||||||
|
|
||||||
|
assertEquals(1, decl1.getDeclarators().size());
|
||||||
|
|
||||||
|
Declarator declarator1 = (Declarator) decl1.getDeclarators().get(0);
|
||||||
|
assertEquals(declarator1.getName().toString(), "x");
|
||||||
|
Expression initValue1 = declarator1.getExpression();
|
||||||
|
assertEquals(initValue1.elements().size(), 1);
|
||||||
|
List ptrOps1 = declarator1.getPointerOperators();
|
||||||
|
assertNotNull(ptrOps1);
|
||||||
|
assertEquals(1, ptrOps1.size());
|
||||||
|
PointerOperator po1 = (PointerOperator) ptrOps1.get(0);
|
||||||
|
assertNotNull(po1);
|
||||||
|
assertFalse(po1.isConst());
|
||||||
|
assertFalse(po1.isVolatile());
|
||||||
|
assertEquals(po1.getType(), PointerOperator.t_pointer_to_member);
|
||||||
|
assertEquals(po1.getNameSpecifier().toString(), "A::");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPointersToMemberFunctions() throws Exception
|
||||||
|
{
|
||||||
|
TranslationUnit tu = parse("void (A::*name)(void);");
|
||||||
|
assertEquals( tu.getDeclarations().size(), 1 );
|
||||||
|
SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0);
|
||||||
|
assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void );
|
||||||
|
assertEquals( declaration.getDeclarators().size(), 1);
|
||||||
|
assertNull( ((Declarator)declaration.getDeclarators().get(0)).getName() );
|
||||||
|
assertNotNull( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator() );
|
||||||
|
assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getName().toString(), "name" );
|
||||||
|
ParameterDeclarationClause clause = ((Declarator)declaration.getDeclarators().get(0)).getParms();
|
||||||
|
assertEquals( clause.getDeclarations().size(), 1 );
|
||||||
|
assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().size(), 1 );
|
||||||
|
assertNull( ((Declarator)((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().get(0)).getName() );
|
||||||
|
assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclSpecifier().getType(), DeclSpecifier.t_void );
|
||||||
|
|
||||||
|
List ptrOps1 = ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getPointerOperators();
|
||||||
|
assertNotNull(ptrOps1);
|
||||||
|
assertEquals(1, ptrOps1.size());
|
||||||
|
PointerOperator po1 = (PointerOperator) ptrOps1.get(0);
|
||||||
|
assertNotNull(po1);
|
||||||
|
assertFalse(po1.isConst());
|
||||||
|
assertFalse(po1.isVolatile());
|
||||||
|
assertEquals(po1.getType(), PointerOperator.t_pointer_to_member);
|
||||||
|
assertEquals(po1.getNameSpecifier().toString(), "A::");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBug36290() throws Exception {
|
||||||
|
parse("typedef void ( A:: * pFunction ) ( void ); ");
|
||||||
|
parse("typedef void (boo) ( void ); ");
|
||||||
|
parse("typedef void boo (void); ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBug36931() throws Exception {
|
||||||
|
parse("A::nested::nested(){}; ");
|
||||||
|
parse("int A::nested::foo() {} ");
|
||||||
|
parse("int A::nested::operator+() {} ");
|
||||||
|
parse("A::nested::operator int() {} ");
|
||||||
|
parse("static const int A::nested::i = 1; ");
|
||||||
|
|
||||||
|
parse("template <class B,C> A<B>::nested::nested(){}; ");
|
||||||
|
parse("template <class B,C> int A::nested<B,D>::foo() {} ");
|
||||||
|
parse("template <class B,C> int A<B,C>::nested<C,B>::operator+() {} ");
|
||||||
|
parse("template <class B,C> A::nested::operator int() {} ");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue