Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -2019,6 +2019,10 @@ /// limited representation in the AST. SourceRange getReturnTypeSourceRange() const; + /// \brief Attempt to compute an informative source range covering the + /// function exception specification, if any. + SourceRange getExceptionSpecSourceRange() const; + /// \brief Determine the type of an expression that calls this function. QualType getCallResultType() const { assert(getType()->getAs() && "Expected a FunctionType!"); Index: include/clang/AST/TypeLoc.h =================================================================== --- include/clang/AST/TypeLoc.h +++ include/clang/AST/TypeLoc.h @@ -1248,6 +1248,7 @@ SourceLocation LocalRangeBegin; SourceLocation LParenLoc; SourceLocation RParenLoc; + SourceRange ExceptionSpecRange; SourceLocation LocalRangeEnd; }; @@ -1289,6 +1290,13 @@ return SourceRange(getLParenLoc(), getRParenLoc()); } + SourceRange getExceptionSpecRange() const { + return this->getLocalData()->ExceptionSpecRange; + } + void setExceptionSpecRange(SourceRange R) { + this->getLocalData()->ExceptionSpecRange = R; + } + ArrayRef getParams() const { return llvm::makeArrayRef(getParmArray(), getNumParams()); } @@ -1318,6 +1326,7 @@ setLocalRangeBegin(Loc); setLParenLoc(Loc); setRParenLoc(Loc); + setExceptionSpecRange(SourceRange(Loc)); setLocalRangeEnd(Loc); for (unsigned i = 0, e = getNumParams(); i != e; ++i) setParam(i, nullptr); Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2935,6 +2935,18 @@ return RTRange; } +SourceRange FunctionDecl::getExceptionSpecSourceRange() const { + const TypeSourceInfo *TSI = getTypeSourceInfo(); + if (!TSI) + return SourceRange(); + FunctionTypeLoc FTL = + TSI->getTypeLoc().IgnoreParens().getAs(); + if (!FTL) + return SourceRange(); + + return FTL.getExceptionSpecRange(); +} + const Attr *FunctionDecl::getUnusedResultAttr() const { QualType RetType = getReturnType(); if (RetType->isRecordType()) { Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -5065,7 +5065,7 @@ ParmVarDecl *Param = cast(FTI.Params[i].Param); TL.setParam(tpi++, Param); } - // FIXME: exception specs + TL.setExceptionSpecRange(FTI.getExceptionSpecRange()); } void VisitParenTypeLoc(ParenTypeLoc TL) { assert(Chunk.Kind == DeclaratorChunk::Paren); Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -4919,6 +4919,7 @@ NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); NewTL.setLParenLoc(TL.getLParenLoc()); NewTL.setRParenLoc(TL.getRParenLoc()); + NewTL.setExceptionSpecRange(TL.getExceptionSpecRange()); NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i) NewTL.setParam(i, ParamDecls[i]); Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -5812,6 +5812,8 @@ TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx)); TL.setLParenLoc(ReadSourceLocation(Record, Idx)); TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setExceptionSpecRange(SourceRange(ReadSourceLocation(Record, Idx), + ReadSourceLocation(Record, Idx))); TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx)); for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) { TL.setParam(i, ReadDeclAs(Record, Idx)); Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -572,6 +572,7 @@ Record.AddSourceLocation(TL.getLocalRangeBegin()); Record.AddSourceLocation(TL.getLParenLoc()); Record.AddSourceLocation(TL.getRParenLoc()); + Record.AddSourceRange(TL.getExceptionSpecRange()); Record.AddSourceLocation(TL.getLocalRangeEnd()); for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) Record.AddDeclRef(TL.getParam(i));