Hi
I added few functions to libclang:

+clang_getCursorSourceFile
+clang_getOperatorString
+clang_getBinaryOpCode
+clang_getUnaryOpCode
+clang_getLiteralString
+clang_getForStmtInit
+clang_getForStmtCond
+clang_getForStmtInc
+clang_getForStmtBody
+clang_getFriendCursor
+clang_getFriendType

I using them in my project.

Not all of them are perfect. My Clang SDK knowledge is much lower than
midle. So any fixes including 'best practice' are welcome.

Based on r205967

Aleksey
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h	(revision 205968)
+++ include/clang-c/Index.h	(working copy)
@@ -2667,7 +2667,107 @@
  */
 CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
 
+//-------- !!! begin
+
 /**
+ * \brief Retrieve the source file for cursor
+ */
+CINDEX_LINKAGE CXFile clang_getCursorSourceFile(CXCursor C);
+
+enum CXBinaryOpCode {
+  // Operators listed in order of precedence.
+  // Note that additions to this should also update the StmtVisitor class.
+  BO_PtrMemD, BO_PtrMemI,       // [C++ 5.5] Pointer-to-member operators.
+  BO_Mul, BO_Div, BO_Rem,       // [C99 6.5.5] Multiplicative operators.
+  BO_Add, BO_Sub,               // [C99 6.5.6] Additive operators.
+  BO_Shl, BO_Shr,               // [C99 6.5.7] Bitwise shift operators.
+  BO_LT, BO_GT, BO_LE, BO_GE,   // [C99 6.5.8] Relational operators.
+  BO_EQ, BO_NE,                 // [C99 6.5.9] Equality operators.
+  BO_And,                       // [C99 6.5.10] Bitwise AND operator.
+  BO_Xor,                       // [C99 6.5.11] Bitwise XOR operator.
+  BO_Or,                        // [C99 6.5.12] Bitwise OR operator.
+  BO_LAnd,                      // [C99 6.5.13] Logical AND operator.
+  BO_LOr,                       // [C99 6.5.14] Logical OR operator.
+  BO_Assign, BO_MulAssign,      // [C99 6.5.16] Assignment operators.
+  BO_DivAssign, BO_RemAssign,
+  BO_AddAssign, BO_SubAssign,
+  BO_ShlAssign, BO_ShrAssign,
+  BO_AndAssign, BO_XorAssign,
+  BO_OrAssign,
+  BO_Comma,                      // [C99 6.5.17] Comma operator.
+  BO_Unknown
+};
+
+enum CXUnaryOpCode {
+  // Note that additions to this should also update the StmtVisitor class.
+  UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement
+  UO_PreInc, UO_PreDec,   // [C99 6.5.3.1] Prefix increment and decrement
+  UO_AddrOf, UO_Deref,    // [C99 6.5.3.2] Address and indirection
+  UO_Plus, UO_Minus,      // [C99 6.5.3.3] Unary arithmetic
+  UO_Not, UO_LNot,        // [C99 6.5.3.3] Unary arithmetic
+  UO_Real, UO_Imag,       // "__real expr"/"__imag expr" Extension.
+  UO_Extension,            // __extension__ marker.
+  UO_Unknown
+};
+
+/**
+ * \brief Returns string representation of unary and binary operators
+ */
+CINDEX_LINKAGE CXString clang_getOperatorString(CXCursor C);
+
+/**
+ * \brief Returns OpCode of binary operator
+ */
+CINDEX_LINKAGE enum CXBinaryOpCode clang_getBinaryOpCode(CXCursor C); 
+
+/**
+ * \brief Returns OpCode of unary operator
+ */
+CINDEX_LINKAGE enum CXUnaryOpCode clang_getUnaryOpCode(CXCursor C); 
+
+/**
+ * \brief Returns string representation of literal cursor (1.f, 1000L, etc)
+ */
+CINDEX_LINKAGE CXString clang_getLiteralString(CXCursor C);
+
+/**
+ * \brief Returns for-loop init cursor [for(init;cond;inc)], or CXCursor_NoDeclFound if there is no decl,
+ * or CXCursor_InvalidCode if C is not CXCursor_ForStmt
+ */
+CINDEX_LINKAGE CXCursor clang_getForStmtInit(CXCursor C);
+
+/**
+ * \brief Returns for-loop condition cursor [for(init;cond;inc)], or CXCursor_NoDeclFound if there is no decl,
+ * or CXCursor_InvalidCode if C is not CXCursor_ForStmt
+ */
+CINDEX_LINKAGE CXCursor clang_getForStmtCond(CXCursor C);
+
+/**
+ * \brief Returns for-loop increment cursor [for(init;cond;inc)], or CXCursor_NoDeclFound if there is no decl,
+ * or CXCursor_InvalidCode if C is not CXCursor_ForStmt
+ */
+CINDEX_LINKAGE CXCursor clang_getForStmtInc(CXCursor C);
+
+/**
+ * \brief Returns for-loop body, or CXCursor_NoDeclFound if there is no decl,
+ * or CXCursor_InvalidCode if C is not CXCursor_ForStmt
+ */
+CINDEX_LINKAGE CXCursor clang_getForStmtBody(CXCursor C);
+
+/**
+ * \brief Returns FriendDecl cursor, or CXCursor_NoDeclFound if there is no decl,
+ * or CXCursor_InvalidCode if C is not friend cursor
+ */
+CINDEX_LINKAGE CXCursor clang_getFriendCursor(CXCursor C);
+
+/**
+ * \brief Returns friend type (friend class A) => class A (FIXME: make it returns CXCursorKind or something much useful)
+ */
+CINDEX_LINKAGE CXString clang_getFriendType(CXCursor C);
+
+//---------!!! end
+
+/**
  * \brief Retrieve the physical extent of the source construct referenced by
  * the given cursor.
  *
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp	(revision 205968)
+++ tools/libclang/CIndex.cpp	(working copy)
@@ -3114,6 +3114,33 @@
   return const_cast<FileEntry *>(FMgr.getFile(file_name));
 }
 
+//-----------------!!! patch begin
+
+static const FileEntry *getFileEntryFromSourceLocation(SourceManager &SMgr,SourceLocation SLoc) 
+{
+  FileID FID;
+  if (SLoc.isFileID())
+    FID = SMgr.getFileID(SLoc);
+  else
+    FID = SMgr.getDecomposedSpellingLoc(SLoc).first;
+  return SMgr.getFileEntryForID(FID);
+}
+
+CXFile clang_getCursorSourceFile(CXCursor C)
+{
+  if (!clang_isDeclaration(C.kind)) return 0;
+
+  NamedDecl *ND = (NamedDecl*)getCursorDecl(C);
+  SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
+  
+  CXSourceLocation CXLoc = clang_getCursorLocation(C);
+  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
+  
+  return (void *)getFileEntryFromSourceLocation(SourceMgr,Loc);
+}
+
+//-----------------!!! end
+
 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
                                             CXFile file) {
   if (isNotUsableTU(TU)) {
@@ -4478,7 +4505,163 @@
 }
 
 extern "C" {
+	
+//----------!!! begin
+CXString clang_getOperatorString(CXCursor C) 
+{
 
+  if (C.kind == CXCursor_BinaryOperator) {
+    BinaryOperator *Op = (clang::BinaryOperator*)getCursorExpr(C);
+    return cxstring::createDup(clang::BinaryOperator::getOpcodeStr(Op->getOpcode()));
+  }
+  
+  if (C.kind == CXCursor_CompoundAssignOperator) {
+    CompoundAssignOperator *Op = (clang::CompoundAssignOperator*)getCursorExpr(C);
+    return cxstring::createDup(clang::BinaryOperator::getOpcodeStr(Op->getOpcode()));
+  }
+
+  if (C.kind == CXCursor_UnaryOperator) {
+    UnaryOperator *Op = (clang::UnaryOperator*)getCursorExpr(C);
+    return cxstring::createDup(clang::UnaryOperator::getOpcodeStr(Op->getOpcode()));
+  }
+  
+  return cxstring::createEmpty();
+}
+
+enum CXBinaryOpCode clang_getBinaryOpCode(CXCursor C) 
+{
+  if (C.kind == CXCursor_BinaryOperator) {
+    BinaryOperator *Op = (clang::BinaryOperator*)getCursorExpr(C);
+    return static_cast<CXBinaryOpCode>(Op->getOpcode());
+  }
+  if (C.kind == CXCursor_CompoundAssignOperator) {
+    CompoundAssignOperator *Op = (clang::CompoundAssignOperator*)getCursorExpr(C);
+    return static_cast<CXBinaryOpCode>(Op->getOpcode());
+  }
+  return BO_Unknown;
+}
+
+enum CXUnaryOpCode clang_getUnaryOpCode(CXCursor C) 
+{
+  if (C.kind == CXCursor_UnaryOperator) {
+    UnaryOperator *Op = (clang::UnaryOperator*)getCursorExpr(C);
+    return static_cast<CXUnaryOpCode>(Op->getOpcode());
+  }
+  return UO_Unknown;
+}
+
+CXString clang_getLiteralString(CXCursor C) 
+{
+
+  if (C.kind == CXCursor_IntegerLiteral) {
+    IntegerLiteral *Li = (clang::IntegerLiteral*)getCursorExpr(C);
+    return cxstring::createDup(Li->getValue().toString(10, true));
+  }
+
+  if (C.kind == CXCursor_FloatingLiteral) {
+    FloatingLiteral *Fi = (clang::FloatingLiteral*)getCursorExpr(C);
+    llvm::SmallString<1024> S;
+    Fi->getValue().toString(S);
+    return cxstring::createDup(S.c_str());
+  }
+
+  if (C.kind == CXCursor_CharacterLiteral) {
+    CharacterLiteral *Cl = (clang::CharacterLiteral*)getCursorExpr(C);
+    char c[2];
+    c[0] = (char)Cl->getValue();c[1] = '\0';
+    return cxstring::createDup(c);
+  }
+
+  if (C.kind == CXCursor_StringLiteral) {
+    StringLiteral *Sl = (clang::StringLiteral*)getCursorExpr(C);
+    return cxstring::createDup(Sl->getBytes());
+  }
+  
+  if (C.kind == CXCursor_CXXBoolLiteralExpr) {
+    CXXBoolLiteralExpr *Bl = (clang::CXXBoolLiteralExpr*)getCursorExpr(C);
+    return cxstring::createDup(Bl->getValue()?"true":"false");
+  }
+
+  return cxstring::createEmpty();
+}
+
+CXCursor clang_getForStmtInit(CXCursor C)
+{
+	if(C.kind!=CXCursor_ForStmt) return MakeCXCursorInvalid(CXCursor_InvalidCode);
+	
+	ForStmt* Node=(ForStmt*)(C.data[1]);
+	const CXTranslationUnit tu=(const CXTranslationUnit)(C.data[2]);
+	
+	Stmt* init=Node->getInit();
+	if (init) return MakeCXCursor(init,0,tu);
+  	else return MakeCXCursorInvalid(CXCursor_NoDeclFound);
+}
+
+CXCursor clang_getForStmtCond(CXCursor C)
+{
+	if(C.kind!=CXCursor_ForStmt) return MakeCXCursorInvalid(CXCursor_InvalidCode);
+	
+	ForStmt* Node=(ForStmt*)(C.data[1]);
+	const CXTranslationUnit tu=(const CXTranslationUnit)(C.data[2]);
+	
+	Stmt* cond=Node->getCond();
+	if (cond) return MakeCXCursor(cond,0,tu);
+  	else return MakeCXCursorInvalid(CXCursor_NoDeclFound);
+}
+
+CXCursor clang_getForStmtInc(CXCursor C)
+{
+	if(C.kind!=CXCursor_ForStmt) return MakeCXCursorInvalid(CXCursor_InvalidCode);
+	
+	ForStmt* Node=(ForStmt*)(C.data[1]);
+	const CXTranslationUnit tu=(const CXTranslationUnit)(C.data[2]);
+	
+	Stmt* inc=Node->getInc();
+	if (inc) return MakeCXCursor(inc,0,tu);
+  	else return MakeCXCursorInvalid(CXCursor_NoDeclFound);
+}
+
+CXCursor clang_getForStmtBody(CXCursor C)
+{
+	if(C.kind!=CXCursor_ForStmt) return MakeCXCursorInvalid(CXCursor_InvalidCode);
+	
+	ForStmt* Node=(ForStmt*)(C.data[1]);
+	const CXTranslationUnit tu=(const CXTranslationUnit)(C.data[2]);
+	
+	Stmt* body=Node->getBody();
+	if (body) return MakeCXCursor(body,0,tu);
+  	else return MakeCXCursorInvalid(CXCursor_NoDeclFound);
+}
+
+CXCursor clang_getFriendCursor(CXCursor C)
+{
+	const Decl *D = getCursorDecl(C);
+	if(!D) return MakeCXCursorInvalid(CXCursor_NoDeclFound);
+	
+	const CXTranslationUnit tu = (const CXTranslationUnit)(C.data[2]);
+	
+	NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl();
+	if(Friend) return MakeCXCursor(Friend, tu);
+	
+ 	return MakeCXCursorInvalid(CXCursor_InvalidCode);
+}
+
+CXString clang_getFriendType(CXCursor C)
+{
+	const Decl *D = getCursorDecl(C);
+	if(!D) return cxstring::createDup("no_decl");
+
+	TypeSourceInfo *type = cast<FriendDecl>(D)->getFriendType();
+	if(type) 
+	{
+		PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
+		return cxstring::createDup(type->getType().getAsString(Policy));
+	}
+	
+	return cxstring::createDup("unknown");
+}
+//------------------------!!! patch end
+
 CXSourceRange clang_getCursorExtent(CXCursor C) {
   SourceRange R = getRawCursorExtent(C);
   if (R.isInvalid())
Index: tools/libclang/libclang.exports
===================================================================
--- tools/libclang/libclang.exports	(revision 205968)
+++ tools/libclang/libclang.exports	(working copy)
@@ -145,6 +145,17 @@
 clang_getCursorCompletionString
 clang_getCursorDefinition
 clang_getCursorDisplayName
+clang_getCursorSourceFile
+clang_getOperatorString
+clang_getBinaryOpCode
+clang_getUnaryOpCode
+clang_getLiteralString
+clang_getForStmtInit
+clang_getForStmtCond
+clang_getForStmtInc
+clang_getForStmtBody
+clang_getFriendCursor
+clang_getFriendType
 clang_getCursorExtent
 clang_getCursorKind
 clang_getCursorKindSpelling
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to