]> granicus.if.org Git - clang/commitdiff
Migrate Sema::ActOnCallExpr to Sema::FixOverloadedFunctionReference,
authorDouglas Gregor <dgregor@apple.com>
Fri, 23 Oct 2009 22:18:25 +0000 (22:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 23 Oct 2009 22:18:25 +0000 (22:18 +0000)
so that we maintain better source information after template argument
deduction and overloading resolves down to a specific
declaration. Found and dealt with a few more cases that
FixOverloadedFunctionReference didn't cope with.

(Finally) added a test case that puts together this change with the
DeclRefExpr change to (optionally) include nested-name-specifiers and
explicit template argument lists.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84974 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
test/SemaTemplate/template-id-printing.cpp [new file with mode: 0644]

index 490c73896ed13a81d1db21a63039fb39e3c32ae9..b1915750c9e9164ea6081568450acd2bd46ea73f 100644 (file)
@@ -2922,13 +2922,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
       if (!FDecl)
         return ExprError();
 
-      // Update Fn to refer to the actual function selected.
-      // FIXME: Use FixOverloadedFunctionReference?
-      Expr *NewFn = DeclRefExpr::Create(Context, Qualifier, QualifierRange, FDecl, 
-                                        Fn->getLocStart(), FDecl->getType(), false, 
-                                        false);
-      Fn->Destroy(Context);
-      Fn = NewFn;
+      Fn = FixOverloadedFunctionReference(Fn, FDecl);
     }
   }
 
index 5e946eb762131aea65cd0c9c949754a2437aebe0..7ed79f307337f36f500e45ef5bd3628d6204a32a 100644 (file)
@@ -5361,8 +5361,14 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
 Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
   if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
     Expr *NewExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
-    NewExpr->setType(PE->getSubExpr()->getType());
-    return NewExpr;
+    PE->setSubExpr(NewExpr);
+    PE->setType(NewExpr->getType());
+  } else if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+    Expr *NewExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), Fn);
+    assert(Context.hasSameType(ICE->getSubExpr()->getType(), 
+                               NewExpr->getType()) &&
+           "Implicit cast type cannot be determined from overload");
+    ICE->setSubExpr(NewExpr);
   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
     assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
            "Can only take the address of an overloaded function");
@@ -5394,8 +5400,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
     return UnOp;
   } else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
     assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
-            isa<FunctionTemplateDecl>(DR->getDecl())) &&
-           "Expected overloaded function or function template");
+            isa<FunctionTemplateDecl>(DR->getDecl()) ||
+            isa<FunctionDecl>(DR->getDecl())) &&
+           "Expected function or function template");
     DR->setDecl(Fn);
     E->setType(Fn->getType());
   } else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
@@ -5416,6 +5423,12 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
     // FIXME: Don't destroy TID here, since we need its template arguments
     // to survive.
     // TID->Destroy(Context);
+  } else if (isa<UnresolvedFunctionNameExpr>(E)) {
+    return DeclRefExpr::Create(Context, 
+                               /*Qualifier=*/0,
+                               /*QualifierRange=*/SourceRange(),
+                               Fn, E->getLocStart(),
+                               Fn->getType(), false, false);
   } else {
     assert(false && "Invalid reference to overloaded function");
   }
diff --git a/test/SemaTemplate/template-id-printing.cpp b/test/SemaTemplate/template-id-printing.cpp
new file mode 100644 (file)
index 0000000..1325094
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: clang-cc -fsyntax-only -ast-print %s | FileCheck %s
+namespace N {
+  template<typename T, typename U> void f(U);
+  template<int> void f();
+}
+
+void g() {
+  // CHECK: N::f<int>(3.14
+  N::f<int>(3.14);
+  
+  // CHECK: N::f<double>
+  void (*fp)(int) = N::f<double>;
+}