Rework translation unit actions to actually take an entire translation unit

as imput.

llvm-svn: 96182
This commit is contained in:
Ted Kremenek 2010-02-14 19:08:51 +00:00
parent c968e5e9b9
commit 39df94b00d
1 changed files with 51 additions and 44 deletions

View File

@ -65,13 +65,17 @@ namespace {
class AnalysisConsumer : public ASTConsumer { class AnalysisConsumer : public ASTConsumer {
public: public:
typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D); typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
TranslationUnitDecl &TU);
private: private:
typedef std::vector<CodeAction> Actions; typedef std::vector<CodeAction> Actions;
typedef std::vector<TUAction> TUActions;
Actions FunctionActions; Actions FunctionActions;
Actions ObjCMethodActions; Actions ObjCMethodActions;
Actions ObjCImplementationActions; Actions ObjCImplementationActions;
Actions TranslationUnitActions; TUActions TranslationUnitActions;
public: public:
ASTContext* Ctx; ASTContext* Ctx;
@ -134,11 +138,11 @@ public:
} }
} }
} }
void DisplayFunction(const Decl *D) { void DisplayFunction(const Decl *D) {
if (!Opts.AnalyzerDisplayProgress || declDisplayed) if (!Opts.AnalyzerDisplayProgress || declDisplayed)
return; return;
declDisplayed = true; declDisplayed = true;
SourceManager &SM = Mgr->getASTContext().getSourceManager(); SourceManager &SM = Mgr->getASTContext().getSourceManager();
PresumedLoc Loc = SM.getPresumedLoc(D->getLocation()); PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
@ -163,7 +167,7 @@ public:
ObjCImplementationActions.push_back(action); ObjCImplementationActions.push_back(action);
} }
void addTranslationUnitAction(CodeAction action) { void addTranslationUnitAction(TUAction action) {
TranslationUnitActions.push_back(action); TranslationUnitActions.push_back(action);
} }
@ -192,7 +196,7 @@ public:
namespace llvm { namespace llvm {
template <> struct FoldingSetTrait<AnalysisConsumer::CodeAction> { template <> struct FoldingSetTrait<AnalysisConsumer::CodeAction> {
static inline void Profile(AnalysisConsumer::CodeAction X, static inline void Profile(AnalysisConsumer::CodeAction X,
FoldingSetNodeID& ID) { FoldingSetNodeID& ID) {
ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X))); ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X)));
} }
@ -238,30 +242,12 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
} }
void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
TranslationUnitDecl *TU = C.getTranslationUnitDecl();
if (!TranslationUnitActions.empty()) {
// Find the entry function definition (if any).
FunctionDecl *FD = 0;
// Must specify an entry function.
if (!Opts.AnalyzeSpecificFunction.empty()) {
for (DeclContext::decl_iterator I=TU->decls_begin(), E=TU->decls_end();
I != E; ++I) {
if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
if (fd->isThisDeclarationADefinition() &&
fd->getNameAsString() == Opts.AnalyzeSpecificFunction) {
FD = fd;
break;
}
}
}
if (FD) { TranslationUnitDecl *TU = C.getTranslationUnitDecl();
for (Actions::iterator I = TranslationUnitActions.begin(),
E = TranslationUnitActions.end(); I != E; ++I) for (TUActions::iterator I = TranslationUnitActions.begin(),
(*I)(*this, *Mgr, FD); E = TranslationUnitActions.end(); I != E; ++I) {
} (*I)(*this, *Mgr, *TU);
} }
if (!ObjCImplementationActions.empty()) { if (!ObjCImplementationActions.empty()) {
@ -282,7 +268,7 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) { static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
WL.push_back(BD); WL.push_back(BD);
for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
I!=E; ++I) I!=E; ++I)
if (DeclContext *DC = dyn_cast<DeclContext>(*I)) if (DeclContext *DC = dyn_cast<DeclContext>(*I))
@ -303,14 +289,14 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
// Clear the AnalysisManager of old AnalysisContexts. // Clear the AnalysisManager of old AnalysisContexts.
Mgr->ClearContexts(); Mgr->ClearContexts();
// Dispatch on the actions. // Dispatch on the actions.
llvm::SmallVector<Decl*, 10> WL; llvm::SmallVector<Decl*, 10> WL;
WL.push_back(D); WL.push_back(D);
if (Body && Opts.AnalyzeNestedBlocks) if (Body && Opts.AnalyzeNestedBlocks)
FindBlocks(cast<DeclContext>(D), WL); FindBlocks(cast<DeclContext>(D), WL);
for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end(); for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
WI != WE; ++WI) WI != WE; ++WI)
@ -340,7 +326,7 @@ static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr, static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D, Decl *D,
GRTransferFuncs* tf) { GRTransferFuncs* tf) {
llvm::OwningPtr<GRTransferFuncs> TF(tf); llvm::OwningPtr<GRTransferFuncs> TF(tf);
@ -352,18 +338,18 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
// information to see if the CFG is valid. // information to see if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs. // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!mgr.getLiveVariables(D)) if (!mgr.getLiveVariables(D))
return; return;
GRExprEngine Eng(mgr, TF.take()); GRExprEngine Eng(mgr, TF.take());
if (C.Opts.EnableExperimentalInternalChecks) if (C.Opts.EnableExperimentalInternalChecks)
RegisterExperimentalInternalChecks(Eng); RegisterExperimentalInternalChecks(Eng);
RegisterAppleChecks(Eng, *D); RegisterAppleChecks(Eng, *D);
if (C.Opts.EnableExperimentalChecks) if (C.Opts.EnableExperimentalChecks)
RegisterExperimentalChecks(Eng); RegisterExperimentalChecks(Eng);
// Set the graph auditor. // Set the graph auditor.
llvm::OwningPtr<ExplodedNode::Auditor> Auditor; llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
if (mgr.shouldVisualizeUbigraph()) { if (mgr.shouldVisualizeUbigraph()) {
@ -486,8 +472,29 @@ static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
} }
static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr, static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D) { TranslationUnitDecl &TU) {
// FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
// Find the entry function definition (if any).
FunctionDecl *D = 0;
// Must specify an entry function.
if (!C.Opts.AnalyzeSpecificFunction.empty()) {
for (DeclContext::decl_iterator I=TU.decls_begin(), E=TU.decls_end();
I != E; ++I) {
if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
if (fd->isThisDeclarationADefinition() &&
fd->getNameAsString() == C.Opts.AnalyzeSpecificFunction) {
D = fd;
break;
}
}
}
if (!D)
return;
// FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
// Display progress. // Display progress.
C.DisplayFunction(D); C.DisplayFunction(D);
@ -497,9 +504,9 @@ static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
if (C.Opts.EnableExperimentalInternalChecks) if (C.Opts.EnableExperimentalInternalChecks)
RegisterExperimentalInternalChecks(Eng); RegisterExperimentalInternalChecks(Eng);
RegisterAppleChecks(Eng, *D); RegisterAppleChecks(Eng, *D);
if (C.Opts.EnableExperimentalChecks) if (C.Opts.EnableExperimentalChecks)
RegisterExperimentalChecks(Eng); RegisterExperimentalChecks(Eng);