]> granicus.if.org Git - clang/commitdiff
Fix http://llvm.org/PR5090.
authorMike Stump <mrs@apple.com>
Tue, 29 Sep 2009 00:50:50 +0000 (00:50 +0000)
committerMike Stump <mrs@apple.com>
Tue, 29 Sep 2009 00:50:50 +0000 (00:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83035 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
include/clang/AST/DeclCXX.h
include/clang/AST/Redeclarable.h
lib/AST/Decl.cpp
lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/virt.cpp

index 0b02ee26a85214a2733147b47d87c75b188d8fc4..4474719f366cab66c48d46089532b4c8d7195e4a 100644 (file)
@@ -973,6 +973,7 @@ public:
 
   void setPreviousDeclaration(FunctionDecl * PrevDecl);
 
+  virtual const FunctionDecl *getCanonicalDecl() const;
   virtual FunctionDecl *getCanonicalDecl();
 
   unsigned getBuiltinID() const;
index 4693034422515369370708c5a50865a527596451..e4becf81cc5f6e2d849ed2da39479f54c3424ba9 100644 (file)
@@ -785,6 +785,13 @@ public:
     return (CD->begin_overridden_methods() != CD->end_overridden_methods());
   }
   
+  const CXXMethodDecl *getCanonicalDecl() const {
+    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  CXXMethodDecl *getCanonicalDecl() {
+    return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
+  }
+  
   ///
   void addOverriddenMethod(const CXXMethodDecl *MD);
 
index 5cd50686c599a7514727fa6f6df1ead64d63ccdb..458af1f14423dba485f49e847aaebb88800fc3ca 100644 (file)
@@ -79,6 +79,15 @@ public:
     return D;
   }
 
+  /// \brief Return the first declaration of this declaration or itself if this
+  /// is the only declaration.
+  const decl_type *getFirstDeclaration() const {
+    const decl_type *D = static_cast<const decl_type*>(this);
+    while (D->getPreviousDeclaration())
+      D = D->getPreviousDeclaration();
+    return D;
+  }
+
   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
   /// first and only declaration.
   void setPreviousDeclaration(decl_type *PrevDecl) {
index 25d3d44cc8a791f058f657195088e6df144061d0..24dd3e5e3d74c0ce5e2a36cf2ddd965460974078 100644 (file)
@@ -653,6 +653,10 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
   }
 }
 
+const FunctionDecl *FunctionDecl::getCanonicalDecl() const {
+  return getFirstDeclaration();
+}
+
 FunctionDecl *FunctionDecl::getCanonicalDecl() {
   return getFirstDeclaration();
 }
index 4c1f6ad4cd3bf19479cbdad2479f1f3aa9e83d6c..e37b4a854824b5759b76d756d8f96810b13c6d78 100644 (file)
@@ -221,7 +221,8 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) {
   //   virtual call mechanism.
   llvm::Value *Callee;
   if (MD->isVirtual() && !ME->hasQualifier())
-    Callee = BuildVirtualCall(MD, This, Ty);
+    // FIXME: push getCanonicalDecl as a conversion using the static type system (CanCXXMethodDecl).
+    Callee = BuildVirtualCall(MD->getCanonicalDecl(), This, Ty);
   else if (const CXXDestructorDecl *Destructor
              = dyn_cast<CXXDestructorDecl>(MD))
     Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
index dfb705ae5377bf3a6af6ebfbf8ef3e9695e28244..176009acc4a8a236146e81acd3f11d686f076271 100644 (file)
@@ -920,6 +920,19 @@ struct test13_D : test13_NV1, virtual test13_B2 {
 // CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev
 // CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev
 
+class test14 {
+public:
+    virtual void initWithInt(int a);
+    static test14 *withInt(int a);
+};
+
+void test14::initWithInt(int a) { }
+
+test14 *test14::withInt(int a) {
+  test14 *me = new test14;
+  me->initWithInt(a);
+  return me;
+}
 
 test11_D d11;
 test10_D d10;