[cfe-commits] [PATCH] Implement C++0x deduced auto type
Richard Smith
richard at metafoo.co.uk
Sun Feb 20 15:57:18 PST 2011
Hi,
The attached patch makes the remaining requested tweaks:
On Fri, February 18, 2011 17:52, Douglas Gregor wrote:
> On Feb 17, 2011, at 6:26 PM, Richard Smith wrote:
>> The attached patch implements the C++0x deduced 'auto' type feature.
>> This
>> should fix the following PRs:
>>
>> Bug 8738 - C++'0x auto not implemented
>> Bug 9060 - Late-specified return type accepted for parenthesized
>> declarator Bug 9132 - clang accepts declarators other than a literal
>> 'auto' as the
>> return type of a function with a trailing-return-type
[snip]
> Index: include/clang/AST/Decl.h
> ===================================================================
> --- include/clang/AST/Decl.h (revision 125795)
> +++ include/clang/AST/Decl.h (working copy)
> @@ -646,6 +646,10 @@
> /// \brief Whether this local variable could be allocated in the return
> /// slot of its function, enabling the named return value optimization
> (NRVO).
> bool NRVOVariable : 1; +
> + /// \brief Whether this variable has a deduced C++0x auto type for
> which we're + /// currently parsing the initializer.
> + bool ParsingAutoInit : 1;
>
>
> It's unfortunate that this temporary bit has to live forever in the AST.
> Did you consider an alternative, such as a SmallPtrSet inside Sema that
> tracks the (few, relatively rare) VarDecls that are waiting for their
> initializers? (I guess in the future, FieldDecls must also be
> considered).
Done. I've rearranged the point where the flag is cleared to be sure we
cover all the cases, and added an assert in case any are missed. I've
added Sema::FinalizeDeclarator function to be called once a declaration is
complete (with any initializer attached) which removes the flag.
> +/// \brief Deduce the type for an auto type-specifier (C++0x
> [dcl.spec.auto]p6)
> +///
> +/// \param Type the type pattern using the auto type-specifier.
> +///
> +/// \param Init the initializer for the variable whose type is to be
> deduced. +///
> +/// \param Result if type deduction was successful, this will be set to
> the +/// deduced type. This may still contain undeduced autos if the type
> is +/// dependent.
> +///
> +/// \returns true if deduction succeeded, false if it failed.
> +bool
> +Sema::DeduceAutoType(QualType Type, Expr *Init, QualType &Result) {
> + if (Init->isTypeDependent()) {
> + Result = Type;
> + return true;
> + }
> +
> + SourceLocation Loc = Init->getExprLoc();
> +
> + LocalInstantiationScope InstScope(*this);
> +
> + // Build template<class TemplParam> void Func(FuncParam);
> + NamedDecl *TemplParam
> + = TemplateTypeParmDecl::Create(Context, 0, Loc, 0, 0, 0, false,
> false); + TemplateParameterList *TemplateParams
> + = TemplateParameterList::Create(Context, Loc, Loc, &TemplParam, 1,
> Loc);
> +
> + QualType TemplArg = Context.getTemplateTypeParmType(0, 0, false);
> + QualType FuncParam =
> + SubstituteAutoTransform(*this, TemplArg).TransformType(Type);
> +
> + // Deduce type of TemplParam in Func(Init)
> + llvm::SmallVector<DeducedTemplateArgument, 1> Deduced;
> + Deduced.resize(1);
> + QualType InitType = Init->getType();
> + unsigned TDF = 0;
> + if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
> + FuncParam, InitType,
> Init,
> + TDF))
> + return false;
> +
> + TemplateDeductionInfo Info(Context, Loc);
> + if (::DeduceTemplateArguments(*this, TemplateParams,
> + FuncParam, InitType, Info, Deduced,
> + TDF))
> + return false;
> +
> + QualType DeducedType = Deduced[0].getAsType();
> + if (DeducedType.isNull())
> + return false;
> +
> + Result = SubstituteAutoTransform(*this,
> DeducedType).TransformType(Type);
> + return true;
> +}
> +
>
>
> 1-1 mapping between standard and implementation, I like it! I do wonder
> if we could reduce the memory footprint a bit by, e.g., allocating the
> template parameter list and template type parameter on the stack rather
> than in the never-to-be-freed ASTContext.
Done. I've added a FixedSizeTemplateParameterList class template to
implement the variable-sized array suffix for TemplateParameterList.
> Index: lib/AST/ItaniumMangle.cpp
> ===================================================================
> --- lib/AST/ItaniumMangle.cpp (revision 125795)
> +++ lib/AST/ItaniumMangle.cpp (working copy)
> @@ -1313,9 +1313,6 @@
> 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;
> case BuiltinType::ObjCId: Out << "11objc_object"; break; case
> BuiltinType::ObjCClass: Out << "10objc_class"; break;
> case BuiltinType::ObjCSel: Out << "13objc_selector"; break; @@ -1648,6
> +1645,12 @@
> Out << 'E';
> }
>
>
> +void CXXNameMangler::mangleType(const AutoType *T) {
> + QualType D = T->getDeducedType();
> + assert(!D.isNull() && "can't mangle undeduced auto type");
> + mangleType(D);
> +}
>
>
> Please make this an error (via the Diagnostics subsystem) rather than an
> assertion... I can think of evil ways to write code that would trip up
> here, which we should (but don't) diagnose as errors. I'd rather fail
> gracefully.
Done. I managed to tickle this with:
template<typename T> void f(decltype(new auto(T())));
template void f<int>(int*);
> Index: lib/AST/ASTContext.cpp
> ===================================================================
> --- lib/AST/ASTContext.cpp (revision 125795)
> +++ lib/AST/ASTContext.cpp (working copy)
> @@ -2674,6 +2677,14 @@
> return QualType(dt, 0); }
>
>
> +/// getAutoType - Unlike many "get<Type>" functions, we don't unique
> +/// AutoType AST's.
> +QualType ASTContext::getAutoType(QualType DeducedType) const {
> + AutoType *at = new (*this, TypeAlignment) AutoType(DeducedType);
> + Types.push_back(at);
> + return QualType(at, 0);
> +}
>
>
> Why not unique 'auto' types when we have a deduced type?
Done.
Thanks,
Richard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang-auto-tweaks.diff
Type: text/x-patch
Size: 15169 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110220/e0bed35e/attachment.bin>
More information about the cfe-commits
mailing list