summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/DeclSpec.cpp9
-rw-r--r--clang/lib/Parse/ParseDecl.cpp42
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp12
-rw-r--r--clang/lib/Parse/ParseExpr.cpp2
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);
OpenPOWER on IntegriCloud