forked from OSchip/llvm-project
[libclang]
-Allow cursor visitation of an attribute using its source range -Add C++ 'final' and 'override' attributes as cursor kinds -Simplify the logic that marks 'final' and 'override' attributes as tokens. llvm-svn: 139609
This commit is contained in:
parent
820c8fd0db
commit
2cb4e3c554
|
@ -1450,7 +1450,9 @@ enum CXCursorKind {
|
|||
CXCursor_IBActionAttr = 401,
|
||||
CXCursor_IBOutletAttr = 402,
|
||||
CXCursor_IBOutletCollectionAttr = 403,
|
||||
CXCursor_LastAttr = CXCursor_IBOutletCollectionAttr,
|
||||
CXCursor_CXXFinalAttr = 404,
|
||||
CXCursor_CXXOverrideAttr = 405,
|
||||
CXCursor_LastAttr = CXCursor_CXXOverrideAttr,
|
||||
|
||||
/* Preprocessing */
|
||||
CXCursor_PreprocessingDirective = 500,
|
||||
|
|
|
@ -22,7 +22,7 @@ struct Derived2 : Base2 {
|
|||
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "class" [6:1 - 6:6] ClassDecl=Derived:6:7 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Identifier: "Derived" [6:7 - 6:14] ClassDecl=Derived:6:7 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "final" [6:15 - 6:20] ClassDecl=Derived:6:7 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "final" [6:15 - 6:20] attribute(final)=
|
||||
// CHECK-OVERRIDE-FINAL: Punctuation: ":" [6:21 - 6:22] ClassDecl=Derived:6:7 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "public" [6:23 - 6:29] C++ base class specifier=class Base:1:7 [access=public isVirtual=false]
|
||||
// CHECK-OVERRIDE-FINAL: Identifier: "Base" [6:30 - 6:34] TypeRef=class Base:1:7
|
||||
|
@ -32,8 +32,8 @@ struct Derived2 : Base2 {
|
|||
// CHECK-OVERRIDE-FINAL: Identifier: "f" [7:16 - 7:17] CXXMethod=f:7:16 (virtual) [Overrides @3:16]
|
||||
// CHECK-OVERRIDE-FINAL: Punctuation: "(" [7:17 - 7:18] CXXMethod=f:7:16 (virtual) [Overrides @3:16]
|
||||
// CHECK-OVERRIDE-FINAL: Punctuation: ")" [7:18 - 7:19] CXXMethod=f:7:16 (virtual) [Overrides @3:16]
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "override" [7:20 - 7:28] CXXMethod=f:7:16 (virtual) [Overrides @3:16]
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "final" [7:29 - 7:34] CXXMethod=f:7:16 (virtual) [Overrides @3:16]
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "override" [7:20 - 7:28] attribute(override)=
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "final" [7:29 - 7:34] attribute(final)=
|
||||
// CHECK-OVERRIDE-FINAL: Punctuation: ";" [7:34 - 7:35] ClassDecl=Derived:6:7 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Keyword: "struct" [9:3 - 9:9] StructDecl=final:9:10 (Definition)
|
||||
// CHECK-OVERRIDE-FINAL: Identifier: "final" [9:10 - 9:15] StructDecl=final:9:10 (Definition)
|
||||
|
|
|
@ -3386,6 +3386,10 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
|
|||
return createCXString("attribute(iboutlet)");
|
||||
case CXCursor_IBOutletCollectionAttr:
|
||||
return createCXString("attribute(iboutletcollection)");
|
||||
case CXCursor_CXXFinalAttr:
|
||||
return createCXString("attribute(final)");
|
||||
case CXCursor_CXXOverrideAttr:
|
||||
return createCXString("attribute(override)");
|
||||
case CXCursor_PreprocessingDirective:
|
||||
return createCXString("preprocessing directive");
|
||||
case CXCursor_MacroDefinition:
|
||||
|
@ -3804,6 +3808,9 @@ static SourceRange getRawCursorExtent(CXCursor C) {
|
|||
if (clang_isStatement(C.kind))
|
||||
return getCursorStmt(C)->getSourceRange();
|
||||
|
||||
if (clang_isAttribute(C.kind))
|
||||
return getCursorAttr(C)->getRange();
|
||||
|
||||
if (C.kind == CXCursor_PreprocessingDirective)
|
||||
return cxcursor::getCursorPreprocessingDirective(C);
|
||||
|
||||
|
@ -5083,44 +5090,10 @@ static void clang_annotateTokensImpl(void *UserData) {
|
|||
Tokens[I].int_data[0] = CXToken_Keyword;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Cursors[I].kind == CXCursor_CXXMethod) {
|
||||
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
|
||||
if (CXXMethodDecl *Method
|
||||
= dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
|
||||
if ((Method->hasAttr<FinalAttr>() ||
|
||||
Method->hasAttr<OverrideAttr>()) &&
|
||||
Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
|
||||
llvm::StringSwitch<bool>(II->getName())
|
||||
.Case("final", true)
|
||||
.Case("override", true)
|
||||
.Default(false))
|
||||
Tokens[I].int_data[0] = CXToken_Keyword;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Cursors[I].kind == CXCursor_ClassDecl ||
|
||||
Cursors[I].kind == CXCursor_StructDecl ||
|
||||
Cursors[I].kind == CXCursor_ClassTemplate) {
|
||||
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
|
||||
if (II->getName() == "final") {
|
||||
// We have to be careful with 'final', since it could be the name
|
||||
// of a member class rather than the context-sensitive keyword.
|
||||
// So, check whether the cursor associated with this
|
||||
Decl *D = getCursorDecl(Cursors[I]);
|
||||
if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
|
||||
if ((Record->hasAttr<FinalAttr>()) &&
|
||||
Record->getIdentifier() != II)
|
||||
Tokens[I].int_data[0] = CXToken_Keyword;
|
||||
} else if (ClassTemplateDecl *ClassTemplate
|
||||
= dyn_cast_or_null<ClassTemplateDecl>(D)) {
|
||||
CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
|
||||
if ((Record->hasAttr<FinalAttr>()) &&
|
||||
Record->getIdentifier() != II)
|
||||
Tokens[I].int_data[0] = CXToken_Keyword;
|
||||
}
|
||||
}
|
||||
|
||||
if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
|
||||
Cursors[I].kind == CXCursor_CXXOverrideAttr) {
|
||||
Tokens[I].int_data[0] = CXToken_Keyword;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ static CXCursorKind GetCursorKind(const Attr *A) {
|
|||
case attr::IBAction: return CXCursor_IBActionAttr;
|
||||
case attr::IBOutlet: return CXCursor_IBOutletAttr;
|
||||
case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
|
||||
case attr::Final: return CXCursor_CXXFinalAttr;
|
||||
case attr::Override: return CXCursor_CXXOverrideAttr;
|
||||
}
|
||||
|
||||
return CXCursor_UnexposedAttr;
|
||||
|
|
Loading…
Reference in New Issue