Have the parser communicate the exception specification to the action.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70389 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index bcf14d9..d742ef2 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -32,19 +32,27 @@
ParamInfo *ArgInfo,
unsigned NumArgs,
unsigned TypeQuals,
+ bool hasExceptionSpec,
+ bool hasAnyExceptionSpec,
+ ActionBase::TypeTy **Exceptions,
+ unsigned NumExceptions,
SourceLocation Loc,
Declarator &TheDeclarator) {
DeclaratorChunk I;
- I.Kind = Function;
- I.Loc = Loc;
- I.Fun.hasPrototype = hasProto;
- I.Fun.isVariadic = isVariadic;
- I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
- I.Fun.DeleteArgInfo = false;
- I.Fun.TypeQuals = TypeQuals;
- I.Fun.NumArgs = NumArgs;
- I.Fun.ArgInfo = 0;
-
+ I.Kind = Function;
+ I.Loc = Loc;
+ I.Fun.hasPrototype = hasProto;
+ I.Fun.isVariadic = isVariadic;
+ I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
+ I.Fun.DeleteArgInfo = false;
+ I.Fun.TypeQuals = TypeQuals;
+ I.Fun.NumArgs = NumArgs;
+ I.Fun.ArgInfo = 0;
+ I.Fun.hasExceptionSpec = hasExceptionSpec;
+ I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
+ I.Fun.NumExceptions = NumExceptions;
+ I.Fun.Exceptions = 0;
+
// new[] an argument array if needed.
if (NumArgs) {
// If the 'InlineParams' in Declarator is unused and big enough, put our
@@ -62,6 +70,12 @@
}
memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
}
+ // new[] an exception array if needed
+ if (NumExceptions) {
+ I.Fun.Exceptions = new ActionBase::TypeTy*[NumExceptions];
+ memcpy(I.Fun.Exceptions, Exceptions,
+ sizeof(ActionBase::TypeTy*)*NumExceptions);
+ }
return I;
}
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index f02b8a0..ec8923a 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2246,14 +2246,21 @@
// cv-qualifier-seq[opt].
DeclSpec DS;
+ bool hasExceptionSpec = false;
+ bool hasAnyExceptionSpec = false;
+ // FIXME: Does an empty vector ever allocate? Exception specifications are
+ // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-)
+ std::vector<TypeTy*> Exceptions;
if (getLang().CPlusPlus) {
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
if (!DS.getSourceRange().getEnd().isInvalid())
Loc = DS.getSourceRange().getEnd();
// Parse exception-specification[opt].
- if (Tok.is(tok::kw_throw))
- ParseExceptionSpecification(Loc);
+ if (Tok.is(tok::kw_throw)) {
+ hasExceptionSpec = true;
+ ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec);
+ }
}
// Remember that we parsed a function type, and remember the attributes.
@@ -2263,6 +2270,11 @@
SourceLocation(),
/*arglist*/ 0, 0,
DS.getTypeQualifiers(),
+ hasExceptionSpec,
+ hasAnyExceptionSpec,
+ Exceptions.empty() ? 0 :
+ &Exceptions[0],
+ Exceptions.size(),
LParenLoc, D),
Loc);
return;
@@ -2406,6 +2418,11 @@
SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
DeclSpec DS;
+ bool hasExceptionSpec = false;
+ bool hasAnyExceptionSpec = false;
+ // FIXME: Does an empty vector ever allocate? Exception specifications are
+ // extremely rare, so we want something like a SmallVector<TypeTy*, 0>. :-)
+ std::vector<TypeTy*> Exceptions;
if (getLang().CPlusPlus) {
// Parse cv-qualifier-seq[opt].
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
@@ -2413,8 +2430,10 @@
Loc = DS.getSourceRange().getEnd();
// Parse exception-specification[opt].
- if (Tok.is(tok::kw_throw))
- ParseExceptionSpecification(Loc);
+ if (Tok.is(tok::kw_throw)) {
+ hasExceptionSpec = true;
+ ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec);
+ }
}
// Remember that we parsed a function type, and remember the attributes.
@@ -2422,7 +2441,11 @@
EllipsisLoc,
&ParamInfo[0], ParamInfo.size(),
DS.getTypeQualifiers(),
- LParenLoc, D),
+ hasExceptionSpec,
+ hasAnyExceptionSpec,
+ Exceptions.empty() ? 0 :
+ &Exceptions[0],
+ Exceptions.size(), LParenLoc, D),
Loc);
}
@@ -2496,7 +2519,9 @@
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
SourceLocation(),
&ParamInfo[0], ParamInfo.size(),
- /*TypeQuals*/0, LParenLoc, D),
+ /*TypeQuals*/0,
+ /*exception*/false, false, 0, 0,
+ LParenLoc, D),
RLoc);
}
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index c6a373d..f684649 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1112,7 +1112,9 @@
/// type-id
/// type-id-list ',' type-id
///
-bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
+bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
+ std::vector<TypeTy*> &Exceptions,
+ bool &hasAnyExceptionSpec) {
assert(Tok.is(tok::kw_throw) && "expected throw");
SourceLocation ThrowLoc = ConsumeToken();
@@ -1125,6 +1127,7 @@
// Parse throw(...), a Microsoft extension that means "this function
// can throw anything".
if (Tok.is(tok::ellipsis)) {
+ hasAnyExceptionSpec = true;
SourceLocation EllipsisLoc = ConsumeToken();
if (!getLang().Microsoft)
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
@@ -1134,10 +1137,12 @@
// Parse the sequence of type-ids.
while (Tok.isNot(tok::r_paren)) {
- ParseTypeName();
+ TypeResult Res(ParseTypeName());
+ if (!Res.isInvalid())
+ Exceptions.push_back(Res.get());
if (Tok.is(tok::comma))
ConsumeToken();
- else
+ else
break;
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 55bc186..f299c52 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1353,8 +1353,9 @@
// Otherwise, pretend we saw (void).
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
SourceLocation(),
- 0, 0, 0, CaretLoc,
- ParamInfo),
+ 0, 0, 0,
+ false, false, 0, 0,
+ CaretLoc, ParamInfo),
CaretLoc);
// Inform sema that we are starting a block.
Actions.ActOnBlockArguments(ParamInfo, CurScope);