|
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