diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 42 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 2 |
4 files changed, 40 insertions, 25 deletions
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 2a765d21248..f3ff0c63797 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -35,6 +35,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, bool hasExceptionSpec, bool hasAnyExceptionSpec, ActionBase::TypeTy **Exceptions, + SourceRange *ExceptionRanges, unsigned NumExceptions, SourceLocation Loc, Declarator &TheDeclarator) { @@ -72,9 +73,11 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, } // new[] an exception array if needed if (NumExceptions) { - I.Fun.Exceptions = new ActionBase::TypeTy*[NumExceptions]; - memcpy(I.Fun.Exceptions, Exceptions, - sizeof(ActionBase::TypeTy*)*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]; + } } return I; } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index b667014efc7..36ebec33b3b 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -27,15 +27,17 @@ using namespace clang; /// specifier-qualifier-list abstract-declarator[opt] /// /// Called type-id in C++. -Action::TypeResult Parser::ParseTypeName() { +Action::TypeResult Parser::ParseTypeName(SourceRange *Range) { // Parse the common declaration-specifiers piece. DeclSpec DS; ParseSpecifierQualifierList(DS); - + // Parse the abstract-declarator, if present. Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); ParseDeclarator(DeclaratorInfo); - + if (Range) + *Range = DeclaratorInfo.getSourceRange(); + if (DeclaratorInfo.isInvalidType()) return true; @@ -2273,9 +2275,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, 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; + llvm::SmallVector<TypeTy*, 2> Exceptions; + llvm::SmallVector<SourceRange, 2> ExceptionRanges; if (getLang().CPlusPlus) { ParseTypeQualifierListOpt(DS, false /*no attributes*/); if (!DS.getSourceRange().getEnd().isInvalid()) @@ -2284,7 +2285,10 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Parse exception-specification[opt]. if (Tok.is(tok::kw_throw)) { hasExceptionSpec = true; - ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec); + ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges, + hasAnyExceptionSpec); + assert(Exceptions.size() == ExceptionRanges.size() && + "Produced different number of exception types and ranges."); } } @@ -2297,14 +2301,14 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DS.getTypeQualifiers(), hasExceptionSpec, hasAnyExceptionSpec, - Exceptions.empty() ? 0 : - &Exceptions[0], + Exceptions.data(), + ExceptionRanges.data(), Exceptions.size(), LParenLoc, D), Loc); return; - } - + } + // Alternatively, this parameter list may be an identifier list form for a // K&R-style function: void foo(a,b,c) if (!getLang().CPlusPlus && Tok.is(tok::identifier)) { @@ -2445,9 +2449,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, 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; + llvm::SmallVector<TypeTy*, 2> Exceptions; + llvm::SmallVector<SourceRange, 2> ExceptionRanges; if (getLang().CPlusPlus) { // Parse cv-qualifier-seq[opt]. ParseTypeQualifierListOpt(DS, false /*no attributes*/); @@ -2457,7 +2460,10 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Parse exception-specification[opt]. if (Tok.is(tok::kw_throw)) { hasExceptionSpec = true; - ParseExceptionSpecification(Loc, Exceptions, hasAnyExceptionSpec); + ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges, + hasAnyExceptionSpec); + assert(Exceptions.size() == ExceptionRanges.size() && + "Produced different number of exception types and ranges."); } } @@ -2468,8 +2474,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, DS.getTypeQualifiers(), hasExceptionSpec, hasAnyExceptionSpec, - Exceptions.empty() ? 0 : - &Exceptions[0], + Exceptions.data(), + ExceptionRanges.data(), Exceptions.size(), LParenLoc, D), Loc); } @@ -2545,7 +2551,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, SourceLocation(), &ParamInfo[0], ParamInfo.size(), /*TypeQuals*/0, - /*exception*/false, false, 0, 0, + /*exception*/false, false, 0, 0, 0, LParenLoc, D), RLoc); } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 7cbd72bed4e..809dc10c3ab 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1191,7 +1191,10 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) { /// type-id-list ',' type-id /// bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, - std::vector<TypeTy*> &Exceptions, + llvm::SmallVector<TypeTy*, 2> + &Exceptions, + llvm::SmallVector<SourceRange, 2> + &Ranges, bool &hasAnyExceptionSpec) { assert(Tok.is(tok::kw_throw) && "expected throw"); @@ -1214,10 +1217,13 @@ bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, } // Parse the sequence of type-ids. + SourceRange Range; while (Tok.isNot(tok::r_paren)) { - TypeResult Res(ParseTypeName()); - if (!Res.isInvalid()) + TypeResult Res(ParseTypeName(&Range)); + if (!Res.isInvalid()) { Exceptions.push_back(Res.get()); + Ranges.push_back(Range); + } if (Tok.is(tok::comma)) ConsumeToken(); else diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 5c063868bb6..8b8d4e19249 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1481,7 +1481,7 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, SourceLocation(), 0, 0, 0, - false, false, 0, 0, + false, false, 0, 0, 0, CaretLoc, ParamInfo), CaretLoc); |