Skip to content

Commit

Permalink
Torwards #4
Browse files Browse the repository at this point in the history
  • Loading branch information
stettberger committed Nov 29, 2017
1 parent 27eeb8d commit bd79653
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 27 deletions.
35 changes: 33 additions & 2 deletions clang-plugin/StmtDataCollectors.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,21 @@ DEF_ADD_DATA(AtomicType, {
DEF_ADD_DATA(Attr, {

std::string AttrString;
// Print all template arguments into ArgString
llvm::raw_string_ostream OS(AttrString);
S->printPretty(OS, Context.getLangOpts());
OS.flush();
std::cerr << " ATTR:" << AttrString << "\n";
addData(AttrString);
}
)
DEF_ADD_DATA(AttributedStmt, {

for (const Attr *A : S->getAttrs()) {
// We duplicate class Attr here to not rely on being integrated
// into a RecursiveASTVisitor.
std::string AttrString;
llvm::raw_string_ostream OS(AttrString);
A->printPretty(OS, Context.getLangOpts());
OS.flush();
addData(std::string(A->getSpelling()));
}
}
Expand Down Expand Up @@ -121,6 +125,11 @@ DEF_ADD_DATA(CharacterLiteral, {
DEF_ADD_DATA(ComplexType, {
}
)
DEF_ADD_DATA(CompoundStmt, {

addData(S->size());
}
)
DEF_ADD_DATA(ConstantArrayType, {

addData(S->getSize().getZExtValue());
Expand Down Expand Up @@ -155,6 +164,20 @@ DEF_ADD_DATA(DependentSizedArrayType, {
DEF_ADD_DATA(DependentSizedExtVectorType, {
}
)
DEF_ADD_DATA(EnumConstantDecl, {

/* Not every enum has a init expression. Therefore,
we extract the actual enum value from it. */
std::cout << "ASDASD" << S->getInitVal().getExtValue() << std::endl;
addData(S->getInitVal().getExtValue());
}
)
DEF_ADD_DATA(EnumDecl, {

addData(S->getNumPositiveBits());
addData(S->getNumNegativeBits());
}
)
DEF_ADD_DATA(Expr, {

addData(S->getType());
Expand Down Expand Up @@ -335,6 +358,14 @@ DEF_ADD_DATA(TypedefNameDecl, {
addData(S->getUnderlyingType());
}
)
DEF_ADD_DATA(UnaryExprOrTypeTraitExpr, {

addData(S->getKind());
if (S->isArgumentType()) {
addData(S->getArgumentType());
}
}
)
DEF_ADD_DATA(UnaryOperator, {

addData(S->getOpcode());
Expand Down
34 changes: 34 additions & 0 deletions clang-plugin/StmtDataCollectors.td
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ class TypeTraitExpr {
}];
}

class UnaryExprOrTypeTraitExpr {
code Code = [{
addData(S->getKind());
if (S->isArgumentType()) {
addData(S->getArgumentType());
}
}];
}


//--- Calls --------------------------------------------------------------//
class CallExpr {
code Code = [{
Expand Down Expand Up @@ -248,6 +258,13 @@ class AttributedStmt {
}];
}

class CompoundStmt {
code Code = [{
addData(S->size());
}];
}


//--- Attributes ---------------------------------------------------------//
class Attr {
code Code = [{
Expand Down Expand Up @@ -290,6 +307,23 @@ class TypeDecl {
}];
}

class EnumDecl {
code Code = [{
addData(S->getNumPositiveBits());
addData(S->getNumNegativeBits());
}];
}

class EnumConstantDecl {
code Code = [{
/* Not every enum has a init expression. Therefore,
we extract the actual enum value from it. */
std::cout << "ASDASD" << S->getInitVal().getExtValue() << std::endl;
addData(S->getInitVal().getExtValue());
}];
}


class TagDecl {
code Code = [{
addData(S->getTagKind());
Expand Down
62 changes: 61 additions & 1 deletion clang-plugin/clang-hash.cc
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,63 @@ struct ObjectCache {
}
};

class DefinitionUseVisitor
: public RecursiveASTVisitor<DefinitionUseVisitor> {
typedef RecursiveASTVisitor<DefinitionUseVisitor> Inherited;
public:

std::map<const Decl *, std::set<const Decl *>> DefUseSilo;
const Decl* CurrentDefinition;

bool TraverseDecl(Decl *D) {
bool record = false;
if (isa<VarDecl>(D) && static_cast<VarDecl*>(D)->hasGlobalStorage()) {
CurrentDefinition = D;
record = true;
}
if (isa<FunctionDecl>(D)) {
FunctionDecl *FD = static_cast<FunctionDecl*>(D);
std::cout << "FUNC " << std::string(FD->getName()) << std::endl;
CurrentDefinition = D;
record = true;
}

bool ret = Inherited::TraverseDecl(D);
if (record) {
CurrentDefinition = nullptr;
}
return ret;
}

bool VisitDeclRefExpr(const DeclRefExpr *Node) {
const ValueDecl * ValDecl = Node->getDecl();
if (!CurrentDefinition) return true;
if (!ValDecl) return true;

if (isa<VarDecl>(ValDecl)) {
const VarDecl *VD = static_cast<const VarDecl *>(ValDecl);
if (VD->hasGlobalStorage()) {
DefUseSilo[CurrentDefinition].insert(VD);
}
} else if (isa<FunctionDecl>(ValDecl)) {
const FunctionDecl *FD = static_cast<const FunctionDecl *>(ValDecl);
std::cout << " -> FUNC" << std::string(FD->getName()) << std::endl;
DefUseSilo[CurrentDefinition].insert(ValDecl);
}
return true;
}

bool VisitCallExpr(CallExpr *Node) {
if (!CurrentDefinition) return true;
if (FunctionDecl * FD = Node->getDirectCallee()) {
DefUseSilo[CurrentDefinition].insert(FD);
}
return true;
}

};


class HashTranslationUnitConsumer : public ASTConsumer {
public:
HashTranslationUnitConsumer(CompilerInstance &CI, raw_ostream *OS,
Expand All @@ -169,6 +226,9 @@ class HashTranslationUnitConsumer : public ASTConsumer {
TranslationUnitHashVisitor Visitor(Context);
Visitor.TraverseDecl(Context.getTranslationUnitDecl());

DefinitionUseVisitor DefUse;
DefUse.TraverseDecl(Context.getTranslationUnitDecl());

hashCommandLineArguments(Visitor);

const auto FinishHashing = std::chrono::high_resolution_clock::now();
Expand Down Expand Up @@ -274,7 +334,7 @@ class HashTranslationUnitConsumer : public ASTConsumer {

if (IsFunctionDefinition || IsNonExternVariableDeclaration) {
*Terminal << ", [";
for (const auto &SavedCallee : Visitor.DefUseSilo[cast<Decl>(D)]) {
for (const auto &SavedCallee : DefUse.DefUseSilo[cast<Decl>(D)]) {
// TODO: also dump records? could be forward-declarated?!
bool AppendFilename = false;
if (isa<FunctionDecl>(SavedCallee)) {
Expand Down
62 changes: 42 additions & 20 deletions clang-plugin/hash-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,6 @@ class TranslationUnitHashVisitor
/// TypeLocs.
bool shouldWalkTypesOfTypeLocs() const { return false; }



/* For some special nodes, override the traverse function, since we
need both pre- and post order traversal */
bool TraverseTranslationUnitDecl(TranslationUnitDecl *Unit);
Expand All @@ -262,7 +260,7 @@ class TranslationUnitHashVisitor
// std::cerr << "DECL: " << D << "\n";
/* For some declarations, we store the calculated hash value. */
bool CacheHash = false;
if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isGlobal())
if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDefined())
CacheHash = true;
if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasGlobalStorage())
CacheHash = true;
Expand All @@ -288,23 +286,6 @@ class TranslationUnitHashVisitor
return ret;
}

bool VisitCallExpr(CallExpr *Call) {
addData(TranslationUnitHashVisitorPrefix::CallExpr);
bool ret;
if (FunctionDecl* FD = Call->getDirectCallee()) {
// FIXME: This is kind of an ugly non-const hack
// We do a hack to avoid the hashing of the callees body.
// If we would do that, we would get into an endless
// recursion on recursive functions.
Stmt *Body = FD->getBody();
FD->setBody(nullptr);
ret = TraverseDecl(FD);
FD->setBody(Body);
} else if (Expr *E = Call->getCallee()) {
ret = TraverseStmt(E);
}
return ret;
}

#define DEF_TYPE_GOTO_DECL(CLASS, EXPR) \
bool Visit##CLASS(CLASS *T) { \
Expand All @@ -314,7 +295,48 @@ class TranslationUnitHashVisitor

DEF_TYPE_GOTO_DECL(TypedefType, T->getDecl());
DEF_TYPE_GOTO_DECL(RecordType, T->getDecl());
// The EnumType forwards to the declaration. The declaration does
// not hand back to the type.
DEF_TYPE_GOTO_DECL(EnumType, T->getDecl());
bool TraverseEnumDecl(EnumDecl *E) {
/* In the original RecursiveASTVisitor
> if (D->getTypeForDecl()) {
> TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
> }
=> NO, NO, NO, to avoid endless recursion
*/
return WalkUpFromEnumDecl(E);
}

bool VisitDeclRefExpr(DeclRefExpr *E) {
ValueDecl * ValDecl = E->getDecl();
// Function Declarations are handled in VisitCallExpr
if (!ValDecl) { return true; }
if (isa<VarDecl>(ValDecl)) {
/* We emulate TraverseDecl here for VarDecl, because we
* are not allowed to call TraverseDecl here, since the
* initial expression of a DeclRefExpr might reference a
* sourronding Declaration itself. For example:
*
* struct foo {int N;}
* struct foo a = { sizeof(a) };
*/
VarDecl * VD = static_cast<VarDecl *>(ValDecl);
VisitNamedDecl(VD);
TraverseType(VD->getType());
VisitVarDecl(VD);
} else if (isa<FunctionDecl>(ValDecl)) {
/* Hash Functions without their body */
FunctionDecl *FD = static_cast<FunctionDecl *>(ValDecl);
Stmt *Body = FD->getBody();
FD->setBody(nullptr);
TraverseDecl(FD);
FD->setBody(Body);
} else {
TraverseDecl(ValDecl);
}
return true;
}

#if 0
// C Declarations
Expand Down
3 changes: 1 addition & 2 deletions test/enums/unusedEnumConstant_typedeffed.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ e_type e = cc;
/*
* check-name: Adding unused enum constant to typedeffed enum
* obj-not-diff: yes
* assert-ast: A != B
* assert-obj: A == B
* assert-ast: A == B
*/
13 changes: 13 additions & 0 deletions test/functions/func_ptr_ref.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extern void foo();
extern void bar();


void f2() {
void (*barfoo)() = &foo; {{A}}
void (*barfoo)() = &bar; {{B}}
}

/*
* check-name: Function pointer references
* assert-obj: A != B
*/
7 changes: 7 additions & 0 deletions test/run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -534,19 +534,26 @@ def run_test_suite(tests):
if TAP is True:
to_console("%d..%d\n" %(1, len(running_tests)))

failed = []
for future in running_tests:
test_case = future.get()
if not test_case['passed']:
tests_failed += 1
if test_case['check-known-to-fail']:
tests_known_fail += 1
else:
failed.append(test_case['test_case'])


to_console("Out of %d tests, %d passed, %d failed (%d of them are known to fail).\n" \
% (len(running_tests),
len(running_tests) - tests_failed,
tests_failed,
tests_known_fail))
if failed:
to_console("Failed Testcases:\n")
for f in failed:
to_console(" - %s\n" % f)

return tests_failed <= tests_known_fail

Expand Down
5 changes: 3 additions & 2 deletions test/structs/unnamed_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ struct Named { int i; }; {{B}}
struct Named u; {{B}}

/*
* check-name: unnamed struct
* assert-ast: A == B
* check-name: Names of structs matter
* obj-not-diff: maybe
* assert-ast: A != B
*/


0 comments on commit bd79653

Please sign in to comment.