summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-05-23 21:48:49 +0000
committerdim <dim@FreeBSD.org>2012-05-23 21:48:49 +0000
commit9d2e8543e6db6007e7d86295d6eee895ab247a70 (patch)
treeee30f8a7e81d1d6646490f99e21aa99ecfeb049a /contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
parenta9e55b2ceb39f5bb150ecfcb1882c11f6e29c411 (diff)
downloadFreeBSD-src-9d2e8543e6db6007e7d86295d6eee895ab247a70.zip
FreeBSD-src-9d2e8543e6db6007e7d86295d6eee895ab247a70.tar.gz
Upgrade our copy of llvm/clang to 3.1 release. Release notes can be
found at: http://llvm.org/releases/3.1/docs/ReleaseNotes.html MFC after: 3 days
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp126
1 files changed, 52 insertions, 74 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
index 1d251b9..c861072 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7319,15 +7319,42 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
}
}
+/// \brief Perform any semantic analysis which needs to be delayed until all
+/// pending class member declarations have been parsed.
+void Sema::ActOnFinishCXXMemberDecls() {
+ // Now we have parsed all exception specifications, determine the implicit
+ // exception specifications for destructors.
+ for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size();
+ i != e; ++i) {
+ CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i];
+ AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true);
+ }
+ DelayedDestructorExceptionSpecs.clear();
+
+ // Perform any deferred checking of exception specifications for virtual
+ // destructors.
+ for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size();
+ i != e; ++i) {
+ const CXXDestructorDecl *Dtor =
+ DelayedDestructorExceptionSpecChecks[i].first;
+ assert(!Dtor->getParent()->isDependentType() &&
+ "Should not ever add destructors of templates into the list.");
+ CheckOverridingFunctionExceptionSpec(Dtor,
+ DelayedDestructorExceptionSpecChecks[i].second);
+ }
+ DelayedDestructorExceptionSpecChecks.clear();
+}
+
void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
- CXXDestructorDecl *destructor) {
+ CXXDestructorDecl *destructor,
+ bool WasDelayed) {
// C++11 [class.dtor]p3:
// A declaration of a destructor that does not have an exception-
// specification is implicitly considered to have the same exception-
// specification as an implicit declaration.
const FunctionProtoType *dtorType = destructor->getType()->
getAs<FunctionProtoType>();
- if (dtorType->hasExceptionSpec())
+ if (!WasDelayed && dtorType->hasExceptionSpec())
return;
ImplicitExceptionSpecification exceptSpec =
@@ -7344,6 +7371,14 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
destructor->setType(ty);
+ // If we can't compute the exception specification for this destructor yet
+ // (because it depends on an exception specification which we have not parsed
+ // yet), make a note that we need to try again when the class is complete.
+ if (epi.ExceptionSpecType == EST_Delayed) {
+ assert(!WasDelayed && "couldn't compute destructor exception spec");
+ DelayedDestructorExceptionSpecs.push_back(destructor);
+ }
+
// FIXME: If the destructor has a body that could throw, and the newly created
// spec doesn't allow exceptions, we should emit a warning, because this
// change in behavior can break conforming C++03 programs at runtime.
@@ -7579,8 +7614,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
assert(!Base->getType()->isDependentType() &&
"Cannot generate implicit members for class with dependent bases.");
CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
- LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
- &HasConstCopyAssignment);
+ HasConstCopyAssignment &=
+ (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
+ false, 0);
}
// In C++11, the above citation has "or virtual" added
@@ -7591,8 +7627,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
assert(!Base->getType()->isDependentType() &&
"Cannot generate implicit members for class with dependent bases.");
CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
- LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
- &HasConstCopyAssignment);
+ HasConstCopyAssignment &=
+ (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
+ false, 0);
}
}
@@ -7606,8 +7643,9 @@ Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
- LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const, false, 0,
- &HasConstCopyAssignment);
+ HasConstCopyAssignment &=
+ (bool)LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const,
+ false, 0);
}
}
@@ -8610,8 +8648,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
- &HasConstCopyConstructor);
+ HasConstCopyConstructor &=
+ (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
}
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
@@ -8620,8 +8658,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
- &HasConstCopyConstructor);
+ HasConstCopyConstructor &=
+ (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
}
// -- for all the nonstatic data members of X that are of a
@@ -8634,8 +8672,8 @@ Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
++Field) {
QualType FieldType = Context.getBaseElementType((*Field)->getType());
if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
- LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const,
- &HasConstCopyConstructor);
+ HasConstCopyConstructor &=
+ (bool)LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const);
}
}
// Otherwise, the implicitly declared copy constructor will have
@@ -11260,66 +11298,6 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST,
}
}
-void Sema::actOnDelayedExceptionSpecification(Decl *MethodD,
- ExceptionSpecificationType EST,
- SourceRange SpecificationRange,
- ArrayRef<ParsedType> DynamicExceptions,
- ArrayRef<SourceRange> DynamicExceptionRanges,
- Expr *NoexceptExpr) {
- if (!MethodD)
- return;
-
- // Dig out the method we're referring to.
- CXXMethodDecl *Method = 0;
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast<CXXMethodDecl>(MethodD);
-
- if (!Method)
- return;
-
- // Dig out the prototype. This should never fail.
- const FunctionProtoType *Proto
- = dyn_cast<FunctionProtoType>(Method->getType());
- if (!Proto)
- return;
-
- // Check the exception specification.
- llvm::SmallVector<QualType, 4> Exceptions;
- FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
- checkExceptionSpecification(EST, DynamicExceptions, DynamicExceptionRanges,
- NoexceptExpr, Exceptions, EPI);
-
- // Rebuild the function type.
- QualType T = Context.getFunctionType(Proto->getResultType(),
- Proto->arg_type_begin(),
- Proto->getNumArgs(),
- EPI);
- if (TypeSourceInfo *TSInfo = Method->getTypeSourceInfo()) {
- // FIXME: When we get proper type location information for exceptions,
- // we'll also have to rebuild the TypeSourceInfo. For now, we just patch
- // up the TypeSourceInfo;
- assert(TypeLoc::getFullDataSizeForType(T)
- == TypeLoc::getFullDataSizeForType(Method->getType()) &&
- "TypeLoc size mismatch with delayed exception specification");
- TSInfo->overrideType(T);
- }
-
- Method->setType(T);
-
- if (Method->isStatic())
- checkThisInStaticMemberFunctionExceptionSpec(Method);
-
- if (Method->isVirtual()) {
- // Check overrides, which we previously had to delay.
- for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(),
- OEnd = Method->end_overridden_methods();
- O != OEnd; ++O)
- CheckOverridingFunctionExceptionSpec(Method, *O);
- }
-}
-
/// IdentifyCUDATarget - Determine the CUDA compilation target for this function
Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) {
// Implicitly declared functions (e.g. copy constructors) are
OpenPOWER on IntegriCloud