[cfe-commits] r81618 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/conversion-delete-expr.cpp

Fariborz Jahanian fjahanian at apple.com
Sat Sep 12 11:26:03 PDT 2009


Author: fjahanian
Date: Sat Sep 12 13:26:03 2009
New Revision: 81618

URL: http://llvm.org/viewvc/llvm-project?rev=81618&view=rev
Log:
More work toward having an access method for visible
conversion functions.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=81618&r1=81617&r2=81618&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Sep 12 13:26:03 2009
@@ -351,6 +351,10 @@
   ///   type (or array thereof), each such class has a trivial destructor.
   bool HasTrivialDestructor : 1;
 
+  /// ComputedVisibleConversions - True when visible conversion functions are
+  /// already computed and are available.
+  bool ComputedVisibleConversions : 1;
+  
   /// Bases - Base classes of this class.
   /// FIXME: This is wasted space for a union.
   CXXBaseSpecifier *Bases;
@@ -386,7 +390,9 @@
   /// RecordDecl from which the member class was instantiated.
   llvm::PointerUnion<ClassTemplateDecl*, CXXRecordDecl*>
     TemplateOrInstantiation;
-
+  
+  void getNestedVisibleConversionFunctions(CXXRecordDecl *RD);
+  
 protected:
   CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
                 SourceLocation L, IdentifierInfo *Id,
@@ -578,17 +584,14 @@
 
   /// getVisibleConversionFunctions - get all conversion functions visible
   /// in current class; including conversion function templates.
-  OverloadedFunctionDecl *getVisibleConversionFunctions(ASTContext &Context,
-                                                        CXXRecordDecl *RD);
+  OverloadedFunctionDecl *getVisibleConversionFunctions();
   /// addVisibleConversionFunction - Add a new conversion function to the
   /// list of visible conversion functions.
-  void addVisibleConversionFunction(ASTContext &Context, 
-                                    CXXConversionDecl *ConvDecl);
+  void addVisibleConversionFunction(CXXConversionDecl *ConvDecl);
   
   /// \brief Add a new conversion function template to the list of visible
   /// conversion functions.
-  void addVisibleConversionFunction(ASTContext &Context,
-                                    FunctionTemplateDecl *ConvDecl);
+  void addVisibleConversionFunction(FunctionTemplateDecl *ConvDecl);
   
   /// addConversionFunction - Add a new conversion function to the
   /// list of conversion functions.

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=81618&r1=81617&r2=81618&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Sep 12 13:26:03 2009
@@ -33,7 +33,8 @@
     Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
     Abstract(false), HasTrivialConstructor(true),
     HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
-    HasTrivialDestructor(true), Bases(0), NumBases(0), VBases(0), NumVBases(0),
+    HasTrivialDestructor(true), ComputedVisibleConversions(false),
+    Bases(0), NumBases(0), VBases(0), NumVBases(0),
     Conversions(DC, DeclarationName()),
     VisibleConversions(DC, DeclarationName()),
     TemplateOrInstantiation() { }
@@ -283,22 +284,12 @@
   PlainOldData = false;
 }
 
-/// getVisibleConversionFunctions - get all conversion functions visible
-/// in current class; including conversion function templates.
-OverloadedFunctionDecl *
-CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context,
-                                             CXXRecordDecl *RD) {
-  if (RD == this) {
-    // If root class, all conversions are visible.
-    if (RD->bases_begin() == RD->bases_end())
-      return &Conversions;
-    // If visible conversion list is already evaluated, return it.
-    if (VisibleConversions.function_begin() 
-        != VisibleConversions.function_end())
-      return &VisibleConversions;
-  }
-      
-  QualType ClassType = Context.getTypeDeclType(this);
+/// getNestedVisibleConversionFunctions - imports unique conversion 
+/// functions from base classes into the visible conversion function
+/// list of the class 'RD'. This is a private helper method.
+void
+CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
+  QualType ClassType = getASTContext().getTypeDeclType(this);
   if (const RecordType *Record = ClassType->getAs<RecordType>()) {
     OverloadedFunctionDecl *Conversions
       = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
@@ -306,24 +297,36 @@
          Func = Conversions->function_begin(),
          FuncEnd = Conversions->function_end();
          Func != FuncEnd; ++Func) {
-      if (FunctionTemplateDecl *ConversionTemplate = 
-            dyn_cast<FunctionTemplateDecl>(*Func)) {
-        RD->addVisibleConversionFunction(Context, ConversionTemplate);
-        continue;
-      }
-      CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
+      NamedDecl *Conv = Func->get();
       bool Candidate = true;
       // Only those conversions not exact match of conversions in current
       // class are candidateconversion routines.
+      // FIXME. This is a O(n^2) algorithm. 
       if (RD != this) {
         OverloadedFunctionDecl *TopConversions = RD->getConversionFunctions();
-        QualType ConvType = Context.getCanonicalType(Conv->getType());
+        QualType ConvType;
+        FunctionDecl *FD;
+        if (FunctionTemplateDecl *ConversionTemplate = 
+              dyn_cast<FunctionTemplateDecl>(Conv))
+          FD = ConversionTemplate->getTemplatedDecl();
+        else
+          FD = cast<FunctionDecl>(Conv);
+        ConvType = getASTContext().getCanonicalType(FD->getType());
+        
         for (OverloadedFunctionDecl::function_iterator
              TFunc = TopConversions->function_begin(),
              TFuncEnd = TopConversions->function_end();
              TFunc != TFuncEnd; ++TFunc) {
-          CXXConversionDecl *TopConv = cast<CXXConversionDecl>(*TFunc);
-          QualType TConvType = Context.getCanonicalType(TopConv->getType());
+          
+          NamedDecl *TopConv = TFunc->get();
+          FunctionDecl *TFD;
+          QualType TConvType;
+          if (FunctionTemplateDecl *TConversionTemplate =
+                dyn_cast<FunctionTemplateDecl>(TopConv))
+            TFD = TConversionTemplate->getTemplatedDecl();
+          else 
+            TFD = cast<FunctionDecl>(TopConv);
+          TConvType = getASTContext().getCanonicalType(TFD->getType());
           if (ConvType == TConvType) {
             Candidate = false;
             break;
@@ -331,11 +334,11 @@
         }
       }
       if (Candidate) {
-        if (FunctionTemplateDecl *ConversionTemplate
-              = Conv->getDescribedFunctionTemplate())
-          RD->addVisibleConversionFunction(Context, ConversionTemplate);
-        else if (!Conv->getPrimaryTemplate()) // ignore specializations
-          RD->addVisibleConversionFunction(Context, Conv);
+        if (FunctionTemplateDecl *ConversionTemplate =
+              dyn_cast<FunctionTemplateDecl>(Conv))
+          RD->addVisibleConversionFunction(ConversionTemplate);
+        else
+          RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv));
       }
     }
   }
