aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2011-03-05 22:42:13 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2011-03-05 22:42:13 +0000
commit6e5d319b671dbb0ecf70619834aa23c853d17621 (patch)
treea8652e0c9289d3bd14ab63f10a7e8ef12856415b
parent69db2ddcb2cef7dbdfe92a49137ae322bc42d319 (diff)
Propagate new-style exception spec information to Declarator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127111 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/DeclSpec.h56
-rw-r--r--lib/Parse/ParseDecl.cpp19
-rw-r--r--lib/Parse/ParseExpr.cpp5
-rw-r--r--lib/Sema/DeclSpec.cpp65
-rw-r--r--lib/Sema/SemaDecl.cpp4
-rw-r--r--lib/Sema/SemaType.cpp14
6 files changed, 93 insertions, 70 deletions
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 1567baaaad..164dac096d 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -1028,11 +1028,8 @@ struct DeclaratorChunk {
/// The qualifier bitmask values are the same as in QualType.
unsigned TypeQuals : 3;
- /// hasExceptionSpec - True if the function has an exception specification.
- unsigned hasExceptionSpec : 1;
-
- /// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
- unsigned hasAnyExceptionSpec : 1;
+ /// ExceptionSpecType - An ExceptionSpecificationType value.
+ unsigned ExceptionSpecType : 3;
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
unsigned DeleteArgInfo : 1;
@@ -1044,28 +1041,34 @@ struct DeclaratorChunk {
/// declarator.
unsigned NumArgs;
- /// NumExceptions - This is the number of types in the exception-decl, if
- /// the function has one.
+ /// NumExceptions - This is the number of types in the dynamic-exception-
+ /// decl, if the function has one.
unsigned NumExceptions;
/// \brief The location of the ref-qualifier, if any.
///
/// If this is an invalid location, there is no ref-qualifier.
unsigned RefQualifierLoc;
-
- /// ThrowLoc - When hasExceptionSpec is true, the location of the throw
+
+ /// \brief When ExceptionSpecType isn't EST_None, the location of the
/// keyword introducing the spec.
- unsigned ThrowLoc;
+ unsigned ExceptionSpecLoc;
/// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
/// describe the arguments for this function declarator. This is null if
/// there are no arguments specified.
ParamInfo *ArgInfo;
- /// Exceptions - This is a pointer to a new[]'d array of TypeAndRange
- /// objects that contain the types in the function's exception
- /// specification and their locations.
- TypeAndRange *Exceptions;
+ union {
+ /// \brief Pointer to a new[]'d array of TypeAndRange objects that
+ /// contain the types in the function's dynamic exception specification
+ /// and their locations, if there is one.
+ TypeAndRange *Exceptions;
+
+ /// \brief Pointer to the expression in the noexcept-specifier of this
+ /// function, if it has one.
+ Expr *NoexceptExpr;
+ };
/// TrailingReturnType - If this isn't null, it's the trailing return type
/// specified. This is actually a ParsedType, but stored as void* to
@@ -1085,7 +1088,8 @@ struct DeclaratorChunk {
void destroy() {
if (DeleteArgInfo)
delete[] ArgInfo;
- delete[] Exceptions;
+ if (getExceptionSpecType() == EST_Dynamic)
+ delete[] Exceptions;
}
/// isKNRPrototype - Return true if this is a K&R style identifier list,
@@ -1098,18 +1102,23 @@ struct DeclaratorChunk {
SourceLocation getEllipsisLoc() const {
return SourceLocation::getFromRawEncoding(EllipsisLoc);
}
- SourceLocation getThrowLoc() const {
- return SourceLocation::getFromRawEncoding(ThrowLoc);
+ SourceLocation getExceptionSpecLoc() const {
+ return SourceLocation::getFromRawEncoding(ExceptionSpecLoc);
}
-
+
/// \brief Retrieve the location of the ref-qualifier, if any.
SourceLocation getRefQualifierLoc() const {
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
}
-
+
/// \brief Determine whether this function declaration contains a
/// ref-qualifier.
bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
+
+ /// \brief Get the type of exception specification this function has.
+ ExceptionSpecificationType getExceptionSpecType() const {
+ return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+ }
};
struct BlockPointerTypeInfo : TypeInfoCommon {
@@ -1233,15 +1242,16 @@ struct DeclaratorChunk {
unsigned TypeQuals,
bool RefQualifierIsLvalueRef,
SourceLocation RefQualifierLoc,
- bool hasExceptionSpec,
- SourceLocation ThrowLoc,
- bool hasAnyExceptionSpec,
+ ExceptionSpecificationType ESpecType,
+ SourceLocation ESpecLoc,
ParsedType *Exceptions,
SourceRange *ExceptionRanges,
unsigned NumExceptions,
+ Expr *NoexceptExpr,
SourceLocation LPLoc, SourceLocation RPLoc,
Declarator &TheDeclarator,
- ParsedType TrailingReturnType = ParsedType());
+ ParsedType TrailingReturnType =
+ ParsedType());
/// getBlockPointer - Return a DeclaratorChunk for a block.
///
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5cda4e6d5c..7fd49838c8 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3197,13 +3197,12 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
DS.getTypeQualifiers(),
RefQualifierIsLValueRef,
RefQualifierLoc,
- ESpecType == EST_Dynamic ||
- ESpecType == EST_DynamicAny,
- ESpecRange.getBegin(),
- ESpecType == EST_DynamicAny,
+ ESpecType, ESpecRange.getBegin(),
DynamicExceptions.data(),
DynamicExceptionRanges.data(),
DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ?
+ NoexceptExpr.get() : 0,
LParenLoc, RParenLoc, D,
TrailingReturnType),
EndLoc);
@@ -3453,13 +3452,12 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
DS.getTypeQualifiers(),
RefQualifierIsLValueRef,
RefQualifierLoc,
- ESpecType == EST_Dynamic ||
- ESpecType == EST_DynamicAny,
- ESpecRange.getBegin(),
- ESpecType == EST_DynamicAny,
+ ESpecType, ESpecRange.getBegin(),
DynamicExceptions.data(),
DynamicExceptionRanges.data(),
DynamicExceptions.size(),
+ NoexceptExpr.isUsable() ?
+ NoexceptExpr.get() : 0,
LParenLoc, RParenLoc, D,
TrailingReturnType),
EndLoc);
@@ -3537,9 +3535,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
&ParamInfo[0], ParamInfo.size(),
/*TypeQuals*/0,
true, SourceLocation(),
- /*exception*/false,
- SourceLocation(), false, 0, 0, 0,
- LParenLoc, RLoc, D),
+ EST_None, SourceLocation(), 0, 0,
+ 0, 0, LParenLoc, RLoc, D),
RLoc);
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4a155a302f..ab74d5160d 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1918,8 +1918,9 @@ ExprResult Parser::ParseBlockLiteralExpression() {
SourceLocation(),
0, 0, 0,
true, SourceLocation(),
- false, SourceLocation(),
- false, 0, 0, 0,
+ EST_None,
+ SourceLocation(),
+ 0, 0, 0, 0,
CaretLoc, CaretLoc,
ParamInfo),
CaretLoc);
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index df29febe4f..a154fbd79a 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -142,35 +142,36 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
unsigned TypeQuals,
bool RefQualifierIsLvalueRef,
SourceLocation RefQualifierLoc,
- bool hasExceptionSpec,
- SourceLocation ThrowLoc,
- bool hasAnyExceptionSpec,
+ ExceptionSpecificationType
+ ESpecType,
+ SourceLocation ESpecLoc,
ParsedType *Exceptions,
SourceRange *ExceptionRanges,
unsigned NumExceptions,
+ Expr *NoexceptExpr,
SourceLocation LPLoc,
SourceLocation RPLoc,
Declarator &TheDeclarator,
ParsedType TrailingReturnType) {
DeclaratorChunk I;
- I.Kind = Function;
- I.Loc = LPLoc;
- I.EndLoc = RPLoc;
- I.Fun.AttrList = attrs.getList();
- 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 = LPLoc;
+ I.EndLoc = RPLoc;
+ I.Fun.AttrList = attrs.getList();
+ 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.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
- I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
- I.Fun.hasExceptionSpec = hasExceptionSpec;
- I.Fun.ThrowLoc = ThrowLoc.getRawEncoding();
- I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
- I.Fun.NumExceptions = NumExceptions;
- I.Fun.Exceptions = 0;
+ I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
+ I.Fun.ExceptionSpecType = ESpecType;
+ I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding();
+ I.Fun.NumExceptions = 0;
+ I.Fun.Exceptions = 0;
+ I.Fun.NoexceptExpr = 0;
I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr();
// new[] an argument array if needed.
@@ -190,13 +191,25 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
}
memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
}
- // new[] an exception array if needed
- if (NumExceptions) {
- I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
- for (unsigned i = 0; i != NumExceptions; ++i) {
- I.Fun.Exceptions[i].Ty = Exceptions[i];
- I.Fun.Exceptions[i].Range = ExceptionRanges[i];
+
+ // Check what exception specification information we should actually store.
+ switch (ESpecType) {
+ default: break; // By default, save nothing.
+ case EST_Dynamic:
+ // new[] an exception array if needed
+ if (NumExceptions) {
+ I.Fun.NumExceptions = NumExceptions;
+ I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
+ for (unsigned i = 0; i != NumExceptions; ++i) {
+ I.Fun.Exceptions[i].Ty = Exceptions[i];
+ I.Fun.Exceptions[i].Range = ExceptionRanges[i];
+ }
}
+ break;
+
+ case EST_ComputedNoexcept:
+ I.Fun.NoexceptExpr = NoexceptExpr;
+ break;
}
return I;
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index b40d4f3e9e..b674cc1701 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5758,8 +5758,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
false, false, SourceLocation(), 0,
0, 0, true, SourceLocation(),
- false, SourceLocation(),
- false, 0,0,0, Loc, Loc, D),
+ EST_None, SourceLocation(),
+ 0, 0, 0, 0, Loc, Loc, D),
SourceLocation());
D.SetIdentifier(&II, Loc);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index dcd61a8d1a..33df7a0529 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -511,7 +511,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
/*args*/ 0, 0,
/*type quals*/ 0,
/*ref-qualifier*/true, SourceLocation(),
- /*EH*/ false, SourceLocation(), false, 0, 0, 0,
+ /*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0,
/*parens*/ loc, loc,
declarator));
@@ -1764,9 +1764,9 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// Exception specs are not allowed in typedefs. Complain, but add it
// anyway.
- if (FTI.hasExceptionSpec &&
+ if (FTI.getExceptionSpecType() != EST_None &&
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
- Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef);
+ Diag(FTI.getExceptionSpecLoc(), diag::err_exception_spec_in_typedef);
if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
// Simple void foo(), where the incoming T is the result type.
@@ -1855,9 +1855,11 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
llvm::SmallVector<QualType, 4> Exceptions;
- if (FTI.hasExceptionSpec) {
- EPI.HasExceptionSpec = FTI.hasExceptionSpec;
- EPI.HasAnyExceptionSpec = FTI.hasAnyExceptionSpec;
+ if (FTI.getExceptionSpecType() == EST_Dynamic ||
+ FTI.getExceptionSpecType() == EST_DynamicAny) {
+ EPI.HasExceptionSpec = true;
+ EPI.HasAnyExceptionSpec =
+ FTI.getExceptionSpecType() == EST_DynamicAny;
Exceptions.reserve(FTI.NumExceptions);
for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
// FIXME: Preserve type source info.