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