@@ -344,7 +347,7 @@
        E = vbases_end(); VBase != E; ++VBase) {
     CXXRecordDecl *VBaseClassDecl
       = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
-    VBaseClassDecl->getVisibleConversionFunctions(Context, RD);
+    VBaseClassDecl->getNestedVisibleConversionFunctions(RD);
   }
   for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
        E = bases_end(); Base != E; ++Base) {
@@ -352,19 +355,33 @@
       continue;
     CXXRecordDecl *BaseClassDecl
       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-    BaseClassDecl->getVisibleConversionFunctions(Context, RD);
+    BaseClassDecl->getNestedVisibleConversionFunctions(RD);
   }
+}
+
+/// getVisibleConversionFunctions - get all conversion functions visible
+/// in current class; including conversion function templates.
+OverloadedFunctionDecl *
+CXXRecordDecl::getVisibleConversionFunctions() {
+  // If root class, all conversions are visible.
+  if (bases_begin() == bases_end())
+    return &Conversions;
+  // If visible conversion list is already evaluated, return it.
+  if (ComputedVisibleConversions)
+    return &VisibleConversions;
+  getNestedVisibleConversionFunctions(this);
+  ComputedVisibleConversions = true;
   return &VisibleConversions;
 }
 
-void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context,
+void CXXRecordDecl::addVisibleConversionFunction(
                                           CXXConversionDecl *ConvDecl) {
   assert(!ConvDecl->getDescribedFunctionTemplate() &&
          "Conversion function templates should cast to FunctionTemplateDecl.");
   VisibleConversions.addOverload(ConvDecl);
 }
 
-void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context,
+void CXXRecordDecl::addVisibleConversionFunction(
                                           FunctionTemplateDecl *ConvDecl) {
   assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
          "Function template is not a conversion function template");

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=81618&r1=81617&r2=81618&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Sep 12 13:26:03 2009
@@ -739,7 +739,7 @@
       llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
       OverloadedFunctionDecl *Conversions = 
-        RD->getVisibleConversionFunctions(Context, RD);
+        RD->getVisibleConversionFunctions();
       
       for (OverloadedFunctionDecl::function_iterator
              Func = Conversions->function_begin(),

Modified: cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp?rev=81618&r1=81617&r2=81618&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-delete-expr.cpp Sat Sep 12 13:26:03 2009
@@ -43,7 +43,6 @@
 }
 
 // Test4
-
 struct B3 {
   operator const int *();
 };
@@ -69,7 +68,6 @@
 void f4(X x) { delete x; delete x; }
 
 // Test6
-
 struct X1 {
    operator int();
    operator int*();
@@ -78,6 +76,36 @@
 
 void f5(X1 x) { delete x; } // FIXME. May have to issue error here too.
 
+// Test7
+struct Base {
+   operator int*();
+};
+
+struct Derived : Base {
+   operator int*() const; // not the same function as Base's non-const operator int()
+};
+
+void foo6(const Derived cd) {
+	// FIXME. overload resolution must select Derived::operator int*() const;
+	delete cd;	// expected-error {{cannot delete expression of type 'struct Derived const'}}
+}
+
+// Test8
+struct BB {
+   template<typename T> operator T*() const;
+};
+
+struct DD : BB {
+   template<typename T> operator T*() const; // hides base conversion
+   operator int *() const;
+};
+
+void foo7 (DD d)
+{
+	// FIXME. We select DD::operator int *() const; g++ issues ambiguity error. Investigate.
+	delete d;
+}
+
 
 
 





More information about the cfe-commits mailing list