From ba6efd3419a93ccc13a0e07ad65aa6a524291bb7 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Tue, 5 Mar 2013 13:05:56 +0000 Subject: [PATCH] Documentation: use code highlighting git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176480 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersTutorial.rst | 61 +++++++++++++++++---------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst index 381c558705..6ebb499697 100644 --- a/docs/LibASTMatchersTutorial.rst +++ b/docs/LibASTMatchersTutorial.rst @@ -21,7 +21,7 @@ repositories, but we'll be accessing them through the git mirror. For further information, see the `getting started guide `_. -:: +.. code-block:: console mkdir ~/clang-llvm && cd ~/clang-llvm git clone http://llvm.org/git/llvm.git @@ -32,7 +32,7 @@ Next you need to obtain the CMake build system and Ninja build tool. You may already have CMake installed, but current binary versions of CMake aren't built with Ninja support. -:: +.. code-block:: console cd ~/clang-llvm git clone https://github.com/martine/ninja.git @@ -51,7 +51,7 @@ aren't built with Ninja support. Okay. Now we'll build Clang! -:: +.. code-block:: console cd ~/clang-llvm mkdir build && cd build @@ -69,7 +69,7 @@ in both the llvm and clang directories should fix any problems. Finally, we want to set Clang as its own compiler. -:: +.. code-block:: console cd ~/clang-llvm/build ccmake ../llvm @@ -94,7 +94,7 @@ First, we'll need to create a new directory for our tool and tell CMake that it exists. As this is not going to be a core clang tool, it will live in the ``tools/extra`` repository. -:: +.. code-block:: console cd ~/clang-llvm/llvm/tools/clang mkdir tools/extra/loop-convert @@ -123,7 +123,7 @@ something to compile! Put the following into why the different parts are needed can be found in the `LibTooling documentation `_. -:: +.. code-block:: c++ // Declares clang::SyntaxOnlyAction. #include "clang/Frontend/FrontendActions.h" @@ -153,7 +153,7 @@ documentation `_. And that's it! You can compile our new tool by running ninja from the ``build`` directory. -:: +.. code-block:: console cd ~/clang-llvm/build ninja @@ -161,7 +161,7 @@ And that's it! You can compile our new tool by running ninja from the You should now be able to run the syntax checker, which is located in ``~/clang-llvm/build/bin``, on any source file. Try it! -:: +.. code-block:: console cat "void main() {}" > test.cpp bin/loop-convert test.cpp -- @@ -186,7 +186,7 @@ For example, suppose you wanted to examine only binary operators. There is a matcher to do exactly that, conveniently named ``binaryOperator``. I'll give you one guess what this matcher does: -:: +.. code-block:: c++ binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0)))) @@ -207,7 +207,7 @@ All matcher that are nouns describe entities in the AST and can be bound, so that they can be referred to whenever a match is found. To do so, simply call the method ``bind`` on these matchers, e.g.: -:: +.. code-block:: c++ variable(hasType(isInteger())).bind("intvar") @@ -218,21 +218,21 @@ Okay, on to using matchers for real. Let's start by defining a matcher which will capture all ``for`` statements that define a new variable initialized to zero. Let's start with matching all ``for`` loops: -:: +.. code-block:: c++ forStmt() Next, we want to specify that a single variable is declared in the first portion of the loop, so we can extend the matcher to -:: +.. code-block:: c++ forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl())))) Finally, we can add the condition that the variable is initialized to zero. -:: +.. code-block:: c++ forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl( hasInitializer(integerLiteral(equals(0)))))))) @@ -247,7 +247,7 @@ zero besides the integer 0. The last step is giving the matcher a name and binding the ``ForStmt`` as we will want to do something with it: -:: +.. code-block:: c++ StatementMatcher LoopMatcher = forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl( @@ -260,7 +260,8 @@ from a ``ClangTool``. More code! Add the following to ``LoopConvert.cpp``: -:: +.. code-block:: c++ + #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -280,7 +281,7 @@ Add the following to ``LoopConvert.cpp``: And change ``main()`` to: -:: +.. code-block:: c++ int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv); @@ -298,7 +299,7 @@ Now, you should be able to recompile and run the code to discover for loops. Create a new file with a few examples, and test out our new handiwork: -:: +.. code-block:: console cd ~/clang-llvm/llvm/llvm_build/ ninja loop-convert @@ -336,7 +337,7 @@ would like to allow, and punting extra comparisons to the callback. In any case, we can start building this sub-matcher. We can require that the increment step be a unary increment like this: -:: +.. code-block:: c++ hasIncrement(unaryOperator(hasOperatorName("++"))) @@ -346,7 +347,7 @@ reference expressions") because they are expressions which refer to variable declarations. To find a ``unaryOperator`` that refers to a specific declaration, we can simply add a second condition to it: -:: +.. code-block:: c++ hasIncrement(unaryOperator( hasOperatorName("++"), @@ -355,7 +356,7 @@ specific declaration, we can simply add a second condition to it: Furthermore, we can restrict our matcher to only match if the incremented variable is an integer: -:: +.. code-block:: c++ hasIncrement(unaryOperator( hasOperatorName("++"), @@ -364,7 +365,7 @@ incremented variable is an integer: And the last step will be to attach an identifier to this variable, so that we can retrieve it in the callback: -:: +.. code-block:: c++ hasIncrement(unaryOperator( hasOperatorName("++"), @@ -383,14 +384,14 @@ without looking at the body of the loop! We are again restricted to approximating the result we want with matchers, filling in the details in the callback. So we start with: -:: +.. code-block:: c++ hasCondition(binaryOperator(hasOperatorName("<")) It makes sense to ensure that the left-hand side is a reference to a variable, and that the right-hand side has integer type. -:: +.. code-block:: c++ hasCondition(binaryOperator( hasOperatorName("<"), @@ -427,7 +428,7 @@ in the form of ``ignoringParenImpCasts``, which instructs the matcher to ignore implicit casts and parentheses before continuing to match. Adjusting the condition operator will restore the desired match. -:: +.. code-block:: c++ hasCondition(binaryOperator( hasOperatorName("<"), @@ -461,7 +462,7 @@ using the ``getNodeAs()`` member function. In ``LoopActions.cpp``: -:: +.. code-block:: c++ #include "clang/AST/ASTContext.h" @@ -479,7 +480,7 @@ Now that we have the three variables, represented by their respective declarations, let's make sure that they're all the same, using a helper function I call ``areSameVariable()``. -:: +.. code-block:: c++ if (!areSameVariable(IncVar, CondVar) || !areSameVariable(IncVar, InitVar)) return; @@ -489,7 +490,7 @@ function I call ``areSameVariable()``. If execution reaches the end of ``LoopPrinter::run()``, we know that the loop shell that looks like -:: +.. code-block:: c++ for (int i= 0; i < expr(); ++i) { ... } @@ -503,7 +504,7 @@ declaration. Since the "canonical" form of each declaration is unique by address, all we need to do is make sure neither ``ValueDecl`` (base class of ``VarDecl``) is ``NULL`` and compare the canonical Decls. -:: +.. code-block:: c++ static bool areSameVariable(const ValueDecl *First, const ValueDecl *Second) { return First && Second && @@ -514,9 +515,9 @@ It's not as trivial to test if two expressions are the same, though Clang has already done the hard work for us by providing a way to canonicalize expressions: -:: +.. code-block:: c++ - static bool areSameExpr(ASTContext* Context, const Expr *First, + static bool areSameExpr(ASTContext *Context, const Expr *First, const Expr *Second) { if (!First || !Second) return false; -- 2.40.0