vsapsai created this revision.
vsapsai added reviewers: aaron.ballman, ChuanqiXu, erichkeane.
Herald added a subscriber: ributzka.
Herald added a project: All.
vsapsai requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
In this change deliberately keeping the tests intact to make sure
TableGen implementation works the same way as the manual one.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D138859
Files:
clang/include/clang/AST/Attr.h
clang/include/clang/Basic/Attr.td
clang/lib/AST/AttrImpl.cpp
clang/lib/AST/ODRHash.cpp
clang/utils/TableGen/ClangAttrEmitter.cpp
Index: clang/utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- clang/utils/TableGen/ClangAttrEmitter.cpp
+++ clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -249,6 +249,7 @@
virtual void writeDump(raw_ostream &OS) const = 0;
virtual void writeDumpChildren(raw_ostream &OS) const {}
virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
+ virtual void writeODRHashing(raw_ostream &OS) const {}
virtual bool isEnumArg() const { return false; }
virtual bool isVariadicEnumArg() const { return false; }
@@ -647,6 +648,20 @@
void writeHasChildren(raw_ostream &OS) const override {
OS << "SA->is" << getUpperName() << "Expr()";
}
+
+ void writeODRHashing(raw_ostream &OS) const override {
+ OS << " ID.AddBoolean(is" << getUpperName() << "Expr());\n";
+ OS << " if (is" << getUpperName() << "Expr()) {\n";
+ OS << " const Expr *" << getUpperName() << "Expr = "
+ << "get" << getUpperName() << "Expr();\n";
+ OS << " ID.AddBoolean(" << getUpperName() << "Expr);\n";
+ OS << " if (" << getUpperName() << "Expr)\n"
+ << " Hash.AddStmt(" << getUpperName() << "Expr);\n";
+ OS << " } else {\n";
+ OS << " ID.AddString(get" << getUpperName()
+ << "Type()->getType().getAsString());\n";
+ OS << " }\n";
+ }
};
class VariadicArgument : public Argument {
@@ -1006,6 +1021,10 @@
<< " llvm_unreachable(\"No enumerator with that value\");\n"
<< "}\n";
}
+
+ void writeODRHashing(raw_ostream &OS) const override {
+ OS << " ID.AddInteger(get" << getUpperName() << "());\n";
+ }
};
class VariadicEnumArgument: public VariadicArgument {
@@ -1230,6 +1249,14 @@
}
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
+
+ void writeODRHashing(raw_ostream &OS) const override {
+ OS << " const Expr *" << getUpperName() << "Expr = "
+ << "get" << getUpperName() << "();\n";
+ OS << " ID.AddBoolean(" << getUpperName() << "Expr);\n";
+ OS << " if (" << getUpperName() << "Expr)\n"
+ << " Hash.AddStmt(" << getUpperName() << "Expr);\n";
+ }
};
class VariadicExprArgument : public VariadicArgument {
@@ -1624,6 +1651,27 @@
OS << "}\n\n";
}
+static void
+writeProcessODRHashFunction(const Record &R,
+ const std::vector<std::unique_ptr<Argument>> &Args,
+ raw_ostream &OS) {
+ OS << "void " << R.getName() << "Attr::processODRHash(\n"
+ << " llvm::FoldingSetNodeID &ID, ODRHash &Hash) const {\n";
+ if (!R.getValueAsBit("IsODRHashable")) {
+ OS << " // Not ODR-hashable\n}\n\n";
+ return;
+ }
+
+ OS << " ID.AddInteger(Attr::getKind());\n";
+ for (const auto &Arg : Args) {
+ if (Arg->isFake())
+ continue;
+ Arg->writeODRHashing(OS);
+ }
+ // End of the processODRHash function.
+ OS << "}\n\n";
+}
+
/// Return the index of a spelling in a spelling list.
static unsigned
getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
@@ -2683,7 +2731,8 @@
}
OS << "\n : " << SuperName << "(Ctx, CommonInfo, ";
OS << "attr::" << R.getName() << ", "
- << (R.getValueAsBit("LateParsed") ? "true" : "false");
+ << (R.getValueAsBit("LateParsed") ? "true" : "false") << ", "
+ << (R.getValueAsBit("IsODRHashable") ? "true" : "false");
if (Inheritable) {
OS << ", "
<< (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
@@ -2746,6 +2795,8 @@
OS << " void printPretty(raw_ostream &OS,\n"
<< " const PrintingPolicy &Policy) const;\n";
OS << " const char *getSpelling() const;\n";
+ OS << " void processODRHash(llvm::FoldingSetNodeID &ID,\n"
+ << " class ODRHash &Hash) const;\n";
}
if (!ElideSpelling) {
@@ -2820,6 +2871,7 @@
writePrettyPrintFunction(R, Args, OS);
writeGetSpellingFunction(R, OS);
+ writeProcessODRHashFunction(R, Args, OS);
}
}
}
@@ -2870,6 +2922,10 @@
OS << "void Attr::printPretty(raw_ostream &OS, "
"const PrintingPolicy &Policy) const {\n";
EmitFunc("printPretty(OS, Policy)");
+
+ OS << "void Attr::processODRHash(llvm::FoldingSetNodeID &ID, "
+ << "class ODRHash &Hash) const {";
+ EmitFunc("processODRHash(ID, Hash)");
}
static void emitAttrList(raw_ostream &OS, StringRef Class,
Index: clang/lib/AST/ODRHash.cpp
===================================================================
--- clang/lib/AST/ODRHash.cpp
+++ clang/lib/AST/ODRHash.cpp
@@ -539,7 +539,7 @@
return;
llvm::copy_if(D->attrs(), std::back_inserter(HashableAttrs),
- [](const Attr *A) { return !A->isImplicit(); });
+ [](const Attr *A) { return A->isODRHashable(); });
}
void ODRHash::AddAttrs(const Decl *D) {
@@ -551,39 +551,7 @@
}
void ODRHash::AddAttr(const Attr *A) {
- ID.AddInteger(A->getKind());
-
- // FIXME: This should be auto-generated as part of Attr.td
- switch (A->getKind()) {
- case attr::Aligned: {
- auto *M = cast<AlignedAttr>(A);
- ID.AddBoolean(M->isAlignmentExpr());
- if (M->isAlignmentExpr()) {
- Expr *AlignmentExpr = M->getAlignmentExpr();
- ID.AddBoolean(AlignmentExpr);
- if (AlignmentExpr)
- AddStmt(AlignmentExpr);
- } else {
- ID.AddString(M->getAlignmentType()->getType().getAsString());
- }
- break;
- }
- case attr::AlignValue: {
- auto *M = cast<AlignValueAttr>(A);
- Expr *AlignmentExpr = M->getAlignment();
- ID.AddBoolean(AlignmentExpr);
- if (AlignmentExpr)
- AddStmt(AlignmentExpr);
- break;
- }
- case attr::EnumExtensibility: {
- auto *M = cast<EnumExtensibilityAttr>(A);
- ID.AddInteger(M->getExtensibility());
- break;
- }
- default:
- break;
- }
+ A->processODRHash(ID, *this);
}
void ODRHash::AddSubDecl(const Decl *D) {
Index: clang/lib/AST/AttrImpl.cpp
===================================================================
--- clang/lib/AST/AttrImpl.cpp
+++ clang/lib/AST/AttrImpl.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ODRHash.h"
#include "clang/AST/Type.h"
using namespace clang;
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -549,6 +549,8 @@
list<Accessor> Accessors = [];
// Set to true for attributes with arguments which require delayed parsing.
bit LateParsed = 0;
+ // Set to true for attributes that should participate in ODR hashing.
+ bit IsODRHashable = 0;
// Set to false to prevent an attribute from being propagated from a template
// to the instantiation.
bit Clone = 1;
@@ -669,6 +671,7 @@
let Args = [VariadicStringArgument<"Tags">];
let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>;
let MeaningfulToClassTemplateDefinition = 1;
+ let IsODRHashable = 1;
let Documentation = [AbiTagsDocs];
}
@@ -710,6 +713,7 @@
Accessor<"isAlignas", [Keyword<"alignas">,
Keyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
+ let IsODRHashable = 1;
let Documentation = [Undocumented];
}
@@ -730,6 +734,7 @@
];
let Args = [ExprArgument<"Alignment">];
let Subjects = SubjectList<[Var, TypedefName]>;
+ let IsODRHashable = 1;
let Documentation = [AlignValueDocs];
}
@@ -1497,6 +1502,7 @@
let Subjects = SubjectList<[Enum]>;
let Args = [EnumArgument<"Extensibility", "Kind",
["closed", "open"], ["Closed", "Open"]>];
+ let IsODRHashable = 1;
let Documentation = [EnumExtensibilityDocs];
}
@@ -1719,6 +1725,7 @@
def Naked : InheritableAttr {
let Spellings = [GCC<"naked">, Declspec<"naked">];
let Subjects = SubjectList<[Function]>;
+ let IsODRHashable = 1;
let Documentation = [Undocumented];
}
@@ -2320,6 +2327,7 @@
def OptimizeNone : InheritableAttr {
let Spellings = [Clang<"optnone">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
+ let IsODRHashable = 1;
let Documentation = [OptnoneDocs];
}
@@ -2361,6 +2369,7 @@
def Packed : InheritableAttr {
let Spellings = [GCC<"packed">];
// let Subjects = [Tag, Field];
+ let IsODRHashable = 1;
let Documentation = [Undocumented];
}
@@ -2861,6 +2870,7 @@
C2x<"", "maybe_unused", 202106>];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
Field, ObjCMethod, FunctionLike]>;
+ let IsODRHashable = 1;
let Documentation = [WarnMaybeUnusedDocs];
}
Index: clang/include/clang/AST/Attr.h
===================================================================
--- clang/include/clang/AST/Attr.h
+++ clang/include/clang/AST/Attr.h
@@ -50,6 +50,7 @@
// FIXME: These are properties of the attribute kind, not state for this
// instance of the attribute.
unsigned IsLateParsed : 1;
+ unsigned IsODRHashable : 1;
unsigned InheritEvenIfAlreadyPresent : 1;
void *operator new(size_t bytes) noexcept {
@@ -71,10 +72,10 @@
protected:
Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable)
: AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
- InheritEvenIfAlreadyPresent(false) {}
+ IsODRHashable(IsODRHashable), InheritEvenIfAlreadyPresent(false) {}
public:
attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
@@ -101,17 +102,25 @@
bool isLateParsed() const { return IsLateParsed; }
+ bool isODRHashable() const { return IsODRHashable; }
+
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ /// Hash the attribute and its salient arguments.
+ ///
+ /// It is an implementation detail and for obtaining a hash you should use
+ /// ODRHash, specifically ODRHash::AddAttr.
+ void processODRHash(llvm::FoldingSetNodeID &ID, class ODRHash &Hash) const;
+
static StringRef getDocumentation(attr::Kind);
};
class TypeAttr : public Attr {
protected:
TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {}
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable)
+ : Attr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable) {}
public:
static bool classof(const Attr *A) {
@@ -123,8 +132,8 @@
class StmtAttr : public Attr {
protected:
StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {}
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable)
+ : Attr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable) {}
public:
static bool classof(const Attr *A) {
@@ -136,9 +145,9 @@
class InheritableAttr : public Attr {
protected:
InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable,
bool InheritEvenIfAlreadyPresent)
- : Attr(Context, CommonInfo, AK, IsLateParsed) {
+ : Attr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable) {
this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
}
@@ -161,9 +170,9 @@
class DeclOrStmtAttr : public InheritableAttr {
protected:
DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable,
bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable,
InheritEvenIfAlreadyPresent) {}
public:
@@ -177,8 +186,9 @@
protected:
InheritableParamAttr(ASTContext &Context,
const AttributeCommonInfo &CommonInfo, attr::Kind AK,
- bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
+ bool IsLateParsed, bool IsODRHashable,
+ bool InheritEvenIfAlreadyPresent)
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable,
InheritEvenIfAlreadyPresent) {}
public:
@@ -192,9 +202,9 @@
class HLSLAnnotationAttr : public InheritableAttr {
protected:
HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable,
bool InheritEvenIfAlreadyPresent)
- : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed, IsODRHashable,
InheritEvenIfAlreadyPresent) {}
public:
@@ -210,10 +220,10 @@
class ParameterABIAttr : public InheritableParamAttr {
protected:
ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
- attr::Kind AK, bool IsLateParsed,
+ attr::Kind AK, bool IsLateParsed, bool IsODRHashable,
bool InheritEvenIfAlreadyPresent)
: InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
- InheritEvenIfAlreadyPresent) {}
+ IsODRHashable, InheritEvenIfAlreadyPresent) {}
public:
ParameterABI getABI() const {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits