]> granicus.if.org Git - clang/commitdiff
Change FixOverloadedFunctionReference to return a (possibly new) expression. Substitu...
authorAnders Carlsson <andersca@mac.com>
Wed, 21 Oct 2009 17:16:23 +0000 (17:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 21 Oct 2009 17:16:23 +0000 (17:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84763 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplate.cpp
test/CodeGenCXX/address-of-fntemplate.cpp

index 0b55ecd7705cf7011ad00e63d966cb6de2967e47..3f31405426cfb5afed451b3918139131da5dacc9 100644 (file)
@@ -929,7 +929,7 @@ public:
 
   FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
                                                    bool Complain);
-  bool FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
+  Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
 
   void AddOverloadedCallCandidates(NamedDecl *Callee,
                                    DeclarationName &UnqualifiedName,
index d2ef113b3050b67b88f2a0119b7f2330f9ea4e89..ba2a93d65c58b4369efd2a391945a6f93452d1f8 100644 (file)
@@ -3569,7 +3569,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
         if (DiagnoseUseOfDecl(Fn, DeclLoc))
           return true;
 
-        FixOverloadedFunctionReference(Init, Fn);
+        Init = FixOverloadedFunctionReference(Init, Fn);
       }
 
       T2 = Fn->getType();
index 181c1349bd939e454d80851083a2b104a23a9e06..567111223a6d855b40d3ac3134f4532897b3ed94 100644 (file)
@@ -1226,12 +1226,13 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
       if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin()))
         return true;
 
-      bool WasAddrOf = FixOverloadedFunctionReference(From, Fn);
+      From = FixOverloadedFunctionReference(From, Fn);
       FromType = From->getType();
+        
       // If there's already an address-of operator in the expression, we have
       // the right type already, and the code below would just introduce an
       // invalid additional pointer level.
-      if (WasAddrOf)
+      if (FromType->isPointerType() || FromType->isMemberFunctionPointerType())
         break;
     }
     FromType = Context.getPointerType(FromType);
index 5c3e131eb4f370ff4d82bc1674e327704d51b065..f5a7d18980c93e15d1228435f9a58a2089da6305 100644 (file)
@@ -5368,13 +5368,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
 /// a C++ overloaded function (possibly with some parentheses and
 /// perhaps a '&' around it). We have resolved the overloaded function
 /// to the function declaration Fn, so patch up the expression E to
-/// refer (possibly indirectly) to Fn.
-/// Returns true if the function reference used an explicit address-of operator.
-bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
+/// refer (possibly indirectly) to Fn. Returns the new expr.
+Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
   if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
-    bool ret = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
-    E->setType(PE->getSubExpr()->getType());
-    return ret;
+    Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
+    NewExpr->setType(PE->getSubExpr()->getType());
+    return NewExpr;
   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
     assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
            "Can only take the address of an overloaded function");
@@ -5393,12 +5392,14 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
           = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
         E->setType(Context.getMemberPointerType(Fn->getType(),
                                                 ClassType.getTypePtr()));
-        return true;
+        return E;
       }
     }
-    FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
-    E->setType(Context.getPointerType(UnOp->getSubExpr()->getType()));
-    return true;
+    Expr *NewExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
+    UnOp->setSubExpr(NewExpr);
+    UnOp->setType(Context.getPointerType(NewExpr->getType()));
+    
+    return UnOp;
   } else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
     assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
             isa<FunctionTemplateDecl>(DR->getDecl())) &&
@@ -5408,10 +5409,17 @@ bool Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
   } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
     MemExpr->setMemberDecl(Fn);
     E->setType(Fn->getType());
+  } else if (TemplateIdRefExpr *TID = dyn_cast<TemplateIdRefExpr>(E)) {
+    // FIXME: Should we create QualifiedDeclRefExprs here too?
+    // FIXME: We should capture the template arguments here.
+    E = new (Context) DeclRefExpr(Fn, Fn->getType(), 
+                                  TID->getSourceRange().getBegin());
+    TID->Destroy(Context);
   } else {
     assert(false && "Invalid reference to overloaded function");
   }
-  return false;
+  
+  return E;
 }
 
 } // end namespace clang
index da7545c02de30a1a910fc2024da65e0b6a28d996..d9c53ebec63d53d864850244dc39940dfb1fa0dc 100644 (file)
@@ -2037,7 +2037,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
       if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
         return true;
 
-      FixOverloadedFunctionReference(Arg, Fn);
+      Arg = FixOverloadedFunctionReference(Arg, Fn);
       ArgType = Arg->getType();
       if (ArgType->isFunctionType() && ParamType->isPointerType()) {
         ArgType = Context.getPointerType(Arg->getType());
index 9a1364325f74f1c249ac0507156c94e6d480f67b..1f0c8f38630b8f581fab895ef89d68c99430c33d 100644 (file)
@@ -1,8 +1,13 @@
 // RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
 template <typename T> void f(T) {}
+template <typename T> void f() { }
 
 void test() {
   // CHECK: @_Z1fIiEvT_
   void (*p)(int) = &f;
+  
+  // CHECK: @_Z1fIiEvv
+  void (*p2)() = f<int>;
 }
 // CHECK: define linkonce_odr void @_Z1fIiEvT_
+// CHECK: define linkonce_odr void @_Z1fIiEvv