forked from OSchip/llvm-project
[AST] Don't include RecursiveASTVisitor.h in ASTContext.h
The untemplated implementation of getParents() doesn't need to be in a header file. RecursiveASTVisitor.h is full of repeated macro expansion. Moving this include to ASTContext.cpp speeds up compilation of LambdaMangleContext.cpp, a small C++ file with few includes, from 3.7s to 2.8s for me locally. I haven't measured a full build, but it can't hurt. I had to fix a few static analyzer files that were depending on transitive includes of C++ AST headers. Reviewers: rsmith, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D982 llvm-svn: 184075
This commit is contained in:
parent
52772bf356
commit
2ab0ac5360
|
@ -23,7 +23,6 @@
|
|||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/PrettyPrinter.h"
|
||||
#include "clang/AST/RawCommentList.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/AddressSpaces.h"
|
||||
|
@ -425,22 +424,7 @@ public:
|
|||
return getParents(ast_type_traits::DynTypedNode::create(Node));
|
||||
}
|
||||
|
||||
ParentVector getParents(const ast_type_traits::DynTypedNode &Node) {
|
||||
assert(Node.getMemoizationData() &&
|
||||
"Invariant broken: only nodes that support memoization may be "
|
||||
"used in the parent map.");
|
||||
if (!AllParents) {
|
||||
// We always need to run over the whole translation unit, as
|
||||
// hasAncestor can escape any subtree.
|
||||
AllParents.reset(
|
||||
ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()));
|
||||
}
|
||||
ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData());
|
||||
if (I == AllParents->end()) {
|
||||
return ParentVector();
|
||||
}
|
||||
return I->second;
|
||||
}
|
||||
ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
|
||||
|
||||
const clang::PrintingPolicy &getPrintingPolicy() const {
|
||||
return PrintingPolicy;
|
||||
|
@ -2235,77 +2219,6 @@ private:
|
|||
friend class DeclarationNameTable;
|
||||
void ReleaseDeclContextMaps();
|
||||
|
||||
/// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
|
||||
/// parents as defined by the \c RecursiveASTVisitor.
|
||||
///
|
||||
/// Note that the relationship described here is purely in terms of AST
|
||||
/// traversal - there are other relationships (for example declaration context)
|
||||
/// in the AST that are better modeled by special matchers.
|
||||
///
|
||||
/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
|
||||
class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
|
||||
public:
|
||||
/// \brief Builds and returns the translation unit's parent map.
|
||||
///
|
||||
/// The caller takes ownership of the returned \c ParentMap.
|
||||
static ParentMap *buildMap(TranslationUnitDecl &TU) {
|
||||
ParentMapASTVisitor Visitor(new ParentMap);
|
||||
Visitor.TraverseDecl(&TU);
|
||||
return Visitor.Parents;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
|
||||
|
||||
ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) {
|
||||
}
|
||||
|
||||
bool shouldVisitTemplateInstantiations() const {
|
||||
return true;
|
||||
}
|
||||
bool shouldVisitImplicitCode() const {
|
||||
return true;
|
||||
}
|
||||
// Disables data recursion. We intercept Traverse* methods in the RAV, which
|
||||
// are not triggered during data recursion.
|
||||
bool shouldUseDataRecursionFor(clang::Stmt *S) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
|
||||
if (Node == NULL)
|
||||
return true;
|
||||
if (ParentStack.size() > 0)
|
||||
// FIXME: Currently we add the same parent multiple times, for example
|
||||
// when we visit all subexpressions of template instantiations; this is
|
||||
// suboptimal, bug benign: the only way to visit those is with
|
||||
// hasAncestor / hasParent, and those do not create new matches.
|
||||
// The plan is to enable DynTypedNode to be storable in a map or hash
|
||||
// map. The main problem there is to implement hash functions /
|
||||
// comparison operators for all types that DynTypedNode supports that
|
||||
// do not have pointer identity.
|
||||
(*Parents)[Node].push_back(ParentStack.back());
|
||||
ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
|
||||
bool Result = (this ->* traverse) (Node);
|
||||
ParentStack.pop_back();
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool TraverseDecl(Decl *DeclNode) {
|
||||
return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
|
||||
}
|
||||
|
||||
bool TraverseStmt(Stmt *StmtNode) {
|
||||
return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
|
||||
}
|
||||
|
||||
ParentMap *Parents;
|
||||
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
|
||||
|
||||
friend class RecursiveASTVisitor<ParentMapASTVisitor>;
|
||||
};
|
||||
|
||||
llvm::OwningPtr<ParentMap> AllParents;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
|
@ -8046,3 +8047,97 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
|
|||
unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth();
|
||||
return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
|
||||
/// parents as defined by the \c RecursiveASTVisitor.
|
||||
///
|
||||
/// Note that the relationship described here is purely in terms of AST
|
||||
/// traversal - there are other relationships (for example declaration context)
|
||||
/// in the AST that are better modeled by special matchers.
|
||||
///
|
||||
/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
|
||||
class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
|
||||
|
||||
public:
|
||||
/// \brief Builds and returns the translation unit's parent map.
|
||||
///
|
||||
/// The caller takes ownership of the returned \c ParentMap.
|
||||
static ASTContext::ParentMap *buildMap(TranslationUnitDecl &TU) {
|
||||
ParentMapASTVisitor Visitor(new ASTContext::ParentMap);
|
||||
Visitor.TraverseDecl(&TU);
|
||||
return Visitor.Parents;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
|
||||
|
||||
ParentMapASTVisitor(ASTContext::ParentMap *Parents) : Parents(Parents) {
|
||||
}
|
||||
|
||||
bool shouldVisitTemplateInstantiations() const {
|
||||
return true;
|
||||
}
|
||||
bool shouldVisitImplicitCode() const {
|
||||
return true;
|
||||
}
|
||||
// Disables data recursion. We intercept Traverse* methods in the RAV, which
|
||||
// are not triggered during data recursion.
|
||||
bool shouldUseDataRecursionFor(clang::Stmt *S) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
|
||||
if (Node == NULL)
|
||||
return true;
|
||||
if (ParentStack.size() > 0)
|
||||
// FIXME: Currently we add the same parent multiple times, for example
|
||||
// when we visit all subexpressions of template instantiations; this is
|
||||
// suboptimal, bug benign: the only way to visit those is with
|
||||
// hasAncestor / hasParent, and those do not create new matches.
|
||||
// The plan is to enable DynTypedNode to be storable in a map or hash
|
||||
// map. The main problem there is to implement hash functions /
|
||||
// comparison operators for all types that DynTypedNode supports that
|
||||
// do not have pointer identity.
|
||||
(*Parents)[Node].push_back(ParentStack.back());
|
||||
ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
|
||||
bool Result = (this ->* traverse) (Node);
|
||||
ParentStack.pop_back();
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool TraverseDecl(Decl *DeclNode) {
|
||||
return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
|
||||
}
|
||||
|
||||
bool TraverseStmt(Stmt *StmtNode) {
|
||||
return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
|
||||
}
|
||||
|
||||
ASTContext::ParentMap *Parents;
|
||||
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
|
||||
|
||||
friend class RecursiveASTVisitor<ParentMapASTVisitor>;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
ASTContext::ParentVector
|
||||
ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
|
||||
assert(Node.getMemoizationData() &&
|
||||
"Invariant broken: only nodes that support memoization may be "
|
||||
"used in the parent map.");
|
||||
if (!AllParents) {
|
||||
// We always need to run over the whole translation unit, as
|
||||
// hasAncestor can escape any subtree.
|
||||
AllParents.reset(
|
||||
ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()));
|
||||
}
|
||||
ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData());
|
||||
if (I == AllParents->end()) {
|
||||
return ParentVector();
|
||||
}
|
||||
return I->second;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ClangSACheckers.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
|
||||
#include "clang/StaticAnalyzer/Core/Checker.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ParentMap.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/Analysis/CFG.h"
|
||||
#include "clang/Analysis/ProgramPoint.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
|
|
Loading…
Reference in New Issue