mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 22:36:06 +00:00

Instead of bailing out of parsing when we encounter an invalid template-name or template arguments in a template-id, produce an annotation token describing the invalid construct. This avoids duplicate errors and generally allows us to recover better. In principle we should be able to extend this to store some kinds of invalid template-id in the AST for tooling use, but that isn't handled as part of this change.
80 lines
2.0 KiB
C++
80 lines
2.0 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
|
|
|
|
class X {};
|
|
|
|
void test() {
|
|
X x;
|
|
|
|
x.int; // expected-error{{expected unqualified-id}}
|
|
x.~int(); // expected-error{{expected a class name}}
|
|
x.operator; // expected-error{{expected a type}}
|
|
x.operator typedef; // expected-error{{expected a type}} expected-error{{type name does not allow storage class}}
|
|
}
|
|
|
|
void test2() {
|
|
X *x;
|
|
|
|
x->int; // expected-error{{expected unqualified-id}}
|
|
x->~int(); // expected-error{{expected a class name}}
|
|
x->operator; // expected-error{{expected a type}}
|
|
x->operator typedef; // expected-error{{expected a type}} expected-error{{type name does not allow storage class}}
|
|
}
|
|
|
|
// PR6327
|
|
namespace test3 {
|
|
template <class A, class B> struct pair {};
|
|
template <class _E> class initializer_list {};
|
|
template <typename _Tp> pair<_Tp, _Tp> minmax(initializer_list<_Tp> __l) {};
|
|
|
|
void test0() {
|
|
pair<int, int> z = minmax({});
|
|
#if __cplusplus <= 199711L // C++03 or earlier modes
|
|
// expected-error@-2 {{expected expression}}
|
|
#else
|
|
// expected-error@-4 {{no matching function for call to 'minmax'}}
|
|
// expected-note@-8 {{candidate template ignored: couldn't infer template argument '_Tp'}}
|
|
#endif
|
|
}
|
|
|
|
struct string {
|
|
class iterator {};
|
|
};
|
|
|
|
void test1() {
|
|
string s;
|
|
string::iterator i = s.foo(); // expected-error {{no member named 'foo'}}
|
|
}
|
|
}
|
|
|
|
|
|
// Make sure we don't crash.
|
|
namespace rdar11293995 {
|
|
|
|
struct Length {
|
|
explicit Length(PassRefPtr<CalculationValue>); // expected-error {{undeclared identifier 'CalculationValue'}}
|
|
};
|
|
|
|
struct LengthSize {
|
|
Length m_width;
|
|
Length m_height;
|
|
};
|
|
|
|
enum EFillSizeType { Contain, Cover, SizeLength, SizeNone };
|
|
|
|
struct FillSize {
|
|
EFillSizeType type;
|
|
LengthSize size;
|
|
};
|
|
|
|
class FillLayer {
|
|
public:
|
|
void setSize(FillSize f) { m_sizeType = f.type;}
|
|
private:
|
|
unsigned m_sizeType : 2;
|
|
};
|
|
|
|
}
|