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.
|
/// The qualifier bitmask values are the same as in QualType.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
|
|
||||||
/// hasExceptionSpec - True if the function has an exception specification.
|
/// ExceptionSpecType - An ExceptionSpecificationType value.
|
||||||
unsigned hasExceptionSpec : 1;
|
unsigned ExceptionSpecType : 3;
|
||||||
|
|
||||||
/// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
|
|
||||||
unsigned hasAnyExceptionSpec : 1;
|
|
||||||
|
|
||||||
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
|
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
|
||||||
unsigned DeleteArgInfo : 1;
|
unsigned DeleteArgInfo : 1;
|
||||||
|
@ -1044,28 +1041,34 @@ struct DeclaratorChunk {
|
||||||
/// declarator.
|
/// declarator.
|
||||||
unsigned NumArgs;
|
unsigned NumArgs;
|
||||||
|
|
||||||
/// NumExceptions - This is the number of types in the exception-decl, if
|
/// NumExceptions - This is the number of types in the dynamic-exception-
|
||||||
/// the function has one.
|
/// decl, if the function has one.
|
||||||
unsigned NumExceptions;
|
unsigned NumExceptions;
|
||||||
|
|
||||||
/// \brief The location of the ref-qualifier, if any.
|
/// \brief The location of the ref-qualifier, if any.
|
||||||
///
|
///
|
||||||
/// If this is an invalid location, there is no ref-qualifier.
|
/// If this is an invalid location, there is no ref-qualifier.
|
||||||
unsigned RefQualifierLoc;
|
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.
|
/// keyword introducing the spec.
|
||||||
unsigned ThrowLoc;
|
unsigned ExceptionSpecLoc;
|
||||||
|
|
||||||
/// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
|
/// 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
|
/// describe the arguments for this function declarator. This is null if
|
||||||
/// there are no arguments specified.
|
/// there are no arguments specified.
|
||||||
ParamInfo *ArgInfo;
|
ParamInfo *ArgInfo;
|
||||||
|
|
||||||
/// Exceptions - This is a pointer to a new[]'d array of TypeAndRange
|
union {
|
||||||
/// objects that contain the types in the function's exception
|
/// \brief Pointer to a new[]'d array of TypeAndRange objects that
|
||||||
/// specification and their locations.
|
/// contain the types in the function's dynamic exception specification
|
||||||
TypeAndRange *Exceptions;
|
/// 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
|
/// TrailingReturnType - If this isn't null, it's the trailing return type
|
||||||
/// specified. This is actually a ParsedType, but stored as void* to
|
/// specified. This is actually a ParsedType, but stored as void* to
|
||||||
|
@ -1085,7 +1088,8 @@ struct DeclaratorChunk {
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (DeleteArgInfo)
|
if (DeleteArgInfo)
|
||||||
delete[] ArgInfo;
|
delete[] ArgInfo;
|
||||||
delete[] Exceptions;
|
if (getExceptionSpecType() == EST_Dynamic)
|
||||||
|
delete[] Exceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isKNRPrototype - Return true if this is a K&R style identifier list,
|
/// isKNRPrototype - Return true if this is a K&R style identifier list,
|
||||||
|
@ -1098,18 +1102,23 @@ struct DeclaratorChunk {
|
||||||
SourceLocation getEllipsisLoc() const {
|
SourceLocation getEllipsisLoc() const {
|
||||||
return SourceLocation::getFromRawEncoding(EllipsisLoc);
|
return SourceLocation::getFromRawEncoding(EllipsisLoc);
|
||||||
}
|
}
|
||||||
SourceLocation getThrowLoc() const {
|
SourceLocation getExceptionSpecLoc() const {
|
||||||
return SourceLocation::getFromRawEncoding(ThrowLoc);
|
return SourceLocation::getFromRawEncoding(ExceptionSpecLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Retrieve the location of the ref-qualifier, if any.
|
/// \brief Retrieve the location of the ref-qualifier, if any.
|
||||||
SourceLocation getRefQualifierLoc() const {
|
SourceLocation getRefQualifierLoc() const {
|
||||||
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
|
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this function declaration contains a
|
/// \brief Determine whether this function declaration contains a
|
||||||
/// ref-qualifier.
|
/// ref-qualifier.
|
||||||
bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
|
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 {
|
struct BlockPointerTypeInfo : TypeInfoCommon {
|
||||||
|
@ -1233,15 +1242,16 @@ struct DeclaratorChunk {
|
||||||
unsigned TypeQuals,
|
unsigned TypeQuals,
|
||||||
bool RefQualifierIsLvalueRef,
|
bool RefQualifierIsLvalueRef,
|
||||||
SourceLocation RefQualifierLoc,
|
SourceLocation RefQualifierLoc,
|
||||||
bool hasExceptionSpec,
|
ExceptionSpecificationType ESpecType,
|
||||||
SourceLocation ThrowLoc,
|
SourceLocation ESpecLoc,
|
||||||
bool hasAnyExceptionSpec,
|
|
||||||
ParsedType *Exceptions,
|
ParsedType *Exceptions,
|
||||||
SourceRange *ExceptionRanges,
|
SourceRange *ExceptionRanges,
|
||||||
unsigned NumExceptions,
|
unsigned NumExceptions,
|
||||||
|
Expr *NoexceptExpr,
|
||||||
SourceLocation LPLoc, SourceLocation RPLoc,
|
SourceLocation LPLoc, SourceLocation RPLoc,
|
||||||
Declarator &TheDeclarator,
|
Declarator &TheDeclarator,
|
||||||
ParsedType TrailingReturnType = ParsedType());
|
ParsedType TrailingReturnType =
|
||||||
|
ParsedType());
|
||||||
|
|
||||||
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
||||||
///
|
///
|
||||||
|
|
|
@ -3197,13 +3197,12 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
DS.getTypeQualifiers(),
|
DS.getTypeQualifiers(),
|
||||||
RefQualifierIsLValueRef,
|
RefQualifierIsLValueRef,
|
||||||
RefQualifierLoc,
|
RefQualifierLoc,
|
||||||
ESpecType == EST_Dynamic ||
|
ESpecType, ESpecRange.getBegin(),
|
||||||
ESpecType == EST_DynamicAny,
|
|
||||||
ESpecRange.getBegin(),
|
|
||||||
ESpecType == EST_DynamicAny,
|
|
||||||
DynamicExceptions.data(),
|
DynamicExceptions.data(),
|
||||||
DynamicExceptionRanges.data(),
|
DynamicExceptionRanges.data(),
|
||||||
DynamicExceptions.size(),
|
DynamicExceptions.size(),
|
||||||
|
NoexceptExpr.isUsable() ?
|
||||||
|
NoexceptExpr.get() : 0,
|
||||||
LParenLoc, RParenLoc, D,
|
LParenLoc, RParenLoc, D,
|
||||||
TrailingReturnType),
|
TrailingReturnType),
|
||||||
EndLoc);
|
EndLoc);
|
||||||
|
@ -3453,13 +3452,12 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
DS.getTypeQualifiers(),
|
DS.getTypeQualifiers(),
|
||||||
RefQualifierIsLValueRef,
|
RefQualifierIsLValueRef,
|
||||||
RefQualifierLoc,
|
RefQualifierLoc,
|
||||||
ESpecType == EST_Dynamic ||
|
ESpecType, ESpecRange.getBegin(),
|
||||||
ESpecType == EST_DynamicAny,
|
|
||||||
ESpecRange.getBegin(),
|
|
||||||
ESpecType == EST_DynamicAny,
|
|
||||||
DynamicExceptions.data(),
|
DynamicExceptions.data(),
|
||||||
DynamicExceptionRanges.data(),
|
DynamicExceptionRanges.data(),
|
||||||
DynamicExceptions.size(),
|
DynamicExceptions.size(),
|
||||||
|
NoexceptExpr.isUsable() ?
|
||||||
|
NoexceptExpr.get() : 0,
|
||||||
LParenLoc, RParenLoc, D,
|
LParenLoc, RParenLoc, D,
|
||||||
TrailingReturnType),
|
TrailingReturnType),
|
||||||
EndLoc);
|
EndLoc);
|
||||||
|
@ -3537,9 +3535,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
||||||
&ParamInfo[0], ParamInfo.size(),
|
&ParamInfo[0], ParamInfo.size(),
|
||||||
/*TypeQuals*/0,
|
/*TypeQuals*/0,
|
||||||
true, SourceLocation(),
|
true, SourceLocation(),
|
||||||
/*exception*/false,
|
EST_None, SourceLocation(), 0, 0,
|
||||||
SourceLocation(), false, 0, 0, 0,
|
0, 0, LParenLoc, RLoc, D),
|
||||||
LParenLoc, RLoc, D),
|
|
||||||
RLoc);
|
RLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1918,8 +1918,9 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
true, SourceLocation(),
|
true, SourceLocation(),
|
||||||
false, SourceLocation(),
|
EST_None,
|
||||||
false, 0, 0, 0,
|
SourceLocation(),
|
||||||
|
0, 0, 0, 0,
|
||||||
CaretLoc, CaretLoc,
|
CaretLoc, CaretLoc,
|
||||||
ParamInfo),
|
ParamInfo),
|
||||||
CaretLoc);
|
CaretLoc);
|
||||||
|
|
|
@ -142,35 +142,36 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
|
||||||
unsigned TypeQuals,
|
unsigned TypeQuals,
|
||||||
bool RefQualifierIsLvalueRef,
|
bool RefQualifierIsLvalueRef,
|
||||||
SourceLocation RefQualifierLoc,
|
SourceLocation RefQualifierLoc,
|
||||||
bool hasExceptionSpec,
|
ExceptionSpecificationType
|
||||||
SourceLocation ThrowLoc,
|
ESpecType,
|
||||||
bool hasAnyExceptionSpec,
|
SourceLocation ESpecLoc,
|
||||||
ParsedType *Exceptions,
|
ParsedType *Exceptions,
|
||||||
SourceRange *ExceptionRanges,
|
SourceRange *ExceptionRanges,
|
||||||
unsigned NumExceptions,
|
unsigned NumExceptions,
|
||||||
|
Expr *NoexceptExpr,
|
||||||
SourceLocation LPLoc,
|
SourceLocation LPLoc,
|
||||||
SourceLocation RPLoc,
|
SourceLocation RPLoc,
|
||||||
Declarator &TheDeclarator,
|
Declarator &TheDeclarator,
|
||||||
ParsedType TrailingReturnType) {
|
ParsedType TrailingReturnType) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = Function;
|
I.Kind = Function;
|
||||||
I.Loc = LPLoc;
|
I.Loc = LPLoc;
|
||||||
I.EndLoc = RPLoc;
|
I.EndLoc = RPLoc;
|
||||||
I.Fun.AttrList = attrs.getList();
|
I.Fun.AttrList = attrs.getList();
|
||||||
I.Fun.hasPrototype = hasProto;
|
I.Fun.hasPrototype = hasProto;
|
||||||
I.Fun.isVariadic = isVariadic;
|
I.Fun.isVariadic = isVariadic;
|
||||||
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
||||||
I.Fun.DeleteArgInfo = false;
|
I.Fun.DeleteArgInfo = false;
|
||||||
I.Fun.TypeQuals = TypeQuals;
|
I.Fun.TypeQuals = TypeQuals;
|
||||||
I.Fun.NumArgs = NumArgs;
|
I.Fun.NumArgs = NumArgs;
|
||||||
I.Fun.ArgInfo = 0;
|
I.Fun.ArgInfo = 0;
|
||||||
I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
|
I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
|
||||||
I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
|
I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
|
||||||
I.Fun.hasExceptionSpec = hasExceptionSpec;
|
I.Fun.ExceptionSpecType = ESpecType;
|
||||||
I.Fun.ThrowLoc = ThrowLoc.getRawEncoding();
|
I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding();
|
||||||
I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
|
I.Fun.NumExceptions = 0;
|
||||||
I.Fun.NumExceptions = NumExceptions;
|
I.Fun.Exceptions = 0;
|
||||||
I.Fun.Exceptions = 0;
|
I.Fun.NoexceptExpr = 0;
|
||||||
I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr();
|
I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr();
|
||||||
|
|
||||||
// new[] an argument array if needed.
|
// 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);
|
memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
|
||||||
}
|
}
|
||||||
// new[] an exception array if needed
|
|
||||||
if (NumExceptions) {
|
// Check what exception specification information we should actually store.
|
||||||
I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
|
switch (ESpecType) {
|
||||||
for (unsigned i = 0; i != NumExceptions; ++i) {
|
default: break; // By default, save nothing.
|
||||||
I.Fun.Exceptions[i].Ty = Exceptions[i];
|
case EST_Dynamic:
|
||||||
I.Fun.Exceptions[i].Range = ExceptionRanges[i];
|
// 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;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5758,8 +5758,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
||||||
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||||
false, false, SourceLocation(), 0,
|
false, false, SourceLocation(), 0,
|
||||||
0, 0, true, SourceLocation(),
|
0, 0, true, SourceLocation(),
|
||||||
false, SourceLocation(),
|
EST_None, SourceLocation(),
|
||||||
false, 0,0,0, Loc, Loc, D),
|
0, 0, 0, 0, Loc, Loc, D),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
D.SetIdentifier(&II, Loc);
|
D.SetIdentifier(&II, Loc);
|
||||||
|
|
||||||
|
|
|
@ -511,7 +511,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
|
||||||
/*args*/ 0, 0,
|
/*args*/ 0, 0,
|
||||||
/*type quals*/ 0,
|
/*type quals*/ 0,
|
||||||
/*ref-qualifier*/true, SourceLocation(),
|
/*ref-qualifier*/true, SourceLocation(),
|
||||||
/*EH*/ false, SourceLocation(), false, 0, 0, 0,
|
/*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0,
|
||||||
/*parens*/ loc, loc,
|
/*parens*/ loc, loc,
|
||||||
declarator));
|
declarator));
|
||||||
|
|
||||||
|
@ -1764,9 +1764,9 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
|
||||||
|
|
||||||
// Exception specs are not allowed in typedefs. Complain, but add it
|
// Exception specs are not allowed in typedefs. Complain, but add it
|
||||||
// anyway.
|
// anyway.
|
||||||
if (FTI.hasExceptionSpec &&
|
if (FTI.getExceptionSpecType() != EST_None &&
|
||||||
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
|
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) {
|
if (!FTI.NumArgs && !FTI.isVariadic && !getLangOptions().CPlusPlus) {
|
||||||
// Simple void foo(), where the incoming T is the result type.
|
// 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;
|
llvm::SmallVector<QualType, 4> Exceptions;
|
||||||
if (FTI.hasExceptionSpec) {
|
if (FTI.getExceptionSpecType() == EST_Dynamic ||
|
||||||
EPI.HasExceptionSpec = FTI.hasExceptionSpec;
|
FTI.getExceptionSpecType() == EST_DynamicAny) {
|
||||||
EPI.HasAnyExceptionSpec = FTI.hasAnyExceptionSpec;
|
EPI.HasExceptionSpec = true;
|
||||||
|
EPI.HasAnyExceptionSpec =
|
||||||
|
FTI.getExceptionSpecType() == EST_DynamicAny;
|
||||||
Exceptions.reserve(FTI.NumExceptions);
|
Exceptions.reserve(FTI.NumExceptions);
|
||||||
for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
|
for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
|
||||||
// FIXME: Preserve type source info.
|
// FIXME: Preserve type source info.
|
||||||
|
|
Loading…
Reference in New Issue