From owner-svn-src-head@FreeBSD.ORG Wed May 23 21:48:50 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D1C20106564A; Wed, 23 May 2012 21:48:50 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B79638FC08; Wed, 23 May 2012 21:48:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4NLmoZe097403; Wed, 23 May 2012 21:48:50 GMT (envelope-from dim@svn.freebsd.org) Received: (from dim@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4NLmoXp097382; Wed, 23 May 2012 21:48:50 GMT (envelope-from dim@svn.freebsd.org) Message-Id: <201205232148.q4NLmoXp097382@svn.freebsd.org> From: Dimitry Andric Date: Wed, 23 May 2012 21:48:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r235864 - in head: contrib/llvm/lib/CodeGen/SelectionDAG contrib/llvm/tools/clang/include/clang/AST contrib/llvm/tools/clang/include/clang/Basic contrib/llvm/tools/clang/include/clang/P... X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 May 2012 21:48:50 -0000 Author: dim Date: Wed May 23 21:48:49 2012 New Revision: 235864 URL: http://svn.freebsd.org/changeset/base/235864 Log: Upgrade our copy of llvm/clang to 3.1 release. Release notes can be found at: http://llvm.org/releases/3.1/docs/ReleaseNotes.html MFC after: 3 days Modified: head/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp head/contrib/llvm/tools/clang/include/clang/AST/Decl.h head/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td head/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def head/contrib/llvm/tools/clang/include/clang/Parse/Parser.h head/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h head/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h head/contrib/llvm/tools/clang/include/clang/Sema/Sema.h head/contrib/llvm/tools/clang/lib/Analysis/UninitializedValues.cpp head/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp head/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp head/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp head/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp head/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp head/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp head/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp head/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp head/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp head/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp head/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp head/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp head/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp head/lib/clang/include/clang/Basic/Version.inc head/lib/clang/include/llvm/Config/config.h Directory Properties: head/contrib/llvm/ (props changed) head/contrib/llvm/tools/clang/ (props changed) Modified: head/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp ============================================================================== --- head/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp Wed May 23 21:48:49 2012 (r235864) @@ -131,30 +131,16 @@ static void CheckForPhysRegDependency(SD } } -static void AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) { - SmallVector VTs; - SDNode *GlueDestNode = Glue.getNode(); - - // Don't add glue from a node to itself. - if (GlueDestNode == N) return; - - // Don't add glue to something that already has it, either as a use or value. - if (N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue || - N->getValueType(N->getNumValues() - 1) == MVT::Glue) { - return; - } - for (unsigned I = 0, E = N->getNumValues(); I != E; ++I) - VTs.push_back(N->getValueType(I)); - - if (AddGlue) - VTs.push_back(MVT::Glue); - +// Helper for AddGlue to clone node operands. +static void CloneNodeWithValues(SDNode *N, SelectionDAG *DAG, + SmallVectorImpl &VTs, + SDValue ExtraOper = SDValue()) { SmallVector Ops; for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I) Ops.push_back(N->getOperand(I)); - if (GlueDestNode) - Ops.push_back(Glue); + if (ExtraOper.getNode()) + Ops.push_back(ExtraOper); SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size()); MachineSDNode::mmo_iterator Begin = 0, End = 0; @@ -173,6 +159,46 @@ static void AddGlue(SDNode *N, SDValue G MN->setMemRefs(Begin, End); } +static bool AddGlue(SDNode *N, SDValue Glue, bool AddGlue, SelectionDAG *DAG) { + SmallVector VTs; + SDNode *GlueDestNode = Glue.getNode(); + + // Don't add glue from a node to itself. + if (GlueDestNode == N) return false; + + // Don't add a glue operand to something that already uses glue. + if (GlueDestNode && + N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue) { + return false; + } + // Don't add glue to something that already has a glue value. + if (N->getValueType(N->getNumValues() - 1) == MVT::Glue) return false; + + for (unsigned I = 0, E = N->getNumValues(); I != E; ++I) + VTs.push_back(N->getValueType(I)); + + if (AddGlue) + VTs.push_back(MVT::Glue); + + CloneNodeWithValues(N, DAG, VTs, Glue); + + return true; +} + +// Cleanup after unsuccessful AddGlue. Use the standard method of morphing the +// node even though simply shrinking the value list is sufficient. +static void RemoveUnusedGlue(SDNode *N, SelectionDAG *DAG) { + assert((N->getValueType(N->getNumValues() - 1) == MVT::Glue && + !N->hasAnyUseOfValue(N->getNumValues() - 1)) && + "expected an unused glue value"); + + SmallVector VTs; + for (unsigned I = 0, E = N->getNumValues()-1; I != E; ++I) + VTs.push_back(N->getValueType(I)); + + CloneNodeWithValues(N, DAG, VTs); +} + /// ClusterNeighboringLoads - Force nearby loads together by "gluing" them. /// This function finds loads of the same base and different offsets. If the /// offsets are not far apart (target specific), it add MVT::Glue inputs and @@ -240,19 +266,23 @@ void ScheduleDAGSDNodes::ClusterNeighbor // Cluster loads by adding MVT::Glue outputs and inputs. This also // ensure they are scheduled in order of increasing addresses. SDNode *Lead = Loads[0]; - AddGlue(Lead, SDValue(0, 0), true, DAG); - - SDValue InGlue = SDValue(Lead, Lead->getNumValues() - 1); + SDValue InGlue = SDValue(0, 0); + if (AddGlue(Lead, InGlue, true, DAG)) + InGlue = SDValue(Lead, Lead->getNumValues() - 1); for (unsigned I = 1, E = Loads.size(); I != E; ++I) { bool OutGlue = I < E - 1; SDNode *Load = Loads[I]; - AddGlue(Load, InGlue, OutGlue, DAG); + // If AddGlue fails, we could leave an unsused glue value. This should not + // cause any + if (AddGlue(Load, InGlue, OutGlue, DAG)) { + if (OutGlue) + InGlue = SDValue(Load, Load->getNumValues() - 1); - if (OutGlue) - InGlue = SDValue(Load, Load->getNumValues() - 1); - - ++LoadsClustered; + ++LoadsClustered; + } + else if (!OutGlue && InGlue.getNode()) + RemoveUnusedGlue(InGlue.getNode(), DAG); } } Modified: head/contrib/llvm/tools/clang/include/clang/AST/Decl.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/AST/Decl.h Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/AST/Decl.h Wed May 23 21:48:49 2012 (r235864) @@ -64,9 +64,6 @@ public: /// \brief Return the TypeLoc wrapper for the type source info. TypeLoc getTypeLoc() const; // implemented in TypeLoc.h - - /// \brief Override the type stored in this TypeSourceInfo. Use with caution! - void overrideType(QualType T) { Ty = T; } }; /// TranslationUnitDecl - The top declaration context. Modified: head/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td Wed May 23 21:48:49 2012 (r235864) @@ -410,8 +410,6 @@ def ext_ellipsis_exception_spec : Extens "exception specification of '...' is a Microsoft extension">; def err_dynamic_and_noexcept_specification : Error< "cannot have both throw() and noexcept() clause on the same function">; -def err_except_spec_unparsed : Error< - "unexpected end of exception specification">; def warn_cxx98_compat_noexcept_decl : Warning< "noexcept specifications are incompatible with C++98">, InGroup, DefaultIgnore; Modified: head/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def Wed May 23 21:48:49 2012 (r235864) @@ -105,7 +105,6 @@ TOK(eod) // End of prepr // directive). TOK(code_completion) // Code completion marker TOK(cxx_defaultarg_end) // C++ default argument end marker -TOK(cxx_exceptspec_end) // C++ exception-specification end marker // C99 6.4.9: Comments. TOK(comment) // Comment (only in -E -C[C] mode) Modified: head/contrib/llvm/tools/clang/include/clang/Parse/Parser.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Parse/Parser.h Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Parse/Parser.h Wed May 23 21:48:49 2012 (r235864) @@ -584,11 +584,15 @@ private: class TentativeParsingAction { Parser &P; Token PrevTok; + unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount; bool isActive; public: explicit TentativeParsingAction(Parser& p) : P(p) { PrevTok = P.Tok; + PrevParenCount = P.ParenCount; + PrevBracketCount = P.BracketCount; + PrevBraceCount = P.BraceCount; P.PP.EnableBacktrackAtThisPos(); isActive = true; } @@ -601,6 +605,9 @@ private: assert(isActive && "Parsing action was finished!"); P.PP.Backtrack(); P.Tok = PrevTok; + P.ParenCount = PrevParenCount; + P.BracketCount = PrevBracketCount; + P.BraceCount = PrevBraceCount; isActive = false; } ~TentativeParsingAction() { @@ -1422,12 +1429,10 @@ private: ExprResult ParseThrowExpression(); ExceptionSpecificationType tryParseExceptionSpecification( - bool Delayed, SourceRange &SpecificationRange, SmallVectorImpl &DynamicExceptions, SmallVectorImpl &DynamicExceptionRanges, - ExprResult &NoexceptExpr, - CachedTokens *&ExceptionSpecTokens); + ExprResult &NoexceptExpr); // EndLoc is filled with the location of the last token of the specification. ExceptionSpecificationType ParseDynamicExceptionSpecification( Modified: head/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h Wed May 23 21:48:49 2012 (r235864) @@ -1150,10 +1150,6 @@ struct DeclaratorChunk { /// \brief Pointer to the expression in the noexcept-specifier of this /// function, if it has one. Expr *NoexceptExpr; - - /// \brief Pointer to the cached tokens for an exception-specification - /// that has not yet been parsed. - CachedTokens *ExceptionSpecTokens; }; /// TrailingReturnType - If this isn't null, it's the trailing return type @@ -1176,8 +1172,6 @@ struct DeclaratorChunk { delete[] ArgInfo; if (getExceptionSpecType() == EST_Dynamic) delete[] Exceptions; - else if (getExceptionSpecType() == EST_Delayed) - delete ExceptionSpecTokens; } /// isKNRPrototype - Return true if this is a K&R style identifier list, @@ -1353,7 +1347,6 @@ struct DeclaratorChunk { SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, - CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, Modified: head/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h Wed May 23 21:48:49 2012 (r235864) @@ -225,7 +225,9 @@ public: /// \brief Create the initialization entity for a temporary. static InitializedEntity InitializeTemporary(QualType Type) { - return InitializedEntity(EK_Temporary, SourceLocation(), Type); + InitializedEntity Result(EK_Temporary, SourceLocation(), Type); + Result.TypeInfo = 0; + return Result; } /// \brief Create the initialization entity for a temporary. Modified: head/contrib/llvm/tools/clang/include/clang/Sema/Sema.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Sema/Sema.h Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/include/clang/Sema/Sema.h Wed May 23 21:48:49 2012 (r235864) @@ -331,6 +331,11 @@ public: /// cycle detection at the end of the TU. DelegatingCtorDeclsType DelegatingCtorDecls; + /// \brief All the destructors seen during a class definition that had their + /// exception spec computation delayed because it depended on an unparsed + /// exception spec. + SmallVector DelayedDestructorExceptionSpecs; + /// \brief All the overriding destructors seen during a class definition /// (there could be multiple due to nested classes) that had their exception /// spec checks delayed, plus the overridden destructor. @@ -653,23 +658,19 @@ public: /// SpecialMemberOverloadResult - The overloading result for a special member /// function. /// - /// This is basically a wrapper around PointerIntPair. The lowest bit of the - /// integer is used to determine whether we have a parameter qualification - /// match, the second-lowest is whether we had success in resolving the - /// overload to a unique non-deleted function. - /// - /// The ConstParamMatch bit represents whether, when looking up a copy - /// constructor or assignment operator, we found a potential copy - /// constructor/assignment operator whose first parameter is const-qualified. - /// This is used for determining parameter types of other objects and is - /// utterly meaningless on other types of special members. + /// This is basically a wrapper around PointerIntPair. The lowest bits of the + /// integer are used to determine whether overload resolution succeeded, and + /// whether, when looking up a copy constructor or assignment operator, we + /// found a potential copy constructor/assignment operator whose first + /// parameter is const-qualified. This is used for determining parameter types + /// of other objects and is utterly meaningless on other types of special + /// members. class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { public: enum Kind { NoMemberOrDeleted, Ambiguous, - SuccessNonConst, - SuccessConst + Success }; private: @@ -685,9 +686,6 @@ public: Kind getKind() const { return static_cast(Pair.getInt()); } void setKind(Kind K) { Pair.setInt(K); } - - bool hasSuccess() const { return getKind() >= SuccessNonConst; } - bool hasConstParamMatch() const { return getKind() == SuccessConst; } }; /// \brief A cache of special member function overload resolution results @@ -1909,11 +1907,9 @@ public: DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, - unsigned Quals, - bool *ConstParam = 0); + unsigned Quals); CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, - bool RValueThis, unsigned ThisQuals, - bool *ConstParam = 0); + bool RValueThis, unsigned ThisQuals); CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class); CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, bool RValueThis, unsigned ThisQuals); @@ -3158,16 +3154,6 @@ public: llvm::SmallVectorImpl &Exceptions, FunctionProtoType::ExtProtoInfo &EPI); - /// \brief Add an exception-specification to the given member function - /// (or member function template). The exception-specification was parsed - /// after the method itself was declared. - void actOnDelayedExceptionSpecification(Decl *Method, - ExceptionSpecificationType EST, - SourceRange SpecificationRange, - ArrayRef DynamicExceptions, - ArrayRef DynamicExceptionRanges, - Expr *NoexceptExpr); - /// \brief Determine if a special member function should have a deleted /// definition when it is defaulted. bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, @@ -3205,7 +3191,8 @@ public: /// C++11 says that user-defined destructors with no exception spec get one /// that looks as if the destructor was implicitly declared. void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, - CXXDestructorDecl *Destructor); + CXXDestructorDecl *Destructor, + bool WasDelayed = false); /// \brief Declare all inherited constructors for the given class. /// @@ -4043,6 +4030,7 @@ public: SourceLocation LBrac, SourceLocation RBrac, AttributeList *AttrList); + void ActOnFinishCXXMemberDecls(); void ActOnReenterTemplateScope(Scope *S, Decl *Template); void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D); Modified: head/contrib/llvm/tools/clang/lib/Analysis/UninitializedValues.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Analysis/UninitializedValues.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Analysis/UninitializedValues.cpp Wed May 23 21:48:49 2012 (r235864) @@ -168,7 +168,8 @@ static const BinaryOperator *getLogicalO if (block->empty()) return 0; - const CFGStmt *cstmt = block->front().getAs(); + CFGElement front = block->front(); + const CFGStmt *cstmt = front.getAs(); if (!cstmt) return 0; Modified: head/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Driver/ToolChains.cpp Wed May 23 21:48:49 2012 (r235864) @@ -1830,6 +1830,7 @@ enum LinuxDistro { OpenSuse11_3, OpenSuse11_4, OpenSuse12_1, + OpenSuse12_2, UbuntuHardy, UbuntuIntrepid, UbuntuJaunty, @@ -1848,7 +1849,7 @@ static bool IsRedhat(enum LinuxDistro Di } static bool IsOpenSuse(enum LinuxDistro Distro) { - return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_1; + return Distro >= OpenSuse11_3 && Distro <= OpenSuse12_2; } static bool IsDebian(enum LinuxDistro Distro) { @@ -1925,6 +1926,7 @@ static LinuxDistro DetectLinuxDistro(llv .StartsWith("openSUSE 11.3", OpenSuse11_3) .StartsWith("openSUSE 11.4", OpenSuse11_4) .StartsWith("openSUSE 12.1", OpenSuse12_1) + .StartsWith("openSUSE 12.2", OpenSuse12_2) .Default(UnknownDistro); bool Exists; Modified: head/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp Wed May 23 21:48:49 2012 (r235864) @@ -348,77 +348,7 @@ void Parser::ParseLexedMethodDeclaration 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(LM.Method)) - Method = cast(FunTmpl->getTemplatedDecl()); - else - Method = cast(LM.Method); - - Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(), - Method->getTypeQualifiers(), - getLangOpts().CPlusPlus0x); - - // Parse the exception-specification. - SourceRange SpecificationRange; - SmallVector DynamicExceptions; - SmallVector 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. Modified: head/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp Wed May 23 21:48:49 2012 (r235864) @@ -4197,7 +4197,6 @@ void Parser::ParseFunctionDeclarator(Dec SmallVector DynamicExceptions; SmallVector DynamicExceptionRanges; ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens = 0; ParsedAttributes FnAttrs(AttrFactory); ParsedType TrailingReturnType; @@ -4264,18 +4263,12 @@ void Parser::ParseFunctionDeclarator(Dec dyn_cast(Actions.CurContext), DS.getTypeQualifiers(), IsCXX11MemberFunction); - + // Parse exception-specification[opt]. - bool Delayed = (D.getContext() == Declarator::MemberContext && - D.getDeclSpec().getStorageClassSpec() - != DeclSpec::SCS_typedef && - !D.getDeclSpec().isFriendSpecified()); - ESpecType = tryParseExceptionSpecification(Delayed, - ESpecRange, + ESpecType = tryParseExceptionSpecification(ESpecRange, DynamicExceptions, DynamicExceptionRanges, - NoexceptExpr, - ExceptionSpecTokens); + NoexceptExpr); if (ESpecType != EST_None) EndLoc = ESpecRange.getEnd(); @@ -4310,7 +4303,6 @@ void Parser::ParseFunctionDeclarator(Dec DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, - ExceptionSpecTokens, Tracker.getOpenLocation(), EndLoc, D, TrailingReturnType), Modified: head/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp Wed May 23 21:48:49 2012 (r235864) @@ -1535,34 +1535,16 @@ AccessSpecifier Parser::getAccessSpecifi } /// \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. +/// delayed, e.g., default arguments, 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 or an exception-specification, we'll need to - // parse them later. + // has any default arguments, 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) { @@ -1846,7 +1828,7 @@ void Parser::ParseCXXClassMemberDeclarat // Parse the first declarator. ParseDeclarator(DeclaratorInfo); - // Error parsin g the declarator? + // Error parsing the declarator? if (!DeclaratorInfo.hasName()) { // If so, skip until the semi-colon or a }. SkipUntil(tok::r_brace, true, true); @@ -2065,7 +2047,7 @@ void Parser::ParseCXXClassMemberDeclarat DeclsInGroup.push_back(ThisDecl); } - if (DeclaratorInfo.isFunctionDeclarator() && + if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() && DeclaratorInfo.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef) { HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); @@ -2358,7 +2340,7 @@ void Parser::ParseCXXMemberSpecification // C++11 [class.mem]p2: // Within the class member-specification, the class is regarded as complete - // within function bodies, default arguments, exception-specifications, and + // within function bodies, default arguments, and // brace-or-equal-initializers for non-static data members (including such // things in nested classes). if (TagDecl && NonNestedClass) { @@ -2369,6 +2351,10 @@ void Parser::ParseCXXMemberSpecification SourceLocation SavedPrevTokLocation = PrevTokLocation; ParseLexedAttributes(getCurrentClass()); ParseLexedMethodDeclarations(getCurrentClass()); + + // We've finished with all pending member declarations. + Actions.ActOnFinishCXXMemberDecls(); + ParseLexedMemberInitializers(getCurrentClass()); ParseLexedMethodDefs(getCurrentClass()); PrevTokLocation = SavedPrevTokLocation; @@ -2555,63 +2541,13 @@ Parser::MemInitResult Parser::ParseMemIn /// 'noexcept' /// 'noexcept' '(' constant-expression ')' ExceptionSpecificationType -Parser::tryParseExceptionSpecification(bool Delayed, +Parser::tryParseExceptionSpecification( SourceRange &SpecificationRange, SmallVectorImpl &DynamicExceptions, SmallVectorImpl &DynamicExceptionRanges, - ExprResult &NoexceptExpr, - CachedTokens *&ExceptionSpecTokens) { + ExprResult &NoexceptExpr) { 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, Modified: head/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp Wed May 23 21:48:49 2012 (r235864) @@ -2392,7 +2392,7 @@ ExprResult Parser::ParseBlockLiteralExpr SourceLocation(), EST_None, SourceLocation(), - 0, 0, 0, 0, 0, + 0, 0, 0, 0, CaretLoc, CaretLoc, ParamInfo), attrs, CaretLoc); Modified: head/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp Wed May 23 21:48:49 2012 (r235864) @@ -780,13 +780,10 @@ ExprResult Parser::ParseLambdaExpression llvm::SmallVector DynamicExceptions; llvm::SmallVector DynamicExceptionRanges; ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens; - ESpecType = tryParseExceptionSpecification(/*Delayed=*/false, - ESpecRange, + ESpecType = tryParseExceptionSpecification(ESpecRange, DynamicExceptions, DynamicExceptionRanges, - NoexceptExpr, - ExceptionSpecTokens); + NoexceptExpr); if (ESpecType != EST_None) DeclEndLoc = ESpecRange.getEnd(); @@ -821,7 +818,6 @@ ExprResult Parser::ParseLambdaExpression DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, - 0, DeclLoc, DeclEndLoc, D, TrailingReturnType), Attr, DeclEndLoc); @@ -867,7 +863,6 @@ ExprResult Parser::ParseLambdaExpression /*ExceptionRanges=*/0, /*NumExceptions=*/0, /*NoexceptExpr=*/0, - /*ExceptionSpecTokens=*/0, DeclLoc, DeclEndLoc, D, TrailingReturnType), Attr, DeclEndLoc); Modified: head/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp Wed May 23 21:48:49 2012 (r235864) @@ -162,7 +162,6 @@ DeclaratorChunk DeclaratorChunk::getFunc SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, - CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, @@ -227,10 +226,6 @@ DeclaratorChunk DeclaratorChunk::getFunc case EST_ComputedNoexcept: I.Fun.NoexceptExpr = NoexceptExpr; break; - - case EST_Delayed: - I.Fun.ExceptionSpecTokens = ExceptionSpecTokens; - break; } return I; } Modified: head/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp Wed May 23 21:48:49 2012 (r235864) @@ -7635,7 +7635,7 @@ NamedDecl *Sema::ImplicitlyDefineFunctio SourceLocation(), SourceLocation(), SourceLocation(), EST_None, SourceLocation(), - 0, 0, 0, 0, 0, Loc, Loc, D), + 0, 0, 0, 0, Loc, Loc, D), DS.getAttributes(), SourceLocation()); D.SetIdentifier(&II, Loc); @@ -9784,21 +9784,6 @@ void Sema::ActOnFields(Scope* S, if (!Completed) Record->completeDefinition(); - // Now that the record is complete, do any delayed exception spec checks - // we were missing. - while (!DelayedDestructorExceptionSpecChecks.empty()) { - const CXXDestructorDecl *Dtor = - DelayedDestructorExceptionSpecChecks.back().first; - if (Dtor->getParent() != Record) - break; - - assert(!Dtor->getParent()->isDependentType() && - "Should not ever add destructors of templates into the list."); - CheckOverridingFunctionExceptionSpec(Dtor, - DelayedDestructorExceptionSpecChecks.back().second); - DelayedDestructorExceptionSpecChecks.pop_back(); - } - } else { ObjCIvarDecl **ClsFields = reinterpret_cast(RecFields.data()); Modified: head/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp Wed May 23 21:48:49 2012 (r235864) @@ -7319,15 +7319,42 @@ void Sema::DefineImplicitDestructor(Sour } } +/// \brief Perform any semantic analysis which needs to be delayed until all +/// pending class member declarations have been parsed. +void Sema::ActOnFinishCXXMemberDecls() { + // Now we have parsed all exception specifications, determine the implicit + // exception specifications for destructors. + for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size(); + i != e; ++i) { + CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i]; + AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true); + } + DelayedDestructorExceptionSpecs.clear(); + + // Perform any deferred checking of exception specifications for virtual + // destructors. + for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size(); + i != e; ++i) { + const CXXDestructorDecl *Dtor = + DelayedDestructorExceptionSpecChecks[i].first; + assert(!Dtor->getParent()->isDependentType() && + "Should not ever add destructors of templates into the list."); + CheckOverridingFunctionExceptionSpec(Dtor, + DelayedDestructorExceptionSpecChecks[i].second); + } + DelayedDestructorExceptionSpecChecks.clear(); +} + void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl, - CXXDestructorDecl *destructor) { + CXXDestructorDecl *destructor, + bool WasDelayed) { // C++11 [class.dtor]p3: // A declaration of a destructor that does not have an exception- // specification is implicitly considered to have the same exception- // specification as an implicit declaration. const FunctionProtoType *dtorType = destructor->getType()-> getAs(); - if (dtorType->hasExceptionSpec()) + if (!WasDelayed && dtorType->hasExceptionSpec()) return; ImplicitExceptionSpecification exceptSpec = @@ -7344,6 +7371,14 @@ void Sema::AdjustDestructorExceptionSpec destructor->setType(ty); + // If we can't compute the exception specification for this destructor yet + // (because it depends on an exception specification which we have not parsed + // yet), make a note that we need to try again when the class is complete. + if (epi.ExceptionSpecType == EST_Delayed) { + assert(!WasDelayed && "couldn't compute destructor exception spec"); + DelayedDestructorExceptionSpecs.push_back(destructor); + } + // FIXME: If the destructor has a body that could throw, and the newly created // spec doesn't allow exceptions, we should emit a warning, because this // change in behavior can break conforming C++03 programs at runtime. @@ -7579,8 +7614,9 @@ Sema::ComputeDefaultedCopyAssignmentExce assert(!Base->getType()->isDependentType() && "Cannot generate implicit members for class with dependent bases."); CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl(); - LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0, - &HasConstCopyAssignment); + HasConstCopyAssignment &= + (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, + false, 0); } // In C++11, the above citation has "or virtual" added @@ -7591,8 +7627,9 @@ Sema::ComputeDefaultedCopyAssignmentExce assert(!Base->getType()->isDependentType() && "Cannot generate implicit members for class with dependent bases."); CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl(); - LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0, - &HasConstCopyAssignment); + HasConstCopyAssignment &= + (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, + false, 0); } } @@ -7606,8 +7643,9 @@ Sema::ComputeDefaultedCopyAssignmentExce ++Field) { QualType FieldType = Context.getBaseElementType((*Field)->getType()); if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { - LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const, false, 0, - &HasConstCopyAssignment); + HasConstCopyAssignment &= + (bool)LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const, + false, 0); } } @@ -8610,8 +8648,8 @@ Sema::ComputeDefaultedCopyCtorExceptionS CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); - LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const, - &HasConstCopyConstructor); + HasConstCopyConstructor &= + (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const); } for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), @@ -8620,8 +8658,8 @@ Sema::ComputeDefaultedCopyCtorExceptionS ++Base) { CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->getDecl()); - LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const, - &HasConstCopyConstructor); + HasConstCopyConstructor &= + (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const); } // -- for all the nonstatic data members of X that are of a @@ -8634,8 +8672,8 @@ Sema::ComputeDefaultedCopyCtorExceptionS ++Field) { QualType FieldType = Context.getBaseElementType((*Field)->getType()); if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) { - LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const, - &HasConstCopyConstructor); + HasConstCopyConstructor &= + (bool)LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const); } } // Otherwise, the implicitly declared copy constructor will have @@ -11260,66 +11298,6 @@ Sema::checkExceptionSpecification(Except } } -void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, - ExceptionSpecificationType EST, - SourceRange SpecificationRange, - ArrayRef DynamicExceptions, - ArrayRef DynamicExceptionRanges, - Expr *NoexceptExpr) { - if (!MethodD) - return; - - // Dig out the method we're referring to. - CXXMethodDecl *Method = 0; - if (FunctionTemplateDecl *FunTmpl = dyn_cast(MethodD)) - Method = dyn_cast(FunTmpl->getTemplatedDecl()); - else - Method = dyn_cast(MethodD); - - if (!Method) - return; - - // Dig out the prototype. This should never fail. - const FunctionProtoType *Proto - = dyn_cast(Method->getType()); - if (!Proto) - return; - - // Check the exception specification. - llvm::SmallVector Exceptions; - FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); - checkExceptionSpecification(EST, DynamicExceptions, DynamicExceptionRanges, - NoexceptExpr, Exceptions, EPI); - - // Rebuild the function type. - QualType T = Context.getFunctionType(Proto->getResultType(), - Proto->arg_type_begin(), - Proto->getNumArgs(), - EPI); - if (TypeSourceInfo *TSInfo = Method->getTypeSourceInfo()) { - // FIXME: When we get proper type location information for exceptions, - // we'll also have to rebuild the TypeSourceInfo. For now, we just patch - // up the TypeSourceInfo; - assert(TypeLoc::getFullDataSizeForType(T) - == TypeLoc::getFullDataSizeForType(Method->getType()) && - "TypeLoc size mismatch with delayed exception specification"); - TSInfo->overrideType(T); - } - - Method->setType(T); - - if (Method->isStatic()) - checkThisInStaticMemberFunctionExceptionSpec(Method); - - if (Method->isVirtual()) { - // Check overrides, which we previously had to delay. - for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(), - OEnd = Method->end_overridden_methods(); - O != OEnd; ++O) - CheckOverridingFunctionExceptionSpec(Method, *O); - } -} - /// IdentifyCUDATarget - Determine the CUDA compilation target for this function Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { // Implicitly declared functions (e.g. copy constructors) are Modified: head/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp Wed May 23 21:39:39 2012 (r235863) +++ head/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp Wed May 23 21:48:49 2012 (r235864) @@ -2277,7 +2277,7 @@ Sema::SpecialMemberOverloadResult *Sema: Result->setMethod(DD); Result->setKind(DD->isDeleted() ? SpecialMemberOverloadResult::NoMemberOrDeleted : - SpecialMemberOverloadResult::SuccessNonConst); + SpecialMemberOverloadResult::Success); return Result; } @@ -2288,6 +2288,9 @@ Sema::SpecialMemberOverloadResult *Sema: Expr *Arg = 0; unsigned NumArgs; + QualType ArgType = CanTy; + ExprValueKind VK = VK_LValue; + if (SM == CXXDefaultConstructor) { Name = Context.DeclarationNames.getCXXConstructorName(CanTy); NumArgs = 0; @@ -2308,7 +2311,6 @@ Sema::SpecialMemberOverloadResult *Sema: DeclareImplicitMoveAssignment(RD); } - QualType ArgType = CanTy; if (ConstArg) ArgType.addConst(); if (VolatileArg) @@ -2321,14 +2323,17 @@ Sema::SpecialMemberOverloadResult *Sema: // Possibly an XValue is actually correct in the case of move, but // there is no semantic difference for class types in this restricted // case. - ExprValueKind VK; if (SM == CXXCopyConstructor || SM == CXXCopyAssignment) VK = VK_LValue; else VK = VK_RValue; + } + OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK); + + if (SM != CXXDefaultConstructor) { NumArgs = 1; - Arg = new (Context) OpaqueValueExpr(SourceLocation(), ArgType, VK); + Arg = &FakeArg; } // Create the object argument @@ -2338,17 +2343,14 @@ Sema::SpecialMemberOverloadResult *Sema: if (VolatileThis) ThisTy.addVolatile(); Expr::Classification Classification = - (new (Context) OpaqueValueExpr(SourceLocation(), ThisTy, - RValueThis ? VK_RValue : VK_LValue))-> - Classify(Context); + OpaqueValueExpr(SourceLocation(), ThisTy, + RValueThis ? VK_RValue : VK_LValue).Classify(Context); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***