diff options
author | Anders Carlsson <andersca@mac.com> | 2009-06-26 22:18:59 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-06-26 22:18:59 +0000 |
commit | baf45d31f18e6d5b3d2a33695c2af6e6cbc4ee29 (patch) | |
tree | 8cc8191dd3ffc309a5e61ee057552a9cf8a0f563 | |
parent | 714d35b451b9250bb53f5c27327bc3348a6ba54b (diff) |
More auto work.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74339 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 46 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp | 9 |
3 files changed, 58 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index e16286f208..7e8c34c9c9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -403,6 +403,9 @@ def err_auto_variable_cannot_appear_in_own_initializer : Error< "variable %0 declared with 'auto' type cannot appear in its own initializer">; def err_illegal_decl_array_of_auto : Error< "'%0' declared as array of 'auto'">; +def err_auto_not_allowed : Error< + "'auto' not allowed in %select{function prototype|struct member|union member" + "|class member|exception declaration|template parameter|block literal}0">; // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 35cfce2e1f..c6bcdc36f1 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -807,6 +807,52 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, break; } + if (T == Context.UndeducedAutoTy) { + int Error = -1; + + switch (D.getContext()) { + case Declarator::KNRTypeListContext: + assert(0 && "K&R type lists aren't allowed in C++"); + break; + default: + printf("context: %d\n", D.getContext()); + assert(0); + case Declarator::PrototypeContext: + Error = 0; // Function prototype + break; + case Declarator::MemberContext: + switch (cast<TagDecl>(CurContext)->getTagKind()) { + case TagDecl::TK_enum: assert(0 && "unhandled tag kind"); break; + case TagDecl::TK_struct: Error = 1; /* Struct member */ break; + case TagDecl::TK_union: Error = 2; /* Union member */ break; + case TagDecl::TK_class: Error = 3; /* Class member */ break; + } + break; + case Declarator::CXXCatchContext: + Error = 4; // Exception declaration + break; + case Declarator::TemplateParamContext: + Error = 5; // Template parameter + break; + case Declarator::BlockLiteralContext: + Error = 6; // Block literal + break; + case Declarator::FileContext: + case Declarator::BlockContext: + case Declarator::ForContext: + case Declarator::ConditionContext: + case Declarator::TypeNameContext: + break; + } + + if (Error != -1) { + Diag(D.getDeclSpec().getTypeSpecTypeLoc(), diag::err_auto_not_allowed) + << Error; + T = Context.IntTy; + D.setInvalidType(true); + } + } + // The name we're declaring, if any. DeclarationName Name; if (D.getIdentifier()) diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp index 8f5058ee2d..fa3101c673 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -2,3 +2,12 @@ void f() { auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} } + +struct S { auto a; }; // expected-error{{'auto' not allowed in struct member}} + +void f(auto a) // expected-error{{'auto' not allowed in function prototype}} +{ + try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}} +} + +template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}} |