aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-10-11 09:03:14 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-10-11 09:03:14 +0000
commitdced226e37f7c2c31c25d06c514f29b610fe2a54 (patch)
tree30aa2297994e532099f846cc528e47c6c5a4b829 /lib/Sema/SemaType.cpp
parent13d50177b13161b209579e1f30a5e3cc72f7e2bd (diff)
Test exception spec compatibility on return type and parameters.
Along the way, use RequireCompleteType when testing exception spec types. Separate all the ugly spec stuff into its own file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp184
1 files changed, 0 insertions, 184 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 5c7bbd0441..b82e5ec9b1 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1413,190 +1413,6 @@ void LocInfoType::getAsStringInternal(std::string &Str,
" GetTypeFromParser");
}
-/// CheckSpecifiedExceptionType - Check if the given type is valid in an
-/// exception specification. Incomplete types, or pointers to incomplete types
-/// other than void are not allowed.
-bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
- // FIXME: This may not correctly work with the fix for core issue 437,
- // where a class's own type is considered complete within its body.
-
- // C++ 15.4p2: A type denoted in an exception-specification shall not denote
- // an incomplete type.
- if (T->isIncompleteType())
- return Diag(Range.getBegin(), diag::err_incomplete_in_exception_spec)
- << Range << T << /*direct*/0;
-
- // C++ 15.4p2: A type denoted in an exception-specification shall not denote
- // an incomplete type a pointer or reference to an incomplete type, other
- // than (cv) void*.
- int kind;
- if (const PointerType* IT = T->getAs<PointerType>()) {
- T = IT->getPointeeType();
- kind = 1;
- } else if (const ReferenceType* IT = T->getAs<ReferenceType>()) {
- T = IT->getPointeeType();
- kind = 2;
- } else
- return false;
-
- if (T->isIncompleteType() && !T->isVoidType())
- return Diag(Range.getBegin(), diag::err_incomplete_in_exception_spec)
- << Range << T << /*indirect*/kind;
-
- return false;
-}
-
-/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
-/// to member to a function with an exception specification. This means that
-/// it is invalid to add another level of indirection.
-bool Sema::CheckDistantExceptionSpec(QualType T) {
- if (const PointerType *PT = T->getAs<PointerType>())
- T = PT->getPointeeType();
- else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
- T = PT->getPointeeType();
- else
- return false;
-
- const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
- if (!FnT)
- return false;
-
- return FnT->hasExceptionSpec();
-}
-
-/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
-/// exception specifications. Exception specifications are equivalent if
-/// they allow exactly the same set of exception types. It does not matter how
-/// that is achieved. See C++ [except.spec]p2.
-bool Sema::CheckEquivalentExceptionSpec(
- const FunctionProtoType *Old, SourceLocation OldLoc,
- const FunctionProtoType *New, SourceLocation NewLoc) {
- bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
- bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
- if (OldAny && NewAny)
- return false;
- if (OldAny || NewAny) {
- Diag(NewLoc, diag::err_mismatched_exception_spec);
- Diag(OldLoc, diag::note_previous_declaration);
- return true;
- }
-
- bool Success = true;
- // Both have a definite exception spec. Collect the first set, then compare
- // to the second.
- llvm::SmallPtrSet<const Type*, 8> Types;
- for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
- E = Old->exception_end(); I != E; ++I)
- Types.insert(Context.getCanonicalType(*I).getTypePtr());
-
- for (FunctionProtoType::exception_iterator I = New->exception_begin(),
- E = New->exception_end(); I != E && Success; ++I)
- Success = Types.erase(Context.getCanonicalType(*I).getTypePtr());
-
- Success = Success && Types.empty();
-
- if (Success) {
- return false;
- }
- Diag(NewLoc, diag::err_mismatched_exception_spec);
- Diag(OldLoc, diag::note_previous_declaration);
- return true;
-}
-
-/// CheckExceptionSpecSubset - Check whether the second function type's
-/// exception specification is a subset (or equivalent) of the first function
-/// type. This is used by override and pointer assignment checks.
-bool Sema::CheckExceptionSpecSubset(unsigned DiagID, unsigned NoteID,
- const FunctionProtoType *Superset, SourceLocation SuperLoc,
- const FunctionProtoType *Subset, SourceLocation SubLoc) {
- // FIXME: As usual, we could be more specific in our error messages, but
- // that better waits until we've got types with source locations.
-
- if (!SubLoc.isValid())
- SubLoc = SuperLoc;
-
- // If superset contains everything, we're done.
- if (!Superset->hasExceptionSpec() || Superset->hasAnyExceptionSpec())
- return false;
-
- // It does not. If the subset contains everything, we've failed.
- if (!Subset->hasExceptionSpec() || Subset->hasAnyExceptionSpec()) {
- Diag(SubLoc, DiagID);
- if (NoteID != 0)
- Diag(SuperLoc, NoteID);
- return true;
- }
-
- // Neither contains everything. Do a proper comparison.
- for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(),
- SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
- // Take one type from the subset.
- QualType CanonicalSubT = Context.getCanonicalType(*SubI);
- bool SubIsPointer = false;
- if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
- CanonicalSubT = RefTy->getPointeeType();
- if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
- CanonicalSubT = PtrTy->getPointeeType();
- SubIsPointer = true;
- }
- bool SubIsClass = CanonicalSubT->isRecordType();
- CanonicalSubT = CanonicalSubT.getUnqualifiedType();
-
- CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
- /*DetectVirtual=*/false);
-
- bool Contained = false;
- // Make sure it's in the superset.
- for (FunctionProtoType::exception_iterator SuperI =
- Superset->exception_begin(), SuperE = Superset->exception_end();
- SuperI != SuperE; ++SuperI) {
- QualType CanonicalSuperT = Context.getCanonicalType(*SuperI);
- // SubT must be SuperT or derived from it, or pointer or reference to
- // such types.
- if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
- CanonicalSuperT = RefTy->getPointeeType();
- if (SubIsPointer) {
- if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
- CanonicalSuperT = PtrTy->getPointeeType();
- else {
- continue;
- }
- }
- CanonicalSuperT = CanonicalSuperT.getUnqualifiedType();
- // If the types are the same, move on to the next type in the subset.
- if (CanonicalSubT == CanonicalSuperT) {
- Contained = true;
- break;
- }
-
- // Otherwise we need to check the inheritance.
- if (!SubIsClass || !CanonicalSuperT->isRecordType())
- continue;
-
- Paths.clear();
- if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths))
- continue;
-
- if (Paths.isAmbiguous(CanonicalSuperT))
- continue;
-
- if (FindInaccessibleBase(CanonicalSubT, CanonicalSuperT, Paths, true))
- continue;
-
- Contained = true;
- break;
- }
- if (!Contained) {
- Diag(SubLoc, DiagID);
- if (NoteID != 0)
- Diag(SuperLoc, NoteID);
- return true;
- }
- }
- // We've run the gauntlet.
- return false;
-}
-
/// ObjCGetTypeForMethodDefinition - Builds the type for a method definition
/// declarator
QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) {