1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
12 #ifndef LO_CLANG_SHARED_PLUGINS
16 #include <clang/Lex/Lexer.h>
24 This is a compile check.
26 Check that DBG_UNHANDLED_EXCEPTION is always the first statement in a catch block, otherwise
27 it does not work properly.
30 class DbgUnhandledException
: public loplugin::FilteringPlugin
<DbgUnhandledException
>
33 explicit DbgUnhandledException(InstantiationData
const& data
);
34 virtual void run() override
;
35 bool VisitCallExpr(CallExpr
const* call
);
36 bool TraverseCXXCatchStmt(CXXCatchStmt
*);
37 bool PreTraverseCXXCatchStmt(CXXCatchStmt
*);
38 bool PostTraverseCXXCatchStmt(CXXCatchStmt
*, bool traverseOk
);
41 std::stack
<CXXCatchStmt
const*> currCatchStmt
;
44 DbgUnhandledException::DbgUnhandledException(const InstantiationData
& data
)
45 : FilteringPlugin(data
)
49 void DbgUnhandledException::run()
51 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
54 bool DbgUnhandledException::PreTraverseCXXCatchStmt(CXXCatchStmt
* catchStmt
)
56 currCatchStmt
.push(catchStmt
);
60 bool DbgUnhandledException::PostTraverseCXXCatchStmt(CXXCatchStmt
* catchStmt
, bool)
62 assert(currCatchStmt
.top() == catchStmt
);
68 bool DbgUnhandledException::TraverseCXXCatchStmt(CXXCatchStmt
* catchStmt
)
70 if (!PreTraverseCXXCatchStmt(catchStmt
))
72 bool ret
= RecursiveASTVisitor::TraverseCXXCatchStmt(catchStmt
);
73 if (!PostTraverseCXXCatchStmt(catchStmt
, ret
))
78 bool DbgUnhandledException::VisitCallExpr(const CallExpr
* call
)
80 if (ignoreLocation(call
))
82 const FunctionDecl
* func
= call
->getDirectCallee();
86 if (!func
->getIdentifier() || func
->getName() != "DbgUnhandledException")
89 if (currCatchStmt
.empty())
91 report(DiagnosticsEngine::Warning
, "DBG_UNHANDLED_EXCEPTION outside catch block",
95 auto catchBlock
= dyn_cast
<CompoundStmt
>(currCatchStmt
.top()->getHandlerBlock());
98 report(DiagnosticsEngine::Warning
,
99 "something wrong with DBG_UNHANDLED_EXCEPTION, no CompoundStmt?",
100 call
->getBeginLoc());
103 if (catchBlock
->size() < 1)
105 report(DiagnosticsEngine::Warning
,
106 "something wrong with DBG_UNHANDLED_EXCEPTION, CompoundStmt size == 0?",
107 call
->getBeginLoc());
111 Stmt
const* firstStmt
= *catchBlock
->body_begin();
112 if (auto exprWithCleanups
= dyn_cast
<ExprWithCleanups
>(firstStmt
))
113 firstStmt
= exprWithCleanups
->getSubExpr();
114 if (firstStmt
!= call
)
116 report(DiagnosticsEngine::Warning
,
117 "DBG_UNHANDLED_EXCEPTION must be first statement in catch block",
118 call
->getBeginLoc());
123 static Plugin::Registration
<DbgUnhandledException
> dbgunhandledexception("dbgunhandledexception");
127 #endif // LO_CLANG_SHARED_PLUGINS
129 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */