~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 
3
// Use of this source code is governed by a BSD-style license that can be
 
4
// found in the LICENSE file.
 
5
//
 
6
 
 
7
#include "compiler/DetectRecursion.h"
 
8
 
 
9
DetectRecursion::FunctionNode::FunctionNode(const TString& fname)
 
10
    : name(fname),
 
11
      visit(PreVisit)
 
12
{
 
13
}
 
14
 
 
15
const TString& DetectRecursion::FunctionNode::getName() const
 
16
{
 
17
    return name;
 
18
}
 
19
 
 
20
void DetectRecursion::FunctionNode::addCallee(
 
21
    DetectRecursion::FunctionNode* callee)
 
22
{
 
23
    for (size_t i = 0; i < callees.size(); ++i) {
 
24
        if (callees[i] == callee)
 
25
            return;
 
26
    }
 
27
    callees.push_back(callee);
 
28
}
 
29
 
 
30
bool DetectRecursion::FunctionNode::detectRecursion()
 
31
{
 
32
    ASSERT(visit == PreVisit);
 
33
    visit = InVisit;
 
34
    for (size_t i = 0; i < callees.size(); ++i) {
 
35
        switch (callees[i]->visit) {
 
36
            case InVisit:
 
37
                // cycle detected, i.e., recursion detected.
 
38
                return true;
 
39
            case PostVisit:
 
40
                break;
 
41
            case PreVisit: {
 
42
                bool recursion = callees[i]->detectRecursion();
 
43
                if (recursion)
 
44
                    return true;
 
45
                break;
 
46
            }
 
47
            default:
 
48
                UNREACHABLE();
 
49
                break;
 
50
        }
 
51
    }
 
52
    visit = PostVisit;
 
53
    return false;
 
54
}
 
55
 
 
56
DetectRecursion::DetectRecursion()
 
57
    : currentFunction(NULL)
 
58
{
 
59
}
 
60
 
 
61
DetectRecursion::~DetectRecursion()
 
62
{
 
63
    for (size_t i = 0; i < functions.size(); ++i)
 
64
        delete functions[i];
 
65
}
 
66
 
 
67
bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node)
 
68
{
 
69
    switch (node->getOp())
 
70
    {
 
71
        case EOpPrototype:
 
72
            // Function declaration.
 
73
            // Don't add FunctionNode here because node->getName() is the
 
74
            // unmangled function name.
 
75
            break;
 
76
        case EOpFunction: {
 
77
            // Function definition.
 
78
            if (visit == PreVisit) {
 
79
                currentFunction = findFunctionByName(node->getName());
 
80
                if (currentFunction == NULL) {
 
81
                    currentFunction = new FunctionNode(node->getName());
 
82
                    functions.push_back(currentFunction);
 
83
                }
 
84
            }
 
85
            break;
 
86
        }
 
87
        case EOpFunctionCall: {
 
88
            // Function call.
 
89
            if (visit == PreVisit) {
 
90
                ASSERT(currentFunction != NULL);
 
91
                FunctionNode* func = findFunctionByName(node->getName());
 
92
                if (func == NULL) {
 
93
                    func = new FunctionNode(node->getName());
 
94
                    functions.push_back(func);
 
95
                }
 
96
                currentFunction->addCallee(func);
 
97
            }
 
98
            break;
 
99
        }
 
100
        default:
 
101
            break;
 
102
    }
 
103
    return true;
 
104
}
 
105
 
 
106
DetectRecursion::ErrorCode DetectRecursion::detectRecursion()
 
107
{
 
108
    FunctionNode* main = findFunctionByName("main(");
 
109
    if (main == NULL)
 
110
        return kErrorMissingMain;
 
111
    if (main->detectRecursion())
 
112
        return kErrorRecursion;
 
113
    return kErrorNone;
 
114
}
 
115
 
 
116
DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName(
 
117
    const TString& name)
 
118
{
 
119
    for (size_t i = 0; i < functions.size(); ++i) {
 
120
        if (functions[i]->getName() == name)
 
121
            return functions[i];
 
122
    }
 
123
    return NULL;
 
124
}
 
125