Skip to content

Commit 016dcdb

Browse files
committed
[clang][Summary] refactor summary attributes
1 parent 81b039f commit 016dcdb

File tree

4 files changed

+60
-50
lines changed

4 files changed

+60
-50
lines changed

clang/include/clang/Sema/SummaryAttribute.h

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,40 @@
33

44
#include "clang/AST/Decl.h"
55
#include "clang/ASTMatchers/ASTMatchFinder.h"
6-
#include <string>
76

87
namespace clang {
9-
enum SummaryAttributeKind {
8+
enum SummaryAttrKind {
109
NO_WRITE_GLOBAL,
1110
};
1211

1312
class FunctionSummary;
13+
class SummaryContext;
1414

15-
class SummaryAttribute {
16-
const SummaryAttributeKind Kind;
17-
std::string_view Serialzed;
15+
class SummaryAttr {
16+
const SummaryAttrKind Kind;
17+
const char *Spelling;
18+
19+
protected:
20+
SummaryAttr(SummaryAttrKind Kind, const char *Spelling)
21+
: Kind(Kind), Spelling(Spelling){};
1822

1923
public:
20-
SummaryAttribute(SummaryAttributeKind Attr, const char *Str)
21-
: Kind(Attr), Serialzed(Str) {}
22-
virtual ~SummaryAttribute() = default;
24+
virtual ~SummaryAttr() = default;
2325

24-
SummaryAttributeKind getKind() { return Kind; }
26+
SummaryAttrKind getKind() const { return Kind; }
27+
const char *getSpelling() const { return Spelling; }
2528

2629
virtual bool infer(const FunctionDecl *FD) const = 0;
2730
virtual bool merge(const FunctionSummary &Caller,
2831
const FunctionSummary &Callee) const = 0;
2932

30-
virtual std::string serialize() const { return std::string(Serialzed); };
33+
virtual std::string serialize() const { return std::string(Spelling); };
3134
virtual bool parse(std::string_view input) const {
32-
return input == Serialzed;
35+
return input == Spelling;
3336
};
3437
};
3538

36-
class NoWriteGlobalAttr : public SummaryAttribute {
39+
class NoWriteGlobalAttr : public SummaryAttr {
3740
class Callback : public ast_matchers::MatchFinder::MatchCallback {
3841
public:
3942
bool WriteGlobal = false;
@@ -42,12 +45,17 @@ class NoWriteGlobalAttr : public SummaryAttribute {
4245
run(const ast_matchers::MatchFinder::MatchResult &Result) override final;
4346
};
4447

45-
public:
46-
NoWriteGlobalAttr() : SummaryAttribute(NO_WRITE_GLOBAL, "no_write_global") {}
48+
NoWriteGlobalAttr() : SummaryAttr(NO_WRITE_GLOBAL, "no_write_global") {}
4749

50+
public:
4851
bool infer(const FunctionDecl *FD) const override final;
4952
bool merge(const FunctionSummary &Caller,
5053
const FunctionSummary &Callee) const override final;
54+
55+
static bool classof(const SummaryAttr *A) {
56+
return A->getKind() == NO_WRITE_GLOBAL;
57+
}
58+
friend class SummaryContext;
5159
};
5260
} // namespace clang
5361

clang/include/clang/Sema/SummaryContext.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,27 @@
88
namespace clang {
99
class FunctionSummary {
1010
SmallVector<char> ID;
11-
std::set<const SummaryAttribute *> Attrs;
11+
std::set<const SummaryAttr *> Attrs;
1212
std::set<SmallVector<char>> Calls;
1313

1414
public:
15-
FunctionSummary(SmallVector<char> ID,
16-
std::set<const SummaryAttribute *> Attrs,
15+
FunctionSummary(SmallVector<char> ID, std::set<const SummaryAttr *> Attrs,
1716
std::set<SmallVector<char>> Calls);
1817

1918
SmallVector<char> getID() const { return ID; }
20-
const std::set<const SummaryAttribute *> &getAttributes() const {
21-
return Attrs;
22-
}
19+
const std::set<const SummaryAttr *> &getAttributes() const { return Attrs; }
2320
const std::set<SmallVector<char>> &getCalls() const { return Calls; }
2421

25-
void replaceAttributes(std::set<const SummaryAttribute *> Attrs) {
22+
template <typename T> bool hasAttribute() const {
23+
for (auto &&attr : Attrs) {
24+
if (llvm::isa<T>(attr))
25+
return true;
26+
}
27+
28+
return false;
29+
}
30+
31+
void replaceAttributes(std::set<const SummaryAttr *> Attrs) {
2632
this->Attrs = std::move(Attrs);
2733
}
2834
};
@@ -31,18 +37,18 @@ class SummaryContext {
3137
std::map<SmallVector<char>, const FunctionSummary *> IDToSummary;
3238
std::vector<std::unique_ptr<FunctionSummary>> FunctionSummaries;
3339

34-
std::map<SummaryAttributeKind, const SummaryAttribute *> KindToAttribute;
35-
std::vector<std::unique_ptr<SummaryAttribute>> Attributes;
40+
std::map<SummaryAttrKind, const SummaryAttr *> KindToAttribute;
41+
std::vector<std::unique_ptr<SummaryAttr>> Attributes;
3642

37-
void CreateSummary(SmallVector<char> ID,
38-
std::set<const SummaryAttribute *> Attrs,
43+
void CreateSummary(SmallVector<char> ID, std::set<const SummaryAttr *> Attrs,
3944
std::set<SmallVector<char>> Calls);
4045
bool ReduceFunctionSummary(FunctionSummary &FunctionSummary);
4146

47+
template <typename T> void registerAttr();
48+
4249
public:
4350
SummaryContext();
4451

45-
const SummaryAttribute *GetAttribute(SummaryAttributeKind kind) const;
4652
const FunctionSummary *GetSummary(const FunctionDecl *FD) const;
4753
void SummarizeFunctionBody(const FunctionDecl *FD);
4854

clang/lib/Sema/SummaryContext.cpp

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,41 @@ class CallCollector : public ast_matchers::MatchFinder::MatchCallback {
4040
};
4141
} // namespace
4242

43-
FunctionSummary::FunctionSummary(
44-
SmallVector<char> ID, std::set<const SummaryAttribute *> FunctionAttrs,
45-
std::set<SmallVector<char>> Calls)
43+
FunctionSummary::FunctionSummary(SmallVector<char> ID,
44+
std::set<const SummaryAttr *> FunctionAttrs,
45+
std::set<SmallVector<char>> Calls)
4646
: ID(std::move(ID)), Attrs(std::move(FunctionAttrs)),
4747
Calls(std::move(Calls)) {}
4848

49-
SummaryContext::SummaryContext() {
50-
Attributes.emplace_back(std::make_unique<NoWriteGlobalAttr>());
49+
template <typename T> void SummaryContext::registerAttr() {
50+
std::unique_ptr<T> attr(new T());
51+
SummaryAttrKind Kind = attr->getKind();
5152

52-
for (auto &&Attr : Attributes) {
53-
assert(KindToAttribute.count(Attr->getKind()) == 0 &&
54-
"Attr already registered");
55-
KindToAttribute[Attr->getKind()] = Attr.get();
56-
}
53+
if (KindToAttribute.count(Kind))
54+
return;
55+
56+
KindToAttribute[Kind] = Attributes.emplace_back(std::move(attr)).get();
5757
}
5858

59+
SummaryContext::SummaryContext() { registerAttr<NoWriteGlobalAttr>(); }
60+
5961
void SummaryContext::CreateSummary(SmallVector<char> ID,
60-
std::set<const SummaryAttribute *> Attrs,
62+
std::set<const SummaryAttr *> Attrs,
6163
std::set<SmallVector<char>> Calls) {
6264
auto Summary = std::make_unique<FunctionSummary>(
6365
std::move(ID), std::move(Attrs), std::move(Calls));
6466
auto *SummaryPtr = FunctionSummaries.emplace_back(std::move(Summary)).get();
6567
IDToSummary[SummaryPtr->getID()] = SummaryPtr;
6668
}
6769

68-
const SummaryAttribute *
69-
SummaryContext::GetAttribute(SummaryAttributeKind kind) const {
70-
return KindToAttribute.at(kind);
71-
}
72-
7370
const FunctionSummary *
7471
SummaryContext::GetSummary(const FunctionDecl *FD) const {
7572
auto USR = GetUSR(FD);
7673
return IDToSummary.count(USR) ? IDToSummary.at(USR) : nullptr;
7774
}
7875

7976
void SummaryContext::SummarizeFunctionBody(const FunctionDecl *FD) {
80-
std::set<const SummaryAttribute *> Attrs;
77+
std::set<const SummaryAttr *> Attrs;
8178

8279
for (auto &&Attr : Attributes) {
8380
if (Attr->infer(FD))
@@ -92,7 +89,7 @@ void SummaryContext::ParseSummaryFromJSON(const llvm::json::Array &Summary) {
9289
const llvm::json::Object *FunctionSummary = it->getAsObject();
9390

9491
SmallString<128> ID(*FunctionSummary->getString("id"));
95-
std::set<const SummaryAttribute *> FunctionAttrs;
92+
std::set<const SummaryAttr *> FunctionAttrs;
9693
const llvm::json::Array *FunctionAttributes =
9794
FunctionSummary->getObject("attrs")->getArray("function");
9895
for(auto attrIt = FunctionAttributes->begin(); attrIt != FunctionAttributes->end(); ++attrIt) {
@@ -117,7 +114,7 @@ bool SummaryContext::ReduceFunctionSummary(FunctionSummary &Function) {
117114
bool changed = false;
118115

119116
for (auto &&call : Function.getCalls()) {
120-
std::set<const SummaryAttribute *> reducedAttrs;
117+
std::set<const SummaryAttr *> reducedAttrs;
121118

122119
// If we don't have a summary about a called function, we forget
123120
// everything about the current one as well.

clang/lib/StaticAnalyzer/Core/CallEvent.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,11 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
280280
bool ShouldPreserveGlobals = false;
281281
const SummaryContext *SummaryCtx =
282282
State->getStateManager().getOwningEngine().getSummaryCtx();
283-
if (SummaryCtx) {
284-
const auto *Summary =
285-
SummaryCtx->GetSummary(llvm::dyn_cast<FunctionDecl>(getDecl()));
283+
const FunctionDecl *FD = llvm::dyn_cast<FunctionDecl>(getDecl());
284+
if (SummaryCtx && FD) {
285+
const auto *Summary = SummaryCtx->GetSummary(FD);
286286
ShouldPreserveGlobals =
287-
Summary && Summary->getAttributes().count(
288-
SummaryCtx->GetAttribute(NO_WRITE_GLOBAL));
287+
Summary && Summary->hasAttribute<NoWriteGlobalAttr>();
289288
}
290289

291290
// Invalidate designated regions using the batch invalidation API.

0 commit comments

Comments
 (0)