[cfe-dev] [RFC PATCH] C++0x trailing return type

Douglas Gregor dgregor at apple.com
Fri Sep 24 07:31:04 PDT 2010


On Sep 23, 2010, at 1:49 AM, Daniel Wallin wrote:

> Accidentally left out the list cc in my first response:
> 
> On Thu, Sep 23, 2010 at 1:07 AM, Daniel Wallin <daniel at boostpro.com> wrote:
>> On Wed, Sep 22, 2010 at 8:49 PM, Sebastian Redl
>> <sebastian.redl at getdesigned.at> wrote:
>>> 
>>> On Sep 22, 2010, at 11:30 AM, Daniel Wallin wrote:
>>> 
>>>> <trailing-return.patch>
>>> 
>>> Very nice! One important thing, though, is that the trailing return type is really a property of the declaration, not of the type. In particular, you made type uniquing dependent on whether the return type is trailing, which is incorrect:
>>> int f();
>>> and
>>> auto f() -> int;
>>> declare the same function; the type is the same.
>> 
>> Ah yes, good point. The only reason I had to attach the property at
>> all was because I needed access to it when transforming the function
>> type, so that this order:
>> 
>>  // We instantiate in source order, with the return type first followed by
>>  // the parameters, because users tend to expect this (even if they shouldn't
>>  // rely on it!).
>> 
>> could be switched in TreeTransform.h. Any ideas on where the property
>> could be stored? Keep in mind that for things like:
>> 
>>  X<auto(int) -> int>
>> 
>> there is no Decl for the function type. I could hack this by moving
>> the HasTrailing bool to FunctionLocInfo, but since I don't have a very
>> good idea on what TypeLoc's are, I have no idea if that's a viable
>> solution. ;)
> 
> I'm attaching a patch that does that.


This looks great! One comment and a request, then I'd like to see this go in:

diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index aa30b5c..a4e5392 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -993,7 +993,31 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
                           &ReturnTypeInfo);
     break;
   }
-  
+
+  // Check for auto functions and trailing return type and adjust the
+  // return type accordingly.
+  if (getLangOptions().CPlusPlus0x && D.isFunctionDeclarator()) {
+    const DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+    if (T == Context.UndeducedAutoTy) {
+      if (FTI.TrailingReturnType) {
+          T = GetTypeFromParser(ParsedType::getFromOpaquePtr(FTI.TrailingReturnType),
+                                &ReturnTypeInfo);
+      }
+      else {
+          Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+               diag::err_auto_missing_trailing_return);
+          T = Context.IntTy;
+          D.setInvalidType(true);
+      }
+    }
+    else if (FTI.TrailingReturnType) {
+      Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+           diag::err_trailing_return_without_auto)
+        << FixItHint::CreateReplacement(D.getDeclSpec().getSourceRange(), "auto");
+      D.setInvalidType(true);
+    }
+  }

I like the use of the Fix-it hint, but I don't think that D.DeclSpec().getSourceRange() is always going to be the correct range. For example, I'd expect that we'd end up fixing

	virtual int f(int) -> float;

to

	auto f(int) -> float;


because the DeclSpec also contains function specifiers, storage specifiers, etc. It would be nice to have a test in test/FixIt that tests this kind of rewriting, to make sure we got it right.

Please add __has_feature(cxx_trailing_return_type) support and documentation, as in

	http://clang.llvm.org/docs/LanguageExtensions.html#checking_upcoming_features

Thanks!

	- Doug



More information about the cfe-dev mailing list