summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-10-20 21:14:49 +0000
committerdim <dim@FreeBSD.org>2011-10-20 21:14:49 +0000
commit3963a48221351c61c17fb3f382341ab04809a3d3 (patch)
treeee2483e98b09cac943dc93a6969d83ca737ff139 /tools
parent611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (diff)
downloadFreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.zip
FreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.tar.gz
Vendor import of clang release_30 branch r142614:
http://llvm.org/svn/llvm-project/cfe/branches/release_30@142614
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/Makefile2
-rw-r--r--tools/arcmt-test/arcmt-test.cpp47
-rw-r--r--tools/c-index-test/CMakeLists.txt1
-rw-r--r--tools/c-index-test/Makefile3
-rw-r--r--tools/c-index-test/c-index-test.c264
-rw-r--r--tools/diagtool/CMakeLists.txt24
-rw-r--r--tools/diagtool/DiagTool.cpp68
-rw-r--r--tools/diagtool/DiagTool.h70
-rw-r--r--tools/diagtool/ListWarnings.cpp106
-rw-r--r--tools/diagtool/Makefile25
-rw-r--r--tools/diagtool/diagtool_main.cpp26
-rw-r--r--tools/driver/Makefile9
-rw-r--r--tools/driver/cc1_main.cpp17
-rw-r--r--tools/driver/cc1as_main.cpp94
-rw-r--r--tools/driver/driver.cpp71
-rw-r--r--tools/libclang/CIndex.cpp1403
-rw-r--r--tools/libclang/CIndexCXX.cpp11
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp185
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp18
-rw-r--r--tools/libclang/CIndexHigh.cpp315
-rw-r--r--tools/libclang/CIndexInclusionStack.cpp19
-rw-r--r--tools/libclang/CIndexUSRs.cpp106
-rw-r--r--tools/libclang/CIndexer.cpp2
-rw-r--r--tools/libclang/CMakeLists.txt1
-rw-r--r--tools/libclang/CXCursor.cpp697
-rw-r--r--tools/libclang/CXCursor.h37
-rw-r--r--tools/libclang/CXString.cpp6
-rw-r--r--tools/libclang/CXString.h6
-rw-r--r--tools/libclang/CXTranslationUnit.h9
-rw-r--r--tools/libclang/CXType.cpp36
-rw-r--r--tools/libclang/Index_Internal.h43
-rw-r--r--tools/libclang/libclang.darwin.exports143
-rw-r--r--tools/libclang/libclang.exports26
-rwxr-xr-xtools/scan-build/ccc-analyzer29
-rwxr-xr-xtools/scan-build/scan-build4
36 files changed, 2817 insertions, 1107 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index aff437f..117d10a 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -2,4 +2,5 @@ add_subdirectory(libclang)
add_subdirectory(c-index-test)
add_subdirectory(arcmt-test)
add_subdirectory(c-arcmt-test)
+add_subdirectory(diagtool)
add_subdirectory(driver)
diff --git a/tools/Makefile b/tools/Makefile
index bfd2a64..4ea2cdd 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ..
-DIRS := driver libclang c-index-test arcmt-test c-arcmt-test
+DIRS := driver libclang c-index-test arcmt-test c-arcmt-test diagtool
include $(CLANG_LEVEL)/../../Makefile.config
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index eb0f569..d27483f 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -10,7 +10,7 @@
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Frontend/VerifyDiagnosticsClient.h"
+#include "clang/Frontend/VerifyDiagnosticConsumer.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -69,24 +69,24 @@ llvm::sys::Path GetExecutablePath(const char *Argv0) {
}
static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
- llvm::raw_ostream &OS);
+ raw_ostream &OS);
static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
- llvm::raw_ostream &OS);
+ raw_ostream &OS);
namespace {
class PrintTransforms : public MigrationProcess::RewriteListener {
ASTContext *Ctx;
- llvm::raw_ostream &OS;
+ raw_ostream &OS;
public:
- PrintTransforms(llvm::raw_ostream &OS)
+ PrintTransforms(raw_ostream &OS)
: Ctx(0), OS(OS) { }
virtual void start(ASTContext &ctx) { Ctx = &ctx; }
virtual void finish() { Ctx = 0; }
- virtual void insert(SourceLocation loc, llvm::StringRef text) {
+ virtual void insert(SourceLocation loc, StringRef text) {
assert(Ctx);
OS << "Insert: ";
printSourceLocation(loc, *Ctx, OS);
@@ -103,16 +103,17 @@ public:
} // anonymous namespace
-static bool checkForMigration(llvm::StringRef resourcesPath,
- llvm::ArrayRef<const char *> Args) {
- DiagnosticClient *DiagClient =
+static bool checkForMigration(StringRef resourcesPath,
+ ArrayRef<const char *> Args) {
+ DiagnosticConsumer *DiagClient =
new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(new Diagnostic(DiagID, DiagClient));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient));
// Chain in -verify checker, if requested.
- VerifyDiagnosticsClient *verifyDiag = 0;
+ VerifyDiagnosticConsumer *verifyDiag = 0;
if (VerifyDiags) {
- verifyDiag = new VerifyDiagnosticsClient(*Diags, Diags->takeClient());
+ verifyDiag = new VerifyDiagnosticConsumer(*Diags);
Diags->setClient(verifyDiag);
}
@@ -134,7 +135,7 @@ static bool checkForMigration(llvm::StringRef resourcesPath,
return Diags->getClient()->getNumErrors() > 0;
}
-static void printResult(FileRemapper &remapper, llvm::raw_ostream &OS) {
+static void printResult(FileRemapper &remapper, raw_ostream &OS) {
CompilerInvocation CI;
remapper.applyMappings(CI);
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
@@ -145,16 +146,17 @@ static void printResult(FileRemapper &remapper, llvm::raw_ostream &OS) {
}
}
-static bool performTransformations(llvm::StringRef resourcesPath,
- llvm::ArrayRef<const char *> Args) {
+static bool performTransformations(StringRef resourcesPath,
+ ArrayRef<const char *> Args) {
// Check first.
if (checkForMigration(resourcesPath, Args))
return true;
- DiagnosticClient *DiagClient =
+ DiagnosticConsumer *DiagClient =
new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> TopDiags(new Diagnostic(DiagID, DiagClient));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> TopDiags(
+ new DiagnosticsEngine(DiagID, DiagClient));
CompilerInvocation origCI;
CompilerInvocation::CreateFromArgs(origCI, Args.begin(), Args.end(),
@@ -199,7 +201,7 @@ static bool performTransformations(llvm::StringRef resourcesPath,
return false;
}
-static bool filesCompareEqual(llvm::StringRef fname1, llvm::StringRef fname2) {
+static bool filesCompareEqual(StringRef fname1, StringRef fname2) {
using namespace llvm;
OwningPtr<MemoryBuffer> file1;
@@ -215,7 +217,7 @@ static bool filesCompareEqual(llvm::StringRef fname1, llvm::StringRef fname2) {
return file1->getBuffer() == file2->getBuffer();
}
-static bool verifyTransformedFiles(llvm::ArrayRef<std::string> resultFiles) {
+static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
using namespace llvm;
assert(!resultFiles.empty());
@@ -303,7 +305,7 @@ static bool verifyTransformedFiles(llvm::ArrayRef<std::string> resultFiles) {
//===----------------------------------------------------------------------===//
static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
- llvm::raw_ostream &OS) {
+ raw_ostream &OS) {
SourceManager &SM = Ctx.getSourceManager();
PresumedLoc PL = SM.getPresumedLoc(loc);
@@ -313,7 +315,7 @@ static void printSourceLocation(SourceLocation loc, ASTContext &Ctx,
}
static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
- llvm::raw_ostream &OS) {
+ raw_ostream &OS) {
SourceManager &SM = Ctx.getSourceManager();
const LangOptions &langOpts = Ctx.getLangOptions();
@@ -338,7 +340,6 @@ static void printSourceRange(CharSourceRange range, ASTContext &Ctx,
//===----------------------------------------------------------------------===//
int main(int argc, const char **argv) {
- using llvm::StringRef;
void *MainAddr = (void*) (intptr_t) GetExecutablePath;
llvm::sys::PrintStackTraceOnErrorSignal();
@@ -365,7 +366,7 @@ int main(int argc, const char **argv) {
return 1;
}
- llvm::ArrayRef<const char*> Args(argv+optargc+1, argc-optargc-1);
+ ArrayRef<const char*> Args(argv+optargc+1, argc-optargc-1);
if (CheckOnly)
return checkForMigration(resourcesPath, Args);
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index 45ad9e3..c44b34b 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -13,3 +13,4 @@ set_target_properties(c-index-test
PROPERTIES
LINKER_LANGUAGE CXX)
+install(TARGETS c-index-test RUNTIME DESTINATION bin)
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index 5e5b857..c21b327 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -13,9 +13,6 @@ TOOLNAME = c-index-test
# No plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-# Don't install this. It is used for tests.
-NO_INSTALL = 1
-
LINK_COMPONENTS := support mc
USEDLIBS = clang.a clangIndex.a clangFrontend.a clangDriver.a \
clangSerialization.a clangParse.a clangSema.a \
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 6e0aaac..2a3584b 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -158,9 +158,25 @@ int parse_remapped_files(int argc, const char **argv, int start_arg,
/* Pretty-printing. */
/******************************************************************************/
+static void PrintRange(CXSourceRange R, const char *str) {
+ CXFile begin_file, end_file;
+ unsigned begin_line, begin_column, end_line, end_column;
+
+ clang_getSpellingLocation(clang_getRangeStart(R),
+ &begin_file, &begin_line, &begin_column, 0);
+ clang_getSpellingLocation(clang_getRangeEnd(R),
+ &end_file, &end_line, &end_column, 0);
+ if (!begin_file || !end_file)
+ return;
+
+ printf(" %s=", str);
+ PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
+}
+
int want_display_name = 0;
-static void PrintCursor(CXTranslationUnit TU, CXCursor Cursor) {
+static void PrintCursor(CXCursor Cursor) {
+ CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
if (clang_isInvalid(Cursor.kind)) {
CXString ks = clang_getCursorKindSpelling(Cursor.kind);
printf("Invalid Cursor => %s", clang_getCString(ks));
@@ -173,6 +189,9 @@ static void PrintCursor(CXTranslationUnit TU, CXCursor Cursor) {
CXCursor SpecializationOf;
CXCursor *overridden;
unsigned num_overridden;
+ unsigned RefNameRangeNr;
+ CXSourceRange CursorExtent;
+ CXSourceRange RefNameRange;
ks = clang_getCursorKindSpelling(Cursor.kind);
string = want_display_name? clang_getCursorDisplayName(Cursor)
@@ -219,6 +238,10 @@ static void PrintCursor(CXTranslationUnit TU, CXCursor Cursor) {
case CXAvailability_NotAvailable:
printf(" (unavailable)");
break;
+
+ case CXAvailability_NotAccessible:
+ printf(" (inaccessible)");
+ break;
}
if (clang_CXXMethod_isStatic(Cursor))
@@ -288,6 +311,26 @@ static void PrintCursor(CXTranslationUnit TU, CXCursor Cursor) {
if (clang_isFileMultipleIncludeGuarded(TU, File))
printf(" [multi-include guarded]");
}
+
+ CursorExtent = clang_getCursorExtent(Cursor);
+ RefNameRange = clang_getCursorReferenceNameRange(Cursor,
+ CXNameRange_WantQualifier
+ | CXNameRange_WantSinglePiece
+ | CXNameRange_WantTemplateArgs,
+ 0);
+ if (!clang_equalRanges(CursorExtent, RefNameRange))
+ PrintRange(RefNameRange, "SingleRefName");
+
+ for (RefNameRangeNr = 0; 1; RefNameRangeNr++) {
+ RefNameRange = clang_getCursorReferenceNameRange(Cursor,
+ CXNameRange_WantQualifier
+ | CXNameRange_WantTemplateArgs,
+ RefNameRangeNr);
+ if (clang_equalRanges(clang_getNullRange(), RefNameRange))
+ break;
+ if (!clang_equalRanges(CursorExtent, RefNameRange))
+ PrintRange(RefNameRange, "RefName");
+ }
}
}
@@ -381,7 +424,7 @@ void PrintDiagnostics(CXTranslationUnit TU) {
}
void PrintMemoryUsage(CXTranslationUnit TU) {
- unsigned long total = 0.0;
+ unsigned long total = 0;
unsigned i = 0;
CXTUResourceUsage usage = clang_getCXTUResourceUsage(TU);
fprintf(stderr, "Memory usage:\n");
@@ -405,18 +448,7 @@ static const char *FileCheckPrefix = "CHECK";
static void PrintCursorExtent(CXCursor C) {
CXSourceRange extent = clang_getCursorExtent(C);
- CXFile begin_file, end_file;
- unsigned begin_line, begin_column, end_line, end_column;
-
- clang_getSpellingLocation(clang_getRangeStart(extent),
- &begin_file, &begin_line, &begin_column, 0);
- clang_getSpellingLocation(clang_getRangeEnd(extent),
- &end_file, &end_line, &end_column, 0);
- if (!begin_file || !end_file)
- return;
-
- printf(" Extent=");
- PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
+ PrintRange(extent, "Extent");
}
/* Data used by all of the visitors. */
@@ -436,7 +468,7 @@ enum CXChildVisitResult FilteredPrintingVisitor(CXCursor Cursor,
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
printf("// %s: %s:%d:%d: ", FileCheckPrefix,
GetCursorSource(Cursor), line, column);
- PrintCursor(Data->TU, Cursor);
+ PrintCursor(Cursor);
PrintCursorExtent(Cursor);
printf("\n");
return CXChildVisit_Recurse;
@@ -489,7 +521,7 @@ static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
} else if (Ref.kind != CXCursor_FunctionDecl) {
printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
curLine, curColumn);
- PrintCursor(Data->TU, Ref);
+ PrintCursor(Ref);
printf("\n");
}
}
@@ -564,8 +596,6 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
CXClientData d) {
const char *linkage = 0;
- VisitorData *Data = (VisitorData *)d;
-
if (clang_isInvalid(clang_getCursorKind(cursor)))
return CXChildVisit_Recurse;
@@ -578,7 +608,7 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
}
if (linkage) {
- PrintCursor(Data->TU, cursor);
+ PrintCursor(cursor);
printf("linkage=%s\n", linkage);
}
@@ -591,12 +621,10 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
CXClientData d) {
- VisitorData *Data = (VisitorData *)d;
-
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
CXType T = clang_getCursorType(cursor);
CXString S = clang_getTypeKindSpelling(T.kind);
- PrintCursor(Data->TU, cursor);
+ PrintCursor(cursor);
printf(" typekind=%s", clang_getCString(S));
if (clang_isConstQualifiedType(T))
printf(" const");
@@ -747,6 +775,8 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
int num_unsaved_files = 0;
int result;
int trial;
+ int remap_after_trial = 0;
+ char *endptr = 0;
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
@@ -770,8 +800,15 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
return 1;
}
+ if (getenv("CINDEXTEST_REMAP_AFTER_TRIAL")) {
+ remap_after_trial =
+ strtol(getenv("CINDEXTEST_REMAP_AFTER_TRIAL"), &endptr, 10);
+ }
+
for (trial = 0; trial < trials; ++trial) {
- if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ if (clang_reparseTranslationUnit(TU,
+ trial >= remap_after_trial ? num_unsaved_files : 0,
+ trial >= remap_after_trial ? unsaved_files : 0,
clang_defaultReparseOptions(TU))) {
fprintf(stderr, "Unable to reparse translation unit!\n");
clang_disposeTranslationUnit(TU);
@@ -800,7 +837,7 @@ static void print_cursor_file_scan(CXTranslationUnit TU, CXCursor cursor,
printf("-%s", prefix);
PrintExtent(stdout, start_line, start_col, end_line, end_col);
printf(" ");
- PrintCursor(TU, cursor);
+ PrintCursor(cursor);
printf("\n");
}
@@ -996,6 +1033,7 @@ void print_completion_result(CXCompletionResult *completion_result,
CXClientData client_data) {
FILE *file = (FILE *)client_data;
CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
+ unsigned annotationCount;
fprintf(file, "%s:", clang_getCString(ks));
clang_disposeString(ks);
@@ -1014,7 +1052,27 @@ void print_completion_result(CXCompletionResult *completion_result,
case CXAvailability_NotAvailable:
fprintf(file, " (unavailable)");
break;
+
+ case CXAvailability_NotAccessible:
+ fprintf(file, " (inaccessible)");
+ break;
+ }
+
+ annotationCount = clang_getCompletionNumAnnotations(
+ completion_result->CompletionString);
+ if (annotationCount) {
+ unsigned i;
+ fprintf(file, " (");
+ for (i = 0; i < annotationCount; ++i) {
+ if (i != 0)
+ fprintf(file, ", ");
+ fprintf(file, "\"%s\"",
+ clang_getCString(clang_getCompletionAnnotation(
+ completion_result->CompletionString, i)));
+ }
+ fprintf(file, ")");
}
+
fprintf(file, "\n");
}
@@ -1171,8 +1229,11 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
}
if (results) {
- unsigned i, n = results->NumResults;
+ unsigned i, n = results->NumResults, containerIsIncomplete = 0;
unsigned long long contexts;
+ enum CXCursorKind containerKind;
+ CXString objCSelector;
+ const char *selectorString;
if (!timing_only) {
/* Sort the code-completion results based on the typed text. */
clang_sortCodeCompletionResults(results->Results, results->NumResults);
@@ -1190,6 +1251,35 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
contexts = clang_codeCompleteGetContexts(results);
print_completion_contexts(contexts, stdout);
+ containerKind = clang_codeCompleteGetContainerKind(results,
+ &containerIsIncomplete);
+
+ if (containerKind != CXCursor_InvalidCode) {
+ /* We have found a container */
+ CXString containerUSR, containerKindSpelling;
+ containerKindSpelling = clang_getCursorKindSpelling(containerKind);
+ printf("Container Kind: %s\n", clang_getCString(containerKindSpelling));
+ clang_disposeString(containerKindSpelling);
+
+ if (containerIsIncomplete) {
+ printf("Container is incomplete\n");
+ }
+ else {
+ printf("Container is complete\n");
+ }
+
+ containerUSR = clang_codeCompleteGetContainerUSR(results);
+ printf("Container USR: %s\n", clang_getCString(containerUSR));
+ clang_disposeString(containerUSR);
+ }
+
+ objCSelector = clang_codeCompleteGetObjCSelector(results);
+ selectorString = clang_getCString(objCSelector);
+ if (selectorString && strlen(selectorString) > 0) {
+ printf("Objective-C selector: %s\n", selectorString);
+ }
+ clang_disposeString(objCSelector);
+
clang_disposeCodeCompleteResults(results);
}
clang_disposeTranslationUnit(TU);
@@ -1207,7 +1297,7 @@ typedef struct {
unsigned column;
} CursorSourceLocation;
-int inspect_cursor_at(int argc, const char **argv) {
+static int inspect_cursor_at(int argc, const char **argv) {
CXIndex CIdx;
int errorCode;
struct CXUnsavedFile *unsaved_files = 0;
@@ -1274,7 +1364,13 @@ int inspect_cursor_at(int argc, const char **argv) {
clang_getLocation(TU, file, Locations[Loc].line,
Locations[Loc].column));
if (I + 1 == Repeats) {
- PrintCursor(TU, Cursor);
+ CXCompletionString completionString = clang_getCursorCompletionString(
+ Cursor);
+ PrintCursor(Cursor);
+ if (completionString != NULL) {
+ printf("\nCompletion string: ");
+ print_completion_string(completionString, stdout);
+ }
printf("\n");
free(Locations[Loc].filename);
}
@@ -1289,6 +1385,101 @@ int inspect_cursor_at(int argc, const char **argv) {
return 0;
}
+static enum CXVisitorResult findFileRefsVisit(void *context,
+ CXCursor cursor, CXSourceRange range) {
+ if (clang_Range_isNull(range))
+ return CXVisit_Continue;
+
+ PrintCursor(cursor);
+ PrintRange(range, "");
+ printf("\n");
+ return CXVisit_Continue;
+}
+
+static int find_file_refs_at(int argc, const char **argv) {
+ CXIndex CIdx;
+ int errorCode;
+ struct CXUnsavedFile *unsaved_files = 0;
+ int num_unsaved_files = 0;
+ CXTranslationUnit TU;
+ CXCursor Cursor;
+ CursorSourceLocation *Locations = 0;
+ unsigned NumLocations = 0, Loc;
+ unsigned Repeats = 1;
+ unsigned I;
+
+ /* Count the number of locations. */
+ while (strstr(argv[NumLocations+1], "-file-refs-at=") == argv[NumLocations+1])
+ ++NumLocations;
+
+ /* Parse the locations. */
+ assert(NumLocations > 0 && "Unable to count locations?");
+ Locations = (CursorSourceLocation *)malloc(
+ NumLocations * sizeof(CursorSourceLocation));
+ for (Loc = 0; Loc < NumLocations; ++Loc) {
+ const char *input = argv[Loc + 1] + strlen("-file-refs-at=");
+ if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename,
+ &Locations[Loc].line,
+ &Locations[Loc].column, 0, 0)))
+ return errorCode;
+ }
+
+ if (parse_remapped_files(argc, argv, NumLocations + 1, &unsaved_files,
+ &num_unsaved_files))
+ return -1;
+
+ if (getenv("CINDEXTEST_EDITING"))
+ Repeats = 5;
+
+ /* Parse the translation unit. When we're testing clang_getCursor() after
+ reparsing, don't remap unsaved files until the second parse. */
+ CIdx = clang_createIndex(1, 1);
+ TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
+ argv + num_unsaved_files + 1 + NumLocations,
+ argc - num_unsaved_files - 2 - NumLocations,
+ unsaved_files,
+ Repeats > 1? 0 : num_unsaved_files,
+ getDefaultParsingOptions());
+
+ if (!TU) {
+ fprintf(stderr, "unable to parse input\n");
+ return -1;
+ }
+
+ for (I = 0; I != Repeats; ++I) {
+ if (Repeats > 1 &&
+ clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU))) {
+ clang_disposeTranslationUnit(TU);
+ return 1;
+ }
+
+ for (Loc = 0; Loc < NumLocations; ++Loc) {
+ CXFile file = clang_getFile(TU, Locations[Loc].filename);
+ if (!file)
+ continue;
+
+ Cursor = clang_getCursor(TU,
+ clang_getLocation(TU, file, Locations[Loc].line,
+ Locations[Loc].column));
+ if (I + 1 == Repeats) {
+ CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit };
+ PrintCursor(Cursor);
+ printf("\n");
+ clang_findReferencesInFile(Cursor, file, visitor);
+ free(Locations[Loc].filename);
+ }
+ }
+ }
+
+ PrintDiagnostics(TU);
+ clang_disposeTranslationUnit(TU);
+ clang_disposeIndex(CIdx);
+ free(Locations);
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ return 0;
+}
+
int perform_token_annotation(int argc, const char **argv) {
const char *input = argv[1];
char *filename = 0;
@@ -1331,6 +1522,17 @@ int perform_token_annotation(int argc, const char **argv) {
}
errorCode = 0;
+ if (getenv("CINDEXTEST_EDITING")) {
+ for (i = 0; i < 5; ++i) {
+ if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(TU))) {
+ fprintf(stderr, "Unable to reparse translation unit!\n");
+ errorCode = -1;
+ goto teardown;
+ }
+ }
+ }
+
file = clang_getFile(TU, filename);
if (!file) {
fprintf(stderr, "file %s is not in this translation unit\n", filename);
@@ -1379,7 +1581,7 @@ int perform_token_annotation(int argc, const char **argv) {
PrintExtent(stdout, start_line, start_column, end_line, end_column);
if (!clang_isInvalid(cursors[i].kind)) {
printf(" ");
- PrintCursor(TU, cursors[i]);
+ PrintCursor(cursors[i]);
}
printf("\n");
}
@@ -1645,8 +1847,10 @@ static void print_usage(void) {
"usage: c-index-test -code-completion-at=<site> <compiler arguments>\n"
" c-index-test -code-completion-timing=<site> <compiler arguments>\n"
" c-index-test -cursor-at=<site> <compiler arguments>\n"
+ " c-index-test -file-refs-at=<site> <compiler arguments>\n"
" c-index-test -test-file-scan <AST file> <source file> "
- "[FileCheck prefix]\n"
+ "[FileCheck prefix]\n");
+ fprintf(stderr,
" c-index-test -test-load-tu <AST file> <symbol filter> "
"[FileCheck prefix]\n"
" c-index-test -test-load-tu-usrs <AST file> <symbol filter> "
@@ -1691,6 +1895,8 @@ int cindextest_main(int argc, const char **argv) {
return perform_code_completion(argc, argv, 1);
if (argc > 2 && strstr(argv[1], "-cursor-at=") == argv[1])
return inspect_cursor_at(argc, argv);
+ if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
+ return find_file_refs_at(argc, argv);
else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
CXCursorVisitor I = GetVisitor(argv[1] + 13);
if (I)
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
new file mode 100644
index 0000000..f1fd9de
--- /dev/null
+++ b/tools/diagtool/CMakeLists.txt
@@ -0,0 +1,24 @@
+set( LLVM_LINK_COMPONENTS
+ support
+ )
+
+set( LLVM_USED_LIBS
+ clangBasic
+ clangLex
+ clangSema
+ )
+
+add_clang_executable(diagtool
+ diagtool_main.cpp
+ DiagTool.cpp
+ ListWarnings.cpp
+)
+
+if(UNIX)
+ set(CLANGXX_LINK_OR_COPY create_symlink)
+else()
+ set(CLANGXX_LINK_OR_COPY copy)
+endif()
+
+install(TARGETS diagtool
+ RUNTIME DESTINATION bin)
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
new file mode 100644
index 0000000..36e72a2
--- /dev/null
+++ b/tools/diagtool/DiagTool.cpp
@@ -0,0 +1,68 @@
+//===- DiagTool.cpp - Classes for defining diagtool tools -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the boilerplate for defining diagtool tools.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagTool.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/SmallString.h"
+#include <vector>
+
+using namespace diagtool;
+
+DiagTool::DiagTool(llvm::StringRef toolCmd,
+ llvm::StringRef toolDesc)
+ : cmd(toolCmd), description(toolDesc) {}
+
+DiagTool::~DiagTool() {}
+
+typedef llvm::StringMap<DiagTool *> ToolMap;
+static inline ToolMap *getTools(void *v) { return static_cast<ToolMap*>(v); }
+
+DiagTools::DiagTools() : tools(new ToolMap()) {}
+DiagTools::~DiagTools() { delete getTools(tools); }
+
+DiagTool *DiagTools::getTool(llvm::StringRef toolCmd) {
+ ToolMap::iterator it = getTools(tools)->find(toolCmd);
+ return (it == getTools(tools)->end()) ? 0 : it->getValue();
+}
+
+void DiagTools::registerTool(DiagTool *tool) {
+ getTools(tools)->GetOrCreateValue(tool->getName(), tool);
+}
+
+void DiagTools::printCommands(llvm::raw_ostream &out) {
+ std::vector<llvm::StringRef> toolNames;
+ unsigned maxName = 0;
+ for (ToolMap::iterator it = getTools(tools)->begin(),
+ ei = getTools(tools)->end(); it != ei; ++it) {
+ toolNames.push_back(it->getKey());
+ unsigned len = it->getKey().size();
+ if (len > maxName)
+ maxName = len;
+ }
+ std::sort(toolNames.begin(), toolNames.end());
+
+ for (std::vector<llvm::StringRef>::iterator it = toolNames.begin(),
+ ei = toolNames.end(); it != ei; ++it) {
+
+ out << " " << (*it);
+ unsigned spaces = (maxName + 3) - (it->size());
+ for (unsigned i = 0; i < spaces; ++i)
+ out << ' ';
+
+ out << getTool(*it)->getDescription() << '\n';
+ }
+}
+
+namespace diagtool {
+ llvm::ManagedStatic<DiagTools> diagTools;
+}
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
new file mode 100644
index 0000000..dcb6ac7
--- /dev/null
+++ b/tools/diagtool/DiagTool.h
@@ -0,0 +1,70 @@
+//===- DiagTool.h - Classes for defining diagtool tools -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the boilerplate for defining diagtool tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DIAGTOOL_DIAGTOOL_H
+#define DIAGTOOL_DIAGTOOL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ManagedStatic.h"
+#include <string>
+
+
+namespace diagtool {
+
+class DiagTool {
+ const std::string cmd;
+ const std::string description;
+public:
+ DiagTool(llvm::StringRef toolCmd, llvm::StringRef toolDesc);
+ virtual ~DiagTool();
+
+ llvm::StringRef getName() const { return cmd; }
+ llvm::StringRef getDescription() const { return description; }
+
+ virtual int run(unsigned argc, char *argv[], llvm::raw_ostream &out) = 0;
+};
+
+class DiagTools {
+ void *tools;
+public:
+ DiagTools();
+ ~DiagTools();
+
+ DiagTool *getTool(llvm::StringRef toolCmd);
+ void registerTool(DiagTool *tool);
+ void printCommands(llvm::raw_ostream &out);
+};
+
+extern llvm::ManagedStatic<DiagTools> diagTools;
+
+template <typename DIAGTOOL>
+class RegisterDiagTool {
+public:
+ RegisterDiagTool() { diagTools->registerTool(new DIAGTOOL()); }
+};
+
+} // end diagtool namespace
+
+#define DEF_DIAGTOOL(NAME, DESC, CLSNAME)\
+namespace {\
+class CLSNAME : public diagtool::DiagTool {\
+public:\
+ CLSNAME() : DiagTool(NAME, DESC) {}\
+ virtual ~CLSNAME() {}\
+ virtual int run(unsigned argc, char *argv[], llvm::raw_ostream &out);\
+};\
+diagtool::RegisterDiagTool<CLSNAME> Register##CLSNAME;\
+}
+
+#endif
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
new file mode 100644
index 0000000..7f7db8e
--- /dev/null
+++ b/tools/diagtool/ListWarnings.cpp
@@ -0,0 +1,106 @@
+//===- ListWarnings.h - diagtool tool for printing warning flags ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a diagtool tool that displays warning flags for
+// diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagTool.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/Format.h"
+#include "llvm/ADT/StringMap.h"
+
+DEF_DIAGTOOL("list-warnings",
+ "List warnings and their corresponding flags",
+ ListWarnings)
+
+using namespace clang;
+
+
+namespace {
+struct Entry {
+ llvm::StringRef DiagName;
+ llvm::StringRef Flag;
+
+ Entry(llvm::StringRef diagN, llvm::StringRef flag)
+ : DiagName(diagN), Flag(flag) {}
+
+ bool operator<(const Entry &x) const { return DiagName < x.DiagName; }
+};
+}
+
+static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) {
+ for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end();
+ it != ei; ++it) {
+ out << " " << it->DiagName;
+ if (!it->Flag.empty())
+ out << " [-W" << it->Flag << "]";
+ out << '\n';
+ }
+}
+
+int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags(new DiagnosticIDs);
+ DiagnosticsEngine D(Diags);
+
+ std::vector<Entry> Flagged, Unflagged;
+ llvm::StringMap<std::vector<unsigned> > flagHistogram;
+
+ for (DiagnosticIDs::diag_iterator di = DiagnosticIDs::diags_begin(),
+ de = DiagnosticIDs::diags_end(); di != de; ++di) {
+
+ unsigned diagID = di.getDiagID();
+
+ if (DiagnosticIDs::isBuiltinNote(diagID))
+ continue;
+
+ if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
+ continue;
+
+ Entry entry(di.getDiagName(),
+ DiagnosticIDs::getWarningOptionForDiag(diagID));
+
+ if (entry.Flag.empty())
+ Unflagged.push_back(entry);
+ else {
+ Flagged.push_back(entry);
+ flagHistogram.GetOrCreateValue(entry.Flag).getValue().push_back(diagID);
+ }
+ }
+
+ std::sort(Flagged.begin(), Flagged.end());
+ std::sort(Unflagged.begin(), Unflagged.end());
+
+ out << "Warnings with flags (" << Flagged.size() << "):\n";
+ printEntries(Flagged, out);
+
+ out << "Warnings without flags (" << Unflagged.size() << "):\n";
+ printEntries(Unflagged, out);
+
+ out << "\nSTATISTICS:\n\n";
+
+ double percentFlagged = ((double) Flagged.size())
+ / (Flagged.size() + Unflagged.size()) * 100.0;
+
+ out << " Percentage of warnings with flags: "
+ << llvm::format("%.4g",percentFlagged) << "%\n";
+
+ out << " Number of unique flags: "
+ << flagHistogram.size() << '\n';
+
+ double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
+ out << " Average number of diagnostics per flag: "
+ << llvm::format("%.4g", avgDiagsPerFlag) << '\n';
+
+ out << '\n';
+
+ return 0;
+}
+
diff --git a/tools/diagtool/Makefile b/tools/diagtool/Makefile
new file mode 100644
index 0000000..22d7411
--- /dev/null
+++ b/tools/diagtool/Makefile
@@ -0,0 +1,25 @@
+##===- tools/driver/Makefile -------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+CLANG_LEVEL := ../..
+
+TOOLNAME = diagtool
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
+
+# Don't install this.
+NO_INSTALL = 1
+
+LINK_COMPONENTS := support
+
+USEDLIBS = clangCodeGen.a clangParse.a clangSema.a \
+ clangAST.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
+
diff --git a/tools/diagtool/diagtool_main.cpp b/tools/diagtool/diagtool_main.cpp
new file mode 100644
index 0000000..e34f0dc
--- /dev/null
+++ b/tools/diagtool/diagtool_main.cpp
@@ -0,0 +1,26 @@
+//===- diagtool_main.h - Entry point for invoking all diagnostic tools ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the main function for diagtool.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagTool.h"
+
+using namespace diagtool;
+
+int main(int argc, char *argv[]) {
+ if (argc > 1)
+ if (DiagTool *tool = diagTools->getTool(argv[1]))
+ return tool->run(argc - 1, &argv[2], llvm::errs());
+
+ llvm::errs() << "usage: diagtool <command> [<args>]\n\n";
+ diagTools->printCommands(llvm::errs());
+ return 1;
+}
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index 1ba8bc2..6b34a99 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -9,13 +9,7 @@
CLANG_LEVEL := ../..
TOOLNAME = clang
-ifndef CLANG_IS_PRODUCTION
TOOLALIAS = clang++
-else
- ifdef CLANGXX_IS_PRODUCTION
- TOOLALIAS = clang++
- endif
-endif
# We don't currently expect production Clang builds to be interested in
# plugins. This is important for startup performance.
@@ -73,6 +67,3 @@ endif
ifdef CLANG_IS_PRODUCTION
CPP.Defines += -DCLANG_IS_PRODUCTION
endif
-ifdef CLANGXX_IS_PRODUCTION
-CPP.Defines += -DCLANGXX_IS_PRODUCTION
-endif
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 9ad4af1..27f79b7 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -27,9 +27,9 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetSelect.h"
#include <cstdio>
using namespace clang;
@@ -38,7 +38,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
static void LLVMErrorHandler(void *UserData, const std::string &Message) {
- Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
+ DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
Diags.Report(diag::err_fe_error_backend) << Message;
@@ -47,7 +47,7 @@ static void LLVMErrorHandler(void *UserData, const std::string &Message) {
}
// FIXME: Define the need for this testing away.
-static int cc1_test(Diagnostic &Diags,
+static int cc1_test(DiagnosticsEngine &Diags,
const char **ArgBegin, const char **ArgEnd) {
using namespace clang::driver;
@@ -83,7 +83,7 @@ static int cc1_test(Diagnostic &Diags,
Invocation.toArgs(InvocationArgs);
// Dump the converted arguments.
- llvm::SmallVector<const char*, 32> Invocation2Args;
+ SmallVector<const char*, 32> Invocation2Args;
llvm::errs() << "invocation argv :";
for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
Invocation2Args.push_back(InvocationArgs[i].c_str());
@@ -118,23 +118,22 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
// Run clang -cc1 test.
- if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
- Diagnostic Diags(DiagID, new TextDiagnosticPrinter(llvm::errs(),
+ if (ArgBegin != ArgEnd && StringRef(ArgBegin[0]) == "-cc1test") {
+ DiagnosticsEngine Diags(DiagID, new TextDiagnosticPrinter(llvm::errs(),
DiagnosticOptions()));
return cc1_test(Diags, ArgBegin + 1, ArgEnd);
}
// Initialize targets first, so that --version shows registered targets.
llvm::InitializeAllTargets();
- llvm::InitializeAllMCAsmInfos();
- llvm::InitializeAllMCSubtargetInfos();
+ llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllAsmParsers();
// Buffer diagnostics from argument parsing so that we can output them using a
// well formed diagnostic object.
TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
- Diagnostic Diags(DiagID, DiagsBuffer);
+ DiagnosticsEngine Diags(DiagID, DiagsBuffer);
CompilerInvocation::CreateFromArgs(Clang->getInvocation(), ArgBegin, ArgEnd,
Diags);
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 358d746..7cc42aa 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -30,8 +30,12 @@
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -39,23 +43,15 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetAsmBackend.h"
-#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace clang;
using namespace clang::driver;
using namespace llvm;
@@ -125,7 +121,7 @@ public:
}
static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
- const char **ArgEnd, Diagnostic &Diags);
+ const char **ArgEnd, DiagnosticsEngine &Diags);
};
}
@@ -133,7 +129,7 @@ public:
void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
const char **ArgBegin,
const char **ArgEnd,
- Diagnostic &Diags) {
+ DiagnosticsEngine &Diags) {
using namespace clang::driver::cc1asoptions;
// Parse the arguments.
OwningPtr<OptTable> OptTbl(createCC1AsOptTable());
@@ -207,7 +203,7 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
}
static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
- Diagnostic &Diags,
+ DiagnosticsEngine &Diags,
bool Binary) {
if (Opts.OutputPath.empty())
Opts.OutputPath = "-";
@@ -230,7 +226,8 @@ static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts,
return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
}
-static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
+static bool ExecuteAssembler(AssemblerInvocation &Opts,
+ DiagnosticsEngine &Diags) {
// Get the target specific parser.
std::string Error;
const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
@@ -259,64 +256,60 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(Opts.Triple));
assert(MAI && "Unable to create target asm info!");
+ OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
+ assert(MRI && "Unable to create target register info!");
+
bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
if (!Out)
return false;
- // FIXME: We shouldn't need to do this (and link in codegen).
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(Opts.Triple,
- "", ""));
- if (!TM) {
- Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
- return false;
- }
-
- const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
- MCContext Ctx(*MAI, tai);
+ // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
+ // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
+ OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+ MCContext Ctx(*MAI, *MRI, MOFI.get());
+ // FIXME: Assembler behavior can change with -static.
+ MOFI->InitMCObjectFileInfo(Opts.Triple,
+ Reloc::Default, CodeModel::Default, Ctx);
if (Opts.SaveTemporaryLabels)
Ctx.setAllowTemporaryLabels(false);
OwningPtr<MCStreamer> Str;
- const TargetLoweringObjectFile &TLOF =
- TM->getTargetLowering()->getObjFileLowering();
- const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
-
- const MCSubtargetInfo &STI = TM->getSubtarget<MCSubtargetInfo>();
+ OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
+ OwningPtr<MCSubtargetInfo>
+ STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", ""));
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI);
+ TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *STI);
MCCodeEmitter *CE = 0;
- TargetAsmBackend *TAB = 0;
+ MCAsmBackend *MAB = 0;
if (Opts.ShowEncoding) {
- CE = TheTarget->createCodeEmitter(*TM->getInstrInfo(), STI, Ctx);
- TAB = TheTarget->createAsmBackend(Opts.Triple);
+ CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MAB = TheTarget->createMCAsmBackend(Opts.Triple);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
/*useLoc*/ true,
- /*useCFI*/ true, IP, CE, TAB,
+ /*useCFI*/ true, IP, CE, MAB,
Opts.ShowInst));
} else if (Opts.OutputType == AssemblerInvocation::FT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
assert(Opts.OutputType == AssemblerInvocation::FT_Obj &&
"Invalid file type!");
- MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM->getInstrInfo(),
- STI, Ctx);
- TargetAsmBackend *TAB = TheTarget->createAsmBackend(Opts.Triple);
- Str.reset(TheTarget->createObjectStreamer(Opts.Triple, Ctx, *TAB, *Out,
- CE, Opts.RelaxAll,
- Opts.NoExecStack));
+ MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MCAsmBackend *MAB = TheTarget->createMCAsmBackend(Opts.Triple);
+ Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
+ CE, Opts.RelaxAll,
+ Opts.NoExecStack));
Str.get()->InitSections();
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
*Str.get(), *MAI));
- OwningPtr<TargetAsmParser>
- TAP(TheTarget->createAsmParser(const_cast<MCSubtargetInfo&>(STI), *Parser));
+ OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
if (!TAP) {
Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
return false;
@@ -337,7 +330,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Diagnostic &Diags) {
}
static void LLVMErrorHandler(void *UserData, const std::string &Message) {
- Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
+ DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
Diags.Report(diag::err_fe_error_backend) << Message;
@@ -354,12 +347,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd,
// Initialize targets and assembly printers/parsers.
InitializeAllTargetInfos();
- // FIXME: We shouldn't need to initialize the Target(Machine)s.
- InitializeAllTargets();
- InitializeAllMCAsmInfos();
- InitializeAllMCInstrInfos();
- InitializeAllMCSubtargetInfos();
- InitializeAllAsmPrinters();
+ InitializeAllTargetMCs();
InitializeAllAsmParsers();
// Construct our diagnostic client.
@@ -367,7 +355,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd,
= new TextDiagnosticPrinter(errs(), DiagnosticOptions());
DiagClient->setPrefix("clang -cc1as");
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- Diagnostic Diags(DiagID, DiagClient);
+ DiagnosticsEngine Diags(DiagID, DiagClient);
// Set an error handler, so that any LLVM backend diagnostics go through our
// error handler.
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index ca89826..bd1d2a2 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -35,9 +35,9 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
#include <cctype>
using namespace clang;
using namespace clang::driver;
@@ -53,7 +53,7 @@ llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
}
static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
- llvm::StringRef S) {
+ StringRef S) {
return SavedStrings.insert(S).first->c_str();
}
@@ -84,9 +84,9 @@ static const char *SaveStringInSet(std::set<std::string> &SavedStrings,
/// \param Args - The vector of command line arguments.
/// \param Edit - The override command to perform.
/// \param SavedStrings - Set to use for storing string representations.
-static void ApplyOneQAOverride(llvm::raw_ostream &OS,
- llvm::SmallVectorImpl<const char*> &Args,
- llvm::StringRef Edit,
+static void ApplyOneQAOverride(raw_ostream &OS,
+ SmallVectorImpl<const char*> &Args,
+ StringRef Edit,
std::set<std::string> &SavedStrings) {
// This does not need to be efficient.
@@ -101,9 +101,9 @@ static void ApplyOneQAOverride(llvm::raw_ostream &OS,
OS << "### Adding argument " << Str << " at end\n";
Args.push_back(Str);
} else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") &&
- Edit.slice(2, Edit.size()-1).find('/') != llvm::StringRef::npos) {
- llvm::StringRef MatchPattern = Edit.substr(2).split('/').first;
- llvm::StringRef ReplPattern = Edit.substr(2).split('/').second;
+ Edit.slice(2, Edit.size()-1).find('/') != StringRef::npos) {
+ StringRef MatchPattern = Edit.substr(2).split('/').first;
+ StringRef ReplPattern = Edit.substr(2).split('/').second;
ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1);
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
@@ -151,10 +151,10 @@ static void ApplyOneQAOverride(llvm::raw_ostream &OS,
/// ApplyQAOverride - Apply a comma separate list of edits to the
/// input argument lists. See ApplyOneQAOverride.
-static void ApplyQAOverride(llvm::SmallVectorImpl<const char*> &Args,
+static void ApplyQAOverride(SmallVectorImpl<const char*> &Args,
const char *OverrideStr,
std::set<std::string> &SavedStrings) {
- llvm::raw_ostream *OS = &llvm::errs();
+ raw_ostream *OS = &llvm::errs();
if (OverrideStr[0] == '#') {
++OverrideStr;
@@ -184,7 +184,7 @@ extern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
const char *Argv0, void *MainAddr);
static void ExpandArgsFromBuf(const char *Arg,
- llvm::SmallVectorImpl<const char*> &ArgVector,
+ SmallVectorImpl<const char*> &ArgVector,
std::set<std::string> &SavedStrings) {
const char *FName = Arg + 1;
llvm::OwningPtr<llvm::MemoryBuffer> MemBuf;
@@ -242,7 +242,7 @@ static void ExpandArgsFromBuf(const char *Arg,
}
static void ExpandArgv(int argc, const char **argv,
- llvm::SmallVectorImpl<const char*> &ArgVector,
+ SmallVectorImpl<const char*> &ArgVector,
std::set<std::string> &SavedStrings) {
for (int i = 0; i < argc; ++i) {
const char *Arg = argv[i];
@@ -255,7 +255,7 @@ static void ExpandArgv(int argc, const char **argv,
}
}
-static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
+static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
std::set<std::string> &SavedStrings,
Driver &TheDriver)
{
@@ -290,8 +290,8 @@ static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
{ "++", true, false },
};
std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
- llvm::StringRef ProgNameRef(ProgName);
- llvm::StringRef Prefix;
+ StringRef ProgNameRef(ProgName);
+ StringRef Prefix;
for (int Components = 2; Components; --Components) {
bool FoundMatch = false;
@@ -309,15 +309,15 @@ static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
}
if (FoundMatch) {
- llvm::StringRef::size_type LastComponent = ProgNameRef.rfind('-',
+ StringRef::size_type LastComponent = ProgNameRef.rfind('-',
ProgNameRef.size() - strlen(suffixes[i].Suffix));
- if (LastComponent != llvm::StringRef::npos)
+ if (LastComponent != StringRef::npos)
Prefix = ProgNameRef.slice(0, LastComponent);
break;
}
- llvm::StringRef::size_type LastComponent = ProgNameRef.rfind('-');
- if (LastComponent == llvm::StringRef::npos)
+ StringRef::size_type LastComponent = ProgNameRef.rfind('-');
+ if (LastComponent == StringRef::npos)
break;
ProgNameRef = ProgNameRef.slice(0, LastComponent);
}
@@ -327,7 +327,7 @@ static void ParseProgName(llvm::SmallVectorImpl<const char *> &ArgVector,
std::string IgnoredError;
if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) {
- llvm::SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
+ SmallVectorImpl<const char *>::iterator it = ArgVector.begin();
if (it != ArgVector.end())
++it;
ArgVector.insert(it, SaveStringInSet(SavedStrings, Prefix));
@@ -341,13 +341,13 @@ int main(int argc_, const char **argv_) {
llvm::PrettyStackTraceProgram X(argc_, argv_);
std::set<std::string> SavedStrings;
- llvm::SmallVector<const char*, 256> argv;
+ SmallVector<const char*, 256> argv;
ExpandArgv(argc_, argv_, argv, SavedStrings);
// Handle -cc1 integrated tools.
- if (argv.size() > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) {
- llvm::StringRef Tool = argv[1] + 4;
+ if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) {
+ StringRef Tool = argv[1] + 4;
if (Tool == "")
return cc1_main(argv.data()+2, argv.data()+argv.size(), argv[0],
@@ -363,7 +363,7 @@ int main(int argc_, const char **argv_) {
bool CanonicalPrefixes = true;
for (int i = 1, size = argv.size(); i < size; ++i) {
- if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") {
+ if (StringRef(argv[i]) == "-no-canonical-prefixes") {
CanonicalPrefixes = false;
break;
}
@@ -375,22 +375,15 @@ int main(int argc_, const char **argv_) {
= new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
DiagClient->setPrefix(llvm::sys::path::stem(Path.str()));
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- Diagnostic Diags(DiagID, DiagClient);
+ DiagnosticsEngine Diags(DiagID, DiagClient);
#ifdef CLANG_IS_PRODUCTION
const bool IsProduction = true;
-# ifdef CLANGXX_IS_PRODUCTION
- const bool CXXIsProduction = true;
-# else
- const bool CXXIsProduction = false;
-# endif
#else
const bool IsProduction = false;
- const bool CXXIsProduction = false;
#endif
Driver TheDriver(Path.str(), llvm::sys::getHostTriple(),
- "a.out", IsProduction, CXXIsProduction,
- Diags);
+ "a.out", IsProduction, Diags);
// Attempt to find the original path used to invoke the driver, to determine
// the installed path. We do this manually, because we want to support that
@@ -458,9 +451,15 @@ int main(int argc_, const char **argv_) {
llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
+ const Command *FailingCommand = 0;
if (C.get())
- Res = TheDriver.ExecuteCompilation(*C);
-
+ Res = TheDriver.ExecuteCompilation(*C, FailingCommand);
+
+ // If result status is < 0, then the driver command signalled an error.
+ // In this case, generate additional diagnostic information if possible.
+ if (Res < 0)
+ TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
+
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
llvm::TimerGroup::printAll(llvm::errs());
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 50d56fc..46ba3d5 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -51,8 +51,9 @@
using namespace clang;
using namespace clang::cxcursor;
using namespace clang::cxstring;
+using namespace clang::cxtu;
-static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
+CXTranslationUnit cxtu::MakeCXTranslationUnit(ASTUnit *TU) {
if (!TU)
return 0;
CXTranslationUnit D = new CXTranslationUnitImpl();
@@ -117,10 +118,10 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
// location accordingly.
SourceLocation EndLoc = R.getEnd();
if (EndLoc.isValid() && EndLoc.isMacroID())
- EndLoc = SM.getInstantiationRange(EndLoc).second;
+ EndLoc = SM.getExpansionRange(EndLoc).second;
if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
- EndLoc = EndLoc.getFileLocWithOffset(Length);
+ EndLoc = EndLoc.getLocWithOffset(Length);
}
CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
@@ -141,7 +142,6 @@ public:
TypeLocVisitKind, OverloadExprPartsKind,
DeclRefExprPartsKind, LabelRefVisitKind,
ExplicitTemplateArgsVisitKind,
- NestedNameSpecifierVisitKind,
NestedNameSpecifierLocVisitKind,
DeclarationNameInfoVisitKind,
MemberRefVisitKind, SizeOfPackExprPartsKind };
@@ -161,7 +161,7 @@ public:
static bool classof(VisitorJob *VJ) { return true; }
};
-typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
+typedef SmallVector<VisitorJob, 10> VisitorWorkList;
// Cursor visitor.
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
@@ -184,11 +184,6 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
/// \brief The opaque client data, to be passed along to the visitor.
CXClientData ClientData;
- // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
- // to the visitor. Declarations with a PCH level greater than this value will
- // be suppressed.
- unsigned MaxPCHLevel;
-
/// \brief Whether we should visit the preprocessing record entries last,
/// after visiting other declarations.
bool VisitPreprocessorLast;
@@ -203,8 +198,8 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
DeclContext::decl_iterator DE_current;
// Cache of pre-allocated worklists for data-recursion walk of Stmts.
- llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
- llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
+ SmallVector<VisitorWorkList*, 5> WorkListFreeList;
+ SmallVector<VisitorWorkList*, 5> WorkListCache;
using DeclVisitor<CursorVisitor, bool>::Visit;
using TypeLocVisitor<CursorVisitor, bool>::Visit;
@@ -239,12 +234,11 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
public:
CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
CXClientData ClientData,
- unsigned MaxPCHLevel,
bool VisitPreprocessorLast,
SourceRange RegionOfInterest = SourceRange())
: TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
Visitor(Visitor), ClientData(ClientData),
- MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
+ VisitPreprocessorLast(VisitPreprocessorLast),
RegionOfInterest(RegionOfInterest), DI_current(0)
{
Parent.kind = CXCursor_NoDeclFound;
@@ -256,7 +250,7 @@ public:
~CursorVisitor() {
// Free the pre-allocated worklists for data-recursion.
- for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
+ for (SmallVectorImpl<VisitorWorkList*>::iterator
I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
delete *I;
}
@@ -267,8 +261,10 @@ public:
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
- std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
- getPreprocessedEntities();
+ bool visitPreprocessedEntitiesInRegion();
+
+ template<typename InputIterator>
+ bool visitPreprocessedEntities(InputIterator First, InputIterator Last);
bool VisitChildren(CXCursor Parent);
@@ -327,35 +323,15 @@ public:
bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
// Type visitors
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
- bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
- bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
- bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
+#include "clang/AST/TypeLocNodes.def"
+
bool VisitTagTypeLoc(TagTypeLoc TL);
- bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
- bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
- bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
- bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
- bool VisitParenTypeLoc(ParenTypeLoc TL);
- bool VisitPointerTypeLoc(PointerTypeLoc TL);
- bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
- bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
- bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
- bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
- bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
bool VisitArrayTypeLoc(ArrayTypeLoc TL);
- bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
- // FIXME: Implement visitors here when the unimplemented TypeLocs get
- // implemented
- bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
- bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
- bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
- bool VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL);
- bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
- bool VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL);
- bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
-
+ bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
+
// Data-recursive visitor functions.
bool IsInRegionOfInterest(CXCursor C);
bool RunVisitorWorkList(VisitorWorkList &WL);
@@ -390,10 +366,9 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
if (clang_isDeclaration(Cursor.kind)) {
Decl *D = getCursorDecl(Cursor);
assert(D && "Invalid declaration cursor");
- if (D->getPCHLevel() > MaxPCHLevel)
- return false;
-
- if (D->isImplicit())
+ // Ignore implicit declarations, unless it's an objc method because
+ // currently we should report implicit methods for properties when indexing.
+ if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
return false;
}
@@ -419,65 +394,53 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
return false;
}
-std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
-CursorVisitor::getPreprocessedEntities() {
+bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
PreprocessingRecord &PPRec
= *AU->getPreprocessor().getPreprocessingRecord();
+ if (RegionOfInterest.isValid()) {
+ SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
+ std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+ Entities = PPRec.getPreprocessedEntitiesInRange(MappedRange);
+ return visitPreprocessedEntities(Entities.first, Entities.second);
+ }
+
bool OnlyLocalDecls
= !AU->isMainFileAST() && AU->getOnlyLocalDecls();
- if (OnlyLocalDecls && RegionOfInterest.isValid()) {
- // If we would only look at local declarations but we have a region of
- // interest, check whether that region of interest is in the main file.
- // If not, we should traverse all declarations.
- // FIXME: My kingdom for a proper binary search approach to finding
- // cursors!
- std::pair<FileID, unsigned> Location
- = AU->getSourceManager().getDecomposedInstantiationLoc(
- RegionOfInterest.getBegin());
- if (Location.first != AU->getSourceManager().getMainFileID())
- OnlyLocalDecls = false;
- }
-
- PreprocessingRecord::iterator StartEntity, EndEntity;
- if (OnlyLocalDecls) {
- StartEntity = AU->pp_entity_begin();
- EndEntity = AU->pp_entity_end();
- } else {
- StartEntity = PPRec.begin();
- EndEntity = PPRec.end();
- }
-
- // There is no region of interest; we have to walk everything.
- if (RegionOfInterest.isInvalid())
- return std::make_pair(StartEntity, EndEntity);
-
- // Find the file in which the region of interest lands.
- SourceManager &SM = AU->getSourceManager();
- std::pair<FileID, unsigned> Begin
- = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
- std::pair<FileID, unsigned> End
- = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
-
- // The region of interest spans files; we have to walk everything.
- if (Begin.first != End.first)
- return std::make_pair(StartEntity, EndEntity);
+ if (OnlyLocalDecls)
+ return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end());
+
+ return visitPreprocessedEntities(PPRec.begin(), PPRec.end());
+}
+
+template<typename InputIterator>
+bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
+ InputIterator Last) {
+ for (; First != Last; ++First) {
+ if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*First)) {
+ if (Visit(MakeMacroExpansionCursor(ME, TU)))
+ return true;
+
+ continue;
+ }
+
+ if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*First)) {
+ if (Visit(MakeMacroDefinitionCursor(MD, TU)))
+ return true;
+
+ continue;
+ }
- ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
- = AU->getPreprocessedEntitiesByFile();
- if (ByFileMap.empty()) {
- // Build the mapping from files to sets of preprocessed entities.
- for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
- std::pair<FileID, unsigned> P
- = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
+ if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*First)) {
+ if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
+ return true;
- ByFileMap[P.first].push_back(*E);
+ continue;
}
}
- return std::make_pair(ByFileMap[Begin.first].begin(),
- ByFileMap[Begin.first].end());
+ return false;
}
/// \brief Visit the children of the given cursor.
@@ -529,7 +492,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
TLEnd = CXXUnit->top_level_end();
TL != TLEnd; ++TL) {
- if (Visit(MakeCXCursor(*TL, tu), true))
+ if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true))
return true;
}
} else if (VisitDeclContext(
@@ -539,33 +502,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
// Walk the preprocessing record.
- if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
- // FIXME: Once we have the ability to deserialize a preprocessing record,
- // do so.
- PreprocessingRecord::iterator E, EEnd;
- for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
- if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
- if (Visit(MakeMacroExpansionCursor(ME, tu)))
- return true;
-
- continue;
- }
-
- if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
- if (Visit(MakeMacroDefinitionCursor(MD, tu)))
- return true;
-
- continue;
- }
-
- if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
- if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
- return true;
-
- continue;
- }
- }
- }
+ if (CXXUnit->getPreprocessor().getPreprocessingRecord())
+ visitPreprocessedEntitiesInRegion();
}
return false;
@@ -578,7 +516,15 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
}
}
-
+
+ if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
+ IBOutletCollectionAttr *A =
+ cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
+ if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
+ return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
+ A->getInterfaceLoc(), TU));
+ }
+
// Nothing to visit at the moment.
return false;
}
@@ -589,7 +535,7 @@ bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
return true;
if (Stmt *Body = B->getBody())
- return Visit(MakeCXCursor(Body, StmtParent, TU));
+ return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -629,7 +575,7 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
Decl *D = *I;
if (D->getLexicalDeclContext() != DC)
continue;
- CXCursor Cursor = MakeCXCursor(D, TU);
+ CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
@@ -727,7 +673,7 @@ bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (Expr *Init = D->getInitExpr())
- return Visit(MakeCXCursor(Init, StmtParent, TU));
+ return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -794,7 +740,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
// Find the initializers that were written in the source.
- llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
+ SmallVector<CXXCtorInitializer *, 4> WrittenInits;
for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
IEnd = Constructor->init_end();
I != IEnd; ++I) {
@@ -822,12 +768,12 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// Visit the initializer value.
if (Expr *Initializer = Init->getInit())
- if (Visit(MakeCXCursor(Initializer, ND, TU)))
+ if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
return true;
}
}
- if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+ if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
return true;
}
@@ -839,7 +785,7 @@ bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
return true;
if (Expr *BitWidth = D->getBitWidth())
- return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
+ return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -849,7 +795,7 @@ bool CursorVisitor::VisitVarDecl(VarDecl *D) {
return true;
if (Expr *Init = D->getInit())
- return Visit(MakeCXCursor(Init, StmtParent, TU));
+ return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -860,7 +806,7 @@ bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
if (Expr *DefArg = D->getDefaultArgument())
- return Visit(MakeCXCursor(DefArg, StmtParent, TU));
+ return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -902,12 +848,12 @@ bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
PEnd = ND->param_end();
P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU)))
+ if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
return true;
}
if (ND->isThisDeclarationADefinition() &&
- Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+ Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
return true;
return false;
@@ -938,7 +884,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
// in the current DeclContext. If any fall within the
// container's lexical region, stash them into a vector
// for later processing.
- llvm::SmallVector<Decl *, 24> DeclsInContainer;
+ SmallVector<Decl *, 24> DeclsInContainer;
SourceLocation EndLoc = D->getSourceRange().getEnd();
SourceManager &SM = AU->getSourceManager();
if (EndLoc.isValid()) {
@@ -979,9 +925,9 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
ContainerDeclsSort(SM));
// Now visit the decls.
- for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
+ for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
E = DeclsInContainer.end(); I != E; ++I) {
- CXCursor Cursor = MakeCXCursor(*I, TU);
+ CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
@@ -1043,12 +989,12 @@ bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
// the @interface.
if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
- if (Visit(MakeCXCursor(MD, TU)))
+ if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
return true;
if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
- if (Visit(MakeCXCursor(MD, TU)))
+ if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
return true;
return false;
@@ -1110,10 +1056,9 @@ bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
}
bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
- for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
- if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
+ if (Visit(MakeCursorObjCClassRef(D->getForwardInterfaceDecl(),
+ D->getForwardDecl()->getLocation(), TU)))
return true;
-
return false;
}
@@ -1254,7 +1199,7 @@ bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
bool
CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
- llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
+ SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
for (; Qualifier; Qualifier = Qualifier.getPrefix())
Qualifiers.push_back(Qualifier);
@@ -1302,7 +1247,7 @@ bool CursorVisitor::VisitTemplateParameters(
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU)))
+ if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
return true;
}
@@ -1359,12 +1304,12 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
case TemplateArgument::Declaration:
if (Expr *E = TAL.getSourceDeclExpression())
- return Visit(MakeCXCursor(E, StmtParent, TU));
+ return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
return false;
case TemplateArgument::Expression:
if (Expr *E = TAL.getSourceExpression())
- return Visit(MakeCXCursor(E, StmtParent, TU));
+ return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
return false;
case TemplateArgument::Template:
@@ -1414,6 +1359,7 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::Int128:
+ case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
@@ -1455,6 +1401,9 @@ bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
}
bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+ if (TL.isDefinition())
+ return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
+
return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
@@ -1510,6 +1459,10 @@ bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
return Visit(TL.getPointeeLoc());
}
+bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
+ return Visit(TL.getModifiedLoc());
+}
+
bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
bool SkipResultType) {
if (!SkipResultType && Visit(TL.getResultLoc()))
@@ -1517,7 +1470,7 @@ bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
if (Decl *D = TL.getArg(I))
- if (Visit(MakeCXCursor(D, TU)))
+ if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
return true;
return false;
@@ -1528,7 +1481,7 @@ bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
return true;
if (Expr *Size = TL.getSizeExpr())
- return Visit(MakeCXCursor(Size, StmtParent, TU));
+ return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -1599,13 +1552,49 @@ bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
return Visit(TL.getPatternLoc());
}
+bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+ if (Expr *E = TL.getUnderlyingExpr())
+ return Visit(MakeCXCursor(E, StmtParent, TU));
+
+ return false;
+}
+
+bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ return Visit(TL.getValueLoc());
+}
+
+#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
+bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ return Visit##PARENT##Loc(TL); \
+}
+
+DEFAULT_TYPELOC_IMPL(Complex, Type)
+DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
+DEFAULT_TYPELOC_IMPL(Vector, Type)
+DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
+DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(Record, TagType)
+DEFAULT_TYPELOC_IMPL(Enum, TagType)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
+DEFAULT_TYPELOC_IMPL(Auto, Type)
+
bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Visit the nested-name-specifier, if present.
if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
return true;
- if (D->isDefinition()) {
+ if (D->isCompleteDefinition()) {
for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
E = D->bases_end(); I != E; ++I) {
if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
@@ -1642,7 +1631,7 @@ DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
-DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
+DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
ExplicitTemplateArgsVisitKind)
DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
#undef DEF_JOB
@@ -1687,27 +1676,6 @@ public:
SourceLocation getLoc() const {
return SourceLocation::getFromPtrEncoding(data[1]); }
};
-class NestedNameSpecifierVisit : public VisitorJob {
-public:
- NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
- CXCursor parent)
- : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
- NS, R.getBegin().getPtrEncoding(),
- R.getEnd().getPtrEncoding()) {}
- static bool classof(const VisitorJob *VJ) {
- return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
- }
- NestedNameSpecifier *get() const {
- return static_cast<NestedNameSpecifier*>(data[0]);
- }
- SourceRange getSourceRange() const {
- SourceLocation A =
- SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
- SourceLocation B =
- SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
- return SourceRange(A, B);
- }
-};
class NestedNameSpecifierLocVisit : public VisitorJob {
public:
@@ -1809,9 +1777,8 @@ public:
private:
void AddDeclarationNameInfo(Stmt *S);
- void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
- void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
+ void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
void AddMemberRef(FieldDecl *D, SourceLocation L);
void AddStmt(Stmt *S);
void AddDecl(Decl *D, bool isFirst = true);
@@ -1825,11 +1792,6 @@ void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
// statement we are visiting.
WL.push_back(DeclarationNameInfoVisit(S, Parent));
}
-void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
- SourceRange R) {
- if (N)
- WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
-}
void
EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
@@ -1846,10 +1808,10 @@ void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
WL.push_back(DeclVisit(D, Parent, isFirst));
}
void EnqueueVisitor::
- AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
+ AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
if (A)
WL.push_back(ExplicitTemplateArgsVisit(
- const_cast<ExplicitTemplateArgumentList*>(A), Parent));
+ const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
}
void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
if (D)
@@ -2114,7 +2076,7 @@ void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
}
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
- EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
+ EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
@@ -2142,13 +2104,14 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
// For now, perform default visitation for Decls.
- if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
+ if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
+ cast<DeclVisit>(&LI)->isFirst())))
return true;
continue;
}
case VisitorJob::ExplicitTemplateArgsVisitKind: {
- const ExplicitTemplateArgumentList *ArgList =
+ const ASTTemplateArgumentListInfo *ArgList =
cast<ExplicitTemplateArgsVisit>(&LI)->get();
for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
*ArgEnd = Arg + ArgList->NumTemplateArgs;
@@ -2174,14 +2137,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
}
continue;
}
-
- case VisitorJob::NestedNameSpecifierVisitKind: {
- NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
- if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
- return true;
- continue;
- }
-
+
case VisitorJob::NestedNameSpecifierLocVisitKind: {
NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
if (VisitNestedNameSpecifierLoc(V->get()))
@@ -2207,7 +2163,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
// Update the current cursor.
- CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
+ CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
if (!IsInRegionOfInterest(Cursor))
continue;
switch (Visitor(Cursor, Parent, ClientData)) {
@@ -2313,6 +2269,47 @@ bool CursorVisitor::Visit(Stmt *S) {
return result;
}
+namespace {
+typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
+RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
+ const DeclarationNameInfo &NI,
+ const SourceRange &QLoc,
+ const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+ const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
+ const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
+ const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
+
+ const DeclarationName::NameKind Kind = NI.getName().getNameKind();
+
+ RefNamePieces Pieces;
+
+ if (WantQualifier && QLoc.isValid())
+ Pieces.push_back(QLoc);
+
+ if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
+ Pieces.push_back(NI.getLoc());
+
+ if (WantTemplateArgs && TemplateArgs)
+ Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
+ TemplateArgs->RAngleLoc));
+
+ if (Kind == DeclarationName::CXXOperatorName) {
+ Pieces.push_back(SourceLocation::getFromRawEncoding(
+ NI.getInfo().CXXOperatorName.BeginOpNameLoc));
+ Pieces.push_back(SourceLocation::getFromRawEncoding(
+ NI.getInfo().CXXOperatorName.EndOpNameLoc));
+ }
+
+ if (WantSinglePiece) {
+ SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
+ Pieces.clear();
+ Pieces.push_back(R);
+ }
+
+ return Pieces;
+}
+}
+
//===----------------------------------------------------------------------===//
// Misc. API hooks.
//===----------------------------------------------------------------------===//
@@ -2369,7 +2366,7 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
FileSystemOptions FileSystemOpts;
FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
CXXIdx->getOnlyLocalDecls(),
0, 0, true);
@@ -2378,9 +2375,7 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
unsigned clang_defaultEditingTranslationUnitOptions() {
return CXTranslationUnit_PrecompiledPreamble |
- CXTranslationUnit_CacheCompletionResults |
- CXTranslationUnit_CXXPrecompiledPreamble |
- CXTranslationUnit_CXXChainedPCH;
+ CXTranslationUnit_CacheCompletionResults;
}
CXTranslationUnit
@@ -2426,24 +2421,21 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
- bool CompleteTranslationUnit
- = ((options & CXTranslationUnit_Incomplete) == 0);
+ // FIXME: Add a flag for modules.
+ TranslationUnitKind TUKind
+ = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
bool CacheCodeCompetionResults
= options & CXTranslationUnit_CacheCompletionResults;
- bool CXXPrecompilePreamble
- = options & CXTranslationUnit_CXXPrecompiledPreamble;
- bool CXXChainedPCH
- = options & CXTranslationUnit_CXXChainedPCH;
// Configure the diagnostics.
DiagnosticOptions DiagOpts;
- llvm::IntrusiveRefCntPtr<Diagnostic>
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
command_line_args));
// Recover resources if we crash before exiting this function.
- llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
- llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
+ llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
+ llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
@@ -2454,7 +2446,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
const llvm::MemoryBuffer *Buffer
= llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
@@ -2517,10 +2509,8 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
RemappedFiles->size(),
/*RemappedFilesKeepOriginalName=*/true,
PrecompilePreamble,
- CompleteTranslationUnit,
+ TUKind,
CacheCodeCompetionResults,
- CXXPrecompilePreamble,
- CXXChainedPCH,
NestedMacroExpansions));
if (NumErrors != Diags->getClient()->getNumErrors()) {
@@ -2651,7 +2641,7 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
const llvm::MemoryBuffer *Buffer
= llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
@@ -2691,7 +2681,7 @@ CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
+ CXCursor Result = { CXCursor_TranslationUnit, 0, { 0, 0, TU } };
return Result;
}
@@ -2722,9 +2712,9 @@ CXSourceLocation clang_getLocation(CXTranslationUnit tu,
bool Logging = ::getenv("LIBCLANG_LOGGING");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
const FileEntry *File = static_cast<const FileEntry *>(file);
- SourceLocation SLoc
- = CXXUnit->getSourceManager().getLocation(File, line, column);
+ SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
if (Logging)
llvm::errs() << "clang_getLocation(\"" << File->getName()
@@ -2747,14 +2737,8 @@ CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
return clang_getNullLocation();
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
- SourceLocation Start
- = CXXUnit->getSourceManager().getLocation(
- static_cast<const FileEntry *>(file),
- 1, 1);
- if (Start.isInvalid()) return clang_getNullLocation();
-
- SourceLocation SLoc = Start.getFileLocWithOffset(offset);
-
+ SourceLocation SLoc
+ = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
if (SLoc.isInvalid()) return clang_getNullLocation();
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
@@ -2774,6 +2758,19 @@ CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
begin.int_data, end.int_data };
return Result;
}
+
+unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2)
+{
+ return range1.ptr_data[0] == range2.ptr_data[0]
+ && range1.ptr_data[1] == range2.ptr_data[1]
+ && range1.begin_int_data == range2.begin_int_data
+ && range1.end_int_data == range2.end_int_data;
+}
+
+int clang_Range_isNull(CXSourceRange range) {
+ return clang_equalRanges(range, clang_getNullRange());
+}
+
} // end: extern "C"
static void createNullLocation(CXFile *file, unsigned *line,
@@ -2790,11 +2787,11 @@ static void createNullLocation(CXFile *file, unsigned *line,
}
extern "C" {
-void clang_getInstantiationLocation(CXSourceLocation location,
- CXFile *file,
- unsigned *line,
- unsigned *column,
- unsigned *offset) {
+void clang_getExpansionLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
if (!location.ptr_data[0] || Loc.isInvalid()) {
@@ -2804,11 +2801,11 @@ void clang_getInstantiationLocation(CXSourceLocation location,
const SourceManager &SM =
*static_cast<const SourceManager*>(location.ptr_data[0]);
- SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
+ SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
// Check that the FileID is invalid on the expansion location.
// This can manifest in invalid code.
- FileID fileID = SM.getFileID(InstLoc);
+ FileID fileID = SM.getFileID(ExpansionLoc);
bool Invalid = false;
const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
if (!sloc.isFile() || Invalid) {
@@ -2819,11 +2816,48 @@ void clang_getInstantiationLocation(CXSourceLocation location,
if (file)
*file = (void *)SM.getFileEntryForSLocEntry(sloc);
if (line)
- *line = SM.getInstantiationLineNumber(InstLoc);
+ *line = SM.getExpansionLineNumber(ExpansionLoc);
if (column)
- *column = SM.getInstantiationColumnNumber(InstLoc);
+ *column = SM.getExpansionColumnNumber(ExpansionLoc);
if (offset)
- *offset = SM.getDecomposedLoc(InstLoc).second;
+ *offset = SM.getDecomposedLoc(ExpansionLoc).second;
+}
+
+void clang_getPresumedLocation(CXSourceLocation location,
+ CXString *filename,
+ unsigned *line,
+ unsigned *column) {
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid()) {
+ if (filename)
+ *filename = createCXString("");
+ if (line)
+ *line = 0;
+ if (column)
+ *column = 0;
+ }
+ else {
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
+
+ if (filename)
+ *filename = createCXString(PreLoc.getFilename());
+ if (line)
+ *line = PreLoc.getLine();
+ if (column)
+ *column = PreLoc.getColumn();
+ }
+}
+
+void clang_getInstantiationLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+ // Redirect to new API.
+ clang_getExpansionLocation(location, file, line, column, offset);
}
void clang_getSpellingLocation(CXSourceLocation location,
@@ -2845,7 +2879,7 @@ void clang_getSpellingLocation(CXSourceLocation location,
SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
SpellLoc = SimpleSpellingLoc;
else
- SpellLoc = SM.getInstantiationLoc(SpellLoc);
+ SpellLoc = SM.getExpansionLoc(SpellLoc);
}
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
@@ -2927,7 +2961,7 @@ unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
//===----------------------------------------------------------------------===//
static Decl *getDeclFromExpr(Stmt *E) {
- if (CastExpr *CE = dyn_cast<CastExpr>(E))
+ if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getDeclFromExpr(CE->getSubExpr());
if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
@@ -2943,7 +2977,7 @@ static Decl *getDeclFromExpr(Stmt *E) {
if (CallExpr *CE = dyn_cast<CallExpr>(E))
return getDeclFromExpr(CE->getCallee());
- if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
+ if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
if (!CE->isElidable())
return CE->getConstructor();
if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
@@ -2963,6 +2997,9 @@ static Decl *getDeclFromExpr(Stmt *E) {
}
static SourceLocation getLocationFromExpr(Expr *E) {
+ if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+ return getLocationFromExpr(CE->getSubExpr());
+
if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
return /*FIXME:*/Msg->getLeftLoc();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
@@ -2985,7 +3022,6 @@ unsigned clang_visitChildren(CXCursor parent,
CXCursorVisitor visitor,
CXClientData client_data) {
CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
- getCursorASTUnit(parent)->getMaxPCHLevel(),
false);
return CursorVis.VisitChildren(parent);
}
@@ -3030,7 +3066,7 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent,
static CXString getDeclSpelling(Decl *D) {
NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
if (!ND) {
- if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
+ if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return createCXString(Property->getIdentifier()->getName());
@@ -3165,6 +3201,11 @@ CXString clang_getCursorSpelling(CXCursor C) {
if (clang_isDeclaration(C.kind))
return getDeclSpelling(getCursorDecl(C));
+ if (C.kind == CXCursor_AnnotateAttr) {
+ AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
+ return createCXString(AA->getAnnotation());
+ }
+
return createCXString("");
}
@@ -3176,7 +3217,7 @@ CXString clang_getCursorDisplayName(CXCursor C) {
if (!D)
return createCXString("");
- PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
+ PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
D = FunTmpl->getTemplatedDecl();
@@ -3314,10 +3355,86 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("LabelRef");
case CXCursor_OverloadedDeclRef:
return createCXString("OverloadedDeclRef");
- case CXCursor_UnexposedExpr:
- return createCXString("UnexposedExpr");
+ case CXCursor_IntegerLiteral:
+ return createCXString("IntegerLiteral");
+ case CXCursor_FloatingLiteral:
+ return createCXString("FloatingLiteral");
+ case CXCursor_ImaginaryLiteral:
+ return createCXString("ImaginaryLiteral");
+ case CXCursor_StringLiteral:
+ return createCXString("StringLiteral");
+ case CXCursor_CharacterLiteral:
+ return createCXString("CharacterLiteral");
+ case CXCursor_ParenExpr:
+ return createCXString("ParenExpr");
+ case CXCursor_UnaryOperator:
+ return createCXString("UnaryOperator");
+ case CXCursor_ArraySubscriptExpr:
+ return createCXString("ArraySubscriptExpr");
+ case CXCursor_BinaryOperator:
+ return createCXString("BinaryOperator");
+ case CXCursor_CompoundAssignOperator:
+ return createCXString("CompoundAssignOperator");
+ case CXCursor_ConditionalOperator:
+ return createCXString("ConditionalOperator");
+ case CXCursor_CStyleCastExpr:
+ return createCXString("CStyleCastExpr");
+ case CXCursor_CompoundLiteralExpr:
+ return createCXString("CompoundLiteralExpr");
+ case CXCursor_InitListExpr:
+ return createCXString("InitListExpr");
+ case CXCursor_AddrLabelExpr:
+ return createCXString("AddrLabelExpr");
+ case CXCursor_StmtExpr:
+ return createCXString("StmtExpr");
+ case CXCursor_GenericSelectionExpr:
+ return createCXString("GenericSelectionExpr");
+ case CXCursor_GNUNullExpr:
+ return createCXString("GNUNullExpr");
+ case CXCursor_CXXStaticCastExpr:
+ return createCXString("CXXStaticCastExpr");
+ case CXCursor_CXXDynamicCastExpr:
+ return createCXString("CXXDynamicCastExpr");
+ case CXCursor_CXXReinterpretCastExpr:
+ return createCXString("CXXReinterpretCastExpr");
+ case CXCursor_CXXConstCastExpr:
+ return createCXString("CXXConstCastExpr");
+ case CXCursor_CXXFunctionalCastExpr:
+ return createCXString("CXXFunctionalCastExpr");
+ case CXCursor_CXXTypeidExpr:
+ return createCXString("CXXTypeidExpr");
+ case CXCursor_CXXBoolLiteralExpr:
+ return createCXString("CXXBoolLiteralExpr");
+ case CXCursor_CXXNullPtrLiteralExpr:
+ return createCXString("CXXNullPtrLiteralExpr");
+ case CXCursor_CXXThisExpr:
+ return createCXString("CXXThisExpr");
+ case CXCursor_CXXThrowExpr:
+ return createCXString("CXXThrowExpr");
+ case CXCursor_CXXNewExpr:
+ return createCXString("CXXNewExpr");
+ case CXCursor_CXXDeleteExpr:
+ return createCXString("CXXDeleteExpr");
+ case CXCursor_UnaryExpr:
+ return createCXString("UnaryExpr");
+ case CXCursor_ObjCStringLiteral:
+ return createCXString("ObjCStringLiteral");
+ case CXCursor_ObjCEncodeExpr:
+ return createCXString("ObjCEncodeExpr");
+ case CXCursor_ObjCSelectorExpr:
+ return createCXString("ObjCSelectorExpr");
+ case CXCursor_ObjCProtocolExpr:
+ return createCXString("ObjCProtocolExpr");
+ case CXCursor_ObjCBridgedCastExpr:
+ return createCXString("ObjCBridgedCastExpr");
case CXCursor_BlockExpr:
return createCXString("BlockExpr");
+ case CXCursor_PackExpansionExpr:
+ return createCXString("PackExpansionExpr");
+ case CXCursor_SizeOfPackExpr:
+ return createCXString("SizeOfPackExpr");
+ case CXCursor_UnexposedExpr:
+ return createCXString("UnexposedExpr");
case CXCursor_DeclRefExpr:
return createCXString("DeclRefExpr");
case CXCursor_MemberRefExpr:
@@ -3328,8 +3445,66 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("ObjCMessageExpr");
case CXCursor_UnexposedStmt:
return createCXString("UnexposedStmt");
+ case CXCursor_DeclStmt:
+ return createCXString("DeclStmt");
case CXCursor_LabelStmt:
return createCXString("LabelStmt");
+ case CXCursor_CompoundStmt:
+ return createCXString("CompoundStmt");
+ case CXCursor_CaseStmt:
+ return createCXString("CaseStmt");
+ case CXCursor_DefaultStmt:
+ return createCXString("DefaultStmt");
+ case CXCursor_IfStmt:
+ return createCXString("IfStmt");
+ case CXCursor_SwitchStmt:
+ return createCXString("SwitchStmt");
+ case CXCursor_WhileStmt:
+ return createCXString("WhileStmt");
+ case CXCursor_DoStmt:
+ return createCXString("DoStmt");
+ case CXCursor_ForStmt:
+ return createCXString("ForStmt");
+ case CXCursor_GotoStmt:
+ return createCXString("GotoStmt");
+ case CXCursor_IndirectGotoStmt:
+ return createCXString("IndirectGotoStmt");
+ case CXCursor_ContinueStmt:
+ return createCXString("ContinueStmt");
+ case CXCursor_BreakStmt:
+ return createCXString("BreakStmt");
+ case CXCursor_ReturnStmt:
+ return createCXString("ReturnStmt");
+ case CXCursor_AsmStmt:
+ return createCXString("AsmStmt");
+ case CXCursor_ObjCAtTryStmt:
+ return createCXString("ObjCAtTryStmt");
+ case CXCursor_ObjCAtCatchStmt:
+ return createCXString("ObjCAtCatchStmt");
+ case CXCursor_ObjCAtFinallyStmt:
+ return createCXString("ObjCAtFinallyStmt");
+ case CXCursor_ObjCAtThrowStmt:
+ return createCXString("ObjCAtThrowStmt");
+ case CXCursor_ObjCAtSynchronizedStmt:
+ return createCXString("ObjCAtSynchronizedStmt");
+ case CXCursor_ObjCAutoreleasePoolStmt:
+ return createCXString("ObjCAutoreleasePoolStmt");
+ case CXCursor_ObjCForCollectionStmt:
+ return createCXString("ObjCForCollectionStmt");
+ case CXCursor_CXXCatchStmt:
+ return createCXString("CXXCatchStmt");
+ case CXCursor_CXXTryStmt:
+ return createCXString("CXXTryStmt");
+ case CXCursor_CXXForRangeStmt:
+ return createCXString("CXXForRangeStmt");
+ case CXCursor_SEHTryStmt:
+ return createCXString("SEHTryStmt");
+ case CXCursor_SEHExceptStmt:
+ return createCXString("SEHExceptStmt");
+ case CXCursor_SEHFinallyStmt:
+ return createCXString("SEHFinallyStmt");
+ case CXCursor_NullStmt:
+ return createCXString("NullStmt");
case CXCursor_InvalidFile:
return createCXString("InvalidFile");
case CXCursor_InvalidCode:
@@ -3348,6 +3523,12 @@ 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_AnnotateAttr:
+ return createCXString("attribute(annotate)");
case CXCursor_PreprocessingDirective:
return createCXString("preprocessing directive");
case CXCursor_MacroDefinition:
@@ -3392,6 +3573,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("ObjCSynthesizeDecl");
case CXCursor_ObjCDynamicDecl:
return createCXString("ObjCDynamicDecl");
+ case CXCursor_CXXAccessSpecifier:
+ return createCXString("CXXAccessSpecifier");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3400,18 +3583,35 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
struct GetCursorData {
SourceLocation TokenBeginLoc;
+ bool PointsAtMacroArgExpansion;
CXCursor &BestCursor;
- GetCursorData(SourceLocation tokenBegin, CXCursor &outputCursor)
- : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { }
+ GetCursorData(SourceManager &SM,
+ SourceLocation tokenBegin, CXCursor &outputCursor)
+ : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
+ PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
+ }
};
-enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
- CXCursor parent,
- CXClientData client_data) {
+static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
+ CXCursor parent,
+ CXClientData client_data) {
GetCursorData *Data = static_cast<GetCursorData *>(client_data);
CXCursor *BestCursor = &Data->BestCursor;
+ // If we point inside a macro argument we should provide info of what the
+ // token is so use the actual cursor, don't replace it with a macro expansion
+ // cursor.
+ if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
+ return CXChildVisit_Recurse;
+
+ if (clang_isDeclaration(cursor.kind)) {
+ // Avoid having the implicit methods override the property decls.
+ if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCursorDecl(cursor)))
+ if (MD->isImplicit())
+ return CXChildVisit_Break;
+ }
+
if (clang_isExpression(cursor.kind) &&
clang_isDeclaration(BestCursor->kind)) {
Decl *D = getCursorDecl(*BestCursor);
@@ -3431,14 +3631,12 @@ enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
// clang_getCursor() to point at the constructor.
if (clang_isExpression(BestCursor->kind) &&
isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
- cursor.kind == CXCursor_TypeRef)
- return CXChildVisit_Recurse;
-
- // Don't override a preprocessing cursor with another preprocessing
- // cursor; we want the outermost preprocessing cursor.
- if (clang_isPreprocessing(cursor.kind) &&
- clang_isPreprocessing(BestCursor->kind))
+ cursor.kind == CXCursor_TypeRef) {
+ // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
+ // as having the actual point on the type reference.
+ *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
return CXChildVisit_Recurse;
+ }
*BestCursor = cursor;
return CXChildVisit_Recurse;
@@ -3451,31 +3649,10 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
- // Translate the given source location to make it point at the beginning of
- // the token under the cursor.
SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
-
- // Guard against an invalid SourceLocation, or we may assert in one
- // of the following calls.
- if (SLoc.isInvalid())
- return clang_getNullCursor();
+ CXCursor Result = cxcursor::getCursor(TU, SLoc);
bool Logging = getenv("LIBCLANG_LOGGING");
- SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
- CXXUnit->getASTContext().getLangOptions());
-
- CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
- if (SLoc.isValid()) {
- // 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.
- GetCursorData ResultData(SLoc, Result);
- CXCursor Parent = clang_getTranslationUnitCursor(TU);
- CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
- Decl::MaxPCHLevel, true, SourceLocation(SLoc));
- CursorVis.VisitChildren(Parent);
- }
-
if (Logging) {
CXFile SearchFile;
unsigned SearchLine, SearchColumn;
@@ -3485,10 +3662,9 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
- clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
- 0);
- clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
- &ResultColumn, 0);
+ clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+ clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
+ &ResultColumn, 0);
SearchFileName = clang_getFileName(SearchFile);
ResultFileName = clang_getFileName(ResultFile);
KindSpelling = clang_getCursorKindSpelling(Result.kind);
@@ -3510,8 +3686,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
= clang_getCursorKindSpelling(Definition.kind);
CXFile DefinitionFile;
unsigned DefinitionLine, DefinitionColumn;
- clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
- &DefinitionLine, &DefinitionColumn, 0);
+ clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
+ &DefinitionLine, &DefinitionColumn, 0);
CXString DefinitionFileName = clang_getFileName(DefinitionFile);
fprintf(stderr, " -> %s(%s:%d:%d)\n",
clang_getCString(DefinitionKindSpelling),
@@ -3694,8 +3870,6 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
Decl *D = getCursorDecl(C);
SourceLocation Loc = D->getLocation();
- if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
- Loc = Class->getClassLoc();
// FIXME: Multiple variables declared in a single declaration
// currently lack the information needed to correctly determine their
// ranges when accounting for the type-specifier. We use context
@@ -3711,6 +3885,37 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
} // end extern "C"
+CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
+ assert(TU);
+
+ // Guard against an invalid SourceLocation, or we may assert in one
+ // of the following calls.
+ if (SLoc.isInvalid())
+ return clang_getNullCursor();
+
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+ // Translate the given source location to make it point at the beginning of
+ // the token under the cursor.
+ SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
+ CXXUnit->getASTContext().getLangOptions());
+
+ CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
+ if (SLoc.isValid()) {
+ // 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.
+ GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
+ CXCursor Parent = clang_getTranslationUnitCursor(TU);
+ CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
+ /*VisitPreprocessorLast=*/true,
+ SourceLocation(SLoc));
+ CursorVis.VisitChildren(Parent);
+ }
+
+ return Result;
+}
+
static SourceRange getRawCursorExtent(CXCursor C) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
@@ -3756,17 +3961,29 @@ 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);
- if (C.kind == CXCursor_MacroExpansion)
- return cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ if (C.kind == CXCursor_MacroExpansion) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
- if (C.kind == CXCursor_MacroDefinition)
- return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+ if (C.kind == CXCursor_MacroDefinition) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
- if (C.kind == CXCursor_InclusionDirective)
- return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
+ if (C.kind == CXCursor_InclusionDirective) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
Decl *D = cxcursor::getCursorDecl(C);
@@ -3847,7 +4064,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
if (ObjCForwardProtocolDecl *Protocols
= dyn_cast<ObjCForwardProtocolDecl>(D))
return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
- if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
+ if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return MakeCXCursor(Property, tu);
@@ -3857,8 +4074,12 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
if (clang_isExpression(C.kind)) {
Expr *E = getCursorExpr(C);
Decl *D = getDeclFromExpr(E);
- if (D)
- return MakeCXCursor(D, tu);
+ if (D) {
+ CXCursor declCursor = MakeCXCursor(D, tu);
+ declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
+ declCursor);
+ return declCursor;
+ }
if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
return MakeCursorOverloadedDeclRef(Ovl, tu);
@@ -3981,6 +4202,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::StaticAssert:
case Decl::Block:
case Decl::Label: // FIXME: Is this right??
+ case Decl::ClassScopeFunctionSpecialization:
return C;
// Declaration kinds that don't make any sense here, but are
@@ -4171,8 +4393,8 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) {
Decl *D = Storage.get<Decl*>();
if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
return Using->shadow_size();
- if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
- return Classes->size();
+ if (isa<ObjCClassDecl>(D))
+ return 1;
if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
return Protocols->protocol_size();
@@ -4202,10 +4424,8 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
std::advance(Pos, index);
return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
}
-
if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
- return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
-
+ return MakeCXCursor(Classes->getForwardInterfaceDecl(), TU);
if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
return MakeCXCursor(Protocols->protocol_begin()[index], TU);
@@ -4233,6 +4453,54 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,
*endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
}
+
+CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
+ unsigned PieceIndex) {
+ RefNamePieces Pieces;
+
+ switch (C.kind) {
+ case CXCursor_MemberRefExpr:
+ if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
+ Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
+ E->getQualifierLoc().getSourceRange());
+ break;
+
+ case CXCursor_DeclRefExpr:
+ if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
+ Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
+ E->getQualifierLoc().getSourceRange(),
+ E->getExplicitTemplateArgsOpt());
+ break;
+
+ case CXCursor_CallExpr:
+ if (CXXOperatorCallExpr *OCE =
+ dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
+ Expr *Callee = OCE->getCallee();
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+ Callee = ICE->getSubExpr();
+
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
+ Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
+ DRE->getQualifierLoc().getSourceRange());
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (Pieces.empty()) {
+ if (PieceIndex == 0)
+ return clang_getCursorExtent(C);
+ } else if (PieceIndex < Pieces.size()) {
+ SourceRange R = Pieces[PieceIndex];
+ if (R.isValid())
+ return cxloc::translateSourceRange(getCursorContext(C), R);
+ }
+
+ return clang_getNullRange();
+}
+
void clang_enableStackTraces(void) {
llvm::sys::PrintStackTraceOnErrorSignal();
}
@@ -4273,7 +4541,7 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
case CXToken_Literal: {
// We have stashed the starting pointer in the ptr_data field. Use it.
const char *Text = static_cast<const char *>(CXTok.ptr_data);
- return createCXString(llvm::StringRef(Text, CXTok.int_data[2]));
+ return createCXString(StringRef(Text, CXTok.int_data[2]));
}
case CXToken_Punctuation:
@@ -4289,9 +4557,9 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
std::pair<FileID, unsigned> LocInfo
- = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
+ = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
bool Invalid = false;
- llvm::StringRef Buffer
+ StringRef Buffer
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
if (Invalid)
return createCXString("");
@@ -4317,28 +4585,13 @@ CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
}
-void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
- CXToken **Tokens, unsigned *NumTokens) {
- if (Tokens)
- *Tokens = 0;
- if (NumTokens)
- *NumTokens = 0;
-
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
- if (!CXXUnit || !Tokens || !NumTokens)
- return;
-
- ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-
- SourceRange R = cxloc::translateCXSourceRange(Range);
- if (R.isInvalid())
- return;
-
+static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
+ SmallVectorImpl<CXToken> &CXTokens) {
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(R.getBegin());
+ = SourceMgr.getDecomposedLoc(Range.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(R.getEnd());
+ = SourceMgr.getDecomposedLoc(Range.getEnd());
// Cannot tokenize across files.
if (BeginLocInfo.first != EndLocInfo.first)
@@ -4346,7 +4599,7 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
// Create a lexer
bool Invalid = false;
- llvm::StringRef Buffer
+ StringRef Buffer
= SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
if (Invalid)
return;
@@ -4358,7 +4611,6 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
// Lex tokens until we hit the end of the range.
const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
- llvm::SmallVector<CXToken, 32> CXTokens;
Token Tok;
bool previousWasAt = false;
do {
@@ -4403,6 +4655,27 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
CXTokens.push_back(CXTok);
previousWasAt = Tok.is(tok::at);
} while (Lex.getBufferLocation() <= EffectiveBufferEnd);
+}
+
+void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+ CXToken **Tokens, unsigned *NumTokens) {
+ if (Tokens)
+ *Tokens = 0;
+ if (NumTokens)
+ *NumTokens = 0;
+
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ if (!CXXUnit || !Tokens || !NumTokens)
+ return;
+
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ SourceRange R = cxloc::translateCXSourceRange(Range);
+ if (R.isInvalid())
+ return;
+
+ SmallVector<CXToken, 32> CXTokens;
+ getTokens(CXXUnit, R, CXTokens);
if (CXTokens.empty())
return;
@@ -4445,6 +4718,16 @@ class AnnotateTokensWorker {
SourceLocation GetTokenLoc(unsigned tokI) {
return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
}
+ bool isFunctionMacroToken(unsigned tokI) const {
+ return Tokens[tokI].int_data[3] != 0;
+ }
+ SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
+ return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+ }
+
+ void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
+ void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+ SourceRange);
public:
AnnotateTokensWorker(AnnotateTokensData &annotated,
@@ -4453,8 +4736,7 @@ public:
: Annotated(annotated), Tokens(tokens), Cursors(cursors),
NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
AnnotateVis(tu,
- AnnotateTokensVisitor, this,
- Decl::MaxPCHLevel, true, RegionOfInterest),
+ AnnotateTokensVisitor, this, true, RegionOfInterest),
SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
HasContextSensitiveKeywords(false) { }
@@ -4497,6 +4779,65 @@ void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
}
}
+/// \brief It annotates and advances tokens with a cursor until the comparison
+//// between the cursor location and the source range is the same as
+/// \arg compResult.
+///
+/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
+/// Pass RangeOverlap to annotate tokens inside a range.
+void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
+ RangeComparisonResult compResult,
+ SourceRange range) {
+ while (MoreTokens()) {
+ const unsigned I = NextToken();
+ if (isFunctionMacroToken(I))
+ return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
+
+ SourceLocation TokLoc = GetTokenLoc(I);
+ if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+ Cursors[I] = updateC;
+ AdvanceToken();
+ continue;
+ }
+ break;
+ }
+}
+
+/// \brief Special annotation handling for macro argument tokens.
+void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
+ CXCursor updateC,
+ RangeComparisonResult compResult,
+ SourceRange range) {
+ assert(MoreTokens());
+ assert(isFunctionMacroToken(NextToken()) &&
+ "Should be called only for macro arg tokens");
+
+ // This works differently than annotateAndAdvanceTokens; because expanded
+ // macro arguments can have arbitrary translation-unit source order, we do not
+ // advance the token index one by one until a token fails the range test.
+ // We only advance once past all of the macro arg tokens if all of them
+ // pass the range test. If one of them fails we keep the token index pointing
+ // at the start of the macro arg tokens so that the failing token will be
+ // annotated by a subsequent annotation try.
+
+ bool atLeastOneCompFail = false;
+
+ unsigned I = NextToken();
+ for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
+ SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
+ if (TokLoc.isFileID())
+ continue; // not macro arg token, it's parens or comma.
+ if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+ if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
+ Cursors[I] = updateC;
+ } else
+ atLeastOneCompFail = true;
+ }
+
+ if (!atLeastOneCompFail)
+ TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+}
+
enum CXChildVisitResult
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
CXSourceLocation Loc = clang_getCursorLocation(cursor);
@@ -4584,7 +4925,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
SourceLocation TokLoc = GetTokenLoc(I);
switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
case RangeBefore:
- assert(0 && "Infeasible");
+ llvm_unreachable("Infeasible");
case RangeAfter:
break;
case RangeOverlap:
@@ -4611,12 +4952,6 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Decl *D = cxcursor::getCursorDecl(cursor);
- // Don't visit synthesized ObjC methods, since they have no syntatic
- // representation in the source.
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (MD->isSynthesized())
- return CXChildVisit_Continue;
- }
SourceLocation StartLoc;
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
@@ -4654,20 +4989,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
(clang_isInvalid(K) || K == CXCursor_TranslationUnit)
? clang_getNullCursor() : parent;
- while (MoreTokens()) {
- const unsigned I = NextToken();
- SourceLocation TokLoc = GetTokenLoc(I);
- switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
- case RangeBefore:
- Cursors[I] = updateC;
- AdvanceToken();
- continue;
- case RangeAfter:
- case RangeOverlap:
- break;
- }
- break;
- }
+ annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
// Avoid having the cursor of an expression "overwrite" the annotation of the
// variable declaration that it belongs to.
@@ -4692,46 +5014,19 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
VisitChildren(cursor);
const unsigned AfterChildren = NextToken();
- // Adjust 'Last' to the last token within the extent of the cursor.
- while (MoreTokens()) {
- const unsigned I = NextToken();
- SourceLocation TokLoc = GetTokenLoc(I);
- switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
- case RangeBefore:
- assert(0 && "Infeasible");
- case RangeAfter:
- break;
- case RangeOverlap:
- Cursors[I] = updateC;
- AdvanceToken();
- continue;
- }
- break;
- }
- const unsigned Last = NextToken();
+ // Scan the tokens that are at the end of the cursor, but are not captured
+ // but the child cursors.
+ annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
// Scan the tokens that are at the beginning of the cursor, but are not
// capture by the child cursors.
-
- // For AST elements within macros, rely on a post-annotate pass to
- // to correctly annotate the tokens with cursors. Otherwise we can
- // get confusing results of having tokens that map to cursors that really
- // are expanded by an instantiation.
- if (L.isMacroID())
- cursor = clang_getNullCursor();
-
for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
break;
Cursors[I] = cursor;
}
- // Scan the tokens that are at the end of the cursor, but are not captured
- // but the child cursors.
- for (unsigned I = AfterChildren; I != Last; ++I)
- Cursors[I] = cursor;
- TokIdx = Last;
return CXChildVisit_Continue;
}
@@ -4742,6 +5037,74 @@ static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
}
namespace {
+
+/// \brief Uses the macro expansions in the preprocessing record to find
+/// and mark tokens that are macro arguments. This info is used by the
+/// AnnotateTokensWorker.
+class MarkMacroArgTokensVisitor {
+ SourceManager &SM;
+ CXToken *Tokens;
+ unsigned NumTokens;
+ unsigned CurIdx;
+
+public:
+ MarkMacroArgTokensVisitor(SourceManager &SM,
+ CXToken *tokens, unsigned numTokens)
+ : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
+
+ CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+ if (cursor.kind != CXCursor_MacroExpansion)
+ return CXChildVisit_Continue;
+
+ SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
+ if (macroRange.getBegin() == macroRange.getEnd())
+ return CXChildVisit_Continue; // it's not a function macro.
+
+ for (; CurIdx < NumTokens; ++CurIdx) {
+ if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
+ macroRange.getBegin()))
+ break;
+ }
+
+ if (CurIdx == NumTokens)
+ return CXChildVisit_Break;
+
+ for (; CurIdx < NumTokens; ++CurIdx) {
+ SourceLocation tokLoc = getTokenLoc(CurIdx);
+ if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
+ break;
+
+ setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
+ }
+
+ if (CurIdx == NumTokens)
+ return CXChildVisit_Break;
+
+ return CXChildVisit_Continue;
+ }
+
+private:
+ SourceLocation getTokenLoc(unsigned tokI) {
+ return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+ }
+
+ void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
+ // The third field is reserved and currently not used. Use it here
+ // to mark macro arg expanded tokens with their expanded locations.
+ Tokens[tokI].int_data[3] = loc.getRawEncoding();
+ }
+};
+
+} // end anonymous namespace
+
+static CXChildVisitResult
+MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
+ CXClientData client_data) {
+ return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
+ parent);
+}
+
+namespace {
struct clang_annotateTokens_Data {
CXTranslationUnit TU;
ASTUnit *CXXUnit;
@@ -4751,6 +5114,73 @@ namespace {
};
}
+static void annotatePreprocessorTokens(CXTranslationUnit TU,
+ SourceRange RegionOfInterest,
+ AnnotateTokensData &Annotated) {
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+ SourceManager &SourceMgr = CXXUnit->getSourceManager();
+ std::pair<FileID, unsigned> BeginLocInfo
+ = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+ std::pair<FileID, unsigned> EndLocInfo
+ = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+
+ if (BeginLocInfo.first != EndLocInfo.first)
+ return;
+
+ StringRef Buffer;
+ bool Invalid = false;
+ Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
+ if (Buffer.empty() || Invalid)
+ return;
+
+ Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+ CXXUnit->getASTContext().getLangOptions(),
+ Buffer.begin(), Buffer.data() + BeginLocInfo.second,
+ Buffer.end());
+ Lex.SetCommentRetentionState(true);
+
+ // Lex tokens in raw mode until we hit the end of the range, to avoid
+ // entering #includes or expanding macros.
+ while (true) {
+ Token Tok;
+ Lex.LexFromRawLexer(Tok);
+
+ reprocess:
+ if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
+ // We have found a preprocessing directive. Gobble it up so that we
+ // don't see it while preprocessing these tokens later, but keep track
+ // of all of the token locations inside this preprocessing directive so
+ // that we can annotate them appropriately.
+ //
+ // FIXME: Some simple tests here could identify macro definitions and
+ // #undefs, to provide specific cursor kinds for those.
+ SmallVector<SourceLocation, 32> Locations;
+ do {
+ Locations.push_back(Tok.getLocation());
+ Lex.LexFromRawLexer(Tok);
+ } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
+
+ using namespace cxcursor;
+ CXCursor Cursor
+ = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
+ Locations.back()),
+ TU);
+ for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
+ Annotated[Locations[I].getRawEncoding()] = Cursor;
+ }
+
+ if (Tok.isAtStartOfLine())
+ goto reprocess;
+
+ continue;
+ }
+
+ if (Tok.is(tok::eof))
+ break;
+ }
+}
+
// This gets run a separate thread to avoid stack blowout.
static void clang_annotateTokensImpl(void *UserData) {
CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
@@ -4770,65 +5200,19 @@ static void clang_annotateTokensImpl(void *UserData) {
// A mapping from the source locations found when re-lexing or traversing the
// region of interest to the corresponding cursors.
AnnotateTokensData Annotated;
-
+
// Relex the tokens within the source range to look for preprocessing
// directives.
- SourceManager &SourceMgr = CXXUnit->getSourceManager();
- std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
- std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+ annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
- llvm::StringRef Buffer;
- bool Invalid = false;
- if (BeginLocInfo.first == EndLocInfo.first &&
- ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
- !Invalid) {
- Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
- CXXUnit->getASTContext().getLangOptions(),
- Buffer.begin(), Buffer.data() + BeginLocInfo.second,
- Buffer.end());
- Lex.SetCommentRetentionState(true);
-
- // Lex tokens in raw mode until we hit the end of the range, to avoid
- // entering #includes or expanding macros.
- while (true) {
- Token Tok;
- Lex.LexFromRawLexer(Tok);
-
- reprocess:
- if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
- // We have found a preprocessing directive. Gobble it up so that we
- // don't see it while preprocessing these tokens later, but keep track
- // of all of the token locations inside this preprocessing directive so
- // that we can annotate them appropriately.
- //
- // FIXME: Some simple tests here could identify macro definitions and
- // #undefs, to provide specific cursor kinds for those.
- llvm::SmallVector<SourceLocation, 32> Locations;
- do {
- Locations.push_back(Tok.getLocation());
- Lex.LexFromRawLexer(Tok);
- } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
-
- using namespace cxcursor;
- CXCursor Cursor
- = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
- Locations.back()),
- TU);
- for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
- Annotated[Locations[I].getRawEncoding()] = Cursor;
- }
-
- if (Tok.isAtStartOfLine())
- goto reprocess;
-
- continue;
- }
-
- if (Tok.is(tok::eof))
- break;
- }
+ if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
+ // Search and mark tokens that are macro argument expansions.
+ MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
+ Tokens, NumTokens);
+ CursorVisitor MacroArgMarker(TU,
+ MarkMacroArgTokensVisitorDelegate, &Visitor,
+ true, RegionOfInterest);
+ MacroArgMarker.visitPreprocessedEntitiesInRegion();
}
// Annotate all of the source locations in the region of interest that map to
@@ -4888,44 +5272,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;
}
}
@@ -5122,62 +5472,6 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
return clang_getNullCursor();
}
-static void CollectOverriddenMethods(DeclContext *Ctx,
- ObjCMethodDecl *Method,
- llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
- if (!Ctx)
- return;
-
- // If we have a class or category implementation, jump straight to the
- // interface.
- if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
- return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
-
- ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
- if (!Container)
- return;
-
- // Check whether we have a matching method at this level.
- if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
- Method->isInstanceMethod()))
- if (Method != Overridden) {
- // We found an override at this level; there is no need to look
- // into other protocols or categories.
- Methods.push_back(Overridden);
- return;
- }
-
- if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
- for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
- PEnd = Protocol->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
- }
-
- if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
- for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
- PEnd = Category->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
- }
-
- if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
- for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
- PEnd = Interface->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
-
- for (ObjCCategoryDecl *Category = Interface->getCategoryList();
- Category; Category = Category->getNextClassCategory())
- CollectOverriddenMethods(Category, Method, Methods);
-
- // We only look into the superclass if we haven't found anything yet.
- if (Methods.empty())
- if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
- return CollectOverriddenMethods(Super, Method, Methods);
- }
-}
-
void clang_getOverriddenCursors(CXCursor cursor,
CXCursor **overridden,
unsigned *num_overridden) {
@@ -5188,45 +5482,12 @@ void clang_getOverriddenCursors(CXCursor cursor,
if (!overridden || !num_overridden)
return;
- if (!clang_isDeclaration(cursor.kind))
- return;
-
- Decl *D = getCursorDecl(cursor);
- if (!D)
- return;
+ SmallVector<CXCursor, 8> Overridden;
+ cxcursor::getOverriddenCursors(cursor, Overridden);
- // Handle C++ member functions.
- CXTranslationUnit TU = getCursorTU(cursor);
- if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
- *num_overridden = CXXMethod->size_overridden_methods();
- if (!*num_overridden)
- return;
-
- *overridden = new CXCursor [*num_overridden];
- unsigned I = 0;
- for (CXXMethodDecl::method_iterator
- M = CXXMethod->begin_overridden_methods(),
- MEnd = CXXMethod->end_overridden_methods();
- M != MEnd; (void)++M, ++I)
- (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
- return;
- }
-
- ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
- if (!Method)
- return;
-
- // Handle Objective-C methods.
- llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
- CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
-
- if (Methods.empty())
- return;
-
- *num_overridden = Methods.size();
- *overridden = new CXCursor [Methods.size()];
- for (unsigned I = 0, N = Methods.size(); I != N; ++I)
- (*overridden)[I] = MakeCXCursor(Methods[I], TU);
+ *num_overridden = Overridden.size();
+ *overridden = new CXCursor [Overridden.size()];
+ std::copy(Overridden.begin(), Overridden.end(), *overridden);
}
void clang_disposeOverriddenCursors(CXCursor *overridden) {
@@ -5274,7 +5535,6 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
Method = dyn_cast_or_null<CXXMethodDecl>(D);
return (Method && Method->isVirtual()) ? 1 : 0;
}
-
} // end: extern "C"
//===----------------------------------------------------------------------===//
@@ -5289,7 +5549,7 @@ CXType clang_getIBOutletCollectionType(CXCursor C) {
IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
- return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
+ return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
}
} // end: extern "C"
@@ -5347,6 +5607,12 @@ const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
case CXTUResourceUsage_PreprocessingRecord:
str = "Preprocessor: PreprocessingRecord";
break;
+ case CXTUResourceUsage_SourceManager_DataStructures:
+ str = "SourceManager: data structures and tables";
+ break;
+ case CXTUResourceUsage_Preprocessor_HeaderSearch:
+ str = "Preprocessor: header search tables";
+ break;
}
return str;
}
@@ -5399,9 +5665,13 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_SourceManager_Membuffer_Malloc,
(unsigned long) srcBufs.malloc_bytes);
- createCXTUResourceUsageEntry(*entries,
+ createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_SourceManager_Membuffer_MMap,
(unsigned long) srcBufs.mmap_bytes);
+ createCXTUResourceUsageEntry(*entries,
+ CXTUResourceUsage_SourceManager_DataStructures,
+ (unsigned long) astContext.getSourceManager()
+ .getDataStructureSizes());
// How much memory is being used by the ExternalASTSource?
if (ExternalASTSource *esrc = astContext.getExternalSource()) {
@@ -5428,6 +5698,9 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
pRec->getTotalMemory());
}
+ createCXTUResourceUsageEntry(*entries,
+ CXTUResourceUsage_Preprocessor_HeaderSearch,
+ pp.getHeaderSearchInfo().getTotalMemory());
CXTUResourceUsage usage = { (void*) entries.get(),
(unsigned) entries->size(),
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 0f49f65..fb0ccb1 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -31,11 +31,16 @@ unsigned clang_isVirtualBase(CXCursor C) {
}
enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
- if (C.kind != CXCursor_CXXBaseSpecifier)
+ AccessSpecifier spec = AS_none;
+
+ if (C.kind == CXCursor_CXXAccessSpecifier)
+ spec = getCursorDecl(C)->getAccess();
+ else if (C.kind == CXCursor_CXXBaseSpecifier)
+ spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
+ else
return CX_CXXInvalidAccessSpecifier;
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
- switch (B->getAccessSpecifier()) {
+ switch (spec) {
case AS_public: return CX_CXXPublic;
case AS_protected: return CX_CXXProtected;
case AS_private: return CX_CXXPrivate;
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 832e2f2..c19b340 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -15,7 +15,12 @@
#include "CIndexer.h"
#include "CXTranslationUnit.h"
#include "CXString.h"
+#include "CXCursor.h"
+#include "CXString.h"
#include "CIndexDiagnostic.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTUnit.h"
@@ -198,6 +203,20 @@ clang_getCompletionAvailability(CXCompletionString completion_string) {
: CXAvailability_Available;
}
+unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
+{
+ CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+ return CCStr ? CCStr->getAnnotationCount() : 0;
+}
+
+CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
+ unsigned annotation_number) {
+ CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+ return CCStr ? createCXString(CCStr->getAnnotation(annotation_number))
+ : createCXString((const char *) 0);
+}
+
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
@@ -205,10 +224,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
~AllocatedCXCodeCompleteResults();
/// \brief Diagnostics produced while performing code completion.
- llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
+ SmallVector<StoredDiagnostic, 8> Diagnostics;
/// \brief Diag object
- llvm::IntrusiveRefCntPtr<Diagnostic> Diag;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
/// \brief Language options used to adjust source locations.
LangOptions LangOpts;
@@ -227,7 +246,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief Temporary buffers that will be deleted once we have finished with
/// the code-completion results.
- llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
+ SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
/// \brief Allocator used to store globally cached code-completion results.
llvm::IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
@@ -242,6 +261,18 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief A bitfield representing the acceptable completions for the
/// current context.
unsigned long long Contexts;
+
+ /// \brief The kind of the container for the current context for completions.
+ enum CXCursorKind ContainerKind;
+ /// \brief The USR of the container for the current context for completions.
+ CXString ContainerUSR;
+ /// \brief a boolean value indicating whether there is complete information
+ /// about the container
+ unsigned ContainerIsIncomplete;
+
+ /// \brief A string containing the Objective-C selector entered thus far for a
+ /// message send.
+ std::string Selector;
};
/// \brief Tracks the number of code-completion result objects that are
@@ -253,11 +284,16 @@ static llvm::sys::cas_flag CodeCompletionResultObjects;
AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
const FileSystemOptions& FileSystemOpts)
: CXCodeCompleteResults(),
- Diag(new Diagnostic(
+ Diag(new DiagnosticsEngine(
llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))),
FileSystemOpts(FileSystemOpts),
FileMgr(new FileManager(FileSystemOpts)),
- SourceMgr(new SourceManager(*Diag, *FileMgr)) {
+ SourceMgr(new SourceManager(*Diag, *FileMgr)),
+ Contexts(CXCompletionContext_Unknown),
+ ContainerKind(CXCursor_InvalidCode),
+ ContainerUSR(createCXString("")),
+ ContainerIsIncomplete(1)
+{
if (getenv("LIBCLANG_OBJTRACKING")) {
llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
@@ -267,6 +303,8 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
delete [] Results;
+ clang_disposeString(ContainerUSR);
+
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
TemporaryFiles[I].eraseFromDisk();
for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
@@ -420,7 +458,7 @@ static unsigned long long getContextsForContextKind(
contexts = CXCompletionContext_ObjCClassMessage;
break;
}
- case CodeCompletionContext::CCC_ObjCSuperclass: {
+ case CodeCompletionContext::CCC_ObjCInterfaceName: {
contexts = CXCompletionContext_ObjCInterface;
break;
}
@@ -454,11 +492,13 @@ static unsigned long long getContextsForContextKind(
namespace {
class CaptureCompletionResults : public CodeCompleteConsumer {
AllocatedCXCodeCompleteResults &AllocatedResults;
- llvm::SmallVector<CXCompletionResult, 16> StoredResults;
+ SmallVector<CXCompletionResult, 16> StoredResults;
+ CXTranslationUnit *TU;
public:
- CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
+ CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
+ CXTranslationUnit *TranslationUnit)
: CodeCompleteConsumer(true, false, true, false),
- AllocatedResults(Results) { }
+ AllocatedResults(Results), TU(TranslationUnit) { }
~CaptureCompletionResults() { Finish(); }
virtual void ProcessCodeCompleteResults(Sema &S,
@@ -477,10 +517,77 @@ namespace {
StoredResults.push_back(R);
}
- enum CodeCompletionContext::Kind kind = Context.getKind();
+ enum CodeCompletionContext::Kind contextKind = Context.getKind();
- AllocatedResults.ContextKind = kind;
- AllocatedResults.Contexts = getContextsForContextKind(kind, S);
+ AllocatedResults.ContextKind = contextKind;
+ AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
+
+ AllocatedResults.Selector = "";
+ if (Context.getNumSelIdents() > 0) {
+ for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
+ IdentifierInfo *selIdent = Context.getSelIdents()[i];
+ if (selIdent != NULL) {
+ StringRef selectorString = Context.getSelIdents()[i]->getName();
+ AllocatedResults.Selector += selectorString;
+ }
+ AllocatedResults.Selector += ":";
+ }
+ }
+
+ QualType baseType = Context.getBaseType();
+ NamedDecl *D = NULL;
+
+ if (!baseType.isNull()) {
+ // Get the declaration for a class/struct/union/enum type
+ if (const TagType *Tag = baseType->getAs<TagType>())
+ D = Tag->getDecl();
+ // Get the @interface declaration for a (possibly-qualified) Objective-C
+ // object pointer type, e.g., NSString*
+ else if (const ObjCObjectPointerType *ObjPtr =
+ baseType->getAs<ObjCObjectPointerType>())
+ D = ObjPtr->getInterfaceDecl();
+ // Get the @interface declaration for an Objective-C object type
+ else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
+ D = Obj->getInterface();
+ // Get the class for a C++ injected-class-name
+ else if (const InjectedClassNameType *Injected =
+ baseType->getAs<InjectedClassNameType>())
+ D = Injected->getDecl();
+ }
+
+ if (D != NULL) {
+ CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
+
+ CXCursorKind cursorKind = clang_getCursorKind(cursor);
+ CXString cursorUSR = clang_getCursorUSR(cursor);
+
+ // Normally, clients of CXString shouldn't care whether or not
+ // a CXString is managed by a pool or by explicitly malloc'ed memory.
+ // However, there are cases when AllocatedResults outlives the
+ // CXTranslationUnit. This is a workaround that failure mode.
+ if (cxstring::isManagedByPool(cursorUSR)) {
+ CXString heapStr =
+ cxstring::createCXString(clang_getCString(cursorUSR), true);
+ clang_disposeString(cursorUSR);
+ cursorUSR = heapStr;
+ }
+
+ AllocatedResults.ContainerKind = cursorKind;
+ AllocatedResults.ContainerUSR = cursorUSR;
+
+ const Type *type = baseType.getTypePtrOrNull();
+ if (type != NULL) {
+ AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
+ }
+ else {
+ AllocatedResults.ContainerIsIncomplete = 1;
+ }
+ }
+ else {
+ AllocatedResults.ContainerKind = CXCursor_InvalidCode;
+ AllocatedResults.ContainerUSR = createCXString("");
+ AllocatedResults.ContainerIsIncomplete = 1;
+ }
}
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
@@ -551,9 +658,9 @@ void clang_codeCompleteAt_Impl(void *UserData) {
ASTUnit::ConcurrencyCheck Check(*AST);
// Perform the remapping of source files.
- llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
+ SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
const llvm::MemoryBuffer *Buffer
= llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
@@ -571,7 +678,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
Results->NumResults = 0;
// Create a code-completion consumer to capture the results.
- CaptureCompletionResults Capture(*Results);
+ CaptureCompletionResults Capture(*Results, &TU);
// Perform completion.
AST->CodeComplete(complete_filename, complete_line, complete_column,
@@ -621,7 +728,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
}
pchName.push_back('\0');
struct stat stat_results;
- if (stat(pchName.data(), &stat_results) == 0)
+ if (stat(pchName.str().c_str(), &stat_results) == 0)
usesPCH = true;
continue;
}
@@ -639,7 +746,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
os << " }";
- llvm::StringRef res = os.str();
+ StringRef res = os.str();
if (res.size() > 0) {
do {
// Setup the UDP socket.
@@ -731,6 +838,40 @@ clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
return Results->Contexts;
}
+enum CXCursorKind clang_codeCompleteGetContainerKind(
+ CXCodeCompleteResults *ResultsIn,
+ unsigned *IsIncomplete) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return CXCursor_InvalidCode;
+
+ if (IsIncomplete != NULL) {
+ *IsIncomplete = Results->ContainerIsIncomplete;
+ }
+
+ return Results->ContainerKind;
+}
+
+CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return createCXString("");
+
+ return createCXString(clang_getCString(Results->ContainerUSR));
+}
+
+
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return createCXString("");
+
+ return createCXString(Results->Selector);
+}
+
} // end extern "C"
/// \brief Simple utility function that appends a \p New string to the given
@@ -744,7 +885,7 @@ clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
///
/// \param Buffer A buffer that stores the actual, concatenated string. It will
/// be used if the old string is already-non-empty.
-static void AppendToString(llvm::StringRef &Old, llvm::StringRef New,
+static void AppendToString(StringRef &Old, StringRef New,
llvm::SmallString<256> &Buffer) {
if (Old.empty()) {
Old = New;
@@ -764,9 +905,9 @@ static void AppendToString(llvm::StringRef &Old, llvm::StringRef New,
/// concatenated.
///
/// \param Buffer A buffer used for storage of the completed name.
-static llvm::StringRef GetTypedName(CodeCompletionString *String,
+static StringRef GetTypedName(CodeCompletionString *String,
llvm::SmallString<256> &Buffer) {
- llvm::StringRef Result;
+ StringRef Result;
for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
C != CEnd; ++C) {
if (C->Kind == CodeCompletionString::CK_TypedText)
@@ -786,9 +927,9 @@ namespace {
= (CodeCompletionString *)YR.CompletionString;
llvm::SmallString<256> XBuffer;
- llvm::StringRef XText = GetTypedName(X, XBuffer);
+ StringRef XText = GetTypedName(X, XBuffer);
llvm::SmallString<256> YBuffer;
- llvm::StringRef YText = GetTypedName(Y, YBuffer);
+ StringRef YText = GetTypedName(Y, YBuffer);
if (XText.empty() || YText.empty())
return !XText.empty();
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 0fcdab7..26f69b0 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -106,7 +106,7 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
/* Print warning/error/etc. */
switch (Severity) {
- case CXDiagnostic_Ignored: assert(0 && "impossible"); break;
+ case CXDiagnostic_Ignored: llvm_unreachable("impossible");
case CXDiagnostic_Note: Out << "note: "; break;
case CXDiagnostic_Warning: Out << "warning: "; break;
case CXDiagnostic_Error: Out << "error: "; break;
@@ -182,11 +182,11 @@ enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
return CXDiagnostic_Ignored;
switch (StoredDiag->Diag.getLevel()) {
- case Diagnostic::Ignored: return CXDiagnostic_Ignored;
- case Diagnostic::Note: return CXDiagnostic_Note;
- case Diagnostic::Warning: return CXDiagnostic_Warning;
- case Diagnostic::Error: return CXDiagnostic_Error;
- case Diagnostic::Fatal: return CXDiagnostic_Fatal;
+ case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
+ case DiagnosticsEngine::Note: return CXDiagnostic_Note;
+ case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
+ case DiagnosticsEngine::Error: return CXDiagnostic_Error;
+ case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal;
}
llvm_unreachable("Invalid diagnostic level");
@@ -220,11 +220,11 @@ CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
return createCXString("");
unsigned ID = StoredDiag->Diag.getID();
- llvm::StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
+ StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
if (!Option.empty()) {
if (Disable)
- *Disable = createCXString((llvm::Twine("-Wno-") + Option).str());
- return createCXString((llvm::Twine("-W") + Option).str());
+ *Disable = createCXString((Twine("-Wno-") + Option).str());
+ return createCXString((Twine("-W") + Option).str());
}
if (ID == diag::fatal_too_many_errors) {
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
new file mode 100644
index 0000000..b5a05ea
--- /dev/null
+++ b/tools/libclang/CIndexHigh.cpp
@@ -0,0 +1,315 @@
+//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Index_Internal.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CXTranslationUnit.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace clang;
+
+static void getTopOverriddenMethods(CXTranslationUnit TU,
+ Decl *D,
+ SmallVectorImpl<Decl *> &Methods) {
+ if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
+ return;
+
+ SmallVector<CXCursor, 8> Overridden;
+ cxcursor::getOverriddenCursors(cxcursor::MakeCXCursor(D, TU), Overridden);
+
+ if (Overridden.empty()) {
+ Methods.push_back(D->getCanonicalDecl());
+ return;
+ }
+
+ for (SmallVector<CXCursor, 8>::iterator
+ I = Overridden.begin(), E = Overridden.end(); I != E; ++I)
+ getTopOverriddenMethods(TU, cxcursor::getCursorDecl(*I), Methods);
+}
+
+namespace {
+
+struct FindFileIdRefVisitData {
+ CXTranslationUnit TU;
+ FileID FID;
+ Decl *Dcl;
+ int SelectorIdIdx;
+ CXCursorAndRangeVisitor visitor;
+
+ typedef SmallVector<Decl *, 8> TopMethodsTy;
+ TopMethodsTy TopMethods;
+
+ FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID,
+ Decl *D, int selectorIdIdx,
+ CXCursorAndRangeVisitor visitor)
+ : TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) {
+ Dcl = getCanonical(D);
+ getTopOverriddenMethods(TU, Dcl, TopMethods);
+ }
+
+ ASTContext &getASTContext() const {
+ return static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ }
+
+ /// \brief We are looking to find all semantically relevant identifiers,
+ /// so the definition of "canonical" here is different than in the AST, e.g.
+ ///
+ /// \code
+ /// class C {
+ /// C() {}
+ /// };
+ /// \endcode
+ ///
+ /// we consider the canonical decl of the constructor decl to be the class
+ /// itself, so both 'C' can be highlighted.
+ Decl *getCanonical(Decl *D) const {
+ D = D->getCanonicalDecl();
+
+ if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ return getCanonical(ImplD->getClassInterface());
+ if (CXXConstructorDecl *CXXCtorD = dyn_cast<CXXConstructorDecl>(D))
+ return getCanonical(CXXCtorD->getParent());
+
+ return D;
+ }
+
+ bool isHit(Decl *D) const {
+ D = getCanonical(D);
+ if (D == Dcl)
+ return true;
+
+ if (isa<ObjCMethodDecl>(D) || isa<CXXMethodDecl>(D))
+ return isOverriddingMethod(D);
+
+ return false;
+ }
+
+private:
+ bool isOverriddingMethod(Decl *D) const {
+ if (std::find(TopMethods.begin(), TopMethods.end(), D) !=
+ TopMethods.end())
+ return true;
+
+ TopMethodsTy methods;
+ getTopOverriddenMethods(TU, D, methods);
+ for (TopMethodsTy::iterator
+ I = methods.begin(), E = methods.end(); I != E; ++I) {
+ if (std::find(TopMethods.begin(), TopMethods.end(), *I) !=
+ TopMethods.end())
+ return true;
+ }
+
+ return false;
+ }
+};
+
+} // end anonymous namespace.
+
+/// \brief For a macro \arg Loc, returns the file spelling location and sets
+/// to \arg isMacroArg whether the spelling resides inside a macro definition or
+/// a macro argument.
+static SourceLocation getFileSpellingLoc(SourceManager &SM,
+ SourceLocation Loc,
+ bool &isMacroArg) {
+ assert(Loc.isMacroID());
+ SourceLocation SpellLoc = SM.getImmediateSpellingLoc(Loc);
+ if (SpellLoc.isMacroID())
+ return getFileSpellingLoc(SM, SpellLoc, isMacroArg);
+
+ isMacroArg = SM.isMacroArgExpansion(Loc);
+ return SpellLoc;
+}
+
+static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
+ CXCursor parent,
+ CXClientData client_data) {
+ CXCursor declCursor = clang_getCursorReferenced(cursor);
+ if (!clang_isDeclaration(declCursor.kind))
+ return CXChildVisit_Recurse;
+
+ Decl *D = cxcursor::getCursorDecl(declCursor);
+ FindFileIdRefVisitData *data = (FindFileIdRefVisitData *)client_data;
+ if (data->isHit(D)) {
+ cursor = cxcursor::getSelectorIdentifierCursor(data->SelectorIdIdx, cursor);
+
+ // We are looking for identifiers to highlight so for objc methods (and
+ // not a parameter) we can only highlight the selector identifiers.
+ if ((cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) &&
+ cxcursor::getSelectorIdentifierIndex(cursor) == -1)
+ return CXChildVisit_Recurse;
+
+ if (clang_isExpression(cursor.kind)) {
+ if (cursor.kind == CXCursor_DeclRefExpr ||
+ cursor.kind == CXCursor_MemberRefExpr) {
+ // continue..
+
+ } else if (cursor.kind == CXCursor_ObjCMessageExpr &&
+ cxcursor::getSelectorIdentifierIndex(cursor) != -1) {
+ // continue..
+
+ } else
+ return CXChildVisit_Recurse;
+ }
+
+ SourceLocation
+ Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
+ SourceLocation SelIdLoc = cxcursor::getSelectorIdentifierLoc(cursor);
+ if (SelIdLoc.isValid())
+ Loc = SelIdLoc;
+
+ SourceManager &SM = data->getASTContext().getSourceManager();
+ bool isInMacroDef = false;
+ if (Loc.isMacroID()) {
+ bool isMacroArg;
+ Loc = getFileSpellingLoc(SM, Loc, isMacroArg);
+ isInMacroDef = !isMacroArg;
+ }
+
+ // We are looking for identifiers in a specific file.
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+ if (LocInfo.first != data->FID)
+ return CXChildVisit_Recurse;
+
+ if (isInMacroDef) {
+ // FIXME: For a macro definition make sure that all expansions
+ // of it expand to the same reference before allowing to point to it.
+ Loc = SourceLocation();
+ }
+
+ data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(D->getASTContext(), Loc));
+ }
+ return CXChildVisit_Recurse;
+}
+
+static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
+ const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
+ assert(clang_isDeclaration(declCursor.kind));
+ ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
+ ASTContext &Ctx = Unit->getASTContext();
+ SourceManager &SM = Unit->getSourceManager();
+
+ FileID FID = SM.translateFile(File);
+ Decl *Dcl = cxcursor::getCursorDecl(declCursor);
+ FindFileIdRefVisitData data(TU, FID, Dcl,
+ cxcursor::getSelectorIdentifierIndex(declCursor),
+ Visitor);
+
+ if (DeclContext *DC = Dcl->getParentFunctionOrMethod()) {
+ clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU),
+ findFileIdRefVisit, &data);
+ return;
+ }
+
+ if (FID == SM.getMainFileID() && !Unit->isMainFileAST()) {
+ SourceLocation FileLoc = SM.getLocForStartOfFile(FID);
+ TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl();
+ CXCursor TUCursor = clang_getTranslationUnitCursor(TU);
+ for (DeclContext::decl_iterator
+ I = TUD->noload_decls_begin(), E = TUD->noload_decls_end();
+ I != E; ++I) {
+ Decl *D = *I;
+
+ SourceRange R = D->getSourceRange();
+ if (R.isInvalid())
+ continue;
+ if (SM.isBeforeInTranslationUnit(R.getEnd(), FileLoc))
+ continue;
+
+ if (TagDecl *TD = dyn_cast<TagDecl>(D))
+ if (!TD->isFreeStanding())
+ continue;
+
+ CXCursor CurCursor = cxcursor::MakeCXCursor(D, TU);
+ findFileIdRefVisit(CurCursor, TUCursor, &data);
+ clang_visitChildren(CurCursor, findFileIdRefVisit, &data);
+ }
+ return;
+ }
+
+ clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ findFileIdRefVisit, &data);
+}
+
+
+//===----------------------------------------------------------------------===//
+// libclang public APIs.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+void clang_findReferencesInFile(CXCursor cursor, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ bool Logging = ::getenv("LIBCLANG_LOGGING");
+
+ if (clang_Cursor_isNull(cursor)) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null cursor\n";
+ return;
+ }
+ if (!file) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null file\n";
+ return;
+ }
+ if (!visitor.visit) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null visitor\n";
+ return;
+ }
+
+ // We are interested in semantics of identifiers so for C++ constructor exprs
+ // prefer type references, e.g.:
+ //
+ // return MyStruct();
+ //
+ // for 'MyStruct' we'll have a cursor pointing at the constructor decl but
+ // we are actually interested in the type declaration.
+ cursor = cxcursor::getTypeRefCursor(cursor);
+
+ CXCursor refCursor = clang_getCursorReferenced(cursor);
+
+ if (!clang_isDeclaration(refCursor.kind)) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: cursor is not referencing a "
+ "declaration\n";
+ return;
+ }
+
+ ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ findIdRefsInFile(cxcursor::getCursorTU(cursor),
+ refCursor,
+ static_cast<const FileEntry *>(file),
+ visitor);
+}
+
+static enum CXVisitorResult _visitCursorAndRange(void *context,
+ CXCursor cursor,
+ CXSourceRange range) {
+ CXCursorAndRangeVisitorBlock block = (CXCursorAndRangeVisitorBlock)context;
+ return INVOKE_BLOCK2(block, cursor, range);
+}
+
+void clang_findReferencesInFileWithBlock(CXCursor cursor,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
+ CXCursorAndRangeVisitor visitor = { block,
+ block ? _visitCursorAndRange : 0 };
+ return clang_findReferencesInFile(cursor, file, visitor);
+}
+
+} // end: extern "C"
+
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 6bc4f2e..848ca31 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -29,19 +29,22 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
- llvm::SmallVector<CXSourceLocation, 10> InclusionStack;
- unsigned i = SM.sloc_loaded_entry_size();
- unsigned n = SM.sloc_entry_size();
+ SmallVector<CXSourceLocation, 10> InclusionStack;
+ unsigned n = SM.local_sloc_entry_size();
// In the case where all the SLocEntries are in an external source, traverse
// those SLocEntries as well. This is the case where we are looking
// at the inclusion stack of an AST/PCH file.
- if (i >= n)
- i = 0;
-
- for ( ; i < n ; ++i) {
+ const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const;
+ if (n == 1) {
+ Getter = &SourceManager::getLoadedSLocEntry;
+ n = SM.loaded_sloc_entry_size();
+ } else
+ Getter = &SourceManager::getLocalSLocEntry;
+
+ for (unsigned i = 0 ; i < n ; ++i) {
bool Invalid = false;
- const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i, &Invalid);
+ const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid);
if (!SL.isFile() || Invalid)
continue;
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 4f1f071..121d67d 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -31,28 +31,28 @@ using namespace clang::cxstring;
namespace {
class USRGenerator : public DeclVisitor<USRGenerator> {
llvm::OwningPtr<llvm::SmallString<128> > OwnedBuf;
- llvm::SmallVectorImpl<char> &Buf;
+ SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
bool IgnoreResults;
- ASTUnit *AU;
+ ASTContext *Context;
bool generatedLoc;
llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
public:
- USRGenerator(const CXCursor *C = 0, llvm::SmallVectorImpl<char> *extBuf = 0)
+ explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
: OwnedBuf(extBuf ? 0 : new llvm::SmallString<128>()),
Buf(extBuf ? *extBuf : *OwnedBuf.get()),
Out(Buf),
IgnoreResults(false),
- AU(C ? cxcursor::getCursorASTUnit(*C) : 0),
+ Context(Ctx),
generatedLoc(false)
{
// Add the USR space prefix.
Out << "c:";
}
- llvm::StringRef str() {
+ StringRef str() {
return Out.str();
}
@@ -114,19 +114,19 @@ public:
/// itself.
/// Generate a USR for an Objective-C class.
- void GenObjCClass(llvm::StringRef cls);
+ void GenObjCClass(StringRef cls);
/// Generate a USR for an Objective-C class category.
- void GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat);
+ void GenObjCCategory(StringRef cls, StringRef cat);
/// Generate a USR fragment for an Objective-C instance variable. The
/// complete USR can be created by concatenating the USR for the
/// encompassing class with this USR fragment.
- void GenObjCIvar(llvm::StringRef ivar);
+ void GenObjCIvar(StringRef ivar);
/// Generate a USR fragment for an Objective-C method.
- void GenObjCMethod(llvm::StringRef sel, bool isInstanceMethod);
+ void GenObjCMethod(StringRef sel, bool isInstanceMethod);
/// Generate a USR fragment for an Objective-C property.
- void GenObjCProperty(llvm::StringRef prop);
+ void GenObjCProperty(StringRef prop);
/// Generate a USR for an Objective-C protocol.
- void GenObjCProtocol(llvm::StringRef prot);
+ void GenObjCProtocol(StringRef prot);
void VisitType(QualType T);
void VisitTemplateParameterList(const TemplateParameterList *Params);
@@ -190,7 +190,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
Out << "@F@";
D->printName(Out);
- ASTContext &Ctx = AU->getASTContext();
+ ASTContext &Ctx = *Context;
if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
return;
@@ -235,7 +235,7 @@ void USRGenerator::VisitVarDecl(VarDecl *D) {
VisitDeclContext(D->getDeclContext());
// Variables always have simple names.
- llvm::StringRef s = D->getName();
+ StringRef s = D->getName();
// The string can be empty if the declaration has no name; e.g., it is
// the ParmDecl with no name for declaration of a function pointer type, e.g.:
@@ -320,7 +320,7 @@ void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
switch (D->getKind()) {
default:
- assert(false && "Invalid ObjC container.");
+ llvm_unreachable("Invalid ObjC container.");
case Decl::ObjCInterface:
case Decl::ObjCImplementation:
GenObjCClass(D->getName());
@@ -433,7 +433,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
if (EmitDeclName(D)) {
if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
Buf[off] = 'A';
- Out << '@' << TD;
+ Out << '@' << *TD;
}
else
Buf[off] = 'a';
@@ -480,13 +480,13 @@ bool USRGenerator::GenLoc(const Decl *D) {
// Use the location of canonical decl.
D = D->getCanonicalDecl();
- const SourceManager &SM = AU->getSourceManager();
+ const SourceManager &SM = Context->getSourceManager();
SourceLocation L = D->getLocStart();
if (L.isInvalid()) {
IgnoreResults = true;
return true;
}
- L = SM.getInstantiationLoc(L);
+ L = SM.getExpansionLoc(L);
const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
if (FE) {
@@ -508,7 +508,7 @@ 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.
- ASTContext &Ctx = AU->getASTContext();
+ ASTContext &Ctx = *Context;
do {
T = Ctx.getCanonicalType(T);
@@ -570,6 +570,8 @@ void USRGenerator::VisitType(QualType T) {
c = 'K'; break;
case BuiltinType::Int128:
c = 'J'; break;
+ case BuiltinType::Half:
+ c = 'h'; break;
case BuiltinType::Float:
c = 'f'; break;
case BuiltinType::Double:
@@ -755,27 +757,27 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
// General purpose USR generation methods.
//===----------------------------------------------------------------------===//
-void USRGenerator::GenObjCClass(llvm::StringRef cls) {
+void USRGenerator::GenObjCClass(StringRef cls) {
Out << "objc(cs)" << cls;
}
-void USRGenerator::GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat) {
+void USRGenerator::GenObjCCategory(StringRef cls, StringRef cat) {
Out << "objc(cy)" << cls << '@' << cat;
}
-void USRGenerator::GenObjCIvar(llvm::StringRef ivar) {
+void USRGenerator::GenObjCIvar(StringRef ivar) {
Out << '@' << ivar;
}
-void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) {
+void USRGenerator::GenObjCMethod(StringRef meth, bool isInstanceMethod) {
Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
}
-void USRGenerator::GenObjCProperty(llvm::StringRef prop) {
+void USRGenerator::GenObjCProperty(StringRef prop) {
Out << "(py)" << prop;
}
-void USRGenerator::GenObjCProtocol(llvm::StringRef prot) {
+void USRGenerator::GenObjCProtocol(StringRef prot) {
Out << "objc(pl)" << prot;
}
@@ -783,16 +785,14 @@ void USRGenerator::GenObjCProtocol(llvm::StringRef prot) {
// API hooks.
//===----------------------------------------------------------------------===//
-static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) {
+static inline StringRef extractUSRSuffix(StringRef s) {
return s.startswith("c:") ? s.substr(2) : "";
}
-static CXString getDeclCursorUSR(const CXCursor &C) {
- Decl *D = cxcursor::getCursorDecl(C);
-
+bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) {
// Don't generate USRs for things with invalid locations.
if (!D || D->getLocStart().isInvalid())
- return createCXString("");
+ return true;
// Check if the cursor has 'NoLinkage'.
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
@@ -817,27 +817,15 @@ static CXString getDeclCursorUSR(const CXCursor &C) {
break;
}
- CXTranslationUnit TU = cxcursor::getCursorTU(C);
- if (!TU)
- return createCXString("");
-
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
- if (!buf)
- return createCXString("");
-
{
- USRGenerator UG(&C, &buf->Data);
+ USRGenerator UG(&D->getASTContext(), &Buf);
UG->Visit(D);
- if (UG->ignoreResults()) {
- disposeCXStringBuf(buf);
- return createCXString("");
- }
+ if (UG->ignoreResults())
+ return true;
}
- // Return the C-string, but don't make a copy since it is already in
- // the string buffer.
- buf->Data.push_back('\0');
- return createCXString(buf);
+
+ return false;
}
extern "C" {
@@ -845,8 +833,27 @@ extern "C" {
CXString clang_getCursorUSR(CXCursor C) {
const CXCursorKind &K = clang_getCursorKind(C);
- if (clang_isDeclaration(K))
- return getDeclCursorUSR(C);
+ if (clang_isDeclaration(K)) {
+ Decl *D = cxcursor::getCursorDecl(C);
+ CXTranslationUnit TU = cxcursor::getCursorTU(C);
+ if (!TU)
+ return createCXString("");
+
+ CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ if (!buf)
+ return createCXString("");
+
+ bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
+ if (Ignore) {
+ disposeCXStringBuf(buf);
+ return createCXString("");
+ }
+
+ // Return the C-string, but don't make a copy since it is already in
+ // the string buffer.
+ buf->Data.push_back('\0');
+ return createCXString(buf);
+ }
if (K == CXCursor_MacroDefinition) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
@@ -858,7 +865,8 @@ CXString clang_getCursorUSR(CXCursor C) {
return createCXString("");
{
- USRGenerator UG(&C, &buf->Data);
+ USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
+ &buf->Data);
UG << "macro@"
<< cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
}
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index 56974b9..995a8fe 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -74,7 +74,7 @@ std::string CIndexer::getClangResourcesPath() {
// This silly cast below avoids a C++ warning.
Dl_info info;
if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
- assert(0 && "Call to dladdr() failed");
+ llvm_unreachable("Call to dladdr() failed");
llvm::sys::Path LibClangPath(info.dli_fname);
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index f45389f..f754e98 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -21,6 +21,7 @@ set(SOURCES
CIndexCXX.cpp
CIndexCodeCompletion.cpp
CIndexDiagnostic.cpp
+ CIndexHigh.cpp
CIndexInclusionStack.cpp
CIndexUSRs.cpp
CIndexer.cpp
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index b3c57dc..db275001 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -20,8 +20,10 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
#include "clang-c/Index.h"
#include "llvm/Support/ErrorHandling.h"
@@ -30,7 +32,7 @@ using namespace cxcursor;
CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
- CXCursor C = { K, { 0, 0, 0 } };
+ CXCursor C = { K, 0, { 0, 0, 0 } };
return C;
}
@@ -41,6 +43,9 @@ 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;
+ case attr::Annotate: return CXCursor_AnnotateAttr;
}
return CXCursor_UnexposedAttr;
@@ -49,152 +54,369 @@ static CXCursorKind GetCursorKind(const Attr *A) {
CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
CXTranslationUnit TU) {
assert(A && Parent && TU && "Invalid arguments!");
- CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } };
+ CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
return C;
}
CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
+ SourceRange RegionOfInterest,
bool FirstInDeclGroup) {
assert(D && TU && "Invalid arguments!");
- CXCursor C = { getCursorKindForDecl(D),
- { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }
- };
+
+ CXCursorKind K = getCursorKindForDecl(D);
+
+ if (K == CXCursor_ObjCClassMethodDecl ||
+ K == CXCursor_ObjCInstanceMethodDecl) {
+ int SelectorIdIndex = -1;
+ // Check if cursor points to a selector id.
+ if (RegionOfInterest.isValid() &&
+ RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
+ SmallVector<SourceLocation, 16> SelLocs;
+ cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
+ SmallVector<SourceLocation, 16>::iterator
+ I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ if (I != SelLocs.end())
+ SelectorIdIndex = I - SelLocs.begin();
+ }
+ CXCursor C = { K, SelectorIdIndex,
+ { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
+ return C;
+ }
+
+ CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
return C;
}
-CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
- CXTranslationUnit TU) {
+CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
+ SourceRange RegionOfInterest) {
assert(S && TU && "Invalid arguments!");
CXCursorKind K = CXCursor_NotImplemented;
switch (S->getStmtClass()) {
case Stmt::NoStmtClass:
break;
-
- case Stmt::NullStmtClass:
- case Stmt::CompoundStmtClass:
+
case Stmt::CaseStmtClass:
+ K = CXCursor_CaseStmt;
+ break;
+
case Stmt::DefaultStmtClass:
- case Stmt::IfStmtClass:
- case Stmt::SwitchStmtClass:
- case Stmt::WhileStmtClass:
- case Stmt::DoStmtClass:
- case Stmt::ForStmtClass:
- case Stmt::GotoStmtClass:
+ K = CXCursor_DefaultStmt;
+ break;
+
+ case Stmt::IfStmtClass:
+ K = CXCursor_IfStmt;
+ break;
+
+ case Stmt::SwitchStmtClass:
+ K = CXCursor_SwitchStmt;
+ break;
+
+ case Stmt::WhileStmtClass:
+ K = CXCursor_WhileStmt;
+ break;
+
+ case Stmt::DoStmtClass:
+ K = CXCursor_DoStmt;
+ break;
+
+ case Stmt::ForStmtClass:
+ K = CXCursor_ForStmt;
+ break;
+
+ case Stmt::GotoStmtClass:
+ K = CXCursor_GotoStmt;
+ break;
+
case Stmt::IndirectGotoStmtClass:
- case Stmt::ContinueStmtClass:
- case Stmt::BreakStmtClass:
- case Stmt::ReturnStmtClass:
- case Stmt::DeclStmtClass:
- case Stmt::AsmStmtClass:
- case Stmt::ObjCAtTryStmtClass:
- case Stmt::ObjCAtCatchStmtClass:
- case Stmt::ObjCAtFinallyStmtClass:
- case Stmt::ObjCAtThrowStmtClass:
- case Stmt::ObjCAtSynchronizedStmtClass:
- case Stmt::ObjCAutoreleasePoolStmtClass:
+ K = CXCursor_IndirectGotoStmt;
+ break;
+
+ case Stmt::ContinueStmtClass:
+ K = CXCursor_ContinueStmt;
+ break;
+
+ case Stmt::BreakStmtClass:
+ K = CXCursor_BreakStmt;
+ break;
+
+ case Stmt::ReturnStmtClass:
+ K = CXCursor_ReturnStmt;
+ break;
+
+ case Stmt::AsmStmtClass:
+ K = CXCursor_AsmStmt;
+ break;
+
+ case Stmt::ObjCAtTryStmtClass:
+ K = CXCursor_ObjCAtTryStmt;
+ break;
+
+ case Stmt::ObjCAtCatchStmtClass:
+ K = CXCursor_ObjCAtCatchStmt;
+ break;
+
+ case Stmt::ObjCAtFinallyStmtClass:
+ K = CXCursor_ObjCAtFinallyStmt;
+ break;
+
+ case Stmt::ObjCAtThrowStmtClass:
+ K = CXCursor_ObjCAtThrowStmt;
+ break;
+
+ case Stmt::ObjCAtSynchronizedStmtClass:
+ K = CXCursor_ObjCAtSynchronizedStmt;
+ break;
+
+ case Stmt::ObjCAutoreleasePoolStmtClass:
+ K = CXCursor_ObjCAutoreleasePoolStmt;
+ break;
+
case Stmt::ObjCForCollectionStmtClass:
+ K = CXCursor_ObjCForCollectionStmt;
+ break;
+
case Stmt::CXXCatchStmtClass:
- case Stmt::CXXTryStmtClass:
- case Stmt::CXXForRangeStmtClass:
+ K = CXCursor_CXXCatchStmt;
+ break;
+
+ case Stmt::CXXTryStmtClass:
+ K = CXCursor_CXXTryStmt;
+ break;
+
+ case Stmt::CXXForRangeStmtClass:
+ K = CXCursor_CXXForRangeStmt;
+ break;
+
case Stmt::SEHTryStmtClass:
+ K = CXCursor_SEHTryStmt;
+ break;
+
case Stmt::SEHExceptStmtClass:
+ K = CXCursor_SEHExceptStmt;
+ break;
+
case Stmt::SEHFinallyStmtClass:
+ K = CXCursor_SEHFinallyStmt;
+ break;
+
+ case Stmt::ArrayTypeTraitExprClass:
+ case Stmt::AsTypeExprClass:
+ case Stmt::AtomicExprClass:
+ case Stmt::BinaryConditionalOperatorClass:
+ case Stmt::BinaryTypeTraitExprClass:
+ case Stmt::CXXBindTemporaryExprClass:
+ case Stmt::CXXDefaultArgExprClass:
+ case Stmt::CXXScalarValueInitExprClass:
+ case Stmt::CXXUuidofExprClass:
+ case Stmt::ChooseExprClass:
+ case Stmt::DesignatedInitExprClass:
+ case Stmt::ExprWithCleanupsClass:
+ case Stmt::ExpressionTraitExprClass:
+ case Stmt::ExtVectorElementExprClass:
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::ImplicitValueInitExprClass:
case Stmt::MaterializeTemporaryExprClass:
- K = CXCursor_UnexposedStmt;
+ case Stmt::ObjCIndirectCopyRestoreExprClass:
+ case Stmt::OffsetOfExprClass:
+ case Stmt::OpaqueValueExprClass:
+ case Stmt::ParenListExprClass:
+ case Stmt::PredefinedExprClass:
+ case Stmt::ShuffleVectorExprClass:
+ case Stmt::UnaryExprOrTypeTraitExprClass:
+ case Stmt::UnaryTypeTraitExprClass:
+ case Stmt::VAArgExprClass:
+ K = CXCursor_UnexposedExpr;
+ break;
+
+ case Stmt::CompoundStmtClass:
+ K = CXCursor_CompoundStmt;
break;
- case Stmt::LabelStmtClass:
- K = CXCursor_LabelStmt;
+ case Stmt::NullStmtClass:
+ K = CXCursor_NullStmt;
break;
- case Stmt::PredefinedExprClass:
- case Stmt::IntegerLiteralClass:
- case Stmt::FloatingLiteralClass:
- case Stmt::ImaginaryLiteralClass:
- case Stmt::StringLiteralClass:
- case Stmt::CharacterLiteralClass:
- case Stmt::ParenExprClass:
+ case Stmt::LabelStmtClass:
+ K = CXCursor_LabelStmt;
+ break;
+
+ case Stmt::DeclStmtClass:
+ K = CXCursor_DeclStmt;
+ break;
+
+ case Stmt::IntegerLiteralClass:
+ K = CXCursor_IntegerLiteral;
+ break;
+
+ case Stmt::FloatingLiteralClass:
+ K = CXCursor_FloatingLiteral;
+ break;
+
+ case Stmt::ImaginaryLiteralClass:
+ K = CXCursor_ImaginaryLiteral;
+ break;
+
+ case Stmt::StringLiteralClass:
+ K = CXCursor_StringLiteral;
+ break;
+
+ case Stmt::CharacterLiteralClass:
+ K = CXCursor_CharacterLiteral;
+ break;
+
+ case Stmt::ParenExprClass:
+ K = CXCursor_ParenExpr;
+ break;
+
case Stmt::UnaryOperatorClass:
- case Stmt::OffsetOfExprClass:
- case Stmt::UnaryExprOrTypeTraitExprClass:
- case Stmt::ArraySubscriptExprClass:
- case Stmt::BinaryOperatorClass:
+ K = CXCursor_UnaryOperator;
+ break;
+
+ case Stmt::CXXNoexceptExprClass:
+ K = CXCursor_UnaryExpr;
+ break;
+
+ case Stmt::ArraySubscriptExprClass:
+ K = CXCursor_ArraySubscriptExpr;
+ break;
+
+ case Stmt::BinaryOperatorClass:
+ K = CXCursor_BinaryOperator;
+ break;
+
case Stmt::CompoundAssignOperatorClass:
- case Stmt::ConditionalOperatorClass:
- case Stmt::BinaryConditionalOperatorClass:
- case Stmt::ImplicitCastExprClass:
+ K = CXCursor_CompoundAssignOperator;
+ break;
+
+ case Stmt::ConditionalOperatorClass:
+ K = CXCursor_ConditionalOperator;
+ break;
+
case Stmt::CStyleCastExprClass:
- case Stmt::CompoundLiteralExprClass:
- case Stmt::ExtVectorElementExprClass:
- case Stmt::InitListExprClass:
- case Stmt::DesignatedInitExprClass:
- case Stmt::ImplicitValueInitExprClass:
- case Stmt::ParenListExprClass:
- case Stmt::VAArgExprClass:
- case Stmt::AddrLabelExprClass:
- case Stmt::StmtExprClass:
- case Stmt::ChooseExprClass:
+ K = CXCursor_CStyleCastExpr;
+ break;
+
+ case Stmt::CompoundLiteralExprClass:
+ K = CXCursor_CompoundLiteralExpr;
+ break;
+
+ case Stmt::InitListExprClass:
+ K = CXCursor_InitListExpr;
+ break;
+
+ case Stmt::AddrLabelExprClass:
+ K = CXCursor_AddrLabelExpr;
+ break;
+
+ case Stmt::StmtExprClass:
+ K = CXCursor_StmtExpr;
+ break;
+
case Stmt::GenericSelectionExprClass:
- case Stmt::GNUNullExprClass:
- case Stmt::CXXStaticCastExprClass:
- case Stmt::CXXDynamicCastExprClass:
- case Stmt::CXXReinterpretCastExprClass:
- case Stmt::CXXConstCastExprClass:
+ K = CXCursor_GenericSelectionExpr;
+ break;
+
+ case Stmt::GNUNullExprClass:
+ K = CXCursor_GNUNullExpr;
+ break;
+
+ case Stmt::CXXStaticCastExprClass:
+ K = CXCursor_CXXStaticCastExpr;
+ break;
+
+ case Stmt::CXXDynamicCastExprClass:
+ K = CXCursor_CXXDynamicCastExpr;
+ break;
+
+ case Stmt::CXXReinterpretCastExprClass:
+ K = CXCursor_CXXReinterpretCastExpr;
+ break;
+
+ case Stmt::CXXConstCastExprClass:
+ K = CXCursor_CXXConstCastExpr;
+ break;
+
case Stmt::CXXFunctionalCastExprClass:
- case Stmt::CXXTypeidExprClass:
- case Stmt::CXXUuidofExprClass:
- case Stmt::CXXBoolLiteralExprClass:
- case Stmt::CXXNullPtrLiteralExprClass:
- case Stmt::CXXThisExprClass:
- case Stmt::CXXThrowExprClass:
- case Stmt::CXXDefaultArgExprClass:
- case Stmt::CXXScalarValueInitExprClass:
- case Stmt::CXXNewExprClass:
- case Stmt::CXXDeleteExprClass:
- case Stmt::CXXPseudoDestructorExprClass:
- case Stmt::UnresolvedLookupExprClass:
- case Stmt::UnaryTypeTraitExprClass:
- case Stmt::BinaryTypeTraitExprClass:
- case Stmt::ArrayTypeTraitExprClass:
- case Stmt::ExpressionTraitExprClass:
- case Stmt::DependentScopeDeclRefExprClass:
- case Stmt::CXXBindTemporaryExprClass:
- case Stmt::ExprWithCleanupsClass:
- case Stmt::CXXUnresolvedConstructExprClass:
- case Stmt::CXXDependentScopeMemberExprClass:
- case Stmt::UnresolvedMemberExprClass:
- case Stmt::CXXNoexceptExprClass:
- case Stmt::ObjCStringLiteralClass:
- case Stmt::ObjCEncodeExprClass:
- case Stmt::ObjCSelectorExprClass:
- case Stmt::ObjCProtocolExprClass:
- case Stmt::ObjCIsaExprClass:
- case Stmt::ObjCIndirectCopyRestoreExprClass:
+ K = CXCursor_CXXFunctionalCastExpr;
+ break;
+
+ case Stmt::CXXTypeidExprClass:
+ K = CXCursor_CXXTypeidExpr;
+ break;
+
+ case Stmt::CXXBoolLiteralExprClass:
+ K = CXCursor_CXXBoolLiteralExpr;
+ break;
+
+ case Stmt::CXXNullPtrLiteralExprClass:
+ K = CXCursor_CXXNullPtrLiteralExpr;
+ break;
+
+ case Stmt::CXXThisExprClass:
+ K = CXCursor_CXXThisExpr;
+ break;
+
+ case Stmt::CXXThrowExprClass:
+ K = CXCursor_CXXThrowExpr;
+ break;
+
+ case Stmt::CXXNewExprClass:
+ K = CXCursor_CXXNewExpr;
+ break;
+
+ case Stmt::CXXDeleteExprClass:
+ K = CXCursor_CXXDeleteExpr;
+ break;
+
+ case Stmt::ObjCStringLiteralClass:
+ K = CXCursor_ObjCStringLiteral;
+ break;
+
+ case Stmt::ObjCEncodeExprClass:
+ K = CXCursor_ObjCEncodeExpr;
+ break;
+
+ case Stmt::ObjCSelectorExprClass:
+ K = CXCursor_ObjCSelectorExpr;
+ break;
+
+ case Stmt::ObjCProtocolExprClass:
+ K = CXCursor_ObjCProtocolExpr;
+ break;
+
case Stmt::ObjCBridgedCastExprClass:
- case Stmt::ShuffleVectorExprClass:
- case Stmt::BlockExprClass:
- case Stmt::OpaqueValueExprClass:
+ K = CXCursor_ObjCBridgedCastExpr;
+ break;
+
+ case Stmt::BlockExprClass:
+ K = CXCursor_BlockExpr;
+ break;
+
case Stmt::PackExpansionExprClass:
+ K = CXCursor_PackExpansionExpr;
+ break;
+
case Stmt::SizeOfPackExprClass:
- case Stmt::AsTypeExprClass:
- K = CXCursor_UnexposedExpr;
+ K = CXCursor_SizeOfPackExpr;
break;
-
- case Stmt::DeclRefExprClass:
+
case Stmt::BlockDeclRefExprClass:
+ case Stmt::DeclRefExprClass:
+ case Stmt::DependentScopeDeclRefExprClass:
case Stmt::SubstNonTypeTemplateParmExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
- // FIXME: UnresolvedLookupExpr?
- // FIXME: DependentScopeDeclRefExpr?
+ case Stmt::UnresolvedLookupExprClass:
K = CXCursor_DeclRefExpr;
break;
+ case Stmt::CXXDependentScopeMemberExprClass:
+ case Stmt::CXXPseudoDestructorExprClass:
case Stmt::MemberExprClass:
+ case Stmt::ObjCIsaExprClass:
case Stmt::ObjCIvarRefExprClass:
case Stmt::ObjCPropertyRefExprClass:
- // FIXME: UnresolvedMemberExpr?
- // FIXME: CXXDependentScopeMemberExpr?
+ case Stmt::UnresolvedMemberExprClass:
K = CXCursor_MemberRefExpr;
break;
@@ -204,16 +426,28 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::CUDAKernelCallExprClass:
case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass:
- // FIXME: CXXUnresolvedConstructExpr
+ case Stmt::CXXUnresolvedConstructExprClass:
K = CXCursor_CallExpr;
break;
case Stmt::ObjCMessageExprClass:
K = CXCursor_ObjCMessageExpr;
- break;
+ int SelectorIdIndex = -1;
+ // Check if cursor points to a selector id.
+ if (RegionOfInterest.isValid() &&
+ RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
+ SmallVector<SourceLocation, 16> SelLocs;
+ cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
+ SmallVector<SourceLocation, 16>::iterator
+ I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ if (I != SelLocs.end())
+ SelectorIdIndex = I - SelLocs.begin();
+ }
+ CXCursor C = { K, 0, { Parent, S, TU } };
+ return getSelectorIdentifierCursor(SelectorIdIndex, C);
}
- CXCursor C = { K, { Parent, S, TU } };
+ CXCursor C = { K, 0, { Parent, S, TU } };
return C;
}
@@ -222,7 +456,7 @@ CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
return C;
}
@@ -239,7 +473,7 @@ CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Super, RawLoc, TU } };
return C;
}
@@ -259,7 +493,7 @@ CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
return MakeCXCursorInvalid(CXCursor_InvalidCode);
assert(TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
return C;
}
@@ -275,7 +509,7 @@ CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Type && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } };
+ CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
return C;
}
@@ -292,7 +526,7 @@ CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template,
CXTranslationUnit TU) {
assert(Template && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } };
+ CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
return C;
}
@@ -310,7 +544,7 @@ CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
"Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } };
+ CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
return C;
}
@@ -327,7 +561,7 @@ CXCursor cxcursor::MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc,
assert(Field && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_MemberRef, { Field, RawLoc, TU } };
+ CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
return C;
}
@@ -341,7 +575,7 @@ cxcursor::getCursorMemberRef(CXCursor C) {
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
CXTranslationUnit TU){
- CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
+ CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
return C;
}
@@ -352,7 +586,7 @@ CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_PreprocessingDirective,
+ CXCursor C = { CXCursor_PreprocessingDirective, 0,
{ reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
TU }
@@ -362,15 +596,17 @@ CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
assert(C.kind == CXCursor_PreprocessingDirective);
- return SourceRange(SourceLocation::getFromRawEncoding(
+ SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
reinterpret_cast<uintptr_t> (C.data[0])),
SourceLocation::getFromRawEncoding(
reinterpret_cast<uintptr_t> (C.data[1])));
+ ASTUnit *TU = getCursorASTUnit(C);
+ return TU->mapRangeFromPreamble(Range);
}
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } };
+ CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
return C;
}
@@ -381,7 +617,7 @@ MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroExpansion, { MI, 0, TU } };
+ CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
return C;
}
@@ -392,7 +628,7 @@ MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_InclusionDirective, { ID, 0, TU } };
+ CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
return C;
}
@@ -406,7 +642,7 @@ CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
assert(Label && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_LabelRef, { Label, RawLoc, TU } };
+ CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
return C;
}
@@ -424,7 +660,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
OverloadedDeclRefStorage Storage(E);
void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -437,7 +673,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
OverloadedDeclRefStorage Storage(D);
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -450,7 +686,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -502,6 +738,173 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
return static_cast<CXTranslationUnit>(Cursor.data[2]);
}
+static void CollectOverriddenMethods(CXTranslationUnit TU,
+ DeclContext *Ctx,
+ ObjCMethodDecl *Method,
+ SmallVectorImpl<CXCursor> &Methods) {
+ if (!Ctx)
+ return;
+
+ // If we have a class or category implementation, jump straight to the
+ // interface.
+ if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
+ return CollectOverriddenMethods(TU, Impl->getClassInterface(),
+ Method, Methods);
+
+ ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
+ if (!Container)
+ return;
+
+ // Check whether we have a matching method at this level.
+ if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
+ Method->isInstanceMethod()))
+ if (Method != Overridden) {
+ // We found an override at this level; there is no need to look
+ // into other protocols or categories.
+ Methods.push_back(MakeCXCursor(Overridden, TU));
+ return;
+ }
+
+ if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
+ for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
+ PEnd = Protocol->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+ }
+
+ if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+ for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+ PEnd = Category->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+ }
+
+ if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
+ for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
+ PEnd = Interface->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+
+ for (ObjCCategoryDecl *Category = Interface->getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ CollectOverriddenMethods(TU, Category, Method, Methods);
+
+ // We only look into the superclass if we haven't found anything yet.
+ if (Methods.empty())
+ if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
+ return CollectOverriddenMethods(TU, Super, Method, Methods);
+ }
+}
+
+void cxcursor::getOverriddenCursors(CXCursor cursor,
+ SmallVectorImpl<CXCursor> &overridden) {
+ if (!clang_isDeclaration(cursor.kind))
+ return;
+
+ Decl *D = getCursorDecl(cursor);
+ if (!D)
+ return;
+
+ // Handle C++ member functions.
+ CXTranslationUnit TU = getCursorTU(cursor);
+ if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
+ for (CXXMethodDecl::method_iterator
+ M = CXXMethod->begin_overridden_methods(),
+ MEnd = CXXMethod->end_overridden_methods();
+ M != MEnd; ++M)
+ overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU));
+ return;
+ }
+
+ ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
+ if (!Method)
+ return;
+
+ // Handle Objective-C methods.
+ CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
+}
+
+std::pair<int, SourceLocation>
+cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
+ if (cursor.kind == CXCursor_ObjCMessageExpr) {
+ if (cursor.xdata != -1)
+ return std::make_pair(cursor.xdata,
+ cast<ObjCMessageExpr>(getCursorExpr(cursor))
+ ->getSelectorLoc(cursor.xdata));
+ } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
+ if (cursor.xdata != -1)
+ return std::make_pair(cursor.xdata,
+ cast<ObjCMethodDecl>(getCursorDecl(cursor))
+ ->getSelectorLoc(cursor.xdata));
+ }
+
+ return std::make_pair(-1, SourceLocation());
+}
+
+CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
+ CXCursor newCursor = cursor;
+
+ if (cursor.kind == CXCursor_ObjCMessageExpr) {
+ if (SelIdx == -1 ||
+ unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
+ ->getNumSelectorLocs())
+ newCursor.xdata = -1;
+ else
+ newCursor.xdata = SelIdx;
+ } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
+ if (SelIdx == -1 ||
+ unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
+ ->getNumSelectorLocs())
+ newCursor.xdata = -1;
+ else
+ newCursor.xdata = SelIdx;
+ }
+
+ return newCursor;
+}
+
+CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
+ if (cursor.kind != CXCursor_CallExpr)
+ return cursor;
+
+ if (cursor.xdata == 0)
+ return cursor;
+
+ Expr *E = getCursorExpr(cursor);
+ TypeSourceInfo *Type = 0;
+ if (CXXUnresolvedConstructExpr *
+ UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
+ Type = UnCtor->getTypeSourceInfo();
+ } else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
+ Type = Tmp->getTypeSourceInfo();
+ }
+
+ if (!Type)
+ return cursor;
+
+ CXTranslationUnit TU = getCursorTU(cursor);
+ QualType Ty = Type->getType();
+ TypeLoc TL = Type->getTypeLoc();
+ SourceLocation Loc = TL.getBeginLoc();
+
+ if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
+ Ty = ElabT->getNamedType();
+ ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
+ Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
+ }
+
+ if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
+ return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
+ if (const TagType *Tag = Ty->getAs<TagType>())
+ return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
+ if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
+ return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
+
+ return cursor;
+}
+
bool cxcursor::operator==(CXCursor X, CXCursor Y) {
return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
X.data[2] == Y.data[2];
@@ -515,6 +918,22 @@ bool cxcursor::isFirstInDeclGroup(CXCursor C) {
}
//===----------------------------------------------------------------------===//
+// libclang CXCursor APIs
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+int clang_Cursor_isNull(CXCursor cursor) {
+ return clang_equalCursors(cursor, clang_getNullCursor());
+}
+
+CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
+ return getCursorTU(cursor);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
// CXCursorSet.
//===----------------------------------------------------------------------===//
@@ -577,4 +996,40 @@ unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
entry = 1;
return flag;
}
+
+CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
+ enum CXCursorKind kind = clang_getCursorKind(cursor);
+ if (clang_isDeclaration(kind)) {
+ Decl *decl = getCursorDecl(cursor);
+ if (isa<NamedDecl>(decl)) {
+ NamedDecl *namedDecl = (NamedDecl *)decl;
+ ASTUnit *unit = getCursorASTUnit(cursor);
+ if (unit->hasSema()) {
+ Sema &S = unit->getSema();
+ CodeCompletionAllocator *Allocator
+ = unit->getCursorCompletionAllocator().getPtr();
+ CodeCompletionResult Result(namedDecl);
+ CodeCompletionString *String
+ = Result.CreateCodeCompletionString(S, *Allocator);
+ return String;
+ }
+ }
+ }
+ else if (kind == CXCursor_MacroDefinition) {
+ MacroDefinition *definition = getCursorMacroDefinition(cursor);
+ const IdentifierInfo *MacroInfo = definition->getName();
+ ASTUnit *unit = getCursorASTUnit(cursor);
+ if (unit->hasSema()) {
+ Sema &S = unit->getSema();
+ CodeCompletionAllocator *Allocator
+ = unit->getCursorCompletionAllocator().getPtr();
+ CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
+ CodeCompletionString *String
+ = Result.CreateCodeCompletionString(S, *Allocator);
+ return String;
+ }
+ }
+ return NULL;
+}
+
} // end: extern "C"
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 68d09e7..e402d7f 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -43,13 +43,17 @@ class TemplateName;
class TypeDecl;
namespace cxcursor {
+
+CXCursor getCursor(CXTranslationUnit, SourceLocation);
CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent,
CXTranslationUnit TU);
CXCursor MakeCXCursor(clang::Decl *D, CXTranslationUnit TU,
+ SourceRange RegionOfInterest = SourceRange(),
bool FirstInDeclGroup = true);
CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent,
- CXTranslationUnit TU);
+ CXTranslationUnit TU,
+ SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K);
/// \brief Create an Objective-C superclass reference at the given location.
@@ -189,7 +193,36 @@ Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
CXTranslationUnit getCursorTU(CXCursor Cursor);
-
+
+void getOverriddenCursors(CXCursor cursor,
+ SmallVectorImpl<CXCursor> &overridden);
+
+/// \brief Returns a index/location pair for a selector identifier if the cursor
+/// points to one.
+std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
+static inline int getSelectorIdentifierIndex(CXCursor cursor) {
+ return getSelectorIdentifierIndexAndLoc(cursor).first;
+}
+static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
+ return getSelectorIdentifierIndexAndLoc(cursor).second;
+}
+
+CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
+
+static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
+ CXCursor newCursor = cursor;
+ if (cursor.kind == CXCursor_CallExpr)
+ newCursor.xdata = 1;
+ return newCursor;
+}
+
+CXCursor getTypeRefCursor(CXCursor cursor);
+
+/// \brief Generate a USR for \arg D and put it in \arg Buf.
+/// \returns true if no USR was computed or the result should be ignored,
+/// false otherwise.
+bool getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf);
+
bool operator==(CXCursor X, CXCursor Y);
inline bool operator!=(CXCursor X, CXCursor Y) {
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index f2a6b09..bb09cd5 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -41,7 +41,7 @@ CXString cxstring::createCXString(const char *String, bool DupString){
return Str;
}
-CXString cxstring::createCXString(llvm::StringRef String, bool DupString) {
+CXString cxstring::createCXString(StringRef String, bool DupString) {
CXString Result;
if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
char *Spelling = (char *)malloc(String.size() + 1);
@@ -101,6 +101,10 @@ void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
}
+bool cxstring::isManagedByPool(CXString str) {
+ return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
+}
+
//===----------------------------------------------------------------------===//
// libClang public APIs.
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index f03a6b2..d36c7c1 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_CXSTRING_H
#include "clang-c/Index.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
@@ -31,7 +32,7 @@ struct CXStringBuf {
CXString createCXString(const char *String, bool DupString = false);
/// \brief Create a CXString object from a StringRef.
-CXString createCXString(llvm::StringRef String, bool DupString = true);
+CXString createCXString(StringRef String, bool DupString = true);
/// \brief Create a CXString object that is backed by a string buffer.
CXString createCXString(CXStringBuf *buf);
@@ -46,6 +47,9 @@ CXStringBuf *getCXStringBuf(CXTranslationUnit TU);
void disposeCXStringBuf(CXStringBuf *buf);
+/// \brief Returns true if the CXString data is managed by a pool.
+bool isManagedByPool(CXString str);
+
}
}
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 6df85b7..2b8f977 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -21,4 +21,13 @@ struct CXTranslationUnitImpl {
};
}
+namespace clang {
+ class ASTUnit;
+
+namespace cxtu {
+
+CXTranslationUnitImpl *MakeCXTranslationUnit(ASTUnit *TU);
+
+}} // end namespace clang::cxtu
+
#endif
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 45c7346..0e62e27 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -84,6 +84,7 @@ static CXTypeKind GetTypeKind(QualType T) {
TKCASE(ObjCObjectPointer);
TKCASE(FunctionNoProto);
TKCASE(FunctionProto);
+ TKCASE(ConstantArray);
default:
return CXType_Unexposed;
}
@@ -330,6 +331,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(ObjCObjectPointer);
TKIND(FunctionNoProto);
TKIND(FunctionProto);
+ TKIND(ConstantArray);
}
#undef TKIND
return cxstring::createCXString(s);
@@ -373,6 +375,40 @@ unsigned clang_isPODType(CXType X) {
return T.isPODType(AU->getASTContext()) ? 1 : 0;
}
+CXType clang_getArrayElementType(CXType CT) {
+ QualType ET = QualType();
+ QualType T = GetQualType(CT);
+ const Type *TP = T.getTypePtrOrNull();
+
+ if (TP) {
+ switch (TP->getTypeClass()) {
+ case Type::ConstantArray:
+ ET = cast<ConstantArrayType> (TP)->getElementType();
+ break;
+ default:
+ break;
+ }
+ }
+ return MakeCXType(ET, GetTU(CT));
+}
+
+long long clang_getArraySize(CXType CT) {
+ long long result = -1;
+ QualType T = GetQualType(CT);
+ const Type *TP = T.getTypePtrOrNull();
+
+ if (TP) {
+ switch (TP->getTypeClass()) {
+ case Type::ConstantArray:
+ result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
+ break;
+ default:
+ break;
+ }
+ }
+ return result;
+}
+
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
return cxstring::createCXString("");
diff --git a/tools/libclang/Index_Internal.h b/tools/libclang/Index_Internal.h
new file mode 100644
index 0000000..df54d7c
--- /dev/null
+++ b/tools/libclang/Index_Internal.h
@@ -0,0 +1,43 @@
+//===- CXString.h - Routines for manipulating CXStrings -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines routines for manipulating CXStrings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBCLANG_INDEX_INTERNAL_H
+#define LLVM_LIBCLANG_INDEX_INTERNAL_H
+
+#include "clang-c/Index.h"
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(blocks)
+
+#define INVOKE_BLOCK2(block, arg1, arg2) block(arg1, arg2)
+
+#else
+// If we are compiled with a compiler that doesn't have native blocks support,
+// define and call the block manually.
+
+#define INVOKE_BLOCK2(block, arg1, arg2) block->invoke(block, arg1, arg2)
+
+typedef struct _CXCursorAndRangeVisitorBlock {
+ void *isa;
+ int flags;
+ int reserved;
+ enum CXVisitorResult (*invoke)(_CXCursorAndRangeVisitorBlock *,
+ CXCursor, CXSourceRange);
+} *CXCursorAndRangeVisitorBlock;
+
+#endif // !__has_feature(blocks)
+
+#endif
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
deleted file mode 100644
index bfc5be9..0000000
--- a/tools/libclang/libclang.darwin.exports
+++ /dev/null
@@ -1,143 +0,0 @@
-_clang_CXCursorSet_contains
-_clang_CXCursorSet_insert
-_clang_CXXMethod_isStatic
-_clang_CXXMethod_isVirtual
-_clang_annotateTokens
-_clang_codeCompleteAt
-_clang_codeCompleteGetDiagnostic
-_clang_codeCompleteGetNumDiagnostics
-_clang_codeCompleteGetContexts
-_clang_constructUSR_ObjCCategory
-_clang_constructUSR_ObjCClass
-_clang_constructUSR_ObjCIvar
-_clang_constructUSR_ObjCMethod
-_clang_constructUSR_ObjCProperty
-_clang_constructUSR_ObjCProtocol
-_clang_createCXCursorSet
-_clang_createIndex
-_clang_createTranslationUnit
-_clang_createTranslationUnitFromSourceFile
-_clang_defaultCodeCompleteOptions
-_clang_defaultDiagnosticDisplayOptions
-_clang_defaultEditingTranslationUnitOptions
-_clang_defaultReparseOptions
-_clang_defaultSaveOptions
-_clang_disposeCXCursorSet
-_clang_disposeCXTUResourceUsage
-_clang_disposeCodeCompleteResults
-_clang_disposeDiagnostic
-_clang_disposeIndex
-_clang_disposeOverriddenCursors
-_clang_disposeString
-_clang_disposeTokens
-_clang_disposeTranslationUnit
-_clang_enableStackTraces
-_clang_equalCursors
-_clang_equalLocations
-_clang_equalTypes
-_clang_executeOnThread
-_clang_formatDiagnostic
-_clang_getCString
-_clang_getCXTUResourceUsage
-_clang_getCXXAccessSpecifier
-_clang_getCanonicalCursor
-_clang_getCanonicalType
-_clang_getClangVersion
-_clang_getCompletionAvailability
-_clang_getCompletionChunkCompletionString
-_clang_getCompletionChunkKind
-_clang_getCompletionChunkText
-_clang_getCompletionPriority
-_clang_getCursor
-_clang_getCursorAvailability
-_clang_getCursorDefinition
-_clang_getCursorDisplayName
-_clang_getCursorExtent
-_clang_getCursorKind
-_clang_getCursorKindSpelling
-_clang_getCursorLanguage
-_clang_getCursorLexicalParent
-_clang_getCursorLinkage
-_clang_getCursorLocation
-_clang_getCursorReferenced
-_clang_getCursorResultType
-_clang_getCursorSemanticParent
-_clang_getCursorSpelling
-_clang_getCursorType
-_clang_getCursorUSR
-_clang_getDeclObjCTypeEncoding
-_clang_getDefinitionSpellingAndExtent
-_clang_getDiagnostic
-_clang_getDiagnosticCategory
-_clang_getDiagnosticCategoryName
-_clang_getDiagnosticFixIt
-_clang_getDiagnosticLocation
-_clang_getDiagnosticNumFixIts
-_clang_getDiagnosticNumRanges
-_clang_getDiagnosticOption
-_clang_getDiagnosticRange
-_clang_getDiagnosticSeverity
-_clang_getDiagnosticSpelling
-_clang_getFile
-_clang_getFileName
-_clang_getFileTime
-_clang_getIBOutletCollectionType
-_clang_getIncludedFile
-_clang_getInclusions
-_clang_getInstantiationLocation
-_clang_getLocation
-_clang_getLocationForOffset
-_clang_getNullCursor
-_clang_getNullLocation
-_clang_getNullRange
-_clang_getNumCompletionChunks
-_clang_getNumDiagnostics
-_clang_getNumOverloadedDecls
-_clang_getOverloadedDecl
-_clang_getOverriddenCursors
-_clang_getPointeeType
-_clang_getRange
-_clang_getRangeEnd
-_clang_getRangeStart
-_clang_getResultType
-_clang_getSpecializedCursorTemplate
-_clang_getSpellingLocation
-_clang_getTUResourceUsageName
-_clang_getTemplateCursorKind
-_clang_getTokenExtent
-_clang_getTokenKind
-_clang_getTokenLocation
-_clang_getTokenSpelling
-_clang_getTranslationUnitCursor
-_clang_getTranslationUnitSpelling
-_clang_getTypeDeclaration
-_clang_getTypeKindSpelling
-_clang_hashCursor
-_clang_isAttribute
-_clang_isConstQualifiedType
-_clang_isCursorDefinition
-_clang_isDeclaration
-_clang_isExpression
-_clang_isFileMultipleIncludeGuarded
-_clang_isInvalid
-_clang_isPODType
-_clang_isPreprocessing
-_clang_isReference
-_clang_isRestrictQualifiedType
-_clang_isStatement
-_clang_isTranslationUnit
-_clang_isUnexposed
-_clang_isVirtualBase
-_clang_isVolatileQualifiedType
-_clang_parseTranslationUnit
-_clang_reparseTranslationUnit
-_clang_saveTranslationUnit
-_clang_sortCodeCompletionResults
-_clang_toggleCrashRecovery
-_clang_tokenize
-_clang_visitChildren
-_clang_visitChildrenWithBlock
-_clang_getRemappings
-_clang_remap_getNumFiles
-_clang_remap_getFilenames
-_clang_remap_dispose
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 47b7030..989ed83 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -4,9 +4,12 @@ clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
clang_annotateTokens
clang_codeCompleteAt
+clang_codeCompleteGetContainerKind
+clang_codeCompleteGetContainerUSR
+clang_codeCompleteGetContexts
clang_codeCompleteGetDiagnostic
clang_codeCompleteGetNumDiagnostics
-clang_codeCompleteGetContexts
+clang_codeCompleteGetObjCSelector
clang_constructUSR_ObjCCategory
clang_constructUSR_ObjCClass
clang_constructUSR_ObjCIvar
@@ -17,6 +20,8 @@ clang_createCXCursorSet
clang_createIndex
clang_createTranslationUnit
clang_createTranslationUnitFromSourceFile
+clang_Cursor_getTranslationUnit
+clang_Cursor_isNull
clang_defaultCodeCompleteOptions
clang_defaultDiagnosticDisplayOptions
clang_defaultEditingTranslationUnitOptions
@@ -34,9 +39,14 @@ clang_disposeTranslationUnit
clang_enableStackTraces
clang_equalCursors
clang_equalLocations
+clang_equalRanges
clang_equalTypes
clang_executeOnThread
+clang_findReferencesInFile
+clang_findReferencesInFileWithBlock
clang_formatDiagnostic
+clang_getArrayElementType
+clang_getArraySize
clang_getCString
clang_getCXTUResourceUsage
clang_getCXXAccessSpecifier
@@ -44,12 +54,15 @@ clang_getCanonicalCursor
clang_getCanonicalType
clang_getClangVersion
clang_getCompletionAvailability
+clang_getCompletionAnnotation
clang_getCompletionChunkCompletionString
clang_getCompletionChunkKind
clang_getCompletionChunkText
+clang_getCompletionNumAnnotations
clang_getCompletionPriority
clang_getCursor
clang_getCursorAvailability
+clang_getCursorCompletionString
clang_getCursorDefinition
clang_getCursorDisplayName
clang_getCursorExtent
@@ -59,6 +72,7 @@ clang_getCursorLanguage
clang_getCursorLexicalParent
clang_getCursorLinkage
clang_getCursorLocation
+clang_getCursorReferenceNameRange
clang_getCursorReferenced
clang_getCursorResultType
clang_getCursorSemanticParent
@@ -96,9 +110,11 @@ clang_getNumOverloadedDecls
clang_getOverloadedDecl
clang_getOverriddenCursors
clang_getPointeeType
+clang_getPresumedLocation
clang_getRange
clang_getRangeEnd
clang_getRangeStart
+clang_getRemappings
clang_getResultType
clang_getSpecializedCursorTemplate
clang_getSpellingLocation
@@ -130,6 +146,10 @@ clang_isUnexposed
clang_isVirtualBase
clang_isVolatileQualifiedType
clang_parseTranslationUnit
+clang_Range_isNull
+clang_remap_dispose
+clang_remap_getFilenames
+clang_remap_getNumFiles
clang_reparseTranslationUnit
clang_saveTranslationUnit
clang_sortCodeCompletionResults
@@ -137,7 +157,3 @@ clang_toggleCrashRecovery
clang_tokenize
clang_visitChildren
clang_visitChildrenWithBlock
-clang_getRemappings
-clang_remap_getNumFiles
-clang_remap_getFilenames
-clang_remap_dispose
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 5697b21..c39e417 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -55,7 +55,10 @@ my $ResultFile;
# Remove any stale files at exit.
END {
- if (defined $CleanupFile && -z $CleanupFile) {
+ if (defined $ResultFile && -z $ResultFile) {
+ `rm -f $ResultFile`;
+ }
+ if (defined $CleanupFile) {
`rm -f $CleanupFile`;
}
}
@@ -365,9 +368,11 @@ my %LangMap = (
'cp' => 'c++',
'cpp' => 'c++',
'cc' => 'c++',
+ 'ii' => 'c++',
'i' => 'c-cpp-output',
'm' => 'objective-c',
- 'mi' => 'objective-c-cpp-output'
+ 'mi' => 'objective-c-cpp-output',
+ 'mm' => 'objective-c++'
);
my %UniqueOptions = (
@@ -380,14 +385,11 @@ my %UniqueOptions = (
my %LangsAccepted = (
"objective-c" => 1,
- "c" => 1
+ "c" => 1,
+ "c++" => 1,
+ "objective-c++" => 1
);
-if (defined $ENV{'CCC_ANALYZER_CPLUSPLUS'}) {
- $LangsAccepted{"c++"} = 1;
- $LangsAccepted{"objective-c++"} = 1;
-}
-
##----------------------------------------------------------------------------##
# Main Logic.
##----------------------------------------------------------------------------##
@@ -621,9 +623,9 @@ if ($Action eq 'compile' or $Action eq 'link') {
push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
}
-# if (defined $Analyses) {
-# push @AnalyzeArgs, split '\s+', $Analyses;
-# }
+ if (defined $Analyses) {
+ push @AnalyzeArgs, split '\s+', $Analyses;
+ }
if (defined $OutputFormat) {
push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;
@@ -632,7 +634,10 @@ if ($Action eq 'compile' or $Action eq 'link') {
my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
DIR => $HtmlDir);
$ResultFile = $f;
- $CleanupFile = $f;
+ # If the HtmlDir is not set, we sould clean up the plist files.
+ if (!defined $HtmlDir || -z $HtmlDir) {
+ $CleanupFile = $f;
+ }
}
}
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index f835ca3..dae86f4 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -61,7 +61,7 @@ sub DiagCrashes {
Diag ("The analyzer encountered problems on some source files.\n");
Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n");
Diag ("Please consider submitting a bug report using these files:\n");
- Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
+ Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n")
}
sub DieDiag {
@@ -802,7 +802,7 @@ ENDTEXT
}
print OUT "</table>\n";
}
- print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
+ print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang-analyzer.llvm.org/filing_bugs.html\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
}
print OUT "</body></html>\n";
OpenPOWER on IntegriCloud