ollydbg: if you plan to integrate clang, please, don't do it with creating another process and communicating with some IPC mechanism.
The proper way is to link directly to clangs libs. It will save you many problems.
thanks for the hint.
currently, I'm checking Clang's features (command line mode) listed in
Examples of using Clang section of http://clang.llvm.org/get_started.html
Tested by this package
http://llvm.org/releases/2.8/llvm-gcc4.2-2.8-x86-mingw32.tar.bz2
It seems I can't get the result from
$ clang -cc1 ~/t.c -ast-print
I have the error like:
F:\cb\test_code\test_clang>llvm-c++ main.cpp
llvm-c++: CreateProcess: No such file or directory
F:\cb\test_code\test_clang>llvm-c++ main.cpp -E
# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.cpp"
int main()
{
}
F:\cb\test_code\test_clang>llvm-c++ main.cpp -cc1 -ast-print
llvm-c++: unrecognized option '-cc1'
cc1plus.exe: error: unrecognized command line option "-ast-print"
F:\cb\test_code\test_clang>llvm-c++ -cc1 main.cpp -ast-print
llvm-c++: unrecognized option '-cc1'
cc1plus.exe: error: unrecognized command line option "-ast-print"
So, I have to firstly figure it out. :D
Probably you should post on their mailing list :)
I asked there, but no replies. seems the devs are not interested in windows build.
my friend xunxun has build on for me (under mingw 4.5.1), he just some customized configure.
./configure --prefix=/llvm --enable-optimized --enable-targets=host
then manually change the file
Makefile.config
-O2
to
-pipe -O2 -DPTW32_STATIC_LIB
But the built clang seems can't work correctly, it even crashed in a quite dummy test code
a.c
then I run:
then clang crashed....Too bad. :(
I don't want to test any more until it becomes stable and useful enough. :shock:
You will most likely find a broken clang++.exe in the bin subfolder, this is just a symlink to clang.exe on linux, but neither 7z, nor windows can handle (linux-)symlinks.
To use clang++.exe, you can just copy clang.exe to clang++.exe .
Not that it matters, but as a quick FYI, you can use tar to de-reference symlinks:
-h, --dereference follow symlinks; archive and dump the files they point to
--hard-dereference follow hard links; archive and dump the files they refer to
I use these options when preparing MinGW packages that I've compiled under Cygwin.
Here is my detailed test for codecompletion in clang (Windows)
prerequisite:
You need to download the package supplied by jens: clang_win32 (http://apt.jenslody.de/downloads/clang_win32.7z)
Then add the path of clang.exe in your PATH.
test
create a file like:
E:\clang_win32\main.cpp
the file contains some code snippet like:
class AAA
{
public:
int aaa;
int bbb;
};
int myfunction()
{
AAA a;
a.
return 0;
}
Now, you can see, the codecompletion list should generated after "a." .
You just run the command: pay attention to the :13:5, this this the line and column number of the caret after "a."
clang -w -fsyntax-only -Xclang -code-completion-at=E:\clang_win32\main.cpp:13:5 E:\clang_win32\main.cpp
Then here is the wonder result:
E:\clang_win32>clang -w -fsyntax-only -Xclang -code-completion-at=E:\clang_win32
\main.cpp:13:5 E:\clang_win32\main.cpp
COMPLETION: AAA : AAA::
COMPLETION: aaa : [#int#]aaa
COMPLETION: bbb : [#int#]bbb
COMPLETION: operator= : [#AAA &#]operator=(<#const AAA &#>)
COMPLETION: ~AAA : [#void#]~AAA()
:D
then main reference is eranif's codelite source (thanks eranif):
http://codelite.svn.sourceforge.net/viewvc/codelite/trunk/LiteEditor/clang_code_completion.cpp?revision=4207&view=markup
about the pch. suppose I have two files: testcpp.h and main.cpp
testcpp.h
class BBB
{
public:
int f1();
int f2();
int f3();
};
main.cpp
#include "testcpp.h"
int myfunction()
{
BBB a;
a.
return 0;
}
Now,
first I need to generate the pch file using command:
E:\clang_win32>clang++ -cc1 -x c++-header testcpp.h -emit-pch -o testcpp.h.pch
Then, do the code completion command.
E:\clang_win32>clang++ -cc1 -w -fsyntax-only -include-pch testcpp.h.pch -code-co
mpletion-at=E:\clang_win32\main.cpp:8:5 E:\clang_win32\main.cpp
In file included from E:\clang_win32\main.cpp:3:
E:\clang_win32\testcpp.h:3:7: error: redefinition of 'BBB'
class BBB
^
E:\clang_win32\testcpp.h:3:7: note: previous definition is here
class BBB
^
1 error generated.
COMPLETION: BBB : BBB::
COMPLETION: f1 : [#int#]f1()
COMPLETION: f2 : [#int#]f2()
COMPLETION: f3 : [#int#]f3()
Strange that there is an error about "redefinition".
So, I just comment the #include line like, so the modified main.cpp
//#include "testcpp.h"
int myfunction()
{
BBB a;
a.
return 0;
}
Now, everything works fine.
E:\clang_win32>clang++ -cc1 -w -fsyntax-only -include-pch testcpp.h.pch -code-co
mpletion-at=E:\clang_win32\main.cpp:8:5 E:\clang_win32\main.cpp
COMPLETION: BBB : BBB::
COMPLETION: f1 : [#int#]f1()
COMPLETION: f2 : [#int#]f2()
COMPLETION: f3 : [#int#]f3()
Any comments about how to solve the redefinition issue???
thanks.
Sorry guys, I have made a mistake in my previous post, now add the include guard solved all the problem of redefinition.
modified testcpp.h
#ifndef TESTCPP_H
#define TESTCPP_H
class BBB
{
public:
int f1();
int f2();
int f3();
};
#endif
@eranif
it seems the clang++ and PCH works fine. You can try it to see if it works much faster.
I have just briefly read the Clang's source code about
lexer
parser
And I found that it is definitely all hand-written code (Note our CC's parser is also hand-written), but it is quite modular.
It's lexer's source code was located in
llvm\tools\clang\include\clang\Lex
llvm\tools\clang\lib\Lex
parser's source is located in
llvm\tools\clang\include\clang\Parse
llvm\tools\clang\lib\Parse
for example:
In the parser.cpp
/// \brief Determine whether the current token, if it occurs after a
/// declarator, continues a declaration or declaration list.
bool Parser::isDeclarationAfterDeclarator() const {
return Tok.is(tok::equal) || // int X()= -> not a function def
Tok.is(tok::comma) || // int X(), -> not a function def
Tok.is(tok::semi) || // int X(); -> not a function def
Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
(getLang().CPlusPlus &&
Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
}
there are even skip functions in lexer ( we have skip XXX functions in CC either) :D
/// SkipEscapedNewLines - If P points to an escaped newline (or a series of
/// them), skip over them and return the first non-escaped-newline found,
/// otherwise return P.
const char *Lexer::SkipEscapedNewLines(const char *P) {
while (1) {
const char *AfterEscape;
if (*P == '\\') {
AfterEscape = P+1;
} else if (*P == '?') {
// If not a trigraph for escape, bail out.
if (P[1] != '?' || P[2] != '/')
return P;
AfterEscape = P+3;
} else {
return P;
}
unsigned NewLineSize = Lexer::getEscapedNewLineSize(AfterEscape);
if (NewLineSize == 0) return P;
P = AfterEscape+NewLineSize;
}
}
BTW: seems all the tokens were handled as char type.(one byte). Hope our CC can use char type instead. because wxChar seems waste a lot of space. (Unicode wxChar seems equal two bytes, not sure how long in X86-64 system).
Another similaity is that Clang do the pre-processors and lexer in the same stage, this is the conceptional same as in CC's Tokenizer.
Information for those who would like to use Clang for codecompletion and code indexer.
There are two ways:
1, using the clang from the command line. this is currently done in vim, Emacs, codelite by calling the clang.exe from command line.
2, directly link to the libraries supplied by libclang. this is done only in Apples Xcode, but it is suggest the better way. You can take the file:
\llvm\tools\clang\tools\c-index-test\c-index-test.c
, this file contains all the information you need.
BTW: to build a release version of clang, the options can be found here:
How To Release LLVM To The Public (http://llvm.org/docs/HowToReleaseLLVM.html)
Building the Release
The build of llvm, llvm-gcc, and clang must be free of errors and warnings in both debug, release+asserts, and release builds. If all builds are clean, then the release passes build qualification.
1. debug: ENABLE_OPTIMIZED=0
2. release+asserts: ENABLE_OPTIMIZED=1
3. release: ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1
Edit:
The common feature like "find the definition of a function" or "find the reference" can be found there:
The Index Library (http://clang.llvm.org/docs/libIndex.html)
see below:
index-test tool
Usage
A command-line tool that exercises the libIndex API, useful for testing its features. As input it accepts multiple AST files (representing multiple translation units) and a few options:
-point-at [file:line:column]
Resolves a [file:line:column] triplet into a ASTLocation from the first AST file. If no other option is specified, it prints the ASTLocation. It also prints a declaration's associated doxygen comment, if one is available.
-print-refs
Prints the ASTLocations that reference the declaration that was resolved out of the [file:line:column] triplet
-print-defs
Prints the ASTLocations that define the resolved declaration
-print-decls
Prints the ASTLocations that declare the resolved declaration
Examples
Here's an example of using index-test:
We have 3 files,
foo.h:
extern int global_var;
void foo_func(int param1);
void bar_func(void);
t1.c:
#include "foo.h"
void foo_func(int param1) {
int local_var = global_var;
for (int for_var = 100; for_var < 500; ++for_var) {
local_var = param1 + for_var;
}
bar_func();
}
t2.c:
#include "foo.h"
int global_var = 10;
void bar_func(void) {
global_var += 100;
foo_func(global_var);
}
You first get AST files out of t1.c and t2.c:
$ clang -emit-ast t1.c -o t1.ast
$ clang -emit-ast t2.c -o t2.ast
Find the ASTLocation under this position of t1.c:
[...]
void foo_func(int param1) {
int local_var = global_var;
^
[...]
$ index-test t1.ast -point-at t1.c:4:23
> [Decl: Var local_var | Stmt: DeclRefExpr global_var] <t1.c:4:19, t1.c:4:19>
Find the declaration:
$ index-test t1.ast -point-at t1.c:4:23 -print-decls
> [Decl: Var global_var] <foo.h:1:12, foo.h:1:12>
Find the references:
$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-refs
> [Decl: Var local_var | Stmt: DeclRefExpr global_var] <t1.c:4:19, t1.c:4:19>
> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] <t2.c:6:3, t2.c:6:3>
> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] <t2.c:7:12, t2.c:7:12>
Find definitions:
$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-defs
> [Decl: Var global_var] <t2.c:3:5, t2.c:3:18>
All the features was done in the code:
\llvm\tools\clang\tools\c-index-test\c-index-test.c
This is quite GOOD for an IDE!!!! :D :D :D
It also lacks some crucial information (which I could not seem to get an access to, like an exact position of the match), I can probably obtain more information if I will link directly with the clang libraries - but for the POC (prove of concept) it seems too much for me.
Hi, eranif, I have just dig into the libclang, especially the c-index-test.c file to see if is fit your desire.
From the latest svn code of clang and llvm, I found that:
F:\llvm_build\llvm\tools\clang\include\clang-c\Index.h
/**
* \brief A single result of code completion.
*/
typedef struct {
/**
* \brief The kind of entity that this completion refers to.
*
* The cursor kind will be a macro, keyword, or a declaration (one of the
* *Decl cursor kinds), describing the entity that the completion is
* referring to.
*
* \todo In the future, we would like to provide a full cursor, to allow
* the client to extract additional information from declaration.
*/
enum CXCursorKind CursorKind;
/**
* \brief The code-completion string that describes how to insert this
* code-completion result into the editing buffer.
*/
CXCompletionString CompletionString;
} CXCompletionResult;
You can see, the code completion result (one entry) only contains two members:
one is the CursorKind. and if it supply a "full Cursor" information, you can get the Location information about this code completion entry.
Maybe, the clang developers will improved this in the future. :D