aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-06-26 22:18:59 +0000
committerAnders Carlsson <andersca@mac.com>2009-06-26 22:18:59 +0000
commitbaf45d31f18e6d5b3d2a33695c2af6e6cbc4ee29 (patch)
tree8cc8191dd3ffc309a5e61ee057552a9cf8a0f563
parent714d35b451b9250bb53f5c27327bc3348a6ba54b (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.td3
-rw-r--r--lib/Sema/SemaType.cpp46
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp9
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}}