20 using namespace clang;
21 using namespace arcmt;
22 using namespace trans;
35 if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
50 CaseInfo() : SC(nullptr),
State(St_Unchecked) {}
52 : SC(S), Range(Range),
State(St_Unchecked) {}
61 : PMap(PMap), Cases(Cases) { }
67 Stmt *Parent = getCaseParent(Curr);
71 if (getCaseParent(Curr) != Parent)
88 Stmt *Parent = PMap.getParent(S);
89 while (Parent && (isa<SwitchCase>(Parent) || isa<LabelStmt>(Parent)))
90 Parent = PMap.getParent(Parent);
95 class ProtectedScopeFixer {
103 : Pass(BodyCtx.getMigrationContext().Pass),
104 SM(Pass.Ctx.getSourceManager()) {
108 LocalRefsCollector(LocalRefs).TraverseStmt(BodyCtx.
getTopStmt());
115 StoredDiags.append(DiagList.
begin(), DiagList.
end());
117 I = StoredDiags.begin(), E = StoredDiags.end();
119 if (I->getID() == diag::err_switch_into_protected_scope &&
120 isInRange(I->getLocation(), BodyRange)) {
121 handleProtectedScopeError(I, E);
128 void handleProtectedScopeError(
132 assert(DiagI->getID() == diag::err_switch_into_protected_scope);
134 bool handledAllNotes =
true;
138 if (!handleProtectedNote(*DiagI))
139 handledAllNotes =
false;
143 Pass.TA.clearDiagnostic(diag::err_switch_into_protected_scope, ErrLoc);
149 for (
unsigned i = 0; i != Cases.size(); i++) {
150 CaseInfo &info = Cases[i];
153 if (info.State == CaseInfo::St_Unchecked)
155 assert(info.State != CaseInfo::St_Unchecked);
157 if (info.State == CaseInfo::St_Fixed) {
168 void tryFixing(CaseInfo &info) {
169 assert(info.State == CaseInfo::St_Unchecked);
170 if (hasVarReferencedOutside(info)) {
171 info.State = CaseInfo::St_CannotFix;
175 Pass.TA.insertAfterToken(info.SC->getColonLoc(),
" {");
176 Pass.TA.insert(info.Range.getEnd(),
"}\n");
177 info.State = CaseInfo::St_Fixed;
180 bool hasVarReferencedOutside(CaseInfo &info) {
181 for (
unsigned i = 0, e = LocalRefs.size(); i != e; ++i) {
183 if (isInRange(DRE->
getDecl()->getLocation(), info.Range) &&
201 ProtectedScopeFixer Fix(BodyCtx);
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
const SwitchCase * getNextSwitchCase() const
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
SourceLocation getLocStart() const LLVM_READONLY
Represents a diagnostic in a form that can be retained until its corresponding source manager is dest...
const FullSourceLoc & getLocation() const
SourceLocation getLocation() const
TextDiagnosticBuffer::DiagList DiagList
ParentMap & getParentMap()
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
detail::InMemoryDirectory::const_iterator I
void traverseBody(BodyContext &BodyCtx) override
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
const SwitchCase * getSwitchCaseList() const
Encodes a location in the source.
SourceLocation getBegin() const
SourceLocation getLocEnd() const LLVM_READONLY
detail::InMemoryDirectory::const_iterator E
SwitchStmt - This represents a 'switch' stmt.
DiagnosticsEngine::Level getLevel() const
A reference to a declared variable, function, enum, etc.
A trivial tuple used to represent a source range.
This class handles loading and caching of source files into memory.