<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Yeah, should be fixed in r160840, thanks!</div><div><br></div><br><div><div>On Jul 26, 2012, at 16:27 , Manman Ren <<a href="mailto:mren@apple.com">mren@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>Seeing this failure , looks like yours :)</div><div><a href="http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-nt-O3/builds/1581/steps/compile/logs/stdio">http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-nt-O3/builds/1581/steps/compile/logs/stdio</a></div><div><span class="Apple-style-span" style="font-family: Times; "><pre style="font-family: 'Courier New', courier, monotype, monospace; "><span class="stderr" style="font-family: 'Courier New', courier, monotype, monospace; color: red; ">/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h: In copy constructor 'clang::ento::ObjCMethodCall::ObjCMethodCall(const clang::ento::ObjCMethodCall&)':
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:63: error: 'clang::ento::CallEvent::CallEvent(const clang::ento::CallEvent&)' is private
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/../../../include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:584: error: within this context
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp: In member function 'void clang::ento::ExprEngine::Visit(const clang::Stmt*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&)':
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.src/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:883: note: synthesized method 'clang::ento::ObjCMethodCall::ObjCMethodCall(const clang::ento::ObjCMethodCall&)' first required here 
make[5]: *** [/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/clang-x86_64-darwin10-nt-O3/llvm.obj/tools/clang/lib/StaticAnalyzer/Core/Release+Asserts/ExprEngine.o] Error 1
make[4]: *** [Core/.makeall] Error 2
make[4]: *** Waiting for unfinished jobs....</span></pre></span><div><br></div></div><div><a href="http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/5499/steps/compile/logs/stdio">http://lab.llvm.org:8011/builders/clang-x86_64-darwin11-self-mingw32/builds/5499/steps/compile/logs/stdio</a></div><span class="Apple-style-span" style="font-family: Times; "><pre style="font-family: 'Courier New', courier, monotype, monospace; "><span class="stdout" style="font-family: 'Courier New', courier, monotype, monospace; ">llvm[5]: Compiling ObjCSelfInitChecker.cpp for Debug+Asserts build
</span><span class="stderr" style="font-family: 'Courier New', courier, monotype, monospace; color: red; ">/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseMap.h: In copy constructor 'llvm::DenseMap<KeyT, ValueT, KeyInfoT>::DenseMap(const llvm::DenseMap<KeyT, ValueT, KeyInfoT>&) [with KeyT = clang::Expr*, ValueT = char, KeyInfoT = llvm::DenseMapInfo<clang::Expr*>]':
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseSet.h:30:   instantiated from 'llvm::DenseSet<ValueT, ValueInfoT>::DenseSet(const llvm::DenseSet<ValueT, ValueInfoT>&) [with ValueT = clang::Expr*, ValueInfoT = llvm::DenseMapInfo<clang::Expr*>]'
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp:419:   instantiated from '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = clang::VarDecl*, _Tp = <unnamed>::AutoreleasePoolRewriter::PoolVarInfo, _Compare = std::less<clang::VarDecl*>, _Alloc = std::allocator<std::pair<clang::VarDecl* const, <unnamed>::AutoreleasePoolRewriter::PoolVarInfo> >]'
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/tools/clang/lib/ARCMigrate/TransAutoreleasePool.cpp:111:   instantiated from here
/Volumes/Macintosh_HD2/buildbots/clang-x86_64-darwin11-self-mingw32/llvm.src/include/llvm/ADT/DenseMap.h:533: warning: base class 'class llvm::DenseMapBase<llvm::DenseMap<clang::Expr*, char, llvm::DenseMapInfo<clang::Expr*> >, clang::Expr*, char, llvm::DenseMapInfo<clang::Expr*> >' should be explicitly initialized in the copy constructor
</span><span class="stdout" style="font-family: 'Courier New', courier, monotype, monospace; ">llvm[5]: Compiling ObjCUnusedIVarsChecker.cpp for Debug+Asserts build</span></pre></span><div>Thanks,</div><div>Manman</div><div><br></div><div><div>On Jul 26, 2012, at 2:41 PM, Jordan Rose wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Author: jrose<br>Date: Thu Jul 26 16:41:15 2012<br>New Revision: 160817<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=160817&view=rev">http://llvm.org/viewvc/llvm-project?rev=160817&view=rev</a><br>Log:<br>[analyzer] CallEvent is no longer a value object.<br><br>After discussion, the type-based dispatch was decided to be bad for<br>maintenance and made it very easy for subtle bugs to creep in. Instead,<br>we'll just be very careful when we do have to allocate these on the heap.<br><br>Modified:<br>    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h<br>    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp<br><br>Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=160817&r1=160816&r2=160817&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=160817&r1=160816&r2=160817&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)<br>+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Thu Jul 26 16:41:15 2012<br>@@ -55,45 +55,31 @@<br>   typedef CallEventKind Kind;<br><br> private:<br>-  // PointerIntPair doesn't respect IntrusiveRefCntPtr, so we have to manually<br>-  // retain and release the state.<br>-  llvm::PointerIntPair<const ProgramState *, 2> State;<br>-  llvm::PointerIntPair<const LocationContext *, 2> LCtx;<br>+  ProgramStateRef State;<br>+  const LocationContext *LCtx;<br>   llvm::PointerUnion<const Expr *, const Decl *> Origin;<br><br>+  // DO NOT IMPLEMENT! CallEvents should not be copied.<br>+  CallEvent(const CallEvent &);<br>+  CallEvent &operator=(const CallEvent &);<br>+<br> protected:<br>   // This is user data for subclasses.<br>   const void *Data;<br>   SourceLocation Location;<br><br>-  CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx,<br>-            Kind k)<br>-    : State(state.getPtr(), (k & 0x3)),<br>-      LCtx(lctx, ((k >> 2) & 0x3)),<br>-      Origin(E) {<br>-    IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());<br>-    assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");<br>-  }<br>-<br>-  CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx,<br>-            Kind k)<br>-    : State(state.getPtr(), (k & 0x3)),<br>-      LCtx(lctx, ((k >> 2) & 0x3)),<br>-      Origin(D) {<br>-    IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());<br>-    assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");<br>-  }<br>+  CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)<br>+    : State(state), LCtx(lctx), Origin(E) {}<br><br>-  const ProgramState *getState() const {<br>-    return State.getPointer();<br>-  }<br>+  CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)<br>+    : State(state), LCtx(lctx), Origin(D) {}<br><br>-  const LocationContext *getLocationContext() const {<br>-    return LCtx.getPointer();<br>+  ProgramStateRef getState() const {<br>+    return State;<br>   }<br><br>-  ~CallEvent() {<br>-    IntrusiveRefCntPtrInfo<const ProgramState>::release(getState());<br>+  const LocationContext *getLocationContext() const {<br>+    return LCtx;<br>   }<br><br><br>@@ -106,24 +92,26 @@<br><br>   /// \brief Used to specify non-argument regions that will be invalidated as a<br>   /// result of this call.<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const {}<br><br>-  QualType getDeclaredResultType() const;<br>+  virtual QualType getDeclaredResultType() const = 0;<br><br> public:<br>+  virtual ~CallEvent() {}<br>+<br>   /// \brief Returns the kind of call this is.<br>-  Kind getKind() const {<br>-    return static_cast<Kind>((State.getInt()) | (LCtx.getInt() << 2));<br>-  }<br>+  virtual Kind getKind() const = 0;<br><br>   /// \brief Returns the declaration of the function or method that will be<br>   /// called. May be null.<br>-  const Decl *getDecl() const;<br>+  virtual const Decl *getDecl() const {<br>+    return Origin.dyn_cast<const Decl *>();<br>+  }<br><br>   /// \brief Returns the definition of the function or method that will be<br>   /// called. Returns NULL if the definition cannot be found; ex: due to<br>   /// dynamic dispatch in ObjC methods.<br>-  const Decl *getRuntimeDefinition() const;<br>+  virtual const Decl *getRuntimeDefinition() const = 0;<br><br>   /// \brief Returns the expression whose value will be the result of this call.<br>   /// May be null.<br>@@ -136,7 +124,7 @@<br>   /// Note that this may be greater than the number of parameters in the<br>   /// callee's declaration, and that it may include arguments not written in<br>   /// the source.<br>-  unsigned getNumArgs() const;<br>+  virtual unsigned getNumArgs() const = 0;<br><br>   /// \brief Returns true if the callee is known to be from a system header.<br>   bool isInSystemHeader() const {<br>@@ -161,27 +149,30 @@<br><br>   /// \brief Returns a source range for the entire call, suitable for<br>   /// outputting in diagnostics.<br>-  SourceRange getSourceRange() const;<br>+  virtual SourceRange getSourceRange() const {<br>+    return getOriginExpr()->getSourceRange();<br>+  }<br><br>   /// \brief Returns the value of a given argument at the time of the call.<br>-  SVal getArgSVal(unsigned Index) const;<br>+  virtual SVal getArgSVal(unsigned Index) const;<br><br>   /// \brief Returns the expression associated with a given argument.<br>   /// May be null if this expression does not appear in the source.<br>-  const Expr *getArgExpr(unsigned Index) const;<br>+  virtual const Expr *getArgExpr(unsigned Index) const { return 0; }<br><br>   /// \brief Returns the source range for errors associated with this argument.<br>+  ///<br>   /// May be invalid if the argument is not written in the source.<br>-  // FIXME: Is it better to return an invalid range or the range of the origin<br>-  // expression?<br>-  SourceRange getArgSourceRange(unsigned Index) const;<br>+  virtual SourceRange getArgSourceRange(unsigned Index) const;<br><br>   /// \brief Returns the result type, adjusted for references.<br>   QualType getResultType() const;<br><br>   /// \brief Returns the value of the implicit 'this' object, or UndefinedVal if<br>   /// this is not a C++ member function call.<br>-  SVal getCXXThisVal() const;<br>+  virtual SVal getCXXThisVal() const {<br>+    return UndefinedVal();<br>+  }<br><br>   /// \brief Returns true if any of the arguments appear to represent callbacks.<br>   bool hasNonZeroCallbackArg() const;<br>@@ -191,7 +182,9 @@<br>   // NOTE: The exact semantics of this are still being defined!<br>   // We don't really want a list of hardcoded exceptions in the long run,<br>   // but we don't want duplicated lists of known APIs in the short term either.<br>-  bool argumentsMayEscape() const;<br>+  virtual bool argumentsMayEscape() const {<br>+    return hasNonZeroCallbackArg();<br>+  }<br><br>   /// \brief Returns an appropriate ProgramPoint for this call.<br>   ProgramPoint getProgramPoint(bool IsPreVisit = false,<br>@@ -206,6 +199,9 @@<br><br>   /// \brief Returns true if this is a statement that can be considered for<br>   /// inlining.<br>+  ///<br>+  /// FIXME: This should go away once CallEvents are cheap and easy to<br>+  /// construct from ExplodedNodes.<br>   static bool mayBeInlined(const Stmt *S);<br><br>   // Iterator access to formal parameters and their types.<br>@@ -229,9 +225,9 @@<br>   /// If the call has no accessible declaration (or definition, if<br>   /// \p UseDefinitionParams is set), \c param_begin() will be equal to<br>   /// \c param_end().<br>-  param_iterator param_begin(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_begin(bool UseDefinitionParams = false) const =0;<br>   /// \sa param_begin()<br>-  param_iterator param_end(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_end(bool UseDefinitionParams = false) const = 0;<br><br>   typedef llvm::mapped_iterator<param_iterator, get_type_fun><br>     param_type_iterator;<br>@@ -261,29 +257,24 @@<br> /// \brief Represents a call to any sort of function that might have a<br> /// FunctionDecl.<br> class AnyFunctionCall : public CallEvent {<br>-  friend class CallEvent;<br>-<br> protected:<br>   AnyFunctionCall(const Expr *E, ProgramStateRef St,<br>-                  const LocationContext *LCtx, Kind K)<br>-    : CallEvent(E, St, LCtx, K) {}<br>+                  const LocationContext *LCtx)<br>+    : CallEvent(E, St, LCtx) {}<br>   AnyFunctionCall(const Decl *D, ProgramStateRef St,<br>-                  const LocationContext *LCtx, Kind K)<br>-    : CallEvent(D, St, LCtx, K) {}<br>-<br>-  // Most function calls have no extra invalidated regions.<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const {}<br>+                  const LocationContext *LCtx)<br>+    : CallEvent(D, St, LCtx) {}<br><br>-  QualType getDeclaredResultType() const;<br>+  virtual QualType getDeclaredResultType() const;<br><br> public:<br>   // This function is overridden by subclasses, but they must return<br>   // a FunctionDecl.<br>-  const FunctionDecl *getDecl() const {<br>-    return cast_or_null<FunctionDecl>(CallEvent::getDecl());<br>+  virtual const FunctionDecl *getDecl() const {<br>+    return cast<FunctionDecl>(CallEvent::getDecl());<br>   }<br><br>-  const Decl *getRuntimeDefinition() const {<br>+  virtual const Decl *getRuntimeDefinition() const {<br>     const FunctionDecl *FD = getDecl();<br>     // Note that hasBody() will fill FD with the definition FunctionDecl.<br>     if (FD && FD->hasBody(FD))<br>@@ -291,13 +282,10 @@<br>     return 0;<br>   }<br><br>-  bool argumentsMayEscape() const;<br>-<br>-  SVal getArgSVal(unsigned Index) const;<br>-  SourceRange getArgSourceRange(unsigned Index) const;<br>+  virtual bool argumentsMayEscape() const;<br><br>-  param_iterator param_begin(bool UseDefinitionParams = false) const;<br>-  param_iterator param_end(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_begin(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_end(bool UseDefinitionParams = false) const;<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&<br>@@ -309,23 +297,20 @@<br> class SimpleCall : public AnyFunctionCall {<br> protected:<br>   SimpleCall(const CallExpr *CE, ProgramStateRef St,<br>-             const LocationContext *LCtx, Kind K)<br>-    : AnyFunctionCall(CE, St, LCtx, K) {<br>+             const LocationContext *LCtx)<br>+    : AnyFunctionCall(CE, St, LCtx) {<br>   }<br><br> public:<br>-  const CallExpr *getOriginExpr() const {<br>+  virtual const CallExpr *getOriginExpr() const {<br>     return cast<CallExpr>(AnyFunctionCall::getOriginExpr());<br>   }<br><br>-  const FunctionDecl *getDecl() const;<br>+  virtual const FunctionDecl *getDecl() const;<br><br>-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }<br>-  SourceRange getSourceRange() const {<br>-    return getOriginExpr()->getSourceRange();<br>-  }<br>-  <br>-  const Expr *getArgExpr(unsigned Index) const {<br>+  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }<br>+<br>+  virtual const Expr *getArgExpr(unsigned Index) const {<br>     return getOriginExpr()->getArg(Index);<br>   }<br><br>@@ -342,9 +327,9 @@<br> public:<br>   FunctionCall(const CallExpr *CE, ProgramStateRef St,<br>                const LocationContext *LCtx)<br>-    : SimpleCall(CE, St, LCtx, CE_Function) {}<br>+    : SimpleCall(CE, St, LCtx) {}<br><br>-  SVal getCXXThisVal() const { return UndefinedVal(); }<br>+  virtual Kind getKind() const { return CE_Function; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_Function;<br>@@ -354,17 +339,15 @@<br> /// \brief Represents a non-static C++ member function call, no matter how<br> /// it is written.<br> class CXXInstanceCall : public SimpleCall {<br>-  friend class CallEvent;<br>-<br> protected:<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;<br><br>   CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,<br>-                  const LocationContext *LCtx, Kind K)<br>-    : SimpleCall(CE, St, LCtx, K) {}<br>+                  const LocationContext *LCtx)<br>+    : SimpleCall(CE, St, LCtx) {}<br><br> public:<br>-  const Decl *getRuntimeDefinition() const;<br>+  virtual const Decl *getRuntimeDefinition() const;<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&<br>@@ -379,13 +362,15 @@<br> public:<br>   CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,<br>                 const LocationContext *LCtx)<br>-    : CXXInstanceCall(CE, St, LCtx, CE_CXXMember) {}<br>+    : CXXInstanceCall(CE, St, LCtx) {}<br><br>-  const CXXMemberCallExpr *getOriginExpr() const {<br>+  virtual const CXXMemberCallExpr *getOriginExpr() const {<br>     return cast<CXXMemberCallExpr>(SimpleCall::getOriginExpr());<br>   }<br><br>-  SVal getCXXThisVal() const;<br>+  virtual SVal getCXXThisVal() const;<br>+<br>+  virtual Kind getKind() const { return CE_CXXMember; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_CXXMember;<br>@@ -400,18 +385,22 @@<br> public:<br>   CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,<br>                         const LocationContext *LCtx)<br>-    : CXXInstanceCall(CE, St, LCtx, CE_CXXMemberOperator) {}<br>+    : CXXInstanceCall(CE, St, LCtx) {}<br><br>-  const CXXOperatorCallExpr *getOriginExpr() const {<br>+  virtual const CXXOperatorCallExpr *getOriginExpr() const {<br>     return cast<CXXOperatorCallExpr>(SimpleCall::getOriginExpr());<br>   }<br><br>-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs() - 1; }<br>-  const Expr *getArgExpr(unsigned Index) const {<br>+  virtual unsigned getNumArgs() const {<br>+    return getOriginExpr()->getNumArgs() - 1;<br>+  }<br>+  virtual const Expr *getArgExpr(unsigned Index) const {<br>     return getOriginExpr()->getArg(Index + 1);<br>   }<br><br>-  SVal getCXXThisVal() const;<br>+  virtual SVal getCXXThisVal() const;<br>+<br>+  virtual Kind getKind() const { return CE_CXXMemberOperator; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_CXXMemberOperator;<br>@@ -422,17 +411,15 @@<br> ///<br> /// Example: <tt>^{ /* ... */ }()</tt><br> class BlockCall : public SimpleCall {<br>-  friend class CallEvent;<br>-<br> protected:<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;<br><br>-  QualType getDeclaredResultType() const;<br>+  virtual QualType getDeclaredResultType() const;<br><br> public:<br>   BlockCall(const CallExpr *CE, ProgramStateRef St,<br>             const LocationContext *LCtx)<br>-    : SimpleCall(CE, St, LCtx, CE_Block) {}<br>+    : SimpleCall(CE, St, LCtx) {}<br><br>   /// \brief Returns the region associated with this instance of the block.<br>   ///<br>@@ -450,14 +437,14 @@<br>     return BR->getDecl();<br>   }<br><br>-  const Decl *getRuntimeDefinition() const {<br>+  virtual const Decl *getRuntimeDefinition() const {<br>     return getBlockDecl();<br>   }<br><br>-  param_iterator param_begin(bool UseDefinitionParams = false) const;<br>-  param_iterator param_end(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_begin(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_end(bool UseDefinitionParams = false) const;<br><br>-  SVal getCXXThisVal() const { return UndefinedVal(); }<br>+  virtual Kind getKind() const { return CE_Block; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_Block;<br>@@ -468,45 +455,41 @@<br> ///<br> /// Example: \c T(1)<br> class CXXConstructorCall : public AnyFunctionCall {<br>-  friend class CallEvent;<br>-<br> protected:<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;<br><br> public:<br>   /// Represents a constructor call to a new or unknown region.<br>   CXXConstructorCall(const CXXConstructExpr *CE, ProgramStateRef St,<br>                      const LocationContext *LCtx)<br>-    : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {<br>+    : AnyFunctionCall(CE, St, LCtx) {<br>     Data = 0;<br>   }<br><br>   /// Represents a constructor call on an existing object region.<br>   CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *target,<br>                      ProgramStateRef St, const LocationContext *LCtx)<br>-    : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {<br>+    : AnyFunctionCall(CE, St, LCtx) {<br>     Data = target;<br>   }<br><br>-  const CXXConstructExpr *getOriginExpr() const {<br>+  virtual const CXXConstructExpr *getOriginExpr() const {<br>     return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());<br>   }<br><br>-  SourceRange getSourceRange() const {<br>-    return getOriginExpr()->getSourceRange();<br>-  }<br>-<br>-  const CXXConstructorDecl *getDecl() const {<br>+  virtual const CXXConstructorDecl *getDecl() const {<br>     return getOriginExpr()->getConstructor();<br>   }<br><br>-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }<br>+  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }<br><br>-  const Expr *getArgExpr(unsigned Index) const {<br>+  virtual const Expr *getArgExpr(unsigned Index) const {<br>     return getOriginExpr()->getArg(Index);<br>   }<br><br>-  SVal getCXXThisVal() const;<br>+  virtual SVal getCXXThisVal() const;<br>+<br>+  virtual Kind getKind() const { return CE_CXXConstructor; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_CXXConstructor;<br>@@ -518,10 +501,8 @@<br> /// This can occur at the end of a scope (for automatic objects), at the end<br> /// of a full-expression (for temporaries), or as part of a delete.<br> class CXXDestructorCall : public AnyFunctionCall {<br>-  friend class CallEvent;<br>-<br> protected:<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;<br><br> public:<br>   /// Creates an implicit destructor.<br>@@ -534,16 +515,18 @@<br>   CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,<br>                     const MemRegion *Target, ProgramStateRef St,<br>                     const LocationContext *LCtx)<br>-    : AnyFunctionCall(DD, St, LCtx, CE_CXXDestructor) {<br>+    : AnyFunctionCall(DD, St, LCtx) {<br>     Data = Target;<br>     Location = Trigger->getLocEnd();<br>   }<br><br>-  SourceRange getSourceRange() const { return Location; }<br>-  unsigned getNumArgs() const { return 0; }<br>+  virtual SourceRange getSourceRange() const { return Location; }<br>+  virtual unsigned getNumArgs() const { return 0; }<br>+<br>+  virtual SVal getCXXThisVal() const;<br>+  virtual const Decl *getRuntimeDefinition() const;<br><br>-  SVal getCXXThisVal() const;<br>-  const Decl *getRuntimeDefinition() const;<br>+  virtual Kind getKind() const { return CE_CXXDestructor; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_CXXDestructor;<br>@@ -557,33 +540,28 @@<br> public:<br>   CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,<br>                    const LocationContext *LCtx)<br>-    : AnyFunctionCall(E, St, LCtx, CE_CXXAllocator) {}<br>+    : AnyFunctionCall(E, St, LCtx) {}<br><br>-  const CXXNewExpr *getOriginExpr() const {<br>+  virtual const CXXNewExpr *getOriginExpr() const {<br>     return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());<br>   }<br><br>-  // FIXME: This isn't exactly the range of the allocator...<br>-  SourceRange getSourceRange() const {<br>-    return getOriginExpr()->getSourceRange();<br>-  }<br>-<br>-  const FunctionDecl *getDecl() const {<br>+  virtual const FunctionDecl *getDecl() const {<br>     return getOriginExpr()->getOperatorNew();<br>   }<br><br>-  unsigned getNumArgs() const {<br>+  virtual unsigned getNumArgs() const {<br>     return getOriginExpr()->getNumPlacementArgs() + 1;<br>   }<br><br>-  const Expr *getArgExpr(unsigned Index) const {<br>+  virtual const Expr *getArgExpr(unsigned Index) const {<br>     // The first argument of an allocator call is the size of the allocation.<br>     if (Index == 0)<br>       return 0;<br>     return getOriginExpr()->getPlacementArg(Index - 1);<br>   }<br><br>-  SVal getCXXThisVal() const { return UndefinedVal(); }<br>+  virtual Kind getKind() const { return CE_CXXAllocator; }<br><br>   static bool classof(const CallEvent *CE) {<br>     return CE->getKind() == CE_CXXAllocator;<br>@@ -604,34 +582,32 @@<br> ///<br> /// This includes all of the kinds listed in ObjCMessageKind.<br> class ObjCMethodCall : public CallEvent {<br>-  friend class CallEvent;<br>-<br>   const PseudoObjectExpr *getContainingPseudoObjectExpr() const;<br><br> protected:<br>-  void getExtraInvalidatedRegions(RegionList &Regions) const;<br>+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;<br><br>-  QualType getDeclaredResultType() const;<br>+  virtual QualType getDeclaredResultType() const;<br>   ObjCMethodDecl *LookupClassMethodDefinition(Selector Sel,<br>                                            ObjCInterfaceDecl *ClassDecl) const;<br><br> public:<br>   ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,<br>                  const LocationContext *LCtx)<br>-    : CallEvent(Msg, St, LCtx, CE_ObjCMessage) {<br>+    : CallEvent(Msg, St, LCtx) {<br>     Data = 0;<br>   }<br><br>-  const ObjCMessageExpr *getOriginExpr() const {<br>+  virtual const ObjCMessageExpr *getOriginExpr() const {<br>     return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());<br>   }<br>-  const ObjCMethodDecl *getDecl() const {<br>+  virtual const ObjCMethodDecl *getDecl() const {<br>     return getOriginExpr()->getMethodDecl();<br>   }<br>-  unsigned getNumArgs() const {<br>+  virtual unsigned getNumArgs() const {<br>     return getOriginExpr()->getNumArgs();<br>   }<br>-  const Expr *getArgExpr(unsigned Index) const {<br>+  virtual const Expr *getArgExpr(unsigned Index) const {<br>     return getOriginExpr()->getArg(Index);<br>   }<br><br>@@ -645,7 +621,7 @@<br>     return getOriginExpr()->getSelector();<br>   }<br><br>-  SourceRange getSourceRange() const;<br>+  virtual SourceRange getSourceRange() const;<br><br>   /// \brief Returns the value of the receiver at the time of this call.<br>   SVal getReceiverSVal() const;<br>@@ -675,7 +651,7 @@<br>   // TODO: We might want to only compute this once (or change the API for <br>   // getting the parameters). Currently, this gets called 3 times during <br>   // inlining.<br>-  const Decl *getRuntimeDefinition() const {<br>+  virtual const Decl *getRuntimeDefinition() const {<br><br>     const ObjCMessageExpr *E = getOriginExpr();<br>     if (E->isInstanceMessage()) {<br>@@ -692,129 +668,16 @@<br>     return 0;<br>   }<br><br>-  SVal getCXXThisVal() const { return UndefinedVal(); }<br>+  virtual param_iterator param_begin(bool UseDefinitionParams = false) const;<br>+  virtual param_iterator param_end(bool UseDefinitionParams = false) const;<br><br>-  bool argumentsMayEscape() const {<br>-    return hasNonZeroCallbackArg();<br>-  }<br>-  <br>-  SVal getArgSVal(unsigned Index) const { return getSVal(getArgExpr(Index)); }<br>-  SourceRange getArgSourceRange(unsigned Index) const {<br>-    return getArgExpr(Index)->getSourceRange();<br>-  }<br>-<br>-  param_iterator param_begin(bool UseDefinitionParams = false) const;<br>-  param_iterator param_end(bool UseDefinitionParams = false) const;<br>+  virtual Kind getKind() const { return CE_ObjCMessage; }<br><br>   static bool classof(const CallEvent *CA) {<br>     return CA->getKind() == CE_ObjCMessage;<br>   }<br> };<br><br>-<br>-// FIXME: Use a .def or .td file for this.<br>-#define DISPATCH(fn) \<br>-  switch (getKind()) { \<br>-  case CE_Function: \<br>-    return cast<FunctionCall>(this)->fn(); \<br>-  case CE_CXXMember: \<br>-    return cast<CXXMemberCall>(this)->fn(); \<br>-  case CE_CXXMemberOperator: \<br>-    return cast<CXXMemberOperatorCall>(this)->fn(); \<br>-  case CE_Block: \<br>-    return cast<BlockCall>(this)->fn(); \<br>-  case CE_CXXConstructor: \<br>-    return cast<CXXConstructorCall>(this)->fn(); \<br>-  case CE_CXXDestructor: \<br>-    return cast<CXXDestructorCall>(this)->fn(); \<br>-  case CE_CXXAllocator: \<br>-    return cast<CXXAllocatorCall>(this)->fn(); \<br>-  case CE_ObjCMessage: \<br>-    return cast<ObjCMethodCall>(this)->fn(); \<br>-  } \<br>-  llvm_unreachable("unknown CallEvent kind");<br>-<br>-#define DISPATCH_ARG(fn, arg) \<br>-  switch (getKind()) { \<br>-  case CE_Function: \<br>-    return cast<FunctionCall>(this)->fn(arg); \<br>-  case CE_CXXMember: \<br>-    return cast<CXXMemberCall>(this)->fn(arg); \<br>-  case CE_CXXMemberOperator: \<br>-    return cast<CXXMemberOperatorCall>(this)->fn(arg); \<br>-  case CE_Block: \<br>-    return cast<BlockCall>(this)->fn(arg); \<br>-  case CE_CXXConstructor: \<br>-    return cast<CXXConstructorCall>(this)->fn(arg); \<br>-  case CE_CXXDestructor: \<br>-    return cast<CXXDestructorCall>(this)->fn(arg); \<br>-  case CE_CXXAllocator: \<br>-    return cast<CXXAllocatorCall>(this)->fn(arg); \<br>-  case CE_ObjCMessage: \<br>-    return cast<ObjCMethodCall>(this)->fn(arg); \<br>-  } \<br>-  llvm_unreachable("unknown CallEvent kind");<br>-<br>-inline void CallEvent::getExtraInvalidatedRegions(RegionList &Regions) const {<br>-  DISPATCH_ARG(getExtraInvalidatedRegions, Regions);<br>-}<br>-<br>-inline QualType CallEvent::getDeclaredResultType() const {<br>-  DISPATCH(getDeclaredResultType);<br>-}<br>-<br>-inline const Decl *CallEvent::getDecl() const {<br>-  if (const Decl *D = Origin.dyn_cast<const Decl *>())<br>-    return D;<br>-  DISPATCH(getDecl);<br>-}<br>-<br>-inline const Decl *CallEvent::getRuntimeDefinition() const {<br>-  DISPATCH(getRuntimeDefinition);<br>-}<br>-<br>-inline unsigned CallEvent::getNumArgs() const {<br>-  DISPATCH(getNumArgs);<br>-}<br>-<br>-inline SourceRange CallEvent::getSourceRange() const {<br>-  DISPATCH(getSourceRange);<br>-}<br>-<br>-inline SVal CallEvent::getArgSVal(unsigned Index) const {<br>-  DISPATCH_ARG(getArgSVal, Index);<br>-}<br>-<br>-inline const Expr *CallEvent::getArgExpr(unsigned Index) const {<br>-  DISPATCH_ARG(getArgExpr, Index);<br>-}<br>-<br>-inline SourceRange CallEvent::getArgSourceRange(unsigned Index) const {<br>-  DISPATCH_ARG(getArgSourceRange, Index);<br>-}<br>-<br>-inline SVal CallEvent::getCXXThisVal() const {<br>-  DISPATCH(getCXXThisVal);<br>-}<br>-<br>-<br>-inline bool CallEvent::argumentsMayEscape() const {<br>-  DISPATCH(argumentsMayEscape);<br>-}<br>-<br>-inline CallEvent::param_iterator<br>-CallEvent::param_begin(bool UseDefinitionParams) const {<br>-  DISPATCH_ARG(param_begin, UseDefinitionParams);<br>-}<br>-<br>-inline CallEvent::param_iterator<br>-CallEvent::param_end(bool UseDefinitionParams) const {<br>-  DISPATCH_ARG(param_end, UseDefinitionParams);<br>-}<br>-<br>-#undef DISPATCH<br>-#undef DISPATCH_ARG<br>-<br> } // end namespace ento<br> } // end namespace clang<br><br><br>Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=160817&r1=160816&r2=160817&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=160817&r1=160816&r2=160817&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)<br>+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Jul 26 16:41:15 2012<br>@@ -193,9 +193,43 @@<br>   return PostImplicitCall(D, Loc, getLocationContext(), Tag);<br> }<br><br>+SVal CallEvent::getArgSVal(unsigned Index) const {<br>+  const Expr *ArgE = getArgExpr(Index);<br>+  if (!ArgE)<br>+    return UnknownVal();<br>+  return getSVal(ArgE);<br>+}<br>+<br>+SourceRange CallEvent::getArgSourceRange(unsigned Index) const {<br>+  const Expr *ArgE = getArgExpr(Index);<br>+  if (!ArgE)<br>+    return SourceRange();<br>+  return ArgE->getSourceRange();<br>+}<br>+<br>+void CallEvent::dump(raw_ostream &Out) const {<br>+  ASTContext &Ctx = getState()->getStateManager().getContext();<br>+  if (const Expr *E = getOriginExpr()) {<br>+    E->printPretty(Out, Ctx, 0, Ctx.getPrintingPolicy());<br>+    Out << "\n";<br>+    return;<br>+  }<br>+<br>+  if (const Decl *D = getDecl()) {<br>+    Out << "Call to ";<br>+    D->print(Out, Ctx.getPrintingPolicy());<br>+    return;<br>+  }<br>+<br>+  // FIXME: a string representation of the kind would be nice.<br>+  Out << "Unknown call (type " << getKind() << ")";<br>+}<br>+<br><br> bool CallEvent::mayBeInlined(const Stmt *S) {<br>-  return isa<CallExpr>(S);<br>+  // FIXME: Kill this.<br>+  return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)<br>+                          || isa<CXXConstructExpr>(S);<br> }<br><br><br>@@ -283,20 +317,6 @@<br>   return false;<br> }<br><br>-SVal AnyFunctionCall::getArgSVal(unsigned Index) const {<br>-  const Expr *ArgE = getArgExpr(Index);<br>-  if (!ArgE)<br>-    return UnknownVal();<br>-  return getSVal(ArgE);<br>-}<br>-<br>-SourceRange AnyFunctionCall::getArgSourceRange(unsigned Index) const {<br>-  const Expr *ArgE = getArgExpr(Index);<br>-  if (!ArgE)<br>-    return SourceRange();<br>-  return ArgE->getSourceRange();<br>-}<br>-<br><br> const FunctionDecl *SimpleCall::getDecl() const {<br>   const FunctionDecl *D = getOriginExpr()->getDirectCallee();<br>@@ -306,24 +326,6 @@<br>   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();<br> }<br><br>-void CallEvent::dump(raw_ostream &Out) const {<br>-  ASTContext &Ctx = getState()->getStateManager().getContext();<br>-  if (const Expr *E = getOriginExpr()) {<br>-    E->printPretty(Out, Ctx, 0, Ctx.getLangOpts());<br>-    Out << "\n";<br>-    return;<br>-  }<br>-<br>-  if (const Decl *D = getDecl()) {<br>-    Out << "Call to ";<br>-    D->print(Out, Ctx.getLangOpts());<br>-    return;<br>-  }<br>-<br>-  // FIXME: a string representation of the kind would be nice.<br>-  Out << "Unknown call (type " << getKind() << ")";<br>-}<br>-<br><br> void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {<br>   if (const MemRegion *R = getCXXThisVal().getAsRegion())<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></blockquote></div><br></div></blockquote></div><br></body></html>