summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse')
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp94
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp54
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp103
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp6
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp17
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp181
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/Parse/Parser.cpp28
8 files changed, 339 insertions, 147 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
index c000f69..f04d767 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -59,7 +59,7 @@ Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
}
}
- HandleMemberFunctionDefaultArgs(D, FnD);
+ HandleMemberFunctionDeclDelays(D, FnD);
D.complete(FnD);
@@ -348,6 +348,77 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
LM.DefaultArgs[I].Toks = 0;
}
}
+
+ // Parse a delayed exception-specification, if there is one.
+ if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
+ // Save the current token position.
+ SourceLocation origLoc = Tok.getLocation();
+
+ // Parse the default argument from its saved token stream.
+ Toks->push_back(Tok); // So that the current token doesn't get lost
+ PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
+
+ // Consume the previously-pushed token.
+ ConsumeAnyToken();
+
+ // C++11 [expr.prim.general]p3:
+ // If a declaration declares a member function or member function
+ // template of a class X, the expression this is a prvalue of type
+ // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
+ // and the end of the function-definition, member-declarator, or
+ // declarator.
+ CXXMethodDecl *Method;
+ if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(LM.Method))
+ Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ else
+ Method = cast<CXXMethodDecl>(LM.Method);
+
+ Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(),
+ Method->getTypeQualifiers(),
+ getLangOpts().CPlusPlus0x);
+
+ // Parse the exception-specification.
+ SourceRange SpecificationRange;
+ SmallVector<ParsedType, 4> DynamicExceptions;
+ SmallVector<SourceRange, 4> DynamicExceptionRanges;
+ ExprResult NoexceptExpr;
+ CachedTokens *ExceptionSpecTokens;
+
+ ExceptionSpecificationType EST
+ = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,
+ DynamicExceptions,
+ DynamicExceptionRanges, NoexceptExpr,
+ ExceptionSpecTokens);
+
+ // Clean up the remaining tokens.
+ if (Tok.is(tok::cxx_exceptspec_end))
+ ConsumeToken();
+ else if (EST != EST_None)
+ Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
+
+ // Attach the exception-specification to the method.
+ if (EST != EST_None)
+ Actions.actOnDelayedExceptionSpecification(LM.Method, EST,
+ SpecificationRange,
+ DynamicExceptions,
+ DynamicExceptionRanges,
+ NoexceptExpr.isUsable()?
+ NoexceptExpr.get() : 0);
+
+ assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
+ Tok.getLocation()) &&
+ "tryParseExceptionSpecification went over the exception tokens!");
+
+ // There could be leftover tokens (e.g. because of an error).
+ // Skip through until we reach the original token position.
+ while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
+ ConsumeAnyToken();
+
+ delete LM.ExceptionSpecTokens;
+ LM.ExceptionSpecTokens = 0;
+ }
+
PrototypeScope.Exit();
// Finish the delayed C++ method declaration.
@@ -447,9 +518,9 @@ void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
if (HasTemplateScope)
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
- // Set or update the scope flags to include Scope::ThisScope.
+ // Set or update the scope flags.
bool AlreadyHasClassScope = Class.TopLevelClass;
- unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope|Scope::ThisScope;
+ unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
@@ -457,10 +528,20 @@ void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
Class.TagOrTemplate);
- for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
- Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers();
+ {
+ // C++11 [expr.prim.general]p4:
+ // Otherwise, if a member-declarator declares a non-static data member
+ // (9.2) of a class X, the expression this is a prvalue of type "pointer
+ // to X" within the optional brace-or-equal-initializer. It shall not
+ // appear elsewhere in the member-declarator.
+ Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
+ /*TypeQuals=*/(unsigned)0);
+
+ for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
+ Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers();
+ }
}
-
+
if (!AlreadyHasClassScope)
Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
Class.TagOrTemplate);
@@ -481,6 +562,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
ConsumeAnyToken();
SourceLocation EqualLoc;
+
ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
EqualLoc);
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
index cf3dca2..932ffb4 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp
@@ -729,9 +729,9 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) {
if (HasTemplateScope)
Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
- // Set or update the scope flags to include Scope::ThisScope.
+ // Set or update the scope flags.
bool AlreadyHasClassScope = Class.TopLevelClass;
- unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope|Scope::ThisScope;
+ unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
@@ -739,11 +739,16 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) {
if (!AlreadyHasClassScope)
Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
Class.TagOrTemplate);
-
- for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i) {
- Class.LateParsedDeclarations[i]->ParseLexedAttributes();
+ {
+ // Allow 'this' within late-parsed attributes.
+ Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
+ /*TypeQuals=*/0);
+
+ for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
+ Class.LateParsedDeclarations[i]->ParseLexedAttributes();
+ }
}
-
+
if (!AlreadyHasClassScope)
Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
Class.TagOrTemplate);
@@ -756,6 +761,7 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
LAs[i]->addDecl(D);
ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
+ delete LAs[i];
}
LAs.clear();
}
@@ -958,7 +964,7 @@ void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
/// [C++] namespace-definition
/// [C++] using-directive
/// [C++] using-declaration
-/// [C++0x/C11] static_assert-declaration
+/// [C++11/C11] static_assert-declaration
/// others... [FIXME]
///
Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
@@ -4191,6 +4197,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
SmallVector<ParsedType, 2> DynamicExceptions;
SmallVector<SourceRange, 2> DynamicExceptionRanges;
ExprResult NoexceptExpr;
+ CachedTokens *ExceptionSpecTokens = 0;
ParsedAttributes FnAttrs(AttrFactory);
ParsedType TrailingReturnType;
@@ -4241,11 +4248,34 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
EndLoc = RefQualifierLoc;
}
+ // C++11 [expr.prim.general]p3:
+ // If a declaration declares a member function or member function
+ // template of a class X, the expression this is a prvalue of type
+ // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
+ // and the end of the function-definition, member-declarator, or
+ // declarator.
+ bool IsCXX11MemberFunction =
+ getLangOpts().CPlusPlus0x &&
+ (D.getContext() == Declarator::MemberContext ||
+ (D.getContext() == Declarator::FileContext &&
+ D.getCXXScopeSpec().isValid() &&
+ Actions.CurContext->isRecord()));
+ Sema::CXXThisScopeRAII ThisScope(Actions,
+ dyn_cast<CXXRecordDecl>(Actions.CurContext),
+ DS.getTypeQualifiers(),
+ IsCXX11MemberFunction);
+
// Parse exception-specification[opt].
- ESpecType = MaybeParseExceptionSpecification(ESpecRange,
- DynamicExceptions,
- DynamicExceptionRanges,
- NoexceptExpr);
+ bool Delayed = (D.getContext() == Declarator::MemberContext &&
+ D.getDeclSpec().getStorageClassSpec()
+ != DeclSpec::SCS_typedef &&
+ !D.getDeclSpec().isFriendSpecified());
+ ESpecType = tryParseExceptionSpecification(Delayed,
+ ESpecRange,
+ DynamicExceptions,
+ DynamicExceptionRanges,
+ NoexceptExpr,
+ ExceptionSpecTokens);
if (ESpecType != EST_None)
EndLoc = ESpecRange.getEnd();
@@ -4280,6 +4310,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
DynamicExceptions.size(),
NoexceptExpr.isUsable() ?
NoexceptExpr.get() : 0,
+ ExceptionSpecTokens,
Tracker.getOpenLocation(),
EndLoc, D,
TrailingReturnType),
@@ -4481,7 +4512,6 @@ void Parser::ParseParameterDeclarationClause(
// If we're inside a class definition, cache the tokens
// corresponding to the default argument. We'll actually parse
// them when we see the end of the class definition.
- // FIXME: Templates will require something similar.
// FIXME: Can we use a smart pointer for Toks?
DefArgToks = new CachedTokens;
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
index b2a65ff..b9b51d7 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1534,13 +1534,35 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const {
}
}
-void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
- Decl *ThisDecl) {
+/// \brief If the given declarator has any parts for which parsing has to be
+/// delayed, e.g., default arguments or an exception-specification, create a
+/// late-parsed method declaration record to handle the parsing at the end of
+/// the class definition.
+void Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
+ Decl *ThisDecl) {
// We just declared a member function. If this member function
- // has any default arguments, we'll need to parse them later.
+ // has any default arguments or an exception-specification, we'll need to
+ // parse them later.
LateParsedMethodDeclaration *LateMethod = 0;
DeclaratorChunk::FunctionTypeInfo &FTI
= DeclaratorInfo.getFunctionTypeInfo();
+
+ // If there was a delayed exception-specification, hold onto its tokens.
+ if (FTI.getExceptionSpecType() == EST_Delayed) {
+ // Push this method onto the stack of late-parsed method
+ // declarations.
+ LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
+ getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
+ LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
+
+ // Stash the exception-specification tokens in the late-pased mthod.
+ LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
+ FTI.ExceptionSpecTokens = 0;
+
+ // Reserve space for the parameters.
+ LateMethod->DefaultArgs.reserve(FTI.NumArgs);
+ }
+
for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
if (!LateMethod) {
@@ -1558,7 +1580,7 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
}
- // Add this parameter to the list of parameters (it or may
+ // Add this parameter to the list of parameters (it may or may
// not have a default argument).
LateMethod->DefaultArgs.push_back(
LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
@@ -1824,7 +1846,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Parse the first declarator.
ParseDeclarator(DeclaratorInfo);
- // Error parsing the declarator?
+ // Error parsin g the declarator?
if (!DeclaratorInfo.hasName()) {
// If so, skip until the semi-colon or a }.
SkipUntil(tok::r_brace, true, true);
@@ -2046,7 +2068,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (DeclaratorInfo.isFunctionDeclarator() &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef) {
- HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
+ HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
}
DeclaratorInfo.complete(ThisDecl);
@@ -2334,13 +2356,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
T.getCloseLocation(),
attrs.getList());
- // C++0x [class.mem]p2: Within the class member-specification, the class is
- // regarded as complete within function bodies, default arguments, exception-
- // specifications, and brace-or-equal-initializers for non-static data
- // members (including such things in nested classes).
- //
- // FIXME: Only function bodies and brace-or-equal-initializers are currently
- // handled. Fix the others!
+ // C++11 [class.mem]p2:
+ // Within the class member-specification, the class is regarded as complete
+ // within function bodies, default arguments, exception-specifications, and
+ // brace-or-equal-initializers for non-static data members (including such
+ // things in nested classes).
if (TagDecl && NonNestedClass) {
// We are not inside a nested class. This class and its nested classes
// are complete and we can parse the delayed portions of method
@@ -2535,12 +2555,63 @@ Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
/// 'noexcept'
/// 'noexcept' '(' constant-expression ')'
ExceptionSpecificationType
-Parser::MaybeParseExceptionSpecification(SourceRange &SpecificationRange,
+Parser::tryParseExceptionSpecification(bool Delayed,
+ SourceRange &SpecificationRange,
SmallVectorImpl<ParsedType> &DynamicExceptions,
SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
- ExprResult &NoexceptExpr) {
+ ExprResult &NoexceptExpr,
+ CachedTokens *&ExceptionSpecTokens) {
ExceptionSpecificationType Result = EST_None;
-
+ ExceptionSpecTokens = 0;
+
+ // Handle delayed parsing of exception-specifications.
+ if (Delayed) {
+ if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
+ return EST_None;
+
+ // Consume and cache the starting token.
+ bool IsNoexcept = Tok.is(tok::kw_noexcept);
+ Token StartTok = Tok;
+ SpecificationRange = SourceRange(ConsumeToken());
+
+ // Check for a '('.
+ if (!Tok.is(tok::l_paren)) {
+ // If this is a bare 'noexcept', we're done.
+ if (IsNoexcept) {
+ Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
+ NoexceptExpr = 0;
+ return EST_BasicNoexcept;
+ }
+
+ Diag(Tok, diag::err_expected_lparen_after) << "throw";
+ return EST_DynamicNone;
+ }
+
+ // Cache the tokens for the exception-specification.
+ ExceptionSpecTokens = new CachedTokens;
+ ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept'
+ ExceptionSpecTokens->push_back(Tok); // '('
+ SpecificationRange.setEnd(ConsumeParen()); // '('
+
+ if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
+ /*StopAtSemi=*/true,
+ /*ConsumeFinalToken=*/true)) {
+ NoexceptExpr = 0;
+ delete ExceptionSpecTokens;
+ ExceptionSpecTokens = 0;
+ return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone;
+ }
+ SpecificationRange.setEnd(Tok.getLocation());
+
+ // Add the 'stop' token.
+ Token End;
+ End.startToken();
+ End.setKind(tok::cxx_exceptspec_end);
+ End.setLocation(Tok.getLocation());
+ ExceptionSpecTokens->push_back(End);
+ return EST_Delayed;
+ }
+
// See if there's a dynamic specification.
if (Tok.is(tok::kw_throw)) {
Result = ParseDynamicExceptionSpecification(SpecificationRange,
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
index 7f3a815..b6a027b 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp
@@ -1926,11 +1926,9 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// unless they've already reported an error.
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
Diag(Tok, diag::ext_gnu_statement_expr);
-
Actions.ActOnStartStmtExpr();
- ParsedAttributes attrs(AttrFactory);
- StmtResult Stmt(ParseCompoundStatement(attrs, true));
+ StmtResult Stmt(ParseCompoundStatement(true));
ExprType = CompoundStmt;
// If the substmt parsed correctly, build the AST node.
@@ -2394,7 +2392,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
SourceLocation(),
EST_None,
SourceLocation(),
- 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
CaretLoc, CaretLoc,
ParamInfo),
attrs, CaretLoc);
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
index 2af7482..ae6ad0b 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp
@@ -780,10 +780,13 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
llvm::SmallVector<ParsedType, 2> DynamicExceptions;
llvm::SmallVector<SourceRange, 2> DynamicExceptionRanges;
ExprResult NoexceptExpr;
- ESpecType = MaybeParseExceptionSpecification(ESpecRange,
- DynamicExceptions,
- DynamicExceptionRanges,
- NoexceptExpr);
+ CachedTokens *ExceptionSpecTokens;
+ ESpecType = tryParseExceptionSpecification(/*Delayed=*/false,
+ ESpecRange,
+ DynamicExceptions,
+ DynamicExceptionRanges,
+ NoexceptExpr,
+ ExceptionSpecTokens);
if (ESpecType != EST_None)
DeclEndLoc = ESpecRange.getEnd();
@@ -818,6 +821,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
DynamicExceptions.size(),
NoexceptExpr.isUsable() ?
NoexceptExpr.get() : 0,
+ 0,
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);
@@ -863,6 +867,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
/*ExceptionRanges=*/0,
/*NumExceptions=*/0,
/*NoexceptExpr=*/0,
+ /*ExceptionSpecTokens=*/0,
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);
@@ -872,8 +877,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
// it.
unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope;
- if (getCurScope()->getFlags() & Scope::ThisScope)
- ScopeFlags |= Scope::ThisScope;
ParseScope BodyScope(this, ScopeFlags);
Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
@@ -1711,7 +1714,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// Form a parsed representation of the template-id to be stored in the
// UnqualifiedId.
TemplateIdAnnotation *TemplateId
- = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+ = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
if (Id.getKind() == UnqualifiedId::IK_Identifier) {
TemplateId->Name = Id.Identifier;
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
index fdb9788..44320df 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp
@@ -78,13 +78,30 @@ using namespace clang;
StmtResult
Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
SourceLocation *TrailingElseLoc) {
- const char *SemiError = 0;
- StmtResult Res;
ParenBraceBracketBalancer BalancerRAIIObj(*this);
- ParsedAttributesWithRange attrs(AttrFactory);
- MaybeParseCXX0XAttributes(attrs, 0, /*MightBeObjCMessageSend*/ true);
+ ParsedAttributesWithRange Attrs(AttrFactory);
+ MaybeParseCXX0XAttributes(Attrs, 0, /*MightBeObjCMessageSend*/ true);
+
+ StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts,
+ OnlyStatement, TrailingElseLoc, Attrs);
+
+ assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
+ "attributes on empty statement");
+
+ if (Attrs.empty() || Res.isInvalid())
+ return Res;
+
+ return Actions.ProcessStmtAttributes(Res.get(), Attrs.getList(), Attrs.Range);
+}
+
+StmtResult
+Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
+ bool OnlyStatement, SourceLocation *TrailingElseLoc,
+ ParsedAttributesWithRange &Attrs) {
+ const char *SemiError = 0;
+ StmtResult Res;
// Cases in this switch statement should fall through if the parser expects
// the token to end in a semicolon (in which case SemiError should be set),
@@ -95,6 +112,7 @@ Retry:
switch (Kind) {
case tok::at: // May be a @try or @throw statement
{
+ ProhibitAttributes(Attrs); // TODO: is it correct?
AtLoc = ConsumeToken(); // consume @
return ParseObjCAtStatement(AtLoc);
}
@@ -108,7 +126,7 @@ Retry:
Token Next = NextToken();
if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
// identifier ':' statement
- return ParseLabeledStatement(attrs);
+ return ParseLabeledStatement(Attrs);
}
if (Next.isNot(tok::coloncolon)) {
@@ -210,7 +228,7 @@ Retry:
if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
- DeclEnd, attrs);
+ DeclEnd, Attrs);
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
@@ -219,54 +237,54 @@ Retry:
return StmtError();
}
- return ParseExprStatement(attrs);
+ return ParseExprStatement();
}
case tok::kw_case: // C99 6.8.1: labeled-statement
- return ParseCaseStatement(attrs);
+ return ParseCaseStatement();
case tok::kw_default: // C99 6.8.1: labeled-statement
- return ParseDefaultStatement(attrs);
+ return ParseDefaultStatement();
case tok::l_brace: // C99 6.8.2: compound-statement
- return ParseCompoundStatement(attrs);
+ return ParseCompoundStatement();
case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
bool HasLeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
return Actions.ActOnNullStmt(ConsumeToken(), HasLeadingEmptyMacro);
}
case tok::kw_if: // C99 6.8.4.1: if-statement
- return ParseIfStatement(attrs, TrailingElseLoc);
+ return ParseIfStatement(TrailingElseLoc);
case tok::kw_switch: // C99 6.8.4.2: switch-statement
- return ParseSwitchStatement(attrs, TrailingElseLoc);
+ return ParseSwitchStatement(TrailingElseLoc);
case tok::kw_while: // C99 6.8.5.1: while-statement
- return ParseWhileStatement(attrs, TrailingElseLoc);
+ return ParseWhileStatement(TrailingElseLoc);
case tok::kw_do: // C99 6.8.5.2: do-statement
- Res = ParseDoStatement(attrs);
+ Res = ParseDoStatement();
SemiError = "do/while";
break;
case tok::kw_for: // C99 6.8.5.3: for-statement
- return ParseForStatement(attrs, TrailingElseLoc);
+ return ParseForStatement(TrailingElseLoc);
case tok::kw_goto: // C99 6.8.6.1: goto-statement
- Res = ParseGotoStatement(attrs);
+ Res = ParseGotoStatement();
SemiError = "goto";
break;
case tok::kw_continue: // C99 6.8.6.2: continue-statement
- Res = ParseContinueStatement(attrs);
+ Res = ParseContinueStatement();
SemiError = "continue";
break;
case tok::kw_break: // C99 6.8.6.3: break-statement
- Res = ParseBreakStatement(attrs);
+ Res = ParseBreakStatement();
SemiError = "break";
break;
case tok::kw_return: // C99 6.8.6.4: return-statement
- Res = ParseReturnStatement(attrs);
+ Res = ParseReturnStatement();
SemiError = "return";
break;
case tok::kw_asm: {
- ProhibitAttributes(attrs);
+ ProhibitAttributes(Attrs);
bool msAsm = false;
Res = ParseAsmStatement(msAsm);
Res = Actions.ActOnFinishFullStmt(Res.get());
@@ -276,16 +294,19 @@ Retry:
}
case tok::kw_try: // C++ 15: try-block
- return ParseCXXTryBlock(attrs);
+ return ParseCXXTryBlock();
case tok::kw___try:
- return ParseSEHTryBlock(attrs);
+ ProhibitAttributes(Attrs); // TODO: is it correct?
+ return ParseSEHTryBlock();
case tok::annot_pragma_vis:
+ ProhibitAttributes(Attrs);
HandlePragmaVisibility();
return StmtEmpty();
case tok::annot_pragma_pack:
+ ProhibitAttributes(Attrs);
HandlePragmaPack();
return StmtEmpty();
}
@@ -306,11 +327,10 @@ Retry:
}
/// \brief Parse an expression statement.
-StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) {
+StmtResult Parser::ParseExprStatement() {
// If a case keyword is missing, this is where it should be inserted.
Token OldToken = Tok;
- // FIXME: Use the attributes
// expression[opt] ';'
ExprResult Expr(ParseExpression());
if (Expr.isInvalid()) {
@@ -331,7 +351,7 @@ StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) {
<< FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
// Recover parsing as a case statement.
- return ParseCaseStatement(Attrs, /*MissingCase=*/true, Expr);
+ return ParseCaseStatement(/*MissingCase=*/true, Expr);
}
// Otherwise, eat the semicolon.
@@ -339,7 +359,7 @@ StmtResult Parser::ParseExprStatement(ParsedAttributes &Attrs) {
return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get()));
}
-StmtResult Parser::ParseSEHTryBlock(ParsedAttributes & Attrs) {
+StmtResult Parser::ParseSEHTryBlock() {
assert(Tok.is(tok::kw___try) && "Expected '__try'");
SourceLocation Loc = ConsumeToken();
return ParseSEHTryBlockCommon(Loc);
@@ -358,13 +378,12 @@ StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
if(Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok,diag::err_expected_lbrace));
- ParsedAttributesWithRange attrs(AttrFactory);
- StmtResult TryBlock(ParseCompoundStatement(attrs));
+ StmtResult TryBlock(ParseCompoundStatement());
if(TryBlock.isInvalid())
return move(TryBlock);
StmtResult Handler;
- if (Tok.is(tok::identifier) &&
+ if (Tok.is(tok::identifier) &&
Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
SourceLocation Loc = ConsumeToken();
Handler = ParseSEHExceptBlock(Loc);
@@ -418,8 +437,7 @@ StmtResult Parser::ParseSEHExceptBlock(SourceLocation ExceptLoc) {
if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen))
return StmtError();
- ParsedAttributesWithRange attrs(AttrFactory);
- StmtResult Block(ParseCompoundStatement(attrs));
+ StmtResult Block(ParseCompoundStatement());
if(Block.isInvalid())
return move(Block);
@@ -437,8 +455,7 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
raii2(Ident___abnormal_termination, false),
raii3(Ident_AbnormalTermination, false);
- ParsedAttributesWithRange attrs(AttrFactory);
- StmtResult Block(ParseCompoundStatement(attrs));
+ StmtResult Block(ParseCompoundStatement());
if(Block.isInvalid())
return move(Block);
@@ -451,7 +468,7 @@ StmtResult Parser::ParseSEHFinallyBlock(SourceLocation FinallyBlock) {
/// identifier ':' statement
/// [GNU] identifier ':' attributes[opt] statement
///
-StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
+StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
@@ -463,7 +480,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- // Read label attributes, if present.
+ // Read label attributes, if present. attrs will contain both C++11 and GNU
+ // attributes (if present) after this point.
MaybeParseGNUAttributes(attrs);
StmtResult SubStmt(ParseStatement());
@@ -474,8 +492,10 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
IdentTok.getLocation());
- if (AttributeList *Attrs = attrs.getList())
+ if (AttributeList *Attrs = attrs.getList()) {
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
+ attrs.clear();
+ }
return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
SubStmt.get());
@@ -486,10 +506,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
/// 'case' constant-expression ':' statement
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
///
-StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs, bool MissingCase,
- ExprResult Expr) {
+StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
- // FIXME: Use attributes?
// It is very very common for code to contain many case statements recursively
// nested, as in (but usually without indentation):
@@ -625,9 +643,7 @@ StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs, bool MissingCase,
/// 'default' ':' statement
/// Note that this does not parse the 'statement' at the end.
///
-StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
- //FIXME: Use attributes?
-
+StmtResult Parser::ParseDefaultStatement() {
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
@@ -668,9 +684,8 @@ StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
SubStmt.get(), getCurScope());
}
-StmtResult Parser::ParseCompoundStatement(ParsedAttributes &Attr,
- bool isStmtExpr) {
- return ParseCompoundStatement(Attr, isStmtExpr, Scope::DeclScope);
+StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
+ return ParseCompoundStatement(isStmtExpr, Scope::DeclScope);
}
/// ParseCompoundStatement - Parse a "{}" block.
@@ -700,11 +715,8 @@ StmtResult Parser::ParseCompoundStatement(ParsedAttributes &Attr,
/// [OMP] barrier-directive
/// [OMP] flush-directive
///
-StmtResult Parser::ParseCompoundStatement(ParsedAttributes &attrs,
- bool isStmtExpr,
+StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
unsigned ScopeFlags) {
- //FIXME: Use attributes?
-
assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
// Enter a scope to hold everything within the compound stmt. Compound
@@ -894,10 +906,7 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
/// [C++] 'if' '(' condition ')' statement
/// [C++] 'if' '(' condition ')' statement 'else' statement
///
-StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs,
- SourceLocation *TrailingElseLoc) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
SourceLocation IfLoc = ConsumeToken(); // eat the 'if'.
@@ -1028,10 +1037,7 @@ StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs,
/// switch-statement:
/// 'switch' '(' expression ')' statement
/// [C++] 'switch' '(' condition ')' statement
-StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs,
- SourceLocation *TrailingElseLoc) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseSwitchStatement(SourceLocation *TrailingElseLoc) {
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
SourceLocation SwitchLoc = ConsumeToken(); // eat the 'switch'.
@@ -1119,10 +1125,7 @@ StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs,
/// while-statement: [C99 6.8.5.1]
/// 'while' '(' expression ')' statement
/// [C++] 'while' '(' condition ')' statement
-StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs,
- SourceLocation *TrailingElseLoc) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
assert(Tok.is(tok::kw_while) && "Not a while stmt!");
SourceLocation WhileLoc = Tok.getLocation();
ConsumeToken(); // eat the 'while'.
@@ -1194,9 +1197,7 @@ StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs,
/// do-statement: [C99 6.8.5.2]
/// 'do' statement 'while' '(' expression ')' ';'
/// Note: this lets the caller parse the end ';'.
-StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseDoStatement() {
assert(Tok.is(tok::kw_do) && "Not a do stmt!");
SourceLocation DoLoc = ConsumeToken(); // eat the 'do'.
@@ -1277,10 +1278,7 @@ StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) {
/// [C++0x] for-range-initializer:
/// [C++0x] expression
/// [C++0x] braced-init-list [TODO]
-StmtResult Parser::ParseForStatement(ParsedAttributes &attrs,
- SourceLocation *TrailingElseLoc) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
SourceLocation ForLoc = ConsumeToken(); // eat the 'for'.
@@ -1535,9 +1533,7 @@ StmtResult Parser::ParseForStatement(ParsedAttributes &attrs,
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseGotoStatement() {
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'.
@@ -1571,9 +1567,7 @@ StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) {
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseContinueStatement() {
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
return Actions.ActOnContinueStmt(ContinueLoc, getCurScope());
}
@@ -1584,9 +1578,7 @@ StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) {
///
/// Note: this lets the caller parse the end ';'.
///
-StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseBreakStatement() {
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
return Actions.ActOnBreakStmt(BreakLoc, getCurScope());
}
@@ -1594,9 +1586,7 @@ StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) {
/// ParseReturnStatement
/// jump-statement:
/// 'return' expression[opt] ';'
-StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) {
- // FIXME: Use attributes?
-
+StmtResult Parser::ParseReturnStatement() {
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'.
@@ -2043,9 +2033,7 @@ bool Parser::trySkippingFunctionBody() {
/// try-block:
/// 'try' compound-statement handler-seq
///
-StmtResult Parser::ParseCXXTryBlock(ParsedAttributes &attrs) {
- // FIXME: Add attributes?
-
+StmtResult Parser::ParseCXXTryBlock() {
assert(Tok.is(tok::kw_try) && "Expected 'try'");
SourceLocation TryLoc = ConsumeToken();
@@ -2072,17 +2060,17 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
if (Tok.isNot(tok::l_brace))
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- ParsedAttributesWithRange attrs(AttrFactory);
- StmtResult TryBlock(ParseCompoundStatement(attrs, /*isStmtExpr=*/false,
+
+ StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
Scope::DeclScope|Scope::TryScope));
if (TryBlock.isInvalid())
return move(TryBlock);
// Borland allows SEH-handlers with 'try'
- if((Tok.is(tok::identifier) &&
- Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
- Tok.is(tok::kw___finally)) {
+ if ((Tok.is(tok::identifier) &&
+ Tok.getIdentifierInfo() == getSEHExceptKeyword()) ||
+ Tok.is(tok::kw___finally)) {
// TODO: Factor into common return ParseSEHHandlerCommon(...)
StmtResult Handler;
if(Tok.getIdentifierInfo() == getSEHExceptKeyword()) {
@@ -2103,6 +2091,7 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
}
else {
StmtVector Handlers(Actions);
+ ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
ProhibitAttributes(attrs);
@@ -2168,8 +2157,7 @@ StmtResult Parser::ParseCXXCatchBlock() {
return StmtError(Diag(Tok, diag::err_expected_lbrace));
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
- ParsedAttributes attrs(AttrFactory);
- StmtResult Block(ParseCompoundStatement(attrs));
+ StmtResult Block(ParseCompoundStatement());
if (Block.isInvalid())
return move(Block);
@@ -2188,24 +2176,23 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
if (Result.Behavior == IEB_Dependent) {
if (!Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace);
- return;
+ return;
}
-
- ParsedAttributes Attrs(AttrFactory);
- StmtResult Compound = ParseCompoundStatement(Attrs);
+
+ StmtResult Compound = ParseCompoundStatement();
if (Compound.isInvalid())
return;
-
+
StmtResult DepResult = Actions.ActOnMSDependentExistsStmt(Result.KeywordLoc,
Result.IsIfExists,
- Result.SS,
+ Result.SS,
Result.Name,
Compound.get());
if (DepResult.isUsable())
Stmts.push_back(DepResult.get());
return;
}
-
+
BalancedDelimiterTracker Braces(*this, tok::l_brace);
if (Braces.consumeOpen()) {
Diag(Tok, diag::err_expected_lbrace);
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
index 61cd9f2..5c3e2ba 100644
--- a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp
@@ -652,6 +652,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
// end of the template-parameter-list rather than a greater-than
// operator.
GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+ EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
DefaultArg = ParseAssignmentExpression();
if (DefaultArg.isInvalid())
@@ -838,7 +839,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
// later.
Tok.setKind(tok::annot_template_id);
TemplateIdAnnotation *TemplateId
- = TemplateIdAnnotation::Allocate(TemplateArgs.size());
+ = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
TemplateId->TemplateNameLoc = TemplateNameLoc;
if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
TemplateId->Name = TemplateName.Identifier;
diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
index 054a8fd..f1b99fb 100644
--- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
+++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp
@@ -397,6 +397,8 @@ Parser::~Parser() {
PP.RemovePragmaHandler("STDC", FPContractHandler.get());
FPContractHandler.reset();
PP.clearCodeCompletionHandler();
+
+ assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?");
}
/// Initialize - Warm up the parser.
@@ -470,10 +472,30 @@ void Parser::Initialize() {
}
}
+namespace {
+ /// \brief RAIIObject to destroy the contents of a SmallVector of
+ /// TemplateIdAnnotation pointers and clear the vector.
+ class DestroyTemplateIdAnnotationsRAIIObj {
+ SmallVectorImpl<TemplateIdAnnotation *> &Container;
+ public:
+ DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *>
+ &Container)
+ : Container(Container) {}
+
+ ~DestroyTemplateIdAnnotationsRAIIObj() {
+ for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I =
+ Container.begin(), E = Container.end();
+ I != E; ++I)
+ (*I)->Destroy();
+ Container.clear();
+ }
+ };
+}
+
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
/// action tells us to. This returns true if the EOF was encountered.
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
- DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
// Skip over the EOF token, flagging end of previous input for incremental
// processing
@@ -543,7 +565,7 @@ void Parser::ParseTranslationUnit() {
Parser::DeclGroupPtrTy
Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS) {
- DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
+ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
ParenBraceBracketBalancer BalancerRAIIObj(*this);
if (PP.isCodeCompletionReached()) {
@@ -1201,8 +1223,6 @@ TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
assert(tok.is(tok::annot_template_id) && "Expected template-id token");
TemplateIdAnnotation *
Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue());
- TopLevelDeclCleanupPool.delayMemberFunc< TemplateIdAnnotation,
- &TemplateIdAnnotation::Destroy>(Id);
return Id;
}
OpenPOWER on IntegriCloud