Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Christian Dietrich
clang-hash
Commits
dfbff6f4
Commit
dfbff6f4
authored
Mar 22, 2016
by
Christian Dietrich
Browse files
hashing: factor out hash algorithm
parent
703719f6
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
src/Hash.h
0 → 100644
View file @
dfbff6f4
#ifndef __CLANG_HASH_HASH
#define __CLANG_HASH_HASH
#include
"SHA1.h"
struct
Hash
:
protected
SHA1
{
typedef
SHA1
algorithm
;
struct
digest
{
enum
{
DIGEST_WORDS
=
algorithm
::
DIGEST_WORDS
};
uint32_t
value
[
algorithm
::
DIGEST_WORDS
];
bool
operator
==
(
const
digest
&
other
)
const
{
for
(
unsigned
i
=
0
;
i
<
DIGEST_WORDS
;
i
++
)
{
if
(
other
.
value
[
i
]
!=
value
[
i
])
return
false
;
}
return
true
;
}
bool
operator
!=
(
const
digest
&
other
)
const
{
return
!
(
*
this
==
other
);
}
std
::
string
getHexDigest
()
const
{
std
::
stringstream
ss
;
for
(
unsigned
i
=
0
;
i
<
DIGEST_WORDS
;
i
++
)
{
ss
<<
std
::
hex
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
8
)
<<
value
[
i
];
}
return
ss
.
str
();
}
};
Hash
&
processBlock
(
const
void
*
const
start
,
const
void
*
const
end
)
{
const
uint8_t
*
begin
=
static_cast
<
const
uint8_t
*>
(
start
);
const
uint8_t
*
finish
=
static_cast
<
const
uint8_t
*>
(
end
);
while
(
begin
!=
finish
)
{
processByte
(
*
begin
);
begin
++
;
}
return
*
this
;
}
Hash
&
processBytes
(
const
void
*
const
data
,
size_t
len
)
{
const
uint8_t
*
block
=
static_cast
<
const
uint8_t
*>
(
data
);
processBlock
(
block
,
block
+
len
);
return
*
this
;
}
// Digest Operators
const
digest
getDigest
()
const
{
Hash
copy
=
*
this
;
digest
ret
;
copy
.
finalize
(
ret
.
value
);
return
ret
;
}
// Stream Operators
Hash
&
operator
<<
(
uint8_t
x
)
{
processByte
(
x
);
return
*
this
;
}
Hash
&
operator
<<
(
uint16_t
x
)
{
*
this
<<
(
uint8_t
)
(
x
&
0xFF
)
<<
(
uint8_t
)(
x
>>
8
);
return
*
this
;
}
Hash
&
operator
<<
(
uint32_t
x
)
{
*
this
<<
(
uint16_t
)(
x
&
0xFFFF
)
<<
(
uint16_t
)
(
x
>>
16
);
return
*
this
;
}
Hash
&
operator
<<
(
uint64_t
x
)
{
*
this
<<
(
uint32_t
)(
x
&
0xFFFFFFFF
)
<<
(
uint32_t
)(
x
>>
32
);
return
*
this
;
}
Hash
&
operator
<<
(
int8_t
x
)
{
processByte
(
x
);
return
*
this
;
}
Hash
&
operator
<<
(
int16_t
x
)
{
*
this
<<
(
int8_t
)
(
x
&
0xFF
)
<<
(
int8_t
)(
x
>>
8
);
return
*
this
;
}
Hash
&
operator
<<
(
int32_t
x
)
{
*
this
<<
(
int16_t
)(
x
&
0xFFFF
)
<<
(
int16_t
)
(
x
>>
16
);
return
*
this
;
}
Hash
&
operator
<<
(
int64_t
x
)
{
*
this
<<
(
int32_t
)(
x
&
0xFFFFFFFF
)
<<
(
int32_t
)(
x
>>
32
);
return
*
this
;
}
Hash
&
operator
<<
(
const
digest
&
x
)
{
return
processBytes
(
x
.
value
,
sizeof
(
x
.
value
));
}
Hash
&
operator
<<
(
const
Hash
&
other
)
{
digest
digest
=
other
.
getDigest
();
*
this
<<
digest
;
return
*
this
;
}
Hash
&
operator
<<
(
const
std
::
string
&
x
)
{
processBytes
(
x
.
c_str
(),
x
.
length
());
return
*
this
;
}
};
#endif
src/SHA1.h
View file @
dfbff6f4
// #define DEBUG
/*
*
* TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based
...
...
@@ -33,298 +31,130 @@
#include
<iostream>
namespace
sha1
{
struct
digest
{
enum
{
ITEMS
=
5
};
typedef
uint32_t
digest32_t
[
5
];
digest32_t
value
;
bool
operator
==
(
const
digest
&
other
)
const
{
for
(
unsigned
i
=
0
;
i
<
ITEMS
;
i
++
)
{
if
(
other
.
value
[
i
]
!=
value
[
i
])
return
false
;
}
return
true
;
}
bool
operator
!=
(
const
digest
&
other
)
const
{
return
!
(
*
this
==
other
);
}
std
::
string
getHexDigest
()
const
{
std
::
stringstream
ss
;
for
(
unsigned
i
=
0
;
i
<
ITEMS
;
i
++
)
{
ss
<<
std
::
hex
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
8
)
<<
value
[
i
];
}
return
ss
.
str
();
}
class
SHA1
{
public:
enum
{
DIGEST_WORDS
=
5
,
BLOCK_LENGTH
=
64
};
class
SHA1
{
public:
typedef
uint32_t
digest32_t
[
5
];
typedef
uint8_t
digest8_t
[
20
];
inline
static
uint32_t
LeftRotate
(
uint32_t
value
,
size_t
count
)
{
return
(
value
<<
count
)
^
(
value
>>
(
32
-
count
));
}
SHA1
(){
reset
();
}
virtual
~
SHA1
()
{}
SHA1
(
const
SHA1
&
s
)
{
*
this
=
s
;
}
const
SHA1
&
operator
=
(
const
SHA1
&
s
)
{
memcpy
(
m_digest
,
s
.
m_digest
,
5
*
sizeof
(
uint32_t
));
memcpy
(
m_block
,
s
.
m_block
,
64
);
m_blockByteIndex
=
s
.
m_blockByteIndex
;
m_byteCount
=
s
.
m_byteCount
;
return
*
this
;
}
SHA1
&
reset
()
{
m_digest
[
0
]
=
0x67452301
;
m_digest
[
1
]
=
0xEFCDAB89
;
m_digest
[
2
]
=
0x98BADCFE
;
m_digest
[
3
]
=
0x10325476
;
m_digest
[
4
]
=
0xC3D2E1F0
;
m_blockByteIndex
=
0
;
m_byteCount
=
0
;
return
*
this
;
}
SHA1
&
processByte
(
uint8_t
octet
)
{
this
->
m_block
[
this
->
m_blockByteIndex
++
]
=
octet
;
++
this
->
m_byteCount
;
if
(
m_blockByteIndex
==
64
)
{
this
->
m_blockByteIndex
=
0
;
processBlock
();
SHA1
()
{
reset
();
}
virtual
~
SHA1
()
{}
SHA1
(
const
SHA1
&
s
)
{
*
this
=
s
;
}
const
SHA1
&
operator
=
(
const
SHA1
&
s
)
{
memcpy
(
m_digest
,
s
.
m_digest
,
DIGEST_WORDS
*
sizeof
(
uint32_t
));
memcpy
(
m_block
,
s
.
m_block
,
BLOCK_LENGTH
);
m_blockByteIndex
=
s
.
m_blockByteIndex
;
m_byteCount
=
s
.
m_byteCount
;
return
*
this
;
}
SHA1
&
reset
()
{
m_digest
[
0
]
=
0x67452301
;
m_digest
[
1
]
=
0xEFCDAB89
;
m_digest
[
2
]
=
0x98BADCFE
;
m_digest
[
3
]
=
0x10325476
;
m_digest
[
4
]
=
0xC3D2E1F0
;
m_blockByteIndex
=
0
;
m_byteCount
=
0
;
return
*
this
;
}
SHA1
&
processByte
(
uint8_t
octet
)
{
this
->
m_block
[
this
->
m_blockByteIndex
++
]
=
octet
;
++
this
->
m_byteCount
;
if
(
m_blockByteIndex
==
BLOCK_LENGTH
)
{
this
->
m_blockByteIndex
=
0
;
processBlock
();
}
return
*
this
;
}
void
finalize
(
uint32_t
*
digest
)
{
size_t
bitCount
=
m_byteCount
*
8
;
processByte
(
0x80
);
if
(
m_blockByteIndex
>
56
)
{
while
(
m_blockByteIndex
!=
0
)
{
processByte
(
0
);
}
return
*
this
;
}
SHA1
&
processBlock
(
const
void
*
const
start
,
const
void
*
const
end
)
{
const
uint8_t
*
begin
=
static_cast
<
const
uint8_t
*>
(
start
);
const
uint8_t
*
finish
=
static_cast
<
const
uint8_t
*>
(
end
);
while
(
begin
!=
finish
)
{
processByte
(
*
begin
);
begin
++
;
while
(
m_blockByteIndex
<
56
)
{
processByte
(
0
);
}
return
*
this
;
}
SHA1
&
processBytes
(
const
void
*
const
data
,
size_t
len
)
{
const
uint8_t
*
block
=
static_cast
<
const
uint8_t
*>
(
data
);
processBlock
(
block
,
block
+
len
);
return
*
this
;
}
// Stream Operators
SHA1
&
operator
<<
(
uint8_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
processByte
(
x
);
return
*
this
;
}
SHA1
&
operator
<<
(
uint16_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
uint8_t
)
(
x
&
0xFF
)
<<
(
uint8_t
)(
x
>>
8
);
return
*
this
;
}
SHA1
&
operator
<<
(
uint32_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
uint16_t
)(
x
&
0xFFFF
)
<<
(
uint16_t
)
(
x
>>
16
);
return
*
this
;
}
SHA1
&
operator
<<
(
uint64_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
uint32_t
)(
x
&
0xFFFFFFFF
)
<<
(
uint32_t
)(
x
>>
32
);
return
*
this
;
}
SHA1
&
operator
<<
(
int8_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
processByte
(
x
);
return
*
this
;
}
SHA1
&
operator
<<
(
int16_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
int8_t
)
(
x
&
0xFF
)
<<
(
int8_t
)(
x
>>
8
);
return
*
this
;
}
SHA1
&
operator
<<
(
int32_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
int16_t
)(
x
&
0xFFFF
)
<<
(
int16_t
)
(
x
>>
16
);
return
*
this
;
}
SHA1
&
operator
<<
(
int64_t
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
*
this
<<
(
int32_t
)(
x
&
0xFFFFFFFF
)
<<
(
int32_t
)(
x
>>
32
);
return
*
this
;
}
SHA1
&
operator
<<
(
const
sha1
::
digest
&
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
.
getHexDigest
()
<<
std
::
endl
;
#else
x
.
getHexDigest
();
#endif
return
processBytes
(
&
x
,
sizeof
(
sha1
::
digest
));
}
SHA1
&
operator
<<
(
const
SHA1
&
x
)
{
SHA1
copy
=
x
;
digest
digest
;
copy
.
getDigest
(
digest
.
value
);
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
digest
.
getHexDigest
()
<<
std
::
endl
;
#else
digest
.
getHexDigest
();
#endif
*
this
<<
digest
;
return
*
this
;
}
SHA1
&
operator
<<
(
const
std
::
string
&
x
)
{
#ifdef DEBUG
/*DEBUG:*/
std
::
cerr
<<
"Hash<<"
<<
x
<<
std
::
endl
;
#endif
processBytes
(
x
.
c_str
(),
x
.
length
());
return
*
this
;
}
const
uint32_t
*
getDigest
(
digest32_t
digest
)
const
{
SHA1
copy
(
*
this
);
size_t
bitCount
=
copy
.
m_byteCount
*
8
;
copy
.
processByte
(
0x80
);
if
(
copy
.
m_blockByteIndex
>
56
)
{
while
(
copy
.
m_blockByteIndex
!=
0
)
{
copy
.
processByte
(
0
);
}
while
(
copy
.
m_blockByteIndex
<
56
)
{
copy
.
processByte
(
0
);
}
}
else
{
while
(
copy
.
m_blockByteIndex
<
56
)
{
copy
.
processByte
(
0
);
}
}
else
{
while
(
m_blockByteIndex
<
56
)
{
processByte
(
0
);
}
copy
.
processByte
(
0
);
copy
.
processByte
(
0
);
copy
.
processByte
(
0
);
copy
.
processByte
(
0
);
copy
.
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
24
)
&
0xFF
));
copy
.
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
16
)
&
0xFF
));
copy
.
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
8
)
&
0xFF
));
copy
.
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
)
&
0xFF
));
memcpy
(
digest
,
copy
.
m_digest
,
5
*
sizeof
(
uint32_t
));
return
digest
;
}
const
uint8_t
*
getDigestBytes
(
digest8_t
digest
)
{
digest32_t
d32
;
getDigest
(
d32
);
size_t
di
=
0
;
digest
[
di
++
]
=
((
d32
[
0
]
>>
24
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
0
]
>>
16
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
0
]
>>
8
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
0
])
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
1
]
>>
24
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
1
]
>>
16
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
1
]
>>
8
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
1
])
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
2
]
>>
24
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
2
]
>>
16
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
2
]
>>
8
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
2
])
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
3
]
>>
24
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
3
]
>>
16
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
3
]
>>
8
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
3
])
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
4
]
>>
24
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
4
]
>>
16
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
4
]
>>
8
)
&
0xFF
);
digest
[
di
++
]
=
((
d32
[
4
])
&
0xFF
);
return
digest
;
}
const
std
::
string
getHexDigest
()
{
digest
digest
;
getDigest
(
digest
.
value
);
return
digest
.
getHexDigest
();
}
protected:
void
processBlock
()
{
uint32_t
w
[
80
];
for
(
size_t
i
=
0
;
i
<
16
;
i
++
)
{
w
[
i
]
=
(
m_block
[
i
*
4
+
0
]
<<
24
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
1
]
<<
16
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
2
]
<<
8
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
3
]);
}
for
(
size_t
i
=
16
;
i
<
80
;
i
++
)
{
w
[
i
]
=
LeftRotate
((
w
[
i
-
3
]
^
w
[
i
-
8
]
^
w
[
i
-
14
]
^
w
[
i
-
16
]),
1
);
}
uint32_t
a
=
m_digest
[
0
];
uint32_t
b
=
m_digest
[
1
];
uint32_t
c
=
m_digest
[
2
];
uint32_t
d
=
m_digest
[
3
];
uint32_t
e
=
m_digest
[
4
];
for
(
std
::
size_t
i
=
0
;
i
<
80
;
++
i
)
{
uint32_t
f
=
0
;
uint32_t
k
=
0
;
if
(
i
<
20
)
{
f
=
(
b
&
c
)
|
(
~
b
&
d
);
k
=
0x5A827999
;
}
else
if
(
i
<
40
)
{
f
=
b
^
c
^
d
;
k
=
0x6ED9EBA1
;
}
else
if
(
i
<
60
)
{
f
=
(
b
&
c
)
|
(
b
&
d
)
|
(
c
&
d
);
k
=
0x8F1BBCDC
;
}
else
{
f
=
b
^
c
^
d
;
k
=
0xCA62C1D6
;
}
uint32_t
temp
=
LeftRotate
(
a
,
5
)
+
f
+
e
+
k
+
w
[
i
];
e
=
d
;
d
=
c
;
c
=
LeftRotate
(
b
,
30
);
b
=
a
;
a
=
temp
;
processByte
(
0
);
processByte
(
0
);
processByte
(
0
);
processByte
(
0
);
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
24
)
&
0xFF
));
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
16
)
&
0xFF
));
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
>>
8
)
&
0xFF
));
processByte
(
static_cast
<
unsigned
char
>
((
bitCount
)
&
0xFF
));
memcpy
(
digest
,
m_digest
,
sizeof
(
m_digest
));
}
private:
inline
static
uint32_t
LeftRotate
(
uint32_t
value
,
size_t
count
)
{
return
(
value
<<
count
)
^
(
value
>>
(
32
-
count
));
}
void
processBlock
()
{
uint32_t
w
[
80
];
for
(
size_t
i
=
0
;
i
<
16
;
i
++
)
{
w
[
i
]
=
(
m_block
[
i
*
4
+
0
]
<<
24
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
1
]
<<
16
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
2
]
<<
8
);
w
[
i
]
|=
(
m_block
[
i
*
4
+
3
]);
}
for
(
size_t
i
=
16
;
i
<
80
;
i
++
)
{
w
[
i
]
=
LeftRotate
((
w
[
i
-
3
]
^
w
[
i
-
8
]
^
w
[
i
-
14
]
^
w
[
i
-
16
]),
1
);
}
uint32_t
a
=
m_digest
[
0
];
uint32_t
b
=
m_digest
[
1
];
uint32_t
c
=
m_digest
[
2
];
uint32_t
d
=
m_digest
[
3
];
uint32_t
e
=
m_digest
[
4
];
for
(
std
::
size_t
i
=
0
;
i
<
80
;
++
i
)
{
uint32_t
f
=
0
;
uint32_t
k
=
0
;
if
(
i
<
20
)
{
f
=
(
b
&
c
)
|
(
~
b
&
d
);
k
=
0x5A827999
;
}
else
if
(
i
<
40
)
{
f
=
b
^
c
^
d
;
k
=
0x6ED9EBA1
;
}
else
if
(
i
<
60
)
{
f
=
(
b
&
c
)
|
(
b
&
d
)
|
(
c
&
d
);
k
=
0x8F1BBCDC
;
}
else
{
f
=
b
^
c
^
d
;
k
=
0xCA62C1D6
;
}
m_digest
[
0
]
+=
a
;
m_digest
[
1
]
+=
b
;
m_digest
[
2
]
+=
c
;
m_digest
[
3
]
+=
d
;
m_digest
[
4
]
+=
e
;
}
private:
digest32_t
m_digest
;
uint8_t
m_block
[
64
];
size_t
m_blockByteIndex
;
size_t
m_byteCount
;
};
}
uint32_t
temp
=
LeftRotate
(
a
,
5
)
+
f
+
e
+
k
+
w
[
i
];
e
=
d
;
d
=
c
;
c
=
LeftRotate
(
b
,
30
);
b
=
a
;
a
=
temp
;
}
m_digest
[
0
]
+=
a
;
m_digest
[
1
]
+=
b
;
m_digest
[
2
]
+=
c
;
m_digest
[
3
]
+=
d
;
m_digest
[
4
]
+=
e
;
}
uint32_t
m_digest
[
DIGEST_WORDS
];
uint8_t
m_block
[
BLOCK_LENGTH
];
size_t
m_blockByteIndex
;
size_t
m_byteCount
;
};
#endif
src/hash-visitor.cc
View file @
dfbff6f4
This diff is collapsed.
Click to expand it.
src/hash-visitor.h
View file @
dfbff6f4
...
...
@@ -12,7 +12,7 @@
#include
<tuple>
#include
"
SHA1
.h"
#include
"
Hash
.h"
using
namespace
clang
;
...
...
@@ -25,10 +25,10 @@ class TranslationUnitHashVisitor
typedef
ConstStmtVisitor
<
TranslationUnitHashVisitor
,
bool
>
mt_stmtvisitor
;
typedef
TypeVisitor
<
TranslationUnitHashVisitor
,
bool
>
mt_typevisitor
;
sh
a1
::
SHA1
toplevel_hash
;
Ha
sh
toplevel_hash
;
// In this storage we save hashes for various memory objects
std
::
map
<
const
void
*
,
sh
a1
::
digest
>
silo
;
std
::
map
<
const
void
*
,
Ha
sh
::
digest
>
silo
;
// /// Pending[i] is an action to hash an entity at level i.
bool
FirstChild
;
...
...
@@ -59,7 +59,7 @@ class TranslationUnitHashVisitor
}
}
llvm
::
SmallVector
<
sh
a1
::
SHA1
,
32
>
HashStack
;
llvm
::
SmallVector
<
Ha
sh
,
32
>
HashStack
;
public:
// Utilities
bool
hasNodes
(
const
DeclContext
*
DC
);
...
...
@@ -79,7 +79,7 @@ public:
/// Not interesting
bool
VisitTypedefDecl
(
const
TypedefDecl
*
)
{
return
true
;
};
/* Wird erst in Aufrufen geprueft */
/* Wird erst in Aufrufen geprueft */
bool
VisitRecordDecl
(
const
RecordDecl
*
D
){
return
true
;
};
bool
VisitFieldDecl
(
const
FieldDecl
*
D
){
return
true
;
};
...
...
@@ -140,7 +140,7 @@ public:
bool
VisitDesignatedInitExpr
(
const
DesignatedInitExpr
*
Node
);
bool
VisitStmtExpr
(
const
StmtExpr
*
Node
);
bool
VisitVAArgExpr
(
const
VAArgExpr
*
Node
);
//TODO: evtl. ImplicitValueInitExpr, GenericSelectionExpr, ArraySubscriptExpr
//TODO: evtl. OpaqueValueExpr, ExtVectorElementExpr (Beschreibung klingt nach C++)
...
...
@@ -201,7 +201,7 @@ public:
protected:
bool
doNotHashThis
=
false
;
// Flag used to ignore Nodes such as extern Decls
std
::
map
<
const
void
*
,
const
void
*>
seen_types
;
bool
haveSeen
(
const
void
*
key
,
const
void
*
type
){
if
(
seen_types
.
find
(
key
)
!=
seen_types
.
end
()){
return
true
;
...
...
@@ -277,50 +277,43 @@ protected:
}
// Hash Silo
void
StoreHash
(
const
void
*
obj
,
sh
a1
::
digest
digest
)
{
void
StoreHash
(
const
void
*
obj
,
Ha
sh
::
digest
digest
)
{
silo
[
obj
]
=
digest
;
}
const
sh
a1
::
digest
*
GetHash
(
const
void
*
obj
)
{
const
Ha
sh
::
digest
*
GetHash
(
const
void
*
obj
)
{
if
(
silo
.
find
(
obj
)
!=
silo
.
end
())
{
return
&
silo
[
obj
];
}
return
nullptr
;
}
sh
a1
::
SHA1
*
PushHash
()
{
HashStack
.
push_back
(
sh
a1
::
SHA1
());