From f8b1205d19531ba656dec678ed3c622e61d3ef5d Mon Sep 17 00:00:00 2001 From: Paul Russo Date: Thu, 15 Nov 2012 20:19:21 +0000 Subject: [PATCH] Use the DestroyTemplateIdAnnotationsRAIIObj to cleanup template ids after a parse. git-svn-id: http://root.cern.ch/svn/root/trunk@47335 27541ba8-7e3a-0410-8455-c3a389f83636 --- lib/Interpreter/LookupHelper.cpp | 5 +- patches/cleanup_template_ids.diff | 710 ++++++++++++++++++++++++++++++ 2 files changed, 714 insertions(+), 1 deletion(-) create mode 100644 patches/cleanup_template_ids.diff diff --git a/lib/Interpreter/LookupHelper.cpp b/lib/Interpreter/LookupHelper.cpp index 72085876..6e9bbf87 100644 --- a/lib/Interpreter/LookupHelper.cpp +++ b/lib/Interpreter/LookupHelper.cpp @@ -8,6 +8,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Parse/Parser.h" +#include "clang/Parse/RAIIObjectsForParser.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Overload.h" @@ -35,13 +36,15 @@ namespace cling { bool ResetIncrementalProcessing; bool OldSuppressAllDiagnostics; bool OldSpellChecking; + DestroyTemplateIdAnnotationsRAIIObj CleanupTemplateIds; public: ParserStateRAII(Parser* p, bool rip, bool sad, bool sc) : P(p), PP(P->getPreprocessor()), DClient(P->getActions().getDiagnostics().getClient()), ResetIncrementalProcessing(rip), - OldSuppressAllDiagnostics(sad), OldSpellChecking(sc) + OldSuppressAllDiagnostics(sad), OldSpellChecking(sc), + CleanupTemplateIds(*p) {} ~ParserStateRAII() diff --git a/patches/cleanup_template_ids.diff b/patches/cleanup_template_ids.diff new file mode 100644 index 00000000..6e142673 --- /dev/null +++ b/patches/cleanup_template_ids.diff @@ -0,0 +1,710 @@ +Index: tools/clang/include/clang/Parse/Parser.h +=================================================================== +--- tools/clang/include/clang/Parse/Parser.h (revision 47334) ++++ tools/clang/include/clang/Parse/Parser.h (working copy) +@@ -43,6 +43,7 @@ + class InMessageExpressionRAIIObject; + class PoisonSEHIdentifiersRAIIObject; + class VersionTuple; ++ class DestroyTemplateIdAnnotationsRAIIObj; + + /// PrettyStackTraceParserEntry - If a crash happens while the parser is active, + /// an entry is printed for it. +@@ -89,6 +90,7 @@ + friend class ObjCDeclContextSwitch; + friend class ParenBraceBracketBalancer; + friend class BalancedDelimiterTracker; ++ friend class DestroyTemplateIdAnnotationsRAIIObj; + + Preprocessor &PP; + +Index: tools/clang/include/clang/Parse/RAIIObjectsForParser.h +=================================================================== +--- tools/clang/include/clang/Parse/RAIIObjectsForParser.h (revision 0) ++++ tools/clang/include/clang/Parse/RAIIObjectsForParser.h (working copy) +@@ -0,0 +1,452 @@ ++//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- C++ -*-===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++// ++// This file defines and implements the some simple RAII objects that are used ++// by the parser to manage bits in recursion. ++// ++//===----------------------------------------------------------------------===// ++ ++#ifndef LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H ++#define LLVM_CLANG_PARSE_RAII_OBJECTS_FOR_PARSER_H ++ ++#include "clang/Parse/ParseDiagnostic.h" ++#include "clang/Parse/Parser.h" ++#include "clang/Sema/DelayedDiagnostic.h" ++#include "clang/Sema/ParsedTemplate.h" ++#include "clang/Sema/Sema.h" ++ ++namespace clang { ++ // TODO: move ParsingClassDefinition here. ++ // TODO: move TentativeParsingAction here. ++ ++ /// \brief A RAII object used to temporarily suppress access-like ++ /// checking. Access-like checks are those associated with ++ /// controlling the use of a declaration, like C++ access control ++ /// errors and deprecation warnings. They are contextually ++ /// dependent, in that they can only be resolved with full ++ /// information about what's being declared. They are also ++ /// suppressed in certain contexts, like the template arguments of ++ /// an explicit instantiation. However, those suppression contexts ++ /// cannot necessarily be fully determined in advance; for ++ /// example, something starting like this: ++ /// template <> class std::vector ++ /// might be the entirety of an explicit instantiation: ++ /// template <> class std::vector; ++ /// or just an elaborated type specifier: ++ /// template <> class std::vector make_vector<>(); ++ /// Therefore this class collects all the diagnostics and permits ++ /// them to be re-delayed in a new context. ++ class SuppressAccessChecks { ++ Sema &S; ++ sema::DelayedDiagnosticPool DiagnosticPool; ++ Sema::ParsingDeclState State; ++ bool Active; ++ ++ public: ++ /// Begin suppressing access-like checks ++ SuppressAccessChecks(Parser &P, bool activate = true) ++ : S(P.getActions()), DiagnosticPool(NULL) { ++ if (activate) { ++ State = S.PushParsingDeclaration(DiagnosticPool); ++ Active = true; ++ } else { ++ Active = false; ++ } ++ } ++ ++ void done() { ++ assert(Active && "trying to end an inactive suppression"); ++ S.PopParsingDeclaration(State, NULL); ++ Active = false; ++ } ++ ++ void redelay() { ++ assert(!Active && "redelaying without having ended first"); ++ if (!DiagnosticPool.pool_empty()) ++ S.redelayDiagnostics(DiagnosticPool); ++ assert(DiagnosticPool.pool_empty()); ++ } ++ ++ ~SuppressAccessChecks() { ++ if (Active) done(); ++ } ++ }; ++ ++ /// \brief RAII object used to inform the actions that we're ++ /// currently parsing a declaration. This is active when parsing a ++ /// variable's initializer, but not when parsing the body of a ++ /// class or function definition. ++ class ParsingDeclRAIIObject { ++ Sema &Actions; ++ sema::DelayedDiagnosticPool DiagnosticPool; ++ Sema::ParsingDeclState State; ++ bool Popped; ++ ++ ParsingDeclRAIIObject(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION; ++ void operator=(const ParsingDeclRAIIObject &) LLVM_DELETED_FUNCTION; ++ ++ public: ++ enum NoParent_t { NoParent }; ++ ParsingDeclRAIIObject(Parser &P, NoParent_t _) ++ : Actions(P.getActions()), DiagnosticPool(NULL) { ++ push(); ++ } ++ ++ /// Creates a RAII object whose pool is optionally parented by another. ++ ParsingDeclRAIIObject(Parser &P, ++ const sema::DelayedDiagnosticPool *parentPool) ++ : Actions(P.getActions()), DiagnosticPool(parentPool) { ++ push(); ++ } ++ ++ /// Creates a RAII object and, optionally, initialize its ++ /// diagnostics pool by stealing the diagnostics from another ++ /// RAII object (which is assumed to be the current top pool). ++ ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other) ++ : Actions(P.getActions()), ++ DiagnosticPool(other ? other->DiagnosticPool.getParent() : NULL) { ++ if (other) { ++ DiagnosticPool.steal(other->DiagnosticPool); ++ other->abort(); ++ } ++ push(); ++ } ++ ++ ~ParsingDeclRAIIObject() { ++ abort(); ++ } ++ ++ sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() { ++ return DiagnosticPool; ++ } ++ const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const { ++ return DiagnosticPool; ++ } ++ ++ /// Resets the RAII object for a new declaration. ++ void reset() { ++ abort(); ++ push(); ++ } ++ ++ /// Signals that the context was completed without an appropriate ++ /// declaration being parsed. ++ void abort() { ++ pop(0); ++ } ++ ++ void complete(Decl *D) { ++ assert(!Popped && "ParsingDeclaration has already been popped!"); ++ pop(D); ++ } ++ ++ /// Unregister this object from Sema, but remember all the ++ /// diagnostics that were emitted into it. ++ void abortAndRemember() { ++ pop(0); ++ } ++ ++ private: ++ void push() { ++ State = Actions.PushParsingDeclaration(DiagnosticPool); ++ Popped = false; ++ } ++ ++ void pop(Decl *D) { ++ if (!Popped) { ++ Actions.PopParsingDeclaration(State, D); ++ Popped = true; ++ } ++ } ++ }; ++ ++ /// A class for parsing a DeclSpec. ++ class ParsingDeclSpec : public DeclSpec { ++ ParsingDeclRAIIObject ParsingRAII; ++ ++ public: ++ ParsingDeclSpec(Parser &P) ++ : DeclSpec(P.getAttrFactory()), ++ ParsingRAII(P, ParsingDeclRAIIObject::NoParent) {} ++ ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII) ++ : DeclSpec(P.getAttrFactory()), ++ ParsingRAII(P, RAII) {} ++ ++ const sema::DelayedDiagnosticPool &getDelayedDiagnosticPool() const { ++ return ParsingRAII.getDelayedDiagnosticPool(); ++ } ++ ++ void complete(Decl *D) { ++ ParsingRAII.complete(D); ++ } ++ ++ void abort() { ++ ParsingRAII.abort(); ++ } ++ }; ++ ++ /// A class for parsing a declarator. ++ class ParsingDeclarator : public Declarator { ++ ParsingDeclRAIIObject ParsingRAII; ++ ++ public: ++ ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, TheContext C) ++ : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) { ++ } ++ ++ const ParsingDeclSpec &getDeclSpec() const { ++ return static_cast(Declarator::getDeclSpec()); ++ } ++ ++ ParsingDeclSpec &getMutableDeclSpec() const { ++ return const_cast(getDeclSpec()); ++ } ++ ++ void clear() { ++ Declarator::clear(); ++ ParsingRAII.reset(); ++ } ++ ++ void complete(Decl *D) { ++ ParsingRAII.complete(D); ++ } ++ }; ++ ++ /// A class for parsing a field declarator. ++ class ParsingFieldDeclarator : public FieldDeclarator { ++ ParsingDeclRAIIObject ParsingRAII; ++ ++ public: ++ ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS) ++ : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) { ++ } ++ ++ const ParsingDeclSpec &getDeclSpec() const { ++ return static_cast(D.getDeclSpec()); ++ } ++ ++ ParsingDeclSpec &getMutableDeclSpec() const { ++ return const_cast(getDeclSpec()); ++ } ++ ++ void complete(Decl *D) { ++ ParsingRAII.complete(D); ++ } ++ }; ++ ++ /// ExtensionRAIIObject - This saves the state of extension warnings when ++ /// constructed and disables them. When destructed, it restores them back to ++ /// the way they used to be. This is used to handle __extension__ in the ++ /// parser. ++ class ExtensionRAIIObject { ++ ExtensionRAIIObject(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION; ++ void operator=(const ExtensionRAIIObject &) LLVM_DELETED_FUNCTION; ++ ++ DiagnosticsEngine &Diags; ++ public: ++ ExtensionRAIIObject(DiagnosticsEngine &diags) : Diags(diags) { ++ Diags.IncrementAllExtensionsSilenced(); ++ } ++ ++ ~ExtensionRAIIObject() { ++ Diags.DecrementAllExtensionsSilenced(); ++ } ++ }; ++ ++ /// ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and ++ /// restores it when destroyed. This says that "foo:" should not be ++ /// considered a possible typo for "foo::" for error recovery purposes. ++ class ColonProtectionRAIIObject { ++ Parser &P; ++ bool OldVal; ++ public: ++ ColonProtectionRAIIObject(Parser &p, bool Value = true) ++ : P(p), OldVal(P.ColonIsSacred) { ++ P.ColonIsSacred = Value; ++ } ++ ++ /// restore - This can be used to restore the state early, before the dtor ++ /// is run. ++ void restore() { ++ P.ColonIsSacred = OldVal; ++ } ++ ++ ~ColonProtectionRAIIObject() { ++ restore(); ++ } ++ }; ++ ++ /// \brief RAII object that makes '>' behave either as an operator ++ /// or as the closing angle bracket for a template argument list. ++ class GreaterThanIsOperatorScope { ++ bool &GreaterThanIsOperator; ++ bool OldGreaterThanIsOperator; ++ public: ++ GreaterThanIsOperatorScope(bool >IO, bool Val) ++ : GreaterThanIsOperator(GTIO), OldGreaterThanIsOperator(GTIO) { ++ GreaterThanIsOperator = Val; ++ } ++ ++ ~GreaterThanIsOperatorScope() { ++ GreaterThanIsOperator = OldGreaterThanIsOperator; ++ } ++ }; ++ ++ class InMessageExpressionRAIIObject { ++ bool &InMessageExpression; ++ bool OldValue; ++ ++ public: ++ InMessageExpressionRAIIObject(Parser &P, bool Value) ++ : InMessageExpression(P.InMessageExpression), ++ OldValue(P.InMessageExpression) { ++ InMessageExpression = Value; ++ } ++ ++ ~InMessageExpressionRAIIObject() { ++ InMessageExpression = OldValue; ++ } ++ }; ++ ++ /// \brief RAII object that makes sure paren/bracket/brace count is correct ++ /// after declaration/statement parsing, even when there's a parsing error. ++ class ParenBraceBracketBalancer { ++ Parser &P; ++ unsigned short ParenCount, BracketCount, BraceCount; ++ public: ++ ParenBraceBracketBalancer(Parser &p) ++ : P(p), ParenCount(p.ParenCount), BracketCount(p.BracketCount), ++ BraceCount(p.BraceCount) { } ++ ++ ~ParenBraceBracketBalancer() { ++ P.ParenCount = ParenCount; ++ P.BracketCount = BracketCount; ++ P.BraceCount = BraceCount; ++ } ++ }; ++ ++ class PoisonSEHIdentifiersRAIIObject { ++ PoisonIdentifierRAIIObject Ident_AbnormalTermination; ++ PoisonIdentifierRAIIObject Ident_GetExceptionCode; ++ PoisonIdentifierRAIIObject Ident_GetExceptionInfo; ++ PoisonIdentifierRAIIObject Ident__abnormal_termination; ++ PoisonIdentifierRAIIObject Ident__exception_code; ++ PoisonIdentifierRAIIObject Ident__exception_info; ++ PoisonIdentifierRAIIObject Ident___abnormal_termination; ++ PoisonIdentifierRAIIObject Ident___exception_code; ++ PoisonIdentifierRAIIObject Ident___exception_info; ++ public: ++ PoisonSEHIdentifiersRAIIObject(Parser &Self, bool NewValue) ++ : Ident_AbnormalTermination(Self.Ident_AbnormalTermination, NewValue), ++ Ident_GetExceptionCode(Self.Ident_GetExceptionCode, NewValue), ++ Ident_GetExceptionInfo(Self.Ident_GetExceptionInfo, NewValue), ++ Ident__abnormal_termination(Self.Ident__abnormal_termination, NewValue), ++ Ident__exception_code(Self.Ident__exception_code, NewValue), ++ Ident__exception_info(Self.Ident__exception_info, NewValue), ++ Ident___abnormal_termination(Self.Ident___abnormal_termination, NewValue), ++ Ident___exception_code(Self.Ident___exception_code, NewValue), ++ Ident___exception_info(Self.Ident___exception_info, NewValue) { ++ } ++ }; ++ ++ /// \brief RAII class that helps handle the parsing of an open/close delimiter ++ /// pair, such as braces { ... } or parentheses ( ... ). ++ class BalancedDelimiterTracker : public GreaterThanIsOperatorScope { ++ Parser& P; ++ tok::TokenKind Kind, Close; ++ SourceLocation (Parser::*Consumer)(); ++ SourceLocation LOpen, LClose; ++ ++ unsigned short &getDepth() { ++ switch (Kind) { ++ case tok::l_brace: return P.BraceCount; ++ case tok::l_square: return P.BracketCount; ++ case tok::l_paren: return P.ParenCount; ++ default: llvm_unreachable("Wrong token kind"); ++ } ++ } ++ ++ enum { MaxDepth = 256 }; ++ ++ bool diagnoseOverflow(); ++ bool diagnoseMissingClose(); ++ ++ public: ++ BalancedDelimiterTracker(Parser& p, tok::TokenKind k) ++ : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true), ++ P(p), Kind(k) ++ { ++ switch (Kind) { ++ default: llvm_unreachable("Unexpected balanced token"); ++ case tok::l_brace: ++ Close = tok::r_brace; ++ Consumer = &Parser::ConsumeBrace; ++ break; ++ case tok::l_paren: ++ Close = tok::r_paren; ++ Consumer = &Parser::ConsumeParen; ++ break; ++ ++ case tok::l_square: ++ Close = tok::r_square; ++ Consumer = &Parser::ConsumeBracket; ++ break; ++ } ++ } ++ ++ SourceLocation getOpenLocation() const { return LOpen; } ++ SourceLocation getCloseLocation() const { return LClose; } ++ SourceRange getRange() const { return SourceRange(LOpen, LClose); } ++ ++ bool consumeOpen() { ++ if (!P.Tok.is(Kind)) ++ return true; ++ ++ if (getDepth() < MaxDepth) { ++ LOpen = (P.*Consumer)(); ++ return false; ++ } ++ ++ return diagnoseOverflow(); ++ } ++ ++ bool expectAndConsume(unsigned DiagID, ++ const char *Msg = "", ++ tok::TokenKind SkipToTok = tok::unknown); ++ bool consumeClose() { ++ if (P.Tok.is(Close)) { ++ LClose = (P.*Consumer)(); ++ return false; ++ } ++ ++ return diagnoseMissingClose(); ++ } ++ void skipToEnd(); ++ }; ++ ++ /// \brief RAIIObject to destroy the contents of a SmallVector of ++ /// TemplateIdAnnotation pointers and clear the vector. ++ class DestroyTemplateIdAnnotationsRAIIObj { ++ Parser &P; ++ public: ++ DestroyTemplateIdAnnotationsRAIIObj(Parser &p) ++ : P(p) {} ++ ++ ~DestroyTemplateIdAnnotationsRAIIObj() { ++ for (SmallVectorImpl::iterator I = ++ P.TemplateIds.begin(), E = P.TemplateIds.end(); ++ I != E; ++I) ++ (*I)->Destroy(); ++ P.TemplateIds.clear(); ++ } ++ }; ++ ++} // end namespace clang ++ ++#endif +Index: tools/clang/lib/Parse/ParseCXXInlineMethods.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseCXXInlineMethods.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseCXXInlineMethods.cpp (working copy) +@@ -13,10 +13,10 @@ + + #include "clang/Parse/ParseDiagnostic.h" + #include "clang/Parse/Parser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/Scope.h" + #include "clang/AST/DeclTemplate.h" +-#include "RAIIObjectsForParser.h" + using namespace clang; + + /// ParseCXXInlineMethodDef - We parsed and verified that the specified +Index: tools/clang/lib/Parse/ParseDecl.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseDecl.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseDecl.cpp (working copy) +@@ -13,12 +13,12 @@ + + #include "clang/Parse/Parser.h" + #include "clang/Parse/ParseDiagnostic.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Basic/OpenCL.h" + #include "clang/Sema/Lookup.h" + #include "clang/Sema/Scope.h" + #include "clang/Sema/ParsedTemplate.h" + #include "clang/Sema/PrettyDeclStackTrace.h" +-#include "RAIIObjectsForParser.h" + #include "llvm/ADT/SmallSet.h" + #include "llvm/ADT/SmallString.h" + #include "llvm/ADT/StringSwitch.h" +Index: tools/clang/lib/Parse/ParseDeclCXX.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseDeclCXX.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseDeclCXX.cpp (working copy) +@@ -14,13 +14,13 @@ + #include "clang/Basic/OperatorKinds.h" + #include "clang/Parse/Parser.h" + #include "clang/Parse/ParseDiagnostic.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/Scope.h" + #include "clang/Sema/ParsedTemplate.h" + #include "clang/Sema/PrettyDeclStackTrace.h" + #include "clang/Sema/SemaDiagnostic.h" + #include "llvm/ADT/SmallString.h" +-#include "RAIIObjectsForParser.h" + using namespace clang; + + /// ParseNamespace - We know that the current token is a namespace keyword. This +Index: tools/clang/lib/Parse/ParseExpr.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseExpr.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseExpr.cpp (working copy) +@@ -22,12 +22,12 @@ + //===----------------------------------------------------------------------===// + + #include "clang/Parse/Parser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/Scope.h" + #include "clang/Sema/ParsedTemplate.h" + #include "clang/Sema/TypoCorrection.h" + #include "clang/Basic/PrettyStackTrace.h" +-#include "RAIIObjectsForParser.h" + #include "llvm/ADT/SmallVector.h" + #include "llvm/ADT/SmallString.h" + using namespace clang; +Index: tools/clang/lib/Parse/ParseExprCXX.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseExprCXX.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseExprCXX.cpp (working copy) +@@ -13,7 +13,7 @@ + + #include "clang/Parse/ParseDiagnostic.h" + #include "clang/Parse/Parser.h" +-#include "RAIIObjectsForParser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Basic/PrettyStackTrace.h" + #include "clang/Lex/LiteralSupport.h" + #include "clang/Sema/DeclSpec.h" +Index: tools/clang/lib/Parse/ParseInit.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseInit.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseInit.cpp (working copy) +@@ -13,7 +13,7 @@ + + #include "clang/Parse/Parser.h" + #include "clang/Parse/ParseDiagnostic.h" +-#include "RAIIObjectsForParser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/Designator.h" + #include "clang/Sema/Scope.h" + #include "llvm/ADT/SmallString.h" +Index: tools/clang/lib/Parse/ParseObjc.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseObjc.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseObjc.cpp (working copy) +@@ -13,7 +13,7 @@ + + #include "clang/Parse/ParseDiagnostic.h" + #include "clang/Parse/Parser.h" +-#include "RAIIObjectsForParser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/PrettyDeclStackTrace.h" + #include "clang/Sema/Scope.h" +Index: tools/clang/lib/Parse/ParseStmt.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseStmt.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseStmt.cpp (working copy) +@@ -13,7 +13,7 @@ + //===----------------------------------------------------------------------===// + + #include "clang/Parse/Parser.h" +-#include "RAIIObjectsForParser.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/PrettyDeclStackTrace.h" + #include "clang/Sema/Scope.h" +Index: tools/clang/lib/Parse/ParseTemplate.cpp +=================================================================== +--- tools/clang/lib/Parse/ParseTemplate.cpp (revision 47334) ++++ tools/clang/lib/Parse/ParseTemplate.cpp (working copy) +@@ -13,10 +13,10 @@ + + #include "clang/Parse/Parser.h" + #include "clang/Parse/ParseDiagnostic.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/ParsedTemplate.h" + #include "clang/Sema/Scope.h" +-#include "RAIIObjectsForParser.h" + #include "clang/AST/DeclTemplate.h" + #include "clang/AST/ASTConsumer.h" + using namespace clang; +Index: tools/clang/lib/Parse/Parser.cpp +=================================================================== +--- tools/clang/lib/Parse/Parser.cpp (revision 47334) ++++ tools/clang/lib/Parse/Parser.cpp (working copy) +@@ -13,11 +13,11 @@ + + #include "clang/Parse/Parser.h" + #include "clang/Parse/ParseDiagnostic.h" ++#include "clang/Parse/RAIIObjectsForParser.h" + #include "clang/Sema/DeclSpec.h" + #include "clang/Sema/Scope.h" + #include "clang/Sema/ParsedTemplate.h" + #include "llvm/Support/raw_ostream.h" +-#include "RAIIObjectsForParser.h" + #include "ParsePragma.h" + #include "clang/AST/DeclTemplate.h" + #include "clang/AST/ASTConsumer.h" +@@ -546,30 +546,10 @@ + } + } + +-namespace { +- /// \brief RAIIObject to destroy the contents of a SmallVector of +- /// TemplateIdAnnotation pointers and clear the vector. +- class DestroyTemplateIdAnnotationsRAIIObj { +- SmallVectorImpl &Container; +- public: +- DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl +- &Container) +- : Container(Container) {} +- +- ~DestroyTemplateIdAnnotationsRAIIObj() { +- for (SmallVectorImpl::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) { +- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); ++ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); + + // Skip over the EOF token, flagging end of previous input for incremental + // processing +@@ -639,7 +619,7 @@ + Parser::DeclGroupPtrTy + Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, + ParsingDeclSpec *DS) { +- DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); ++ DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); + ParenBraceBracketBalancer BalancerRAIIObj(*this); + + if (PP.isCodeCompletionReached()) { +Index: tools/clang/lib/Parse/RAIIObjectsForParser.h +=================================================================== +--- tools/clang/lib/Parse/RAIIObjectsForParser.h (revision 47334) ++++ tools/clang/lib/Parse/RAIIObjectsForParser.h (working copy) +@@ -18,6 +18,7 @@ + #include "clang/Parse/ParseDiagnostic.h" + #include "clang/Parse/Parser.h" + #include "clang/Sema/DelayedDiagnostic.h" ++#include "clang/Sema/ParsedTemplate.h" + #include "clang/Sema/Sema.h" + + namespace clang { +@@ -429,6 +430,23 @@ + void skipToEnd(); + }; + ++ /// \brief RAIIObject to destroy the contents of a SmallVector of ++ /// TemplateIdAnnotation pointers and clear the vector. ++ class DestroyTemplateIdAnnotationsRAIIObj { ++ Parser &P; ++ public: ++ DestroyTemplateIdAnnotationsRAIIObj(Parser &p) ++ : P(p) {} ++ ++ ~DestroyTemplateIdAnnotationsRAIIObj() { ++ for (SmallVectorImpl::iterator I = ++ P.TemplateIds.begin(), E = P.TemplateIds.end(); ++ I != E; ++I) ++ (*I)->Destroy(); ++ P.TemplateIds.clear(); ++ } ++ }; ++ + } // end namespace clang + + #endif