]> granicus.if.org Git - clang/commitdiff
Store the isAddressOfOperand in the UnresolvedDeclRefExpr, so that we can pass it...
authorAnders Carlsson <andersca@mac.com>
Thu, 9 Jul 2009 00:05:08 +0000 (00:05 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 9 Jul 2009 00:05:08 +0000 (00:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75075 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiateExpr.cpp
test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp

index 7d76a49d1267b077eece743c3513bea5f8793650..6956e58c8253d23c2073fd223e0190381a9bc7f7 100644 (file)
@@ -985,11 +985,16 @@ class UnresolvedDeclRefExpr : public Expr {
   /// declaration name.
   NestedNameSpecifier *NNS;
 
+  /// \brief Whether this expr is an address of (&) operand.
+  bool IsAddressOfOperand;
+  
 public:
   UnresolvedDeclRefExpr(DeclarationName N, QualType T, SourceLocation L,
-                        SourceRange R, NestedNameSpecifier *NNS)
+                        SourceRange R, NestedNameSpecifier *NNS, 
+                        bool IsAddressOfOperand)
     : Expr(UnresolvedDeclRefExprClass, T, true, true), 
-      Name(N), Loc(L), QualifierRange(R), NNS(NNS) { }
+      Name(N), Loc(L), QualifierRange(R), NNS(NNS), 
+      IsAddressOfOperand(IsAddressOfOperand) { }
 
   /// \brief Retrieve the name that this expression refers to.
   DeclarationName getDeclName() const { return Name; }
@@ -1004,6 +1009,9 @@ public:
   /// declaration.
   NestedNameSpecifier *getQualifier() const { return NNS; }
 
+  /// \brief Retrieve whether this is an address of (&) operand.
+  
+  bool isAddressOfOperand() const { return IsAddressOfOperand; }
   virtual SourceRange getSourceRange() const { 
     return SourceRange(QualifierRange.getBegin(), getLocation()); 
   }
index df7e5afb17b336bf671649138903df1ddfc47d7e..820c1775ae259a3b82aafe76897da70e82d6fd2a 100644 (file)
@@ -849,7 +849,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
   if (SS && isDependentScopeSpecifier(*SS)) {
     return Owned(new (Context) UnresolvedDeclRefExpr(Name, Context.DependentTy,
                                                      Loc, SS->getRange(), 
-                static_cast<NestedNameSpecifier *>(SS->getScopeRep())));
+                static_cast<NestedNameSpecifier *>(SS->getScopeRep()),
+                                                     isAddressOfOperand));
   }
 
   LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
index c82e1a7da3c927eb5900d98cac7b86d588cb9eb3..5e664add5cbfb39f2b3fbf8dc8a5d4935cb5a077 100644 (file)
@@ -798,7 +798,7 @@ TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
                                           E->getDeclName(), 
                                           /*HasTrailingLParen=*/false,
                                           &SS,
-                                          /*FIXME:isAddressOfOperand=*/false);
+                                          E->isAddressOfOperand());
 }
 
 Sema::OwningExprResult 
index ee3cbeae4e0852577bac33970cca80ca87d3f248..101d75fc0f48616f1abe4992dcbe21e79830270a 100644 (file)
@@ -8,13 +8,19 @@ public:
   static int s;
 }; 
 
+template<typename T> void ft(T& t) {
+  t.*&T::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
+}
+
 void f() {
   int b;
   A a(b); 
   
   int A::*ip = &A::s; // expected-error {{incompatible type initializing 'int *', expected 'int class A::*'}}
   a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}}
+  
   a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
-
+  ft(a); // expected-note{{in instantiation of function template specialization 'ft' requested here}}
+  
   void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}}
 }