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