[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