| /******************************************************************************* |
| * Copyright (c) 2005, 2016 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Devin Steffler (IBM Corporation) - initial API and implementation |
| * Markus Schorn (Wind River Systems) |
| * Sergey Prigogin (Google) |
| * Nathan Ridge |
| *******************************************************************************/ |
| package org.eclipse.cdt.core.parser.tests.ast2; |
| |
| import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; |
| import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; |
| import org.eclipse.cdt.core.dom.ast.IASTDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTExpressionList; |
| import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; |
| import org.eclipse.cdt.core.dom.ast.IASTImplicitName; |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; |
| import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; |
| import org.eclipse.cdt.core.dom.ast.IASTTypeId; |
| import org.eclipse.cdt.core.dom.ast.IBasicType; |
| import org.eclipse.cdt.core.dom.ast.IBinding; |
| import org.eclipse.cdt.core.dom.ast.IFunction; |
| import org.eclipse.cdt.core.dom.ast.IProblemBinding; |
| 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.ICPPASTNewExpression; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; |
| 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.ICPPSpecialization; |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; |
| import org.eclipse.cdt.core.parser.ParserLanguage; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; |
| import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; |
| |
| import junit.framework.TestSuite; |
| |
| /** |
| * Examples taken from the c++-specification. |
| */ |
| public class AST2CPPSpecTest extends AST2SpecTestBase { |
| |
| public AST2CPPSpecTest() { |
| } |
| |
| public AST2CPPSpecTest(String name) { |
| super(name); |
| } |
| |
| public static TestSuite suite() { |
| return suite(AST2CPPSpecTest.class); |
| } |
| |
| // int x=x+++++y; |
| public void test2_4s5() throws Exception { |
| parseCandCPP(getAboveComment(), false, 0); |
| } |
| |
| // int a=12, b=014, c=0XC; |
| public void test2_13_1s1() throws Exception { |
| parseCandCPP(getAboveComment(), true, 0); |
| } |
| |
| // ??=define arraycheck(a,b) a??(b??) ??!??! b??(a??) |
| // // becomes |
| // #define arraycheck(a,b) a[b] || b[a] |
| public void test2_3s2() throws Exception { // TODO exists bug 64993 |
| parseCandCPP(getAboveComment(), true, 0); |
| } |
| |
| // int a; // defines a |
| // extern const int c = 1; // defines c |
| // int f(int x) { return x+a; } // defines f and defines x |
| // struct S { int a; int b; }; // defines S, S::a, and S::b |
| // struct X { // defines X |
| // int x; // defines nonstatic data member x |
| // static int y; // declares static data member y |
| // X(): x(0) { } // defines a constructor of X |
| // }; |
| // int X::y = 1; // defines X::y |
| // enum { up, down }; // defines up and down |
| // namespace N { int d; } // defines N and N::d |
| // namespace N1 = N; // defines N1 |
| // X anX; // defines anX |
| // // whereas these are just declarations: |
| // extern int a; // declares a |
| // extern const int c; // declares c |
| // int f(int); // declares f |
| // struct S; // declares S |
| // typedef int Int; // declares Int |
| // extern X anotherX; // declares anotherX |
| // using N::d; // declares N::d |
| public void test3_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct C { |
| // string s; // string is the standard library class (clause 21) |
| // }; |
| // int main() |
| // { |
| // C a; |
| // C b = a; |
| // b = a; |
| // } |
| public void test3_1s4a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct C { |
| // string s; |
| // C(): s() { } |
| // C(const C& x): s(x.s) { } |
| // C& operator=(const C& x) { s = x.s; return *this; } |
| // ~C() { } |
| // }; |
| // |
| public void test3_1s4b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct X; // declare X as a struct type |
| // struct X* x1; // use X in pointer formation |
| // X* x2; // use X in pointer formation |
| public void test3_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // translation unit 1: |
| // struct X { |
| // X(int); |
| // X(int, int); |
| // }; |
| // X::X(int = 0) { } |
| // class D: public X { }; |
| // D d2; // X(int) called by D() |
| public void test3_2s5_a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // translation unit 2: |
| // struct X { |
| // X(int); |
| // X(int, int); |
| // }; |
| // X::X(int = 0, int = 0) { } |
| // class D: public X { }; // X(int, int) called by D(); |
| // // D()'s implicit definition |
| // // violates the ODR |
| public void test3_2s5_b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int j = 24; |
| // int main() |
| // { |
| // int i = j, j; |
| // j = 42; |
| // } |
| public void test3_3s2() throws Exception { |
| parseCandCPP(getAboveComment(), true, 0); |
| } |
| |
| // int foo() { |
| // int x = 12; |
| // { int x = x; } |
| // } |
| public void test3_3_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // const int i = 2; |
| // { int i[i]; } |
| // } |
| public void test3_3_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // const int x = 12; |
| // { enum { x = x }; } |
| // } |
| public void test3_3_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // int i; |
| // int g(int a) { return a; } |
| // int j(); |
| // void q(); |
| // } |
| // namespace { int l=1; } |
| // // the potential scope of l is from its point of declaration |
| // // to the end of the translation unit |
| // namespace N { |
| // int g(char a) // overloads N::g(int) |
| // { |
| // return l+a; // l is from unnamed namespace |
| // } |
| // int i; // error: duplicate definition |
| // int j(); // OK: duplicate function declaration |
| // int j() // OK: definition of N::j() |
| // { |
| // return g(i); // calls N::g(int) |
| // } |
| // int q(); // error: different return type |
| // } |
| public void test3_3_5s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // namespace N { |
| // void f(); |
| // } |
| // } |
| // void A::N::f() { |
| // int i = 5; |
| // // The following scopes are searched for a declaration of i: |
| // // 1) outermost block scope of A::N::f, before the use of i |
| // // 2) scope of namespace N |
| // // 3) scope of namespace A |
| // // 4) global scope, before the definition of A::N::f |
| // } |
| public void test3_4_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace M { |
| // class B { }; |
| // } |
| public void test3_4_1s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { }; |
| // namespace M { |
| // namespace N { |
| // class X : public B { |
| // void f(); |
| // }; |
| // } |
| // } |
| // void M::N::X::f() { |
| // int i = 16; |
| // } |
| // // The following scopes are searched for a declaration of i: |
| // // 1) outermost block scope of M::N::X::f, before the use of i |
| // // 2) scope of class M::N::X |
| // // 3) scope of M::N::X's base class B |
| // // 4) scope of namespace M::N |
| // // 5) scope of namespace M |
| // // 6) global scope, before the definition of M::N::X::f |
| public void test3_4_1s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // typedef int AT; |
| // void f1(AT); |
| // void f2(float); |
| // }; |
| // struct B { |
| // typedef float BT; |
| // friend void A::f1(AT); // parameter type is A::AT |
| // friend void A::f2(BT); // parameter type is B::BT |
| // }; |
| public void test3_4_1s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // public: |
| // static int n; |
| // }; |
| // int main() |
| // { |
| // int A; |
| // A::n = 42; // OK |
| // A b; // illformed: A does not name a type |
| // } |
| public void test3_4_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| } |
| |
| // namespace NS { |
| // class T { }; |
| // void f(T); |
| // } |
| // NS::T parm; |
| // int main() { |
| // f(parm); //OK: calls NS::f |
| // } |
| public void test3_4_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { }; |
| // class C { |
| // class X { }; |
| // static const int number = 50; |
| // static X arr[number]; |
| // }; |
| // X C::arr[number]; // illformed: |
| // // equivalent to: ::X C::arr[C::number]; |
| // // not to: C::X C::arr[C::number]; |
| public void test3_4_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct C { |
| // typedef int I; |
| // }; |
| // typedef int I1, I2; |
| // int foo() { |
| // extern int* p; |
| // extern int* q; |
| // p->C::I::~I(); // I is looked up in the scope of C |
| // q->I1::~I2(); // I2 is looked up in the scope of |
| // }; |
| // // the postfixexpression |
| // struct A { |
| // ~A(); |
| // }; |
| // typedef A AB; |
| // int main() |
| // { |
| // AB *p; |
| // p->AB::~AB(); // explicitly calls the destructor for A |
| // } |
| public void test3_4_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int x; |
| // namespace Y { |
| // void f(float); |
| // void h(int); |
| // } |
| // namespace Z { |
| // void h(double); |
| // } |
| // namespace A { |
| // using namespace Y; |
| // void f(int); |
| // void g(int); |
| // int i; |
| // } |
| // namespace B { |
| // using namespace Z; |
| // void f(char); |
| // int i; |
| // } |
| // namespace AB { |
| // using namespace A; |
| // using namespace B; |
| // void g(); |
| // } |
| // void h() |
| // { |
| // AB::g(); // g is declared directly in AB, |
| // // therefore S is { AB::g() } and AB::g() is chosen |
| // AB::f(1); // f is not declared directly in AB so the rules are |
| // // applied recursively to A and B; |
| // // namespace Y is not searched and Y::f(float) |
| // // is not considered; |
| // // S is { A::f(int), B::f(char) } and overload |
| // // resolution chooses A::f(int) |
| // AB::f('c'); //as above but resolution chooses B::f(char) |
| // AB::x++; // x is not declared directly in AB, and |
| // // is not declared in A or B, so the rules are |
| // // applied recursively to Y and Z, |
| // // S is { } so the program is illformed |
| // AB::i++; // i is not declared directly in AB so the rules are |
| // // applied recursively to A and B, |
| // // S is { A::i, B::i } so the use is ambiguous |
| // // and the program is illformed |
| // AB::h(16.8); // h is not declared directly in AB and |
| // // not declared directly in A or B so the rules are |
| // // applied recursively to Y and Z, |
| // // S is { Y::h(int), Z::h(double) } and overload |
| // // resolution chooses Z::h(double) |
| // } |
| public void test3_4_3_2s2() throws Exception { |
| String[] problems = { "AB::x", "x", "AB::i", "i" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); // qualified names are counted double, so 4 |
| } |
| |
| // namespace A { |
| // int a; |
| // } |
| // namespace B { |
| // using namespace A; |
| // } |
| // namespace C { |
| // using namespace A; |
| // } |
| // namespace BC { |
| // using namespace B; |
| // using namespace C; |
| // } |
| // void f() |
| // { |
| // BC::a++; //OK: S is { A::a, A::a } |
| // } |
| // namespace D { |
| // using A::a; |
| // } |
| // namespace BD { |
| // using namespace B; |
| // using namespace D; |
| // } |
| // void g() |
| // { |
| // BD::a++; //OK: S is { A::a, A::a } |
| // } |
| public void test3_4_3_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace B { |
| // int b; |
| // } |
| // namespace A { |
| // using namespace B; |
| // int a; |
| // } |
| // namespace B { |
| // using namespace A; |
| // } |
| // void f() |
| // { |
| // A::a++; //OK: a declared directly in A, S is { A::a } |
| // B::a++; //OK: both A and B searched (once), S is { A::a } |
| // A::b++; //OK: both A and B searched (once), S is { B::b } |
| // B::b++; //OK: b declared directly in B, S is { B::b } |
| // } |
| public void test3_4_3_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // struct x { }; |
| // int x; |
| // int y; |
| // } |
| // namespace B { |
| // struct y {}; |
| // } |
| // namespace C { |
| // using namespace A; |
| // using namespace B; |
| // int i = C::x; // OK, A::x (of type int) |
| // int j = C::y; // ambiguous, A::y or B::y |
| // } |
| public void test3_4_3_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // namespace B { |
| // void f1(int); |
| // } |
| // using namespace B; |
| // } |
| // void A::f1(int) { } // illformed, |
| // // f1 is not a member of A |
| public void test3_4_3_2s6a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // namespace B { |
| // void f1(int); |
| // } |
| // } |
| // namespace C { |
| // namespace D { |
| // void f1(int); |
| // } |
| // } |
| // using namespace A; |
| // using namespace C::D; |
| // void B::f1(int){} // OK, defines A::B::f1(int) |
| public void test3_4_3_2s6b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct Node { |
| // struct Node* Next; // OK: Refers to Node at global scope |
| // struct Data* Data; // OK: Declares type Data |
| // // at global scope and member Data |
| // }; |
| // struct Data { |
| // struct Node* Node; // OK: Refers to Node at global scope |
| // friend struct ::Glob; // error: Glob is not declared |
| // // cannot introduce a qualified type (7.1.5.3) |
| // friend struct Glob; // OK: Refers to (as yet) undeclared Glob |
| // // at global scope. |
| // |
| // }; |
| // struct Base { |
| // struct Data; // OK: Declares nested Data |
| // struct ::Data* thatData; // OK: Refers to ::Data |
| // struct Base::Data* thisData; // OK: Refers to nested Data |
| // friend class ::Data; // OK: global Data is a friend |
| // friend class Data; // OK: nested Data is a friend |
| // struct Data { // |
| // }; // Defines nested Data |
| // struct Data; // OK: Redeclares nested Data |
| // }; |
| // struct Data; // OK: Redeclares Data at global scope |
| // struct ::Data; // error: cannot introduce a qualified type (7.1.5.3) |
| // struct Base::Data; // error: cannot introduce a qualified type (7.1.5.3) |
| // struct Base::Datum; // error: Datum undefined |
| // struct Base::Data* pBase; // OK: refers to nested Data |
| public void test3_4_4s3() throws Exception { |
| String[] problems = { "::Glob", "Glob", "Base::Datum", "Datum" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // static void f(); |
| // static int i = 0; //1 |
| // void g() { |
| // extern void f(); // internal linkage |
| // int i; //2: i has no linkage |
| // { |
| // extern void f(); // internal linkage |
| // extern int i; //3: external linkage |
| // } |
| // } |
| public void test3_5s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace X { |
| // void p() |
| // { |
| // q(); //error: q not yet declared |
| // extern void q(); // q is a member of namespace X |
| // } |
| // void middle() |
| // { |
| // q(); //error: q not yet declared |
| // } |
| // void q() { // |
| // } // definition of X::q |
| // } |
| // void q() { // |
| // } // some other, unrelated q |
| public void test3_5s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void f() |
| // { |
| // struct A { int x; }; // no linkage |
| // extern A a; // illformed |
| // typedef A B; |
| // extern B b; // illformed |
| // } |
| public void test3_5s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int main(int argc, char* argv[]) { // |
| // } |
| public void test3_6_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual void f(); |
| // void mutate(); |
| // virtual ~B(); |
| // }; |
| // struct D1 : B { void f(); }; |
| // struct D2 : B { void f(); }; |
| // void B::mutate() { |
| // new (this) D2; // reuses storage - ends the lifetime of *this |
| // f(); //undefined behavior |
| // this; // OK, this points to valid memory |
| // } |
| // void g() { |
| // void* p = malloc(sizeof(D1) + sizeof(D2)); |
| // B* pb = new (p) D1; |
| // pb->mutate(); |
| // &pb; //OK: pb points to valid memory |
| // void* q = pb; // OK: pb points to valid memory |
| // pb->f(); //undefined behavior, lifetime of *pb has ended |
| // } |
| public void test3_8s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct C { |
| // int i; |
| // void f(); |
| // const C& operator=( const C& ); |
| // }; |
| // const C& C::operator=( const C& other) |
| // { |
| // if ( this != &other ) { |
| // this->~C(); //lifetime of *this ends |
| // new (this) C(other); // new object of type C created |
| // f(); //welldefined |
| // } |
| // return *this; |
| // } |
| // int foo() { |
| // C c1; |
| // C c2; |
| // c1 = c2; // welldefined |
| // c1.f(); //welldefined; c1 refers to a new object of type C |
| // } |
| public void test3_8s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class T { }; |
| // struct B { |
| // ~B(); |
| // }; |
| // void h() { |
| // B b; |
| // new (&b) T; |
| // } //undefined behavior at block exit |
| public void test3_8s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // B(); |
| // ~B(); |
| // }; |
| // const B b; |
| // void h() { |
| // b.~B(); |
| // new (&b) const B; // undefined behavior |
| // } |
| public void test3_8s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // #define N sizeof(T) |
| // void test() { |
| // char buf[N]; |
| // T obj; // obj initialized to its original value |
| // memcpy(buf, &obj, N); // between these two calls to memcpy, |
| // // obj might be modified |
| // memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type |
| // // holds its original value |
| // } |
| public void test3_9s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void test() { |
| // T* t1p; |
| // T* t2p; |
| // // provided that t2p points to an initialized object ... |
| // memcpy(t1p, t2p, sizeof(T)); // at this point, every subobject of POD type in *t1p contains |
| // // the same value as the corresponding subobject in *t2p |
| // } |
| public void test3_9s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class X; // X is an incomplete type |
| // extern X* xp; // xp is a pointer to an incomplete type |
| // extern int arr[]; // the type of arr is incomplete |
| // typedef int UNKA[]; // UNKA is an incomplete type |
| // UNKA* arrp; // arrp is a pointer to an incomplete type |
| // UNKA** arrpp; |
| // void foo() { |
| // xp++; //ill-formed: X is incomplete |
| // arrp++; //ill-formed: incomplete type |
| // arrpp++; //OK: sizeof UNKA* is known |
| // } |
| // struct X { |
| // int i; |
| // }; // now X is a complete type |
| // int arr[10]; // now the type of arr is complete |
| // X x; |
| // void bar() { |
| // xp = &x; // OK; type is ''pointer to X'' |
| // arrp = &arr; // ill-formed: different types |
| // xp++; //OK: X is complete |
| // arrp++; //ill-formed: UNKA can't be completed |
| // } |
| public void test3_9s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int& f(); |
| public void test3_10s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // i = v[i++]; // the behavior is unspecified |
| // i = 7, i++, i++; // i becomes 9 |
| // i = ++i + 1; // the behavior is unspecified |
| // i = i + 1; // the value of i is incremented |
| // } |
| public void test5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct B {}; |
| // struct D : B {}; |
| // void foo(D* dp) |
| // { |
| // B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp; |
| // } |
| public void test5_2_7s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { virtual void f(); }; |
| // class B { virtual void g(); }; |
| // class D : public virtual A, private B {}; |
| // void g() |
| // { |
| // D d; |
| // B* bp = (B*)&d; // cast needed to break protection |
| // A* ap = &d; // public derivation, no cast needed |
| // D& dr = dynamic_cast<D&>(*bp); // fails |
| // ap = dynamic_cast<A*>(bp); // fails |
| // bp = dynamic_cast<B*>(ap); // fails |
| // ap = dynamic_cast<A*>(&d); // succeeds |
| // bp = dynamic_cast<B*>(&d); // fails |
| // } |
| // class E : public D, public B {}; |
| // class F : public E, public D {}; |
| // void h() |
| // { |
| // F f; |
| // A* ap = &f; // succeeds: finds unique A |
| // D* dp = dynamic_cast<D*>(ap); // fails: yields 0 |
| // // f has two D subobjects |
| // E* ep = (E*)ap; // illformed: |
| // // cast from virtual base |
| // E* ep1 = dynamic_cast<E*>(ap); // succeeds |
| // } |
| public void test5_2_7s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class D { // ... |
| // }; |
| // D d1; |
| // const D d2; |
| // int foo() { |
| // typeid(d1) == typeid(d2); // yields true |
| // typeid(D) == typeid(const D); // yields true |
| // typeid(D) == typeid(d2); // yields true |
| // typeid(D) == typeid(const D&); // yields true |
| // } |
| public void test5_2_8s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B {}; |
| // struct D : public B {}; |
| // D d; |
| // B &br = d; |
| // int foo() { |
| // static_cast<D&>(br); // produces lvalue to the original d object |
| // } |
| public void test5_2_9s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { int i; }; |
| // struct B : A { }; |
| // int foo() { |
| // &B::i; // has type int A::* |
| // } |
| public void test5_3_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void test() { |
| // new (int (*[10])()); |
| // }; |
| public void test5_3_4s3() throws Exception { |
| IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| IASTFunctionDefinition fdef = getDeclaration(tu, 0); |
| IASTExpression expr = getExpressionOfStatement(fdef, 0); |
| assertInstance(expr, ICPPASTNewExpression.class); |
| ICPPASTNewExpression newExpr = (ICPPASTNewExpression) expr; |
| |
| assertNull(newExpr.getNewPlacement()); |
| assertNull(newExpr.getNewInitializer()); |
| IASTTypeId typeid = newExpr.getTypeId(); |
| isTypeEqual(CPPVisitor.createType(typeid), "int (* [10])()"); |
| } |
| |
| // typedef int T; |
| // void test(int f) { |
| // new T; |
| // new(2,f) T; |
| // new T[5]; |
| // new (2,f) T[5]; |
| // }; |
| public void test5_3_4s12() throws Exception { |
| // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=236856 |
| |
| IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| IASTFunctionDefinition fdef = getDeclaration(tu, 1); |
| |
| // new T; |
| IASTExpression expr = getExpressionOfStatement(fdef, 0); |
| assertInstance(expr, ICPPASTNewExpression.class); |
| ICPPASTNewExpression newExpr = (ICPPASTNewExpression) expr; |
| assertNull(newExpr.getNewPlacement()); |
| assertNull(newExpr.getNewInitializer()); |
| isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int"); |
| |
| // new(2,f) T; |
| expr = getExpressionOfStatement(fdef, 1); |
| assertInstance(expr, ICPPASTNewExpression.class); |
| newExpr = (ICPPASTNewExpression) expr; |
| assertInstance(newExpr.getNewPlacement(), IASTExpressionList.class); |
| assertNull(newExpr.getNewInitializer()); |
| isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int"); |
| |
| // new T[5]; |
| expr = getExpressionOfStatement(fdef, 2); |
| assertInstance(expr, ICPPASTNewExpression.class); |
| newExpr = (ICPPASTNewExpression) expr; |
| assertNull(newExpr.getNewPlacement()); |
| assertNull(newExpr.getNewInitializer()); |
| isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]"); |
| |
| // new (2,f) T[5]; |
| expr = getExpressionOfStatement(fdef, 3); |
| assertInstance(expr, ICPPASTNewExpression.class); |
| newExpr = (ICPPASTNewExpression) expr; |
| assertInstance(newExpr.getNewPlacement(), IASTExpressionList.class); |
| assertNull(newExpr.getNewInitializer()); |
| isTypeEqual(CPPVisitor.createType(newExpr.getTypeId()), "int [5]"); |
| } |
| |
| // int n=2; |
| // int x=new float[n][5]; |
| // int y=new float[5][n]; |
| public void test5_3_4s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // const char* strchr(const char* s, int c); |
| // bool b = noexcept (strchr("abc", 'b')); |
| public void test5_3_7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A {}; |
| // struct I1 : A {}; |
| // struct I2 : A {}; |
| // struct D : I1, I2 {}; |
| // A *foo( D *p ) { |
| // return (A*)( p ); // illformed |
| // // static_cast interpretation |
| // } |
| public void test5_4s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // (ptr_to_obj->*ptr_to_mfct)(10); |
| // } |
| public void test5_5s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void *p; |
| // const int *q; |
| // int **pi; |
| // const int *const *pci; |
| // void ct() |
| // { |
| // p <= q; // Both converted to const void * before comparison |
| // pi <= pci; // Both converted to const int *const * before comparison |
| // } |
| public void test5_9s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // int f(); |
| // }; |
| // struct L : B { }; |
| // struct R : B { }; |
| // struct D : L, R { }; |
| // int (B::*pb)() = &B::f; |
| // int (L::*pl)() = pb; |
| // int (R::*pr)() = pb; |
| // int (D::*pdl)() = pl; |
| // int (D::*pdr)() = pr; |
| // bool x = (pdl == pdr); // false |
| public void test5_10s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(int, int, int) {} |
| // int foo() { |
| // int a=0, t=1, c=2; |
| // f(a, (t=3, t+2), c); |
| // } |
| public void test5_18s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // int x=0; |
| // if (x) |
| // int i; |
| // |
| // if (x) { |
| // int i; |
| // } |
| // } |
| public void test6_4s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // if (int x = 1) { |
| // int x; // illformed,redeclaration of x |
| // } |
| // else { |
| // int x; // illformed,redeclaration of x |
| // } |
| // } |
| public void test6_4s3() throws Exception { |
| // raised bug 90618 |
| // gcc does not report an error, either, so leave it as it is. |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // int x=5; |
| // while (--x >= 0) |
| // int i; |
| // //can be equivalently rewritten as |
| // while (--x >= 0) { |
| // int i; |
| // } |
| // } |
| public void test6_5s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // int val; |
| // A(int i) : val(i) { } |
| // ~A() { } |
| // operator bool() { return val != 0; } |
| // }; |
| // |
| // int foo() { |
| // int i = 1; |
| // while (A a = i) { |
| // //... |
| // i = 0; |
| // } |
| // } |
| public void test6_5_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // int i = 42; |
| // int a[10]; |
| // for (int i = 0; i < 10; i++) |
| // a[i] = i; |
| // int j = i; // j = 42 |
| // } |
| public void test6_5_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f() |
| // { |
| // // ... |
| // goto lx; // illformed: jump into scope of a |
| // // ... |
| // ly: |
| // X a = 1; // X is undefined |
| // // ... |
| // lx: |
| // goto ly; // OK, jump implies destructor |
| // // call for a followed by construction |
| // // again immediately following label ly |
| // } |
| public void test6_7s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| } |
| |
| // int foo(int i) |
| // { |
| // static int s = foo(2*i); // recursive call - undefined |
| // return i+1; |
| // } |
| public void test6_7s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // T(a)->m = 7; // expressionstatement |
| // T(a)++; //expressionstatement |
| // T(a,5)<<c; //expressionstatement |
| // T(*d)(int); //declaration |
| // T(e)[5]; //declaration |
| // T(f) = { 1, 2 }; // declaration |
| // T(*g)(double(3)); // declaration |
| // } |
| public void test6_8s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class T { |
| // // ... |
| // public: |
| // T(); |
| // T(int); |
| // T(int, int); |
| // }; |
| // T(a); //declaration |
| // T(*b)(); //declaration |
| // T(c)=7; //declaration |
| // T(d),e,f=3; //declaration |
| // extern int h; |
| // T(g)(h,2); //declaration |
| public void test6_8s2() throws Exception { // TODO raised bug 90622 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct T1 { |
| // T1 operator()(int x) { return T1(x); } |
| // int operator=(int x) { return x; } |
| // T1(int) { } |
| // }; |
| // struct T2 { T2(int){ } }; |
| // int a, (*(*b)(T2))(int), c, d; |
| // void f() { |
| // // disambiguation requires this to be parsed |
| // // as a declaration |
| // T1(a) = 3, |
| // T2(4), // T2 will be declared as |
| // (*(*b)(T2(c)))(int(d)); // a variable of type T1 |
| // // but this will not allow |
| // // the last part of the |
| // // declaration to parse |
| // // properly since it depends |
| // // on T2 being a typename |
| // } |
| public void test6_8s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef char* Pc; |
| // void f(const Pc); // void f(char* const) (not const char*) |
| // void g(const int Pc); // void g(const int) |
| public void test7_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void h(unsigned Pc); // void h(unsigned int) |
| // void k(unsigned int Pc); // void k(unsigned int) |
| public void test7_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // thread_local int e; |
| // static thread_local int f; |
| // extern thread_local int g; |
| public void test7_1_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // static char* f(); // f() has internal linkage |
| // char* f() // f() still has internal linkage |
| // { // |
| // } |
| // char* g(); // g() has external linkage |
| // static char* g() // error: inconsistent linkage |
| // { // |
| // } |
| // void h(); |
| // inline void h(); // external linkage |
| // inline void l(); |
| // void l(); // external linkage |
| // inline void m(); |
| // extern void m(); // external linkage |
| // static void n(); |
| // inline void n(); // internal linkage |
| // static int a; // a has internal linkage |
| // int a; // error: two definitions |
| // static int b; // b has internal linkage |
| // extern int b; // b still has internal linkage |
| // int c; // c has external linkage |
| // static int c; // error: inconsistent linkage |
| // extern int d; // d has external linkage |
| // static int d; // error: inconsistent linkage |
| public void test7_1_1s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S; |
| // extern S a; |
| // extern S f(); |
| // extern void g(S); |
| // void h() |
| // { |
| // g(a); //error: S is incomplete |
| // f(); //error: S is incomplete |
| // } |
| public void test7_1_1s8a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // mutable const int* p; // OK |
| // mutable int* const q; // illformed |
| // }; |
| public void test7_1_1s8b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int MILES, *KLICKSP; |
| // MILES distance; |
| // extern KLICKSP metricp; |
| public void test7_1_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef struct s { // |
| // } s; |
| // typedef int I; |
| // typedef int I; |
| // typedef I I; |
| public void test7_1_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class complex { // |
| // }; |
| // typedef int complex; // error: redefinition |
| public void test7_1_3s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int complex; |
| // class complex { // |
| // }; // error: redefinition |
| public void test7_1_3s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // S(); |
| // ~S(); |
| // }; |
| // typedef struct S T; |
| // S a = T(); // OK |
| // struct T * p; // error |
| public void test7_1_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef struct { } *ps, S; // S is the class name for linkage purposes |
| public void test7_1_3s5a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef struct { |
| // S(); //error: requires a return type because S is |
| // // an ordinary member function, not a constructor |
| // } S; |
| public void test7_1_3s5b() throws Exception { |
| IASTTranslationUnit tu = parseWithErrors(getAboveComment(), ParserLanguage.CPP); |
| IASTCompositeTypeSpecifier comp = getCompositeType(tu, 0); |
| IASTDeclaration d = getDeclaration(comp, 0); |
| assertInstance(d, IASTProblemDeclaration.class); |
| } |
| |
| // constexpr int square(int x); |
| // constexpr int bufsz = 1024; |
| // struct pixel { |
| // int x; |
| // int y; |
| // constexpr pixel(int); |
| // }; |
| // constexpr pixel::pixel(int a) |
| // : x(square(a)), y(square(a)) |
| // { } |
| // constexpr int square(int x) { |
| // return x * x; |
| // } |
| // constexpr pixel large(4); |
| public void test7_1_5s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // const int ci = 3; // cvqualified (initialized as required) |
| // ci = 4; // illformed: attempt to modify const |
| // int i = 2; // not cvqualified |
| // const int* cip; // pointer to const int |
| // cip = &i; // OK: cvqualified access path to unqualified |
| // *cip = 4; // illformed: attempt to modify through ptr to const |
| // int* ip; |
| // ip = const_cast<int*>(cip); // cast needed to convert const int* to int* |
| // *ip = 4; // defined: *ip points to i, a nonconst object |
| // const int* ciq = new const int (3); // initialized as required |
| // int* iq = const_cast<int*>(ciq); // cast required |
| // *iq = 4; // undefined: modifies a const object |
| // } |
| public void test7_1_5_1s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // mutable int i; |
| // int j; |
| // }; |
| // class Y { |
| // public: |
| // X x; |
| // Y(); |
| // }; |
| // |
| // int foo() { |
| // const Y y; |
| // y.x.i++; //wellformed: mutable member can be modified |
| // y.x.j++; //illformed: constqualified member modified |
| // Y* p = const_cast<Y*>(&y); // cast away constness of y |
| // p->x.i = 99; // wellformed: mutable member can be modified |
| // p->x.j = 99; // undefined: modifies a const member |
| // } |
| public void test7_1_5_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // enum { a, b, c=0 }; |
| // enum { d, e, f=e+2 }; |
| public void test7_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // const int x = 12; |
| // { enum { x = x }; } |
| // } |
| public void test7_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // enum color { red, yellow, green=20, blue }; |
| // color col = red; |
| // color* cp = &col; |
| // if (*cp == blue) // ... |
| // return 0; |
| // } |
| public void test7_2s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // enum direction { left='l', right='r' }; |
| // int f(int i) |
| // { return i==left ? 0 : i==right ? 1 : 2; } |
| // }; |
| // void g(X* p) |
| // { |
| // direction d; // error: direction not in scope |
| // int i; |
| // i = p->f(left); // error: left not in scope |
| // i = p> |
| // f(X::right); // OK |
| // i = p> |
| // f(p->left); // OK |
| // // ... |
| // } |
| public void test7_2s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // namespace Outer { |
| // int i; |
| // namespace Inner { |
| // void f() { i++; } // Outer::i |
| // int i; |
| // void g() { i++; } // Inner::i |
| // } |
| // } |
| public void test7_3_1s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace { int i; } // unique::i |
| // void f() { i++; } // unique::i++ |
| // namespace A { |
| // namespace { |
| // int i; // A::unique::i |
| // int j; // A::unique::j |
| // } |
| // void g() { i++; } // A::unique::i++ |
| // } |
| // using namespace A; |
| // void h() { |
| // i++; //error: unique::i or A::unique::i |
| // A::i++; // A::unique::i |
| // j++; // A::unique::j |
| // } |
| public void test7_3_1_1s1() throws Exception { |
| String[] problems = { "i" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // namespace X { |
| // void f() { // |
| // } |
| // } |
| public void test7_3_1_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace Q { |
| // namespace V { |
| // void f(); |
| // } |
| // void V::f() { } // OK |
| // void V::g() { } // error: g() is not yet a member of V |
| // namespace V { |
| // void g(); |
| // } |
| // } |
| // namespace R { |
| // void Q::V::g() { } // error: R doesn't enclose Q |
| // } |
| public void test7_3_1_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 2); |
| } |
| |
| // // Assume f and g have not yet been defined. |
| // void h(int); |
| // namespace A { |
| // class X { |
| // friend void f(X); // A::f is a friend |
| // class Y { |
| // friend void g(); // A::g is a friend |
| // friend void h(int); // A::h is a friend |
| // // ::h not considered |
| // }; |
| // }; |
| // // A::f, A::g and A::h are not visible here |
| // X x; |
| // void g() { f(x); } // definition of A::g |
| // void f(X) { } // definition of A::f |
| // void h(int) { } // definition of A::h |
| // // A::f, A::g and A::h are visible here and known to be friends |
| // } |
| // using A::x; |
| // void h() |
| // { |
| // A::f(x); |
| // A::X::f(x); //error: f is not a member of A::X |
| // A::X::Y::g(); // error: g is not a member of A::X::Y |
| // } |
| public void test7_3_1_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 4); |
| } |
| |
| // namespace Company_with_very_long_name { } |
| // namespace CWVLN = Company_with_very_long_name; |
| // namespace CWVLN = Company_with_very_long_name; // OK: duplicate |
| // namespace CWVLN = CWVLN; |
| public void test7_3_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // void f(char); |
| // void g(char); |
| // enum E { e }; |
| // union { int x; }; |
| // }; |
| // struct D : B { |
| // using B::f; |
| // void f(int) { f('c'); } // calls B::f(char) |
| // void g(int) { g('c'); } // recursively calls D::g(int) |
| // }; |
| public void test7_3_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { |
| // int g(); |
| // }; |
| // class D2 : public B { |
| // using B::f; // OK: B is a base of D2 |
| // using B::e; // OK: e is an enumerator of base B |
| // using B::x; // OK: x is a union member of base B |
| // using C::g; // error: C isn't a base of D2 |
| // }; |
| public void test7_3_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class A { |
| // public: |
| // template <class T> void f(T); |
| // template <class T> struct X { }; |
| // }; |
| // class B : public A { |
| // public: |
| // using A::f<double>; // illformed |
| // using A::X<int>; // illformed |
| // }; |
| public void test7_3_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // int i; |
| // static int s; |
| // }; |
| // void f() |
| // { |
| // using X::i; // error: X::i is a class member |
| // // and this is not a member declaration. |
| // using X::s; // error: X::s is a class member |
| // // and this is not a member declaration. |
| // } |
| public void test7_3_3s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f(); |
| // namespace A { |
| // void g(); |
| // } |
| // namespace X { |
| // using ::f; // global f |
| // using A::g; // A's g |
| // } |
| // void h() |
| // { |
| // X::f(); //calls ::f |
| // X::g(); //calls A::g |
| // } |
| public void test7_3_3s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // int i; |
| // } |
| // namespace A1 { |
| // using A::i; |
| // using A::i; // OK: double declaration |
| // } |
| // void f() |
| // { |
| // using A::i; |
| // using A::i; // error: double declaration |
| // } |
| // class B { |
| // public: |
| // int i; |
| // }; |
| // class X : public B { |
| // using B::i; |
| // using B::i; // error: double member declaration |
| // }; |
| public void test7_3_3s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // void f(int); |
| // } |
| // using A::f; // f is a synonym for A::f; |
| // // that is, for A::f(int). |
| // namespace A { |
| // void f(char); |
| // } |
| // void foo() |
| // { |
| // f('a'); //calls f(int), |
| // } //even though f(char) exists. |
| // void bar() |
| // { |
| // using A::f; // f is a synonym for A::f; |
| // // that is, for A::f(int) and A::f(char). |
| // f('a'); //calls f(char) |
| // } |
| public void test7_3_3s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual void f(int); |
| // virtual void f(char); |
| // void g(int); |
| // void h(int); |
| // }; |
| // struct D : B { |
| // using B::f; |
| // void f(int); // OK: D::f(int) overrides B::f(int); |
| // using B::g; |
| // void g(char); // OK |
| // using B::h; |
| // void h(int); // OK: D::h(int) hides B::h(int) |
| // }; |
| // void k(D* p) |
| // { |
| // p->f(1); //calls D::f(int) |
| // p->f('a'); //calls B::f(char) |
| // p->g(1); //calls B::g(int) |
| // p->g('a'); //calls D::g(char) |
| // } |
| public void test7_3_3s12() throws Exception { // raised bug 161562 for that |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // int x; |
| // } |
| // namespace B { |
| // int i; |
| // struct g { }; |
| // struct x { }; |
| // void f(int); |
| // void f(double); |
| // void g(char); // OK: hides struct g |
| // } |
| // void func() |
| // { |
| // int i; |
| // //using B::i; // error: i declared twice |
| // void f(char); |
| // using B::f; // OK: each f is a function |
| // f(3.5); //calls B::f(double) |
| // using B::g; |
| // g('a'); //calls B::g(char) |
| // struct g g1; // g1 has class type B::g |
| // using B::x; |
| // using A::x; // OK: hides struct B::x |
| // x = 99; // assigns to A::x |
| // struct x x1; // x1 has class type B::x |
| // } |
| public void test7_3_3s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace B { |
| // void f(int); |
| // void f(double); |
| // } |
| // namespace C { |
| // void f(int); |
| // void f(double); |
| // void f(char); |
| // } |
| // void h() |
| // { |
| // using B::f; // B::f(int) and B::f(double) |
| // using C::f; // C::f(int), C::f(double), and C::f(char) |
| // f('h'); //calls C::f(char) |
| // f(1); //error: ambiguous: B::f(int) or C::f(int) ? |
| // void f(int); // error: |
| // // f(int) conflicts with C::f(int) and B::f(int) |
| // } |
| public void test7_3_3s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { int x(); }; |
| // struct B : A { }; |
| // struct C : A { |
| // using A::x; |
| // int x(int); |
| // }; |
| // struct D : B, C { |
| // using C::x; |
| // int x(double); |
| // }; |
| // int f(D* d) { |
| // return d> |
| // x(); // ambiguous: B::x or C::x |
| // } |
| public void test7_3_3s14() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class A { |
| // private: |
| // void f(char); |
| // public: |
| // void f(int); |
| // protected: |
| // void g(); |
| // }; |
| // class B : public A { |
| // using A::f; // error: A::f(char) is inaccessible |
| // public: |
| // using A::g; // B::g is a public synonym for A::g |
| // }; |
| public void test7_3_3s15() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // int i; |
| // namespace B { |
| // namespace C { |
| // int i; |
| // } |
| // using namespace A::B::C; |
| // void f1() { |
| // i = 5; // OK, C::i visible in B and hides A::i |
| // } |
| // } |
| // namespace D { |
| // using namespace B; |
| // using namespace C; |
| // void f2() { |
| // i = 5; // ambiguous, B::C::i or A::i? |
| // } |
| // } |
| // void f3() { |
| // i = 5; // uses A::i |
| // } |
| // } |
| // void f4() { |
| // i = 5; // illformed; neither i is visible |
| // } |
| public void test7_3_4s1() throws Exception { |
| String[] problems = { "i", "i" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // namespace M { |
| // int i; |
| // } |
| // namespace N { |
| // int i; |
| // using namespace M; |
| // } |
| // void f() |
| // { |
| // using namespace N; |
| // i = 7; // error: both M::i and N::i are visible |
| // } |
| public void test7_3_4s2a() throws Exception { |
| String[] problems = { "i" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // namespace A { |
| // int i; |
| // } |
| // namespace B { |
| // int i; |
| // int j; |
| // namespace C { |
| // namespace D { |
| // using namespace A; |
| // int j; |
| // int k; |
| // int a = i; // B::i hides A::i |
| // } |
| // using namespace D; |
| // int k = 89; // no problem yet |
| // int l = k; // ambiguous: C::k or D::k |
| // int m = i; // B::i hides A::i |
| // int n = j; // D::j hides B::j |
| // } |
| // } |
| public void test7_3_4s2b() throws Exception { |
| String[] problems = { "k" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // namespace D { |
| // int d1; |
| // void f(char); |
| // } |
| // using namespace D; |
| // int d1; // OK: no conflict with D::d1 |
| // namespace E { |
| // int e; |
| // void f(int); |
| // } |
| // namespace D { // namespace extension |
| // int d2; |
| // using namespace E; |
| // void f(int); |
| // } |
| // void f() |
| // { |
| // d1++; //error: ambiguous ::d1 or D::d1? |
| // ::d1++; //OK |
| // D::d1++; //OK |
| // d2++; //OK: D::d2 |
| // e++; //OK: E::e |
| // f(1); //error: ambiguous: D::f(int) or E::f(int)? |
| // f('a'); //OK: D::f(char) |
| // } |
| public void test7_3_4s5() throws Exception { |
| String[] problems = { "d1", "f" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // complex sqrt(complex); // C++ linkage by default |
| // extern "C" { |
| // double sqrt(double); // C linkage |
| // } |
| public void test7_5s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // extern "C" void f1(void(*pf)(int)); |
| // // the name f1 and its function type have C language |
| // // linkage; pf is a pointer to a C function |
| // extern "C" typedef void FUNC(); |
| // FUNC f2; // the name f2 has C++ language linkage and the |
| // // function's type has C language linkage |
| // extern "C" FUNC f3; // the name of function f3 and the function's type |
| // // have C language linkage |
| // void (*pf2)(FUNC*); // the name of the variable pf2 has C++ linkage and |
| // // the type of pf2 is pointer to C++ function that |
| // // takes one parameter of type pointer to C function |
| public void test7_5s4a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // extern "C" typedef void FUNC_c(); |
| // class C { |
| // void mf1(FUNC_c*); // the name of the function mf1 and the member |
| // // function's type have C++ language linkage; the |
| // // parameter has type pointer to C function |
| // FUNC_c mf2; // the name of the function mf2 and the member |
| // // function's type have C++ language linkage |
| // static FUNC_c* q; // the name of the data member q has C++ language |
| // // linkage and the data member's type is pointer to |
| // // C function |
| // }; |
| // extern "C" { |
| // class X { |
| // void mf(); // the name of the function mf and the member |
| // // function's type have C++ language linkage |
| // void mf2(void(*)()); // the name of the function mf2 has C++ language |
| // // linkage; the parameter has type pointer to |
| // // C function |
| // }; |
| // } |
| public void test7_5s4b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // extern "C" int f(); |
| // extern "C" int g() { return 1; } |
| // extern "C" int h(); |
| // } |
| // namespace B { |
| // extern "C" int f(); // A::f and B::f refer |
| // // to the same function |
| // extern "C" int g() { return 1; } // illformed, |
| // // the function g |
| // // with C language linkage |
| // // has two definitions |
| // } |
| // int A::f() { return 98; } // definition for the function f |
| // // with C language linkage |
| // extern "C" int h() { return 97; } |
| // // definition for the function h |
| // // with C language linkage |
| // // A::h and ::h refer to the same function |
| public void test7_5s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // extern "C" double f(); |
| // static double f(); // error |
| public void test7_5s7a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // extern "C" int i; // declaration |
| // extern "C" { |
| // int i; // definition |
| // } |
| public void test7_5s7b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // extern "C" static void f(); // error |
| public void test7_5s7c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int i; |
| // int *pi; |
| // int *p[3]; |
| // int (*p3i)[3]; |
| // int *f(); |
| // int (*pf)(double); |
| public void test8_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // S(int); |
| // }; |
| // void foo(double a) |
| // { |
| // S w(int(a)); // function declaration |
| // S x(int()); // function declaration |
| // S y((int)a); // object declaration |
| // S z = int(a); // object declaration |
| // } |
| public void test8_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> |
| // struct S { |
| // T *p; |
| // }; |
| // S<int()> x; // typeid |
| // S<int(1)> y; // expression (illformed) |
| public void test8_2s4() throws Exception { |
| IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| NameCollector col = new NameCollector(); |
| tu.accept(col); |
| |
| assertInstance(col.getName(4), ICPPASTTemplateId.class); |
| assertInstance(((ICPPASTTemplateId) col.getName(4)).getTemplateArguments()[0], IASTTypeId.class); |
| |
| final IASTName S_int_1 = col.getName(7); |
| assertInstance(S_int_1, ICPPASTTemplateId.class); |
| assertInstance(((ICPPASTTemplateId) S_int_1).getTemplateArguments()[0], IASTExpression.class); |
| assertInstance(S_int_1.getBinding(), IProblemBinding.class); |
| } |
| |
| // void foo() |
| // { |
| // sizeof(int(1)); // expression |
| // // sizeof(int()); // typeid (illformed) |
| // } |
| public void test8_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void foo() |
| // { |
| // (int(1)); //expression |
| // // (int())1; //typeid (illformed) |
| // } |
| public void test8_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { }; |
| // void f(int(C)) { } // void f(int (*fp)(C c)) { } |
| // // not: void f(int C); |
| // int g(C); |
| // void foo() { |
| // f(1); //error: cannot convert 1 to function pointer |
| // f(g); //OK |
| // } |
| public void test8_2s7a() throws Exception { // TODO raised bug 90633 |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 1); |
| |
| BindingAssertionHelper ba = new AST2AssertionHelper(code, true); |
| IFunction f = ba.assertNonProblem("f", 1, IFunction.class); |
| isTypeEqual(f.getType(), "void (int (*)(C))"); |
| } |
| |
| // class C { }; |
| // void h(int *(C[10])); // void h(int *(*_fp)(C _parm[10])); |
| // // not: void h(int *C[10]); |
| public void test8_2s7b() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper ba = new AST2AssertionHelper(code, true); |
| IFunction f = ba.assertNonProblem("h", 1, IFunction.class); |
| isTypeEqual(f.getType(), "void (int * (*)(C *))"); |
| } |
| |
| // namespace A { |
| // struct B { |
| // void f(); |
| // }; |
| // void A::B::f() { } // illformed: the declarator must not be |
| // // qualified with A:: |
| // } |
| public void test8_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int unsigned i; |
| public void test8_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; |
| // int i, *p, *const cp = &i; |
| // |
| // int f() { |
| // i = ci; |
| // *cp = ci; |
| // pc++; |
| // pc = cpc; |
| // pc = p; |
| // ppc = &pc; |
| // } |
| public void test8_3_1s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; |
| // int i, *p, *const cp = &i; |
| // int f() { |
| // ci = 1; // error |
| // ci++; //error |
| // *pc = 2; // error |
| // cp = &ci; // error |
| // cpc++; //error |
| // p = pc; // error |
| // ppc = &p; // error |
| // } |
| public void test8_3_1s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; |
| // int i, *p, *const cp = &i; |
| // int f() { |
| // *ppc = &ci; // OK, but would make p point to ci ... |
| // *p = 5; // clobber ci |
| // } |
| public void test8_3_1s2c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int& A; |
| // const A aref = 3; // illformed; |
| // // nonconst reference initialized with rvalue |
| public void test8_3_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f(double& a) { a += 3.14; } |
| // void foo1() { |
| // double d = 0; |
| // f(d); |
| // } |
| // |
| // int v[20]; |
| // int& g(int i) { return v[i]; } |
| // void foo2() { |
| // g(3) = 7; |
| // } |
| // |
| // struct link { |
| // link* next; |
| // }; |
| // link* first; |
| // void h(link*& p) // p is a reference to pointer |
| // { |
| // p->next = first; |
| // first = p; |
| // p = 0; |
| // } |
| // void k() |
| // { |
| // link* q = new link; |
| // h(q); |
| // } |
| public void test8_3_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // void f(int); |
| // int a; |
| // }; |
| // class Y; |
| // |
| // void f() { |
| // int X::* pmi = &X::a; |
| // void (X::* pmf)(int) = &X::f; |
| // double X::* pmd; |
| // char Y::* pmc; |
| // X obj; |
| // //... |
| // obj.*pmi = 7; // assign 7 to an integer |
| // // member of obj |
| // (obj.*pmf)(7); //call a function member of obj |
| // // with the argument 7 |
| // } |
| public void test8_3_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int A[5], AA[2][3]; |
| // typedef const A CA; // type is ''array of 5 const int'' |
| // typedef const AA CAA; // type is ''array of 2 array of 3 const int'' |
| public void test8_3_4s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // float fa[17], *afp[17]; |
| // static int x3d[3][5][7]; |
| public void test8_3_4s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int x[3][5]; |
| public void test8_3_4s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int printf(const char*, ...); |
| // int f() { |
| // int a=1, b=0; |
| // printf("hello world"); |
| // printf("a=%d b=%d", a, b); |
| // } |
| public void test8_3_5s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef void F(); |
| // struct S { |
| // const F f; // illformed: |
| // // not equivalent to: void f() const; |
| // }; |
| public void test8_3_5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // #define FILE int |
| // int fseek(FILE*, long, int); |
| public void test8_3_5s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef void F(); |
| // F fv; // OK: equivalent to void fv(); |
| // // F fv { } // illformed |
| // void fv() { } // OK: definition of fv |
| public void test8_3_5s7a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int FIC(int) const; |
| // FIC f; // illformed: |
| // //does not declare a member function |
| // struct S { |
| // FIC f; // OK |
| // }; |
| // FIC S::*pm = &S::f; // OK |
| public void test8_3_5s7b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int i, |
| // *pi, |
| // f(), |
| // *fpi(int), |
| // (*pif)(const char*, const char*), |
| // (*fpif(int))(int); |
| public void test8_3_5s9a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int IFUNC(int); |
| // IFUNC* fpif(int); |
| public void test8_3_5s9b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void point(int = 3, int = 4); |
| // void f() { |
| // point(1,2); point(1); point(); |
| // } |
| public void test8_3_6s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f(int, int); |
| // void f(int, int = 7); |
| // void h() |
| // { |
| // f(3); //OK, calls f(3, 7) |
| // void f(int = 1, int); // error: does not use default |
| // // from surrounding scope |
| // } |
| // void m() |
| // { |
| // void f(int, int); // has no defaults |
| // f(4); //error: wrong number of arguments |
| // void f(int, int = 5); // OK |
| // f(4); //OK, calls f(4, 5); |
| // void f(int, int = 5); // error: cannot redefine, even to |
| // // same value |
| // } |
| // void n() |
| // { |
| // f(6); //OK, calls f(6, 7) |
| // } |
| public void test8_3_6s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int a = 1; |
| // int f(int); |
| // int g(int x = f(a)); // default argument: f(::a) |
| // void h() { |
| // a = 2; |
| // { |
| // int a = 3; |
| // g(); // g(f(::a)) |
| // } |
| // } |
| public void test8_3_6s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { |
| // void f(int i = 3); |
| // void g(int i, int j = 99); |
| // }; |
| // void C::f(int i = 3) // error: default argument already |
| // { } // specified in class scope |
| // void C::g(int i = 88, int j) // in this translation unit, |
| // { } |
| public void test8_3_6s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f() |
| // { |
| // int i; |
| // extern void g(int x = i); // error |
| // // ... |
| // } |
| public void test8_3_6s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // void f(A* p = this) { } // error |
| // }; |
| public void test8_3_6s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int a; |
| // int f(int a, int b = a); // error: parameter a |
| // // used as default argument |
| // typedef int I; |
| // int g(float I, int b = I(2)); // error: parameter I found |
| // int h(int a, int b = sizeof(a)); // error, parameter a used |
| public void test8_3_6s9a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int b; |
| // class X { |
| // int a; |
| // int mem1(int i = a); // error: nonstatic member a |
| // // used as default argument |
| // int mem2(int i = b); // OK; use X::b |
| // static int b; |
| // }; |
| public void test8_3_6s9b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(int = 0); |
| // void h() |
| // { |
| // int j = f(1); |
| // int k = f(); // OK, means f(0) |
| // } |
| // int (*p1)(int) = &f; |
| // int (*p2)() = &f; // error: type mismatch |
| public void test8_3_6s9c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // virtual void f(int a = 7); |
| // }; |
| // struct B : public A { |
| // void f(int a); |
| // }; |
| // void m() |
| // { |
| // B* pb = new B; |
| // A* pa = pb; |
| // pa->f(); //OK, calls pa->B::f(7) |
| // pb->f(); //error: wrong number of arguments for B::f() |
| // } |
| public void test8_3_6s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int max(int a, int b, int c) |
| // { |
| // int m = (a > b) ? a : b; |
| // return (m > c) ? m : c; |
| // } |
| public void test8_4s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| //class A { |
| // void a() & {} |
| // void b() && {} |
| // |
| // void c() const& {} |
| // void d() const&& {} |
| // |
| // void e() volatile & {} |
| // void f() volatile && {} |
| // |
| // void g() volatile const& {} |
| // void h() volatile const&& {} |
| //}; |
| public void test8s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void print(int a, int) |
| // { |
| // //printf("a = %d",a); |
| // } |
| public void test8_4s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int a; |
| // struct X { |
| // static int a; |
| // static int b; |
| // }; |
| // int X::a = 1; |
| // int X::b = a; // X::b = X::a |
| public void test8_5s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // int x; |
| // struct B { |
| // int i; |
| // int j; |
| // } b; |
| // } a = { 1, { 2, 3 } }; |
| public void test8_5_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int x[] = { 1, 3, 5 }; |
| public void test8_5_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // int i; |
| // static int s; |
| // int j; |
| // } a = { 1, 2 }; |
| public void test8_5_1s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error |
| public void test8_5_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { int a; char* b; int c; }; |
| // S ss = { 1, "asdf" }; |
| public void test8_5_1s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { }; |
| // struct A { |
| // S s; |
| // int i; |
| // } a = { { } , 3 }; |
| public void test8_5_1s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int x[2][2] = { 3, 1, 4, 2 }; |
| // float y[4][3] = { |
| // { 1 }, { 2 }, { 3 }, { 4 } |
| // }; |
| public void test8_5_1s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // float y[4][3] = { |
| // { 1, 3, 5 }, |
| // { 2, 4, 6 }, |
| // { 3, 5, 7 }, |
| // }; |
| public void test8_5_1s11a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // float y[4][3] = { |
| // 1, 3, 5, 2, 4, 6, 3, 5, 7 |
| // }; |
| public void test8_5_1s11b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // int i; |
| // operator int(); |
| // }; |
| // struct B { |
| // A a1, a2; |
| // int z; |
| // }; |
| // A a; |
| // B b = { 4, a, a }; |
| public void test8_5_1s12() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // union u { int a; char* b; }; |
| // u a = { 1 }; |
| // u b = a; |
| // u c = 1; // error |
| // u d = { 0, "asdf" }; // error |
| // u e = { "asdf" }; // error |
| public void test8_5_1s15() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // char msg[] = "Syntax error on line %s"; |
| public void test8_5_2s1() throws Exception { |
| // raised bug 90647 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // char cv[4] = "asdf"; // error |
| public void test8_5_2s2() throws Exception { |
| // we do not check the size of an array, which is ok. |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int& r1; // error: initializer missing |
| // extern int& r2; // OK |
| public void test8_5_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // Note: the examples for 8.5.3/5 are written slightly differently |
| // than they appear in the standard. In the standard, the examples |
| // demonstrate the rules with variable initialiation, but CDT doesn't |
| // currently issue problem bindings for variable initialization, |
| // so in the tests the examples are rewritten to use function calls. |
| |
| // void f1(double); |
| // void f2(double&); |
| // void f3(const double&); |
| // struct A { }; |
| // struct B : public A { operator int&(); } b; |
| // void f4(A&); |
| // void f5(const A&); |
| // void f6(int&); |
| // int main() { |
| // f1(2.0); |
| // double d; |
| // f2(d); |
| // f3(d); |
| // f4(b); |
| // f5(b); |
| // f6(B()); |
| // } |
| public void test8_5_3s5a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f1(double&); |
| // void f2(double&); |
| // int main() { |
| // f1(2.0); // error: not an lvalue and reference not const |
| // int i = 2; |
| // f2(i); // error: type mismatch and reference not const |
| // } |
| public void test8_5_3s5b() throws Exception { |
| BindingAssertionHelper helper = getAssertionHelper(ParserLanguage.CPP); |
| helper.assertProblem("f1(2", "f1"); |
| helper.assertProblem("f2(i", "f2"); |
| } |
| |
| // struct A { }; |
| // struct B : public A { } b; |
| // extern B f(); |
| // void f1(const A&); |
| // void f2(A&&); |
| // struct X { |
| // operator B(); |
| // operator int&(); |
| // } x; |
| // void f3(int&&); |
| // void f4(B&&); |
| // int main() { |
| // f1(f()); // bound to the A subobject of the B rvalue |
| // f2(f()); // same as above |
| // f1(x); // bound to the A subobject of the result of the conversion |
| // f3(static_cast<int&&>(i)); // bound directly to i |
| // f4(x); // bound directly to the result of operator B |
| // f3(X()); // error: lvalue-to-rvalue conversion applied to result of operator int& |
| // } |
| public void test8_5_3s5c() throws Exception { |
| BindingAssertionHelper helper = getAssertionHelper(ParserLanguage.CPP); |
| helper.assertNonProblem("f1(f", "f1"); |
| helper.assertNonProblem("f2(f", "f2"); |
| helper.assertNonProblem("f1(x", "f1"); |
| helper.assertNonProblem("f3(s", "f3"); |
| helper.assertNonProblem("f4(x", "f4"); |
| helper.assertProblem("f3(X", "f3"); |
| } |
| |
| // void f1(const double&); |
| // void f2(double&&); |
| // void f3(const int&); |
| // int main() { |
| // f1(2); |
| // f2(2); |
| // const volatile int cvi = 1; |
| // f3(cvi); // error: type qualifiers dropped |
| // double d; |
| // int i; |
| // f2(d); // error: copying lvalue of related type |
| // f2(i); |
| // } |
| public void test8_5_3s5d() throws Exception { |
| BindingAssertionHelper helper = getAssertionHelper(ParserLanguage.CPP); |
| helper.assertNonProblem("f1(2", "f1"); |
| helper.assertNonProblem("f2(2", "f2"); |
| helper.assertProblem("f3(cv", "f3"); |
| helper.assertProblem("f2(d)", "f2"); |
| helper.assertNonProblem("f2(i", "f2"); |
| } |
| |
| // struct X { int a; }; |
| // struct Y { int a; }; |
| // X a1; |
| // Y a2; |
| // int a3; |
| // void test() { |
| // a1 = a2; // error: Y assigned to X |
| // a1 = a3; // error: int assigned to X |
| // } |
| // int f(X); |
| // int f(Y); |
| // struct S { int a; }; |
| // struct S { int a; }; // error, double definition |
| public void test9_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct stat { |
| // // ... |
| // }; |
| // stat gstat; // use plain stat to |
| // // define variable |
| // int stat(struct stat*); // redeclare stat as function |
| // void f() |
| // { |
| // struct stat* ps; // struct prefix needed |
| // // to name struct stat |
| // // ... |
| // stat(ps); //call stat() |
| // // ... |
| // } |
| public void test9_1s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct s { int a; }; |
| // void g() |
| // { |
| // struct s; // hide global struct s |
| // // with a local declaration |
| // s* p; // refer to local struct s |
| // struct s { char* p; }; // define local struct s |
| // struct s; // redeclaration, has no effect |
| // } |
| public void test9_1s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Vector; |
| // class Matrix { |
| // // ... |
| // friend Vector operator*(Matrix&, Vector&); |
| // }; |
| // class Vector { |
| // // ... |
| // friend Vector operator*(Matrix&, Vector&); |
| // }; |
| public void test9_1s2c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct s { int a; }; |
| // void g(int s) |
| // { |
| // struct s* p = new struct s; // global s |
| // p->a = s; // local s |
| // } |
| public void test9_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A * A; |
| public void test9_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct tnode { |
| // char tword[20]; |
| // int count; |
| // tnode *left; |
| // tnode *right; |
| // }; |
| // tnode s, *sp; |
| public void test9_2s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // typedef int T; |
| // static T count; |
| // void f(T); |
| // }; |
| // void X::f(T t = count) { } |
| public void test9_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef void fv(void); |
| // typedef void fvc(void) const; |
| // struct S { |
| // fv memfunc1; // equivalent to: void memfunc1(void); |
| // void memfunc2(); |
| // fvc memfunc3; // equivalent to: void memfunc3(void) const; |
| // }; |
| // fv S::* pmfv1 = &S::memfunc1; |
| // fv S::* pmfv2 = &S::memfunc2; |
| // fvc S::* pmfv3 = &S::memfunc3; |
| public void test9_3s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct tnode { |
| // char tword[20]; |
| // int count; |
| // tnode *left; |
| // tnode *right; |
| // void set(char*, tnode* l, tnode* r); |
| // }; |
| // void tnode::set(char* w, tnode* l, tnode* r) |
| // { |
| // count = strlen(w)+1; |
| // if (sizeof(tword)<=count) |
| // perror("tnode string too long"); |
| // strcpy(tword,w); |
| // left = l; |
| // right = r; |
| // } |
| // void f(tnode n1, tnode n2) |
| // { |
| // n1.set("abc",&n2,0); |
| // n2.set("def",0,0); |
| // } |
| public void test9_3_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct X { |
| // void g() const; |
| // void h() const volatile; |
| // }; |
| public void test9_3_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct s { |
| // int a; |
| // int f() const; |
| // int g() { return a++; } |
| // int h() const { return a++; } // error |
| // }; |
| // int s::f() const { return a; } |
| public void test9_3_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct s { |
| // int a; |
| // int f() const; |
| // int g() { return a++; } |
| // }; |
| // int s::f() const { return a; } |
| // |
| // void k(s& x, const s& y) |
| // { |
| // x.f(); |
| // x.g(); |
| // y.f(); |
| // y.g(); //error |
| // } |
| public void test9_3_2s4() throws Exception { |
| String[] problems = { "g" }; |
| final String code = getAboveComment(); |
| IASTTranslationUnit tu = parse(code, ParserLanguage.CPP, problems); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| bh.assertNonProblem("g();", 1); |
| bh.assertProblem("g(); //error", 1); |
| } |
| |
| // class process { |
| // public: |
| // static void reschedule(); |
| // }; |
| // process& g(); |
| // void f() |
| // { |
| // process::reschedule(); // OK: no object necessary |
| // g().reschedule(); // g() is called |
| // } |
| public void test9_4s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int g(); |
| // struct X { |
| // static int g(); |
| // }; |
| // struct Y : X { |
| // static int i; |
| // }; |
| // int Y::i = g(); // equivalent to Y::g(); |
| public void test9_4s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class process { |
| // static process* run_chain; |
| // static process* running; |
| // }; |
| // process* process::running = get_main(); |
| // process* process::run_chain = running; |
| public void test9_4_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void f() |
| // { |
| // union { int a; char* p; }; |
| // a = 1; |
| // // ... |
| // p = "Jennifer"; |
| // // ... |
| // } |
| public void test9_5s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // union { int aa; char* p; } obj, *ptr = &obj; |
| // aa = 1; // error |
| // ptr->aa = 1; // OK |
| // } |
| public void test9_5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // enum BOOL { f=0, t=1 }; |
| // struct A { |
| // BOOL b:1; |
| // }; |
| // A a; |
| // void f() { |
| // a.b = t; |
| // if (a.b == t) // shall yield true |
| // { } |
| // } |
| public void test9_6s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int x; |
| // int y; |
| // class enclose { |
| // public: |
| // int x; |
| // static int s; |
| // class inner { |
| // void f(int i) |
| // { |
| // int a = sizeof(x); // error: refers to enclose::x |
| // x = i; // error: assign to enclose::x |
| // s = i; // OK: assign to enclose::s |
| // ::x = i; // OK: assign to global x |
| // y = i; // OK: assign to global y |
| // } |
| // void g(enclose* p, int i) |
| // { |
| // p> |
| // x = i; // OK: assign to enclose::x |
| // } |
| // }; |
| // }; |
| // inner* p = 0; // error: inner not in scope |
| public void test9_7s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class enclose { |
| // public: |
| // class inner { |
| // static int x; |
| // void f(int i); |
| // }; |
| // }; |
| // int enclose::inner::x = 1; |
| // void enclose::inner::f(int i) { } |
| public void test9_7s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class E { |
| // class I1; // forward declaration of nested class |
| // class I2; |
| // class I1 {}; // definition of nested class |
| // }; |
| // class E::I2 {}; // definition of nested class |
| public void test9_7s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int x; |
| // void f() |
| // { |
| // static int s ; |
| // int x; |
| // extern int g(); |
| // struct local { |
| // int g() { return x; } // error: x is auto |
| // int h() { return s; } // OK |
| // int k() { return ::x; } // OK |
| // int l() { return g(); } // OK |
| // }; |
| // // ... |
| // } |
| // local* p = 0; // error: local not in scope |
| public void test9_8s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class X { |
| // public: |
| // typedef int I; |
| // class Y { /* ... */ }; |
| // I a; |
| // }; |
| // I b; // error |
| // Y c; // error |
| // X::Y d; // OK |
| // X::I e; // OK |
| public void test9_9s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class Base { |
| // public: |
| // int a, b, c; |
| // }; |
| // class Derived : public Base { |
| // public: |
| // int b; |
| // }; |
| // class Derived2 : public Derived { |
| // public: |
| // int c; |
| // }; |
| public void test10s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { }; |
| // class B { }; |
| // class C { }; |
| // class D : public A, public B, public C { }; |
| public void test10_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { }; |
| // class Y : public X, public X { }; // illformed |
| public void test10_1s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class L { public: int next; }; |
| // class A : public L { }; |
| // class B : public L { }; |
| // class C : public A, public B { void f(); }; // wellformed |
| // class D : public A, public L { void f(); }; // wellformed |
| // |
| public void test10_1s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // public: |
| // int a; |
| // int (*b)(); |
| // int f(); |
| // int f(int); |
| // int g(); |
| // }; |
| // class B { |
| // int a; |
| // int b(); |
| // public: |
| // int f(); |
| // int g; |
| // int h(); |
| // int h(int); |
| // }; |
| // class C : public A, public B {}; |
| // void g(C* pc) |
| // { |
| // pc->a = 1; // error: ambiguous: A::a or B::a |
| // pc->b(); //error: ambiguous: A::b or B::b |
| // pc->f(); //error: ambiguous: A::f or B::f |
| // pc->f(1); //error: ambiguous: A::f or B::f |
| // pc->g(); //error: ambiguous: A::g or B::g |
| // pc->g = 1; // error: ambiguous: A::g or B::g |
| // pc->h(); //OK |
| // pc->h(1); //OK |
| // } |
| public void test10_2s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct U { static int i; }; |
| // struct V : U { }; |
| // struct W : U { using U::i; }; |
| // struct X : V, W { void foo(); }; |
| // void X::foo() { |
| // i; //finds U::i in two ways: as W::i and U::i in V |
| // // no ambiguity because U::i is static |
| // } |
| public void test10_2s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // public: |
| // int f(); |
| // }; |
| // class B { |
| // public: |
| // int f(); |
| // }; |
| // class C : public A, public B { |
| // int f() { return A::f() + B::f(); } |
| // }; |
| public void test10_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class V { public: int v; }; |
| // class A { |
| // public: |
| // int a; |
| // static int s; |
| // enum { e }; |
| // }; |
| // class B : public A, public virtual V {}; |
| // class C : public A, public virtual V {}; |
| // class D : public B, public C { }; |
| // void f(D* pd) |
| // { |
| // pd->v++; //OK: only one v (virtual) |
| // pd->s++; //OK: only one s (static) |
| // int i = pd> |
| // e; // OK: only one e (enumerator) |
| // pd->a++; //error, ambiguous: two as in D |
| // } |
| public void test10_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class V { public: int f(); int x; }; |
| // class W { public: int g(); int y; }; |
| // class B : public virtual V, public W |
| // { |
| // public: |
| // int f(); int x; |
| // int g(); int y; |
| // }; |
| // class C : public virtual V, public W { }; |
| // class D : public B, public C { void glorp(); }; |
| public void test10_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class V { }; |
| // class A { }; |
| // class B : public A, public virtual V { }; |
| // class C : public A, public virtual V { }; |
| // class D : public B, public C { }; |
| // void g() |
| // { |
| // D d; |
| // B* pb = &d; |
| // A* pa = &d; // error, ambiguous: C's A or B's A? |
| // V* pv = &d; // OK: only one V subobject |
| // } |
| public void test10_2s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // virtual void f(); |
| // }; |
| // struct B : virtual A { |
| // virtual void f(); |
| // }; |
| // struct C : B , virtual A { |
| // using A::f; |
| // }; |
| // void foo() { |
| // C c; |
| // c.f(); //calls B::f, the final overrider |
| // c.C::f(); //calls A::f because of the usingdeclaration |
| // } |
| public void test10_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B {}; |
| // class D : private B { friend class Derived; }; |
| // struct Base { |
| // virtual void vf1(); |
| // virtual void vf2(); |
| // virtual void vf3(); |
| // virtual B* vf4(); |
| // virtual B* vf5(); |
| // void f(); |
| // }; |
| // struct No_good : public Base { |
| // D* vf4(); // error: B (base class of D) inaccessible |
| // }; |
| // class A; |
| // struct Derived : public Base { |
| // void vf1(); // virtual and overrides Base::vf1() |
| // void vf2(int); // not virtual, hides Base::vf2() |
| // char vf3(); // error: invalid difference in return type only |
| // D* vf4(); // OK: returns pointer to derived class |
| // A* vf5(); // error: returns pointer to incomplete class |
| // void f(); |
| // }; |
| // void g() |
| // { |
| // Derived d; |
| // Base* bp = &d; // standard conversion: |
| // // Derived* to Base* |
| // bp->vf1(); //calls Derived::vf1() |
| // bp->vf2(); //calls Base::vf2() |
| // bp->f(); //calls Base::f() (not virtual) |
| // B* p = bp->vf4(); // calls Derived::pf() and converts the |
| // // result to B* |
| // Derived* dp = &d; |
| // D* q = dp->vf4(); // calls Derived::pf() and does not |
| // // convert the result to B* |
| // dp->vf2(); //illformed: argument mismatch |
| // } |
| public void test10_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { |
| // virtual void f(); |
| // }; |
| // struct B1 : A { // note nonvirtual derivation |
| // void f(); |
| // }; |
| // struct B2 : A { |
| // void f(); |
| // }; |
| // struct D : B1, B2 { // D has two separate A subobjects |
| // }; |
| // void foo() |
| // { |
| // D d; |
| // // A* ap = &d; // would be illformed:ambiguous |
| // B1* b1p = &d; |
| // A* ap = b1p; |
| // D* dp = &d; |
| // ap->f(); //calls D::B1::f |
| // dp->f(); //illformed: ambiguous |
| // } |
| public void test10_3s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { |
| // virtual void f(); |
| // }; |
| // struct VB1 : virtual A { // note virtual derivation |
| // void f(); |
| // }; |
| // struct VB2 : virtual A { |
| // void f(); |
| // }; |
| // struct Error : VB1, VB2 { // illformed |
| // }; |
| // struct Okay : VB1, VB2 { |
| // void f(); |
| // }; |
| public void test10_3s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct VB1a : virtual A { // does not declare f |
| // }; |
| // struct Da : VB1a, VB2 { |
| // }; |
| // void foe() |
| // { |
| // VB1a* vb1ap = new Da; |
| // vb1ap->f(); //calls VB2::f |
| // } |
| public void test10_3s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class B { public: virtual void f(); }; |
| // class D : public B { public: void f(); }; |
| // void D::f() { B::f(); } |
| public void test10_3s12() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class point { }; |
| // class shape { // abstract class |
| // point center; |
| // // ... |
| // public: |
| // point where() { return center; } |
| // void move(point p) { center=p; draw(); } |
| // virtual void rotate(int) = 0; // pure virtual |
| // virtual void draw() = 0; // pure virtual |
| // // ... |
| // }; |
| public void test10_4s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // Not legal C++ |
| // // public void test10_4s2b() throws Exception { |
| // StringBuilder buffer = new StringBuilder(); |
| // buffer.append("struct C {\n"); //$NON-NLS-1$ |
| // buffer.append("virtual void f() { }=0; // illformed\n"); //$NON-NLS-1$ |
| // buffer.append("};\n"); //$NON-NLS-1$ |
| // parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| // } |
| |
| // shape x; // error: object of abstract class |
| // shape* p; // OK |
| // shape f(); // error |
| // void g(shape); // error |
| // shape& h(shape&); // OK |
| public void test10_4s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class ab_circle : public shape { |
| // int radius; |
| // public: |
| // void rotate(int) {} |
| // // ab_circle::draw() is a pure virtual |
| // }; |
| public void test10_4s4a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class circle : public shape { |
| // int radius; |
| // public: |
| // void rotate(int) {} |
| // void draw(); // a definition is required somewhere |
| // }; |
| public void test10_4s4b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class X { |
| // int a; // X::a is private by default |
| // }; |
| // struct S { |
| // int a; // S::a is public by default |
| // }; |
| public void test11s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A |
| // { |
| // class B { }; |
| // public: |
| // typedef B BB; |
| // }; |
| // void f() |
| // { |
| // A::BB x; // OK, typedef name A::BB is public |
| // A::B y; // access error, A::B is private |
| // } |
| public void test11s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // typedef int I; // private member |
| // I f(); |
| // friend I g(I); |
| // static I x; |
| // }; |
| // A::I A::f() { return 0; } |
| // A::I g(A::I p = A::x); |
| // A::I g(A::I p) { return 0; } |
| // A::I A::x = 0; |
| public void test11s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class D { |
| // class E { |
| // static int m; |
| // }; |
| // }; |
| // int D::E::m = 1; // OK, no access error on private E |
| public void test11s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // int a; // X::a is private by default: class used |
| // public: |
| // int b; // X::b is public |
| // int c; // X::c is public |
| // }; |
| public void test11_1s1a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // int a; // S::a is public by default: struct used |
| // protected: |
| // int b; // S::b is protected |
| // private: |
| // int c; // S::c is private |
| // public: |
| // int d; // S::d is public |
| // }; |
| public void test11s1b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // class A; |
| // private: |
| // class A { }; // error: cannot change access |
| // }; |
| public void test11_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { }; |
| // class D1 : private B { }; |
| // class D2 : public B { }; |
| // class D3 : B { }; // B private by default |
| // struct D4 : public B { }; |
| // struct D5 : private B { }; |
| // struct D6 : B { }; // B public by default |
| // class D7 : protected B { }; |
| // struct D8 : protected B { }; |
| public void test11_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { |
| // public: |
| // int mi; // nonstatic member |
| // static int si; // static member |
| // }; |
| // class D : private B { |
| // }; |
| // class DD : public D { |
| // void f(); |
| // }; |
| // void DD::f() { |
| // mi = 3; // error: mi is private in D |
| // si = 3; // error: si is private in D |
| // B b; |
| // b.mi = 3; // OK (b.mi is different from this->mi) |
| // b.si = 3; // OK (b.si is different from this->si) |
| // B::si = 3; // OK |
| // B* bp1 = this; // error: B is a private base class |
| // B* bp2 = (B*)this; // OK with cast |
| // bp2->mi = 3; // OK: access through a pointer to B. |
| // } |
| public void test11_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B; |
| // class A { |
| // private: |
| // int i; |
| // friend void f(B*); |
| // }; |
| // class B : public A { }; |
| // void f(B* p) { |
| // p->i = 1; // OK: B* can be implicitly cast to A*, |
| // // and f has access to i in A |
| // } |
| public void test11_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // int a; |
| // friend void friend_set(X*, int); |
| // public: |
| // void member_set(int); |
| // }; |
| // void friend_set(X* p, int i) { p->a = i; } |
| // void X::member_set(int i) { a = i; } |
| // void f() |
| // { |
| // X obj; |
| // friend_set(&obj,10); |
| // obj.member_set(10); |
| // } |
| public void test11_4s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // class B { }; |
| // friend class X; |
| // }; |
| // class X : A::B { // illformed: |
| // //A::B cannot be accessed |
| // // in the baseclause for X |
| // A::B mx; // OK: A::B used to declare member of X |
| // class Y : A::B { // OK: A::B used to declare member of X |
| // A::B my; // illformed: A::B cannot be accessed |
| // // to declare members of nested class of X |
| // }; |
| // }; |
| public void test11_4s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // enum { a=100 }; |
| // friend class Y; |
| // }; |
| // class Y { |
| // int v[X::a]; // OK, Y is a friend of X |
| // }; |
| // class Z { |
| // int v[X::a]; // error: X::a is private |
| // }; |
| public void test11_4s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Y { |
| // friend char* X::foo(int); |
| // // ... |
| // }; |
| public void test11_4s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class M { |
| // friend void f() { } // definition of global f, a friend of M, |
| // // not the definition of a member function |
| // }; |
| public void test11_4s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // friend class B; |
| // int a; |
| // }; |
| // class B { |
| // friend class C; |
| // }; |
| // class C { |
| // void f(A* p) |
| // { |
| // p->a++; //error: C is not a friend of A |
| // // despite being a friend of a friend |
| // } |
| // }; |
| // class D : public B { |
| // void f(A* p) |
| // { |
| // p->a++; //error: D is not a friend of A |
| // // despite being derived from a friend |
| // } |
| // }; |
| public void test11_4s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X; |
| // void a(); |
| // void f() { |
| // class Y; |
| // extern void b(); |
| // class A { |
| // friend class X; // OK, but X is a local class, not ::X |
| // friend class Y; // OK |
| // friend class Z; // OK, introduces local class Z |
| // friend void a(); // error, ::a is not considered |
| // friend void b(); // OK |
| // friend void c(); // error |
| // }; |
| // X *px; // OK, but ::X is found |
| // Z *pz; // error, no Z is found |
| // } |
| public void test11_4s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class B { |
| // protected: |
| // int i; |
| // static int j; |
| // }; |
| // class D1 : public B { |
| // }; |
| // class D2 : public B { |
| // friend void fr(B*,D1*,D2*); |
| // void mem(B*,D1*); |
| // }; |
| // void fr(B* pb, D1* p1, D2* p2) |
| // { |
| // pb->i = 1; // illformed |
| // p1->i = 2; // illformed |
| // p2->i = 3; // OK (access through a D2) |
| // p2->B::i = 4; // OK (access through a D2, even though |
| // // naming class is B) |
| // int B::* pmi_B = &B::i; // illformed |
| // int B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*) |
| // B::j = 5; // OK (because refers to static member) |
| // D2::j =6; // OK (because refers to static member) |
| // } |
| // void D2::mem(B* pb, D1* p1) |
| // { |
| // pb->i = 1; // illformed |
| // p1->i = 2; // illformed |
| // i = 3; // OK (access through this) |
| // B::i = 4; // OK (access through this, qualification ignored) |
| // int B::* pmi_B = &B::i; // illformed |
| // int B::* pmi_B2 = &D2::i; // OK |
| // j = 5; // OK (because j refers to static member) |
| // B::j = 6; // OK (because B::j refers to static member) |
| // } |
| // void g(B* pb, D1* p1, D2* p2) |
| // { |
| // pb->i = 1; // illformed |
| // p1->i = 2; // illformed |
| // p2->i = 3; // illformed |
| // } |
| public void test11_5s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { |
| // public: |
| // virtual int f(); |
| // }; |
| // class D : public B { |
| // private: |
| // int f(); |
| // }; |
| // void f() |
| // { |
| // D d; |
| // B* pb = &d; |
| // D* pd = &d; |
| // pb->f(); //OK: B::f() is public, |
| // // D::f() is invoked |
| // pd->f(); //error: D::f() is private |
| // } |
| public void test11_6s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class W { public: void f(); }; |
| // class A : private virtual W { }; |
| // class B : public virtual W { }; |
| // class C : public A, public B { |
| // void f() { W::f(); } // OK |
| // }; |
| public void test11_7s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class E { |
| // int x; |
| // class B { }; |
| // class I { |
| // B b; // error: E::B is private |
| // int y; |
| // void f(E* p, int i) |
| // { |
| // p->x = i; // error: E::x is private |
| // } |
| // }; |
| // int g(I* p) |
| // { |
| // return p->y; // error: I::y is private |
| // } |
| // }; |
| public void test11_8s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { |
| // class A { }; |
| // A *p; // OK |
| // class B : A // OK |
| // { |
| // A *q; // OK because of injection of name A in A |
| // C::A *r; // error, C::A is inaccessible |
| // B *s; // OK because of injection of name B in B |
| // C::B *t; // error, C::B is inaccessible |
| // }; |
| // }; |
| public void test11_8s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { |
| // public: |
| // C(); //declares the constructor |
| // }; |
| // C::C() { } // defines the constructor |
| public void test12_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct C; |
| // void no_opt(C*); |
| // struct C { |
| // int c; |
| // C() : c(0) { no_opt(this); } |
| // }; |
| // const C cobj; |
| // void no_opt(C* cptr) { |
| // int i = cobj.c * 100; // value of cobj.c is unspecified |
| // cptr->c = 1; |
| // cout << cobj.c * 100 // value of cobj.c is unspecified |
| // << '\ |
| // '; |
| // } |
| public void test12_1s15() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // // ... |
| // X(int); |
| // X(const X&); |
| // ~X(); |
| // }; |
| // X f(X); |
| // void g() |
| // { |
| // X a(1); |
| // X b = f(X(2)); |
| // a = f(a); |
| // } |
| public void test12_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class C { |
| // // ... |
| // public: |
| // C(); |
| // C(int); |
| // friend C operator+(const C&, const C&); |
| // ~C(); |
| // }; |
| // C obj1; |
| // const C& cr = C(16)+C(23); |
| // C obj2; |
| public void test12_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // operator int(); |
| // }; |
| // class Y { |
| // // ... |
| // public: |
| // operator X(); |
| // }; |
| // Y a; |
| // int b = a; // error: |
| // // a.operator X().operator int() not tried |
| // int c = X(a); // OK: a.operator X().operator int() |
| public void test12_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // // ... |
| // operator int(); |
| // }; |
| // class Y : public X { |
| // public: |
| // // ... |
| // operator char(); |
| // }; |
| // void f(Y& a) |
| // { |
| // if (a) { // illformed: |
| // // X::operator int() or Y::operator char() |
| // // ... |
| // } |
| // } |
| public void test12_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // X(int); |
| // X(const char*, int =0); |
| // }; |
| // void f(X arg) |
| // { |
| // X a = 1; // a = X(1) |
| // X b = "Jessie"; // b = X("Jessie",0) |
| // a = 2; // a = X(2) |
| // f(3); // f(X(3)) |
| // } |
| public void test12_3_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Z { |
| // public: |
| // explicit Z(); |
| // explicit Z(int); |
| // // ... |
| // }; |
| // Z a; // OK: defaultinitialization performed |
| // Z a1 = 1; // error: no implicit conversion |
| // Z a3 = Z(1); // OK: direct initialization syntax used |
| // Z a2(1); // OK: direct initialization syntax used |
| // Z* p = new Z(1); // OK: direct initialization syntax used |
| // Z a4 = (Z)1; // OK: explicit cast used |
| // Z a5 = static_cast<Z>(1); // OK: explicit cast used |
| public void test12_3_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // operator int(); |
| // }; |
| // void f(X a) |
| // { |
| // int i = int(a); |
| // i = (int)a; |
| // i = a; |
| // } |
| public void test12_3_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void g(X a, X b) |
| // { |
| // int i = (a) ? 1+a : 0; |
| // int j = (a&&b) ? a+b : i; |
| // if (a) { // ... |
| // } |
| // } |
| public void test12_3_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct B { |
| // virtual ~B() { } |
| // }; |
| // struct D : B { |
| // ~D() { } |
| // }; |
| // D D_object; |
| // typedef B B_alias; |
| // B* B_ptr = &D_object; |
| // void f() { |
| // D_object.B::~B(); //1 // calls B's destructor |
| // B_ptr->~B(); //2 // calls D's destructor |
| // B_ptr->~B_alias(); //3 // calls D's destructor |
| // B_ptr->B_alias::~B(); //4 // calls B's destructor |
| // B_ptr->B_alias::~B_alias(); //5 // error, no B_alias in class B |
| // } |
| public void test12_4s12() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, false, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPFunction dtor = bh.assertNonProblem("~B() {", 2); |
| |
| ICPPFunction d = bh.assertNonProblem("~B(); //1", 2); |
| assertSame(dtor, d); |
| d = bh.assertNonProblem("~B(); //2", 2); |
| assertSame(dtor, d); |
| d = bh.assertNonProblem("~B_alias(); //3", 8); |
| assertSame(dtor, d); |
| d = bh.assertNonProblem("~B(); //4", 2); |
| assertSame(dtor, d); |
| |
| bh.assertProblem("~B_alias(); //5", 8); |
| } |
| |
| // void* operator new(size_t, void* p) { return p; } |
| // struct X { |
| // // ... |
| // X(int); |
| // ~X(); |
| // }; |
| // void f(X* p); |
| // void g() // rare, specialized use: |
| // { |
| // char* buf = new char[sizeof(X)]; |
| // X* p = new(buf) X(222); // use buf[] and initialize |
| // f(p); |
| // p->X::~X(); //cleanup |
| // } |
| public void test12_4s13() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class Arena; |
| // struct B { |
| // void* operator new(size_t, Arena*); |
| // }; |
| // struct D1 : B { |
| // }; |
| // Arena* ap; |
| // void foo(int i) |
| // { |
| // new (ap) D1; // calls B::operator new(size_t, Arena*) |
| // new D1[i]; // calls ::operator new[](size_t) |
| // new D1; // illformed: ::operator new(size_t) hidden |
| // } |
| public void test12_5s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class X { |
| // // ... |
| // void operator delete(void*); |
| // void operator delete[](void*, size_t); |
| // }; |
| // class Y { |
| // // ... |
| // void operator delete(void*, size_t); |
| // void operator delete[](void*); |
| // }; |
| public void test12_5s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class complex { |
| // // ... |
| // public: |
| // complex(); |
| // complex(double); |
| // complex(double,double); |
| // // ... |
| // }; |
| // complex sqrt(complex,complex); |
| // int foo() { |
| // complex a(1); // initialize by a call of |
| // // complex(double) |
| // complex b = a; // initialize by a copy of a |
| // complex c = complex(1,2); // construct complex(1,2) |
| // // using complex(double,double) |
| // // copy it into c |
| // complex d = sqrt(b,c); // call sqrt(complex,complex) |
| // // and copy the result into d |
| // complex e; // initialize by a call of |
| // // complex() |
| // complex f = 3; // construct complex(3) using |
| // // complex(double) |
| // // copy it into f |
| // complex g = { 1, 2 }; // error; constructor is required |
| // } |
| public void test12_6_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class complex { |
| // // ... |
| // public: |
| // complex(); |
| // complex(double); |
| // complex(double,double); |
| // // ... |
| // }; |
| // complex v[6] = { 1,complex(1,2),complex(),2 }; |
| // class X { |
| // public: |
| // int i; |
| // float f; |
| // complex c; |
| // } x = { 99, 88.8, 77.7 }; |
| public void test12_6_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { A(); }; |
| // typedef A global_A; |
| // struct B { }; |
| // struct C: public A, public B { C(); }; |
| // C::C(): global_A() { } // meminitializer for base A |
| public void test12_6_2s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { A(); }; |
| // struct B: public virtual A { }; |
| // struct C: public A, public B { C(); }; |
| // C::C(): A() { } // illformed: which A? |
| public void test12_6_2s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct B1 { B1(int); }; |
| // struct B2 { B2(int); }; |
| // struct D : B1, B2 { |
| // D(int); |
| // B1 b; |
| // const int c; |
| // }; |
| // D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) |
| // { } |
| // D d(10); |
| public void test12_6_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class V { |
| // public: |
| // V(); |
| // V(int); |
| // // ... |
| // }; |
| // class A : public virtual V { |
| // public: |
| // A(); |
| // A(int); |
| // // ... |
| // }; |
| // class B : public virtual V { |
| // public: |
| // B(); |
| // B(int); |
| // // ... |
| // }; |
| // class C : public A, public B, private virtual V { |
| // public: |
| // C(); |
| // C(int); |
| // // ... |
| // }; |
| // A::A(int i) : V(i) { } |
| // B::B(int i) { } |
| // C::C(int i) { } |
| // V v(1); // use V(int) |
| // A a(2); // use V(int) |
| // B b(3); // use V() |
| // C c(4); // use V() |
| public void test12_6_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // int a; |
| // int b; |
| // int i; |
| // int j; |
| // public: |
| // const int& r; |
| // X(int i): r(a), b(i), i(i), j(this->i) {} |
| // }; |
| public void test12_6_2s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { |
| // public: |
| // A(int); |
| // }; |
| // class B : public A { |
| // int j; |
| // public: |
| // int f(); |
| // B() : A(f()), // undefined: calls member function |
| // // but base A not yet initialized |
| // j(f()) { } // welldefined: bases are all initialized |
| // }; |
| // class C { |
| // public: |
| // C(int); |
| // }; |
| // class D : public B, C { |
| // int i; |
| // public: |
| // D() : C(f()), // undefined: calls member function |
| // // but base C not yet initialized |
| // i(f()) {} // welldefined: bases are all initialized |
| // }; |
| public void test12_6_2s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { int i; }; |
| // struct Y : X { }; |
| // struct A { int a; }; |
| // struct B : public A { int j; Y y; }; |
| // extern B bobj; |
| // B* pb = &bobj; // OK |
| // int* p1 = &bobj.a; // undefined, refers to base class member |
| // int* p2 = &bobj.y.i; // undefined, refers to member's member |
| // A* pa = &bobj; // undefined, upcast to a base class type |
| // B bobj; // definition of bobj |
| // extern X xobj; |
| // int* p3 = &xobj.i; // OK, X is a POD class |
| // X xobj; |
| public void test12_7s1_a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct W { int j; }; |
| // struct X : public virtual W { }; |
| // struct Y { |
| // int *p; |
| // X x; |
| // Y() : p(&x.j) // undefined, x is not yet constructed |
| // { } |
| // }; |
| public void test12_7s1_b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class V { |
| // public: |
| // virtual void f(); |
| // virtual void g(); |
| // }; |
| // class A : public virtual V { |
| // public: |
| // virtual void f(); |
| // }; |
| // class B : public virtual V { |
| // public: |
| // virtual void g(); |
| // B(V*, A*); |
| // }; |
| // class D : public A, B { |
| // public: |
| // virtual void f(); |
| // virtual void g(); |
| // D() : B((A*)this, this) { } |
| // }; |
| // B::B(V* v, A* a) { |
| // f(); //calls V::f, not A::f |
| // g(); //calls B::g, not D::g |
| // v->g(); // v is base of B, the call is welldefined, calls B::g |
| // a->f(); //undefined behavior, a's type not a base of B |
| // } |
| public void test12_7s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class V { |
| // public: |
| // virtual void f(); |
| // }; |
| // class A : public virtual V { }; |
| // class B : public virtual V { |
| // public: |
| // B(V*, A*); |
| // }; |
| // class D : public A, B { |
| // public: |
| // D() : B((A*)this, this) { } |
| // }; |
| // B::B(V* v, A* a) { |
| // typeid(*this); // type_info for B |
| // typeid(*v); //welldefined: *v has type V, a base of B |
| // // yields type_info for B |
| // typeid(*a); //undefined behavior: type A not a base of B |
| // dynamic_cast<B*>(v); // welldefined: v of type V*, V base of B |
| // // results in B* |
| // dynamic_cast<B*>(a); // undefined behavior, |
| // // a has type A*, A not a base of B |
| // } |
| public void test12_7s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // X(int); |
| // X(const X&, int = 1); |
| // }; |
| // X a(1); // calls X(int); |
| // X b(a, 0); // calls X(const X&, int); |
| // X c = b; // calls X(const X&, int); |
| public void test12_8s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // // ... |
| // public: |
| // X(const X&); |
| // X(X&); //OK |
| // }; |
| public void test12_8s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // X(); //default constructor |
| // X(X&); //copy constructor with a nonconst parameter |
| // }; |
| // const X cx; |
| // X x = cx; // error - X::X(X&) cannot copy cx into x |
| public void test12_8s2c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // template<typename T> S(T); |
| // }; |
| // S f(); |
| // void g() { |
| // S a( f() ); // does not instantiate member template |
| // } |
| public void test12_8s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void h(int()); |
| // void h(int (*)()); // redeclaration of h(int()) |
| // void h(int x()) { } // definition of h(int()) |
| // void h(int (*x)()) { } // illformed: redefinition of h(int()) |
| public void test12_8s3d() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| } |
| |
| // struct X { |
| // X(const X&, int); |
| // }; |
| public void test12_8s4a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // X(const X&, int); |
| // }; |
| // X::X(const X& x, int i =0) { } |
| public void test12_8s4b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // X(); |
| // X& operator=(X&); |
| // }; |
| // const X cx; |
| // X x; |
| // void f() { |
| // x = cx; // error: |
| // // X::operator=(X&) cannot assign cx into x |
| // } |
| public void test12_8s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct V { }; |
| // struct A : virtual V { }; |
| // struct B : virtual V { }; |
| // struct C : B, A { }; |
| public void test12_8s13() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Thing { |
| // public: |
| // Thing(); |
| // ~Thing(); |
| // Thing(const Thing&); |
| // Thing operator=(const Thing&); |
| // void fun(); |
| // }; |
| // Thing f() { |
| // Thing t; |
| // return t; |
| // } |
| // Thing t2 = f(); |
| public void test12_8s15() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // double abs(double); |
| // int abs(int); |
| // int foo() { |
| // abs(1); //call abs(int); |
| // abs(1.0); //call abs(double); |
| // } |
| public void test13s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // static void f(); |
| // void f(); // illformed |
| // void f() const; // illformed |
| // void f() const volatile; // illformed |
| // void g(); |
| // void g() const; // OK: no static g |
| // void g() const volatile; // OK: no static g |
| // }; |
| public void test12_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int Int; |
| // void f(int i); |
| // void f(Int i); // OK: redeclaration of f(int) |
| // void f(int i) { } |
| // void f(Int i) { } // error: redefinition of f(int) |
| public void test12_1s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| } |
| |
| // enum E { a }; |
| // void f(int i) { } |
| // void f(E i) { } |
| public void test12_1s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(char*); |
| // int f(char[]); // same as f(char*); |
| // int f(char[7]); // same as f(char*); |
| // int f(char[9]); // same as f(char*); |
| // int g(char(*)[10]); |
| // int g(char[5][10]); // same as g(char(*)[10]); |
| // int g(char[7][10]); // same as g(char(*)[10]); |
| // int g(char(*)[20]); // different from g(char(*)[10]); |
| public void test12_1s3c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef const int cInt; |
| // int f (int); |
| // int f (const int); // redeclaration of f(int) |
| // int f (int) { } // definition of f(int) |
| // int f (cInt) { } // error: redefinition of f(int) |
| public void test12_8s3e() throws Exception { |
| String[] problems = { "f" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // void f (int i, int j); |
| // void f (int i, int j = 99); // OK: redeclaration of f(int, int) |
| // void f (int i = 88, int j); // OK: redeclaration of f(int, int) |
| // void f (); // OK: overloaded declaration of f |
| // void prog () |
| // { |
| // f (1, 2); // OK: call f(int, int) |
| // f (1); // OK: call f(int, int) |
| // f (); // Error: f(int, int) or f()? |
| // } |
| public void test12_8s3f() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class B { |
| // public: |
| // int f(int); |
| // }; |
| // class D : public B { |
| // public: |
| // int f(char*); |
| // }; |
| public void test13_2s1a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { |
| // public: |
| // int f(int); |
| // }; |
| // class D : public B { |
| // public: |
| // int f(char*); |
| // }; |
| // void h(D* pd) |
| // { |
| // pd->f(1); //error: |
| // // D::f(char*) hides B::f(int) |
| // pd->B::f(1); //OK |
| // pd->f("Ben"); //OK, calls D::f |
| // } |
| public void test13_2s1b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int f(char*); |
| // void g() |
| // { |
| // extern int f(int); |
| // f("asdf"); //error: f(int) hides f(char*) |
| // // so there is no f(char*) in this scope |
| // } |
| // void caller () |
| // { |
| // extern void callee(int, int); |
| // { |
| // extern void callee(int); // hides callee(int, int) |
| // callee(88, 99); // error: only callee(int) in scope |
| // } |
| // } |
| public void test13_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class buffer { |
| // private: |
| // char* p; |
| // int size; |
| // protected: |
| // buffer(int s, char* store) { size = s; p = store; } |
| // // ... |
| // public: |
| // buffer(int s) { p = new char[size = s]; } |
| // // ... |
| // }; |
| public void test13_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class T { |
| // public: |
| // T(); |
| // // ... |
| // }; |
| // class C : T { |
| // public: |
| // C(int); |
| // // ... |
| // }; |
| // T a = 1; // illformed: T(C(1)) not tried |
| public void test13_3_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f1(int); |
| // int f2(float); |
| // typedef int (*fp1)(int); |
| // typedef int (*fp2)(float); |
| // struct A { |
| // operator fp1() { return f1; } |
| // operator fp2() { return f2; } |
| // } a; |
| // int i = a(1); // Calls f1 via pointer returned from |
| // // conversion function |
| public void test13_3_1_1_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class String { |
| // public: |
| // String (const String&); |
| // String (char*); |
| // operator char* (); |
| // }; |
| // String operator + (const String&, const String&); |
| // void f(void) |
| // { |
| // char* p= "one" + "two"; // illformed because neither |
| // // operand has user defined type |
| // int I = 1 + 1; // Always evaluates to 2 even if |
| // // user defined types exist which |
| // // would perform the operation. |
| // } |
| public void test13_3_1_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // operator int(); |
| // }; |
| // A operator+(const A&, const A&); |
| // void m() { |
| // A a, b; |
| // a + b; // operator+(a,b) chosen over int(a) + int(b) |
| // } |
| public void test13_3_1_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // A(); |
| // operator int(); |
| // operator double(); |
| // } a; |
| // int i = a; // a.operator int() followed by no conversion |
| // // is better than a.operator double() followed by |
| // // a conversion to int |
| // float x = a; // ambiguous: both possibilities require conversions, |
| // // and neither is better than the other |
| public void test13_3_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void Fcn(const int*, short); |
| // void Fcn(int*, int); |
| // int i; |
| // short s = 0; |
| // void f() { |
| // Fcn(&i, s); // is ambiguous because |
| // // &i -> int* is better than &i -> const int* |
| // // but s -> short is also better than s -> int |
| // Fcn(&i, 1L); // calls Fcn(int*, int), because |
| // // &i -> int* is better than &i -> const int* |
| // // and 1L -> short and 1L -> int are indistinguishable |
| // Fcn(&i,'c'); //callsFcn(int*, int), because |
| // // &i -> int* is better than &i -> const int* |
| // // and c -> int is better than c -> short |
| // } |
| public void test13_3_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class B; |
| // class A { A (B&); }; |
| // class B { operator A (); }; |
| // class C { C (B&); }; |
| // void f(A) { } |
| // void f(C) { } |
| // B b; |
| // f(b); //ambiguous because b -> C via constructor and |
| // // b -> A via constructor or conversion function. |
| public void test13_3_3_1_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A {}; |
| // struct B : public A {} b; |
| // int f(A&); |
| // int f(B&); |
| // int i = f(b); // Calls f(B&), an exact match, rather than |
| // // f(A&), a conversion |
| public void test13_3_3_1_4s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(const int *); |
| // int f(int *); |
| // int i; |
| // int j = f(&i); // Calls f(int *) |
| public void test13_3_3_2s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(const int &); |
| // int f(int &); |
| // int g(const int &); |
| // int g(int); |
| // int i; |
| // int j = f(i); // Calls f(int &) |
| // int k = g(i); // ambiguous |
| // class X { |
| // public: |
| // void f() const; |
| // void f(); |
| // }; |
| // void g(const X& a, X b) |
| // { |
| // a.f(); //CallsX::f() const |
| // b.f(); //Calls X::f() |
| // } |
| public void test13_3_3_2s3b() throws Exception { |
| String[] problems = { "g" }; |
| parse(getAboveComment(), ParserLanguage.CPP, problems); |
| } |
| |
| // struct A { |
| // operator short(); |
| // } a; |
| // int f(int); |
| // int f(float); |
| // int i = f(a); // Calls f(int), because short -> int is |
| // // better than short -> float. |
| public void test13_3_3_2s3c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A {}; |
| // struct B : public A {}; |
| // struct C : public B {}; |
| // C *pc; |
| // int f(A *); |
| // int f(B *); |
| // int i = f(pc); // Calls f(B *) |
| public void test13_3_3_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // int f(int); |
| // static int f(long); |
| // }; |
| // int (X::*p1)(int) = &X::f; // OK |
| // int (*p2)(int) = &X::f; // error: mismatch |
| // int (*p3)(long) = &X::f; // OK |
| // int (X::*p4)(long) = &X::f; // error: mismatch |
| // int (*p6)(long) = &(X::f); // OK |
| public void test13_4s5b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class complex { |
| // public: |
| // complex operator+(complex a) {} |
| // }; |
| // int n; |
| // int foo(complex &a, complex &b) { |
| // complex z = a.operator+(b); // complex z = a+b; |
| // void* p = operator new(sizeof(int)*n); |
| // } |
| public void test13_5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual int operator= (int); |
| // virtual B& operator= (const B&); |
| // }; |
| // struct D : B { |
| // virtual int operator= (int); |
| // virtual D& operator= (const B&); |
| // }; |
| // D dobj1; |
| // D dobj2; |
| // B* bptr = &dobj1; |
| // void f() { |
| // bptr->operator=(99); // calls D::operator=(int) |
| // *bptr = 99; // ditto |
| // bptr->operator=(dobj2); // calls D::operator=(const B&) |
| // *bptr = dobj2; // ditto |
| // dobj1 = dobj2; // calls implicitlydeclared |
| // // D::operator=(const D&) |
| // } |
| public void test13_5_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // X& operator++(); // prefix ++a |
| // X operator++(int); // postfix a++ |
| // }; |
| // class Y { }; |
| // Y& operator++(Y&); // prefix ++b |
| // Y operator++(Y&, int); // postfix b++ |
| // void f(X a, Y b) { |
| // ++a; // a.operator++(); |
| // a++; // a.operator++(0); |
| // ++b; // operator++(b); |
| // b++; // operator++(b, 0); |
| // a.operator++(); // explicit call: like ++a; |
| // a.operator++(0); // explicit call: like a++; |
| // operator++(b); //explicit call: like ++b; |
| // operator++(b, 0); // explicit call: like b++; |
| // } |
| public void test13_5_7s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<const X& x, int i> void f() |
| // { |
| // i++; //error: change of template parameter |
| // value |
| // &x; //OK |
| // &i; //error: address of nonreference template parameter |
| // int& ri = i; // error: nonconst reference bound to temporary |
| // const int& cri = i; // OK: const reference bound to temporary |
| // } |
| public void test14_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<double d> class X; // error |
| // template<double* pd> class Y; // OK |
| // template<double& rd> class Z; // OK |
| public void test14_1s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<int *a> struct R { }; |
| // template<int b[5]> struct S { }; |
| // int *p; |
| // R<p> w; // OK |
| // S<p> x; // OK due to parameter adjustment |
| // int v[5]; |
| // R<v> y; // OK due to implicit argument conversion |
| // S<v> z; // OK due to both adjustment and conversion |
| public void test14_1s8() throws Exception { // TODO raised bug 90668 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1, class T2 = int> class A; |
| // template<class T1 = int, class T2> class A; |
| public void test14_1s10a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1 = int, class T2 = int> class A; |
| public void test14_1s10b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1 = int, class T2> class B; // error |
| public void test14_1s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T = int> class X; |
| // template<class T = int> class X { }; // error |
| public void test14_1s12() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T, T* p, class U = T> class X { }; |
| // template<class T> void f(T* p = new T); |
| public void test14_1s13() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<int i = (3 > 4) > // OK |
| // class Y { }; |
| public void test14_1s15() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<int i> class X { }; |
| // X<(1>2)> x2; // OK |
| // template<class T> class Y { }; |
| // Y< X<1> > x3; // OK |
| // // with C++0x this is no longer valid: |
| // // Y<X<6>> 1> > x4; // OK: Y< X< (6>>1) > > |
| public void test14_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // public: |
| // template<size_t> X* alloc(); |
| // template<size_t> static X* adjust(); |
| // }; |
| // template<class T> void f(T* p) |
| // { |
| // T* p1 = p> |
| // alloc<200>(); // illformed: < means less than |
| // T* p2 = p->template alloc<200>(); |
| // // OK: < starts template argument list |
| // T::adjust<100>(); |
| // // illformed: < means less than |
| // T::template adjust<100>(); |
| // // OK: < starts explicit qualification |
| // } |
| public void test14_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<typename T> class complex { |
| // complex(T,T) {} |
| // }; |
| // template<class T> class Array { |
| // T* v; |
| // int sz; |
| // public: |
| // explicit Array(int); |
| // T& operator[](int); |
| // T& elem(int i) { return v[i]; } |
| // // ... |
| // }; |
| // Array<int> v1(20); |
| // typedef complex<double> dcomplex; |
| // Array<dcomplex> v2(30); |
| // Array<dcomplex> v3(40); |
| // void bar() { |
| // v1[3] = 7; |
| // v2[3] = v3.elem(4) = dcomplex(7,8); |
| // } |
| public void test14_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class X { |
| // static T t; |
| // }; |
| // class Y { |
| // private: |
| // struct S { }; |
| // X<S> x; // OK: S is accessible |
| // // X<Y::S> has a static member of type Y::S |
| // // OK: even though Y::S is private |
| // }; |
| // X<Y::S> y; // error: S not accessible |
| public void test14_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // ~A(); |
| // }; |
| // void f(A<int>* p, A<int>* q) { |
| // p->A<int>::~A(); // OK: destructor call |
| // q->A<int>::~A<int>(); // OK: destructor call |
| // } |
| public void test14_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> class X { }; |
| // void f() |
| // { |
| // struct S { }; |
| // X<S> x3; // error: local type used as templateargument |
| // X<S*> x4; // error: pointer to local type used as templateargument |
| // } |
| public void test14_3_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // static T t; |
| // }; |
| // typedef int function(); |
| // A<function> a; // illformed: would declare A<function>::t |
| // // as a static member function |
| public void test14_3_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class A { // primary template |
| // int x; |
| // }; |
| // template<class T> class A<T*> { // partial specialization |
| // long x; |
| // }; |
| // template<template<class U> class V> class C { |
| // V<int> y; |
| // V<int*> z; |
| // }; |
| // C<A> c; // V<int> within C<A> uses the primary template, |
| // // so c.y.x has type int |
| // // V<int*> within C<A> uses the partial specialization, |
| // // so c.z.x has type long |
| public void test14_3_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class E, int size> class buffer { }; |
| // buffer<char,2*512> x; |
| // buffer<char,1024> y; |
| public void test14_2s1a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T, void(*err_fct)()> class list { }; |
| // list<int,&error_handler1> x1; |
| // list<int,&error_handler2> x2; |
| // list<int,&error_handler2> x3; |
| // list<char,&error_handler2> x4; |
| public void test14_4s1b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> class Array { |
| // T* v; |
| // int sz; |
| // public: |
| // explicit Array(int); |
| // T& operator[](int); |
| // T& elem(int i) { return v[i]; } |
| // // ... |
| // }; |
| public void test14_5_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1, class T2> struct A { |
| // void f1(); |
| // void f2(); |
| // }; |
| // template<class T2, class T1> void A<T2,T1>::f1() { } // OK |
| public void test14_5_1s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void error(const char*); |
| // template<class T> class Array { |
| // T* v; |
| // int sz; |
| // public: |
| // explicit Array(int); |
| // T& operator[](int); |
| // T& elem(int i) { return v[i]; } |
| // // ... |
| // }; |
| // template<class T> T& Array<T>::operator[](int i) |
| // { |
| // if (i<0 || sz<=i) error("Array: range error"); |
| // return v[i]; |
| // } |
| public void test14_5_1_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void test() { |
| // Array<int> v1(20); |
| // Array<dcomplex> v2(30); |
| // v1[3] = 7; // Array<int>::operator[]() |
| // v2[3] = dcomplex(7,8); // Array<dcomplex>::operator[]() |
| // } |
| public void test14_5_1_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> struct A { |
| // class B; |
| // }; |
| // A<int>::B* b1; // OK: requires A to be defined but not A::B |
| // template<class T> class A<T>::B { }; |
| // A<int>::B b2; // OK: requires A::B to be defined |
| public void test14_5_1_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class string { |
| // public: |
| // template<class T2> int compare(const T2&); |
| // template<class T2> string(const string<T2>& s) { } |
| // // ... |
| // }; |
| // template<class T> template<class T2> int string<T>::compare(const T2& s) |
| // { |
| // // ... |
| // } |
| public void test14_5_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class B { |
| // virtual void f(int); |
| // }; |
| // class D : public B { |
| // template <class T> void f(T); // does not override B::f(int) |
| // void f(int i) { f<>(i); } // overriding function that calls |
| // // the template instantiation |
| // }; |
| public void test14_5_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // template <class T> operator T*(); |
| // }; |
| // template <class T> A::operator T*(){ return 0; } |
| // template <> A::operator char*(){ return 0; } // specialization |
| // template A::operator void*(); // explicit instantiation |
| // int main() |
| // { |
| // A a; |
| // int* ip; |
| // ip = a.operator int*(); // explicit call to template operator |
| // // A::operator int*() |
| // } |
| public void test14_5_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class X { |
| // static T s; |
| // }; |
| // template<class T> T X<T>::s = 0; |
| public void test14_5_1_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class task; |
| // template<class T> task<T>* preempt(task<T>*); |
| // template<class T> class task { |
| // // ... |
| // friend void next_time(); |
| // friend void process(task<T>*); |
| // friend task<T>* preempt<T>(task<T>*); |
| // template<class C> friend int func(C); |
| // friend class task<int>; |
| // template<class P> friend class frd; |
| // // ... |
| // }; |
| public void test14_5_4s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // template <class T> void f(T); |
| // void g(int); |
| // namespace M { |
| // template <class T> void h(T); |
| // template <class T> void i(T); |
| // struct A { |
| // friend void f<>(int); // illformed- N::f |
| // friend void h<>(int); // OK - M::h |
| // friend void g(int); // OK - new decl of M::g |
| // template <class T> void i(T); |
| // friend void i<>(int); // illformed- A::i |
| // }; |
| // } |
| // } |
| public void test14_5_4s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class A { |
| // template<class T> friend class B; // OK |
| // template<class T> friend void f(T){ } // OK |
| // }; |
| public void test14_5_4s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { |
| // template<class T> friend struct A; |
| // class Y { }; |
| // }; |
| // template<class T> struct A { X::Y ab; }; // OK |
| // template<class T> struct A<T*> { X::Y ab; }; // OK |
| public void test14_5_4s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // struct B { }; |
| // void f(); |
| // }; |
| // class C { |
| // template<class T> friend struct A<T>::B; |
| // template<class T> friend void A<T>::f(); |
| // }; |
| public void test14_5_4s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // template<class T2> struct B {}; // #1 |
| // template<class T2> struct B<T2*> {}; // #2 |
| // }; |
| // template<> template<class T2> struct A<short>::B {}; // #3 |
| // A<char>::B<int*> abcip; // uses #2 |
| // A<short>::B<int*> absip; // uses #3 |
| // A<char>::B<int> abci; // uses #1 |
| public void test14_5_5_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1, class T2, int I> class A { }; // #1 |
| // template<class T, int I> class A<T, T*, I> { }; // #2 |
| // template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 |
| // template<class T> class A<int, T*, 5> { }; // #4 |
| // template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 |
| public void test14_5_5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <int I, int J> struct B {}; |
| // template <int I> struct B<I, I> {}; // OK |
| public void test14_5_5s9b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1, class T2, int I> class A { }; // #1 |
| // template<class T, int I> class A<T, T*, I> { }; // #2 |
| // template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 |
| // template<class T> class A<int, T*, 5> { }; // #4 |
| // template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 |
| // A<int, int, 1> a1; // uses #1 |
| // A<int, int*, 1> a2; // uses #2, T is int, I is 1 |
| // A<int, char*, 5> a3; // uses #4, T is char |
| // A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1 |
| public void test14_5_5_1s2a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1, class T2, int I> class A { }; // #1 |
| // template<class T, int I> class A<T, T*, I> { }; // #2 |
| // template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 |
| // template<class T> class A<int, T*, 5> { }; // #4 |
| // template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 |
| // A<int*, int*, 2> a5; // ambiguous: matches #3 and #5 : expect problem |
| public void test14_5_5_1s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 1); |
| } |
| |
| // template<int I, int J, class T> class X { }; |
| // template<int I, int J> class X<I, J, int> { }; // #1 |
| // template<int I> class X<I, I, int> { }; // #2 |
| // template<int I, int J> void f(X<I, J, int>); // #A |
| // template<int I> void f(X<I, I, int>); // #B |
| public void test14_5_5_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // primary template |
| // template<class T, int I> struct A { |
| // void f(); |
| // }; |
| // template<class T, int I> void A<T,I>::f() { } |
| // // class template partial specialization |
| // template<class T> struct A<T,2> { |
| // void f(); |
| // void g(); |
| // void h(); |
| // }; |
| // // member of class template partial specialization |
| // template<class T> void A<T,2>::g() { } |
| // // explicit specialization |
| // template<> void A<char,2>::h() { } |
| // int main() |
| // { |
| // A<char,0> a0; |
| // A<char,2> a2; |
| // a0.f(); //OK, uses definition of primary template's member |
| // a2.g(); //OK, uses definition of |
| // // partial specialization's member |
| // a2.h(); //OK, uses definition of |
| // // explicit specialization's member |
| // a2.f(); //illformed, no definition of f for A<T,2> |
| // // the primary template is not used here |
| // } |
| public void test14_5_5_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> class Array { }; |
| // template<class T> void sort(Array<T>&); |
| public void test14_5_6s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // file1.c |
| // template<class T> |
| // void f(T*); |
| // void g(int* p) { |
| // f(p); // call |
| // // f<int>(int*) |
| // } |
| public void test14_5_6_1s1a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // file2.c |
| // template<class T> |
| // void f(T); |
| // void h(int* p) { |
| // f(p); // call |
| // // f<int*>(int*) |
| // } |
| public void test14_5_6_1s1b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // Guaranteed to be the same |
| // template <int T> class A; |
| // template <int I> void f/*1*/(A<I>, A<I+10>); |
| // template <int I> void f/*2*/(A<I>, A<I+10>); |
| // // Guaranteed to be different |
| // template <int I> void f/*3*/(A<I>, A<I+11>); |
| public void test14_5_6_1s8a() throws Exception { |
| final String content = getAboveComment(); |
| IASTTranslationUnit tu = parse(content, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| ICPPFunctionTemplate f1 = bh.assertNonProblem("f/*1*/", 1); |
| ICPPFunctionTemplate f2 = bh.assertNonProblem("f/*2*/", 1); |
| ICPPFunctionTemplate f3 = bh.assertNonProblem("f/*3*/", 1); |
| assertSame(f1, f2); |
| assertNotSame(f1, f3); |
| } |
| |
| // // Illformed, no diagnostic required |
| // template <int I> void f(A<I>, A<I+10>); |
| // template <int I> void f(A<I>, A<I+1+2+3+4>); |
| public void test14_5_6_1s8b() throws Exception { |
| //test is only for syntax, semantics are not checked here. |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { }; |
| // template<class T> struct B { |
| // template<class R> int operator*(R&); // #1 |
| // }; |
| // template<class T, class R> int operator*(T&, R&); // #2 |
| // // The declaration of B::operator* is transformed into the equivalent of |
| // // template<class R> int operator*(B<A>&, R&); // #1a |
| // int main() { |
| // A a; |
| // B<A> b; |
| // b * a; // calls #1a |
| // } |
| public void test14_5_6_2s3() throws Exception { |
| String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| IBinding op1 = bh.assertNonProblem("operator*(R&)", -4); |
| IASTImplicitName name = bh.assertImplicitName("* a", 1, ICPPFunction.class); |
| ICPPTemplateInstance inst = (ICPPTemplateInstance) name.resolveBinding(); |
| ICPPSpecialization templateSpecialization = (ICPPSpecialization) inst.getTemplateDefinition(); |
| assertSame(op1, templateSpecialization.getSpecializedBinding()); |
| } |
| |
| // template<class T> struct A { A(); }; |
| // template<class T> void f(T); |
| // template<class T> void f(T*); |
| // template<class T> void f(const T*); |
| // template<class T> void g(T); |
| // template<class T> void g(T&); |
| // template<class T> void h(const T&); |
| // template<class T> void h(A<T>&); |
| // void m() { |
| // const int *p; |
| // f(p); // f(const T*) is more specialized than f(T) or f(T*) |
| // float x; |
| // g(x); //Ambiguous: g(T) or g(T&) |
| // A<int> z; |
| // h(z); //overload resolution selects h(A<T>&) |
| // const A<int> z2; |
| // h(z2); // h(const T&) is called because h(A<T>&) is not callable |
| // } |
| public void test14_5_6_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> void f(T); // #1 |
| // template<class T> void f(T*, int=1); // #2 |
| // template<class T> void g(T); // #3 |
| // template<class T> void g(T*, ...); // #4 |
| // int main() { |
| // int* ip; |
| // f(ip); //calls #2 |
| // g(ip); //calls #4 |
| // } |
| public void test14_5_6_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // no B declared here |
| // class X; |
| // template<class T> class Y { |
| // class Z; // forward declaration of member class |
| // void f() { |
| // X* a1; // declare pointer to X |
| // T* a2; // declare pointer to T |
| // Y* a3; // declare pointer to Y<T> |
| // Z* a4; // declare pointer to Z |
| // typedef typename T::A TA; |
| // TA* a5; // declare pointer to T's A |
| // typename T::A* a6; // declare pointer to T's A |
| // T::A* a7; // T::A is not a type name: |
| // // multiply T::A by a7; illformed, |
| // // no visible declaration of a7 |
| // B* a8; // B is not a type name: |
| // // multiply B by a8; illformed, |
| // // no visible declarations of B and a8 |
| // } |
| // }; |
| public void test14_6s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { |
| // struct X { }; |
| // int X; |
| // }; |
| // template<class T> void f(T t) { |
| // typename T::X x; // illformed: finds the data member X |
| // // not the member type X |
| // } |
| public void test14_6s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // typedef int B; |
| // A::B b; // illformed: typename required before A::B |
| // void f(A<T>::B); // illformed: typename required before A<T>::B |
| // typename A::B g(); // OK |
| // }; |
| public void test14_6s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int j; |
| // template<class T> class X { |
| // // ... |
| // void f(T t, int i, char* p) |
| // { |
| // t = i; // diagnosed if X::f is instantiated |
| // // and the assignment to t is an error |
| // p = i; // may be diagnosed even if X::f is |
| // // not instantiated |
| // p = j; // may be diagnosed even if X::f is |
| // // not instantiated |
| // } |
| // void g(T t) { |
| // // +; //may be diagnosed even if X::g is |
| // // not instantiated |
| // } |
| // }; |
| public void test14_6s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // //#include <iostream> |
| // using namespace std; |
| // template<class T> class Set { |
| // T* p; |
| // int cnt; |
| // public: |
| // Set(); |
| // Set<T>(const Set<T>&); |
| // void printall() |
| // { |
| // for (int i = 0; i<cnt; i++) |
| // cout << p[i] << '\ |
| // '; |
| // } |
| // // ... |
| // }; |
| public void test14_6s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void f(char); |
| // template<class T> void g(T t) |
| // { |
| // f(1); // f(char) |
| // f(T(1)); //dependent |
| // f(t); //dependent |
| // dd++; //not dependent |
| // // error: declaration for dd not found |
| // } |
| // void f(int); |
| // double dd; |
| // void h() |
| // { |
| // g(2); //will cause one call of f(char) followed |
| // // by two calls of f(int) |
| // g('a'); //will cause three calls of f(char) |
| // } |
| public void test14_6s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T, T* p, class U = T> class X { }; |
| // template<class T> void f(T* p = new T); |
| public void test14_6_1s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class X { |
| // X* p; // meaning X<T> |
| // X<T>* p2; |
| // X<int>* p3; |
| // }; |
| public void test14_6_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class Y; |
| // template<> class Y<int> { |
| // Y* p; // meaning Y<int> |
| // Y<char>* q; // meaning Y<char> |
| // }; |
| public void test14_6_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<typename T> class Array {}; |
| // template<class T> class X : public Array<T> { }; |
| // template<class T> class Y : public T { }; |
| public void test14_6_1s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T, int i> class Y { |
| // int T; // error: templateparameter redeclared |
| // void f() { |
| // char T; // error: templateparameter redeclared |
| // } |
| // }; |
| // template<class X> class X; // error: templateparameter redeclared |
| public void test14_6_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // struct B { }; |
| // void f(); |
| // }; |
| // template<class B> void A<B>::f() { |
| // B b; // A's B, not the template parameter |
| // } |
| public void test14_6_1s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // int C; |
| // template<class T> class B { |
| // void f(T); |
| // }; |
| // } |
| // template<class C> void N::B<C>::f(C) { |
| // C b; // C is the template parameter, not N::C |
| // } |
| public void test14_6_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // struct B { }; |
| // int a; |
| // int Y; |
| // }; |
| // template<class B, class a> struct X : A { |
| // B b; // A's B |
| // a b; // error: A's a isn't a type name |
| // }; |
| public void test14_6_1s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template <typename T> class B {}; |
| // template<class T> struct X : B<T> { |
| // typename T::A* pa; |
| // void f(B<T>* pb) { |
| // static int i = B<T>::i; |
| // pb->j++; |
| // } |
| // }; |
| public void test14_6_2s2() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPUnknownBinding unknown = bh.assertNonProblem("B<T>", 4); |
| unknown = bh.assertNonProblem("T::A", 4); |
| unknown = bh.assertNonProblem("B<T>::i", 7); |
| unknown = bh.assertNonProblem("j", 1); |
| } |
| |
| // typedef double A; |
| // template<class T> class B { |
| // typedef int A; |
| // }; |
| // template<class T> struct X : B<T> { |
| // A a; // a has type double |
| // }; |
| public void test14_6_2s3() throws Exception { |
| final String content = getAboveComment(); |
| IASTTranslationUnit tu = parse(content, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| IVariable v = bh.assertNonProblem("a;", 1); |
| IType t = v.getType(); |
| assertInstance(t, ITypedef.class); |
| t = ((ITypedef) t).getType(); |
| assertInstance(t, IBasicType.class); |
| assertEquals(IBasicType.t_double, ((IBasicType) t).getType()); |
| } |
| |
| // struct A { |
| // struct B { }; |
| // int a; |
| // int Y; |
| // }; |
| // int a; |
| // template<class T> struct Y : T { |
| // struct B { }; |
| // B b; // The B defined in Y |
| // void f(int i) { a = i; } // ::a |
| // Y* p; // Y<T> |
| // }; |
| // Y<A> ya; |
| public void test14_6_2s4() throws Exception { |
| final String content = getAboveComment(); |
| parse(content, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| IBinding b = bh.assertNonProblem("b;", 1); |
| assertEquals("Y", b.getOwner().getName()); |
| b = bh.assertNonProblem("a = i", 1); |
| assertNull(b.getOwner()); |
| } |
| |
| // void g(double); |
| // void h(); |
| // template<class T> class Z { |
| // public: |
| // void f() { |
| // g(1); //calls g(double) |
| // h++; //illformed: |
| // // cannot increment function; |
| // // this could be diagnosed either here or |
| // // at the point of instantiation |
| // } |
| // }; |
| // void g(int); // not in scope at the point of the template |
| // // definition, not considered for the call g(1) |
| public void test14_6_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<typename T> class number { |
| // number(int); |
| // //... |
| // friend number gcd(number& x, number& y) { } |
| // //... |
| // }; |
| // void g() |
| // { |
| // number<double> a(3), b(4); |
| // //... |
| // a = gcd(a,b); // finds gcd because number<double> is an |
| // // associated class, making gcd visible |
| // // in its namespace (global scope) |
| // b = gcd(3,4); // illformed; gcd is not visible |
| // } |
| public void test14_6_5s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> class X { |
| // static T s; |
| // // ... |
| // }; |
| // template<class T> T X<T>::s = 0; |
| // X<int> aa; |
| // X<char*> bb; |
| public void test14_7s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class Z { |
| // public: |
| // void f(); |
| // void g(); |
| // }; |
| // void h() |
| // { |
| // Z<int> a; // instantiation of class Z<int> required |
| // Z<char>* p; // instantiation of class Z<char> not |
| // // required |
| // Z<double>* q; // instantiation of class Z<double> |
| // // not required |
| // a.f(); //instantiation of Z<int>::f() required |
| // p->g(); //instantiation of class Z<char> required, and |
| // // instantiation of Z<char>::g() required |
| // } |
| public void test14_7_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class B { }; |
| // template<class T> class D : public B<T> { }; |
| // void f(void*); |
| // void f(B<int>*); |
| // void g(D<int>* p, D<char>* pp, D<double> ppp) |
| // { |
| // f(p); //instantiation of D<int> required: call f(B<int>*) |
| // B<char>* q = pp; // instantiation of D<char> required: |
| // // convert D<char>* to B<char>* |
| // delete ppp; // instantiation of D<double> required |
| // } |
| public void test14_7_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class X; |
| // X<char> ch; // error: definition of X required |
| public void test14_7_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T = int> struct A { |
| // static int x; |
| // }; |
| // template<class U> void g(U) { } |
| // template<> struct A<double> { }; // specialize for T == double |
| // template<> struct A<> { }; // specialize for T == int |
| // template<> void g(char) { } // specialize for U == char |
| // // U is deduced from the parameter type |
| // template<> void g<int>(int) { } // specialize for U == int |
| // template<> int A<char>::x = 0; // specialize for T == char |
| // template<class T = int> struct B { |
| // static int x; |
| // }; |
| // template<> int B<>::x = 1; // specialize for T == int |
| public void test14_7s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> struct S { |
| // operator int(); |
| // }; |
| // void f(int); |
| // void f(S<int>&); |
| // void f(S<float>); |
| // void g(S<int>& sr) { |
| // f(sr); //instantiation of S<int> allowed but not required |
| // // instantiation of S<float> allowed but not required |
| // }; |
| public void test14_7_1s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // template<class T> class List { |
| // public: |
| // T* get(); |
| // // ... |
| // }; |
| // } |
| // template<class K, class V> class Map { |
| // N::List<V> lt; |
| // V get(K); |
| // // ... |
| // }; |
| // void g(Map<char*,int>& m) |
| // { |
| // int i = m.get("Nicholas"); |
| // // ... |
| // } |
| public void test14_7_1s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void f(T x, T y = ydef(T()), T z = zdef(T())); |
| // class A { }; |
| // A zdef(A); |
| // void g(A a, A b, A c) { |
| // f(a, b, c); // no default argument instantiation |
| // f(a, b); // default argument z = zdef(T()) instantiated |
| // f(a); //illformed; ydef is not declared |
| // } |
| public void test14_7_1s12() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> class X { |
| // X<T>* p; // OK |
| // X<T*> a; // implicit generation of X<T> requires |
| // // the implicit instantiation of X<T*> which requires |
| // // the implicit instantiation of X<T**> which ... |
| // }; |
| public void test14_7_1s14() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class Array { void mf(); }; |
| // template class Array<char>; |
| // template void Array<int>::mf(); |
| // template<class T> void sort(Array<T>& v) { } |
| // template void sort(Array<char>&); // argument is deduced here |
| // namespace N { |
| // template<class T> void f(T&) { } |
| // } |
| // template void N::f<int>(int&); |
| public void test14_7_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // template<class T> class Y { void mf() { } }; |
| // } |
| // template class Y<int>; // error: class template Y not visible |
| // // in the global namespace |
| // using N::Y; |
| // template class Y<int>; // OK: explicit instantiation in namespace N |
| // template class N::Y<char*>; // OK: explicit instantiation in namespace N |
| // template void N::Y<double>::mf(); // OK: explicit instantiation |
| // // in namespace N |
| public void test14_7_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> class Array { }; |
| // template<class T> void sort(Array<T>& v); |
| // // instantiate sort(Array<int>&) - templateargument deduced |
| // template void sort<>(Array<int>&); |
| public void test14_7_2s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // char* p = 0; |
| // template<class T> T g(T = &p); |
| // template int g<int>(int); // OK even though &p isn't an int. |
| public void test14_7_2s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class stream; |
| // template<> class stream<char> { }; |
| // template<class T> class Array { }; |
| // template<class T> void sort(Array<T>& v) { } |
| // template<> void sort<char*>(Array<char*>&) ; |
| public void test14_7_3s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<> class X<int> { }; // error: X not a template |
| // template<class T> class X; |
| // template<> class X<char*> { }; // OK: X is a template |
| public void test14_7_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> struct A { |
| // void f(T) { } |
| // }; |
| // template<> struct A<int> { |
| // void f(int); |
| // }; |
| // void h() |
| // { |
| // A<int> a; |
| // a.f(16); // A<int>::f must be defined somewhere |
| // } |
| // // explicit specialization syntax not used for a member of |
| // // explicitly specialized class template specialization |
| // void A<int>::f(int) { } |
| public void test14_7_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class Array { }; |
| // template<class T> void sort(Array<T>& v) { } |
| // void f(Array<String>& v) |
| // { |
| // sort(v); //use primary template |
| // // sort(Array<T>&), T is String |
| // } |
| // template<> void sort<String>(Array<String>& v); // error: specialization |
| // // after use of primary template |
| // template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used |
| public void test14_7_3s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // namespace N { |
| // template<class T> class X { }; |
| // template<class T> class Y { }; |
| // template<> class X<int> { }; // OK: specialization |
| // // in same namespace |
| // template<> class Y<double>; // forward declare intent to |
| // // specialize for double |
| // } |
| // template<> class N::Y<double> { }; // OK: specialization |
| // // in same namespace |
| public void test14_7_3s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class Array { }; |
| // template<class T> void sort(Array<T>& v); |
| // // explicit specialization for sort(Array<int>&) |
| // // with deduces templateargument of type int |
| // template<> void sort(Array<int>&); |
| public void test14_7_3s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1> class A { |
| // template<class T2> class B { |
| // void mf(); |
| // }; |
| // }; |
| // template<> template<> class A<int>::B<double> { }; |
| // template<> template<> void A<char>::B<char>::mf() { }; |
| public void test14_7_3s17() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class X; // X is a class template |
| // template<> class X<int>; |
| // X<int>* p; // OK: pointer to declared class X<int> |
| // X<int> x; // error: object of incomplete class X<int> |
| public void test14_7_3s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> void f(T); |
| // template <class T> void f(T*); |
| // template <> void f(int*); // Ambiguous |
| // template <> void f<int>(int*); // OK |
| // template <> void f(int); // OK |
| public void test14_7_3s12() throws Exception { |
| // gcc does not report the explicit instantiation as ambiguous, so we accept it as well. |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void f(T) { } |
| // template<class T> inline T g(T) { } |
| // template<> inline void f<>(int) { } // OK: inline |
| // template<> int g<>(int) { } // OK: not inline |
| public void test14_7_3s14() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct A { |
| // void f(T); |
| // template<class X> void g(T,X); |
| // void h(T) { } |
| // }; |
| // // specialization |
| // template<> void A<int>::f(int); |
| // // out of class member template definition |
| // template<class T> template<class X> void A<T>::g(T,X) { } |
| // // member template partial specialization |
| // template<> template<class X> void A<int>::g(int,X); |
| // // member template specialization |
| // template<> template<> |
| // void A<int>::g(int,char); // X deduced as char |
| // template<> template<> |
| // void A<int>::g<char>(int,char); // X specified as char |
| // // member specialization even if defined in class definition |
| // template<> void A<int>::h(int) { } |
| public void test14_7_3s16() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T1> class A { |
| // template<class T2> class B { |
| // template<class T3> void mf1(T3); |
| // void mf2(); |
| // }; |
| // }; |
| // template<> template<class X> |
| // class A<int>::B { }; |
| // template<> template<> template<class T> |
| // void A<int>::B<double>::mf1(T t) { }; |
| // template<class Y> template<> |
| // void A<Y>::B<double>::mf2() { }; // illformed; B<double> is specialized but |
| // // its enclosing class template A is not |
| public void test14_7_3s18() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> void f(T* p) |
| // { |
| // static T s; |
| // // ... |
| // }; |
| // void g(int a, char* b) |
| // { |
| // f(&a); //call f<int>(int*) |
| // f(&b); //call f<char*>(char**) |
| // } |
| public void test14_8s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void sort(Array<T>& v); |
| // void f(Array<dcomplex>& cv, Array<int>& ci) |
| // { |
| // sort<dcomplex>(cv); // sort(Array<dcomplex>&) |
| // sort<int>(ci); // sort(Array<int>&) |
| // } |
| // template<class U, class V> U convert(V v); |
| // void g(double d) |
| // { |
| // int i = convert<int,double>(d); // int convert(double) |
| // char c = convert<char,double>(d); // char convert(double) |
| // } |
| public void test14_8_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class X, class Y> X f(Y); |
| // void g() |
| // { |
| // int i = f<int>(5.6); // Y is deduced to be double |
| // int j = f(5.6); // illformed: X cannot be deduced |
| // } |
| public void test14_8_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class X, class Y, class Z> X f(Y,Z); |
| // void g() |
| // { |
| // f<int,char*,double>("aa",3.0); |
| // f<int,char*>("aa",3.0); // Z is deduced to be double |
| // f<int>("aa",3.0); // Y is deduced to be char*, and |
| // // Z is deduced to be double |
| // f("aa",3.0); //error: X cannot be deduced |
| // } |
| public void test14_8_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> void f(T); |
| // class Complex { |
| // // ... |
| // Complex(double); |
| // }; |
| // void g() |
| // { |
| // f<Complex>(1); // OK, means f<Complex>(Complex(1)) |
| // } |
| public void test14_8_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // struct B { }; |
| // template<int X> void f(); |
| // } |
| // namespace C { |
| // template<class T> void f(T t); |
| // } |
| // void g(A::B b) { |
| // f<3>(b); //illformed: not a function call |
| // A::f<3>(b); //wellformed |
| // C::f<3>(b); //illformed; argument dependent lookup |
| // // only applies to unqualified names |
| // using C::f; |
| // f<3>(b); //wellformed because C::f is visible; then |
| // // A::f is found by argument dependent lookup |
| // } |
| public void test14_8_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // void f(Array<dcomplex>& cv, Array<int>& ci) |
| // { |
| // sort(cv); //call sort(Array<dcomplex>&) |
| // sort(ci); //call sort(Array<int>&) |
| // } |
| // void g(double d) |
| // { |
| // int i = convert<int>(d); // call convert<int,double>(double) |
| // int c = convert<char>(d); // call convert<char,double>(double) |
| // } |
| public void test14_8_2s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template <class T> void f(T t); |
| // template <class X> void g(const X x); |
| // template <class Z> void h(Z, Z*); |
| // int main() |
| // { |
| // // #1: function type is f(int), t is nonconst |
| // f<int>(1); |
| // // #2: function type is f(int), t is const |
| // f<const int>(1); |
| // // #3: function type is g(int), x is const |
| // g<int>(1); |
| // // #4: function type is g(int), x is const |
| // g<const int>(1); |
| // // #5: function type is h(int, const int*) |
| // h<const int>(1,0); |
| // } |
| public void test14_8_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T, class U = double> |
| // void f(T t = 0, U u = 0); |
| // void g() { |
| // f(1, 'c'); // f<int,char>(1,'c') |
| // f(1); // f<int,double>(1,0) |
| // f(); // error: T cannot be deduced |
| // f<int>(); // f<int,double>(0,0) |
| // f<int,char>(); // f<int,char>(0,0) |
| // } |
| public void test14_8_2s5() throws Exception { |
| final String content = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(1, 'c')", 1); |
| assertEquals("<int,char>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f(1)", 1); |
| assertEquals("<int,double>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f()", 1); |
| inst = bh.assertNonProblem("f<int>()", -2); |
| assertEquals("<int,double>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f<int,char>()", -2); |
| assertEquals("<int,char>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // struct X { }; |
| // struct Y { |
| // Y(X){} |
| // }; |
| // template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1 |
| // X f(Y, Y); // #2 |
| // X x1, x2; |
| // X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2 |
| public void test14_8_2s8a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template <class T> int f(T[5]); |
| // int I = f<int>(0); |
| // int j = f<void>(0); // invalid array |
| public void _test14_8_2s8b() throws Exception { |
| final String content = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| bh.assertNonProblem("f<int>(0)", -3); |
| bh.assertProblem("f<void>(0)", -3); |
| } |
| |
| // template <class T> int f(typename T::B*); |
| // int i = f<int>(0); |
| public void test14_8_2s8c() throws Exception { |
| final String content = getAboveComment(); |
| IASTTranslationUnit tu = parse(content, ParserLanguage.CPP, true, 2); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| bh.assertProblem("f<", 1); |
| bh.assertProblem("f<int>", 6); |
| } |
| |
| // template <int I> struct X { }; |
| // template <template <class T> class> struct Z { }; |
| // template <class T> void f(typename T::Y*){} |
| // template <class T> void g(X<T::N>*){} |
| // template <class T> void h(Z<T::template TT>*){} |
| // struct A {}; |
| // struct B { int Y; }; |
| // struct C { |
| // typedef int N; |
| // }; |
| // struct D { |
| // typedef int TT; |
| // }; |
| // int main() { |
| // // Deduction fails in each of these cases: |
| // f<A>(0); // A does not contain a member Y |
| // f<B>(0); // The Y member of B is not a type |
| // g<C>(0); // The N member of C is not a non-type |
| // h<D>(0); // The TT member of D is not a template |
| // } |
| public void test14_8_2s8d() throws Exception { |
| final String content = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| bh.assertProblem("f<A>", 0); |
| bh.assertProblem("f<B>", 0); |
| bh.assertProblem("g<C>", 0); |
| bh.assertProblem("h<D>", 0); |
| } |
| |
| // template <class T> int f(int T::*); |
| // int i = f<int>(0); |
| public void test14_8_2s8e() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 2); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| bh.assertProblem("f<int>", 0); |
| } |
| |
| // template <class T, T> struct S {}; |
| // template <class T> int f(S<T, T()>*); |
| // struct X {}; |
| // int i0 = f<X>(0); |
| public void test14_8_2s8f() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 2); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| bh.assertProblem("f<X>", 0); |
| } |
| |
| // template <class T, T*> int f(int); |
| // int i2 = f<int,1>(0); // can't conv 1 to int* |
| public void test14_8_2s8g() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 1); |
| } |
| |
| // template <int> int f(int); |
| // template <signed char> int f(int); |
| // int i1 = f<1>(0); // ambiguous |
| // int i2 = f<1000>(0); // ambiguous |
| public void test14_8_2s9() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 2); |
| } |
| |
| // namespace std { |
| // template<typename T> class initializer_list; |
| // } |
| // template<class T> void f(std::initializer_list<T>); |
| // template<class T> void g(T); |
| // void test() { |
| // f({1,2,3}); // T deduced to int |
| // f({1,"asdf"}); // error: T deduced to both int and const char* |
| // g({1,2,3}); // error: no argument deduced for T |
| // } |
| public void test14_8_2_1s1a() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f({1,2,3})", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f({1,\"asdf\"})", 1); |
| bh.assertProblem("g({1,2,3})", 1); |
| } |
| |
| // template<class ... Types> void f(Types& ...); |
| // template<class T1, class ... Types> void g(T1, Types ...); |
| // void h(int x, float& y) { |
| // const int z = x; |
| // f(x, y, z); // Types is deduced to int, float, const int |
| // g(x, y, z); // T1 is deduced to int; Types is deduced to float, int |
| // } |
| public void test14_8_2_1s1b() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(x, y, z)", 1); |
| assertEquals("<int,float,const int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("g(x, y, z)", 1); |
| assertEquals("<int,float,int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template <class T> int f(T&&); |
| // template <class T> int g(const T&&); |
| // int i; |
| // int n1 = f(i); // calls f<int&>(int&) |
| // int n2 = f(0); // calls f<int>(int&&) |
| // int n3 = g(i); // error: would call g<int>(const int&&), which |
| // // would bind an rvalue reference to an lvalue |
| public void test14_8_2_1s3() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(i)", 1); |
| assertEquals("<int &>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f(0)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("g(i)", 1); |
| } |
| |
| // // Only one function of an overload set matches the call so the function |
| // // parameter is a deduced context. |
| // template <class T> int f(T (*p)(T)); |
| // int g(int); |
| // int g(char); |
| // int i = f(g); // calls f(int (*)(int)) |
| public void test14_8_2_1s7() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(g)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // // Ambiguous deduction causes the second function parameter to be a |
| // // non-deduced context. |
| // template <class T> int f(T, T (*p)(T)); |
| // int g(int); |
| // char g(char); |
| // int i = f(1, g); // calls f(int, int (*)(int)) |
| public void test14_8_2_1s8() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(1, g)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // // The overload set contains a template, causing the second function |
| // // parameter to be a non-deduced context. |
| // template <class T> int f(T, T (*p)(T)); |
| // char g(char); |
| // template <class T> T g(T); |
| // int i = f(1, g); // calls f(int, int (*)(int)) |
| public void test14_8_2_1s9() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(1, g)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // struct A { |
| // template <class T> operator T***(); |
| // }; |
| // A a; |
| // void test(const int * const * const * p1) { |
| // test(a); // T is deduced as int, not const int |
| // } |
| public void test14_8_2_3s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> T f(int); // #1 |
| // template <class T, class U> T f(U); // #2 |
| // void g() { |
| // f<int>(1); // calls #1 |
| // } |
| public void test14_8_2_4s11() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<typename...> struct Tuple { }; |
| // template<typename... Types> void g(Tuple<Types...>); // #1 |
| // template<typename T1, typename... Types> void g(Tuple<T1, Types...>); // #2 |
| // template<typename T1, typename... Types> void g(Tuple<T1, Types&...>); // #3 |
| // void test() { |
| // g(Tuple<>()); // calls #1 |
| // g(Tuple<int, float>()); // calls #2 |
| // g(Tuple<int, float&>()); // calls #3 |
| // g(Tuple<int>()); // calls #3 |
| // } |
| public void test14_8_2_4s12() throws Exception { |
| final String code = getAboveComment(); |
| parse(code, ParserLanguage.CPP, true, 0); |
| |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPFunction g1 = bh.assertNonProblem("g(Tuple<Types...>)", 1); |
| ICPPFunction g2 = bh.assertNonProblem("g(Tuple<T1, Types...>)", 1); |
| ICPPFunction g3 = bh.assertNonProblem("g(Tuple<T1, Types&...>)", 1); |
| |
| ICPPTemplateInstance x = bh.assertNonProblem("g(Tuple<>())", 1); |
| assertSame(g1, x.getTemplateDefinition()); |
| x = bh.assertNonProblem("g(Tuple<int, float>())", 1); |
| assertSame(g2, x.getTemplateDefinition()); |
| x = bh.assertNonProblem("g(Tuple<int, float&>())", 1); |
| assertSame(g3, x.getTemplateDefinition()); |
| x = bh.assertNonProblem("g(Tuple<int>())", 1); |
| assertSame(g3, x.getTemplateDefinition()); |
| } |
| |
| // template<class T> void g(T); |
| // void test() { |
| // g({1,2,3}); // error: no argument deduced for T |
| // } |
| public void test14_8_2_5s5() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| bh.assertProblem("g({1,2,3})", 1); |
| } |
| |
| // template<class T> void f(T x, T y) { } |
| // struct A { }; |
| // struct B : A { }; |
| // int g(A a, B b) |
| // { |
| // f(a,b); //error: T could be A or B |
| // f(b,a); //error: T could be A or B |
| // f(a,a); //OK: T is A |
| // f(b,b); //OK: T is B |
| // } |
| public void test14_8_2_5s7a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template <class T, class U> void f( T (*)( T, U, U ) ); |
| // int g1( int, float, float); |
| // char g2( int, float, float); |
| // int g3( int, char, float); |
| // void r() |
| // { |
| // f(g1); //OK: T is int and U is float |
| // f(g2); //error: T could be char or int |
| // f(g3); //error: U could be char or float |
| // } |
| public void test14_8_2_5s7b() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(g1)", 1); |
| assertEquals("<int,float>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f(g2)", 1); |
| bh.assertProblem("f(g3)", 1); |
| } |
| |
| // template<class T> void f(const T*) {} |
| // int *p; |
| // void s() |
| // { |
| // f(p); // f(const int *) |
| // } |
| public void test14_8_2_5s7c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> struct B { }; |
| // template <class T> struct D : public B<T> {}; |
| // struct D2 : public B<int> {}; |
| // template <class T> void f(B<T>&){} |
| // void t() |
| // { |
| // D<int> d; |
| // D2 d2; |
| // f(d); //calls f(B<int>&) |
| // f(d2); //calls f(B<int>&) |
| // } |
| public void test14_8_2_5s7d() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> void f(T&&); |
| // template <> void f(int&) { } // #1 |
| // template <> void f(int&&) { } // #2 |
| // void g(int i) { |
| // f(i); // calls f<int&>(int&), i.e., #1 |
| // f(0); // calls f<int>(int&&), i.e., #2 |
| // } |
| public void test14_8_2_5s10() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(i)", 1); |
| assertEquals("<int &>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f(0)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template<class T, T i> void f(double a[10][i]); |
| // int v[10][20]; |
| // int foo() { |
| // f(v); //error: argument for templateparameter |
| // //T cannot be deduced |
| // } |
| public void test14_8_2_5s14() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| bh.assertProblem("f(v)", 1); |
| } |
| |
| // template<int i> void f1(int a[10][i]); |
| // template<int i> void f2(int a[i][20]); |
| // template<int i> void f3(int (&a)[i][20]); |
| // void g() |
| // { |
| // int v[10][20]; |
| // f1(v); //OK: i deduced to be 20 |
| // f1<20>(v); //OK |
| // f2(v); //error: cannot deduce templateargument i |
| // f2<10>(v); //OK |
| // f3(v); //OK: i deduced to be 10 |
| // } |
| public void test14_8_2_5s15() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f1(v)", 2); |
| assertEquals("<int20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f1<20>(v)", -3); |
| assertEquals("<int20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f2(v)", 2); |
| inst = bh.assertNonProblem("f2<10>(v)", -3); |
| assertEquals("<int10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f3(v)", 2); |
| assertEquals("<int10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template <int i> class A { }; |
| // template <int i> void g(A<i+1>); |
| // template <int i> void f(A<i>, A<i+1>); |
| // void k() { |
| // A<1> a1; |
| // A<2> a2; |
| // g(a1); // error: deduction fails for expression i+1 |
| // g<0>(a1); // OK |
| // f(a1, a2); // OK |
| // } |
| public void test14_8_2_5s16a() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| bh.assertProblem("g(a1)", 1); |
| inst = bh.assertNonProblem("g<0>(a1)", -4); |
| assertEquals("<int0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("f(a1, a2)", 1); |
| assertEquals("<int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template<typename T> class A { |
| // public: |
| // typedef int X; |
| // X xm; |
| // }; |
| // template<int I> class B { |
| // public: |
| // typedef int* Y; |
| // Y ym; |
| // }; |
| // template<int i, typename T> |
| // T deduce(typename A<T>::X x, // T is not deduced here |
| // T t, // but T is deduced here |
| // typename B<i>::Y y); // i is not deduced here |
| // void test() { |
| // A<int> a; |
| // B<77> b; |
| // deduce<77> (a.xm, 62, b.ym); |
| // } |
| public void test14_8_2_5s16b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<int i> class A {}; |
| // template<short s> void f(A<s>); |
| // void k1() { |
| // A<1> a; |
| // f(a); // error: deduction fails for conversion from int to short |
| // f<1>(a); // OK |
| // } |
| // template<const short cs> class B { }; |
| // template<short s> void g(B<s>); |
| // void k2() { |
| // B<1> b; |
| // g(b); // OK: cv-qualifiers are ignored on template parameter types |
| // } |
| public void test14_8_2_5s17() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| bh.assertProblem("f(a)", 1); |
| inst = bh.assertNonProblem("f<1>(a)", -3); |
| assertEquals("<short int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| inst = bh.assertNonProblem("g(b)", 1); |
| assertEquals("<short int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template<class T> void f(void(*)(T,int)); |
| // template<class T> void foo(T,int); |
| // void g(int,int); |
| // void g(char,int); |
| // void h(int,int,int); |
| // void h(char,int); |
| // int m() { |
| // f(&g); // error: ambiguous |
| // f(&h); // OK: void h(char,int) is a unique match |
| // f(&foo); // error: type deduction fails because foo is a template |
| // } |
| public void test14_8_2_5s18() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| bh.assertProblem("f(&g)", 1); |
| inst = bh.assertNonProblem("f(&h)", 1); |
| assertEquals("<char>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f(&foo)", 1); |
| } |
| |
| // template <class T> void f(T = 5, T = 7); |
| // void g() { |
| // f(1); // OK: call f<int>(1,7) |
| // f(); // error: cannot deduce T |
| // f<int>(); // OK: call f<int>(5,7) |
| // } |
| public void test14_8_2_5s19() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f(1)", 1); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| bh.assertProblem("f()", 1); |
| inst = bh.assertNonProblem("f<int>()", -2); |
| assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); |
| } |
| |
| // template <template <class T> class X> struct A { }; |
| // template <template <class T> class X> void f(A<X>) { } |
| // template<class T> struct B { }; |
| // int foo() { |
| // A<B> ab; |
| // f(ab); //calls f(A<B>) |
| // } |
| public void test14_8_2_4s20() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class> struct X { }; |
| // template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { }; |
| // template<class ... Types> struct Y { }; |
| // template<class T, class ... Types> struct Y<T, Types& ...> { }; |
| // template<class ... Types> int f(void (*)(Types ...)); |
| // void g(int, float); |
| // X<int> x1; // uses primary template |
| // X<int(int, float, double)> x2; // uses partial specialization; ArgTypes contains float, double |
| // X<int(float, int)> x3; // uses primary template |
| // Y<> y1; // use primary template; Types is empty |
| // Y<int&, float&, double&> y2; // uses partial specialization; T is int&, Types contains float, double |
| // Y<int, float, double> y3; // uses primary template; Types contains int, float, double |
| // int fv = f(g); // OK; Types contains int, float |
| public void test14_8_2_4s21() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class ... Args> void f(Args ... args); // #1 |
| // template<class T1, class ... Args> void f(T1 a1, Args ... args); // #2 |
| // template<class T1, class T2> void f(T1 a1, T2 a2); // #3 |
| // void test() { |
| // f(); // calls #1 |
| // f(1, 2, 3); // calls #2 |
| // f(1, 2); // calls #3; non-variadic template #3 is more |
| // // specialized than the variadic templates #1 and #2 |
| // } |
| public void test14_8_2_5s22() throws Exception { |
| final String code = getAboveComment(); |
| BindingAssertionHelper bh = new AST2AssertionHelper(code, true); |
| ICPPFunctionTemplate f1 = bh.assertNonProblem("f(Args ... args)", 1); |
| ICPPFunctionTemplate f2 = bh.assertNonProblem("f(T1 a1, Args ... args)", 1); |
| ICPPFunctionTemplate f3 = bh.assertNonProblem("f(T1 a1, T2 a2)", 1); |
| |
| ICPPTemplateInstance inst; |
| inst = bh.assertNonProblem("f()", 1); |
| assertSame(f1, inst.getTemplateDefinition()); |
| inst = bh.assertNonProblem("f(1, 2, 3)", 1); |
| assertSame(f2, inst.getTemplateDefinition()); |
| inst = bh.assertNonProblem("f(1, 2)", 1); |
| assertSame(f3, inst.getTemplateDefinition()); |
| } |
| |
| // template<class T> T max(T a, T b) { return a>b?a:b; } |
| // void f(int a, int b, char c, char d) |
| // { |
| // int m1 = max(a,b); // max(int a, int b) |
| // char m2 = max(c,d); // max(char a, char b) |
| // int m3 = max(a,c); // error: cannot generate max(int,char) |
| // } |
| public void test14_8_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> T max(T a, T b) { return a>b?a:b; } |
| // int max(int,int); |
| // void f(int a, int b, char c, char d) |
| // { |
| // int m1 = max(a,b); // max(int a, int b) |
| // char m2 = max(c,d); // max(char a, char b) |
| // int m3 = max(a,c); // resolved |
| // } |
| public void test14_8_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> struct B { }; |
| // template<class T> struct D : public B<T> { }; |
| // template<class T> void f(B<T>&); |
| // void g(B<int>& bi, D<int>& di) |
| // { |
| // f(bi); // f(bi) |
| // f(di); // f( (B<int>&)di ) |
| // } |
| public void test14_8_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void f(T*,int); // #1 |
| // template<class T> void f(T,char); // #2 |
| // void h(int* pi, int i, char c) |
| // { |
| // f(pi,i); //#1: f<int>(pi,i) |
| // f(pi,c); //#2: f<int*>(pi,c) |
| // f(i,c); //#2: f<int>(i,c); |
| // f(i,i); //#2: f<int>(i,char(i)) |
| // } |
| public void test14_8_3s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void f(T); // declaration |
| // void g() { |
| // f("Annemarie"); // call of f<const char*> |
| // } |
| public void test14_8_3s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // lab: try { |
| // int t1; |
| // try { |
| // int t2; |
| // if (1) |
| // goto lab; |
| // } catch(...) { // handler 2 |
| // } |
| // } catch(...) { // handler 1 |
| // } |
| // } |
| public void test15s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(int); |
| // class C { |
| // int i; |
| // double d; |
| // public: |
| // C(int, double); |
| // }; |
| // C::C(int ii, double id) |
| // try |
| // : i(f(ii)), d(id) |
| // { |
| // // constructor function body |
| // } |
| // catch (...) |
| // { |
| // // handles exceptions thrown from the ctorinitializer |
| // // and from the constructor function body |
| // } |
| public void test15s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Overflow { |
| // // ... |
| // public: |
| // Overflow(char,double,double); |
| // }; |
| // void f(double x) |
| // { |
| // // ... |
| // throw Overflow('+',x,3.45e107); |
| // } |
| // int foo() { |
| // try { |
| // // ... |
| // f(1.2); |
| // // ... |
| // } |
| // catch(Overflow& oo) { |
| // // handle exceptions of type Overflow here |
| // } |
| // } |
| public void test15_1s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int foo() { |
| // try { |
| // // ... |
| // } |
| // catch (...) { // catch all exceptions |
| // // respond (partially) to exception |
| // throw; //pass the exception to some |
| // // other handler |
| // } |
| // } |
| public void test15_1s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class Matherr { virtual void vf(); }; |
| // class Overflow: public Matherr { }; |
| // class Underflow: public Matherr { }; |
| // class Zerodivide: public Matherr { }; |
| // void f() |
| // { |
| // try { |
| // } |
| // catch (Overflow oo) { |
| // // ... |
| // } |
| // catch (Matherr mm) { |
| // // ... |
| // } |
| // } |
| public void test15_3s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // void f() throw(int); // OK |
| // void (*fp)() throw (int); // OK |
| // void g(void pfa() throw(int)); // OK |
| public void test15_4s1a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int (*pf)() throw(int); // illformed |
| public void test15_4s1b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <typename T> |
| // void f(T p); |
| // |
| // template <typename T> |
| // void g(T p) noexcept; |
| // |
| // template <typename T> |
| // void fg(T a) noexcept (noexcept(f(a)) && noexcept(g(a))) { |
| // f(a); |
| // g(a); |
| // } |
| public void test15_4s1c() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual void f() throw (int, double); |
| // virtual void g(); |
| // }; |
| // struct D: B { |
| // void f(); // illformed |
| // void g() throw (int); // OK |
| // }; |
| public void test15_4s3a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class A { }; |
| // void (*pf1)(); // no exception specification |
| // void (*pf2)() throw(A); |
| // void f() |
| // { |
| // pf1 = pf2; // OK: pf1 is less restrictive |
| // pf2 = pf1; // error: pf2 is more restrictive |
| // } |
| public void test15_4s3b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class X { }; |
| // class Y { }; |
| // class Z: public X { }; |
| // class W { }; |
| // void f() throw (X, Y) |
| // { |
| // int n = 0; |
| // if (n) throw X(); // OK |
| // if (n) throw Z(); // also OK |
| // throw W(); // will call unexpected() |
| // } |
| public void test15_4s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // extern void f() throw(X, Y); |
| // void g() throw(X) |
| // { |
| // // f(); //OK |
| // } |
| public void test15_4s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { |
| // A(); |
| // A(const A&) throw(); |
| // ~A() throw(X); |
| // }; |
| // struct B { |
| // B() throw(); |
| // B(const B&) throw(); |
| // ~B() throw(Y); |
| // }; |
| // struct D : public A, public B { |
| // // Implicit declaration of D::D(); |
| // // Implicit declaration of D::D(const D&) throw(); |
| // // Implicit declaration of D::~D() throw (X,Y); |
| // }; |
| public void test15_4s13() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // #if VERSION == 1 |
| // #define INCFILE "vers1.h" |
| // #elif VERSION == 2 |
| // #define INCFILE "vers2.h" // and so on |
| // #else |
| // #define INCFILE "versN.h" |
| // #endif |
| public void test16_2s8() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // second pass of C++ spec is to get [Note: ] |
| // int f() { |
| // int a, b; |
| // /*...*/ |
| // a = a + 32760 + b + 5; |
| // a = (((a + 32760) + b) + 5); |
| // a = ((a + b) + 32765); |
| // a = ((a + 32765) + b); |
| // a = (a + (b + 32765)); |
| // } |
| public void test18_2_1_5s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct X { |
| // enum E { z = 16 }; |
| // int b[X::z]; // OK |
| // }; |
| public void test3_3_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int f; |
| // struct A { |
| // friend void f(A &); |
| // operator int(); |
| // void g(A a) { |
| // f(a); |
| // } |
| // }; |
| public void test3_4_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { |
| // int a; |
| // }; |
| // struct B: virtual A { }; |
| // struct C: B { }; |
| // struct D: B { }; |
| // struct E: public C, public D { }; |
| // struct F: public A { }; |
| // void f() { |
| // E e; |
| // e.B::a = 0; // OK, only one A::a in E |
| // F f; |
| // f.A::a = 1; // OK, A::a is a member of F |
| // } |
| public void test3_4_5s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // inline double fd() { return 1.0; } |
| // extern double d1; |
| // double d2 = d1; // unspecified: |
| // // may be statically initialized to 0.0 or |
| // // dynamically initialized to 1.0 |
| // double d1 = fd(); // may be initialized statically to 1.0 |
| public void test3_6_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int main() { |
| // const char c = 'c'; |
| // char* pc; |
| // const char** pcc = &pc; //1: not allowed |
| // *pcc = &c; |
| // *pc = 'C'; //2: modifies a const object |
| // } |
| public void test4_4s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct S { |
| // mutable int i; |
| // }; |
| // int f() { |
| // const S cs; |
| // int S::* pm = &S::i; // pm refers to mutable member S::i |
| // cs.*pm = 88; // illformed: cs is a const object |
| // } |
| public void test5_5s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace A { |
| // class X { }; |
| // extern "C" int g(); |
| // extern "C++" int h(); |
| // } |
| // namespace B { |
| // void X(int); |
| // extern "C" int g(); |
| // extern "C++" int h(); |
| // } |
| // using namespace A; |
| // using namespace B; |
| // void f() { |
| // X(1); //error: name X found in two namespaces |
| // g(); //okay: name g refers to the same entity |
| // h(); //error: name h found in two namespaces |
| // } |
| public void test7_3_4s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // int a; |
| // const int b = a; |
| // int c = b; |
| public void test8_5s14() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual void f(); |
| // }; |
| // struct D : B { |
| // void f(int); |
| // }; |
| // struct D2 : D { |
| // void f(); |
| // }; |
| public void test10_3s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct B { |
| // virtual ~B(); |
| // void operator delete(void*, size_t); |
| // }; |
| // struct D : B { |
| // void operator delete(void*); |
| // }; |
| // void f() |
| // { |
| // B* bp = new D; |
| // delete bp; //1: uses D::operator delete(void*) |
| // } |
| public void test12_5s7a() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct B { |
| // virtual ~B(); |
| // void operator delete[](void*, size_t); |
| // }; |
| // struct D : B { |
| // void operator delete[](void*, size_t); |
| // }; |
| // void f(int i) |
| // { |
| // D* dp = new D[i]; |
| // delete [] dp; // uses D::operator delete[](void*, size_t) |
| // B* bp = new D[i]; |
| // delete[] bp; // undefined behavior |
| // } |
| public void test12_5s7b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // struct A { }; |
| // void operator + (A, A); |
| // struct B { |
| // void operator + (B); |
| // void f (); |
| // }; |
| // A a; |
| // void B::f() { |
| // //operator+ (a,a); // ERROR - global operator hidden by member |
| // a + a; // OK - calls global operator+ |
| // } |
| public void test13_3_1_2s10() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> class myarray { }; |
| // template<class K, class V, template<class T> class C = myarray> |
| // class Map { |
| // C<K> key; |
| // C<V> value; |
| // // ... |
| // }; |
| public void test14_1s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // class T { }; |
| // int i; |
| // template<class T, T i> void f(T t) |
| // { |
| // T t1 = i; // templateparameters T and i |
| // ::T t2 = ::i; // global namespace members T and i |
| // } |
| public void test14_1s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<int* p> class X { }; |
| // int a[10]; |
| // struct S { int m; static int s; } s; |
| // X<&a[2]> x3; // error: address of array element |
| // X<&s.m> x4; // error: address of nonstatic member |
| // X<&s.s> x5; // error: &S::s must be used |
| // X<&S::s> x6; // OK: address of static member |
| public void test14_3_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T, char* p> class X { |
| // // ... |
| // X(); |
| // X(const char* q) { } |
| // }; |
| // X<int,"Studebaker"> x1; // error: string literal as template argument |
| // char p[] = "Vivisectionist"; |
| // X<int,p> x2; // OK |
| public void test14_3_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<const int& CRI> struct B { /* ... */ }; |
| // B<1> b2; // error: temporary would be required for template argument |
| // int c = 1; |
| // B<c> b1; // OK |
| public void test14_3_2s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<const int* pci> struct X { }; |
| // int ai[10]; |
| // X<ai> xi; // array to pointer and qualification conversions |
| // struct Y { }; |
| // template<const Y& b> struct Z { }; |
| // Y y; |
| // Z<y> z; // no conversion, but note extra cvqualification |
| // template<int (&pa)[5]> struct W { }; |
| // int b[5]; |
| // W<b> w; // no conversion |
| // void f(char); |
| // void f(int); |
| // template<void (*pf)(int)> struct A { }; |
| // A<&f> a; // selects f(int) |
| public void test14_3_2s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <class T> struct A { |
| // void f(int); |
| // template <class T2> void f(T2); |
| // }; |
| // template <> void A<int>::f(int) { } // nontemplate member |
| // template <> template <> void A<int>::f<>(int) { } // template member |
| // int main() |
| // { |
| // A<char> ac; |
| // ac.f(1); //nontemplate |
| // ac.f('c'); //template |
| // ac.f<>(1); //template |
| // } |
| public void test14_5_2s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); //should be 0 |
| } |
| |
| // template<class T1, class T2, int I> class A<T1, T2, I> { }; // error |
| public void test14_5_5s5() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> struct A { |
| // class C { |
| // template<class T2> struct B { }; |
| // }; |
| // }; |
| // // partial specialization of A<T>::C::B<T2> |
| // template<class T> template<class T2> |
| // struct A<T>::C::B<T2*> { }; |
| // A<short>::C::B<int*> absip; // uses partial specialization |
| public void test14_5_5s6() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // namespace N { |
| // template<class T1, class T2> class A { }; // primary template |
| // } |
| // using N::A; // refers to the primary template |
| // namespace N { |
| // template<class T> class A<T, T*> { }; // partial specialization |
| // } |
| // A<int,int*> a; // uses the partial specialization, which is found through |
| // // the using declaration which refers to the primary template |
| public void test14_5_5s7() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template<class T> void f(); |
| // template<int I> void f(); // OK: overloads the first template |
| // // distinguishable with an explicit template argument list |
| public void test14_5_6_1s4() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // template <int I> class A; |
| // template <int I, int J> A<I+J> f/*1*/(A<I>, A<J>); // #1 |
| // template <int K, int L> A<K+L> f/*2*/(A<K>, A<L>); // same as #1 |
| // template <int I, int J> A<I-J> f/*3*/(A<I>, A<J>); // different from #1 |
| public void test14_5_6_1s5() throws Exception { |
| final String content = getAboveComment(); |
| IASTTranslationUnit tu = parse(content, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| ICPPFunctionTemplate f1 = bh.assertNonProblem("f/*1*/", 1); |
| ICPPFunctionTemplate f2 = bh.assertNonProblem("f/*2*/", 1); |
| ICPPFunctionTemplate f3 = bh.assertNonProblem("f/*3*/", 1); |
| assertSame(f1, f2); |
| assertNotSame(f1, f3); |
| } |
| |
| // template <int I> class A; |
| // template <int I, int J> void f/*1*/(A<I+J>); // #1 |
| // template <int K, int L> void f/*2*/(A<K+L>); // same as #1 |
| public void test14_5_6_1s6() throws Exception { |
| final String content = getAboveComment(); |
| IASTTranslationUnit tu = parse(content, ParserLanguage.CPP, true, 0); |
| BindingAssertionHelper bh = new AST2AssertionHelper(content, true); |
| ICPPFunctionTemplate f1 = bh.assertNonProblem("f/*1*/", 1); |
| ICPPFunctionTemplate f2 = bh.assertNonProblem("f/*2*/", 1); |
| assertSame(f1, f2); |
| } |
| |
| // template <class T> int f(T); // #1 |
| // int f(int); // #2 |
| // int k = f(1); // uses #2 |
| // int l = f<>(1); // uses #1 |
| public void test14_8_1s2b() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // #define TABSIZE 100 |
| // int table[TABSIZE]; |
| public void test15_3_5s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int g(int); |
| // void f() |
| // { |
| // int i; |
| // int& r = i; // r refers to i |
| // r = 1; // the value of i becomes 1 |
| // int* p = &r; // p points to i |
| // int& rr = r; // rr refers to what r refers to, that is, to i |
| // int (&rg)(int) = g; // rg refers to the function g |
| // rg(i); //calls function g |
| // int a[3]; |
| // int (&ra)[3] = a; // ra refers to the array a |
| // ra[1] = i; // modifies a[1] |
| // } |
| public void test8_5_3s1() throws Exception { // TODO raised bug 90648 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { }; // implicitlydeclared A::operator= |
| // struct B : A { |
| // B& operator=(const B &); |
| // }; |
| // B& B::operator=(const B& s) { |
| // this->A::operator=(s); // wellformed |
| // return *this; |
| // } |
| public void test12s1() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // struct A { }; |
| // struct B : virtual A { }; |
| // struct C : B { }; |
| // struct D : virtual A { D(A*); }; |
| // struct X { X(A*); }; |
| // struct E : C, D, X { |
| // E() : D(this), // undefined: upcast from E* to A* |
| // // might use path E* -> D* -> A* |
| // // but D is not constructed |
| // // D((C*)this), // defined: |
| // // E* -> C* defined because E() has started |
| // // and C* -> A* defined because |
| // // C fully constructed |
| // X(this) //defined: upon construction of X, |
| // // C/B/D/A sublattice is fully constructed |
| // { } |
| // }; |
| public void test12_7s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // typedef int c; |
| // enum { i = 1 }; |
| // class X { |
| // int i=3; |
| // char v[i]; |
| // int f() { return sizeof(c); } // OK: X::c |
| // char c; |
| // enum { i = 2 }; |
| // }; |
| // typedef char* T; |
| // struct Y { |
| // typedef long T; |
| // T b; |
| // }; |
| // typedef int I; |
| // class D { |
| // typedef I I; // error, even though no reordering involved |
| // }; |
| public void test3_3_6s5() throws Exception { // 90606 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // int f(double); |
| // int f(int); |
| // int (*pfd)(double) = &f; // selects f(double) |
| // int (*pfi)(int) = &f; // selects f(int) |
| // int (*pfe)(...) = &f; // error: type mismatch |
| // int (&rfi)(int) = f; // selects f(int) |
| // int (&rfd)(double) = f; // selects f(double) |
| // void g() { |
| // (int (*)(int))&f; // cast expression as selector |
| // } |
| public void test13_4s5a() throws Exception { // bug 90674 |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // class A { |
| // public: |
| // int z; |
| // int z1; |
| // }; |
| // class B : public A { |
| // int a; |
| // public: |
| // int b, c; |
| // int bf(); |
| // protected: |
| // int x; |
| // int y; |
| // }; |
| // class D : private B { |
| // int d; |
| // public: |
| // B::c; //adjust access to B::c |
| // B::z; //adjust access to A::z |
| // A::z1; //adjust access to A::z1 |
| // int e; |
| // int df(); |
| // protected: |
| // B::x; //adjust access to B::x |
| // int g; |
| // }; |
| // class X : public D { |
| // int xf(); |
| // }; |
| // int ef(D&); |
| // int ff(X&); |
| public void test11_3s2() throws Exception { //bug 92793 |
| IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| IASTCompositeTypeSpecifier D = getCompositeType(tu, 2); |
| IASTDeclaration accessDecl = getDeclaration(D, 2); |
| assertInstance(accessDecl, ICPPASTUsingDeclaration.class); |
| } |
| |
| // int z() { |
| // int f(int); |
| // int a = 2; |
| // int b = f(a); |
| // int c(b); |
| // } |
| public void test8_5s2() throws Exception { // 90641 |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| |
| // // #include <cstddef> |
| // char *p; |
| // void *operator new(size_t, int); |
| // void foo() { |
| // const int x = 63; |
| // new (int(*p)) int; // newplacement expression |
| // new (int(*[x])); // new typeid |
| // } |
| public void test8_2s3() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, false, 0); |
| } |
| |
| // template<class T> void f(); |
| // template<int I> void f(); |
| // void g() |
| // { |
| // f<int()>(); // int() is a typeid:call the first f() |
| // } |
| public void test14_3s2() throws Exception { |
| parse(getAboveComment(), ParserLanguage.CPP, true, 0); |
| } |
| } |