Hi, Douglas,<div><br></div><div>How could I re-lex the tokens? Does clang store some state information after lexing tokens? if so, simply set the Lexer::BufferPtr to the position of # is not enough.</div><div><br></div><div>

My current though is to still use the clang Lex mechanism</div><div>1) In Preprocessor::HandleIfDirective(), first call Preprocessor::EnableBacktrackAtThisPos().</div><div>2) In PPCallbacks::If(), call Preprocessor::Backtrack(), so that we can use the lexed tokens, and don't need to worry about the correct state of re-lexing.</div>

<div><br></div><div>How about your idea? I want to sync with u for the design before I start the coding again :)</div><div><br clear="all">Wei Hu<br><a href="http://code.google.com/u/wei.hu.tw/">http://code.google.com/u/wei.hu.tw/</a><br>

<a href="http://www.csie.ntu.edu.tw/~r88052/">http://www.csie.ntu.edu.tw/~r88052/</a><br><br>
<br><br><div class="gmail_quote">2011/4/21 Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Hello Wei,<br>
<div class="im"><br>
On Apr 20, 2011, at 7:09 AM, Wei wrote:<br>
<br>
> Hi, all,<br>
><br>
> I have made a patch to make clang::PPCallbacks::If() & clang::PPCallbacks::Elif() can pass-back a token tree.<br>
> That's what the original FIXME of these 2 functions said: "better to pass in a list (or tree!) of Tokens."<br>
><br>
> This patch has passed all the expected tests in the clang-test. (I use Visual C++ 2010 Express as my dev. environment)<br>
> 1>  Testing Time: 738.14s<br>
> 1>    Expected Passes    : 2877<br>
> 1>    Expected Failures  : 26<br>
> 1>    Unsupported Tests  : 5<br>
><br>
> I hope this patch can be merged into clang main trunk, and if you have any problems about this patch, please let me know, I'll modify it so that it can be merged.<br>
<br>
</div>The preprocessor is an extremely performance-sensitive part of Clang, so we need to be very careful about what computation we perform. Building a tree-like data structure such as<br>
<br>
@@ -264,6 +266,57 @@<br>
<br>
 };<br>
<br>
+class TokenTreeNode {<br>
+ private:<br>
+  llvm::BumpPtrAllocator *Allocator;<br>
+  Token Self;<br>
+<br>
+  typedef llvm::SmallVector<TokenTreeNode*,3> ChildrenTy;<br>
+  typedef ChildrenTy::iterator iterator;<br>
+<br>
+  ChildrenTy Children;<br>
+<br>
+ public:<br>
+  TokenTreeNode(Token &token, llvm::BumpPtrAllocator *allocator) :<br>
+      Allocator(allocator),<br>
+      Self(token) {<br>
+    assert(Allocator != 0);<br>
+  }<br>
+<br>
+  ~TokenTreeNode() {<br>
+    for (iterator iter = Children.begin(); iter != Children.end(); ++iter) {<br>
+      (*iter)->~TokenTreeNode();<br>
+      Allocator->Deallocate(*iter);<br>
+    }<br>
+  }<br>
+<br>
+  inline ChildrenTy &getChildren() {<br>
+    return Children;<br>
+  }<br>
+<br>
+  void addChildren(iterator I, Token &T) {<br>
+    TokenTreeNode *Node = Allocator->Allocate<TokenTreeNode>();<br>
+    new (Node) TokenTreeNode(T, Allocator);<br>
+    Children.insert(I, Node);<br>
+  }<br>
+<br>
+  void addChildren(iterator I, TokenTreeNode *N) {<br>
+    assert(N != 0);<br>
+    Children.insert(I, N);<br>
+  }<br>
+<br>
+  inline void addChildren(Token &T) {<br>
+    addChildren(Children.end(), T);<br>
+  }<br>
+<br>
+  inline void addChildren(TokenTreeNode *N) {<br>
+    assert(N != 0);<br>
+    addChildren(Children.end(), N);<br>
+  }<br>
+<br>
+  void dump(unsigned IndentLevel);<br>
+};<br>
<br>
is likely to incur an unacceptable performance penalty. It's probably reasonable to pass the SourceRange of the expression down to If/ElIf, from which one could re-lex the tokens if desired.<br>
<br>
        - Doug<br>
<br>
</blockquote></div><br></div>