diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-05-07 01:04:32 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-05-07 01:04:32 +0000 |
commit | 8e67219a7cb0cf7bfa432f8c30da9c52999737ce (patch) | |
tree | ad56800abb6386f9ad29202b5237a0acac178f88 | |
parent | a0536d8dd900bb48ea886bd68d777b03b061c068 (diff) |
Add initial USR support for mangling in the types of C++ functions and methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103225 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | test/Index/usrs.cpp | 43 | ||||
-rw-r--r-- | tools/libclang/CIndexUSRs.cpp | 140 |
2 files changed, 162 insertions, 21 deletions
diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp index a8b42690e2..45495e6a6b 100644 --- a/test/Index/usrs.cpp +++ b/test/Index/usrs.cpp @@ -47,21 +47,25 @@ namespace foo { namespace taz { }; }} +extern "C" { + void rez(int a, int b); +} + // RUN: c-index-test -test-load-source-usrs all %s | FileCheck %s // CHECK: usrs.cpp c:@N@foo Extent=[1:11 - 4:2] // CHECK: usrs.cpp c:@N@foo@x Extent=[2:3 - 2:8] -// CHECK: usrs.cpp c:@N@foo@F@bar Extent=[3:8 - 3:18] -// CHECK: usrs.cpp c:usrs.cpp@3:12@N@foo@F@bar@z Extent=[3:12 - 3:17] +// CHECK: usrs.cpp c:@N@foo@F@bar#I Extent=[3:8 - 3:18] +// CHECK: usrs.cpp c:usrs.cpp@3:12@N@foo@F@bar#I@z Extent=[3:12 - 3:17] // CHECK: usrs.cpp c:@N@bar Extent=[5:11 - 8:2] // CHECK: usrs.cpp c:usrs.cpp@6:15@N@bar@T@QType Extent=[6:15 - 6:20] -// CHECK: usrs.cpp c:@N@bar@F@bar Extent=[7:8 - 7:20] -// CHECK: usrs.cpp c:usrs.cpp@7:12@N@bar@F@bar@z Extent=[7:12 - 7:19] +// CHECK: usrs.cpp c:@N@bar@F@bar#I Extent=[7:8 - 7:20] +// CHECK: usrs.cpp c:usrs.cpp@7:12@N@bar@F@bar#I@z Extent=[7:12 - 7:19] // CHECK: usrs.cpp c:@C@ClsA Extent=[10:1 - 14:2] // CHECK: usrs.cpp c:@C@ClsA@FI@a Extent=[12:7 - 12:8] // CHECK: usrs.cpp c:@C@ClsA@FI@b Extent=[12:10 - 12:11] -// CHECK: usrs.cpp c:@C@ClsA@F@ClsA Extent=[13:3 - 13:37] -// CHECK: usrs.cpp c:usrs.cpp@13:8@C@ClsA@F@ClsA@A Extent=[13:8 - 13:13] -// CHECK: usrs.cpp c:usrs.cpp@13:15@C@ClsA@F@ClsA@B Extent=[13:15 - 13:20] +// CHECK: usrs.cpp c:@C@ClsA@F@ClsA#I#I Extent=[13:3 - 13:37] +// CHECK: usrs.cpp c:usrs.cpp@13:8@C@ClsA@F@ClsA#I#I@A Extent=[13:8 - 13:13] +// CHECK: usrs.cpp c:usrs.cpp@13:15@C@ClsA@F@ClsA#I#I@B Extent=[13:15 - 13:20] // CHECK: usrs.cpp c:@N@foo Extent=[16:11 - 22:2] // CHECK: usrs.cpp c:@N@foo@C@ClsB Extent=[17:3 - 21:4] // CHECK: usrs.cpp c:@N@foo@C@ClsB@F@ClsB Extent=[19:5 - 19:27] @@ -73,19 +77,20 @@ namespace foo { namespace taz { // CHECK: usrs.cpp c:@N@foo Extent=[35:11 - 40:2] // CHECK: usrs.cpp c:@N@foo@N@taz Extent=[35:27 - 39:2] // CHECK: usrs.cpp c:@N@foo@N@taz@x Extent=[36:3 - 36:8] -// CHECK: usrs.cpp c:usrs.cpp@37:21@N@foo@N@taz@F@add Extent=[37:21 - 37:56] -// CHECK: usrs.cpp c:usrs.cpp@37:25@N@foo@N@taz@F@add@a Extent=[37:25 - 37:30] -// CHECK: usrs.cpp c:usrs.cpp@37:32@N@foo@N@taz@F@add@b Extent=[37:32 - 37:37] -// CHECK: usrs.cpp c:@N@foo@N@taz@F@sub Extent=[38:8 - 38:25] -// CHECK: usrs.cpp c:usrs.cpp@38:12@N@foo@N@taz@F@sub@a Extent=[38:12 - 38:17] -// CHECK: usrs.cpp c:usrs.cpp@38:19@N@foo@N@taz@F@sub@b Extent=[38:19 - 38:24] +// CHECK: usrs.cpp c:usrs.cpp@37:21@N@foo@N@taz@F@add#I#I Extent=[37:21 - 37:56] +// CHECK: usrs.cpp c:usrs.cpp@37:25@N@foo@N@taz@F@add#I#I@a Extent=[37:25 - 37:30] +// CHECK: usrs.cpp c:usrs.cpp@37:32@N@foo@N@taz@F@add#I#I@b Extent=[37:32 - 37:37] +// CHECK: usrs.cpp c:@N@foo@N@taz@F@sub#I#I Extent=[38:8 - 38:25] +// CHECK: usrs.cpp c:usrs.cpp@38:12@N@foo@N@taz@F@sub#I#I@a Extent=[38:12 - 38:17] +// CHECK: usrs.cpp c:usrs.cpp@38:19@N@foo@N@taz@F@sub#I#I@b Extent=[38:19 - 38:24] // CHECK: usrs.cpp c:@N@foo Extent=[42:11 - 48:3] // CHECK: usrs.cpp c:@N@foo@N@taz Extent=[42:27 - 48:2] // CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD Extent=[43:3 - 47:4] -// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator= Extent=[45:11 - 45:52] -// CHECK: usrs.cpp c:usrs.cpp@45:21@N@foo@N@taz@C@ClsD@F@operator=@x Extent=[45:21 - 45:26] -// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator= Extent=[46:11 - 46:61] -// CHECK: usrs.cpp c:usrs.cpp@46:21@N@foo@N@taz@C@ClsD@F@operator=@x Extent=[46:21 - 46:29] - - +// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator=#I Extent=[45:11 - 45:52] +// CHECK: usrs.cpp c:usrs.cpp@45:21@N@foo@N@taz@C@ClsD@F@operator=#I@x Extent=[45:21 - 45:26] +// CHECK: usrs.cpp c:@N@foo@N@taz@C@ClsD@F@operator=#d Extent=[46:11 - 46:61] +// CHECK: usrs.cpp c:usrs.cpp@46:21@N@foo@N@taz@C@ClsD@F@operator=#d@x Extent=[46:21 - 46:29] +// CHECK: usrs.cpp c:@F@rez Extent=[51:8 - 51:25] +// CHECK: usrs.cpp c:usrs.cpp@51:12@F@rez@a Extent=[51:12 - 51:17] +// CHECK: usrs.cpp c:usrs.cpp@51:19@F@rez@b Extent=[51:19 - 51:24] diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index cc481d230e..bcb4f75d9e 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -53,6 +53,10 @@ public: void VisitTagDecl(TagDecl *D); void VisitTypedefDecl(TypedefDecl *D); void VisitVarDecl(VarDecl *D); + void VisitLinkageSpecDecl(LinkageSpecDecl *D) { + IgnoreResults = true; + return; + } /// Generate the string component containing the location of the /// declaration. @@ -82,6 +86,8 @@ public: void GenObjCProperty(llvm::StringRef prop); /// Generate a USR for an Objective-C protocol. void GenObjCProtocol(llvm::StringRef prot); + + void VisitType(QualType T); }; class StringUSRGenerator { @@ -147,6 +153,20 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) { VisitDeclContext(D->getDeclContext()); Out << "@F@" << D->getNameAsString(); + + ASTContext &Ctx = AU->getASTContext(); + if (!Ctx.getLangOptions().CPlusPlus || D->isExternC()) + return; + + // Mangle in type information for the arguments. + for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end(); + I != E; ++I) { + Out << '#'; + if (ParmVarDecl *PD = *I) + VisitType(PD->getType()); + } + if (D->isVariadic()) + Out << '.'; } void USRGenerator::VisitNamedDecl(NamedDecl *D) { @@ -274,7 +294,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) { // translation units. if (ShouldGenerateLocation(D) && GenLoc(D)) return; - + D = D->getCanonicalDecl(); VisitDeclContext(D->getDeclContext()); @@ -336,10 +356,126 @@ bool USRGenerator::GenLoc(const Decl *D) { Out << '@' << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':' << SM.getColumnNumber(Decomposed.first, Decomposed.second); - + return IgnoreResults; } +void USRGenerator::VisitType(QualType T) { + // This method mangles in USR information for types. It can possibly + // just reuse the naming-mangling logic used by codegen, although the + // requirements for USRs might not be the same. + do { + T = T.getTypePtr()->getCanonicalTypeInternal(); + Qualifiers Q = T.getQualifiers(); + if (Q.hasConst()) + Out << '1'; + if (Q.hasVolatile()) + Out << '2'; + if (Q.hasRestrict()) + Out << '3'; + + // Mangle in ObjC GC qualifiers? + + if (const PointerType *PT = T->getAs<PointerType>()) { + Out << '*'; + T = PT->getPointeeType(); + continue; + } + if (const ReferenceType *RT = T->getAs<ReferenceType>()) { + Out << '&'; + T = RT->getPointeeType(); + continue; + } + if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { + Out << 'F'; + VisitType(FT->getResultType()); + for (FunctionProtoType::arg_type_iterator + I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) { + VisitType(*I); + } + if (FT->isVariadic()) + Out << '.'; + return; + } + if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { + Out << 'B'; + T = BT->getPointeeType(); + continue; + } + if (const BuiltinType *BT = T->getAs<BuiltinType>()) { + unsigned char c = '\0'; + switch (BT->getKind()) { + case BuiltinType::Void: + c = 'v'; break; + case BuiltinType::Bool: + c = 'b'; break; + case BuiltinType::Char_U: + case BuiltinType::UChar: + c = 'c'; break; + case BuiltinType::Char16: + c = 'q'; break; + case BuiltinType::Char32: + c = 'w'; break; + case BuiltinType::UShort: + c = 's'; break; + case BuiltinType::UInt: + c = 'i'; break; + case BuiltinType::ULong: + c = 'l'; break; + case BuiltinType::ULongLong: + c = 'k'; break; + case BuiltinType::UInt128: + c = 'j'; break; + case BuiltinType::Char_S: + case BuiltinType::SChar: + c = 'C'; break; + case BuiltinType::WChar: + c = 'W'; break; + case BuiltinType::Short: + c = 'S'; break; + case BuiltinType::Int: + c = 'I'; break; + case BuiltinType::Long: + c = 'L'; break; + case BuiltinType::LongLong: + c = 'K'; break; + case BuiltinType::Int128: + c = 'J'; break; + case BuiltinType::Float: + c = 'f'; break; + case BuiltinType::Double: + c = 'd'; break; + case BuiltinType::LongDouble: + c = 'D'; break; + case BuiltinType::NullPtr: + c = 'n'; break; + case BuiltinType::Overload: + case BuiltinType::Dependent: + case BuiltinType::UndeducedAuto: + IgnoreResults = true; + return; + case BuiltinType::ObjCId: + c = 'o'; break; + case BuiltinType::ObjCClass: + c = 'O'; break; + case BuiltinType::ObjCSel: + c = 'e'; break; + } + Out << c; + return; + } + if (const ComplexType *CT = T->getAs<ComplexType>()) { + Out << '<'; + T = CT->getElementType(); + continue; + } + + // Unhandled type. + Out << ' '; + break; + } while (true); +} + //===----------------------------------------------------------------------===// // General purpose USR generation methods. //===----------------------------------------------------------------------===// |