[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