aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-04-16 18:27:27 +0000
committerDouglas Gregor <dgregor@apple.com>2012-04-16 18:27:27 +0000
commit74e2fc332e07c76d4e69ccbd0e9e47a0bafd3908 (patch)
treee13935dca7e6eaa9e934215f7517e99dd591fcb4 /lib/Sema/SemaType.cpp
parent0f90590c96375052c67116f620fafa2b1eadb41e (diff)
Implement the last part of C++ [class.mem]p2, delaying the parsing of
exception specifications on member functions until after the closing '}' for the containing class. This allows, for example, a member function to throw an instance of its own class. Fixes PR12564 and a fairly embarassing oversight in our C++98/03 support. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154844 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp51
1 files changed, 25 insertions, 26 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index c41df82a48..d0906ded0c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -561,7 +561,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
/*const qualifier*/SourceLocation(),
/*volatile qualifier*/SourceLocation(),
/*mutable qualifier*/SourceLocation(),
- /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0,
+ /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0, 0,
/*parens*/ loc, loc,
declarator));
@@ -2371,34 +2371,33 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
EPI.ConsumedArguments = ConsumedArguments.data();
SmallVector<QualType, 4> Exceptions;
- EPI.ExceptionSpecType = FTI.getExceptionSpecType();
+ SmallVector<ParsedType, 2> DynamicExceptions;
+ SmallVector<SourceRange, 2> DynamicExceptionRanges;
+ Expr *NoexceptExpr = 0;
+
if (FTI.getExceptionSpecType() == EST_Dynamic) {
- Exceptions.reserve(FTI.NumExceptions);
- for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
- // FIXME: Preserve type source info.
- QualType ET = S.GetTypeFromParser(FTI.Exceptions[ei].Ty);
- // Check that the type is valid for an exception spec, and
- // drop it if not.
- if (!S.CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
- Exceptions.push_back(ET);
+ // FIXME: It's rather inefficient to have to split into two vectors
+ // here.
+ unsigned N = FTI.NumExceptions;
+ DynamicExceptions.reserve(N);
+ DynamicExceptionRanges.reserve(N);
+ for (unsigned I = 0; I != N; ++I) {
+ DynamicExceptions.push_back(FTI.Exceptions[I].Ty);
+ DynamicExceptionRanges.push_back(FTI.Exceptions[I].Range);
}
- EPI.NumExceptions = Exceptions.size();
- EPI.Exceptions = Exceptions.data();
} else if (FTI.getExceptionSpecType() == EST_ComputedNoexcept) {
- // If an error occurred, there's no expression here.
- if (Expr *NoexceptExpr = FTI.NoexceptExpr) {
- assert((NoexceptExpr->isTypeDependent() ||
- NoexceptExpr->getType()->getCanonicalTypeUnqualified() ==
- Context.BoolTy) &&
- "Parser should have made sure that the expression is boolean");
- if (!NoexceptExpr->isValueDependent())
- NoexceptExpr = S.VerifyIntegerConstantExpression(NoexceptExpr, 0,
- S.PDiag(diag::err_noexcept_needs_constant_expression),
- /*AllowFold*/ false).take();
- EPI.NoexceptExpr = NoexceptExpr;
- }
- } else if (FTI.getExceptionSpecType() == EST_None &&
- ImplicitlyNoexcept && chunkIndex == 0) {
+ NoexceptExpr = FTI.NoexceptExpr;
+ }
+
+ S.checkExceptionSpecification(FTI.getExceptionSpecType(),
+ DynamicExceptions,
+ DynamicExceptionRanges,
+ NoexceptExpr,
+ Exceptions,
+ EPI);
+
+ if (FTI.getExceptionSpecType() == EST_None &&
+ ImplicitlyNoexcept && chunkIndex == 0) {
// Only the outermost chunk is marked noexcept, of course.
EPI.ExceptionSpecType = EST_BasicNoexcept;
}