[cfe-dev] [ms-mode] Delayed parsing for a UnaryExprOrTypeTraitExpr?

Will Wilson will at indefiant.com
Tue Jun 18 13:06:24 PDT 2013


Hi Richard,

Thanks for the initial suggestion. I've implemented it locally to prototype
the changes required but I'd like a second opinion on how best to structure
the code.

I suggest that when transforming a UnaryExprOrTypeTraitExpr, you look
> for the case where the operand is a ParenExpr containing a
> DependentScopeDeclRefExpr, perform the lookup into the dependent
> scope, and if it resolves to a type then produce that type (and a
> warning in MS mode / error outside MS mode).
>

The (very) rough implementation I've inserted in
TransformUnaryExprOrTypeTraitExpr() is:

  if (SemaRef.getLangOpts().MicrosoftMode) {

    ParenExpr* PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
    DependentScopeDeclRefExpr *DepDecl
      = dyn_cast<DependentScopeDeclRefExpr>(PE ? PE->getSubExpr() :
E->getArgumentExpr());

    if (DepDecl) {
      NestedNameSpecifierLoc QualifierLoc
        =
getDerived().TransformNestedNameSpecifierLoc(DepDecl->getQualifierLoc());
      if (!QualifierLoc)
        return ExprError();

      DeclarationNameInfo NameInfo
        = getDerived().TransformDeclarationNameInfo(DepDecl->getNameInfo());
      if (!NameInfo.getName())
        return ExprError();

      CXXScopeSpec SS;
      SS.Adopt(QualifierLoc);

      // From Sema::BuildQualifiedDeclarationNameExpr()
      DeclContext *DC = SemaRef.computeDeclContext(SS, false);
      if (!DC)
        return ExprError();

      if (SemaRef.RequireCompleteDeclContext(SS, DC))
        return ExprError();

      LookupResult R(SemaRef, NameInfo, Sema::LookupOrdinaryName);
      SemaRef.LookupQualifiedName(R, DC);

      if (TypedefNameDecl* TypeDecl = R.getAsSingle<TypedefNameDecl>())
        return
getDerived().RebuildUnaryExprOrTypeTrait(TypeDecl->getTypeSourceInfo(),
                                                      E->getOperatorLoc(),
                                                      E->getKind(),
                                                      E->getSourceRange());
      // TODO: Issue warn_typename_missing
    }
  }

The code is mostly based on the path TransformExpr() would take when
dealing with a
DependentScopeDeclRefExpr which understandably but unfortunately duplicates
a lot of the logic.

My main questions are:

   - Is the amount of code duplication acceptable in this special case?
   - Are there any short cuts I'm missing?
   - Should I directly call Sema::BuildQualifiedDeclarationNameExpr() and
   find a way to reuse the lookup logic?
   - I'd like to move the code out of TransformUnaryExprOrTypeTraitExpr() -
   any method name suggestions?
   - Does changing from err_unexpected_typedef to warn_typename_missing
   make sense in this case?

Thanks in advance!

Will.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130618/7e5e4a6c/attachment.html>


More information about the cfe-dev mailing list