]> granicus.if.org Git - clang/commitdiff
Implement IRGen for MemberExpr referring to static member function.
authorEli Friedman <eli.friedman@gmail.com>
Thu, 26 Nov 2009 06:08:14 +0000 (06:08 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Thu, 26 Nov 2009 06:08:14 +0000 (06:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89938 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/member-expressions.cpp

index 853715cce2047fbfa51922b3114f87f12b571d0d..88429a3c8629dc7a63a4c2e23706934f23951aad 100644 (file)
@@ -828,6 +828,24 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
   return LV;
 }
 
+static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
+                                      const Expr *E, const FunctionDecl *FD) {
+  llvm::Value* V = CGF.CGM.GetAddrOfFunction(FD);
+  if (!FD->hasPrototype()) {
+    if (const FunctionProtoType *Proto =
+            FD->getType()->getAs<FunctionProtoType>()) {
+      // Ugly case: for a K&R-style definition, the type of the definition
+      // isn't the same as the type of a use.  Correct for this with a
+      // bitcast.
+      QualType NoProtoType =
+          CGF.getContext().getFunctionNoProtoType(Proto->getResultType());
+      NoProtoType = CGF.getContext().getPointerType(NoProtoType);
+      V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType), "tmp");
+    }
+  }
+  return LValue::MakeAddr(V, CGF.MakeQualifiers(E->getType()));
+}
+
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
 
@@ -861,22 +879,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
     return LV;
   }
   
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
-    llvm::Value* V = CGM.GetAddrOfFunction(FD);
-    if (!FD->hasPrototype()) {
-      if (const FunctionProtoType *Proto =
-              FD->getType()->getAs<FunctionProtoType>()) {
-        // Ugly case: for a K&R-style definition, the type of the definition
-        // isn't the same as the type of a use.  Correct for this with a
-        // bitcast.
-        QualType NoProtoType =
-            getContext().getFunctionNoProtoType(Proto->getResultType());
-        NoProtoType = getContext().getPointerType(NoProtoType);
-        V = Builder.CreateBitCast(V, ConvertType(NoProtoType), "tmp");
-      }
-    }
-    return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
-  }
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+    return EmitFunctionDeclLValue(*this, E, FD);
   
   if (E->getQualifier()) {
     // FIXME: the qualifier check does not seem sufficient here
@@ -1163,7 +1167,10 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
   
   if (VarDecl *VD = dyn_cast<VarDecl>(ND))
     return EmitGlobalVarDeclLValue(*this, E, VD);
-  
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+    return EmitFunctionDeclLValue(*this, E, FD);
+
   assert(false && "Unhandled member declaration!");
   return LValue();
 }
index 76b81e068823f9b1de49ee52dd8af4b9be4c3d19..a38d5f9eaa2cf613cab4a43db740e9506dcb874b 100644 (file)
@@ -36,3 +36,11 @@ void f(A *a) {
   A::E e3 = A().Foo;
 }
 
+namespace test3 {
+struct A {
+  static int foo();
+};
+int f() {
+  return A().foo();
+}
+}