2015-05-29 45 views
3

給定一個類層次結構:適當的AST匹配器

class A {}; 
class B {}; 
class C : public A {}; 
class D : public C {}; 

我試圖重構C級從B類繼承,而不是A類,我可以使用recordDecl輕鬆搞定定義語句:

recordDecl(hasName("C"), isDefinition()).bind("MyClass") 

與相關聯的MatchCallback,我可以dump()類驗證它相匹配的右節點。然而,我還沒有找到一種方法來代替public A,或者更好的辦法,就是A

什麼是合適的AST Matcher來捕獲類C的public AA

編輯:

clang -ast-dump在這種情況下,過濾C類會顯示類似下面的輸出:

CXXRecordDecl [address] <line numbers> <loc> class C definition 
|- public 'class A' 
|- CXXRecordDecl [address 2] <columns> <loc> implicit referenced class C 

這是因爲如果沒有AST節點類型來表示父ast-dump中的類聲明。

回答

1

我發現這個link提供了一些關於如何鑽取的上下文。值得注意的是,一個教程建議在返回節點的匹配處理程序中使用RecordDecl,而在CXXRecordDecl中使用此參考。因此,如果我們輸出的匹配處理每個基地:

if (const CXXRecord *entityBase = Result.Nodes.getNodeAs<clang::CXXRecordDecl>("entityBase")) { 
    for (auto &p : entityBase->bases()) { 
     p.dump(); 
    } 
} 

我們發現,提及A類是RecordType它是由CXXRecord簡稱。然而,使用clang-query,我沒有找到一種方法來將match recordType(...)與任何有助於拉動public AA的東西鏈接起來。相反,溶液變得類似於此:

std::string qual = "public "; 
std::string parentName = "A"; 
std::string parentType = "class " + parentName; 
if (0 == parentType.compare(p.getType().getAsString())) { 
    Replacement Rep(*(Result.SourceManager), 
     p.getLocStart().getLocWithOffset(qual.length()), 
     parentName.length(), 
     "B"); 
    Replace->insert(Rep); 
} 

我不只是萬一有人標誌着這個作爲答案尚未有辦法使用RECORDTYPE扎破基類的引用,而不是直接迭代和檢查的基礎類類型名稱,如上所示。