1ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===//
2ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//
3ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
4ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//
5ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
6ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
7ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//
8ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
9ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//
10ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis// Adds brackets in case statements that "contain" initialization of retaining
11ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis// variable, thus emitting the "switch case is in protected scope" error.
12ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//
13ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
14ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
15ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis#include "Transforms.h"
16ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis#include "Internals.h"
174ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis#include "clang/AST/ASTContext.h"
18b1ba0efc3d1dc1daa5d82c40bc504e1f368c4fa0Chandler Carruth#include "clang/Sema/SemaDiagnostic.h"
19ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
20ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisusing namespace clang;
21ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisusing namespace arcmt;
22ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisusing namespace trans;
23ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
24ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisnamespace {
25ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
264ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidisclass LocalRefsCollector : public RecursiveASTVisitor<LocalRefsCollector> {
274ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  SmallVectorImpl<DeclRefExpr *> &Refs;
284ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
294ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidispublic:
304ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  LocalRefsCollector(SmallVectorImpl<DeclRefExpr *> &refs)
314ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    : Refs(refs) { }
324ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
334ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  bool VisitDeclRefExpr(DeclRefExpr *E) {
344ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    if (ValueDecl *D = E->getDecl())
354ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
364ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        Refs.push_back(E);
374ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    return true;
384ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  }
394ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis};
404ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
41ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisstruct CaseInfo {
42ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  SwitchCase *SC;
43ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  SourceRange Range;
444ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  enum {
454ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    St_Unchecked,
464ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    St_CannotFix,
474ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    St_Fixed
484ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  } State;
49ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
504ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  CaseInfo() : SC(0), State(St_Unchecked) {}
51ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  CaseInfo(SwitchCase *S, SourceRange Range)
524ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    : SC(S), Range(Range), State(St_Unchecked) {}
53ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis};
54ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
55ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidisclass CaseCollector : public RecursiveASTVisitor<CaseCollector> {
564ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  ParentMap &PMap;
57cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVectorImpl<CaseInfo> &Cases;
58ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
59ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidispublic:
60cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  CaseCollector(ParentMap &PMap, SmallVectorImpl<CaseInfo> &Cases)
614ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    : PMap(PMap), Cases(Cases) { }
62ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
63ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  bool VisitSwitchStmt(SwitchStmt *S) {
64ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    SwitchCase *Curr = S->getSwitchCaseList();
654ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    if (!Curr)
664ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      return true;
674ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Stmt *Parent = getCaseParent(Curr);
684ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Curr = Curr->getNextSwitchCase();
694ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    // Make sure all case statements are in the same scope.
704ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    while (Curr) {
714ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (getCaseParent(Curr) != Parent)
724ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        return true;
734ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      Curr = Curr->getNextSwitchCase();
744ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    }
754ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
764ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    SourceLocation NextLoc = S->getLocEnd();
774ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Curr = S->getSwitchCaseList();
78ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    // We iterate over case statements in reverse source-order.
79ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    while (Curr) {
80ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis      Cases.push_back(CaseInfo(Curr,SourceRange(Curr->getLocStart(), NextLoc)));
81ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis      NextLoc = Curr->getLocStart();
82ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis      Curr = Curr->getNextSwitchCase();
83ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    }
84ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    return true;
85ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  }
86ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
874ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  Stmt *getCaseParent(SwitchCase *S) {
884ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Stmt *Parent = PMap.getParent(S);
894ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    while (Parent && (isa<SwitchCase>(Parent) || isa<LabelStmt>(Parent)))
904ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      Parent = PMap.getParent(Parent);
914ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    return Parent;
924ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  }
934ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis};
94ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
954ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidisclass ProtectedScopeFixer {
964ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  MigrationPass &Pass;
974ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  SourceManager &SM;
984ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  SmallVector<CaseInfo, 16> Cases;
994ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  SmallVector<DeclRefExpr *, 16> LocalRefs;
100ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
1014ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidispublic:
1024ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  ProtectedScopeFixer(BodyContext &BodyCtx)
1034ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    : Pass(BodyCtx.getMigrationContext().Pass),
1044ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      SM(Pass.Ctx.getSourceManager()) {
1054ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1064ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    CaseCollector(BodyCtx.getParentMap(), Cases)
1074ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        .TraverseStmt(BodyCtx.getTopStmt());
1084ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    LocalRefsCollector(LocalRefs).TraverseStmt(BodyCtx.getTopStmt());
1094ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1104ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    SourceRange BodyRange = BodyCtx.getTopStmt()->getSourceRange();
1114ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    const CapturedDiagList &DiagList = Pass.getDiags();
1124ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    CapturedDiagList::iterator I = DiagList.begin(), E = DiagList.end();
1134ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    while (I != E) {
1144ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (I->getID() == diag::err_switch_into_protected_scope &&
1154ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis          isInRange(I->getLocation(), BodyRange)) {
1164ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        handleProtectedScopeError(I, E);
1174ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        continue;
118ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis      }
1194ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      ++I;
120ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    }
121ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  }
122ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
1234ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  void handleProtectedScopeError(CapturedDiagList::iterator &DiagI,
1244ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis                                 CapturedDiagList::iterator DiagE) {
1254ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Transaction Trans(Pass.TA);
1264ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    assert(DiagI->getID() == diag::err_switch_into_protected_scope);
1274ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    SourceLocation ErrLoc = DiagI->getLocation();
1284ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    bool handledAllNotes = true;
1294ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    ++DiagI;
1304ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    for (; DiagI != DiagE && DiagI->getLevel() == DiagnosticsEngine::Note;
1314ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis         ++DiagI) {
1324ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (!handleProtectedNote(*DiagI))
1334ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        handledAllNotes = false;
1344ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    }
135ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
1364ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    if (handledAllNotes)
1374ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      Pass.TA.clearDiagnostic(diag::err_switch_into_protected_scope, ErrLoc);
138ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  }
139ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
1404ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  bool handleProtectedNote(const StoredDiagnostic &Diag) {
1414ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    assert(Diag.getLevel() == DiagnosticsEngine::Note);
142ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis
1434ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    for (unsigned i = 0; i != Cases.size(); i++) {
1444ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      CaseInfo &info = Cases[i];
1454ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (isInRange(Diag.getLocation(), info.Range)) {
1464ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1474ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        if (info.State == CaseInfo::St_Unchecked)
1484ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis          tryFixing(info);
1494ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        assert(info.State != CaseInfo::St_Unchecked);
1504ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1514ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        if (info.State == CaseInfo::St_Fixed) {
1524ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis          Pass.TA.clearDiagnostic(Diag.getID(), Diag.getLocation());
1534ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis          return true;
1544ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        }
1554ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        return false;
1564ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      }
1574ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    }
1584ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1594ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    return false;
1604ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  }
1614ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1624ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  void tryFixing(CaseInfo &info) {
1634ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    assert(info.State == CaseInfo::St_Unchecked);
1644ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    if (hasVarReferencedOutside(info)) {
1654ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      info.State = CaseInfo::St_CannotFix;
1664ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      return;
167ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis    }
1684ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1694ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Pass.TA.insertAfterToken(info.SC->getColonLoc(), " {");
1704ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    Pass.TA.insert(info.Range.getEnd(), "}\n");
1714ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    info.State = CaseInfo::St_Fixed;
1724ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  }
1734ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1744ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  bool hasVarReferencedOutside(CaseInfo &info) {
1754ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    for (unsigned i = 0, e = LocalRefs.size(); i != e; ++i) {
1764ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      DeclRefExpr *DRE = LocalRefs[i];
1774ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      if (isInRange(DRE->getDecl()->getLocation(), info.Range) &&
1784ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis          !isInRange(DRE->getLocation(), info.Range))
1794ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis        return true;
1804ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    }
1814ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    return false;
1824ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  }
1834ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1844ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  bool isInRange(SourceLocation Loc, SourceRange R) {
1854ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    if (Loc.isInvalid())
1864ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis      return false;
1874ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis    return !SM.isBeforeInTranslationUnit(Loc, R.getBegin()) &&
1884ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis            SM.isBeforeInTranslationUnit(Loc, R.getEnd());
189ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis  }
1904ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis};
1914ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1924ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis} // anonymous namespace
1934ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis
1944ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidisvoid ProtectedScopeTraverser::traverseBody(BodyContext &BodyCtx) {
1954ce831cba3ae3030674fd9d90f8a69f7b3938d63Argyrios Kyrtzidis  ProtectedScopeFixer Fix(BodyCtx);
196ea2224d7078c4d31ad32adbaba4bdc2d85a3d609Argyrios Kyrtzidis}
197