[cfe-commits] r148348 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaDeclCXX.cpp

Richard Smith richard at metafoo.co.uk
Tue Jan 17 15:34:53 PST 2012


On Tue, January 17, 2012 22:49, Sebastian Redl wrote:
> Author: cornedbee
> Date: Tue Jan 17 16:49:33 2012
> New Revision: 148348
>
>
> URL: http://llvm.org/viewvc/llvm-project?rev=148348&view=rev
> Log:
> Add Sema::isStdInitializerList, which will be necessary for the upcoming
> operations.
>
> Modified:
> cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/Sema.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=1
> 48348&r1=148347&r2=148348&view=diff
> ==============================================================================
>  --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jan 17 16:49:33 2012
> @@ -488,6 +488,10 @@
> /// standard library.
> LazyDeclPtr StdBadAlloc;
>
>
> +  /// \brief The C++ "std::initializer_list" template, which is defined in
> +  /// <initializer_list>.
> +  ClassTemplateDecl *StdInitializerList;
> +
> /// \brief The C++ "type_info" declaration, which is defined in <typeinfo>.
> RecordDecl *CXXTypeInfoDecl;
>
>
> @@ -2721,6 +2725,10 @@
>
>
> CXXRecordDecl *getStdBadAlloc() const;
>
>
> +  /// \brief Tests whether Ty is an instance of std::initializer_list and,
> if +  /// it is and Element is not NULL, assigns the element type to Element.
> +  bool isStdInitializerList(QualType Ty, QualType *Element);
> +
> Decl *ActOnUsingDirective(Scope *CurScope,
> SourceLocation UsingLoc,
> SourceLocation NamespcLoc,
>
>
> Modified: cfe/trunk/lib/Sema/Sema.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=148348&r1
> =148347&r2=148348&view=diff
> ==============================================================================
>  --- cfe/trunk/lib/Sema/Sema.cpp (original)
> +++ cfe/trunk/lib/Sema/Sema.cpp Tue Jan 17 16:49:33 2012
> @@ -89,7 +89,7 @@
> CurContext(0), OriginalLexicalContext(0),
> PackContext(0), MSStructPragmaOn(false), VisContext(0),
> ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
> -    IdResolver(pp), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
> +    IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0),
> MSVCGuidDecl(0),
> GlobalNewDeleteDeclared(false),
> ObjCShouldCallSuperDealloc(false),
> ObjCShouldCallSuperFinalize(false),
>
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=14
> 8348&r1=148347&r2=148348&view=diff
> ==============================================================================
>  --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jan 17 16:49:33 2012
> @@ -5767,6 +5767,59 @@
> return getStdNamespace(); }
>
>
> +bool Sema::isStdInitializerList(QualType Ty, QualType *Element) {
> +  assert(getLangOptions().CPlusPlus &&
> +         "Looking for std::initializer_list outside of C++.");
> +
> +  // We're looking for implicit instantiations of
> +  // template <typename E> class std::initializer_list.
> +
> +  if (!StdNamespace) // If we haven't seen namespace std yet, this can't be
> it. +    return false;
> +
> +  const RecordType *RT = Ty->getAs<RecordType>();
> +  if (!RT)
> +    return false;
> +
> +  ClassTemplateSpecializationDecl *Specialization =
> +      dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
> +  if (!Specialization)
> +    return false;
> +
> +  if (Specialization->getSpecializationKind() != TSK_ImplicitInstantiation)
> +    return false;
> +
> +  ClassTemplateDecl *Template = Specialization->getSpecializedTemplate();

It's not clear how we should behave if this isn't a specialization of the
primary template -- [namespace.std]p1 seems to allow user-specialization of
std::initializer_list, though that seems unimplementable in general.

> +
> +  if (!StdInitializerList) {
> +    // Haven't recognized std::initializer_list yet, maybe this is it.
> +    CXXRecordDecl *TemplateClass = Template->getTemplatedDecl();
> +    if (TemplateClass->getIdentifier() !=
> +            &PP.getIdentifierTable().get("initializer_list") ||
> +        !TemplateClass->getDeclContext()->Equals(getStdNamespace()))

initializer_list might be inside an inline namespace within std (and I believe
it is, in libc++). getStdNamespace()->InEnclosingNamespaceSetOf(your
namespace) should handle this, IIRC.

> +      return false;
> +    // This is a template called std::initializer_list, but is it the right
> +    // template?
> +    TemplateParameterList *Params = Template->getTemplateParameters();
> +    if (Params->size() != 1)
> +      return false;

Minor nit: a standard library implementation is permitted to give
initializer_list additional defaulted template parameters.

> +    if (!isa<TemplateTypeParmDecl>(Params->getParam(0)))
> +      return false;
> +
> +    // It's the right template.
> +    StdInitializerList = Template;
> +  }
> +
> +  if (Template != StdInitializerList)
> +    return false;
> +
> +  // This is an instance of std::initializer_list. Find the argument type.
> +  if (Element) {
> +    *Element = Specialization->getTemplateArgs()[0].getAsType();
> +  }
> +  return true;
> +}
> +
> /// \brief Determine whether a using statement is in a context where it will
> be /// apply in all contexts.
> static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
>
>
>
>




More information about the cfe-commits mailing list