[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