forked from OSchip/llvm-project
Propagate new-style exception spec information to Declarator.
llvm-svn: 127111
This commit is contained in:
parent
75e7a147ae
commit
802a45332a
|
@ -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,8 +1041,8 @@ 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.
|
||||
|
@ -1053,19 +1050,25 @@ struct DeclaratorChunk {
|
|||
/// 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,8 +1102,8 @@ 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.
|
||||
|
@ -1110,6 +1114,11 @@ struct DeclaratorChunk {
|
|||
/// \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.
|
||||
///
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue