Skip to content

Commit

Permalink
[ODRHash] static_cast and Stmt hashing.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Weverything committed Feb 22, 2017
1 parent fccbda9 commit 639d7b6
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 91 deletions.
10 changes: 10 additions & 0 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace clang {
class Expr;
class IdentifierInfo;
class LabelDecl;
class ODRHash;
class ParmVarDecl;
class PrinterHelper;
struct PrintingPolicy;
Expand Down Expand Up @@ -436,6 +437,15 @@ class alignas(void *) Stmt {
/// written in the source.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
bool Canonical) const;

/// \brief Calculate a unique representation for a statement that is
/// stable across compiler invocations.
///
/// \param ID profile information will be stored in ID.
///
/// \param Hash an ODRHash object which will be called where pointers would
/// have been used in the Profile function.
void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
};

/// DeclStmt - Adaptor class for mixing declarations with statements and
Expand Down
18 changes: 16 additions & 2 deletions clang/include/clang/Basic/DiagnosticSerializationKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,24 @@ def err_module_odr_violation_mismatch_decl : Error<
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier}3">;
"protected access specifier|static assert}3">;
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
"%select{end of class|public access specifier|private access specifier|"
"protected access specifier}1">;
"protected access specifier|static assert}1">;

def err_module_odr_violation_mismatch_decl_diff : Error<
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
"%select{"
"static assert with condition|"
"static assert with message|"
"static assert with %select{|no }4message}3">;

def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"%select{"
"static assert with different condition|"
"static assert with different message|"
"static assert with %select{|no }2message}1">;

def warn_module_uses_date_time : Warning<
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
Expand Down
27 changes: 23 additions & 4 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@

using namespace clang;

void ODRHash::AddStmt(const Stmt *S) {}
void ODRHash::AddStmt(const Stmt *S) {
assert(S && "Expecting non-null pointer.");
S->ProcessODRHash(ID, *this);
}
void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {}
void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {}
void ODRHash::AddTemplateName(TemplateName Name) {}
Expand Down Expand Up @@ -74,10 +77,18 @@ unsigned ODRHash::CalculateHash() {
class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
typedef ConstDeclVisitor<ODRDeclVisitor> Inherited;
llvm::FoldingSetNodeID &ID;
ODRHash &Hash;

public:
ODRDeclVisitor(llvm::FoldingSetNodeID &ID)
: ID(ID) {}
ODRDeclVisitor(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
: ID(ID), Hash(Hash) {}

void AddStmt(const Stmt *S) {
Hash.AddBoolean(S);
if (S) {
Hash.AddStmt(S);
}
}

void Visit(const Decl *D) {
ID.AddInteger(D->getKind());
Expand All @@ -88,6 +99,13 @@ class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
ID.AddInteger(D->getAccess());
Inherited::VisitAccessSpecDecl(D);
}

void VisitStaticAssertDecl(const StaticAssertDecl *D) {
AddStmt(D->getAssertExpr());
AddStmt(D->getMessage());

Inherited::VisitStaticAssertDecl(D);
}
};

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

ODRDeclVisitor(ID).Visit(D);
ODRDeclVisitor(ID, *this).Visit(D);
}

void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
Expand Down
Loading

0 comments on commit 639d7b6

Please sign in to comment.