23
23
#include " CursorVisitor.h"
24
24
#include " clang-c/FatalErrorHandler.h"
25
25
#include " clang/AST/Attr.h"
26
+ #include " clang/AST/AttrVisitor.h"
26
27
#include " clang/AST/DeclObjCCommon.h"
27
28
#include " clang/AST/Expr.h"
28
29
#include " clang/AST/ExprCXX.h"
@@ -575,6 +576,13 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
575
576
A->getInterfaceLoc ()->getTypeLoc ().getBeginLoc (), TU));
576
577
}
577
578
579
+ if (clang_isAttribute (Cursor.kind )) {
580
+ if (const Attr *A = getCursorAttr (Cursor))
581
+ return Visit (A);
582
+
583
+ return false ;
584
+ }
585
+
578
586
// If pointing inside a macro definition, check if the token is an identifier
579
587
// that was ever defined as a macro. In such a case, create a "pseudo" macro
580
588
// expansion cursor for that token.
@@ -2089,7 +2097,8 @@ class MemberRefVisit : public VisitorJob {
2089
2097
(SourceLocation::UIntTy)(uintptr_t )data[1 ]);
2090
2098
}
2091
2099
};
2092
- class EnqueueVisitor : public ConstStmtVisitor <EnqueueVisitor, void > {
2100
+ class EnqueueVisitor : public ConstStmtVisitor <EnqueueVisitor, void >,
2101
+ public ConstAttrVisitor<EnqueueVisitor, void > {
2093
2102
friend class OMPClauseEnqueue ;
2094
2103
VisitorWorkList &WL;
2095
2104
CXCursor Parent;
@@ -2231,6 +2240,9 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
2231
2240
void VisitOMPTargetTeamsDistributeSimdDirective (
2232
2241
const OMPTargetTeamsDistributeSimdDirective *D);
2233
2242
2243
+ // Attributes
2244
+ void VisitAnnotateAttr (const AnnotateAttr *A);
2245
+
2234
2246
private:
2235
2247
void AddDeclarationNameInfo (const Stmt *S);
2236
2248
void AddNestedNameSpecifierLoc (NestedNameSpecifierLoc Qualifier);
@@ -2242,6 +2254,7 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
2242
2254
void AddTypeLoc (TypeSourceInfo *TI);
2243
2255
void EnqueueChildren (const Stmt *S);
2244
2256
void EnqueueChildren (const OMPClause *S);
2257
+ void EnqueueChildren (const AnnotateAttr *A);
2245
2258
};
2246
2259
} // namespace
2247
2260
@@ -2736,6 +2749,20 @@ void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2736
2749
VisitorWorkList::iterator I = WL.begin () + size, E = WL.end ();
2737
2750
std::reverse (I, E);
2738
2751
}
2752
+
2753
+ void EnqueueVisitor::EnqueueChildren (const AnnotateAttr *A) {
2754
+ unsigned size = WL.size ();
2755
+ for (const Expr *Arg : A->args ()) {
2756
+ VisitStmt (Arg);
2757
+ }
2758
+ if (size == WL.size ())
2759
+ return ;
2760
+ // Now reverse the entries we just added. This will match the DFS
2761
+ // ordering performed by the worklist.
2762
+ VisitorWorkList::iterator I = WL.begin () + size, E = WL.end ();
2763
+ std::reverse (I, E);
2764
+ }
2765
+
2739
2766
void EnqueueVisitor::VisitAddrLabelExpr (const AddrLabelExpr *E) {
2740
2767
WL.push_back (LabelRefVisit (E->getLabel (), E->getLabelLoc (), Parent));
2741
2768
}
@@ -3008,7 +3035,7 @@ void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
3008
3035
// If the opaque value has a source expression, just transparently
3009
3036
// visit that. This is useful for (e.g.) pseudo-object expressions.
3010
3037
if (Expr *SourceExpr = E->getSourceExpr ())
3011
- return Visit (SourceExpr);
3038
+ return ConstStmtVisitor:: Visit (SourceExpr);
3012
3039
}
3013
3040
void EnqueueVisitor::VisitLambdaExpr (const LambdaExpr *E) {
3014
3041
AddStmt (E->getBody ());
@@ -3028,7 +3055,7 @@ void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
3028
3055
}
3029
3056
void EnqueueVisitor::VisitPseudoObjectExpr (const PseudoObjectExpr *E) {
3030
3057
// Treat the expression like its syntactic form.
3031
- Visit (E->getSyntacticForm ());
3058
+ ConstStmtVisitor:: Visit (E->getSyntacticForm ());
3032
3059
}
3033
3060
3034
3061
void EnqueueVisitor::VisitOMPExecutableDirective (
@@ -3338,9 +3365,28 @@ void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3338
3365
VisitOMPLoopDirective (D);
3339
3366
}
3340
3367
3368
+ void EnqueueVisitor::VisitAnnotateAttr (const AnnotateAttr *A) {
3369
+ EnqueueChildren (A);
3370
+ }
3371
+
3341
3372
void CursorVisitor::EnqueueWorkList (VisitorWorkList &WL, const Stmt *S) {
3342
3373
EnqueueVisitor (WL, MakeCXCursor (S, StmtParent, TU, RegionOfInterest))
3343
- .Visit (S);
3374
+ .ConstStmtVisitor ::Visit (S);
3375
+ }
3376
+
3377
+ void CursorVisitor::EnqueueWorkList (VisitorWorkList &WL, const Attr *A) {
3378
+ // Parent is the attribute itself when this is indirectly called from
3379
+ // VisitChildren. Because we need to make a CXCursor for A, we need *its*
3380
+ // parent.
3381
+ auto AttrCursor = Parent;
3382
+
3383
+ // Get the attribute's parent as stored in
3384
+ // cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent, CXTranslationUnit
3385
+ // TU)
3386
+ const Decl *AttrParent = static_cast <const Decl *>(AttrCursor.data [1 ]);
3387
+
3388
+ EnqueueVisitor (WL, MakeCXCursor (A, AttrParent, TU))
3389
+ .ConstAttrVisitor ::Visit (A);
3344
3390
}
3345
3391
3346
3392
bool CursorVisitor::IsInRegionOfInterest (CXCursor C) {
@@ -3605,6 +3651,22 @@ bool CursorVisitor::Visit(const Stmt *S) {
3605
3651
return result;
3606
3652
}
3607
3653
3654
+ bool CursorVisitor::Visit (const Attr *A) {
3655
+ VisitorWorkList *WL = nullptr ;
3656
+ if (!WorkListFreeList.empty ()) {
3657
+ WL = WorkListFreeList.back ();
3658
+ WL->clear ();
3659
+ WorkListFreeList.pop_back ();
3660
+ } else {
3661
+ WL = new VisitorWorkList ();
3662
+ WorkListCache.push_back (WL);
3663
+ }
3664
+ EnqueueWorkList (*WL, A);
3665
+ bool result = RunVisitorWorkList (*WL);
3666
+ WorkListFreeList.push_back (WL);
3667
+ return result;
3668
+ }
3669
+
3608
3670
namespace {
3609
3671
typedef SmallVector<SourceRange, 4 > RefNamePieces;
3610
3672
RefNamePieces buildPieces (unsigned NameFlags, bool IsMemberRefExpr,
0 commit comments