forked from OSchip/llvm-project
Change CXTranslationUnit to not directly cast to an ASTUnit*,
but to wrap both an ASTUnit and a "string pool" that will be used for fast USR generation. This requires a bunch of mechanical changes, as there was a ton of code that assumed that CXTranslationUnit and ASTUnit* were the same. Along with this change, introduce CXStringBuf, which provides an llvm::SmallVector<char> backing for repeatedly generating CXStrings without a huge amount of malloc() traffic. This requires making some changes to the representation of CXString by renaming a few fields (but keeping the size of the object the same). llvm-svn: 119337
This commit is contained in:
parent
9813d3221d
commit
915542850b
|
@ -63,7 +63,10 @@ typedef void *CXIndex;
|
|||
/**
|
||||
* \brief A single translation unit, which resides in an index.
|
||||
*/
|
||||
typedef void *CXTranslationUnit; /* A translation unit instance. */
|
||||
typedef struct CXTranslationUnitImpl {
|
||||
void *TUData;
|
||||
void *StringPool;
|
||||
} *CXTranslationUnit; /* A translation unit instance. */
|
||||
|
||||
/**
|
||||
* \brief Opaque pointer representing client data that will be passed through
|
||||
|
@ -133,7 +136,7 @@ enum CXAvailabilityKind {
|
|||
* with the string data, call \c clang_disposeString() to free the string.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *Spelling;
|
||||
void *data;
|
||||
unsigned private_flags;
|
||||
} CXString;
|
||||
|
||||
|
|
|
@ -1305,7 +1305,7 @@ int print_usrs(const char **I, const char **E) {
|
|||
return not_usr("<class USR>", I[2]);
|
||||
else {
|
||||
CXString x;
|
||||
x.Spelling = I[2];
|
||||
x.data = (void*) I[2];
|
||||
x.private_flags = 0;
|
||||
print_usr(clang_constructUSR_ObjCIvar(I[1], x));
|
||||
}
|
||||
|
@ -1332,7 +1332,7 @@ int print_usrs(const char **I, const char **E) {
|
|||
return not_usr("<class USR>", I[3]);
|
||||
else {
|
||||
CXString x;
|
||||
x.Spelling = I[3];
|
||||
x.data = (void*) I[3];
|
||||
x.private_flags = 0;
|
||||
print_usr(clang_constructUSR_ObjCMethod(I[1], atoi(I[2]), x));
|
||||
}
|
||||
|
@ -1362,7 +1362,7 @@ int print_usrs(const char **I, const char **E) {
|
|||
return not_usr("<class USR>", I[2]);
|
||||
else {
|
||||
CXString x;
|
||||
x.Spelling = I[2];
|
||||
x.data = (void*) I[2];
|
||||
x.private_flags = 0;
|
||||
print_usr(clang_constructUSR_ObjCProperty(I[1], x));
|
||||
}
|
||||
|
|
|
@ -49,6 +49,15 @@ using namespace clang;
|
|||
using namespace clang::cxcursor;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
|
||||
if (!TU)
|
||||
return 0;
|
||||
CXTranslationUnit D = new CXTranslationUnitImpl();
|
||||
D->TUData = TU;
|
||||
D->StringPool = createCXStringPool();
|
||||
return D;
|
||||
}
|
||||
|
||||
/// \brief The result of comparing two source ranges.
|
||||
enum RangeComparisonResult {
|
||||
/// \brief Either the ranges overlap or one of the ranges is invalid.
|
||||
|
@ -149,7 +158,8 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
|||
public StmtVisitor<CursorVisitor, bool>
|
||||
{
|
||||
/// \brief The translation unit we are traversing.
|
||||
ASTUnit *TU;
|
||||
CXTranslationUnit TU;
|
||||
ASTUnit *AU;
|
||||
|
||||
/// \brief The parent cursor whose children we are traversing.
|
||||
CXCursor Parent;
|
||||
|
@ -214,10 +224,12 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
|||
};
|
||||
|
||||
public:
|
||||
CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData,
|
||||
CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
|
||||
CXClientData ClientData,
|
||||
unsigned MaxPCHLevel,
|
||||
SourceRange RegionOfInterest = SourceRange())
|
||||
: TU(TU), Visitor(Visitor), ClientData(ClientData),
|
||||
: TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
|
||||
Visitor(Visitor), ClientData(ClientData),
|
||||
MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest),
|
||||
DI_current(0)
|
||||
{
|
||||
|
@ -236,7 +248,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
ASTUnit *getASTUnit() const { return TU; }
|
||||
ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
|
||||
CXTranslationUnit getTU() const { return TU; }
|
||||
|
||||
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
|
||||
|
||||
|
@ -350,7 +363,7 @@ public:
|
|||
static SourceRange getRawCursorExtent(CXCursor C);
|
||||
|
||||
RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
|
||||
return RangeCompare(TU->getSourceManager(), R, RegionOfInterest);
|
||||
return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
|
||||
}
|
||||
|
||||
/// \brief Visit the given cursor and, if requested by the visitor,
|
||||
|
@ -402,10 +415,10 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
|
|||
std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
|
||||
CursorVisitor::getPreprocessedEntities() {
|
||||
PreprocessingRecord &PPRec
|
||||
= *TU->getPreprocessor().getPreprocessingRecord();
|
||||
= *AU->getPreprocessor().getPreprocessingRecord();
|
||||
|
||||
bool OnlyLocalDecls
|
||||
= !TU->isMainFileAST() && TU->getOnlyLocalDecls();
|
||||
= !AU->isMainFileAST() && AU->getOnlyLocalDecls();
|
||||
|
||||
// There is no region of interest; we have to walk everything.
|
||||
if (RegionOfInterest.isInvalid())
|
||||
|
@ -413,7 +426,7 @@ CursorVisitor::getPreprocessedEntities() {
|
|||
PPRec.end(OnlyLocalDecls));
|
||||
|
||||
// Find the file in which the region of interest lands.
|
||||
SourceManager &SM = TU->getSourceManager();
|
||||
SourceManager &SM = AU->getSourceManager();
|
||||
std::pair<FileID, unsigned> Begin
|
||||
= SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
|
||||
std::pair<FileID, unsigned> End
|
||||
|
@ -425,7 +438,7 @@ CursorVisitor::getPreprocessedEntities() {
|
|||
PPRec.end(OnlyLocalDecls));
|
||||
|
||||
ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
|
||||
= TU->getPreprocessedEntitiesByFile();
|
||||
= AU->getPreprocessedEntitiesByFile();
|
||||
if (ByFileMap.empty()) {
|
||||
// Build the mapping from files to sets of preprocessed entities.
|
||||
for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls),
|
||||
|
@ -442,7 +455,7 @@ CursorVisitor::getPreprocessedEntities() {
|
|||
}
|
||||
|
||||
/// \brief Visit the children of the given cursor.
|
||||
///
|
||||
///
|
||||
/// \returns true if the visitation should be aborted, false if it
|
||||
/// should continue.
|
||||
bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
||||
|
@ -467,13 +480,14 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
|||
return Visit(getCursorExpr(Cursor));
|
||||
|
||||
if (clang_isTranslationUnit(Cursor.kind)) {
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(Cursor);
|
||||
CXTranslationUnit tu = getCursorTU(Cursor);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
|
||||
if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
|
||||
RegionOfInterest.isInvalid()) {
|
||||
for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
|
||||
TLEnd = CXXUnit->top_level_end();
|
||||
TL != TLEnd; ++TL) {
|
||||
if (Visit(MakeCXCursor(*TL, CXXUnit), true))
|
||||
if (Visit(MakeCXCursor(*TL, tu), true))
|
||||
return true;
|
||||
}
|
||||
} else if (VisitDeclContext(
|
||||
|
@ -487,21 +501,21 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
|||
PreprocessingRecord::iterator E, EEnd;
|
||||
for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
|
||||
if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
|
||||
if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit)))
|
||||
if (Visit(MakeMacroInstantiationCursor(MI, tu)))
|
||||
return true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
|
||||
if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit)))
|
||||
if (Visit(MakeMacroDefinitionCursor(MD, tu)))
|
||||
return true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
|
||||
if (Visit(MakeInclusionDirectiveCursor(ID, CXXUnit)))
|
||||
if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
|
||||
return true;
|
||||
|
||||
continue;
|
||||
|
@ -859,7 +873,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
|
|||
// for later processing.
|
||||
llvm::SmallVector<Decl *, 24> DeclsInContainer;
|
||||
SourceLocation EndLoc = D->getSourceRange().getEnd();
|
||||
SourceManager &SM = TU->getSourceManager();
|
||||
SourceManager &SM = AU->getSourceManager();
|
||||
if (EndLoc.isValid()) {
|
||||
DeclContext::decl_iterator next = *DI_current;
|
||||
while (++next != DE_current) {
|
||||
|
@ -1243,7 +1257,7 @@ bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
|
|||
}
|
||||
|
||||
bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
|
||||
ASTContext &Context = TU->getASTContext();
|
||||
ASTContext &Context = AU->getASTContext();
|
||||
|
||||
// Some builtin types (such as Objective-C's "id", "sel", and
|
||||
// "Class") have associated declarations. Create cursors for those.
|
||||
|
@ -2098,9 +2112,10 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
|
|||
FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
|
||||
|
||||
llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
|
||||
return ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
|
||||
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
|
||||
CXXIdx->getOnlyLocalDecls(),
|
||||
0, 0, true);
|
||||
return MakeCXTranslationUnit(TU);
|
||||
}
|
||||
|
||||
unsigned clang_defaultEditingTranslationUnitOptions() {
|
||||
|
@ -2242,7 +2257,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
|
|||
}
|
||||
}
|
||||
|
||||
PTUI->result = Unit.take();
|
||||
PTUI->result = MakeCXTranslationUnit(Unit.take());
|
||||
}
|
||||
CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
|
||||
const char *source_filename,
|
||||
|
@ -2292,17 +2307,19 @@ int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
|
|||
if (!TU)
|
||||
return 1;
|
||||
|
||||
return static_cast<ASTUnit *>(TU)->Save(FileName);
|
||||
return static_cast<ASTUnit *>(TU->TUData)->Save(FileName);
|
||||
}
|
||||
|
||||
void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
|
||||
if (CTUnit) {
|
||||
// If the translation unit has been marked as unsafe to free, just discard
|
||||
// it.
|
||||
if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree())
|
||||
if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
|
||||
return;
|
||||
|
||||
delete static_cast<ASTUnit *>(CTUnit);
|
||||
delete static_cast<ASTUnit *>(CTUnit->TUData);
|
||||
disposeCXStringPool(CTUnit->StringPool);
|
||||
delete CTUnit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2331,7 +2348,7 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
|
|||
if (!TU)
|
||||
return;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
|
||||
llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
|
||||
|
@ -2357,7 +2374,7 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
|
|||
|
||||
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
|
||||
fprintf(stderr, "libclang: crash detected during reparsing\n");
|
||||
static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
|
||||
static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2370,7 +2387,7 @@ CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
|
|||
if (!CTUnit)
|
||||
return createCXString("");
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
|
||||
return createCXString(CXXUnit->getOriginalSourceFileName(), true);
|
||||
}
|
||||
|
||||
|
@ -2404,7 +2421,7 @@ CXSourceLocation clang_getLocation(CXTranslationUnit tu,
|
|||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
SourceLocation SLoc
|
||||
= CXXUnit->getSourceManager().getLocation(
|
||||
static_cast<const FileEntry *>(file),
|
||||
|
@ -2420,7 +2437,7 @@ CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
|
|||
if (!tu || !file)
|
||||
return clang_getNullLocation();
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
SourceLocation Start
|
||||
= CXXUnit->getSourceManager().getLocation(
|
||||
static_cast<const FileEntry *>(file),
|
||||
|
@ -2548,7 +2565,7 @@ CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
|
|||
extern "C" {
|
||||
CXString clang_getFileName(CXFile SFile) {
|
||||
if (!SFile)
|
||||
return createCXString(NULL);
|
||||
return createCXString((const char*)NULL);
|
||||
|
||||
FileEntry *FEnt = static_cast<FileEntry *>(SFile);
|
||||
return createCXString(FEnt->getName());
|
||||
|
@ -2566,7 +2583,7 @@ CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
|
|||
if (!tu)
|
||||
return 0;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
|
||||
|
||||
FileManager &FMgr = CXXUnit->getFileManager();
|
||||
const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name),
|
||||
|
@ -2628,10 +2645,8 @@ extern "C" {
|
|||
unsigned clang_visitChildren(CXCursor parent,
|
||||
CXCursorVisitor visitor,
|
||||
CXClientData client_data) {
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(parent);
|
||||
|
||||
CursorVisitor CursorVis(CXXUnit, visitor, client_data,
|
||||
CXXUnit->getMaxPCHLevel());
|
||||
CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
|
||||
getCursorASTUnit(parent)->getMaxPCHLevel());
|
||||
return CursorVis.VisitChildren(parent);
|
||||
}
|
||||
|
||||
|
@ -2698,7 +2713,8 @@ static CXString getDeclSpelling(Decl *D) {
|
|||
|
||||
CXString clang_getCursorSpelling(CXCursor C) {
|
||||
if (clang_isTranslationUnit(C.kind))
|
||||
return clang_getTranslationUnitSpelling(C.data[2]);
|
||||
return clang_getTranslationUnitSpelling(
|
||||
static_cast<CXTranslationUnit>(C.data[2]));
|
||||
|
||||
if (clang_isReference(C.kind)) {
|
||||
switch (C.kind) {
|
||||
|
@ -3028,7 +3044,7 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
|
|||
}
|
||||
|
||||
llvm_unreachable("Unhandled CXCursorKind");
|
||||
return createCXString(NULL);
|
||||
return createCXString((const char*) 0);
|
||||
}
|
||||
|
||||
enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
|
||||
|
@ -3052,7 +3068,7 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
|
|||
if (!TU)
|
||||
return clang_getNullCursor();
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
|
||||
|
||||
// Translate the given source location to make it point at the beginning of
|
||||
|
@ -3073,8 +3089,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
|
|||
// FIXME: Would be great to have a "hint" cursor, then walk from that
|
||||
// hint cursor upward until we find a cursor whose source range encloses
|
||||
// the region of interest, rather than starting from the translation unit.
|
||||
CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit);
|
||||
CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result,
|
||||
CXCursor Parent = clang_getTranslationUnitCursor(TU);
|
||||
CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
|
||||
Decl::MaxPCHLevel, SourceLocation(SLoc));
|
||||
CursorVis.VisitChildren(Parent);
|
||||
}
|
||||
|
@ -3366,16 +3382,16 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
|
|||
if (clang_isInvalid(C.kind))
|
||||
return clang_getNullCursor();
|
||||
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(C);
|
||||
CXTranslationUnit tu = getCursorTU(C);
|
||||
if (clang_isDeclaration(C.kind)) {
|
||||
Decl *D = getCursorDecl(C);
|
||||
if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
|
||||
return MakeCursorOverloadedDeclRef(Using, D->getLocation(), CXXUnit);
|
||||
return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
|
||||
if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
|
||||
return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), CXXUnit);
|
||||
return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu);
|
||||
if (ObjCForwardProtocolDecl *Protocols
|
||||
= dyn_cast<ObjCForwardProtocolDecl>(D))
|
||||
return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), CXXUnit);
|
||||
return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
|
||||
|
||||
return C;
|
||||
}
|
||||
|
@ -3384,10 +3400,10 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
|
|||
Expr *E = getCursorExpr(C);
|
||||
Decl *D = getDeclFromExpr(E);
|
||||
if (D)
|
||||
return MakeCXCursor(D, CXXUnit);
|
||||
return MakeCXCursor(D, tu);
|
||||
|
||||
if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
|
||||
return MakeCursorOverloadedDeclRef(Ovl, CXXUnit);
|
||||
return MakeCursorOverloadedDeclRef(Ovl, tu);
|
||||
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
@ -3395,15 +3411,14 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
|
|||
if (clang_isStatement(C.kind)) {
|
||||
Stmt *S = getCursorStmt(C);
|
||||
if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
|
||||
return MakeCXCursor(Goto->getLabel(), getCursorDecl(C),
|
||||
getCursorASTUnit(C));
|
||||
return MakeCXCursor(Goto->getLabel(), getCursorDecl(C), tu);
|
||||
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
if (C.kind == CXCursor_MacroInstantiation) {
|
||||
if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition())
|
||||
return MakeMacroDefinitionCursor(Def, CXXUnit);
|
||||
return MakeMacroDefinitionCursor(Def, tu);
|
||||
}
|
||||
|
||||
if (!clang_isReference(C.kind))
|
||||
|
@ -3411,38 +3426,39 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
|
|||
|
||||
switch (C.kind) {
|
||||
case CXCursor_ObjCSuperClassRef:
|
||||
return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
|
||||
|
||||
case CXCursor_ObjCProtocolRef: {
|
||||
return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
|
||||
|
||||
case CXCursor_ObjCClassRef:
|
||||
return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
|
||||
|
||||
case CXCursor_TypeRef:
|
||||
return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorTypeRef(C).first, tu );
|
||||
|
||||
case CXCursor_TemplateRef:
|
||||
return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorTemplateRef(C).first, tu );
|
||||
|
||||
case CXCursor_NamespaceRef:
|
||||
return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
|
||||
|
||||
case CXCursor_MemberRef:
|
||||
return MakeCXCursor(getCursorMemberRef(C).first, CXXUnit);
|
||||
return MakeCXCursor(getCursorMemberRef(C).first, tu );
|
||||
|
||||
case CXCursor_CXXBaseSpecifier: {
|
||||
CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
|
||||
return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
|
||||
CXXUnit));
|
||||
tu ));
|
||||
}
|
||||
|
||||
case CXCursor_LabelRef:
|
||||
// FIXME: We end up faking the "parent" declaration here because we
|
||||
// don't want to make CXCursor larger.
|
||||
return MakeCXCursor(getCursorLabelRef(C).first,
|
||||
CXXUnit->getASTContext().getTranslationUnitDecl(),
|
||||
CXXUnit);
|
||||
static_cast<ASTUnit*>(tu->TUData)->getASTContext()
|
||||
.getTranslationUnitDecl(),
|
||||
tu);
|
||||
|
||||
case CXCursor_OverloadedDeclRef:
|
||||
return C;
|
||||
|
@ -3461,7 +3477,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
if (clang_isInvalid(C.kind))
|
||||
return clang_getNullCursor();
|
||||
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(C);
|
||||
CXTranslationUnit TU = getCursorTU(C);
|
||||
|
||||
bool WasReference = false;
|
||||
if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
|
||||
|
@ -3515,10 +3531,10 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
|
||||
case Decl::UsingDirective:
|
||||
return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
|
||||
CXXUnit);
|
||||
TU);
|
||||
|
||||
case Decl::NamespaceAlias:
|
||||
return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit);
|
||||
return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
|
||||
|
||||
case Decl::Enum:
|
||||
case Decl::Record:
|
||||
|
@ -3526,7 +3542,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
case Decl::ClassTemplateSpecialization:
|
||||
case Decl::ClassTemplatePartialSpecialization:
|
||||
if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
|
||||
return MakeCXCursor(Def, CXXUnit);
|
||||
return MakeCXCursor(Def, TU);
|
||||
return clang_getNullCursor();
|
||||
|
||||
case Decl::Function:
|
||||
|
@ -3536,21 +3552,21 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
case Decl::CXXConversion: {
|
||||
const FunctionDecl *Def = 0;
|
||||
if (cast<FunctionDecl>(D)->getBody(Def))
|
||||
return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit);
|
||||
return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
case Decl::Var: {
|
||||
// Ask the variable if it has a definition.
|
||||
if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
|
||||
return MakeCXCursor(Def, CXXUnit);
|
||||
return MakeCXCursor(Def, TU);
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
case Decl::FunctionTemplate: {
|
||||
const FunctionDecl *Def = 0;
|
||||
if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
|
||||
return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit);
|
||||
return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
|
@ -3558,18 +3574,18 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
|
||||
->getDefinition())
|
||||
return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
|
||||
CXXUnit);
|
||||
TU);
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
case Decl::Using:
|
||||
return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
|
||||
D->getLocation(), CXXUnit);
|
||||
D->getLocation(), TU);
|
||||
|
||||
case Decl::UsingShadow:
|
||||
return clang_getCursorDefinition(
|
||||
MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
|
||||
CXXUnit));
|
||||
TU));
|
||||
|
||||
case Decl::ObjCMethod: {
|
||||
ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
|
||||
|
@ -3585,7 +3601,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
|
||||
Method->isInstanceMethod()))
|
||||
if (Def->isThisDeclarationADefinition())
|
||||
return MakeCXCursor(Def, CXXUnit);
|
||||
return MakeCXCursor(Def, TU);
|
||||
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
@ -3593,7 +3609,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
case Decl::ObjCCategory:
|
||||
if (ObjCCategoryImplDecl *Impl
|
||||
= cast<ObjCCategoryDecl>(D)->getImplementation())
|
||||
return MakeCXCursor(Impl, CXXUnit);
|
||||
return MakeCXCursor(Impl, TU);
|
||||
return clang_getNullCursor();
|
||||
|
||||
case Decl::ObjCProtocol:
|
||||
|
@ -3612,7 +3628,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
return C;
|
||||
} else if (ObjCImplementationDecl *Impl
|
||||
= cast<ObjCInterfaceDecl>(D)->getImplementation())
|
||||
return MakeCXCursor(Impl, CXXUnit);
|
||||
return MakeCXCursor(Impl, TU);
|
||||
return clang_getNullCursor();
|
||||
|
||||
case Decl::ObjCProperty:
|
||||
|
@ -3624,26 +3640,26 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
|||
if (ObjCInterfaceDecl *Class
|
||||
= cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
|
||||
if (!Class->isForwardDecl())
|
||||
return MakeCXCursor(Class, CXXUnit);
|
||||
return MakeCXCursor(Class, TU);
|
||||
|
||||
return clang_getNullCursor();
|
||||
|
||||
case Decl::ObjCForwardProtocol:
|
||||
return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D),
|
||||
D->getLocation(), CXXUnit);
|
||||
D->getLocation(), TU);
|
||||
|
||||
case Decl::ObjCClass:
|
||||
return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(),
|
||||
CXXUnit);
|
||||
TU);
|
||||
|
||||
case Decl::Friend:
|
||||
if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
|
||||
return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
|
||||
return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
|
||||
return clang_getNullCursor();
|
||||
|
||||
case Decl::FriendTemplate:
|
||||
if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
|
||||
return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit));
|
||||
return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
|
@ -3687,28 +3703,28 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
|
|||
if (index >= clang_getNumOverloadedDecls(cursor))
|
||||
return clang_getNullCursor();
|
||||
|
||||
ASTUnit *Unit = getCursorASTUnit(cursor);
|
||||
CXTranslationUnit TU = getCursorTU(cursor);
|
||||
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
|
||||
if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
|
||||
return MakeCXCursor(E->decls_begin()[index], Unit);
|
||||
return MakeCXCursor(E->decls_begin()[index], TU);
|
||||
|
||||
if (OverloadedTemplateStorage *S
|
||||
= Storage.dyn_cast<OverloadedTemplateStorage*>())
|
||||
return MakeCXCursor(S->begin()[index], Unit);
|
||||
return MakeCXCursor(S->begin()[index], TU);
|
||||
|
||||
Decl *D = Storage.get<Decl*>();
|
||||
if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
|
||||
// FIXME: This is, unfortunately, linear time.
|
||||
UsingDecl::shadow_iterator Pos = Using->shadow_begin();
|
||||
std::advance(Pos, index);
|
||||
return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), Unit);
|
||||
return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
|
||||
}
|
||||
|
||||
if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
|
||||
return MakeCXCursor(Classes->begin()[index].getInterface(), Unit);
|
||||
return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
|
||||
|
||||
if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
|
||||
return MakeCXCursor(Protocols->protocol_begin()[index], Unit);
|
||||
return MakeCXCursor(Protocols->protocol_begin()[index], TU);
|
||||
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
@ -3784,7 +3800,7 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
|
|||
|
||||
// We have to find the starting buffer pointer the hard way, by
|
||||
// deconstructing the source location.
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return createCXString("");
|
||||
|
||||
|
@ -3801,7 +3817,7 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
|
|||
}
|
||||
|
||||
CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return clang_getNullLocation();
|
||||
|
||||
|
@ -3810,7 +3826,7 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
|
|||
}
|
||||
|
||||
CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return clang_getNullRange();
|
||||
|
||||
|
@ -3825,7 +3841,7 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
|
|||
if (NumTokens)
|
||||
*NumTokens = 0;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit || !Tokens || !NumTokens)
|
||||
return;
|
||||
|
||||
|
@ -3958,18 +3974,19 @@ class AnnotateTokensWorker {
|
|||
public:
|
||||
AnnotateTokensWorker(AnnotateTokensData &annotated,
|
||||
CXToken *tokens, CXCursor *cursors, unsigned numTokens,
|
||||
ASTUnit *CXXUnit, SourceRange RegionOfInterest)
|
||||
CXTranslationUnit tu, SourceRange RegionOfInterest)
|
||||
: Annotated(annotated), Tokens(tokens), Cursors(cursors),
|
||||
NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
|
||||
AnnotateVis(CXXUnit, AnnotateTokensVisitor, this,
|
||||
AnnotateVis(tu,
|
||||
AnnotateTokensVisitor, this,
|
||||
Decl::MaxPCHLevel, RegionOfInterest),
|
||||
SrcMgr(CXXUnit->getSourceManager()) {}
|
||||
SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()) {}
|
||||
|
||||
void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
|
||||
enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
|
||||
void AnnotateTokens(CXCursor parent);
|
||||
void AnnotateTokens() {
|
||||
AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getASTUnit()));
|
||||
AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -4194,7 +4211,7 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
for (unsigned I = 0; I != NumTokens; ++I)
|
||||
Cursors[I] = C;
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!CXXUnit)
|
||||
return;
|
||||
|
||||
|
@ -4256,7 +4273,7 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
CXCursor Cursor
|
||||
= MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
|
||||
Locations.back()),
|
||||
CXXUnit);
|
||||
TU);
|
||||
for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
|
||||
Annotated[Locations[I].getRawEncoding()] = Cursor;
|
||||
}
|
||||
|
@ -4275,7 +4292,7 @@ void clang_annotateTokens(CXTranslationUnit TU,
|
|||
// Annotate all of the source locations in the region of interest that map to
|
||||
// a specific cursor.
|
||||
AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
|
||||
CXXUnit, RegionOfInterest);
|
||||
TU, RegionOfInterest);
|
||||
|
||||
// Run the worker within a CrashRecoveryContext.
|
||||
// FIXME: We use a ridiculous stack size here because the data-recursion
|
||||
|
@ -4392,13 +4409,13 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
|
|||
if (clang_isDeclaration(cursor.kind)) {
|
||||
if (Decl *D = getCursorDecl(cursor)) {
|
||||
DeclContext *DC = D->getDeclContext();
|
||||
return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor));
|
||||
return MakeCXCursor(cast<Decl>(DC), getCursorTU(cursor));
|
||||
}
|
||||
}
|
||||
|
||||
if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
|
||||
if (Decl *D = getCursorDecl(cursor))
|
||||
return MakeCXCursor(D, getCursorASTUnit(cursor));
|
||||
return MakeCXCursor(D, getCursorTU(cursor));
|
||||
}
|
||||
|
||||
return clang_getNullCursor();
|
||||
|
@ -4408,7 +4425,7 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
|
|||
if (clang_isDeclaration(cursor.kind)) {
|
||||
if (Decl *D = getCursorDecl(cursor)) {
|
||||
DeclContext *DC = D->getLexicalDeclContext();
|
||||
return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor));
|
||||
return MakeCXCursor(cast<Decl>(DC), getCursorTU(cursor));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4491,7 +4508,7 @@ void clang_getOverriddenCursors(CXCursor cursor,
|
|||
return;
|
||||
|
||||
// Handle C++ member functions.
|
||||
ASTUnit *CXXUnit = getCursorASTUnit(cursor);
|
||||
CXTranslationUnit TU = getCursorTU(cursor);
|
||||
if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
|
||||
*num_overridden = CXXMethod->size_overridden_methods();
|
||||
if (!*num_overridden)
|
||||
|
@ -4503,7 +4520,7 @@ void clang_getOverriddenCursors(CXCursor cursor,
|
|||
M = CXXMethod->begin_overridden_methods(),
|
||||
MEnd = CXXMethod->end_overridden_methods();
|
||||
M != MEnd; (void)++M, ++I)
|
||||
(*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), CXXUnit);
|
||||
(*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4521,7 +4538,7 @@ void clang_getOverriddenCursors(CXCursor cursor,
|
|||
*num_overridden = Methods.size();
|
||||
*overridden = new CXCursor [Methods.size()];
|
||||
for (unsigned I = 0, N = Methods.size(); I != N; ++I)
|
||||
(*overridden)[I] = MakeCXCursor(Methods[I], CXXUnit);
|
||||
(*overridden)[I] = MakeCXCursor(Methods[I], TU);
|
||||
}
|
||||
|
||||
void clang_disposeOverriddenCursors(CXCursor *overridden) {
|
||||
|
@ -4566,12 +4583,12 @@ unsigned clang_CXXMethod_isStatic(CXCursor C) {
|
|||
extern "C" {
|
||||
CXType clang_getIBOutletCollectionType(CXCursor C) {
|
||||
if (C.kind != CXCursor_IBOutletCollectionAttr)
|
||||
return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
|
||||
return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
|
||||
|
||||
IBOutletCollectionAttr *A =
|
||||
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
|
||||
|
||||
return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C));
|
||||
return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
|
||||
}
|
||||
} // end: extern "C"
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
|
|||
if (TemplateDecl *Template
|
||||
= dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
|
||||
return MakeCXCursor(Template->getTemplatedDecl(),
|
||||
getCursorASTUnit(C)).kind;
|
||||
static_cast<CXTranslationUnit>(C.data[2])).kind;
|
||||
break;
|
||||
|
||||
case CXCursor_ClassTemplatePartialSpecialization:
|
||||
|
@ -117,7 +117,7 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
|
|||
if (!Template)
|
||||
return clang_getNullCursor();
|
||||
|
||||
return MakeCXCursor(Template, getCursorASTUnit(C));
|
||||
return MakeCXCursor(Template, static_cast<CXTranslationUnit>(C.data[2]));
|
||||
}
|
||||
|
||||
} // end extern "C"
|
||||
|
|
|
@ -125,7 +125,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
|||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return createCXString(0);
|
||||
return createCXString((const char*)0);
|
||||
|
||||
switch ((*CCStr)[chunk_number].Kind) {
|
||||
case CodeCompletionString::CK_TypedText:
|
||||
|
@ -156,7 +156,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
|||
}
|
||||
|
||||
// Should be unreachable, but let's be careful.
|
||||
return createCXString(0);
|
||||
return createCXString((const char*)0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -355,7 +355,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
|
|||
|
||||
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
|
||||
|
||||
ASTUnit *AST = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *AST = static_cast<ASTUnit *>(TU->TUData);
|
||||
if (!AST)
|
||||
return;
|
||||
|
||||
|
@ -483,7 +483,7 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
|
|||
|
||||
if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
|
||||
fprintf(stderr, "libclang: crash detected in code completion\n");
|
||||
static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
|
||||
static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,12 +33,12 @@ using namespace llvm;
|
|||
extern "C" {
|
||||
|
||||
unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit->TUData);
|
||||
return CXXUnit? CXXUnit->stored_diag_size() : 0;
|
||||
}
|
||||
|
||||
CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit->TUData);
|
||||
if (!CXXUnit || Index >= CXXUnit->stored_diag_size())
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
|
||||
CXClientData clientData) {
|
||||
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU);
|
||||
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
|
||||
SourceManager &SM = CXXUnit->getSourceManager();
|
||||
ASTContext &Ctx = CXXUnit->getASTContext();
|
||||
|
||||
|
|
|
@ -45,13 +45,14 @@ static CXCursorKind GetCursorKind(const Attr *A) {
|
|||
return CXCursor_UnexposedAttr;
|
||||
}
|
||||
|
||||
CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) {
|
||||
CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
|
||||
CXTranslationUnit TU) {
|
||||
assert(A && Parent && TU && "Invalid arguments!");
|
||||
CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } };
|
||||
return C;
|
||||
}
|
||||
|
||||
CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU,
|
||||
CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
|
||||
bool FirstInDeclGroup) {
|
||||
assert(D && TU && "Invalid arguments!");
|
||||
CXCursor C = { getCursorKindForDecl(D),
|
||||
|
@ -60,7 +61,8 @@ CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU,
|
|||
return C;
|
||||
}
|
||||
|
||||
CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) {
|
||||
CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
|
||||
CXTranslationUnit TU) {
|
||||
assert(S && TU && "Invalid arguments!");
|
||||
CXCursorKind K = CXCursor_NotImplemented;
|
||||
|
||||
|
@ -201,7 +203,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) {
|
|||
|
||||
CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(Super && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } };
|
||||
|
@ -218,7 +220,7 @@ cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
|
|||
|
||||
CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(Super && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } };
|
||||
|
@ -235,7 +237,7 @@ cxcursor::getCursorObjCProtocolRef(CXCursor C) {
|
|||
|
||||
CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
// 'Class' can be null for invalid code.
|
||||
if (!Class)
|
||||
return MakeCXCursorInvalid(CXCursor_InvalidCode);
|
||||
|
@ -254,7 +256,7 @@ cxcursor::getCursorObjCClassRef(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(Type && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } };
|
||||
|
@ -270,7 +272,8 @@ cxcursor::getCursorTypeRef(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template,
|
||||
SourceLocation Loc, ASTUnit *TU) {
|
||||
SourceLocation Loc,
|
||||
CXTranslationUnit TU) {
|
||||
assert(Template && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } };
|
||||
|
@ -286,7 +289,7 @@ cxcursor::getCursorTemplateRef(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
|
||||
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
|
||||
"Invalid arguments!");
|
||||
|
@ -304,7 +307,7 @@ cxcursor::getCursorNamespaceRef(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
|
||||
assert(Field && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
|
@ -320,7 +323,8 @@ cxcursor::getCursorMemberRef(CXCursor C) {
|
|||
reinterpret_cast<uintptr_t>(C.data[1])));
|
||||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){
|
||||
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
|
||||
CXTranslationUnit TU){
|
||||
CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
|
||||
return C;
|
||||
}
|
||||
|
@ -331,7 +335,7 @@ CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
CXCursor C = { CXCursor_PreprocessingDirective,
|
||||
{ reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
|
||||
reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
|
||||
|
@ -348,7 +352,8 @@ SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
|
|||
reinterpret_cast<uintptr_t> (C.data[1])));
|
||||
}
|
||||
|
||||
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI, ASTUnit *TU) {
|
||||
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
|
||||
CXTranslationUnit TU) {
|
||||
CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } };
|
||||
return C;
|
||||
}
|
||||
|
@ -359,7 +364,7 @@ MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } };
|
||||
return C;
|
||||
}
|
||||
|
@ -370,7 +375,7 @@ MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
CXCursor C = { CXCursor_InclusionDirective, { ID, 0, TU } };
|
||||
return C;
|
||||
}
|
||||
|
@ -381,7 +386,7 @@ InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
|
||||
assert(Label && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
|
@ -398,7 +403,7 @@ cxcursor::getCursorLabelRef(CXCursor C) {
|
|||
}
|
||||
|
||||
CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(E && TU && "Invalid arguments!");
|
||||
OverloadedDeclRefStorage Storage(E);
|
||||
void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
|
||||
|
@ -411,7 +416,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
|
|||
|
||||
CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(D && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
OverloadedDeclRefStorage Storage(D);
|
||||
|
@ -424,7 +429,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
|
|||
|
||||
CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU) {
|
||||
CXTranslationUnit TU) {
|
||||
assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
|
||||
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
||||
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
|
||||
|
@ -469,7 +474,12 @@ ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
|
|||
}
|
||||
|
||||
ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
|
||||
return static_cast<ASTUnit *>(Cursor.data[2]);
|
||||
return static_cast<ASTUnit *>(static_cast<CXTranslationUnit>(Cursor.data[2])
|
||||
->TUData);
|
||||
}
|
||||
|
||||
CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
|
||||
return static_cast<CXTranslationUnit>(Cursor.data[2]);
|
||||
}
|
||||
|
||||
bool cxcursor::operator==(CXCursor X, CXCursor Y) {
|
||||
|
|
|
@ -44,16 +44,18 @@ class TypeDecl;
|
|||
|
||||
namespace cxcursor {
|
||||
|
||||
CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU);
|
||||
CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU,
|
||||
CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent,
|
||||
CXTranslationUnit TU);
|
||||
CXCursor MakeCXCursor(clang::Decl *D, CXTranslationUnit TU,
|
||||
bool FirstInDeclGroup = true);
|
||||
CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU);
|
||||
CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent,
|
||||
CXTranslationUnit TU);
|
||||
CXCursor MakeCXCursorInvalid(CXCursorKind K);
|
||||
|
||||
/// \brief Create an Objective-C superclass reference at the given location.
|
||||
CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
|
||||
SourceLocation Loc,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
|
||||
/// and optionally the location where the reference occurred.
|
||||
|
@ -62,7 +64,7 @@ std::pair<ObjCInterfaceDecl *, SourceLocation>
|
|||
|
||||
/// \brief Create an Objective-C protocol reference at the given location.
|
||||
CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
|
||||
/// and optionally the location where the reference occurred.
|
||||
|
@ -71,7 +73,7 @@ std::pair<ObjCProtocolDecl *, SourceLocation>
|
|||
|
||||
/// \brief Create an Objective-C class reference at the given location.
|
||||
CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack an ObjCClassRef cursor into the class it references
|
||||
/// and optionally the location where the reference occurred.
|
||||
|
@ -79,7 +81,8 @@ std::pair<ObjCInterfaceDecl *, SourceLocation>
|
|||
getCursorObjCClassRef(CXCursor C);
|
||||
|
||||
/// \brief Create a type reference at the given location.
|
||||
CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU);
|
||||
CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a TypeRef cursor into the class it references
|
||||
/// and optionally the location where the reference occurred.
|
||||
|
@ -87,7 +90,7 @@ std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
|
|||
|
||||
/// \brief Create a reference to a template at the given location.
|
||||
CXCursor MakeCursorTemplateRef(TemplateDecl *Template, SourceLocation Loc,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a TemplateRef cursor into the template it references and
|
||||
/// the location where the reference occurred.
|
||||
|
@ -95,7 +98,8 @@ std::pair<TemplateDecl *, SourceLocation> getCursorTemplateRef(CXCursor C);
|
|||
|
||||
/// \brief Create a reference to a namespace or namespace alias at the given
|
||||
/// location.
|
||||
CXCursor MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, ASTUnit *TU);
|
||||
CXCursor MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias
|
||||
/// it references and the location where the reference occurred.
|
||||
|
@ -103,62 +107,68 @@ std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
|
|||
|
||||
/// \brief Create a reference to a field at the given location.
|
||||
CXCursor MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a MemberRef cursor into the field it references and the
|
||||
/// location where the reference occurred.
|
||||
std::pair<FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
|
||||
|
||||
/// \brief Create a CXX base specifier cursor.
|
||||
CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);
|
||||
CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
|
||||
CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
|
||||
|
||||
/// \brief Create a preprocessing directive cursor.
|
||||
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, ASTUnit *TU);
|
||||
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a given preprocessing directive to retrieve its source range.
|
||||
SourceRange getCursorPreprocessingDirective(CXCursor C);
|
||||
|
||||
/// \brief Create a macro definition cursor.
|
||||
CXCursor MakeMacroDefinitionCursor(MacroDefinition *, ASTUnit *TU);
|
||||
CXCursor MakeMacroDefinitionCursor(MacroDefinition *, CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a given macro definition cursor to retrieve its
|
||||
/// source range.
|
||||
MacroDefinition *getCursorMacroDefinition(CXCursor C);
|
||||
|
||||
/// \brief Create a macro instantiation cursor.
|
||||
CXCursor MakeMacroInstantiationCursor(MacroInstantiation *, ASTUnit *TU);
|
||||
CXCursor MakeMacroInstantiationCursor(MacroInstantiation *,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a given macro instantiation cursor to retrieve its
|
||||
/// source range.
|
||||
MacroInstantiation *getCursorMacroInstantiation(CXCursor C);
|
||||
|
||||
/// \brief Create an inclusion directive cursor.
|
||||
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *, ASTUnit *TU);
|
||||
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a given inclusion directive cursor to retrieve its
|
||||
/// source range.
|
||||
InclusionDirective *getCursorInclusionDirective(CXCursor C);
|
||||
|
||||
/// \brief Create a label reference at the given location.
|
||||
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc, ASTUnit *TU);
|
||||
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Unpack a label reference into the label statement it refers to and
|
||||
/// the location of the reference.
|
||||
std::pair<LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
|
||||
|
||||
/// \brief Create a overloaded declaration reference cursor for an expression.
|
||||
CXCursor MakeCursorOverloadedDeclRef(OverloadExpr *E, ASTUnit *TU);
|
||||
CXCursor MakeCursorOverloadedDeclRef(OverloadExpr *E, CXTranslationUnit TU);
|
||||
|
||||
/// \brief Create a overloaded declaration reference cursor for a declaration.
|
||||
CXCursor MakeCursorOverloadedDeclRef(Decl *D, SourceLocation Location,
|
||||
ASTUnit *TU);
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Create a overloaded declaration reference cursor for a template name.
|
||||
CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
|
||||
SourceLocation Location, ASTUnit *TU);
|
||||
SourceLocation Location,
|
||||
CXTranslationUnit TU);
|
||||
|
||||
/// \brief Internal storage for an overloaded declaration reference cursor;
|
||||
typedef llvm::PointerUnion3<OverloadExpr *, Decl *,
|
||||
|
@ -177,6 +187,7 @@ Attr *getCursorAttr(CXCursor Cursor);
|
|||
|
||||
ASTContext &getCursorContext(CXCursor Cursor);
|
||||
ASTUnit *getCursorASTUnit(CXCursor Cursor);
|
||||
CXTranslationUnit getCursorTU(CXCursor Cursor);
|
||||
|
||||
bool operator==(CXCursor X, CXCursor Y);
|
||||
|
||||
|
|
|
@ -16,20 +16,25 @@
|
|||
#include "CXString.h"
|
||||
#include "clang/Frontend/ASTUnit.h"
|
||||
#include "clang-c/Index.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
enum CXStringFlag { CXS_Unmanaged, CXS_Malloc };
|
||||
enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Basic generation of CXStrings.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
CXString cxstring::createCXString(const char *String, bool DupString){
|
||||
CXString Str;
|
||||
if (DupString) {
|
||||
Str.Spelling = strdup(String);
|
||||
Str.data = strdup(String);
|
||||
Str.private_flags = (unsigned) CXS_Malloc;
|
||||
} else {
|
||||
Str.Spelling = String;
|
||||
Str.data = (void*)String;
|
||||
Str.private_flags = (unsigned) CXS_Unmanaged;
|
||||
}
|
||||
return Str;
|
||||
|
@ -41,27 +46,84 @@ CXString cxstring::createCXString(llvm::StringRef String, bool DupString) {
|
|||
char *Spelling = (char *)malloc(String.size() + 1);
|
||||
memmove(Spelling, String.data(), String.size());
|
||||
Spelling[String.size()] = 0;
|
||||
Result.Spelling = Spelling;
|
||||
Result.data = Spelling;
|
||||
Result.private_flags = (unsigned) CXS_Malloc;
|
||||
} else {
|
||||
Result.Spelling = String.data();
|
||||
Result.data = (void*) String.data();
|
||||
Result.private_flags = (unsigned) CXS_Unmanaged;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
CXString cxstring::createCXString(CXStringBuf *buf) {
|
||||
CXString Str;
|
||||
Str.data = buf;
|
||||
Str.private_flags = (unsigned) CXS_StringBuf;
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// String pools.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
typedef std::vector<CXStringBuf *> CXStringPool;
|
||||
|
||||
void *cxstring::createCXStringPool() {
|
||||
return new CXStringPool();
|
||||
}
|
||||
|
||||
void cxstring::disposeCXStringPool(void *p) {
|
||||
CXStringPool *pool = static_cast<CXStringPool*>(p);
|
||||
if (pool) {
|
||||
for (CXStringPool::iterator I = pool->begin(), E = pool->end();
|
||||
I != E; ++I) {
|
||||
delete *I;
|
||||
}
|
||||
delete pool;
|
||||
}
|
||||
}
|
||||
|
||||
CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
|
||||
CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool);
|
||||
if (pool->empty())
|
||||
return new CXStringBuf(TU);
|
||||
CXStringBuf *buf = pool->back();
|
||||
buf->Data.clear();
|
||||
pool->pop_back();
|
||||
return buf;
|
||||
}
|
||||
|
||||
void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
|
||||
if (buf)
|
||||
static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// libClang public APIs.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extern "C" {
|
||||
const char *clang_getCString(CXString string) {
|
||||
return string.Spelling;
|
||||
if (string.private_flags == (unsigned) CXS_StringBuf) {
|
||||
return ((CXStringBuf*)string.data)->Data.data();
|
||||
}
|
||||
return (const char*) string.data;
|
||||
}
|
||||
|
||||
void clang_disposeString(CXString string) {
|
||||
if (string.private_flags == CXS_Malloc && string.Spelling)
|
||||
free((void*)string.Spelling);
|
||||
switch ((CXStringFlag) string.private_flags) {
|
||||
case CXS_Unmanaged:
|
||||
break;
|
||||
case CXS_Malloc:
|
||||
if (string.data)
|
||||
free((void*)string.data);
|
||||
break;
|
||||
case CXS_StringBuf:
|
||||
disposeCXStringBuf((CXStringBuf *) string.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // end: extern "C"
|
||||
|
||||
|
|
|
@ -16,15 +16,35 @@
|
|||
|
||||
#include "clang-c/Index.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
|
||||
namespace clang {
|
||||
namespace cxstring {
|
||||
|
||||
struct CXStringBuf {
|
||||
llvm::SmallString<128> Data;
|
||||
CXTranslationUnit TU;
|
||||
CXStringBuf(CXTranslationUnit tu) : TU(tu) {}
|
||||
};
|
||||
|
||||
/// \brief Create a CXString object from a C string.
|
||||
CXString createCXString(const char *String, bool DupString = false);
|
||||
|
||||
/// \brief Create a CXString ojbect from a StringRef.
|
||||
CXString createCXString(llvm::StringRef String, bool DupString = true);
|
||||
/// \brief Create a CXString object from a StringRef.
|
||||
CXString createCXString(llvm::StringRef String, bool DupString = true);
|
||||
|
||||
/// \brief Create a CXString object that is backed by a string buffer.
|
||||
CXString createCXString(CXStringBuf *buf);
|
||||
|
||||
/// \brief Create an opaque string pool used for fast geneneration of strings.
|
||||
void *createCXStringPool();
|
||||
|
||||
/// \brief Dispose of a string pool.
|
||||
void disposeCXStringPool(void *pool);
|
||||
|
||||
CXStringBuf *getCXStringBuf(CXTranslationUnit TU);
|
||||
|
||||
void disposeCXStringBuf(CXStringBuf *buf);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ static CXTypeKind GetTypeKind(QualType T) {
|
|||
}
|
||||
|
||||
|
||||
CXType cxtype::MakeCXType(QualType T, ASTUnit *TU) {
|
||||
CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
|
||||
CXTypeKind TK = GetTypeKind(T);
|
||||
CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
|
||||
return CT;
|
||||
|
@ -101,8 +101,8 @@ static inline QualType GetQualType(CXType CT) {
|
|||
return QualType::getFromOpaquePtr(CT.data[0]);
|
||||
}
|
||||
|
||||
static inline ASTUnit* GetASTU(CXType CT) {
|
||||
return static_cast<ASTUnit*>(CT.data[1]);
|
||||
static inline CXTranslationUnit GetTU(CXType CT) {
|
||||
return static_cast<CXTranslationUnit>(CT.data[1]);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@ -110,27 +110,26 @@ extern "C" {
|
|||
CXType clang_getCursorType(CXCursor C) {
|
||||
using namespace cxcursor;
|
||||
|
||||
ASTUnit *AU = cxcursor::getCursorASTUnit(C);
|
||||
|
||||
CXTranslationUnit TU = cxcursor::getCursorTU(C);
|
||||
if (clang_isExpression(C.kind)) {
|
||||
QualType T = cxcursor::getCursorExpr(C)->getType();
|
||||
return MakeCXType(T, AU);
|
||||
return MakeCXType(T, TU);
|
||||
}
|
||||
|
||||
if (clang_isDeclaration(C.kind)) {
|
||||
Decl *D = cxcursor::getCursorDecl(C);
|
||||
|
||||
if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
|
||||
return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU);
|
||||
return MakeCXType(QualType(TD->getTypeForDecl(), 0), TU);
|
||||
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
|
||||
return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU);
|
||||
return MakeCXType(QualType(ID->getTypeForDecl(), 0), TU);
|
||||
if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
|
||||
return MakeCXType(VD->getType(), AU);
|
||||
return MakeCXType(VD->getType(), TU);
|
||||
if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
|
||||
return MakeCXType(PD->getType(), AU);
|
||||
return MakeCXType(PD->getType(), TU);
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
||||
return MakeCXType(FD->getType(), AU);
|
||||
return MakeCXType(QualType(), AU);
|
||||
return MakeCXType(FD->getType(), TU);
|
||||
return MakeCXType(QualType(), TU);
|
||||
}
|
||||
|
||||
if (clang_isReference(C.kind)) {
|
||||
|
@ -139,21 +138,21 @@ CXType clang_getCursorType(CXCursor C) {
|
|||
return MakeCXType(
|
||||
QualType(getCursorObjCSuperClassRef(C).first->getTypeForDecl(),
|
||||
0),
|
||||
AU);
|
||||
TU);
|
||||
|
||||
case CXCursor_ObjCClassRef:
|
||||
return MakeCXType(
|
||||
QualType(getCursorObjCClassRef(C).first->getTypeForDecl(),
|
||||
0),
|
||||
AU);
|
||||
TU);
|
||||
|
||||
case CXCursor_TypeRef:
|
||||
return MakeCXType(QualType(getCursorTypeRef(C).first->getTypeForDecl(),
|
||||
0),
|
||||
AU);
|
||||
TU);
|
||||
|
||||
case CXCursor_CXXBaseSpecifier:
|
||||
return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), AU);
|
||||
return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
|
||||
|
||||
case CXCursor_ObjCProtocolRef:
|
||||
case CXCursor_TemplateRef:
|
||||
|
@ -164,10 +163,10 @@ CXType clang_getCursorType(CXCursor C) {
|
|||
break;
|
||||
}
|
||||
|
||||
return MakeCXType(QualType(), AU);
|
||||
return MakeCXType(QualType(), TU);
|
||||
}
|
||||
|
||||
return MakeCXType(QualType(), AU);
|
||||
return MakeCXType(QualType(), TU);
|
||||
}
|
||||
|
||||
CXType clang_getCanonicalType(CXType CT) {
|
||||
|
@ -175,12 +174,13 @@ CXType clang_getCanonicalType(CXType CT) {
|
|||
return CT;
|
||||
|
||||
QualType T = GetQualType(CT);
|
||||
CXTranslationUnit TU = GetTU(CT);
|
||||
|
||||
if (T.isNull())
|
||||
return MakeCXType(QualType(), GetASTU(CT));
|
||||
return MakeCXType(QualType(), GetTU(CT));
|
||||
|
||||
ASTUnit *AU = GetASTU(CT);
|
||||
return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
|
||||
ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
|
||||
return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
|
||||
}
|
||||
|
||||
CXType clang_getPointeeType(CXType CT) {
|
||||
|
@ -188,7 +188,7 @@ CXType clang_getPointeeType(CXType CT) {
|
|||
Type *TP = T.getTypePtr();
|
||||
|
||||
if (!TP)
|
||||
return MakeCXType(QualType(), GetASTU(CT));
|
||||
return MakeCXType(QualType(), GetTU(CT));
|
||||
|
||||
switch (TP->getTypeClass()) {
|
||||
case Type::Pointer:
|
||||
|
@ -208,7 +208,7 @@ CXType clang_getPointeeType(CXType CT) {
|
|||
T = QualType();
|
||||
break;
|
||||
}
|
||||
return MakeCXType(T, GetASTU(CT));
|
||||
return MakeCXType(T, GetTU(CT));
|
||||
}
|
||||
|
||||
CXCursor clang_getTypeDeclaration(CXType CT) {
|
||||
|
@ -263,7 +263,7 @@ try_again:
|
|||
if (!D)
|
||||
return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
|
||||
|
||||
return cxcursor::MakeCXCursor(D, GetASTU(CT));
|
||||
return cxcursor::MakeCXCursor(D, GetTU(CT));
|
||||
}
|
||||
|
||||
CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
|
||||
|
@ -324,24 +324,24 @@ unsigned clang_equalTypes(CXType A, CXType B) {
|
|||
CXType clang_getResultType(CXType X) {
|
||||
QualType T = GetQualType(X);
|
||||
if (!T.getTypePtr())
|
||||
return MakeCXType(QualType(), GetASTU(X));
|
||||
return MakeCXType(QualType(), GetTU(X));
|
||||
|
||||
if (const FunctionType *FD = T->getAs<FunctionType>())
|
||||
return MakeCXType(FD->getResultType(), GetASTU(X));
|
||||
return MakeCXType(FD->getResultType(), GetTU(X));
|
||||
|
||||
return MakeCXType(QualType(), GetASTU(X));
|
||||
return MakeCXType(QualType(), GetTU(X));
|
||||
}
|
||||
|
||||
CXType clang_getCursorResultType(CXCursor C) {
|
||||
if (clang_isDeclaration(C.kind)) {
|
||||
Decl *D = cxcursor::getCursorDecl(C);
|
||||
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
|
||||
return MakeCXType(MD->getResultType(), cxcursor::getCursorASTUnit(C));
|
||||
return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
|
||||
|
||||
return clang_getResultType(clang_getCursorType(C));
|
||||
}
|
||||
|
||||
return MakeCXType(QualType(), cxcursor::getCursorASTUnit(C));
|
||||
return MakeCXType(QualType(), cxcursor::getCursorTU(C));
|
||||
}
|
||||
|
||||
unsigned clang_isPODType(CXType X) {
|
||||
|
|
|
@ -23,7 +23,7 @@ class ASTUnit;
|
|||
|
||||
namespace cxtype {
|
||||
|
||||
CXType MakeCXType(QualType T, ASTUnit *TU);
|
||||
CXType MakeCXType(QualType T, CXTranslationUnit TU);
|
||||
|
||||
}} // end namespace clang::cxtype
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue