]> granicus.if.org Git - clang/commitdiff
Implement enough of the 'auto' keyword so we can claim to support N2546.
authorAnders Carlsson <andersca@mac.com>
Fri, 26 Jun 2009 18:41:36 +0000 (18:41 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 26 Jun 2009 18:41:36 +0000 (18:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74307 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/Type.h
include/clang/Parse/DeclSpec.h
lib/AST/ASTContext.cpp
lib/CodeGen/Mangle.cpp
lib/Frontend/PCHWriter.cpp
lib/Parse/DeclSpec.cpp
lib/Parse/ParseDecl.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/auto-cxx0x.cpp [new file with mode: 0644]
test/SemaCXX/auto-cxx98.cpp [new file with mode: 0644]

index 2d35b4d99034b8e4d10e1e54dd2375c510aa5d85..aa01b7fdf06faf76412511a09dafaeefbfff694b 100644 (file)
@@ -192,6 +192,7 @@ public:
   QualType VoidPtrTy, NullPtrTy;
   QualType OverloadTy;
   QualType DependentTy;
+  QualType UndeducedAutoTy;
 
   ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
              IdentifierTable &idents, SelectorTable &sels,
index 225a423821873c2831bf88757f695828bcbe4ad7..321b1f204fcfb96318c0f99a84e4a64289b824b4 100644 (file)
@@ -572,7 +572,10 @@ public:
     NullPtr,  // This is the type of C++0x 'nullptr'.
 
     Overload,  // This represents the type of an overloaded function declaration.
-    Dependent  // This represents the type of a type-dependent expression.
+    Dependent, // This represents the type of a type-dependent expression.
+    
+    UndeducedAuto  // In C++0x, this represents the type of an auto variable
+                   // that has not been deduced yet.
   };
 private:
   Kind TypeKind;
index 10c5ee39ec5014e17681179d70c80c45c87738fe..300602e5147cc81aacfb4c92c379c6ee19a6d4dc 100644 (file)
@@ -83,6 +83,7 @@ public:
     TST_typeofType,
     TST_typeofExpr,
     TST_decltype,     // C++0x decltype
+    TST_auto,         // C++0x auto
     TST_error         // erroneous type
   };
   
index 16a62fdd8cddcb5d1b08821d7b177ad47a358cf2..12f75ae863a2fa4e698e70e446d5cc3c2d50ae13 100644 (file)
@@ -179,6 +179,10 @@ void ASTContext::InitBuiltinTypes() {
   // expressions.
   InitBuiltinType(DependentTy,         BuiltinType::Dependent);
 
+  // Placeholder type for C++0x auto declarations whose real type has 
+  // not yet been deduced.
+  InitBuiltinType(UndeducedAutoTy, BuiltinType::UndeducedAuto);
+  
   // C99 6.2.5p11.
   FloatComplexTy      = getComplexType(FloatTy);
   DoubleComplexTy     = getComplexType(DoubleTy);
index 24e441a296350e5a11013377338015f1fef2bb83..b5ad5acc01628accf5d855713df64d709540d0eb 100644 (file)
@@ -539,6 +539,9 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
     assert(false && 
            "Overloaded and dependent types shouldn't get to name mangling");
     break;
+  case BuiltinType::UndeducedAuto:
+    assert(0 && "Should not see undeduced auto here");
+    break;
   }
 }
 
index 808df70df30d1272210f8c236c5cd4264975b665..e93219e01d5c8b1fd6fb5bb0b1d917f1601b645c 100644 (file)
@@ -1909,6 +1909,9 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
     case BuiltinType::NullPtr:    ID = pch::PREDEF_TYPE_NULLPTR_ID;    break;
     case BuiltinType::Overload:   ID = pch::PREDEF_TYPE_OVERLOAD_ID;   break;
     case BuiltinType::Dependent:  ID = pch::PREDEF_TYPE_DEPENDENT_ID;  break;
+    case BuiltinType::UndeducedAuto:
+      assert(0 && "Should not see undeduced auto here");
+      break;
     }
 
     Record.push_back((ID << 3) | T.getCVRQualifiers());
index d8c6986f9ea60b5dc80816dda8ecc88a07be1a37..8b3b2851c1e0c008bd9a6ef6715200ab2678e567 100644 (file)
@@ -173,6 +173,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   case DeclSpec::TST_typename:    return "type-name";
   case DeclSpec::TST_typeofType:
   case DeclSpec::TST_typeofExpr:  return "typeof";
+  case DeclSpec::TST_auto:       return "auto";
   }
 }
 
index c11383c3eca9d2c938cec0a136afa6162a45defd..b2b2f31dd6ea40b739552497bca8adf6feeca8ff 100644 (file)
@@ -926,7 +926,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_static, Loc, PrevSpec);
       break;
     case tok::kw_auto:
-      isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
+      if (getLang().CPlusPlus0x)
+        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec);
+      else
+        isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_auto, Loc, PrevSpec);
       break;
     case tok::kw_register:
       isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_register, Loc, PrevSpec);
index 8a0ad089b68f62d65a5c23b3d62f324248d21d43..b58414234438c14c04b4792f599d31200a21e7e8 100644 (file)
@@ -245,6 +245,11 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
     Result = Context.getDecltypeType(E);
     break;
   }
+  case DeclSpec::TST_auto: {
+    // TypeQuals handled by caller.
+    Result = Context.UndeducedAutoTy;
+    break;
+  }
     
   case DeclSpec::TST_error:
     Result = Context.IntTy;
diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp
new file mode 100644 (file)
index 0000000..33156ef
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+void f() {
+  auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}}
+  int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}}
+}
diff --git a/test/SemaCXX/auto-cxx98.cpp b/test/SemaCXX/auto-cxx98.cpp
new file mode 100644 (file)
index 0000000..14670cd
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++98
+void f() {
+  auto int a;
+  int auto b;
+}