mizvekov updated this revision to Diff 464435.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134143/new/

https://reviews.llvm.org/D134143

Files:
  clang/lib/Sema/SemaCXXScopeSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp

Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -9157,6 +9157,56 @@
   return Context.getTypeOfExprType(E);
 }
 
+static QualType getSameReferencedType(ASTContext &Context, QualType VT,
+                                      QualType ET) {
+  assert(!ET->isReferenceType());
+  if (const auto *VTL = VT->getAs<LValueReferenceType>())
+    ET = Context.getLValueReferenceType(ET, VTL->isSpelledAsLValue());
+  else if (VT->isRValueReferenceType())
+    ET = Context.getRValueReferenceType(ET);
+
+  if (!Context.hasSameUnqualifiedType(ET, VT)) {
+    ET.dump();
+    VT.dump();
+    assert(false && "!hasSameUnqualifiedType");
+  }
+
+  Qualifiers ToAdd = VT.getQualifiers(), ToRemove = ET.getQualifiers();
+  (void)Qualifiers::removeCommonQualifiers(ToAdd, ToRemove);
+
+  SplitQualType Split = ET.split();
+  while (!ToRemove.empty()) {
+    (void)Qualifiers::removeCommonQualifiers(Split.Quals, ToRemove);
+    if (ToRemove.empty())
+      break;
+    QualType Next;
+    switch (ET->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent)                                                    \
+  case Type::Class: {                                                          \
+    const auto *ty = cast<Class##Type>(ET);                                    \
+    if (!ty->isSugared())                                                      \
+      goto done;                                                               \
+    Next = ty->desugar();                                                      \
+    break;                                                                     \
+  }
+#include "clang/AST/TypeNodes.inc"
+    }
+    Split = Next.split();
+  }
+done:
+  assert(ToRemove.empty());
+  Split.Quals += ToAdd;
+  ET = Context.getQualifiedType(Split);
+
+  if (!Context.hasSameType(ET, VT)) {
+    ET.dump();
+    VT.dump();
+    assert(false && "!hasSameType");
+  }
+  return ET;
+}
+
 /// getDecltypeForExpr - Given an expr, will return the decltype for
 /// that expression, according to the rules in C++11
 /// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18.
@@ -9189,18 +9239,20 @@
   // We apply the same rules for Objective-C ivar and property references.
   if (const auto *DRE = dyn_cast<DeclRefExpr>(IDExpr)) {
     const ValueDecl *VD = DRE->getDecl();
-    QualType T = VD->getType();
+    QualType T = getSameReferencedType(Context, VD->getType(), DRE->getType());
     return isa<TemplateParamObjectDecl>(VD) ? T.getUnqualifiedType() : T;
   }
   if (const auto *ME = dyn_cast<MemberExpr>(IDExpr)) {
     if (const auto *VD = ME->getMemberDecl())
       if (isa<FieldDecl>(VD) || isa<VarDecl>(VD))
-        return VD->getType();
+        return getSameReferencedType(Context, VD->getType(), ME->getType());
   } else if (const auto *IR = dyn_cast<ObjCIvarRefExpr>(IDExpr)) {
+    // FIXME: Sugar these. Breaks Modules/odr_hash.mm.
     return IR->getDecl()->getType();
   } else if (const auto *PR = dyn_cast<ObjCPropertyRefExpr>(IDExpr)) {
     if (PR->isExplicitProperty())
-      return PR->getExplicitProperty()->getType();
+      return getSameReferencedType(
+          Context, PR->getExplicitProperty()->getType(), PR->getType());
   } else if (const auto *PE = dyn_cast<PredefinedExpr>(IDExpr)) {
     return PE->getType();
   }
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14381,8 +14381,24 @@
     if (isa<CXXDestructorDecl>(MD))
       Diag(OpLoc, diag::err_typecheck_addrof_dtor) << op->getSourceRange();
 
-    QualType MPTy = Context.getMemberPointerType(
-        op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr());
+    const CXXRecordDecl *Cls = MD->getParent();
+    const Type *ClsType = nullptr;
+    if (const NestedNameSpecifier *NNS = DRE->getQualifier()) {
+      const Type *Type = NNS->getAsType();
+      const CXXRecordDecl *ClsAsWritten =
+          Type ? Type->getAsCXXRecordDecl() : NNS->getAsRecordDecl();
+      assert(ClsAsWritten != nullptr);
+      if (declaresSameEntity(Cls, ClsAsWritten))
+        ClsType =
+            Type ? Type : Context.getTypeDeclType(ClsAsWritten).getTypePtr();
+      else
+        // FIXME: Can we do better here?
+        assert(ClsAsWritten->isDerivedFrom(Cls));
+    }
+    if (!ClsType)
+      ClsType = Context.getTypeDeclType(Cls).getTypePtr();
+
+    QualType MPTy = Context.getMemberPointerType(op->getType(), ClsType);
     // Under the MS ABI, lock down the inheritance model now.
     if (Context.getTargetInfo().getCXXABI().isMicrosoft())
       (void)isCompleteType(OpLoc, MPTy);
Index: clang/lib/Sema/SemaCXXScopeSpec.cpp
===================================================================
--- clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -99,8 +99,7 @@
         if (ClassTemplateDecl *ClassTemplate
               = dyn_cast_or_null<ClassTemplateDecl>(
                             SpecType->getTemplateName().getAsTemplateDecl())) {
-          QualType ContextType
-            = Context.getCanonicalType(QualType(SpecType, 0));
+          auto ContextType = QualType(SpecType, 0);
 
           // If the type of the nested name specifier is the same as the
           // injected class name of the named class template, we're entering
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to