summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-29 04:25:11 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-29 04:25:11 +0000
commit457104e98b957aeca55481574ed395c6ee503fbc (patch)
treec05cd6e56c9eb9e22fd14e49b80884fa5a1d1318
parent0be2dbb6a28c8d63defebb18a6dca822db8266ae (diff)
downloadbcm5719-llvm-457104e98b957aeca55481574ed395c6ee503fbc.tar.gz
bcm5719-llvm-457104e98b957aeca55481574ed395c6ee503fbc.zip
Move the management of the set of conversion functions in a C++ class
into CXXRecordDecl. The only part that we do not handle this way are using declarations, since that would require extra name lookup that we don't currently want to pay for. This fixes <rdar://problem/8459981>, so that LLDB can build a CXXRecordDecl and magically get all of the right bits set. llvm-svn: 115026
-rw-r--r--clang/include/clang/AST/DeclCXX.h19
-rw-r--r--clang/lib/AST/DeclCXX.cpp36
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp37
3 files changed, 45 insertions, 47 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 052cbe8cb41..9c2d497c210 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -657,13 +657,6 @@ public:
return getConversionFunctions()->end();
}
- /// Replaces a conversion function with a new declaration.
- ///
- /// Returns true if the old conversion was found.
- bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
- return getConversionFunctions()->replace(Old, New);
- }
-
/// Removes a conversion function from this class. The conversion
/// function must currently be a member of this class. Furthermore,
/// this class must currently be in the process of being defined.
@@ -673,18 +666,6 @@ public:
/// in current class; including conversion function templates.
const UnresolvedSetImpl *getVisibleConversionFunctions();
- /// addConversionFunction - Registers a conversion function which
- /// this class declares directly.
- void addConversionFunction(NamedDecl *Decl) {
-#ifndef NDEBUG
- CheckConversionFunction(Decl);
-#endif
-
- // We intentionally don't use the decl's access here because it
- // hasn't been set yet. That's really just a misdesign in Sema.
- data().Conversions.addDecl(Decl);
- }
-
/// isAggregate - Whether this class is an aggregate (C++
/// [dcl.init.aggr]), which is a class with no user-declared
/// constructors, no private or protected non-static data members,
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 6e879ee9ee4..19caae5b7f2 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -493,6 +493,30 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().PlainOldData = false;
}
+ // Keep the list of conversion functions up-to-date.
+ if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
+ // We don't record specializations.
+ if (Conversion->getPrimaryTemplate())
+ return;
+
+ // FIXME: We intentionally don't use the decl's access here because it
+ // hasn't been set yet. That's really just a misdesign in Sema.
+
+ if (FunTmpl) {
+ if (FunTmpl->getPreviousDeclaration())
+ data().Conversions.replace(FunTmpl->getPreviousDeclaration(),
+ FunTmpl);
+ else
+ data().Conversions.addDecl(FunTmpl);
+ } else {
+ if (Conversion->getPreviousDeclaration())
+ data().Conversions.replace(Conversion->getPreviousDeclaration(),
+ Conversion);
+ else
+ data().Conversions.addDecl(Conversion);
+ }
+ }
+
return;
}
@@ -546,6 +570,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
}
}
}
+
+ // Handle using declarations of conversion functions.
+ if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D))
+ if (Shadow->getDeclName().getNameKind()
+ == DeclarationName::CXXConversionFunctionName)
+ data().Conversions.addDecl(Shadow, Shadow->getAccess());
}
static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
@@ -833,6 +863,12 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
}
}
}
+
+ // Set access bits correctly on the directly-declared conversions.
+ for (UnresolvedSetIterator I = data().Conversions.begin(),
+ E = data().Conversions.end();
+ I != E; ++I)
+ data().Conversions.setAccess(I, (*I)->getAccess());
}
bool CXXRecordDecl::mayBeAbstract() const {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e0049e636fc..1e4065454ed 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3107,25 +3107,10 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
<< ClassType << ConvType;
}
- if (Conversion->getPrimaryTemplate()) {
- // ignore specializations
- } else if (Conversion->getPreviousDeclaration()) {
- if (FunctionTemplateDecl *ConversionTemplate
- = Conversion->getDescribedFunctionTemplate()) {
- if (ClassDecl->replaceConversion(
- ConversionTemplate->getPreviousDeclaration(),
- ConversionTemplate))
- return ConversionTemplate;
- } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
- Conversion))
- return Conversion;
- assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
- } else if (FunctionTemplateDecl *ConversionTemplate
- = Conversion->getDescribedFunctionTemplate())
- ClassDecl->addConversionFunction(ConversionTemplate);
- else
- ClassDecl->addConversionFunction(Conversion);
-
+ if (FunctionTemplateDecl *ConversionTemplate
+ = Conversion->getDescribedFunctionTemplate())
+ return ConversionTemplate;
+
return Conversion;
}
@@ -3669,20 +3654,16 @@ UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S,
= UsingShadowDecl::Create(Context, CurContext,
UD->getLocation(), UD, Target);
UD->addShadowDecl(Shadow);
-
+
+ Shadow->setAccess(UD->getAccess());
+ if (Orig->isInvalidDecl() || UD->isInvalidDecl())
+ Shadow->setInvalidDecl();
+
if (S)
PushOnScopeChains(Shadow, S);
else
CurContext->addDecl(Shadow);
- Shadow->setAccess(UD->getAccess());
- // Register it as a conversion if appropriate.
- if (Shadow->getDeclName().getNameKind()
- == DeclarationName::CXXConversionFunctionName)
- cast<CXXRecordDecl>(CurContext)->addConversionFunction(Shadow);
-
- if (Orig->isInvalidDecl() || UD->isInvalidDecl())
- Shadow->setInvalidDecl();
return Shadow;
}
OpenPOWER on IntegriCloud