Skip to content

Commit 639d7b6

Browse files
committed
[ODRHash] static_cast and Stmt hashing.
Add support for static_cast in classes. Add pointer-independent profiling for Stmt's, sharing most of the logic with Stmt::Profile. This is the first of the deep sub-Decl diffing for error messages. Differential Revision: https://reviews.llvm.org/D21675 llvm-svn: 295890
1 parent fccbda9 commit 639d7b6

File tree

6 files changed

+366
-91
lines changed

6 files changed

+366
-91
lines changed

clang/include/clang/AST/Stmt.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace clang {
3939
class Expr;
4040
class IdentifierInfo;
4141
class LabelDecl;
42+
class ODRHash;
4243
class ParmVarDecl;
4344
class PrinterHelper;
4445
struct PrintingPolicy;
@@ -436,6 +437,15 @@ class alignas(void *) Stmt {
436437
/// written in the source.
437438
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
438439
bool Canonical) const;
440+
441+
/// \brief Calculate a unique representation for a statement that is
442+
/// stable across compiler invocations.
443+
///
444+
/// \param ID profile information will be stored in ID.
445+
///
446+
/// \param Hash an ODRHash object which will be called where pointers would
447+
/// have been used in the Profile function.
448+
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
439449
};
440450

441451
/// DeclStmt - Adaptor class for mixing declarations with statements and

clang/include/clang/Basic/DiagnosticSerializationKinds.td

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,24 @@ def err_module_odr_violation_mismatch_decl : Error<
121121
"%q0 has different definitions in different modules; first difference is "
122122
"%select{definition in module '%2'|defined here}1 found "
123123
"%select{end of class|public access specifier|private access specifier|"
124-
"protected access specifier}3">;
124+
"protected access specifier|static assert}3">;
125125
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
126126
"%select{end of class|public access specifier|private access specifier|"
127-
"protected access specifier}1">;
127+
"protected access specifier|static assert}1">;
128+
129+
def err_module_odr_violation_mismatch_decl_diff : Error<
130+
"%q0 has different definitions in different modules; first difference is "
131+
"%select{definition in module '%2'|defined here}1 found "
132+
"%select{"
133+
"static assert with condition|"
134+
"static assert with message|"
135+
"static assert with %select{|no }4message}3">;
136+
137+
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
138+
"%select{"
139+
"static assert with different condition|"
140+
"static assert with different message|"
141+
"static assert with %select{|no }2message}1">;
128142

129143
def warn_module_uses_date_time : Warning<
130144
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,

clang/lib/AST/ODRHash.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222

2323
using namespace clang;
2424

25-
void ODRHash::AddStmt(const Stmt *S) {}
25+
void ODRHash::AddStmt(const Stmt *S) {
26+
assert(S && "Expecting non-null pointer.");
27+
S->ProcessODRHash(ID, *this);
28+
}
2629
void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {}
2730
void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {}
2831
void ODRHash::AddTemplateName(TemplateName Name) {}
@@ -74,10 +77,18 @@ unsigned ODRHash::CalculateHash() {
7477
class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
7578
typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
7679
llvm::FoldingSetNodeID &ID;
80+
ODRHash &Hash;
7781

7882
public:
79-
ODRDeclVisitor(llvm::FoldingSetNodeID &ID)
80-
: ID(ID) {}
83+
ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
84+
: ID(ID), Hash(Hash) {}
85+
86+
void AddStmt(const Stmt *S) {
87+
Hash.AddBoolean(S);
88+
if (S) {
89+
Hash.AddStmt(S);
90+
}
91+
}
8192

8293
void Visit(const Decl *D) {
8394
ID.AddInteger(D->getKind());
@@ -88,6 +99,13 @@ class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
8899
ID.AddInteger(D->getAccess());
89100
Inherited::VisitAccessSpecDecl(D);
90101
}
102+
103+
void VisitStaticAssertDecl(const StaticAssertDecl *D) {
104+
AddStmt(D->getAssertExpr());
105+
AddStmt(D->getMessage());
106+
107+
Inherited::VisitStaticAssertDecl(D);
108+
}
91109
};
92110

93111
// Only allow a small portion of Decl's to be processed. Remove this once
@@ -100,6 +118,7 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
100118
default:
101119
return false;
102120
case Decl::AccessSpec:
121+
case Decl::StaticAssert:
103122
return true;
104123
}
105124
}
@@ -108,7 +127,7 @@ void ODRHash::AddSubDecl(const Decl *D) {
108127
assert(D && "Expecting non-null pointer.");
109128
AddDecl(D);
110129

111-
ODRDeclVisitor(ID).Visit(D);
130+
ODRDeclVisitor(ID, *this).Visit(D);
112131
}
113132

114133
void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {

0 commit comments

Comments
 (0)