2009-07-28 08:33:38 +08:00
|
|
|
//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the Stmt::Profile method, which builds a unique bit
|
2009-07-29 00:39:25 +08:00
|
|
|
// representation that identifies a statement/expression.
|
2009-07-28 08:33:38 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-07-28 22:44:31 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
2009-07-28 08:33:38 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/ExprCXX.h"
|
|
|
|
#include "clang/AST/ExprObjC.h"
|
2015-08-25 22:24:04 +08:00
|
|
|
#include "clang/AST/ExprOpenMP.h"
|
2017-02-23 06:22:42 +08:00
|
|
|
#include "clang/AST/ODRHash.h"
|
2009-07-28 08:33:38 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
|
|
|
#include "llvm/ADT/FoldingSet.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
namespace {
|
2011-06-16 14:47:06 +08:00
|
|
|
class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
|
2017-02-23 06:22:42 +08:00
|
|
|
protected:
|
2009-07-28 08:33:38 +08:00
|
|
|
llvm::FoldingSetNodeID &ID;
|
|
|
|
bool Canonical;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
public:
|
2017-02-23 06:22:42 +08:00
|
|
|
StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical)
|
|
|
|
: ID(ID), Canonical(Canonical) {}
|
|
|
|
|
|
|
|
virtual ~StmtProfiler() {}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void VisitStmt(const Stmt *S);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
#define STMT(Node, Base) void Visit##Node(const Node *S);
|
2010-05-05 23:24:00 +08:00
|
|
|
#include "clang/AST/StmtNodes.inc"
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
/// \brief Visit a declaration that is referenced within an expression
|
|
|
|
/// or statement.
|
2017-02-23 06:22:42 +08:00
|
|
|
virtual void VisitDecl(const Decl *D) = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
/// \brief Visit a type that is referenced within an expression or
|
2009-07-28 08:33:38 +08:00
|
|
|
/// statement.
|
2017-02-23 06:22:42 +08:00
|
|
|
virtual void VisitType(QualType T) = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
/// \brief Visit a name that occurs within an expression or statement.
|
2017-02-23 06:22:42 +08:00
|
|
|
virtual void VisitName(DeclarationName Name) = 0;
|
|
|
|
|
|
|
|
/// \brief Visit identifiers that are not in Decl's or Type's.
|
|
|
|
virtual void VisitIdentifierInfo(IdentifierInfo *II) = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
/// \brief Visit a nested-name-specifier that occurs within an expression
|
|
|
|
/// or statement.
|
2017-02-23 06:22:42 +08:00
|
|
|
virtual void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
/// \brief Visit a template name that occurs within an expression or
|
|
|
|
/// statement.
|
2017-02-23 06:22:42 +08:00
|
|
|
virtual void VisitTemplateName(TemplateName Name) = 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
/// \brief Visit template arguments that occur within an expression or
|
|
|
|
/// statement.
|
2011-06-16 14:47:06 +08:00
|
|
|
void VisitTemplateArguments(const TemplateArgumentLoc *Args,
|
|
|
|
unsigned NumArgs);
|
2009-10-29 16:12:44 +08:00
|
|
|
|
|
|
|
/// \brief Visit a single template argument.
|
|
|
|
void VisitTemplateArgument(const TemplateArgument &Arg);
|
2009-07-28 08:33:38 +08:00
|
|
|
};
|
2017-02-23 06:22:42 +08:00
|
|
|
|
|
|
|
class StmtProfilerWithPointers : public StmtProfiler {
|
|
|
|
const ASTContext &Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID,
|
|
|
|
const ASTContext &Context, bool Canonical)
|
|
|
|
: StmtProfiler(ID, Canonical), Context(Context) {}
|
|
|
|
private:
|
|
|
|
void VisitDecl(const Decl *D) override {
|
|
|
|
ID.AddInteger(D ? D->getKind() : 0);
|
|
|
|
|
|
|
|
if (Canonical && D) {
|
|
|
|
if (const NonTypeTemplateParmDecl *NTTP =
|
|
|
|
dyn_cast<NonTypeTemplateParmDecl>(D)) {
|
|
|
|
ID.AddInteger(NTTP->getDepth());
|
|
|
|
ID.AddInteger(NTTP->getIndex());
|
|
|
|
ID.AddBoolean(NTTP->isParameterPack());
|
|
|
|
VisitType(NTTP->getType());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
|
|
|
|
// The Itanium C++ ABI uses the type, scope depth, and scope
|
|
|
|
// index of a parameter when mangling expressions that involve
|
|
|
|
// function parameters, so we will use the parameter's type for
|
|
|
|
// establishing function parameter identity. That way, our
|
|
|
|
// definition of "equivalent" (per C++ [temp.over.link]) is at
|
|
|
|
// least as strong as the definition of "equivalent" used for
|
|
|
|
// name mangling.
|
|
|
|
VisitType(Parm->getType());
|
|
|
|
ID.AddInteger(Parm->getFunctionScopeDepth());
|
|
|
|
ID.AddInteger(Parm->getFunctionScopeIndex());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TemplateTypeParmDecl *TTP =
|
|
|
|
dyn_cast<TemplateTypeParmDecl>(D)) {
|
|
|
|
ID.AddInteger(TTP->getDepth());
|
|
|
|
ID.AddInteger(TTP->getIndex());
|
|
|
|
ID.AddBoolean(TTP->isParameterPack());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TemplateTemplateParmDecl *TTP =
|
|
|
|
dyn_cast<TemplateTemplateParmDecl>(D)) {
|
|
|
|
ID.AddInteger(TTP->getDepth());
|
|
|
|
ID.AddInteger(TTP->getIndex());
|
|
|
|
ID.AddBoolean(TTP->isParameterPack());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ID.AddPointer(D ? D->getCanonicalDecl() : nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitType(QualType T) override {
|
|
|
|
if (Canonical)
|
|
|
|
T = Context.getCanonicalType(T);
|
|
|
|
|
|
|
|
ID.AddPointer(T.getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitName(DeclarationName Name) override {
|
|
|
|
ID.AddPointer(Name.getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitIdentifierInfo(IdentifierInfo *II) override {
|
|
|
|
ID.AddPointer(II);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
|
|
|
|
if (Canonical)
|
|
|
|
NNS = Context.getCanonicalNestedNameSpecifier(NNS);
|
|
|
|
ID.AddPointer(NNS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitTemplateName(TemplateName Name) override {
|
|
|
|
if (Canonical)
|
|
|
|
Name = Context.getCanonicalTemplateName(Name);
|
|
|
|
|
|
|
|
Name.Profile(ID);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class StmtProfilerWithoutPointers : public StmtProfiler {
|
|
|
|
ODRHash &Hash;
|
|
|
|
public:
|
|
|
|
StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
|
|
|
|
: StmtProfiler(ID, false), Hash(Hash) {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void VisitType(QualType T) override {
|
|
|
|
Hash.AddQualType(T);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitName(DeclarationName Name) override {
|
|
|
|
Hash.AddDeclarationName(Name);
|
|
|
|
}
|
|
|
|
void VisitIdentifierInfo(IdentifierInfo *II) override {
|
|
|
|
ID.AddBoolean(II);
|
|
|
|
if (II) {
|
|
|
|
Hash.AddIdentifierInfo(II);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void VisitDecl(const Decl *D) override {
|
|
|
|
ID.AddBoolean(D);
|
|
|
|
if (D) {
|
|
|
|
Hash.AddDecl(D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void VisitTemplateName(TemplateName Name) override {
|
|
|
|
Hash.AddTemplateName(Name);
|
|
|
|
}
|
|
|
|
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
|
|
|
|
ID.AddBoolean(NNS);
|
|
|
|
if (NNS) {
|
|
|
|
Hash.AddNestedNameSpecifier(NNS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2009-07-28 08:33:38 +08:00
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitStmt(const Stmt *S) {
|
2016-06-10 12:52:09 +08:00
|
|
|
assert(S && "Requires non-null Stmt pointer");
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddInteger(S->getStmtClass());
|
2015-07-03 05:03:14 +08:00
|
|
|
for (const Stmt *SubStmt : S->children()) {
|
|
|
|
if (SubStmt)
|
|
|
|
Visit(SubStmt);
|
2012-03-02 00:34:31 +08:00
|
|
|
else
|
|
|
|
ID.AddInteger(0);
|
|
|
|
}
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
2014-03-15 01:01:24 +08:00
|
|
|
for (const auto *D : S->decls())
|
|
|
|
VisitDecl(D);
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitNullStmt(const NullStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
2011-02-17 15:39:24 +08:00
|
|
|
VisitDecl(S->getDecl());
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2012-04-14 08:33:13 +08:00
|
|
|
void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
// TODO: maybe visit attributes?
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitIfStmt(const IfStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
2009-11-25 08:27:52 +08:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
|
2009-07-30 00:09:57 +08:00
|
|
|
VisitStmt(S);
|
2009-11-25 08:27:52 +08:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-30 00:09:57 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
2009-11-25 08:27:52 +08:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDoStmt(const DoStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitForStmt(const ForStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
2011-02-17 15:39:24 +08:00
|
|
|
VisitDecl(S->getLabel());
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2012-08-25 08:11:56 +08:00
|
|
|
void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->isVolatile());
|
|
|
|
ID.AddBoolean(S->isSimple());
|
|
|
|
VisitStringLiteral(S->getAsmString());
|
|
|
|
ID.AddInteger(S->getNumOutputs());
|
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
|
|
ID.AddString(S->getOutputName(I));
|
|
|
|
VisitStringLiteral(S->getOutputConstraintLiteral(I));
|
|
|
|
}
|
|
|
|
ID.AddInteger(S->getNumInputs());
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
|
|
ID.AddString(S->getInputName(I));
|
|
|
|
VisitStringLiteral(S->getInputConstraintLiteral(I));
|
|
|
|
}
|
|
|
|
ID.AddInteger(S->getNumClobbers());
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
2012-08-28 07:28:41 +08:00
|
|
|
VisitStringLiteral(S->getClobberStringLiteral(I));
|
2009-07-28 23:27:13 +08:00
|
|
|
}
|
|
|
|
|
2012-06-12 04:47:18 +08:00
|
|
|
void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
|
|
|
|
// FIXME: Implement MS style inline asm statement profiler.
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
VisitType(S->getCaughtType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
|
2011-04-15 06:09:26 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->isIfExists());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
|
|
|
|
VisitName(S->getNameInfo().getName());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
|
2011-04-28 09:08:34 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
|
2011-04-28 09:08:34 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
|
2011-04-28 09:08:34 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2014-07-07 08:12:30 +08:00
|
|
|
void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2013-04-17 02:53:08 +08:00
|
|
|
void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->hasEllipsis());
|
|
|
|
if (S->getCatchParamDecl())
|
|
|
|
VisitType(S->getCatchParamDecl()->getType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
|
2009-07-28 23:27:13 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
|
2011-06-16 07:02:42 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
namespace {
|
|
|
|
class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
|
|
|
|
StmtProfiler *Profiler;
|
2013-09-24 11:17:45 +08:00
|
|
|
/// \brief Process clauses with list of variables.
|
|
|
|
template <typename T>
|
|
|
|
void VisitOMPClauseList(T *Node);
|
2015-12-09 15:52:46 +08:00
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
public:
|
|
|
|
OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
|
|
|
|
#define OPENMP_CLAUSE(Name, Class) \
|
|
|
|
void Visit##Class(const Class *C);
|
|
|
|
#include "clang/Basic/OpenMPKinds.def"
|
2016-02-16 19:18:12 +08:00
|
|
|
void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
|
2016-02-25 13:25:57 +08:00
|
|
|
void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
|
2013-07-19 11:13:43 +08:00
|
|
|
};
|
|
|
|
|
2016-02-16 19:18:12 +08:00
|
|
|
void OMPClauseProfiler::VistOMPClauseWithPreInit(
|
|
|
|
const OMPClauseWithPreInit *C) {
|
|
|
|
if (auto *S = C->getPreInitStmt())
|
|
|
|
Profiler->VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2016-02-25 13:25:57 +08:00
|
|
|
void OMPClauseProfiler::VistOMPClauseWithPostUpdate(
|
|
|
|
const OMPClauseWithPostUpdate *C) {
|
2016-03-04 15:21:16 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-02-25 13:25:57 +08:00
|
|
|
if (auto *E = C->getPostUpdateExpr())
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
|
2014-02-13 13:29:23 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
|
2017-01-19 04:40:48 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-02-13 13:29:23 +08:00
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2014-07-17 15:32:53 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
|
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2014-03-06 14:15:19 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
|
2017-01-25 08:57:16 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-03-06 14:15:19 +08:00
|
|
|
if (C->getNumThreads())
|
|
|
|
Profiler->VisitStmt(C->getNumThreads());
|
|
|
|
}
|
|
|
|
|
2014-03-21 12:51:18 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
|
|
|
|
if (C->getSafelen())
|
|
|
|
Profiler->VisitStmt(C->getSafelen());
|
2015-08-21 19:14:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
|
|
|
|
if (C->getSimdlen())
|
|
|
|
Profiler->VisitStmt(C->getSimdlen());
|
2014-03-21 12:51:18 +08:00
|
|
|
}
|
|
|
|
|
2014-05-27 23:12:19 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
|
|
|
|
if (C->getNumForLoops())
|
|
|
|
Profiler->VisitStmt(C->getNumForLoops());
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
|
2013-09-24 11:17:45 +08:00
|
|
|
|
2014-05-06 14:04:14 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
|
|
|
|
|
2014-06-20 15:16:17 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
|
2016-02-16 19:18:12 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (auto *S = C->getChunkSize())
|
|
|
|
Profiler->VisitStmt(S);
|
2014-06-20 15:16:17 +08:00
|
|
|
}
|
|
|
|
|
2015-07-30 19:36:16 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) {
|
|
|
|
if (auto *Num = C->getNumForLoops())
|
|
|
|
Profiler->VisitStmt(Num);
|
|
|
|
}
|
2014-06-20 17:44:06 +08:00
|
|
|
|
2014-06-20 19:19:47 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
|
|
|
|
|
2014-07-17 20:19:31 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
|
|
|
|
|
2014-07-17 20:47:03 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
|
|
|
|
|
2014-07-23 10:27:21 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
|
|
|
|
|
2014-07-23 15:46:59 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
|
|
|
|
|
2014-07-23 18:25:33 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
|
|
|
|
|
2014-07-24 14:46:57 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
|
|
|
|
|
2014-07-24 16:55:34 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
|
|
|
|
2015-09-25 18:37:12 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
|
|
|
|
2015-09-28 14:39:35 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
|
|
|
|
2015-12-07 18:51:44 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {}
|
|
|
|
|
2013-09-24 11:17:45 +08:00
|
|
|
template<typename T>
|
|
|
|
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
|
2014-10-21 11:16:40 +08:00
|
|
|
for (auto *E : Node->varlists()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-21 11:16:40 +08:00
|
|
|
}
|
2013-09-24 11:17:45 +08:00
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
|
2013-09-24 11:17:45 +08:00
|
|
|
VisitOMPClauseList(C);
|
2014-10-21 11:16:40 +08:00
|
|
|
for (auto *E : C->private_copies()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-21 11:16:40 +08:00
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
2014-10-08 22:01:46 +08:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
|
2013-10-01 13:32:34 +08:00
|
|
|
VisitOMPClauseList(C);
|
2016-02-17 21:19:37 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-10-08 22:01:46 +08:00
|
|
|
for (auto *E : C->private_copies()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-08 22:01:46 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->inits()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-08 22:01:46 +08:00
|
|
|
}
|
2013-10-01 13:32:34 +08:00
|
|
|
}
|
2014-06-04 21:06:39 +08:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-02-25 13:25:57 +08:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-04-16 12:54:05 +08:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 12:54:05 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 12:54:05 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 12:54:05 +08:00
|
|
|
}
|
2014-06-04 21:06:39 +08:00
|
|
|
}
|
2013-09-07 02:03:48 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
|
2013-09-24 11:17:45 +08:00
|
|
|
VisitOMPClauseList(C);
|
2013-09-07 02:03:48 +08:00
|
|
|
}
|
2014-06-16 15:08:35 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPReductionClause(
|
|
|
|
const OMPReductionClause *C) {
|
|
|
|
Profiler->VisitNestedNameSpecifier(
|
|
|
|
C->getQualifierLoc().getNestedNameSpecifier());
|
|
|
|
Profiler->VisitName(C->getNameInfo().getName());
|
|
|
|
VisitOMPClauseList(C);
|
2016-03-02 12:57:40 +08:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-10-08 17:10:53 +08:00
|
|
|
for (auto *E : C->privates()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-10-08 17:10:53 +08:00
|
|
|
}
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 18:43:45 +08:00
|
|
|
for (auto *E : C->lhs_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 18:43:45 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->rhs_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 18:43:45 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->reduction_ops()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 18:43:45 +08:00
|
|
|
}
|
2014-06-16 15:08:35 +08:00
|
|
|
}
|
2014-04-22 21:09:42 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-03-09 17:49:00 +08:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-08-18 14:47:21 +08:00
|
|
|
for (auto *E : C->privates()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-08-18 14:47:21 +08:00
|
|
|
}
|
2015-03-21 18:12:56 +08:00
|
|
|
for (auto *E : C->inits()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 18:12:56 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->updates()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 18:12:56 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->finals()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 18:12:56 +08:00
|
|
|
}
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getStep())
|
|
|
|
Profiler->VisitStmt(C->getStep());
|
|
|
|
if (C->getCalcStep())
|
|
|
|
Profiler->VisitStmt(C->getCalcStep());
|
2014-04-22 21:09:42 +08:00
|
|
|
}
|
2014-05-29 22:36:25 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getAlignment())
|
|
|
|
Profiler->VisitStmt(C->getAlignment());
|
2014-05-29 22:36:25 +08:00
|
|
|
}
|
2014-03-31 11:36:38 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2015-04-16 13:39:01 +08:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 13:39:01 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 13:39:01 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 13:39:01 +08:00
|
|
|
}
|
2014-03-31 11:36:38 +08:00
|
|
|
}
|
2014-06-27 18:37:06 +08:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2015-03-23 14:18:07 +08:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 14:18:07 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 14:18:07 +08:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 14:18:07 +08:00
|
|
|
}
|
2014-06-27 18:37:06 +08:00
|
|
|
}
|
2014-07-21 19:26:11 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-06-23 22:25:19 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-08-08 00:16:36 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getDevice())
|
|
|
|
Profiler->VisitStmt(C->getDevice());
|
2015-08-08 00:16:36 +08:00
|
|
|
}
|
2015-11-23 13:32:03 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-11-25 04:50:12 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
|
2017-01-25 19:28:18 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getNumTeams())
|
|
|
|
Profiler->VisitStmt(C->getNumTeams());
|
2015-11-25 04:50:12 +08:00
|
|
|
}
|
2015-11-28 02:47:36 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPThreadLimitClause(
|
|
|
|
const OMPThreadLimitClause *C) {
|
2017-01-25 19:44:35 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getThreadLimit())
|
|
|
|
Profiler->VisitStmt(C->getThreadLimit());
|
2015-11-28 02:47:36 +08:00
|
|
|
}
|
2015-12-01 18:17:31 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getPriority())
|
|
|
|
Profiler->VisitStmt(C->getPriority());
|
2015-12-01 18:17:31 +08:00
|
|
|
}
|
2015-12-07 20:52:51 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getGrainsize())
|
|
|
|
Profiler->VisitStmt(C->getGrainsize());
|
2015-12-07 20:52:51 +08:00
|
|
|
}
|
2015-12-08 20:06:20 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getNumTasks())
|
|
|
|
Profiler->VisitStmt(C->getNumTasks());
|
2015-12-08 20:06:20 +08:00
|
|
|
}
|
2015-12-15 16:19:24 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
|
2016-06-10 12:52:09 +08:00
|
|
|
if (C->getHint())
|
|
|
|
Profiler->VisitStmt(C->getHint());
|
2015-12-15 16:19:24 +08:00
|
|
|
}
|
2016-05-27 01:39:58 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-05-27 01:49:04 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-07-13 23:37:16 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
|
|
|
|
const OMPUseDevicePtrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-07-14 01:16:49 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
|
|
|
|
const OMPIsDevicePtrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
|
|
|
|
void
|
2014-02-27 16:29:12 +08:00
|
|
|
StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
|
2013-07-19 11:13:43 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
OMPClauseProfiler P(this);
|
|
|
|
ArrayRef<OMPClause *> Clauses = S->clauses();
|
|
|
|
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
|
|
|
|
I != E; ++I)
|
|
|
|
if (*I)
|
|
|
|
P.Visit(*I);
|
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-02-27 16:29:12 +08:00
|
|
|
void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-02-27 16:29:12 +08:00
|
|
|
}
|
|
|
|
|
2014-06-18 12:14:57 +08:00
|
|
|
void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-06-18 12:14:57 +08:00
|
|
|
}
|
|
|
|
|
2014-09-18 13:12:34 +08:00
|
|
|
void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-25 19:44:49 +08:00
|
|
|
void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-26 16:21:58 +08:00
|
|
|
void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-26 20:05:45 +08:00
|
|
|
void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-17 16:54:58 +08:00
|
|
|
void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-21 17:42:05 +08:00
|
|
|
void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
VisitName(S->getDirectiveName().getName());
|
|
|
|
}
|
|
|
|
|
2014-07-07 21:01:15 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-07-07 21:01:15 +08:00
|
|
|
}
|
|
|
|
|
2014-09-23 17:33:00 +08:00
|
|
|
void StmtProfiler::VisitOMPParallelForSimdDirective(
|
|
|
|
const OMPParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-08 16:12:03 +08:00
|
|
|
void StmtProfiler::VisitOMPParallelSectionsDirective(
|
|
|
|
const OMPParallelSectionsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-11 19:25:16 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 15:47:19 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 17:11:51 +08:00
|
|
|
void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 18:17:07 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-06-18 20:14:09 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-21 19:26:11 +08:00
|
|
|
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-22 14:45:04 +08:00
|
|
|
void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-22 18:10:35 +08:00
|
|
|
void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-09-19 16:19:49 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-21 21:44:28 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-20 03:15:56 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetEnterDataDirective(
|
|
|
|
const OMPTargetEnterDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-20 04:04:50 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetExitDataDirective(
|
|
|
|
const OMPTargetExitDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-27 02:48:41 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelDirective(
|
|
|
|
const OMPTargetParallelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-02-03 23:46:42 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelForDirective(
|
|
|
|
const OMPTargetParallelForDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-10-09 12:18:56 +08:00
|
|
|
void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-01 14:57:41 +08:00
|
|
|
void StmtProfiler::VisitOMPCancellationPointDirective(
|
|
|
|
const OMPCancellationPointDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-02 19:25:17 +08:00
|
|
|
void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-01 12:18:41 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-03 17:40:15 +08:00
|
|
|
void StmtProfiler::VisitOMPTaskLoopSimdDirective(
|
|
|
|
const OMPTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-14 22:51:25 +08:00
|
|
|
void StmtProfiler::VisitOMPDistributeDirective(
|
|
|
|
const OMPDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-16 02:50:31 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPDistScheduleClause(
|
|
|
|
const OMPDistScheduleClause *C) {
|
2016-02-16 19:18:12 +08:00
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (auto *S = C->getChunkSize())
|
|
|
|
Profiler->VisitStmt(S);
|
2016-01-16 02:50:31 +08:00
|
|
|
}
|
|
|
|
|
2016-01-27 00:37:23 +08:00
|
|
|
void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
|
|
|
|
|
2016-05-27 01:30:50 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetUpdateDirective(
|
|
|
|
const OMPTargetUpdateDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-06-27 22:55:37 +08:00
|
|
|
void StmtProfiler::VisitOMPDistributeParallelForDirective(
|
|
|
|
const OMPDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-05 13:00:15 +08:00
|
|
|
void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
|
|
|
|
const OMPDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-06 12:45:38 +08:00
|
|
|
void StmtProfiler::VisitOMPDistributeSimdDirective(
|
|
|
|
const OMPDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-14 10:54:56 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
|
|
|
|
const OMPTargetParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-21 06:57:10 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetSimdDirective(
|
|
|
|
const OMPTargetSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-08-05 22:37:37 +08:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeDirective(
|
|
|
|
const OMPTeamsDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-10-25 20:50:55 +08:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
|
|
|
|
const OMPTeamsDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-01 07:51:03 +08:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
|
|
|
|
const OMPTeamsDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-09 11:24:30 +08:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
|
|
|
|
const OMPTeamsDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-17 13:48:59 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDirective(
|
|
|
|
const OMPTargetTeamsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-25 12:52:54 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
|
|
|
|
const OMPTargetTeamsDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-30 06:16:30 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
|
|
|
|
const OMPTargetTeamsDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2017-01-03 13:23:48 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
|
|
|
|
const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2017-01-11 02:08:18 +08:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
|
|
|
|
const OMPTargetTeamsDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitExpr(const Expr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2010-07-13 16:37:11 +08:00
|
|
|
if (!Canonical)
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitDecl(S->getDecl());
|
2010-07-13 16:37:11 +08:00
|
|
|
if (!Canonical)
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getIdentType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
S->getValue().Profile(ID);
|
2014-11-20 11:37:32 +08:00
|
|
|
ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2011-07-27 13:40:30 +08:00
|
|
|
ID.AddInteger(S->getKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddInteger(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
S->getValue().Profile(ID);
|
|
|
|
ID.AddBoolean(S->isExact());
|
2014-11-20 11:37:32 +08:00
|
|
|
ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2011-11-03 01:26:05 +08:00
|
|
|
ID.AddString(S->getBytes());
|
2011-07-27 13:40:30 +08:00
|
|
|
ID.AddInteger(S->getKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
|
2009-08-11 07:49:36 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOpcode());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
VisitType(S->getTypeSourceInfo()->getType());
|
|
|
|
unsigned n = S->getNumComponents();
|
|
|
|
for (unsigned i = 0; i < n; ++i) {
|
2015-12-30 06:31:18 +08:00
|
|
|
const OffsetOfNode &ON = S->getComponent(i);
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
ID.AddInteger(ON.getKind());
|
|
|
|
switch (ON.getKind()) {
|
2015-12-30 06:31:18 +08:00
|
|
|
case OffsetOfNode::Array:
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
// Expressions handled below.
|
|
|
|
break;
|
|
|
|
|
2015-12-30 06:31:18 +08:00
|
|
|
case OffsetOfNode::Field:
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
VisitDecl(ON.getField());
|
|
|
|
break;
|
|
|
|
|
2015-12-30 06:31:18 +08:00
|
|
|
case OffsetOfNode::Identifier:
|
2017-02-23 06:22:42 +08:00
|
|
|
VisitIdentifierInfo(ON.getFieldName());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
break;
|
2015-12-30 06:31:18 +08:00
|
|
|
|
|
|
|
case OffsetOfNode::Base:
|
2010-04-29 08:18:15 +08:00
|
|
|
// These nodes are implicit, and therefore don't need profiling.
|
|
|
|
break;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
}
|
|
|
|
}
|
2017-02-23 06:22:42 +08:00
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2011-03-12 03:24:49 +08:00
|
|
|
ID.AddInteger(S->getKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
if (S->isArgumentType())
|
|
|
|
VisitType(S->getArgumentType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2015-08-25 22:24:04 +08:00
|
|
|
void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCallExpr(const CallExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getMemberDecl());
|
2010-07-13 16:37:11 +08:00
|
|
|
if (!Canonical)
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isFileScope());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCastExpr(const CastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCastExpr(S);
|
2010-08-25 18:28:54 +08:00
|
|
|
ID.AddInteger(S->getValueKind());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCastExpr(S);
|
|
|
|
VisitType(S->getTypeAsWritten());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOpcode());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitBinaryOperator(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitBinaryConditionalOperator(
|
2011-06-22 07:26:32 +08:00
|
|
|
const BinaryConditionalOperator *S) {
|
2011-02-17 18:25:35 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2011-02-17 15:39:24 +08:00
|
|
|
VisitDecl(S->getLabel());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2013-09-18 11:29:45 +08:00
|
|
|
void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
|
2009-07-30 00:09:57 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
if (S->getSyntacticForm()) {
|
|
|
|
VisitInitListExpr(S->getSyntacticForm());
|
|
|
|
return;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->usesGNUSyntax());
|
2016-06-23 08:15:04 +08:00
|
|
|
for (const DesignatedInitExpr::Designator &D : S->designators()) {
|
|
|
|
if (D.isFieldDesignator()) {
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddInteger(0);
|
2016-06-23 08:15:04 +08:00
|
|
|
VisitName(D.getFieldName());
|
2009-07-28 08:33:38 +08:00
|
|
|
continue;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-06-23 08:15:04 +08:00
|
|
|
if (D.isArrayDesignator()) {
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddInteger(1);
|
|
|
|
} else {
|
2016-06-23 08:15:04 +08:00
|
|
|
assert(D.isArrayRangeDesignator());
|
2009-07-28 08:33:38 +08:00
|
|
|
ID.AddInteger(2);
|
|
|
|
}
|
2016-06-23 08:15:04 +08:00
|
|
|
ID.AddInteger(D.getFirstExprIndex());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-10 08:27:52 +08:00
|
|
|
// Seems that if VisitInitListExpr() only works on the syntactic form of an
|
|
|
|
// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
|
|
|
|
void StmtProfiler::VisitDesignatedInitUpdateExpr(
|
|
|
|
const DesignatedInitUpdateExpr *S) {
|
|
|
|
llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
|
|
|
|
"initializer");
|
|
|
|
}
|
|
|
|
|
2016-12-12 10:53:20 +08:00
|
|
|
void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2015-06-10 08:27:52 +08:00
|
|
|
void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
|
|
|
|
llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(&S->getAccessor());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getBlockDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
|
2011-04-15 08:35:48 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
|
|
|
|
QualType T = S->getAssocType(i);
|
|
|
|
if (T.isNull())
|
2014-05-12 13:36:57 +08:00
|
|
|
ID.AddPointer(nullptr);
|
2011-04-15 08:35:48 +08:00
|
|
|
else
|
|
|
|
VisitType(T);
|
|
|
|
VisitExpr(S->getAssocExpr(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
for (PseudoObjectExpr::const_semantics_iterator
|
|
|
|
i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
|
|
|
|
// Normally, we would not profile the source expressions of OVEs.
|
|
|
|
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
|
|
|
|
Visit(OVE->getSourceExpr());
|
|
|
|
}
|
|
|
|
|
2011-10-11 10:20:01 +08:00
|
|
|
void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
|
|
|
|
VisitExpr(S);
|
2011-10-15 04:59:01 +08:00
|
|
|
ID.AddInteger(S->getOp());
|
2011-10-11 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOperatorKind &UnaryOp,
|
|
|
|
BinaryOperatorKind &BinaryOp) {
|
2010-05-19 12:13:23 +08:00
|
|
|
switch (S->getOperator()) {
|
|
|
|
case OO_None:
|
|
|
|
case OO_New:
|
|
|
|
case OO_Delete:
|
|
|
|
case OO_Array_New:
|
|
|
|
case OO_Array_Delete:
|
|
|
|
case OO_Arrow:
|
|
|
|
case OO_Call:
|
|
|
|
case OO_Conditional:
|
2015-10-22 13:12:22 +08:00
|
|
|
case OO_Coawait:
|
2010-05-19 12:13:23 +08:00
|
|
|
case NUM_OVERLOADED_OPERATORS:
|
|
|
|
llvm_unreachable("Invalid operator call kind");
|
|
|
|
|
|
|
|
case OO_Plus:
|
|
|
|
if (S->getNumArgs() == 1) {
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = UO_Plus;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Add;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Minus:
|
|
|
|
if (S->getNumArgs() == 1) {
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = UO_Minus;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Sub;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Star:
|
|
|
|
if (S->getNumArgs() == 1) {
|
2014-06-06 06:43:40 +08:00
|
|
|
UnaryOp = UO_Deref;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
|
|
|
|
2014-06-06 06:43:40 +08:00
|
|
|
BinaryOp = BO_Mul;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Slash:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Div;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Percent:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Rem;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Caret:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Xor;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Amp:
|
|
|
|
if (S->getNumArgs() == 1) {
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = UO_AddrOf;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_And;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Pipe:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Or;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Tilde:
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = UO_Not;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Exclaim:
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = UO_LNot;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Equal:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Assign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Less:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_LT;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Greater:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_GT;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_PlusEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_AddAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_MinusEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_SubAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_StarEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_MulAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_SlashEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_DivAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_PercentEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_RemAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_CaretEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_XorAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_AmpEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_AndAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_PipeEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_OrAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_LessLess:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Shl;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_GreaterGreater:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Shr;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_LessLessEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_ShlAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_GreaterGreaterEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_ShrAssign;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_EqualEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_EQ;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_ExclaimEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_NE;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_LessEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_LE;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_GreaterEqual:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_GE;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_AmpAmp:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_LAnd;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_PipePipe:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_LOr;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_PlusPlus:
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = S->getNumArgs() == 1? UO_PreInc
|
|
|
|
: UO_PostInc;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_MinusMinus:
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOp = S->getNumArgs() == 1? UO_PreDec
|
|
|
|
: UO_PostDec;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Comma:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_Comma;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_ArrowStar:
|
2010-08-25 19:45:40 +08:00
|
|
|
BinaryOp = BO_PtrMemI;
|
2010-05-19 12:13:23 +08:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Subscript:
|
|
|
|
return Stmt::ArraySubscriptExprClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid overloaded operator expression");
|
|
|
|
}
|
2014-06-06 06:43:40 +08:00
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
|
2010-05-19 12:13:23 +08:00
|
|
|
if (S->isTypeDependent()) {
|
|
|
|
// Type-dependent operator calls are profiled like their underlying
|
|
|
|
// syntactic operator.
|
2016-10-25 02:47:04 +08:00
|
|
|
//
|
|
|
|
// An operator call to operator-> is always implicit, so just skip it. The
|
|
|
|
// enclosing MemberExpr will profile the actual member access.
|
|
|
|
if (S->getOperator() == OO_Arrow)
|
|
|
|
return Visit(S->getArg(0));
|
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
UnaryOperatorKind UnaryOp = UO_Extension;
|
|
|
|
BinaryOperatorKind BinaryOp = BO_Comma;
|
2010-05-19 12:13:23 +08:00
|
|
|
Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
|
2014-06-06 06:43:40 +08:00
|
|
|
|
2010-05-19 12:13:23 +08:00
|
|
|
ID.AddInteger(SC);
|
|
|
|
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
|
|
|
Visit(S->getArg(I));
|
|
|
|
if (SC == Stmt::UnaryOperatorClass)
|
|
|
|
ID.AddInteger(UnaryOp);
|
|
|
|
else if (SC == Stmt::BinaryOperatorClass ||
|
|
|
|
SC == Stmt::CompoundAssignOperatorClass)
|
|
|
|
ID.AddInteger(BinaryOp);
|
|
|
|
else
|
|
|
|
assert(SC == Stmt::ArraySubscriptExprClass);
|
2014-06-06 06:43:40 +08:00
|
|
|
|
2010-05-19 12:13:23 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-06-06 06:43:40 +08:00
|
|
|
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCallExpr(S);
|
|
|
|
ID.AddInteger(S->getOperator());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
|
2011-02-10 05:07:24 +08:00
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
|
2011-06-04 08:47:47 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-03-07 16:35:16 +08:00
|
|
|
void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
|
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
|
2009-07-30 00:09:57 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2013-06-13 06:31:48 +08:00
|
|
|
void StmtProfiler::VisitCXXStdInitializerListExpr(
|
|
|
|
const CXXStdInitializerListExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
if (S->isTypeOperand())
|
2013-09-27 15:04:31 +08:00
|
|
|
VisitType(S->getTypeOperandSourceInfo()->getType());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
|
2010-09-08 20:20:18 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
if (S->isTypeOperand())
|
2013-09-27 15:04:31 +08:00
|
|
|
VisitType(S->getTypeOperandSourceInfo()->getType());
|
2010-09-08 20:20:18 +08:00
|
|
|
}
|
|
|
|
|
2013-04-16 15:28:30 +08:00
|
|
|
void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getPropertyDecl());
|
|
|
|
}
|
|
|
|
|
2015-11-25 20:01:00 +08:00
|
|
|
void StmtProfiler::VisitMSPropertySubscriptExpr(
|
|
|
|
const MSPropertySubscriptExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
2012-04-16 15:05:22 +08:00
|
|
|
ID.AddBoolean(S->isImplicit());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParam());
|
|
|
|
}
|
|
|
|
|
2013-04-21 06:23:05 +08:00
|
|
|
void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getField());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(
|
|
|
|
const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getConstructor());
|
|
|
|
ID.AddBoolean(S->isElidable());
|
|
|
|
}
|
|
|
|
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-29 03:03:57 +08:00
|
|
|
void StmtProfiler::VisitCXXInheritedCtorInitExpr(
|
|
|
|
const CXXInheritedCtorInitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getConstructor());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitCXXConstructExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-02-07 18:09:13 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
|
|
|
|
CEnd = S->explicit_capture_end();
|
|
|
|
C != CEnd; ++C) {
|
|
|
|
ID.AddInteger(C->getCaptureKind());
|
2013-05-16 14:20:58 +08:00
|
|
|
switch (C->getCaptureKind()) {
|
[Cxx1z] Implement Lambda Capture of *this by Value as [=,*this] (P0018R3)
Implement lambda capture of *this by copy.
For e.g.:
struct A {
int d = 10;
auto foo() { return [*this] (auto a) mutable { d+=a; return d; }; }
};
auto L = A{}.foo(); // A{}'s lifetime is gone.
// Below is still ok, because *this was captured by value.
assert(L(10) == 20);
assert(L(100) == 120);
If the capture was implicit, or [this] (i.e. *this was captured by reference), this code would be otherwise undefined.
Implementation Strategy:
- amend the parser to accept *this in the lambda introducer
- add a new king of capture LCK_StarThis
- teach Sema::CheckCXXThisCapture to handle by copy captures of the
enclosing object (i.e. *this)
- when CheckCXXThisCapture does capture by copy, the corresponding
initializer expression for the closure's data member
direct-initializes it thus making a copy of '*this'.
- in codegen, when assigning to CXXThisValue, if *this was captured by
copy, make sure it points to the corresponding field member, and
not, unlike when captured by reference, what the field member points
to.
- mark feature as implemented in svn
Much gratitude to Richard Smith for his carefully illuminating reviews!
llvm-svn: 263921
2016-03-21 17:25:37 +08:00
|
|
|
case LCK_StarThis:
|
2013-05-16 14:20:58 +08:00
|
|
|
case LCK_This:
|
|
|
|
break;
|
|
|
|
case LCK_ByRef:
|
|
|
|
case LCK_ByCopy:
|
2012-02-07 18:09:13 +08:00
|
|
|
VisitDecl(C->getCapturedVar());
|
|
|
|
ID.AddBoolean(C->isPackExpansion());
|
2013-05-16 14:20:58 +08:00
|
|
|
break;
|
2014-08-28 12:28:19 +08:00
|
|
|
case LCK_VLAType:
|
|
|
|
llvm_unreachable("VLA type in explicit captures.");
|
2012-02-07 18:09:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Note: If we actually needed to be able to match lambda
|
|
|
|
// expressions, we would have to consider parameters and return type
|
|
|
|
// here, among other things.
|
|
|
|
VisitStmt(S->getBody());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isGlobalDelete());
|
|
|
|
ID.AddBoolean(S->isArrayForm());
|
|
|
|
VisitDecl(S->getOperatorDelete());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getAllocatedType());
|
|
|
|
VisitDecl(S->getOperatorNew());
|
|
|
|
VisitDecl(S->getOperatorDelete());
|
|
|
|
ID.AddBoolean(S->isArray());
|
|
|
|
ID.AddInteger(S->getNumPlacementArgs());
|
|
|
|
ID.AddBoolean(S->isGlobalNew());
|
|
|
|
ID.AddBoolean(S->isParenTypeId());
|
2012-02-16 20:22:20 +08:00
|
|
|
ID.AddInteger(S->getInitializationStyle());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
|
2009-09-05 01:36:40 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2014-05-12 13:36:57 +08:00
|
|
|
ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
|
2013-08-10 07:37:05 +08:00
|
|
|
if (S->getScopeTypeInfo())
|
|
|
|
VisitType(S->getScopeTypeInfo()->getType());
|
2014-05-12 13:36:57 +08:00
|
|
|
ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
|
2013-08-10 07:37:05 +08:00
|
|
|
if (S->getDestroyedTypeInfo())
|
|
|
|
VisitType(S->getDestroyedType());
|
|
|
|
else
|
2017-02-23 06:22:42 +08:00
|
|
|
VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
|
2009-09-05 01:36:40 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
|
2010-08-16 04:53:20 +08:00
|
|
|
VisitExpr(S);
|
2009-11-25 03:00:30 +08:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitName(S->getName());
|
2009-11-25 03:00:30 +08:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
2015-12-24 10:59:37 +08:00
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2010-08-15 09:15:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-06-16 14:47:06 +08:00
|
|
|
StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
|
2010-08-15 09:15:38 +08:00
|
|
|
VisitOverloadExpr(S);
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2012-02-24 15:38:34 +08:00
|
|
|
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
ID.AddInteger(S->getNumArgs());
|
|
|
|
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
|
|
|
VisitType(S->getArg(I)->getType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
|
2011-04-28 08:16:57 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
VisitType(S->getQueriedType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
|
2011-04-25 14:54:41 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
VisitExpr(S->getQueriedExpression());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitDependentScopeDeclRefExpr(
|
|
|
|
const DependentScopeDeclRefExpr *S) {
|
2009-07-28 08:33:38 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getDeclName());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-11-25 03:00:30 +08:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXUnresolvedConstructExpr(
|
|
|
|
const CXXUnresolvedConstructExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getTypeAsWritten());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXDependentScopeMemberExpr(
|
|
|
|
const CXXDependentScopeMemberExpr *S) {
|
2009-12-02 06:10:20 +08:00
|
|
|
ID.AddBoolean(S->isImplicitAccess());
|
|
|
|
if (!S->isImplicitAccess()) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
2009-09-04 00:14:30 +08:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitName(S->getMember());
|
2009-12-02 06:10:20 +08:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
2009-12-01 06:42:35 +08:00
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
|
2009-12-02 06:10:20 +08:00
|
|
|
ID.AddBoolean(S->isImplicitAccess());
|
|
|
|
if (!S->isImplicitAccess()) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
2009-12-01 06:42:35 +08:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
|
|
|
VisitName(S->getMemberName());
|
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2009-07-28 22:44:31 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
|
2010-09-11 04:55:43 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
|
2011-01-04 01:17:50 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
|
2011-01-05 01:33:58 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getPack());
|
2015-09-24 05:41:42 +08:00
|
|
|
if (S->isPartiallySubstituted()) {
|
|
|
|
auto Args = S->getPartialArguments();
|
|
|
|
ID.AddInteger(Args.size());
|
|
|
|
for (const auto &TA : Args)
|
|
|
|
VisitTemplateArgument(TA);
|
|
|
|
} else {
|
|
|
|
ID.AddInteger(0);
|
|
|
|
}
|
2011-01-05 01:33:58 +08:00
|
|
|
}
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
|
2011-06-16 14:47:06 +08:00
|
|
|
const SubstNonTypeTemplateParmPackExpr *S) {
|
2011-01-15 09:15:58 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParameterPack());
|
|
|
|
VisitTemplateArgument(S->getArgumentPack());
|
|
|
|
}
|
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
|
|
|
|
const SubstNonTypeTemplateParmExpr *E) {
|
|
|
|
// Profile exactly as the replacement expression.
|
|
|
|
Visit(E->getReplacement());
|
|
|
|
}
|
|
|
|
|
2012-09-12 08:56:43 +08:00
|
|
|
void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParameterPack());
|
|
|
|
ID.AddInteger(S->getNumExpansions());
|
|
|
|
for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
|
|
|
|
VisitDecl(*I);
|
|
|
|
}
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
void StmtProfiler::VisitMaterializeTemporaryExpr(
|
|
|
|
const MaterializeTemporaryExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2014-11-08 13:07:16 +08:00
|
|
|
void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOperator());
|
|
|
|
}
|
|
|
|
|
2015-10-27 14:02:45 +08:00
|
|
|
void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
|
2010-11-16 07:31:06 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:07:20 +08:00
|
|
|
void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-04-19 08:25:12 +08:00
|
|
|
void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
|
2012-03-07 04:05:56 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getEncodedType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getSelector());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getProtocol());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getDecl());
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
ID.AddBoolean(S->isFreeIvar());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
2010-12-02 09:19:52 +08:00
|
|
|
if (S->isImplicitProperty()) {
|
|
|
|
VisitDecl(S->getImplicitPropertyGetter());
|
|
|
|
VisitDecl(S->getImplicitPropertySetter());
|
|
|
|
} else {
|
|
|
|
VisitDecl(S->getExplicitProperty());
|
2010-10-15 00:04:05 +08:00
|
|
|
}
|
|
|
|
if (S->isSuperReceiver()) {
|
|
|
|
ID.AddBoolean(S->isSuperReceiver());
|
2010-12-02 09:19:52 +08:00
|
|
|
VisitType(S->getSuperReceiverType());
|
2010-10-15 00:04:05 +08:00
|
|
|
}
|
2009-07-28 22:44:31 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getAtIndexMethodDecl());
|
|
|
|
VisitDecl(S->setAtIndexMethodDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getSelector());
|
|
|
|
VisitDecl(S->getMethodDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
|
2009-07-28 22:44:31 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
|
|
|
|
const ObjCIndirectCopyRestoreExpr *S) {
|
2011-06-16 07:02:42 +08:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->shouldCopy());
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:47:06 +08:00
|
|
|
void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
|
2011-06-16 07:02:42 +08:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
ID.AddBoolean(S->getBridgeKind());
|
|
|
|
}
|
|
|
|
|
2016-07-16 08:35:23 +08:00
|
|
|
void StmtProfiler::VisitObjCAvailabilityCheckExpr(
|
|
|
|
const ObjCAvailabilityCheckExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2009-10-29 16:12:44 +08:00
|
|
|
void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
|
2009-07-28 08:33:38 +08:00
|
|
|
unsigned NumArgs) {
|
|
|
|
ID.AddInteger(NumArgs);
|
2009-10-29 16:12:44 +08:00
|
|
|
for (unsigned I = 0; I != NumArgs; ++I)
|
|
|
|
VisitTemplateArgument(Args[I].getArgument());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
|
|
|
|
// Mostly repetitive with TemplateArgument::Profile!
|
|
|
|
ID.AddInteger(Arg.getKind());
|
|
|
|
switch (Arg.getKind()) {
|
|
|
|
case TemplateArgument::Null:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Type:
|
|
|
|
VisitType(Arg.getAsType());
|
|
|
|
break;
|
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
case TemplateArgument::Template:
|
2011-01-06 02:58:31 +08:00
|
|
|
case TemplateArgument::TemplateExpansion:
|
|
|
|
VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
|
2009-11-11 09:00:40 +08:00
|
|
|
break;
|
2010-05-05 23:23:54 +08:00
|
|
|
|
2009-10-29 16:12:44 +08:00
|
|
|
case TemplateArgument::Declaration:
|
|
|
|
VisitDecl(Arg.getAsDecl());
|
|
|
|
break;
|
|
|
|
|
2012-09-26 10:36:12 +08:00
|
|
|
case TemplateArgument::NullPtr:
|
|
|
|
VisitType(Arg.getNullPtrType());
|
|
|
|
break;
|
|
|
|
|
2009-10-29 16:12:44 +08:00
|
|
|
case TemplateArgument::Integral:
|
2012-06-07 23:09:51 +08:00
|
|
|
Arg.getAsIntegral().Profile(ID);
|
2009-10-29 16:12:44 +08:00
|
|
|
VisitType(Arg.getIntegralType());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Expression:
|
|
|
|
Visit(Arg.getAsExpr());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Pack:
|
2014-07-16 05:32:31 +08:00
|
|
|
for (const auto &P : Arg.pack_elements())
|
|
|
|
VisitTemplateArgument(P);
|
2009-10-29 16:12:44 +08:00
|
|
|
break;
|
2009-07-28 08:33:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-12 17:06:06 +08:00
|
|
|
void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
|
2011-06-16 14:47:06 +08:00
|
|
|
bool Canonical) const {
|
2017-02-23 06:22:42 +08:00
|
|
|
StmtProfilerWithPointers Profiler(ID, Context, Canonical);
|
|
|
|
Profiler.Visit(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
|
|
|
|
class ODRHash &Hash) const {
|
|
|
|
StmtProfilerWithoutPointers Profiler(ID, Hash);
|
2009-07-28 08:33:38 +08:00
|
|
|
Profiler.Visit(this);
|
|
|
|
}
|