ScopeInfo.h revision 820b23dc924a4ae7af07d5a75d6b1d781c267d57
1//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines FunctionScopeInfo and its subclasses, which contain
11// information about a single function, block, lambda, or method body.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
16#define LLVM_CLANG_SEMA_SCOPE_INFO_H
17
18#include "clang/AST/Type.h"
19#include "clang/Basic/PartialDiagnostic.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallVector.h"
22
23namespace clang {
24
25class Decl;
26class BlockDecl;
27class CXXMethodDecl;
28class ObjCPropertyDecl;
29class IdentifierInfo;
30class LabelDecl;
31class ReturnStmt;
32class Scope;
33class SwitchStmt;
34class VarDecl;
35class DeclRefExpr;
36class ObjCIvarRefExpr;
37class ObjCPropertyRefExpr;
38class ObjCMessageExpr;
39
40namespace sema {
41
42/// \brief Contains information about the compound statement currently being
43/// parsed.
44class CompoundScopeInfo {
45public:
46  CompoundScopeInfo()
47    : HasEmptyLoopBodies(false) { }
48
49  /// \brief Whether this compound stamement contains `for' or `while' loops
50  /// with empty bodies.
51  bool HasEmptyLoopBodies;
52
53  void setHasEmptyLoopBodies() {
54    HasEmptyLoopBodies = true;
55  }
56};
57
58class PossiblyUnreachableDiag {
59public:
60  PartialDiagnostic PD;
61  SourceLocation Loc;
62  const Stmt *stmt;
63
64  PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
65                          const Stmt *stmt)
66    : PD(PD), Loc(Loc), stmt(stmt) {}
67};
68
69/// \brief Retains information about a function, method, or block that is
70/// currently being parsed.
71class FunctionScopeInfo {
72protected:
73  enum ScopeKind {
74    SK_Function,
75    SK_Block,
76    SK_Lambda
77  };
78
79public:
80  /// \brief What kind of scope we are describing.
81  ///
82  ScopeKind Kind;
83
84  /// \brief Whether this function contains a VLA, \@try, try, C++
85  /// initializer, or anything else that can't be jumped past.
86  bool HasBranchProtectedScope;
87
88  /// \brief Whether this function contains any switches or direct gotos.
89  bool HasBranchIntoScope;
90
91  /// \brief Whether this function contains any indirect gotos.
92  bool HasIndirectGoto;
93
94  /// \brief Whether a statement was dropped because it was invalid.
95  bool HasDroppedStmt;
96
97  /// A flag that is set when parsing a method that must call super's
98  /// implementation, such as \c -dealloc, \c -finalize, or any method marked
99  /// with \c __attribute__((objc_requires_super)).
100  bool ObjCShouldCallSuper;
101
102  /// \brief Used to determine if errors occurred in this function or block.
103  DiagnosticErrorTrap ErrorTrap;
104
105  /// SwitchStack - This is the current set of active switch statements in the
106  /// block.
107  SmallVector<SwitchStmt*, 8> SwitchStack;
108
109  /// \brief The list of return statements that occur within the function or
110  /// block, if there is any chance of applying the named return value
111  /// optimization, or if we need to infer a return type.
112  SmallVector<ReturnStmt*, 4> Returns;
113
114  /// \brief The stack of currently active compound stamement scopes in the
115  /// function.
116  SmallVector<CompoundScopeInfo, 4> CompoundScopes;
117
118  /// \brief A list of PartialDiagnostics created but delayed within the
119  /// current function scope.  These diagnostics are vetted for reachability
120  /// prior to being emitted.
121  SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
122
123public:
124  /// Represents a simple identification of a weak object.
125  ///
126  /// Part of the implementation of -Wrepeated-use-of-weak.
127  ///
128  /// This is used to determine if two weak accesses refer to the same object.
129  /// Here are some examples of how various accesses are "profiled":
130  ///
131  /// Access Expression |     "Base" Decl     |          "Property" Decl
132  /// :---------------: | :-----------------: | :------------------------------:
133  /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
134  /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
135  /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
136  /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
137  /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
138  /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
139  /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
140  /// weakVar           | 0 (known)           | weakVar (VarDecl)
141  /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
142  ///
143  /// Objects are identified with only two Decls to make it reasonably fast to
144  /// compare them.
145  class WeakObjectProfileTy {
146    /// The base object decl, as described in the class documentation.
147    ///
148    /// The extra flag is "true" if the Base and Property are enough to uniquely
149    /// identify the object in memory.
150    ///
151    /// \sa isExactProfile()
152    typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
153    BaseInfoTy Base;
154
155    /// The "property" decl, as described in the class documentation.
156    ///
157    /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
158    /// case of "implicit" properties (regular methods accessed via dot syntax).
159    const NamedDecl *Property;
160
161    /// Used to find the proper base profile for a given base expression.
162    static BaseInfoTy getBaseInfo(const Expr *BaseE);
163
164    // For use in DenseMap.
165    friend class DenseMapInfo;
166    inline WeakObjectProfileTy();
167    static inline WeakObjectProfileTy getSentinel();
168
169  public:
170    WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
171    WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
172    WeakObjectProfileTy(const DeclRefExpr *RE);
173    WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
174
175    const NamedDecl *getBase() const { return Base.getPointer(); }
176    const NamedDecl *getProperty() const { return Property; }
177
178    /// Returns true if the object base specifies a known object in memory,
179    /// rather than, say, an instance variable or property of another object.
180    ///
181    /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
182    /// considered an exact profile if \c foo is a local variable, even if
183    /// another variable \c foo2 refers to the same object as \c foo.
184    ///
185    /// For increased precision, accesses with base variables that are
186    /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
187    /// be exact, though this is not true for arbitrary variables
188    /// (foo.prop1.prop2).
189    bool isExactProfile() const {
190      return Base.getInt();
191    }
192
193    bool operator==(const WeakObjectProfileTy &Other) const {
194      return Base == Other.Base && Property == Other.Property;
195    }
196
197    // For use in DenseMap.
198    // We can't specialize the usual llvm::DenseMapInfo at the end of the file
199    // because by that point the DenseMap in FunctionScopeInfo has already been
200    // instantiated.
201    class DenseMapInfo {
202    public:
203      static inline WeakObjectProfileTy getEmptyKey() {
204        return WeakObjectProfileTy();
205      }
206      static inline WeakObjectProfileTy getTombstoneKey() {
207        return WeakObjectProfileTy::getSentinel();
208      }
209
210      static unsigned getHashValue(const WeakObjectProfileTy &Val) {
211        typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
212        return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
213                                                           Val.Property));
214      }
215
216      static bool isEqual(const WeakObjectProfileTy &LHS,
217                          const WeakObjectProfileTy &RHS) {
218        return LHS == RHS;
219      }
220    };
221  };
222
223  /// Represents a single use of a weak object.
224  ///
225  /// Stores both the expression and whether the access is potentially unsafe
226  /// (i.e. it could potentially be warned about).
227  ///
228  /// Part of the implementation of -Wrepeated-use-of-weak.
229  class WeakUseTy {
230    llvm::PointerIntPair<const Expr *, 1, bool> Rep;
231  public:
232    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
233
234    const Expr *getUseExpr() const { return Rep.getPointer(); }
235    bool isUnsafe() const { return Rep.getInt(); }
236    void markSafe() { Rep.setInt(false); }
237
238    bool operator==(const WeakUseTy &Other) const {
239      return Rep == Other.Rep;
240    }
241  };
242
243  /// Used to collect uses of a particular weak object in a function body.
244  ///
245  /// Part of the implementation of -Wrepeated-use-of-weak.
246  typedef SmallVector<WeakUseTy, 4> WeakUseVector;
247
248  /// Used to collect all uses of weak objects in a function body.
249  ///
250  /// Part of the implementation of -Wrepeated-use-of-weak.
251  typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
252                              WeakObjectProfileTy::DenseMapInfo>
253          WeakObjectUseMap;
254
255private:
256  /// Used to collect all uses of weak objects in this function body.
257  ///
258  /// Part of the implementation of -Wrepeated-use-of-weak.
259  WeakObjectUseMap WeakObjectUses;
260
261public:
262  /// Record that a weak object was accessed.
263  ///
264  /// Part of the implementation of -Wrepeated-use-of-weak.
265  template <typename ExprT>
266  inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
267
268  void recordUseOfWeak(const ObjCMessageExpr *Msg,
269                       const ObjCPropertyDecl *Prop);
270
271  /// Record that a given expression is a "safe" access of a weak object (e.g.
272  /// assigning it to a strong variable.)
273  ///
274  /// Part of the implementation of -Wrepeated-use-of-weak.
275  void markSafeWeakUse(const Expr *E);
276
277  const WeakObjectUseMap &getWeakObjectUses() const {
278    return WeakObjectUses;
279  }
280
281  void setHasBranchIntoScope() {
282    HasBranchIntoScope = true;
283  }
284
285  void setHasBranchProtectedScope() {
286    HasBranchProtectedScope = true;
287  }
288
289  void setHasIndirectGoto() {
290    HasIndirectGoto = true;
291  }
292
293  void setHasDroppedStmt() {
294    HasDroppedStmt = true;
295  }
296
297  bool NeedsScopeChecking() const {
298    return !HasDroppedStmt &&
299        (HasIndirectGoto ||
300          (HasBranchProtectedScope && HasBranchIntoScope));
301  }
302
303  FunctionScopeInfo(DiagnosticsEngine &Diag)
304    : Kind(SK_Function),
305      HasBranchProtectedScope(false),
306      HasBranchIntoScope(false),
307      HasIndirectGoto(false),
308      HasDroppedStmt(false),
309      ObjCShouldCallSuper(false),
310      ErrorTrap(Diag) { }
311
312  virtual ~FunctionScopeInfo();
313
314  /// \brief Clear out the information in this function scope, making it
315  /// suitable for reuse.
316  void Clear();
317};
318
319class CapturingScopeInfo : public FunctionScopeInfo {
320public:
321  enum ImplicitCaptureStyle {
322    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
323  };
324
325  ImplicitCaptureStyle ImpCaptureStyle;
326
327  class Capture {
328    // There are two categories of capture: capturing 'this', and capturing
329    // local variables.  There are three ways to capture a local variable:
330    // capture by copy in the C++11 sense, capture by reference
331    // in the C++11 sense, and __block capture.  Lambdas explicitly specify
332    // capture by copy or capture by reference.  For blocks, __block capture
333    // applies to variables with that annotation, variables of reference type
334    // are captured by reference, and other variables are captured by copy.
335    enum CaptureKind {
336      Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
337    };
338
339    // The variable being captured (if we are not capturing 'this'),
340    // and misc bits descibing the capture.
341    llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
342
343    // Expression to initialize a field of the given type, and whether this
344    // is a nested capture; the expression is only required if we are
345    // capturing ByVal and the variable's type has a non-trivial
346    // copy constructor.
347    llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
348
349    /// \brief The source location at which the first capture occurred..
350    SourceLocation Loc;
351
352    /// \brief The location of the ellipsis that expands a parameter pack.
353    SourceLocation EllipsisLoc;
354
355    /// \brief The type as it was captured, which is in effect the type of the
356    /// non-static data member that would hold the capture.
357    QualType CaptureType;
358
359  public:
360    Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
361            SourceLocation Loc, SourceLocation EllipsisLoc,
362            QualType CaptureType, Expr *Cpy)
363      : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
364        CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
365        CaptureType(CaptureType){}
366
367    enum IsThisCapture { ThisCapture };
368    Capture(IsThisCapture, bool isNested, SourceLocation Loc,
369            QualType CaptureType, Expr *Cpy)
370      : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
371        EllipsisLoc(), CaptureType(CaptureType) { }
372
373    bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
374    bool isVariableCapture() const { return !isThisCapture(); }
375    bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
376    bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
377    bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
378    bool isNested() { return CopyExprAndNested.getInt(); }
379
380    VarDecl *getVariable() const {
381      return VarAndKind.getPointer();
382    }
383
384    /// \brief Retrieve the location at which this variable was captured.
385    SourceLocation getLocation() const { return Loc; }
386
387    /// \brief Retrieve the source location of the ellipsis, whose presence
388    /// indicates that the capture is a pack expansion.
389    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
390
391    /// \brief Retrieve the capture type for this capture, which is effectively
392    /// the type of the non-static data member in the lambda/block structure
393    /// that would store this capture.
394    QualType getCaptureType() const { return CaptureType; }
395
396    Expr *getCopyExpr() const {
397      return CopyExprAndNested.getPointer();
398    }
399  };
400
401  CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
402    : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
403      HasImplicitReturnType(false)
404     {}
405
406  /// CaptureMap - A map of captured variables to (index+1) into Captures.
407  llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
408
409  /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
410  /// zero if 'this' is not captured.
411  unsigned CXXThisCaptureIndex;
412
413  /// Captures - The captures.
414  SmallVector<Capture, 4> Captures;
415
416  /// \brief - Whether the target type of return statements in this context
417  /// is deduced (e.g. a lambda or block with omitted return type).
418  bool HasImplicitReturnType;
419
420  /// ReturnType - The target type of return statements in this context,
421  /// or null if unknown.
422  QualType ReturnType;
423
424  void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
425                  SourceLocation Loc, SourceLocation EllipsisLoc,
426                  QualType CaptureType, Expr *Cpy) {
427    Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
428                               EllipsisLoc, CaptureType, Cpy));
429    CaptureMap[Var] = Captures.size();
430  }
431
432  void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
433                      Expr *Cpy);
434
435  /// \brief Determine whether the C++ 'this' is captured.
436  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
437
438  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
439  Capture &getCXXThisCapture() {
440    assert(isCXXThisCaptured() && "this has not been captured");
441    return Captures[CXXThisCaptureIndex - 1];
442  }
443
444  /// \brief Determine whether the given variable has been captured.
445  bool isCaptured(VarDecl *Var) const {
446    return CaptureMap.count(Var);
447  }
448
449  /// \brief Retrieve the capture of the given variable, if it has been
450  /// captured already.
451  Capture &getCapture(VarDecl *Var) {
452    assert(isCaptured(Var) && "Variable has not been captured");
453    return Captures[CaptureMap[Var] - 1];
454  }
455
456  const Capture &getCapture(VarDecl *Var) const {
457    llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
458      = CaptureMap.find(Var);
459    assert(Known != CaptureMap.end() && "Variable has not been captured");
460    return Captures[Known->second - 1];
461  }
462
463  static bool classof(const FunctionScopeInfo *FSI) {
464    return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
465  }
466};
467
468/// \brief Retains information about a block that is currently being parsed.
469class BlockScopeInfo : public CapturingScopeInfo {
470public:
471  BlockDecl *TheDecl;
472
473  /// TheScope - This is the scope for the block itself, which contains
474  /// arguments etc.
475  Scope *TheScope;
476
477  /// BlockType - The function type of the block, if one was given.
478  /// Its return type may be BuiltinType::Dependent.
479  QualType FunctionType;
480
481  BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
482    : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
483      TheScope(BlockScope)
484  {
485    Kind = SK_Block;
486  }
487
488  virtual ~BlockScopeInfo();
489
490  static bool classof(const FunctionScopeInfo *FSI) {
491    return FSI->Kind == SK_Block;
492  }
493};
494
495class LambdaScopeInfo : public CapturingScopeInfo {
496public:
497  /// \brief The class that describes the lambda.
498  CXXRecordDecl *Lambda;
499
500  /// \brief The class that describes the lambda.
501  CXXMethodDecl *CallOperator;
502
503  /// \brief Source range covering the lambda introducer [...].
504  SourceRange IntroducerRange;
505
506  /// \brief The number of captures in the \c Captures list that are
507  /// explicit captures.
508  unsigned NumExplicitCaptures;
509
510  /// \brief Whether this is a mutable lambda.
511  bool Mutable;
512
513  /// \brief Whether the (empty) parameter list is explicit.
514  bool ExplicitParams;
515
516  /// \brief Whether any of the capture expressions requires cleanups.
517  bool ExprNeedsCleanups;
518
519  /// \brief Whether the lambda contains an unexpanded parameter pack.
520  bool ContainsUnexpandedParameterPack;
521
522  /// \brief Variables used to index into by-copy array captures.
523  SmallVector<VarDecl *, 4> ArrayIndexVars;
524
525  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
526  /// its list of array index variables.
527  SmallVector<unsigned, 4> ArrayIndexStarts;
528
529  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
530                  CXXMethodDecl *CallOperator)
531    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
532      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
533      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
534  {
535    Kind = SK_Lambda;
536  }
537
538  virtual ~LambdaScopeInfo();
539
540  /// \brief Note when
541  void finishedExplicitCaptures() {
542    NumExplicitCaptures = Captures.size();
543  }
544
545  static bool classof(const FunctionScopeInfo *FSI) {
546    return FSI->Kind == SK_Lambda;
547  }
548};
549
550
551FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
552  : Base(0, false), Property(0) {}
553
554FunctionScopeInfo::WeakObjectProfileTy
555FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
556  FunctionScopeInfo::WeakObjectProfileTy Result;
557  Result.Base.setInt(true);
558  return Result;
559}
560
561template <typename ExprT>
562void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
563  assert(E);
564  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
565  Uses.push_back(WeakUseTy(E, IsRead));
566}
567
568inline void
569CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
570                                   QualType CaptureType, Expr *Cpy) {
571  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
572                             Cpy));
573  CXXThisCaptureIndex = Captures.size();
574
575  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
576    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
577}
578
579} // end namespace sema
580} // end namespace clang
581
582#endif
583