|
30 | 30 | #include "clang-c/Index.h" |
31 | 31 | #include "clang-c/Rewrite.h" |
32 | 32 | #include "clang/AST/ASTContext.h" |
| 33 | +#include "clang/AST/ExprCXX.h" |
33 | 34 | #include "clang/AST/ParentMapContext.h" |
| 35 | +#include "clang/AST/StmtCXX.h" |
34 | 36 | #include "clang/Basic/SourceLocation.h" |
35 | 37 | #include "clang/Basic/SourceManager.h" |
36 | 38 | #include "clang/Frontend/ASTUnit.h" |
@@ -96,24 +98,55 @@ clang_getBody (CXCursor C) |
96 | 98 | if (clang_isDeclaration (C.kind)) |
97 | 99 | { |
98 | 100 | if (const Decl *D = cxcursor::getCursorDecl (C)) |
99 | | - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) |
100 | | - if (FD->doesThisDeclarationHaveABody ()) |
101 | | - return MakeCXCursorWithNull (FD->getBody (), C); |
| 101 | + switch (D->getKind ()) |
| 102 | + { |
| 103 | + case Decl::FunctionTemplate: |
| 104 | + return MakeCXCursorWithNull ( |
| 105 | + cast<FunctionTemplateDecl> (D)->getTemplatedDecl ()->getBody (), |
| 106 | + C); |
| 107 | + case Decl::Function: |
| 108 | + case Decl::CXXMethod: |
| 109 | + case Decl::CXXConstructor: |
| 110 | + case Decl::CXXDestructor: |
| 111 | + case Decl::CXXConversion: |
| 112 | + { |
| 113 | + const FunctionDecl *FD = cast<FunctionDecl> (D); |
| 114 | + if (FD->doesThisDeclarationHaveABody ()) |
| 115 | + return MakeCXCursorWithNull (FD->getBody (), C); |
| 116 | + break; |
| 117 | + } |
| 118 | + default: |
| 119 | + return MakeCXCursorWithNull (D->getBody (), C); |
| 120 | + } |
102 | 121 | } |
103 | 122 | else if (clang_isStatement (C.kind)) |
104 | | - if (const Stmt *S = cxcursor::getCursorStmt (C)) |
105 | | - switch (S->getStmtClass ()) |
| 123 | + { |
| 124 | + if (const Stmt *S = cxcursor::getCursorStmt (C)) |
| 125 | + switch (S->getStmtClass ()) |
| 126 | + { |
| 127 | + case Stmt::WhileStmtClass: |
| 128 | + return MakeCXCursorWithNull (cast<WhileStmt> (S)->getBody (), C); |
| 129 | + case Stmt::ForStmtClass: |
| 130 | + return MakeCXCursorWithNull (cast<ForStmt> (S)->getBody (), C); |
| 131 | + case Stmt::CXXForRangeStmtClass: |
| 132 | + return MakeCXCursorWithNull |
| 133 | + (cast<CXXForRangeStmt> (S)->getBody (), C); |
| 134 | + case Stmt::DoStmtClass: |
| 135 | + return MakeCXCursorWithNull (cast<DoStmt> (S)->getBody (), C); |
| 136 | + case Stmt::SwitchStmtClass: |
| 137 | + return MakeCXCursorWithNull (cast<SwitchStmt> (S)->getBody (), C); |
| 138 | + default: |
| 139 | + return clang_getNullCursor (); |
| 140 | + } |
| 141 | + } |
| 142 | + else if (clang_isExpression (C.kind)) |
| 143 | + if (const Expr *E = cxcursor::getCursorExpr (C)) |
| 144 | + switch (E->getStmtClass ()) |
106 | 145 | { |
107 | | - default: |
108 | | - return clang_getNullCursor (); |
109 | | - case Stmt::WhileStmtClass: |
110 | | - return MakeCXCursorWithNull (cast<WhileStmt> (S)->getBody (), C); |
111 | | - case Stmt::ForStmtClass: |
112 | | - return MakeCXCursorWithNull (cast<ForStmt> (S)->getBody (), C); |
113 | | - case Stmt::DoStmtClass: |
114 | | - return MakeCXCursorWithNull (cast<DoStmt> (S)->getBody (), C); |
115 | | - case Stmt::SwitchStmtClass: |
116 | | - return MakeCXCursorWithNull (cast<SwitchStmt> (S)->getBody (), C); |
| 146 | + case Expr::LambdaExprClass: |
| 147 | + return MakeCXCursorWithNull (cast<LambdaExpr> (E)->getBody (), C); |
| 148 | + default: |
| 149 | + return clang_getNullCursor (); |
117 | 150 | } |
118 | 151 | return clang_getNullCursor (); |
119 | 152 | } |
@@ -295,17 +328,36 @@ clang_getOperatorLoc (CXCursor C) |
295 | 328 | return cxloc::translateSourceLocation (CXXUnit->getASTContext (), sloc); |
296 | 329 | } |
297 | 330 |
|
298 | | -/* If the given expression is a paren expression, return the outermost |
299 | | - expression inside that is not a paren expression. */ |
| 331 | +/* If the given expression is a wrapping expression (i.e. a parenthesized |
| 332 | + expression, a cast expression etc.), return the outermost expression inside |
| 333 | + that is not a wrapping expression. */ |
300 | 334 |
|
301 | 335 | extern "C" CXCursor |
302 | 336 | clang_unwrap (CXCursor C) |
303 | 337 | { |
304 | 338 | if (clang_isExpression (C.kind)) |
305 | 339 | if (const Stmt *S = cxcursor::getCursorStmt (C)) |
306 | | - if (S->getStmtClass () == Stmt::ParenExprClass) |
307 | | - return clang_unwrap ( |
308 | | - MakeCXCursorWithNull (cast<ParenExpr> (S)->getSubExpr (), C)); |
| 340 | + switch (S->getStmtClass ()) |
| 341 | + { |
| 342 | + case Stmt::ParenExprClass: |
| 343 | + return clang_unwrap |
| 344 | + (MakeCXCursorWithNull (cast<ParenExpr> (S)->getSubExpr (), C)); |
| 345 | + case Expr::ConstantExprClass: |
| 346 | + case Expr::ExprWithCleanupsClass: |
| 347 | + return clang_unwrap |
| 348 | + (MakeCXCursorWithNull (cast<FullExpr> (S)->getSubExpr (), C)); |
| 349 | + case Expr::ImplicitCastExprClass: |
| 350 | + case Expr::CStyleCastExprClass: |
| 351 | + case Expr::CXXFunctionalCastExprClass: |
| 352 | + case Expr::CXXStaticCastExprClass: |
| 353 | + case Expr::CXXDynamicCastExprClass: |
| 354 | + case Expr::CXXReinterpretCastExprClass: |
| 355 | + case Expr::CXXConstCastExprClass: |
| 356 | + case Expr::CXXAddrspaceCastExprClass: |
| 357 | + return clang_unwrap |
| 358 | + (MakeCXCursorWithNull (cast<CastExpr> (S)->getSubExpr (), C)); |
| 359 | + |
| 360 | + } |
309 | 361 | return C; |
310 | 362 | } |
311 | 363 |
|
|
0 commit comments