forked from apple/swift-clang
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[analyzer] Make StmtDataCollector customizable
Summary: This moves the data collection macro calls for Stmt nodes to lib/AST/StmtDataCollectors.inc Users can subclass ConstStmtVisitor and include StmtDataCollectors.inc to define visitor methods for each Stmt subclass. This makes it also possible to customize the visit methods as exemplified in lib/Analysis/CloneDetection.cpp. Move helper methods for data collection to a new module, AST/DataCollection. Add data collection for DeclRefExpr, MemberExpr and some literals. Reviewers: arphaman, teemperor! Subscribers: mgorny, xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D36664 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311569 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit 6083032)
- Loading branch information
Showing
8 changed files
with
499 additions
and
234 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//===--- DatatCollection.h --------------------------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// \file | ||
/// \brief This file declares helper methods for collecting data from AST nodes. | ||
/// | ||
/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include | ||
/// StmtDataCollectors.inc after defining the macros that you need. This | ||
/// provides data collection implementations for most Stmt kinds. Note | ||
/// that that code requires some conditions to be met: | ||
/// | ||
/// - There must be a method addData(const T &Data) that accepts strings, | ||
/// integral types as well as QualType. All data is forwarded using | ||
/// to this method. | ||
/// - The ASTContext of the Stmt must be accessible by the name Context. | ||
/// | ||
/// It is also possible to override individual visit methods. Have a look at | ||
/// the DataCollector in lib/Analysis/CloneDetection.cpp for a usage example. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_AST_DATACOLLECTION_H | ||
#define LLVM_CLANG_AST_DATACOLLECTION_H | ||
|
||
#include "clang/AST/ASTContext.h" | ||
|
||
namespace clang { | ||
namespace data_collection { | ||
|
||
/// Returns a string that represents all macro expansions that expanded into the | ||
/// given SourceLocation. | ||
/// | ||
/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations | ||
/// A and B are expanded from the same macros in the same order. | ||
std::string getMacroStack(SourceLocation Loc, ASTContext &Context); | ||
|
||
/// Utility functions for implementing addData() for a consumer that has a | ||
/// method update(StringRef) | ||
template <class T> | ||
void addDataToConsumer(T &DataConsumer, llvm::StringRef Str) { | ||
DataConsumer.update(Str); | ||
} | ||
|
||
template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) { | ||
addDataToConsumer(DataConsumer, QT.getAsString()); | ||
} | ||
|
||
template <class T, class Type> | ||
typename std::enable_if< | ||
std::is_integral<Type>::value || std::is_enum<Type>::value || | ||
std::is_convertible<Type, size_t>::value // for llvm::hash_code | ||
>::type | ||
addDataToConsumer(T &DataConsumer, Type Data) { | ||
DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data))); | ||
} | ||
|
||
} // end namespace data_collection | ||
} // end namespace clang | ||
|
||
#endif // LLVM_CLANG_AST_DATACOLLECTION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//===-- DataCollection.cpp --------------------------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "clang/AST/DataCollection.h" | ||
|
||
#include "clang/Lex/Lexer.h" | ||
|
||
namespace clang { | ||
namespace data_collection { | ||
|
||
/// Prints the macro name that contains the given SourceLocation into the given | ||
/// raw_string_ostream. | ||
static void printMacroName(llvm::raw_string_ostream &MacroStack, | ||
ASTContext &Context, SourceLocation Loc) { | ||
MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(), | ||
Context.getLangOpts()); | ||
|
||
// Add an empty space at the end as a padding to prevent | ||
// that macro names concatenate to the names of other macros. | ||
MacroStack << " "; | ||
} | ||
|
||
/// Returns a string that represents all macro expansions that expanded into the | ||
/// given SourceLocation. | ||
/// | ||
/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations | ||
/// A and B are expanded from the same macros in the same order. | ||
std::string getMacroStack(SourceLocation Loc, ASTContext &Context) { | ||
std::string MacroStack; | ||
llvm::raw_string_ostream MacroStackStream(MacroStack); | ||
SourceManager &SM = Context.getSourceManager(); | ||
|
||
// Iterate over all macros that expanded into the given SourceLocation. | ||
while (Loc.isMacroID()) { | ||
// Add the macro name to the stream. | ||
printMacroName(MacroStackStream, Context, Loc); | ||
Loc = SM.getImmediateMacroCallerLoc(Loc); | ||
} | ||
MacroStackStream.flush(); | ||
return MacroStack; | ||
} | ||
|
||
} // end namespace data_collection | ||
} // end namespace clang |
Oops, something went wrong.