summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
committerdim <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
commitc72c57c9e9b69944e3e009cd5e209634839581d3 (patch)
tree4fc2f184c499d106f29a386c452b49e5197bf63d /tools
parent5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff)
downloadFreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip
FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/Makefile2
-rw-r--r--tools/arcmt-test/CMakeLists.txt1
-rw-r--r--tools/arcmt-test/Makefile2
-rw-r--r--tools/arcmt-test/arcmt-test.cpp4
-rw-r--r--tools/c-arcmt-test/Makefile4
-rw-r--r--tools/c-index-test/CMakeLists.txt3
-rw-r--r--tools/c-index-test/Makefile9
-rw-r--r--tools/c-index-test/c-index-test.c456
-rw-r--r--tools/clang-check/CMakeLists.txt1
-rw-r--r--tools/clang-check/ClangCheck.cpp6
-rw-r--r--tools/clang-check/Makefile2
-rw-r--r--tools/clang-format/CMakeLists.txt17
-rw-r--r--tools/clang-format/ClangFormat.cpp152
-rw-r--r--tools/clang-format/Makefile24
-rwxr-xr-xtools/clang-format/clang-format-diff.py115
-rw-r--r--tools/clang-format/clang-format.py60
-rw-r--r--tools/diagtool/CMakeLists.txt1
-rw-r--r--tools/diagtool/DiagTool.cpp2
-rw-r--r--tools/diagtool/DiagTool.h2
-rw-r--r--tools/diagtool/ListWarnings.cpp6
-rw-r--r--tools/diagtool/Makefile2
-rw-r--r--tools/diagtool/ShowEnabledWarnings.cpp3
-rw-r--r--tools/diagtool/TreeView.cpp8
-rw-r--r--tools/driver/CMakeLists.txt2
-rw-r--r--tools/driver/Makefile29
-rw-r--r--tools/driver/cc1_main.cpp20
-rw-r--r--tools/driver/cc1as_main.cpp33
-rw-r--r--tools/driver/driver.cpp119
-rw-r--r--tools/libclang/ARCMigrate.cpp11
-rw-r--r--tools/libclang/CIndex.cpp1826
-rw-r--r--tools/libclang/CIndexCXX.cpp25
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp108
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp35
-rw-r--r--tools/libclang/CIndexHigh.cpp254
-rw-r--r--tools/libclang/CIndexInclusionStack.cpp7
-rw-r--r--tools/libclang/CIndexUSRs.cpp174
-rw-r--r--tools/libclang/CIndexer.cpp6
-rw-r--r--tools/libclang/CIndexer.h33
-rw-r--r--tools/libclang/CLog.h101
-rw-r--r--tools/libclang/CMakeLists.txt7
-rw-r--r--tools/libclang/CXComment.cpp212
-rw-r--r--tools/libclang/CXComment.h7
-rw-r--r--tools/libclang/CXCompilationDatabase.cpp24
-rw-r--r--tools/libclang/CXCursor.cpp255
-rw-r--r--tools/libclang/CXCursor.h100
-rw-r--r--tools/libclang/CXLoadedDiagnostic.cpp129
-rw-r--r--tools/libclang/CXLoadedDiagnostic.h4
-rw-r--r--tools/libclang/CXSourceLocation.cpp99
-rw-r--r--tools/libclang/CXSourceLocation.h6
-rw-r--r--tools/libclang/CXStoredDiagnostic.cpp17
-rw-r--r--tools/libclang/CXString.cpp147
-rw-r--r--tools/libclang/CXString.h82
-rw-r--r--tools/libclang/CXTranslationUnit.h30
-rw-r--r--tools/libclang/CXType.cpp110
-rw-r--r--tools/libclang/CursorVisitor.h29
-rw-r--r--tools/libclang/IndexBody.cpp1
-rw-r--r--tools/libclang/IndexDecl.cpp75
-rw-r--r--tools/libclang/IndexTypeSourceInfo.cpp1
-rw-r--r--tools/libclang/Indexing.cpp340
-rw-r--r--tools/libclang/IndexingContext.cpp79
-rw-r--r--tools/libclang/IndexingContext.h9
-rw-r--r--tools/libclang/Makefile15
-rw-r--r--tools/libclang/RecursiveASTVisitor.h16
-rw-r--r--tools/libclang/SimpleFormatContext.h75
-rw-r--r--tools/libclang/libclang.exports7
-rwxr-xr-xtools/scan-build/ccc-analyzer25
-rwxr-xr-xtools/scan-build/scan-build162
-rwxr-xr-xtools/scan-build/set-xcode-analyzer10
69 files changed, 3905 insertions, 1834 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index cccff5d..eb5e366 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -5,6 +5,7 @@ add_subdirectory(c-arcmt-test)
add_subdirectory(diagtool)
add_subdirectory(driver)
add_subdirectory(clang-check)
+add_subdirectory(clang-format)
# We support checking out the clang-tools-extra repository into the 'extra'
# subdirectory. It contains tools developed as part of the Clang/LLVM project
diff --git a/tools/Makefile b/tools/Makefile
index 23197a1..b33c74d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,7 +12,7 @@ CLANG_LEVEL := ..
include $(CLANG_LEVEL)/../../Makefile.config
DIRS := driver libclang c-index-test arcmt-test c-arcmt-test diagtool \
- clang-check
+ clang-check clang-format
# Recurse into the extra repository of tools if present.
OPTIONAL_DIRS := extra
diff --git a/tools/arcmt-test/CMakeLists.txt b/tools/arcmt-test/CMakeLists.txt
index a7ce586..3d85d05 100644
--- a/tools/arcmt-test/CMakeLists.txt
+++ b/tools/arcmt-test/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
asmparser
+ bitreader
support
mc
)
diff --git a/tools/arcmt-test/Makefile b/tools/arcmt-test/Makefile
index 06e2016..52898ce 100644
--- a/tools/arcmt-test/Makefile
+++ b/tools/arcmt-test/Makefile
@@ -17,7 +17,7 @@ TOOL_NO_EXPORTS = 1
NO_INSTALL = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
USEDLIBS = clangARCMigrate.a clangRewriteCore.a \
clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
clangSema.a clangEdit.a clangAnalysis.a clangAST.a clangLex.a \
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index b745893..179a115 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -10,11 +10,11 @@
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Frontend/VerifyDiagnosticConsumer.h"
#include "clang/Frontend/Utils.h"
+#include "clang/Frontend/VerifyDiagnosticConsumer.h"
#include "clang/Lex/Preprocessor.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
index 3372dae..02b8ab7 100644
--- a/tools/c-arcmt-test/Makefile
+++ b/tools/c-arcmt-test/Makefile
@@ -21,10 +21,10 @@ NO_INSTALL = 1
# LINK_COMPONENTS before including Makefile.rules
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
# Note that 'USEDLIBS' must include all of the core clang libraries
-# as clang.dll is unavailable on cygming yet.
+# when -static is given to linker on cygming.
USEDLIBS = clang.a \
clangARCMigrate.a \
clangRewriteFrontend.a \
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index 6f28c54..d90dc6d 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -23,8 +23,7 @@ set_target_properties(c-index-test
LINKER_LANGUAGE CXX)
# If libxml2 is available, make it available for c-index-test.
-if (LIBXML2_FOUND)
- add_definitions(${LIBXML2_DEFINITIONS} "-DCLANG_HAVE_LIBXML")
+if (CLANG_HAVE_LIBXML)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(c-index-test ${LIBXML2_LIBRARIES})
endif()
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index b81678b..7723115 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -22,8 +22,13 @@ TOOL_NO_EXPORTS = 1
# LINK_COMPONENTS before including Makefile.rules
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
-USEDLIBS = clang.a clangFrontend.a clangDriver.a \
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
+
+# Note that 'USEDLIBS' must include all of the core clang libraries
+# when -static is given to linker on cygming.
+USEDLIBS = clang.a \
+ clangFormat.a clangRewriteCore.a \
+ clangFrontend.a clangDriver.a \
clangTooling.a \
clangSerialization.a clangParse.a clangSema.a \
clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 3e4404c..88b49ed 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -15,6 +15,12 @@
#include <libxml/xmlerror.h>
#endif
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+
/******************************************************************************/
/* Utility functions. */
/******************************************************************************/
@@ -1077,36 +1083,42 @@ static enum CXChildVisitResult PrintLinkage(CXCursor cursor, CXCursor p,
/* Typekind testing. */
/******************************************************************************/
-static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
- CXClientData d) {
+static void PrintTypeAndTypeKind(CXType T, const char *Format) {
+ CXString TypeSpelling, TypeKindSpelling;
+
+ TypeSpelling = clang_getTypeSpelling(T);
+ TypeKindSpelling = clang_getTypeKindSpelling(T.kind);
+ printf(Format,
+ clang_getCString(TypeSpelling),
+ clang_getCString(TypeKindSpelling));
+ clang_disposeString(TypeSpelling);
+ clang_disposeString(TypeKindSpelling);
+}
+
+static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
+ CXClientData d) {
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
CXType T = clang_getCursorType(cursor);
- CXString S = clang_getTypeKindSpelling(T.kind);
PrintCursor(cursor, NULL);
- printf(" typekind=%s", clang_getCString(S));
+ PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
if (clang_isConstQualifiedType(T))
printf(" const");
if (clang_isVolatileQualifiedType(T))
printf(" volatile");
if (clang_isRestrictQualifiedType(T))
printf(" restrict");
- clang_disposeString(S);
/* Print the canonical type if it is different. */
{
CXType CT = clang_getCanonicalType(T);
if (!clang_equalTypes(T, CT)) {
- CXString CS = clang_getTypeKindSpelling(CT.kind);
- printf(" [canonical=%s]", clang_getCString(CS));
- clang_disposeString(CS);
+ PrintTypeAndTypeKind(CT, " [canonicaltype=%s] [canonicaltypekind=%s]");
}
}
/* Print the return type if it exists. */
{
CXType RT = clang_getCursorResultType(cursor);
if (RT.kind != CXType_Invalid) {
- CXString RS = clang_getTypeKindSpelling(RT.kind);
- printf(" [result=%s]", clang_getCString(RS));
- clang_disposeString(RS);
+ PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]");
}
}
/* Print the argument types if they exist. */
@@ -1118,9 +1130,7 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
for (i = 0; i < numArgs; ++i) {
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
if (T.kind != CXType_Invalid) {
- CXString S = clang_getTypeKindSpelling(T.kind);
- printf(" %s", clang_getCString(S));
- clang_disposeString(S);
+ PrintTypeAndTypeKind(T, " [%s] [%s]");
}
}
printf("]");
@@ -1134,6 +1144,24 @@ static enum CXChildVisitResult PrintTypeKind(CXCursor cursor, CXCursor p,
return CXChildVisit_Recurse;
}
+/******************************************************************************/
+/* Bitwidth testing. */
+/******************************************************************************/
+
+static enum CXChildVisitResult PrintBitWidth(CXCursor cursor, CXCursor p,
+ CXClientData d) {
+ int Bitwidth;
+ if (clang_getCursorKind(cursor) != CXCursor_FieldDecl)
+ return CXChildVisit_Recurse;
+
+ Bitwidth = clang_getFieldDeclBitWidth(cursor);
+ if (Bitwidth >= 0) {
+ PrintCursor(cursor, NULL);
+ printf(" bitwidth=%d\n", Bitwidth);
+ }
+
+ return CXChildVisit_Recurse;
+}
/******************************************************************************/
/* Loading ASTs/source. */
@@ -1203,7 +1231,7 @@ int perform_test_load_tu(const char *file, const char *filter,
int result;
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
- /* displayDiagnosics=*/1);
+ /* displayDiagnostics=*/1);
if (!CreateTranslationUnit(Idx, file, &TU)) {
clang_disposeIndex(Idx);
@@ -1228,7 +1256,7 @@ int perform_test_load_source(int argc, const char **argv,
Idx = clang_createIndex(/* excludeDeclsFromPCH */
(!strcmp(filter, "local") ||
!strcmp(filter, "local-display"))? 1 : 0,
- /* displayDiagnosics=*/0);
+ /* displayDiagnostics=*/0);
if ((CommentSchemaFile = parse_comments_schema(argc, argv))) {
argc--;
@@ -1273,7 +1301,7 @@ int perform_test_reparse_source(int argc, const char **argv, int trials,
Idx = clang_createIndex(/* excludeDeclsFromPCH */
!strcmp(filter, "local") ? 1 : 0,
- /* displayDiagnosics=*/0);
+ /* displayDiagnostics=*/0);
if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
clang_disposeIndex(Idx);
@@ -1352,7 +1380,7 @@ static int perform_file_scan(const char *ast_file, const char *source_file,
unsigned start_line = 1, start_col = 1;
if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
+ /* displayDiagnostics=*/1))) {
fprintf(stderr, "Could not create Index\n");
return 1;
}
@@ -1968,12 +1996,12 @@ static int inspect_cursor_at(int argc, const char **argv) {
unsigned i, numHeaders;
if (mod) {
name = clang_Module_getFullName(mod);
- numHeaders = clang_Module_getNumTopLevelHeaders(mod);
+ numHeaders = clang_Module_getNumTopLevelHeaders(TU, mod);
printf(" ModuleName=%s Headers(%d):",
clang_getCString(name), numHeaders);
clang_disposeString(name);
for (i = 0; i < numHeaders; ++i) {
- CXFile file = clang_Module_getTopLevelHeader(mod, i);
+ CXFile file = clang_Module_getTopLevelHeader(TU, mod, i);
CXString filename = clang_getFileName(file);
printf("\n%s", clang_getCString(filename));
clang_disposeString(filename);
@@ -2107,6 +2135,99 @@ static int find_file_refs_at(int argc, const char **argv) {
return 0;
}
+static enum CXVisitorResult findFileIncludesVisit(void *context,
+ CXCursor cursor, CXSourceRange range) {
+ PrintCursor(cursor, NULL);
+ PrintRange(range, "");
+ printf("\n");
+ return CXVisit_Continue;
+}
+
+static int find_file_includes_in(int argc, const char **argv) {
+ CXIndex CIdx;
+ struct CXUnsavedFile *unsaved_files = 0;
+ int num_unsaved_files = 0;
+ CXTranslationUnit TU;
+ const char **Filenames = 0;
+ unsigned NumFilenames = 0;
+ unsigned Repeats = 1;
+ unsigned I, FI;
+
+ /* Count the number of locations. */
+ while (strstr(argv[NumFilenames+1], "-file-includes-in=") == argv[NumFilenames+1])
+ ++NumFilenames;
+
+ /* Parse the locations. */
+ assert(NumFilenames > 0 && "Unable to count filenames?");
+ Filenames = (const char **)malloc(NumFilenames * sizeof(const char *));
+ for (I = 0; I < NumFilenames; ++I) {
+ const char *input = argv[I + 1] + strlen("-file-includes-in=");
+ /* Copy the file name. */
+ Filenames[I] = input;
+ }
+
+ if (parse_remapped_files(argc, argv, NumFilenames + 1, &unsaved_files,
+ &num_unsaved_files))
+ return -1;
+
+ if (getenv("CINDEXTEST_EDITING"))
+ Repeats = 2;
+
+ /* 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 + NumFilenames,
+ argc - num_unsaved_files - 2 - NumFilenames,
+ unsaved_files,
+ Repeats > 1? 0 : num_unsaved_files,
+ getDefaultParsingOptions());
+
+ if (!TU) {
+ fprintf(stderr, "unable to parse input\n");
+ return -1;
+ }
+
+ if (checkForErrors(TU) != 0)
+ 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;
+ }
+
+ if (checkForErrors(TU) != 0)
+ return -1;
+
+ for (FI = 0; FI < NumFilenames; ++FI) {
+ CXFile file = clang_getFile(TU, Filenames[FI]);
+ if (!file)
+ continue;
+
+ if (checkForErrors(TU) != 0)
+ return -1;
+
+ if (I + 1 == Repeats) {
+ CXCursorAndRangeVisitor visitor = { 0, findFileIncludesVisit };
+ clang_findIncludesInFile(TU, file, visitor);
+
+ if (checkForErrors(TU) != 0)
+ return -1;
+ }
+ }
+ }
+
+ PrintDiagnostics(TU);
+ clang_disposeTranslationUnit(TU);
+ clang_disposeIndex(CIdx);
+ free((void *)Filenames);
+ free_remapped_files(unsaved_files, num_unsaved_files);
+ return 0;
+}
+
#define MAX_IMPORTED_ASTFILES 200
typedef struct {
@@ -2473,7 +2594,12 @@ static void index_indexDeclaration(CXClientData client_data,
printCXIndexContainer(info->lexicalContainer);
printf(" | isRedecl: %d", info->isRedeclaration);
printf(" | isDef: %d", info->isDefinition);
- printf(" | isContainer: %d", info->isContainer);
+ if (info->flags & CXIdxDeclFlag_Skipped) {
+ assert(!info->isContainer);
+ printf(" | isContainer: skipped");
+ } else {
+ printf(" | isContainer: %d", info->isContainer);
+ }
printf(" | isImplicit: %d\n", info->isImplicit);
for (i = 0; i != info->numAttributes; ++i) {
@@ -2584,16 +2710,79 @@ static unsigned getIndexOptions(void) {
index_opts |= CXIndexOpt_SuppressRedundantRefs;
if (getenv("CINDEXTEST_INDEXLOCALSYMBOLS"))
index_opts |= CXIndexOpt_IndexFunctionLocalSymbols;
+ if (!getenv("CINDEXTEST_DISABLE_SKIPPARSEDBODIES"))
+ index_opts |= CXIndexOpt_SkipParsedBodiesInSession;
return index_opts;
}
+static int index_compile_args(int num_args, const char **args,
+ CXIndexAction idxAction,
+ ImportedASTFilesData *importedASTs,
+ const char *check_prefix) {
+ IndexData index_data;
+ unsigned index_opts;
+ int result;
+
+ if (num_args == 0) {
+ fprintf(stderr, "no compiler arguments\n");
+ return -1;
+ }
+
+ index_data.check_prefix = check_prefix;
+ index_data.first_check_printed = 0;
+ index_data.fail_for_error = 0;
+ index_data.abort = 0;
+ index_data.main_filename = "";
+ index_data.importedASTs = importedASTs;
+
+ index_opts = getIndexOptions();
+ result = clang_indexSourceFile(idxAction, &index_data,
+ &IndexCB,sizeof(IndexCB), index_opts,
+ 0, args, num_args, 0, 0, 0,
+ getDefaultParsingOptions());
+ if (index_data.fail_for_error)
+ result = -1;
+
+ return result;
+}
+
+static int index_ast_file(const char *ast_file,
+ CXIndex Idx,
+ CXIndexAction idxAction,
+ ImportedASTFilesData *importedASTs,
+ const char *check_prefix) {
+ CXTranslationUnit TU;
+ IndexData index_data;
+ unsigned index_opts;
+ int result;
+
+ if (!CreateTranslationUnit(Idx, ast_file, &TU))
+ return -1;
+
+ index_data.check_prefix = check_prefix;
+ index_data.first_check_printed = 0;
+ index_data.fail_for_error = 0;
+ index_data.abort = 0;
+ index_data.main_filename = "";
+ index_data.importedASTs = importedASTs;
+
+ index_opts = getIndexOptions();
+ result = clang_indexTranslationUnit(idxAction, &index_data,
+ &IndexCB,sizeof(IndexCB),
+ index_opts, TU);
+ if (index_data.fail_for_error)
+ result = -1;
+
+ clang_disposeTranslationUnit(TU);
+ return result;
+}
+
static int index_file(int argc, const char **argv, int full) {
const char *check_prefix;
CXIndex Idx;
CXIndexAction idxAction;
- IndexData index_data;
- unsigned index_opts;
+ ImportedASTFilesData *importedASTs;
int result;
check_prefix = 0;
@@ -2605,68 +2794,39 @@ static int index_file(int argc, const char **argv, int full) {
}
}
- if (argc == 0) {
- fprintf(stderr, "no compiler arguments\n");
- return -1;
- }
-
if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
+ /* displayDiagnostics=*/1))) {
fprintf(stderr, "Could not create Index\n");
return 1;
}
- idxAction = 0;
-
- index_data.check_prefix = check_prefix;
- index_data.first_check_printed = 0;
- index_data.fail_for_error = 0;
- index_data.abort = 0;
- index_data.main_filename = "";
- index_data.importedASTs = 0;
-
+ idxAction = clang_IndexAction_create(Idx);
+ importedASTs = 0;
if (full)
- index_data.importedASTs = importedASTs_create();
+ importedASTs = importedASTs_create();
+
+ result = index_compile_args(argc, argv, idxAction, importedASTs, check_prefix);
+ if (result != 0)
+ goto finished;
- index_opts = getIndexOptions();
- idxAction = clang_IndexAction_create(Idx);
- result = clang_indexSourceFile(idxAction, &index_data,
- &IndexCB,sizeof(IndexCB), index_opts,
- 0, argv, argc, 0, 0, 0,
- getDefaultParsingOptions());
- if (index_data.fail_for_error)
- result = -1;
-
if (full) {
- CXTranslationUnit TU;
unsigned i;
-
- for (i = 0; i < index_data.importedASTs->num_files; ++i) {
- if (!CreateTranslationUnit(Idx, index_data.importedASTs->filenames[i],
- &TU)) {
- result = -1;
- goto finished;
- }
- result = clang_indexTranslationUnit(idxAction, &index_data,
- &IndexCB,sizeof(IndexCB),
- index_opts, TU);
- clang_disposeTranslationUnit(TU);
+ for (i = 0; i < importedASTs->num_files && result == 0; ++i) {
+ result = index_ast_file(importedASTs->filenames[i], Idx, idxAction,
+ importedASTs, check_prefix);
}
}
finished:
- importedASTs_dispose(index_data.importedASTs);
+ importedASTs_dispose(importedASTs);
clang_IndexAction_dispose(idxAction);
clang_disposeIndex(Idx);
return result;
}
static int index_tu(int argc, const char **argv) {
+ const char *check_prefix;
CXIndex Idx;
CXIndexAction idxAction;
- CXTranslationUnit TU;
- const char *check_prefix;
- IndexData index_data;
- unsigned index_opts;
int result;
check_prefix = 0;
@@ -2678,44 +2838,142 @@ static int index_tu(int argc, const char **argv) {
}
}
+ if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
+ /* displayDiagnostics=*/1))) {
+ fprintf(stderr, "Could not create Index\n");
+ return 1;
+ }
+ idxAction = clang_IndexAction_create(Idx);
+
+ result = index_ast_file(argv[0], Idx, idxAction,
+ /*importedASTs=*/0, check_prefix);
+
+ clang_IndexAction_dispose(idxAction);
+ clang_disposeIndex(Idx);
+ return result;
+}
+
+static int index_compile_db(int argc, const char **argv) {
+ const char *check_prefix;
+ CXIndex Idx;
+ CXIndexAction idxAction;
+ int errorCode = 0;
+
+ check_prefix = 0;
+ if (argc > 0) {
+ if (strstr(argv[0], "-check-prefix=") == argv[0]) {
+ check_prefix = argv[0] + strlen("-check-prefix=");
+ ++argv;
+ --argc;
+ }
+ }
+
if (argc == 0) {
- fprintf(stderr, "no ast file\n");
+ fprintf(stderr, "no compilation database\n");
return -1;
}
if (!(Idx = clang_createIndex(/* excludeDeclsFromPCH */ 1,
- /* displayDiagnosics=*/1))) {
+ /* displayDiagnostics=*/1))) {
fprintf(stderr, "Could not create Index\n");
return 1;
}
- idxAction = 0;
- TU = 0;
- result = 1;
+ idxAction = clang_IndexAction_create(Idx);
- if (!CreateTranslationUnit(Idx, argv[0], &TU))
- goto finished;
+ {
+ const char *database = argv[0];
+ CXCompilationDatabase db = 0;
+ CXCompileCommands CCmds = 0;
+ CXCompileCommand CCmd;
+ CXCompilationDatabase_Error ec;
+ CXString wd;
+#define MAX_COMPILE_ARGS 512
+ CXString cxargs[MAX_COMPILE_ARGS];
+ const char *args[MAX_COMPILE_ARGS];
+ char *tmp;
+ unsigned len;
+ char *buildDir;
+ int i, a, numCmds, numArgs;
+
+ len = strlen(database);
+ tmp = (char *) malloc(len+1);
+ memcpy(tmp, database, len+1);
+ buildDir = dirname(tmp);
+
+ db = clang_CompilationDatabase_fromDirectory(buildDir, &ec);
+
+ if (db) {
+
+ if (ec!=CXCompilationDatabase_NoError) {
+ printf("unexpected error %d code while loading compilation database\n", ec);
+ errorCode = -1;
+ goto cdb_end;
+ }
- index_data.check_prefix = check_prefix;
- index_data.first_check_printed = 0;
- index_data.fail_for_error = 0;
- index_data.abort = 0;
- index_data.main_filename = "";
- index_data.importedASTs = 0;
+ if (chdir(buildDir) != 0) {
+ printf("Could not chdir to %s\n", buildDir);
+ errorCode = -1;
+ goto cdb_end;
+ }
- index_opts = getIndexOptions();
- idxAction = clang_IndexAction_create(Idx);
- result = clang_indexTranslationUnit(idxAction, &index_data,
- &IndexCB,sizeof(IndexCB),
- index_opts, TU);
- if (index_data.fail_for_error)
- goto finished;
+ CCmds = clang_CompilationDatabase_getAllCompileCommands(db);
+ if (!CCmds) {
+ printf("compilation db is empty\n");
+ errorCode = -1;
+ goto cdb_end;
+ }
+
+ numCmds = clang_CompileCommands_getSize(CCmds);
+
+ if (numCmds==0) {
+ fprintf(stderr, "should not get an empty compileCommand set\n");
+ errorCode = -1;
+ goto cdb_end;
+ }
+
+ for (i=0; i<numCmds && errorCode == 0; ++i) {
+ CCmd = clang_CompileCommands_getCommand(CCmds, i);
+
+ wd = clang_CompileCommand_getDirectory(CCmd);
+ if (chdir(clang_getCString(wd)) != 0) {
+ printf("Could not chdir to %s\n", clang_getCString(wd));
+ errorCode = -1;
+ goto cdb_end;
+ }
+ clang_disposeString(wd);
+
+ numArgs = clang_CompileCommand_getNumArgs(CCmd);
+ if (numArgs > MAX_COMPILE_ARGS){
+ fprintf(stderr, "got more compile arguments than maximum\n");
+ errorCode = -1;
+ goto cdb_end;
+ }
+ for (a=0; a<numArgs; ++a) {
+ cxargs[a] = clang_CompileCommand_getArg(CCmd, a);
+ args[a] = clang_getCString(cxargs[a]);
+ }
+
+ errorCode = index_compile_args(numArgs, args, idxAction,
+ /*importedASTs=*/0, check_prefix);
+
+ for (a=0; a<numArgs; ++a)
+ clang_disposeString(cxargs[a]);
+ }
+ } else {
+ printf("database loading failed with error code %d.\n", ec);
+ errorCode = -1;
+ }
+
+ cdb_end:
+ clang_CompileCommands_dispose(CCmds);
+ clang_CompilationDatabase_dispose(db);
+ free(tmp);
+
+ }
- finished:
clang_IndexAction_dispose(idxAction);
- clang_disposeTranslationUnit(TU);
clang_disposeIndex(Idx);
-
- return result;
+ return errorCode;
}
int perform_token_annotation(int argc, const char **argv) {
@@ -3124,7 +3382,7 @@ int write_pch_file(const char *filename, int argc, const char *argv[]) {
int num_unsaved_files = 0;
int result = 0;
- Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnosics=*/1);
+ Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);
if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
clang_disposeIndex(Idx);
@@ -3355,11 +3613,13 @@ 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 -file-refs-at=<site> <compiler arguments>\n"
+ " c-index-test -file-includes-in=<filename> <compiler arguments>\n");
fprintf(stderr,
" c-index-test -index-file [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
" c-index-test -index-file-full [-check-prefix=<FileCheck prefix>] <compiler arguments>\n"
" c-index-test -index-tu [-check-prefix=<FileCheck prefix>] <AST file>\n"
+ " c-index-test -index-compile-db [-check-prefix=<FileCheck prefix>] <compilation database>\n"
" c-index-test -test-file-scan <AST file> <source file> "
"[FileCheck prefix]\n");
fprintf(stderr,
@@ -3381,7 +3641,8 @@ static void print_usage(void) {
" c-index-test -test-inclusion-stack-tu <AST file>\n");
fprintf(stderr,
" c-index-test -test-print-linkage-source {<args>}*\n"
- " c-index-test -test-print-typekind {<args>}*\n"
+ " c-index-test -test-print-type {<args>}*\n"
+ " c-index-test -test-print-bitwidth {<args>}*\n"
" c-index-test -print-usr [<CursorKind> {<args>}]*\n"
" c-index-test -print-usr-file <file>\n"
" c-index-test -write-pch <file> <compiler arguments>\n");
@@ -3415,12 +3676,16 @@ int cindextest_main(int argc, const char **argv) {
return inspect_cursor_at(argc, argv);
if (argc > 2 && strstr(argv[1], "-file-refs-at=") == argv[1])
return find_file_refs_at(argc, argv);
+ if (argc > 2 && strstr(argv[1], "-file-includes-in=") == argv[1])
+ return find_file_includes_in(argc, argv);
if (argc > 2 && strcmp(argv[1], "-index-file") == 0)
return index_file(argc - 2, argv + 2, /*full=*/0);
if (argc > 2 && strcmp(argv[1], "-index-file-full") == 0)
return index_file(argc - 2, argv + 2, /*full=*/1);
if (argc > 2 && strcmp(argv[1], "-index-tu") == 0)
return index_tu(argc - 2, argv + 2);
+ if (argc > 2 && strcmp(argv[1], "-index-compile-db") == 0)
+ return index_compile_db(argc - 2, argv + 2);
else if (argc >= 4 && strncmp(argv[1], "-test-load-tu", 13) == 0) {
CXCursorVisitor I = GetVisitor(argv[1] + 13);
if (I)
@@ -3460,9 +3725,12 @@ int cindextest_main(int argc, const char **argv) {
else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0)
return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage,
NULL);
- else if (argc > 2 && strcmp(argv[1], "-test-print-typekind") == 0)
+ else if (argc > 2 && strcmp(argv[1], "-test-print-type") == 0)
+ return perform_test_load_source(argc - 2, argv + 2, "all",
+ PrintType, 0);
+ else if (argc > 2 && strcmp(argv[1], "-test-print-bitwidth") == 0)
return perform_test_load_source(argc - 2, argv + 2, "all",
- PrintTypeKind, 0);
+ PrintBitWidth, 0);
else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
if (argc > 2)
return print_usrs(argv + 2, argv + argc);
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index f5d7616..e8d0d0a 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
asmparser
+ bitreader
support
mc
)
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index 6c081ac..bf43374 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -27,6 +27,7 @@
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
using namespace clang::driver;
using namespace clang::tooling;
@@ -142,9 +143,10 @@ public:
}
int main(int argc, const char **argv) {
+ llvm::sys::PrintStackTraceOnErrorSignal();
CommonOptionsParser OptionsParser(argc, argv);
- ClangTool Tool(OptionsParser.GetCompilations(),
- OptionsParser.GetSourcePathList());
+ ClangTool Tool(OptionsParser.getCompilations(),
+ OptionsParser.getSourcePathList());
if (Fixit)
return Tool.run(newFrontendActionFactory<FixItAction>());
clang_check::ClangCheckActionFactory Factory;
diff --git a/tools/clang-check/Makefile b/tools/clang-check/Makefile
index 28f94f6..7d6505e 100644
--- a/tools/clang-check/Makefile
+++ b/tools/clang-check/Makefile
@@ -15,7 +15,7 @@ TOOLNAME = clang-check
TOOL_NO_EXPORTS = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangParse.a clangSema.a clangAnalysis.a \
clangRewriteFrontend.a clangRewriteCore.a clangEdit.a clangAST.a \
diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
new file mode 100644
index 0000000..c86a920
--- /dev/null
+++ b/tools/clang-format/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_LINK_COMPONENTS support)
+set(LLVM_USED_LIBS clangFormat clangTooling clangBasic clangAST)
+
+add_clang_executable(clang-format
+ ClangFormat.cpp
+ )
+
+target_link_libraries(clang-format
+ clangFormat
+ clangTooling
+ clangBasic
+ clangRewriteFrontend
+ )
+
+install(TARGETS clang-format
+ RUNTIME DESTINATION bin)
+
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
new file mode 100644
index 0000000..c4969b2
--- /dev/null
+++ b/tools/clang-format/ClangFormat.cpp
@@ -0,0 +1,152 @@
+//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements a clang-format tool that automatically formats
+/// (fragments of) C++ code.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Signals.h"
+
+using namespace llvm;
+
+static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
+
+static cl::list<int> Offsets(
+ "offset", cl::desc("Format a range starting at this file offset."));
+static cl::list<int> Lengths(
+ "length", cl::desc("Format a range of this length, -1 for end of file."));
+static cl::opt<std::string> Style(
+ "style",
+ cl::desc("Coding style, currently supports: LLVM, Google, Chromium."),
+ cl::init("LLVM"));
+static cl::opt<bool> Inplace("i",
+ cl::desc("Inplace edit <file>, if specified."));
+
+static cl::opt<bool> OutputXML(
+ "output-replacements-xml", cl::desc("Output replacements as XML."));
+
+static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),
+ cl::init("-"));
+
+namespace clang {
+namespace format {
+
+static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
+ SourceManager &Sources, FileManager &Files) {
+ const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
+ FileName,
+ Source->getBufferSize(), 0);
+ Sources.overrideFileContents(Entry, Source, true);
+ return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+}
+
+static FormatStyle getStyle() {
+ FormatStyle TheStyle = getGoogleStyle();
+ if (Style == "LLVM")
+ TheStyle = getLLVMStyle();
+ if (Style == "Chromium")
+ TheStyle = getChromiumStyle();
+ return TheStyle;
+}
+
+static void format() {
+ FileManager Files((FileSystemOptions()));
+ DiagnosticsEngine Diagnostics(
+ IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
+ new DiagnosticOptions);
+ SourceManager Sources(Diagnostics, Files);
+ OwningPtr<MemoryBuffer> Code;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
+ llvm::errs() << ec.message() << "\n";
+ return;
+ }
+ FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
+ Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
+ if (Offsets.empty())
+ Offsets.push_back(0);
+ if (Offsets.size() != Lengths.size() &&
+ !(Offsets.size() == 1 && Lengths.empty())) {
+ llvm::errs() << "Number of -offset and -length arguments must match.\n";
+ return;
+ }
+ std::vector<CharSourceRange> Ranges;
+ for (cl::list<int>::size_type i = 0, e = Offsets.size(); i != e; ++i) {
+ SourceLocation Start =
+ Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
+ SourceLocation End;
+ if (i < Lengths.size()) {
+ End = Start.getLocWithOffset(Lengths[i]);
+ } else {
+ End = Sources.getLocForEndOfFile(ID);
+ }
+ Ranges.push_back(CharSourceRange::getCharRange(Start, End));
+ }
+ tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
+ if (OutputXML) {
+ llvm::outs() << "<?xml version='1.0'?>\n<replacements xml:space='preserve'>\n";
+ for (tooling::Replacements::const_iterator I = Replaces.begin(),
+ E = Replaces.end();
+ I != E; ++I) {
+ llvm::outs() << "<replacement "
+ << "offset='" << I->getOffset() << "' "
+ << "length='" << I->getLength() << "'>"
+ << I->getReplacementText() << "</replacement>\n";
+ }
+ llvm::outs() << "</replacements>\n";
+ } else {
+ Rewriter Rewrite(Sources, LangOptions());
+ tooling::applyAllReplacements(Replaces, Rewrite);
+ if (Inplace) {
+ if (Replaces.size() == 0)
+ return; // Nothing changed, don't touch the file.
+
+ std::string ErrorInfo;
+ llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
+ llvm::raw_fd_ostream::F_Binary);
+ if (!ErrorInfo.empty()) {
+ llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
+ return;
+ }
+ Rewrite.getEditBuffer(ID).write(FileStream);
+ FileStream.flush();
+ } else {
+ Rewrite.getEditBuffer(ID).write(outs());
+ }
+ }
+}
+
+} // namespace format
+} // namespace clang
+
+int main(int argc, const char **argv) {
+ llvm::sys::PrintStackTraceOnErrorSignal();
+ cl::ParseCommandLineOptions(
+ argc, argv,
+ "A tool to format C/C++/Obj-C code.\n\n"
+ "Currently supports LLVM and Google style guides.\n"
+ "If no arguments are specified, it formats the code from standard input\n"
+ "and writes the result to the standard output.\n"
+ "If <file> is given, it reformats the file. If -i is specified together\n"
+ "with <file>, the file is edited in-place. Otherwise, the result is\n"
+ "written to the standard output.\n");
+ if (Help)
+ cl::PrintHelpMessage();
+ clang::format::format();
+ return 0;
+}
diff --git a/tools/clang-format/Makefile b/tools/clang-format/Makefile
new file mode 100644
index 0000000..d869267
--- /dev/null
+++ b/tools/clang-format/Makefile
@@ -0,0 +1,24 @@
+##===- clang-format/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 = clang-format
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
+USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \
+ clangDriver.a clangParse.a clangSema.a clangAnalysis.a \
+ clangRewriteFrontend.a clangRewriteCore.a clangEdit.a clangAST.a \
+ clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
new file mode 100755
index 0000000..ab5f1b1
--- /dev/null
+++ b/tools/clang-format/clang-format-diff.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+#
+#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+ClangFormat Diff Reformatter
+============================
+
+This script reads input from a unified diff and reformats all the changed
+lines. This is useful to reformat all the lines touched by a specific patch.
+Example usage for git users:
+
+ git diff -U0 HEAD^ | clang-format-diff.py -p1
+
+"""
+
+import argparse
+import re
+import subprocess
+import sys
+
+
+# Change this to the full path if clang-format is not on the path.
+binary = 'clang-format'
+
+
+def getOffsetLength(filename, line_number, line_count):
+ """
+ Calculates the field offset and length based on line number and count.
+ """
+ offset = 0
+ length = 0
+ with open(filename, 'r') as f:
+ for line in f:
+ if line_number > 1:
+ offset += len(line)
+ line_number -= 1
+ elif line_count > 0:
+ length += len(line)
+ line_count -= 1
+ else:
+ break
+ return offset, length
+
+
+def formatRange(r, style):
+ """
+ Formats range 'r' according to style 'style'.
+ """
+ filename, line_number, line_count = r
+ # FIXME: Add other types containing C++/ObjC code.
+ if not (filename.endswith(".cpp") or filename.endswith(".cc") or
+ filename.endswith(".h")):
+ return
+
+ offset, length = getOffsetLength(filename, line_number, line_count)
+ with open(filename, 'r') as f:
+ text = f.read()
+ p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length),
+ '-style', style],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+ stdout, stderr = p.communicate(input=text)
+ if stderr:
+ print stderr
+ return
+ if not stdout:
+ print 'Segfault occurred while formatting', filename
+ print 'Please report a bug on llvm.org/bugs.'
+ return
+ with open(filename, 'w') as f:
+ f.write(stdout)
+
+
+def main():
+ parser = argparse.ArgumentParser(description=
+ 'Reformat changed lines in diff')
+ parser.add_argument('-p', default=1,
+ help='strip the smallest prefix containing P slashes')
+ parser.add_argument('-style', default='LLVM',
+ help='formatting style to apply (LLVM, Google)')
+ args = parser.parse_args()
+
+ filename = None
+ ranges = []
+
+ for line in sys.stdin:
+ match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
+ if match:
+ filename = match.group(2)
+ if filename == None:
+ continue
+
+ match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
+ if match:
+ line_count = 1
+ if match.group(3):
+ line_count = int(match.group(3))
+ ranges.append((filename, int(match.group(1)), line_count))
+
+ # Reverse the ranges so that the reformatting does not influence file offsets.
+ for r in reversed(ranges):
+ # Do the actual formatting.
+ formatRange(r, args.style)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
new file mode 100644
index 0000000..de92257
--- /dev/null
+++ b/tools/clang-format/clang-format.py
@@ -0,0 +1,60 @@
+# This file is a minimal clang-format vim-integration. To install:
+# - Change 'binary' if clang-format is not on the path (see below).
+# - Add to your .vimrc:
+#
+# map <C-I> :pyf <path-to-this-file>/clang-format.py<CR>
+# imap <C-I> <ESC>:pyf <path-to-this-file>/clang-format.py<CR>i
+#
+# The first line enables clang-format for NORMAL and VISUAL mode, the second
+# line adds support for INSERT mode. Change "C-I" to another binding if you
+# need clang-format on a different key (C-I stands for Ctrl+i).
+#
+# With this integration you can press the bound key and clang-format will
+# format the current line in NORMAL and INSERT mode or the selected region in
+# VISUAL mode. The line or region is extended to the next bigger syntactic
+# entity.
+#
+# It operates on the current, potentially unsaved buffer and does not create
+# or save any files. To revert a formatting, just undo.
+
+import vim
+import subprocess
+
+# Change this to the full path if clang-format is not on the path.
+binary = 'clang-format'
+
+# Get the current text.
+buf = vim.current.buffer
+text = "\n".join(buf)
+
+# Determine range to format.
+offset = int(vim.eval('line2byte(' +
+ str(vim.current.range.start + 1) + ')')) - 1
+length = int(vim.eval('line2byte(' +
+ str(vim.current.range.end + 2) + ')')) - offset - 2
+
+# Call formatter.
+p = subprocess.Popen([binary, '-offset', str(offset), '-length', str(length)],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+stdout, stderr = p.communicate(input=text)
+
+# If successful, replace buffer contents.
+if stderr:
+ message = stderr.splitlines()[0]
+ parts = message.split(' ', 2)
+ if len(parts) > 2:
+ message = parts[2]
+ print 'Formatting failed: %s (total %d warnings, %d errors)' % (
+ message, stderr.count('warning:'), stderr.count('error:'))
+
+if not stdout:
+ print ('No output from clang-format (crashed?).\n' +
+ 'Please report to bugs.llvm.org.')
+elif stdout != text:
+ lines = stdout.split('\n')
+ for i in range(min(len(buf), len(lines))):
+ buf[i] = lines[i]
+ for line in lines[len(buf):]:
+ buf.append(line)
+ del buf[len(lines):]
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index a107cbd..8aa2d21 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
asmparser
+ bitreader
support
mc
)
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
index 36e72a2..c3428c9 100644
--- a/tools/diagtool/DiagTool.cpp
+++ b/tools/diagtool/DiagTool.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "DiagTool.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
#include <vector>
using namespace diagtool;
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
index dcb6ac7..93d531b 100644
--- a/tools/diagtool/DiagTool.h
+++ b/tools/diagtool/DiagTool.h
@@ -15,8 +15,8 @@
#define DIAGTOOL_DIAGTOOL_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
#include <string>
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index d554a2e..16837a1 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -14,11 +14,11 @@
#include "DiagTool.h"
#include "DiagnosticNames.h"
-#include "clang/Basic/Diagnostic.h"
-#include "llvm/Support/Format.h"
-#include "llvm/ADT/StringMap.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/Basic/AllDiagnostics.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Format.h"
DEF_DIAGTOOL("list-warnings",
"List warnings and their corresponding flags",
diff --git a/tools/diagtool/Makefile b/tools/diagtool/Makefile
index b629712..94f9c76 100644
--- a/tools/diagtool/Makefile
+++ b/tools/diagtool/Makefile
@@ -17,7 +17,7 @@ TOOL_NO_EXPORTS := 1
NO_INSTALL = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
clangSema.a clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
clangBasic.a
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index abd69fd..bcc7520 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -71,8 +71,7 @@ createDiagnostics(unsigned int argc, char **argv) {
// Build the diagnostics parser
IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
- CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts(),
- argc, argv);
+ CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts());
if (!FinalDiags)
return NULL;
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index bf9f766..6298179 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -13,13 +13,13 @@
#include "DiagTool.h"
#include "DiagnosticNames.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/AllDiagnostics.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
-#include "llvm/Support/Format.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "clang/AST/ASTDiagnostic.h"
-#include "clang/Basic/AllDiagnostics.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/Process.h"
DEF_DIAGTOOL("tree",
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 2545610..97ac7a4 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -3,6 +3,7 @@ set( LLVM_LINK_COMPONENTS
asmparser
bitreader
bitwriter
+ irreader
codegen
instrumentation
ipo
@@ -39,6 +40,7 @@ target_link_libraries(clang
)
set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION})
+set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
add_dependencies(clang clang-headers)
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index f07b0f2..cdf3b52 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -30,14 +30,24 @@ TOOL_INFO_PLIST := Info.plist
include $(CLANG_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
- instrumentation ipo linker selectiondag
+ instrumentation ipo irreader linker selectiondag
USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
- clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
- clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
- clangStaticAnalyzerCore.a \
- clangAnalysis.a clangARCMigrate.a \
- clangRewriteFrontend.a clangRewriteCore.a \
- clangEdit.a clangAST.a clangLex.a clangBasic.a
+ clangSerialization.a clangCodeGen.a clangParse.a clangSema.a
+
+ifeq ($(ENABLE_CLANG_STATIC_ANALYZER),1)
+USEDLIBS += clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
+ clangStaticAnalyzerCore.a
+endif
+
+ifeq ($(ENABLE_CLANG_ARCMT),1)
+USEDLIBS += clangARCMigrate.a
+endif
+
+ifeq ($(ENABLE_CLANG_REWRITER),1)
+USEDLIBS += clangRewriteFrontend.a clangRewriteCore.a
+endif
+
+USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangBasic.a clangLex.a
include $(CLANG_LEVEL)/Makefile
@@ -63,8 +73,3 @@ else
TOOL_INFO_BUILD_VERSION :=
endif
endif
-
-# Translate make variable to define when building a "production" clang.
-ifdef CLANG_IS_PRODUCTION
-CPP.Defines += -DCLANG_IS_PRODUCTION
-endif
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index f196856..35cf5b8 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -15,9 +15,9 @@
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
-#include "clang/Driver/Options.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -25,12 +25,13 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/FrontendTool/Utils.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/LinkAllPasses.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/LinkAllPasses.h"
#include <cstdio>
using namespace clang;
@@ -38,13 +39,20 @@ using namespace clang;
// Main driver
//===----------------------------------------------------------------------===//
-static void LLVMErrorHandler(void *UserData, const std::string &Message) {
+static void LLVMErrorHandler(void *UserData, const std::string &Message,
+ bool GenCrashDiag) {
DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
Diags.Report(diag::err_fe_error_backend) << Message;
- // We cannot recover from llvm errors.
- exit(1);
+ // Run the interrupt handlers to make sure any special cleanups get done, in
+ // particular that we remove files registered with RemoveFileOnSignal.
+ llvm::sys::RunInterruptHandlers();
+
+ // We cannot recover from llvm errors. When reporting a fatal error, exit
+ // with status 70 to generate crash diagnostics. For BSD systems this is
+ // defined as an internal software error. Otherwise, exit with status 1.
+ exit(GenCrashDiag ? 70 : 1);
}
int cc1_main(const char **ArgBegin, const char **ArgEnd,
@@ -74,7 +82,7 @@ int cc1_main(const char **ArgBegin, const char **ArgEnd,
CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
// Create the actual diagnostics engine.
- Clang->createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin));
+ Clang->createDiagnostics();
if (!Clang->hasDiagnostics())
return 1;
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 5587e40..232ea2f 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -13,45 +13,45 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
-#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/CC1AsOptions.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/OptTable.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Basic/DiagnosticOptions.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCParser/MCAsmParser.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"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.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/DataLayout.h"
using namespace clang;
using namespace clang::driver;
using namespace llvm;
@@ -83,6 +83,9 @@ struct AssemblerInvocation {
unsigned SaveTemporaryLabels : 1;
unsigned GenDwarfForAssembly : 1;
std::string DwarfDebugFlags;
+ std::string DwarfDebugProducer;
+ std::string DebugCompilationDir;
+ std::string MainFileName;
/// @}
/// @name Frontend Options
@@ -181,6 +184,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.SaveTemporaryLabels = Args->hasArg(OPT_L);
Opts.GenDwarfForAssembly = Args->hasArg(OPT_g);
Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags);
+ Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer);
+ Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir);
+ Opts.MainFileName = Args->getLastArgValue(OPT_main_file_name);
// Frontend Options
if (Args->hasArg(OPT_INPUT)) {
@@ -305,6 +311,12 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
Ctx.setGenDwarfForAssembly(true);
if (!Opts.DwarfDebugFlags.empty())
Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
+ if (!Opts.DwarfDebugProducer.empty())
+ Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
+ if (!Opts.DebugCompilationDir.empty())
+ Ctx.setCompilationDir(Opts.DebugCompilationDir);
+ if (!Opts.MainFileName.empty())
+ Ctx.setMainFileName(StringRef(Opts.MainFileName));
// Build up the feature string from the target feature list.
std::string FS;
@@ -372,7 +384,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
return Success;
}
-static void LLVMErrorHandler(void *UserData, const std::string &Message) {
+static void LLVMErrorHandler(void *UserData, const std::string &Message,
+ bool GenCrashDiag) {
DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData);
Diags.Report(diag::err_fe_error_backend) << Message;
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 81979ec..4c40da3 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -12,37 +12,37 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Driver/ArgList.h"
-#include "clang/Driver/Options.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
-#include "clang/Driver/Option.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
-
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Regex.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/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/Regex.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 <cctype>
using namespace clang;
using namespace clang::driver;
@@ -202,7 +202,7 @@ static void ExpandArgsFromBuf(const char *Arg,
std::string CurArg;
for (const char *P = Buf; ; ++P) {
- if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
+ if (*P == '\0' || (isWhitespace(*P) && InQuote == ' ')) {
if (!CurArg.empty()) {
if (CurArg[0] != '@') {
@@ -219,7 +219,7 @@ static void ExpandArgsFromBuf(const char *Arg,
continue;
}
- if (isspace(*P)) {
+ if (isWhitespace(*P)) {
if (InQuote != ' ')
CurArg.push_back(*P);
continue;
@@ -373,6 +373,32 @@ int main(int argc_, const char **argv_) {
}
}
+ // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
+ // command line behind the scenes.
+ if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
+ // FIXME: Driver shouldn't take extra initial argument.
+ ApplyQAOverride(argv, OverrideStr, SavedStrings);
+ } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
+ // FIXME: Driver shouldn't take extra initial argument.
+ std::vector<const char*> ExtraArgs;
+
+ for (;;) {
+ const char *Next = strchr(Cur, ',');
+
+ if (Next) {
+ ExtraArgs.push_back(SaveStringInSet(SavedStrings,
+ std::string(Cur, Next)));
+ Cur = Next + 1;
+ } else {
+ if (*Cur != '\0')
+ ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur));
+ break;
+ }
+ }
+
+ argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end());
+ }
+
llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes);
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
@@ -391,19 +417,14 @@ int main(int argc_, const char **argv_) {
// DiagnosticOptions instance.
TextDiagnosticPrinter *DiagClient
= new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
- DiagClient->setPrefix(llvm::sys::path::stem(Path.str()));
+ DiagClient->setPrefix(llvm::sys::path::filename(Path.str()));
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
- ProcessWarningOptions(Diags, *DiagOpts);
+ ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
-#ifdef CLANG_IS_PRODUCTION
- const bool IsProduction = true;
-#else
- const bool IsProduction = false;
-#endif
Driver TheDriver(Path.str(), llvm::sys::getDefaultTargetTriple(),
- "a.out", IsProduction, Diags);
+ "a.out", 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
@@ -443,46 +464,34 @@ int main(int argc_, const char **argv_) {
if (TheDriver.CCLogDiagnostics)
TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
- // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
- // command line behind the scenes.
- if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
- // FIXME: Driver shouldn't take extra initial argument.
- ApplyQAOverride(argv, OverrideStr, SavedStrings);
- } else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
- // FIXME: Driver shouldn't take extra initial argument.
- std::vector<const char*> ExtraArgs;
-
- for (;;) {
- const char *Next = strchr(Cur, ',');
-
- if (Next) {
- ExtraArgs.push_back(SaveStringInSet(SavedStrings,
- std::string(Cur, Next)));
- Cur = Next + 1;
- } else {
- if (*Cur != '\0')
- ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur));
- break;
- }
- }
-
- argv.insert(&argv[1], ExtraArgs.begin(), ExtraArgs.end());
- }
-
OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 0;
- const Command *FailingCommand = 0;
+ SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
if (C.get())
- Res = TheDriver.ExecuteCompilation(*C, FailingCommand);
+ Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
// Force a crash to test the diagnostics.
- if(::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"))
- Res = -1;
+ if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
+ Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
+ const Command *FailingCommand = 0;
+ FailingCommands.push_back(std::make_pair(-1, 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);
+ for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it =
+ FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) {
+ int CommandRes = it->first;
+ const Command *FailingCommand = it->second;
+ if (!Res)
+ Res = CommandRes;
+
+ // If result status is < 0, then the driver command signalled an error.
+ // If result status is 70, then the driver command reported a fatal error.
+ // In these cases, generate additional diagnostic information if possible.
+ if (CommandRes < 0 || CommandRes == 70) {
+ TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
+ break;
+ }
+ }
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
@@ -498,5 +507,7 @@ int main(int argc_, const char **argv_) {
Res = 1;
#endif
+ // If we have multiple failing commands, we return the result of the first
+ // failing command.
return Res;
}
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 5ee5cf6..3941794 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
-
#include "CXString.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
@@ -123,13 +122,11 @@ unsigned clang_remap_getNumFiles(CXRemapping map) {
void clang_remap_getFilenames(CXRemapping map, unsigned index,
CXString *original, CXString *transformed) {
if (original)
- *original = cxstring::createCXString(
- static_cast<Remap *>(map)->Vec[index].first,
- /*DupString =*/ true);
+ *original = cxstring::createDup(
+ static_cast<Remap *>(map)->Vec[index].first);
if (transformed)
- *transformed = cxstring::createCXString(
- static_cast<Remap *>(map)->Vec[index].second,
- /*DupString =*/ true);
+ *transformed = cxstring::createDup(
+ static_cast<Remap *>(map)->Vec[index].second);
}
void clang_remap_dispose(CXRemapping map) {
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 3a6c408..a81f1e4 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -13,56 +13,63 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
+#include "CIndexDiagnostic.h"
+#include "CLog.h"
#include "CXComment.h"
#include "CXCursor.h"
-#include "CXTranslationUnit.h"
+#include "CXSourceLocation.h"
#include "CXString.h"
+#include "CXTranslationUnit.h"
#include "CXType.h"
-#include "CXSourceLocation.h"
-#include "CIndexDiagnostic.h"
#include "CursorVisitor.h"
-
-#include "clang/Basic/Version.h"
-
+#include "SimpleFormatContext.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/Lexer.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Timer.h"
#include "llvm/Support/Mutex.h"
+#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Threading.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
using namespace clang;
using namespace clang::cxcursor;
-using namespace clang::cxstring;
using namespace clang::cxtu;
using namespace clang::cxindex;
-CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) {
- if (!TU)
+CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
+ if (!AU)
return 0;
CXTranslationUnit D = new CXTranslationUnitImpl();
D->CIdx = CIdx;
- D->TUData = TU;
- D->StringPool = createCXStringPool();
+ D->TheASTUnit = AU;
+ D->StringPool = new cxstring::CXStringPool();
D->Diagnostics = 0;
D->OverridenCursorsPool = createOverridenCXCursorsPool();
+ D->FormatContext = 0;
+ D->FormatInMemoryUniqueId = 0;
return D;
}
@@ -122,9 +129,11 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
EndLoc = EndLoc.getLocWithOffset(Length);
}
- CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
- R.getBegin().getRawEncoding(),
- EndLoc.getRawEncoding() };
+ CXSourceRange Result = {
+ { &SM, &LangOpts },
+ R.getBegin().getRawEncoding(),
+ EndLoc.getRawEncoding()
+ };
return Result;
}
@@ -155,7 +164,7 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
return false;
if (clang_isDeclaration(Cursor.kind)) {
- Decl *D = getCursorDecl(Cursor);
+ const Decl *D = getCursorDecl(Cursor);
if (!D) {
assert(0 && "Invalid declaration cursor");
return true; // abort.
@@ -214,11 +223,11 @@ static bool visitPreprocessedEntitiesInRange(SourceRange R,
PPRec, FID);
}
-void CursorVisitor::visitFileRegion() {
+bool CursorVisitor::visitFileRegion() {
if (RegionOfInterest.isInvalid())
- return;
+ return false;
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
std::pair<FileID, unsigned>
@@ -234,7 +243,7 @@ void CursorVisitor::visitFileRegion() {
assert(Begin.first == End.first);
if (Begin.second > End.second)
- return;
+ return false;
FileID File = Begin.first;
unsigned Offset = Begin.second;
@@ -242,12 +251,15 @@ void CursorVisitor::visitFileRegion() {
if (!VisitDeclsOnly && !VisitPreprocessorLast)
if (visitPreprocessedEntitiesInRegion())
- return; // visitation break.
+ return true; // visitation break.
- visitDeclsFromFileRegion(File, Offset, Length);
+ if (visitDeclsFromFileRegion(File, Offset, Length))
+ return true; // visitation break.
if (!VisitDeclsOnly && VisitPreprocessorLast)
- visitPreprocessedEntitiesInRegion();
+ return visitPreprocessedEntitiesInRegion();
+
+ return false;
}
static bool isInLexicalContext(Decl *D, DeclContext *DC) {
@@ -262,9 +274,9 @@ static bool isInLexicalContext(Decl *D, DeclContext *DC) {
return false;
}
-void CursorVisitor::visitDeclsFromFileRegion(FileID File,
+bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
unsigned Offset, unsigned Length) {
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
SourceRange Range = RegionOfInterest;
@@ -277,7 +289,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
bool Invalid = false;
const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
if (Invalid)
- return;
+ return false;
SourceLocation Outer;
if (SLEntry.isFile())
@@ -285,7 +297,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
else
Outer = SLEntry.getExpansion().getExpansionLocStart();
if (Outer.isInvalid())
- return;
+ return false;
llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Length = 0;
@@ -328,11 +340,11 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
}
if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
- break;
+ return true; // visitation break.
}
if (VisitedAtLeastOnce)
- return;
+ return false;
// No Decls overlapped with the range. Move up the lexical context until there
// is a context that contains the range or we reach the translation unit
@@ -347,12 +359,14 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
break;
if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
- Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true);
- break;
+ if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
+ return true; // visitation break.
}
DC = D->getLexicalDeclContext();
}
+
+ return false;
}
bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
@@ -453,7 +467,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
SetParentRAII SetParent(Parent, StmtParent, Cursor);
if (clang_isDeclaration(Cursor.kind)) {
- Decl *D = getCursorDecl(Cursor);
+ Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
if (!D)
return false;
@@ -461,22 +475,22 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (clang_isStatement(Cursor.kind)) {
- if (Stmt *S = getCursorStmt(Cursor))
+ if (const Stmt *S = getCursorStmt(Cursor))
return Visit(S);
return false;
}
if (clang_isExpression(Cursor.kind)) {
- if (Expr *E = getCursorExpr(Cursor))
+ if (const Expr *E = getCursorExpr(Cursor))
return Visit(E);
return false;
}
if (clang_isTranslationUnit(Cursor.kind)) {
- CXTranslationUnit tu = getCursorTU(Cursor);
- ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
+ CXTranslationUnit TU = getCursorTU(Cursor);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
for (unsigned I = 0; I != 2; ++I) {
@@ -486,7 +500,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, RegionOfInterest), true))
+ if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
return true;
}
} else if (VisitDeclContext(
@@ -504,7 +518,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
- if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
+ if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
return Visit(BaseTSInfo->getTypeLoc());
}
@@ -512,13 +526,27 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
- IBOutletCollectionAttr *A =
+ const IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
A->getInterfaceLoc(), TU));
}
+ // If pointing inside a macro definition, check if the token is an identifier
+ // that was ever defined as a macro. In such a case, create a "pseudo" macro
+ // expansion cursor for that token.
+ SourceLocation BeginLoc = RegionOfInterest.getBegin();
+ if (Cursor.kind == CXCursor_MacroDefinition &&
+ BeginLoc == RegionOfInterest.getEnd()) {
+ SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
+ const MacroInfo *MI =
+ getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
+ if (MacroDefinition *MacroDef =
+ checkForMacroInMacroDefinition(MI, Loc, TU))
+ return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
+ }
+
// Nothing to visit at the moment.
return false;
}
@@ -534,16 +562,16 @@ bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
return false;
}
-llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
+Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
if (RegionOfInterest.isValid()) {
SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
if (Range.isInvalid())
- return llvm::Optional<bool>();
+ return None;
switch (CompareRegionOfInterest(Range)) {
case RangeBefore:
// This declaration comes before the region of interest; skip it.
- return llvm::Optional<bool>();
+ return None;
case RangeAfter:
// This declaration comes after the region of interest; we're done.
@@ -594,7 +622,7 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
}
- const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+ const Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
if (!V.getValue())
@@ -648,10 +676,10 @@ bool CursorVisitor::VisitClassTemplateSpecializationDecl(
// Visit the template arguments used in the specialization.
if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
TypeLoc TL = SpecType->getTypeLoc();
- if (TemplateSpecializationTypeLoc *TSTLoc
- = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
- for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
- if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
+ if (TemplateSpecializationTypeLoc TSTLoc =
+ TL.getAs<TemplateSpecializationTypeLoc>()) {
+ for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
+ if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
return true;
}
}
@@ -727,12 +755,12 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// Visit the function declaration's syntactic components in the order
// written. This requires a bit of work.
TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
- FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
+ FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
// If we have a function declared directly (without the use of a typedef),
// visit just the return type. Otherwise, just visit the function's type
// now.
- if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
+ if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
(!FTL && Visit(TL)))
return true;
@@ -748,7 +776,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// FIXME: Visit explicitly-specified template arguments!
// Visit the function parameters, if we have a function type.
- if (FTL && VisitFunctionTypeLoc(*FTL, true))
+ if (FTL && VisitFunctionTypeLoc(FTL, true))
return true;
// FIXME: Attributes?
@@ -958,7 +986,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
E = DeclsInContainer.end(); I != E; ++I) {
CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
- const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+ const Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
if (!V.getValue())
@@ -1369,6 +1397,14 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
case BuiltinType::Void:
case BuiltinType::NullPtr:
case BuiltinType::Dependent:
+ case BuiltinType::OCLImage1d:
+ case BuiltinType::OCLImage1dArray:
+ case BuiltinType::OCLImage1dBuffer:
+ case BuiltinType::OCLImage2d:
+ case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage3d:
+ case BuiltinType::OCLSampler:
+ case BuiltinType::OCLEvent:
#define BUILTIN_TYPE(Id, SingletonId)
#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
@@ -1629,9 +1665,10 @@ namespace {
#define DEF_JOB(NAME, DATA, KIND)\
class NAME : public VisitorJob {\
public:\
- NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
+ NAME(const DATA *d, CXCursor parent) : \
+ VisitorJob(parent, VisitorJob::KIND, d) {} \
static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
- DATA *get() const { return static_cast<DATA*>(data[0]); }\
+ const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
};
DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
@@ -1647,13 +1684,13 @@ DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
class DeclVisit : public VisitorJob {
public:
- DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
+ DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
VisitorJob(parent, VisitorJob::DeclVisitKind,
- d, isFirst ? (void*) 1 : (void*) 0) {}
+ D, isFirst ? (void*) 1 : (void*) 0) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == DeclVisitKind;
}
- Decl *get() const { return static_cast<Decl*>(data[0]); }
+ const Decl *get() const { return static_cast<const Decl *>(data[0]); }
bool isFirst() const { return data[1] ? true : false; }
};
class TypeLocVisit : public VisitorJob {
@@ -1668,7 +1705,7 @@ public:
TypeLoc get() const {
QualType T = QualType::getFromOpaquePtr(data[0]);
- return TypeLoc(T, data[1]);
+ return TypeLoc(T, const_cast<void *>(data[1]));
}
};
@@ -1681,7 +1718,9 @@ public:
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::LabelRefVisitKind;
}
- LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
+ const LabelDecl *get() const {
+ return static_cast<const LabelDecl *>(data[0]);
+ }
SourceLocation getLoc() const {
return SourceLocation::getFromPtrEncoding(data[1]); }
};
@@ -1698,20 +1737,22 @@ public:
}
NestedNameSpecifierLoc get() const {
- return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
- data[1]);
+ return NestedNameSpecifierLoc(
+ const_cast<NestedNameSpecifier *>(
+ static_cast<const NestedNameSpecifier *>(data[0])),
+ const_cast<void *>(data[1]));
}
};
class DeclarationNameInfoVisit : public VisitorJob {
public:
- DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
+ DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
: VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
}
DeclarationNameInfo get() const {
- Stmt *S = static_cast<Stmt*>(data[0]);
+ const Stmt *S = static_cast<const Stmt *>(data[0]);
switch (S->getStmtClass()) {
default:
llvm_unreachable("Unhandled Stmt");
@@ -1726,85 +1767,85 @@ public:
};
class MemberRefVisit : public VisitorJob {
public:
- MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
+ MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
: VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
L.getPtrEncoding()) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::MemberRefVisitKind;
}
- FieldDecl *get() const {
- return static_cast<FieldDecl*>(data[0]);
+ const FieldDecl *get() const {
+ return static_cast<const FieldDecl *>(data[0]);
}
SourceLocation getLoc() const {
return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
}
};
-class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
+class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
VisitorWorkList &WL;
CXCursor Parent;
public:
EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
: WL(wl), Parent(parent) {}
- void VisitAddrLabelExpr(AddrLabelExpr *E);
- void VisitBlockExpr(BlockExpr *B);
- void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
- void VisitCompoundStmt(CompoundStmt *S);
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
- void VisitMSDependentExistsStmt(MSDependentExistsStmt *S);
- void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
- void VisitCXXNewExpr(CXXNewExpr *E);
- void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
- void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
- void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
- void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
- void VisitCXXTypeidExpr(CXXTypeidExpr *E);
- void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
- void VisitCXXUuidofExpr(CXXUuidofExpr *E);
- void VisitCXXCatchStmt(CXXCatchStmt *S);
- void VisitDeclRefExpr(DeclRefExpr *D);
- void VisitDeclStmt(DeclStmt *S);
- void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
- void VisitDesignatedInitExpr(DesignatedInitExpr *E);
- void VisitExplicitCastExpr(ExplicitCastExpr *E);
- void VisitForStmt(ForStmt *FS);
- void VisitGotoStmt(GotoStmt *GS);
- void VisitIfStmt(IfStmt *If);
- void VisitInitListExpr(InitListExpr *IE);
- void VisitMemberExpr(MemberExpr *M);
- void VisitOffsetOfExpr(OffsetOfExpr *E);
- void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
- void VisitObjCMessageExpr(ObjCMessageExpr *M);
- void VisitOverloadExpr(OverloadExpr *E);
- void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
- void VisitStmt(Stmt *S);
- void VisitSwitchStmt(SwitchStmt *S);
- void VisitWhileStmt(WhileStmt *W);
- void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
- void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
- void VisitTypeTraitExpr(TypeTraitExpr *E);
- void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
- void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
- void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
- void VisitVAArgExpr(VAArgExpr *E);
- void VisitSizeOfPackExpr(SizeOfPackExpr *E);
- void VisitPseudoObjectExpr(PseudoObjectExpr *E);
- void VisitOpaqueValueExpr(OpaqueValueExpr *E);
- void VisitLambdaExpr(LambdaExpr *E);
-
+ void VisitAddrLabelExpr(const AddrLabelExpr *E);
+ void VisitBlockExpr(const BlockExpr *B);
+ void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
+ void VisitCompoundStmt(const CompoundStmt *S);
+ void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
+ void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
+ void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
+ void VisitCXXNewExpr(const CXXNewExpr *E);
+ void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+ void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
+ void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
+ void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
+ void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
+ void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
+ void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
+ void VisitCXXCatchStmt(const CXXCatchStmt *S);
+ void VisitDeclRefExpr(const DeclRefExpr *D);
+ void VisitDeclStmt(const DeclStmt *S);
+ void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
+ void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
+ void VisitExplicitCastExpr(const ExplicitCastExpr *E);
+ void VisitForStmt(const ForStmt *FS);
+ void VisitGotoStmt(const GotoStmt *GS);
+ void VisitIfStmt(const IfStmt *If);
+ void VisitInitListExpr(const InitListExpr *IE);
+ void VisitMemberExpr(const MemberExpr *M);
+ void VisitOffsetOfExpr(const OffsetOfExpr *E);
+ void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
+ void VisitObjCMessageExpr(const ObjCMessageExpr *M);
+ void VisitOverloadExpr(const OverloadExpr *E);
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
+ void VisitStmt(const Stmt *S);
+ void VisitSwitchStmt(const SwitchStmt *S);
+ void VisitWhileStmt(const WhileStmt *W);
+ void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
+ void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
+ void VisitTypeTraitExpr(const TypeTraitExpr *E);
+ void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
+ void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
+ void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
+ void VisitVAArgExpr(const VAArgExpr *E);
+ void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
+ void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
+ void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
+ void VisitLambdaExpr(const LambdaExpr *E);
+
private:
- void AddDeclarationNameInfo(Stmt *S);
+ void AddDeclarationNameInfo(const Stmt *S);
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
- void AddMemberRef(FieldDecl *D, SourceLocation L);
- void AddStmt(Stmt *S);
- void AddDecl(Decl *D, bool isFirst = true);
+ void AddMemberRef(const FieldDecl *D, SourceLocation L);
+ void AddStmt(const Stmt *S);
+ void AddDecl(const Decl *D, bool isFirst = true);
void AddTypeLoc(TypeSourceInfo *TI);
- void EnqueueChildren(Stmt *S);
+ void EnqueueChildren(const Stmt *S);
};
} // end anonyous namespace
-void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
+void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
// 'S' should always be non-null, since it comes from the
// statement we are visiting.
WL.push_back(DeclarationNameInfoVisit(S, Parent));
@@ -1816,21 +1857,20 @@ EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
}
-void EnqueueVisitor::AddStmt(Stmt *S) {
+void EnqueueVisitor::AddStmt(const Stmt *S) {
if (S)
WL.push_back(StmtVisit(S, Parent));
}
-void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
+void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
if (D)
WL.push_back(DeclVisit(D, Parent, isFirst));
}
void EnqueueVisitor::
AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
if (A)
- WL.push_back(ExplicitTemplateArgsVisit(
- const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
+ WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
}
-void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
+void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
if (D)
WL.push_back(MemberRefVisit(D, L, Parent));
}
@@ -1838,9 +1878,9 @@ void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
if (TI)
WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
}
-void EnqueueVisitor::EnqueueChildren(Stmt *S) {
+void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
unsigned size = WL.size();
- for (Stmt::child_range Child = S->children(); Child; ++Child) {
+ for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
AddStmt(*Child);
}
if (size == WL.size())
@@ -1850,24 +1890,24 @@ void EnqueueVisitor::EnqueueChildren(Stmt *S) {
VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
std::reverse(I, E);
}
-void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
+void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
}
-void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
+void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
AddDecl(B->getBlockDecl());
}
-void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
- for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
+void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
+ for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
E = S->body_rend(); I != E; ++I) {
AddStmt(*I);
}
}
void EnqueueVisitor::
-VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
+VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
AddStmt(S->getSubStmt());
AddDeclarationNameInfo(S);
if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
@@ -1875,7 +1915,7 @@ VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
}
void EnqueueVisitor::
-VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
AddDeclarationNameInfo(E);
if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
@@ -1883,7 +1923,7 @@ VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
if (!E->isImplicitAccess())
AddStmt(E->getBase());
}
-void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
+void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
// Enqueue the initializer , if any.
AddStmt(E->getInitializer());
// Enqueue the array size, if any.
@@ -1894,13 +1934,14 @@ void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
AddStmt(E->getPlacementArg(I-1));
}
-void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
+void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
AddStmt(CE->getArg(I-1));
AddStmt(CE->getCallee());
AddStmt(CE->getArg(0));
}
-void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
+ const CXXPseudoDestructorExpr *E) {
// Visit the name of the type being destroyed.
AddTypeLoc(E->getDestroyedTypeInfo());
// Visit the scope type that looks disturbingly like the nested-name-specifier
@@ -1912,50 +1953,53 @@ void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
// Visit base expression.
AddStmt(E->getBase());
}
-void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+void EnqueueVisitor::VisitCXXScalarValueInitExpr(
+ const CXXScalarValueInitExpr *E) {
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
+ const CXXTemporaryObjectExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
EnqueueChildren(E);
if (E->isTypeOperand())
AddTypeLoc(E->getTypeOperandSourceInfo());
}
-void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
- *E) {
+void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
+ const CXXUnresolvedConstructExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
+void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
EnqueueChildren(E);
if (E->isTypeOperand())
AddTypeLoc(E->getTypeOperandSourceInfo());
}
-void EnqueueVisitor::VisitCXXCatchStmt(CXXCatchStmt *S) {
+void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
EnqueueChildren(S);
AddDecl(S->getExceptionDecl());
}
-void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
+void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
if (DR->hasExplicitTemplateArgs()) {
AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
}
WL.push_back(DeclRefExprParts(DR, Parent));
}
-void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
+ const DependentScopeDeclRefExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
AddDeclarationNameInfo(E);
AddNestedNameSpecifierLoc(E->getQualifierLoc());
}
-void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
+void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
unsigned size = WL.size();
bool isFirst = true;
- for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+ for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
D != DEnd; ++D) {
AddDecl(*D, isFirst);
isFirst = false;
@@ -1967,10 +2011,10 @@ void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
std::reverse(I, E);
}
-void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
AddStmt(E->getInit());
typedef DesignatedInitExpr::Designator Designator;
- for (DesignatedInitExpr::reverse_designators_iterator
+ for (DesignatedInitExpr::const_reverse_designators_iterator
D = E->designators_rbegin(), DEnd = E->designators_rend();
D != DEnd; ++D) {
if (D->isFieldDesignator()) {
@@ -1987,33 +2031,33 @@ void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
AddStmt(E->getArrayRangeStart(*D));
}
}
-void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeInfoAsWritten());
}
-void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
+void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
AddStmt(FS->getBody());
AddStmt(FS->getInc());
AddStmt(FS->getCond());
AddDecl(FS->getConditionVariable());
AddStmt(FS->getInit());
}
-void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
+void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
}
-void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
+void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
AddStmt(If->getElse());
AddStmt(If->getThen());
AddStmt(If->getCond());
AddDecl(If->getConditionVariable());
}
-void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
+void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
// We care about the syntactic form of the initializer list, only.
if (InitListExpr *Syntactic = IE->getSyntacticForm())
IE = Syntactic;
EnqueueChildren(IE);
}
-void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
+void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
WL.push_back(MemberExprParts(M, Parent));
// If the base of the member access expression is an implicit 'this', don't
@@ -2023,14 +2067,14 @@ void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
if (!M->isImplicitAccess())
AddStmt(M->getBase());
}
-void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
AddTypeLoc(E->getEncodedTypeSourceInfo());
}
-void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
+void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
EnqueueChildren(M);
AddTypeLoc(M->getClassReceiverTypeInfo());
}
-void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
+void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
// Visit the components of the offsetof expression.
for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
@@ -2050,81 +2094,81 @@ void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
// Visit the type into which we're computing the offset.
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
+void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
WL.push_back(OverloadExprParts(E, Parent));
}
void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
- UnaryExprOrTypeTraitExpr *E) {
+ const UnaryExprOrTypeTraitExpr *E) {
EnqueueChildren(E);
if (E->isArgumentType())
AddTypeLoc(E->getArgumentTypeInfo());
}
-void EnqueueVisitor::VisitStmt(Stmt *S) {
+void EnqueueVisitor::VisitStmt(const Stmt *S) {
EnqueueChildren(S);
}
-void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
+void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
AddStmt(S->getBody());
AddStmt(S->getCond());
AddDecl(S->getConditionVariable());
}
-void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
+void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
AddStmt(W->getBody());
AddStmt(W->getCond());
AddDecl(W->getConditionVariable());
}
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
AddTypeLoc(E->getQueriedTypeSourceInfo());
}
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
+void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
AddTypeLoc(E->getRhsTypeSourceInfo());
AddTypeLoc(E->getLhsTypeSourceInfo());
}
-void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) {
+void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
for (unsigned I = E->getNumArgs(); I > 0; --I)
AddTypeLoc(E->getArg(I-1));
}
-void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
AddTypeLoc(E->getQueriedTypeSourceInfo());
}
-void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
EnqueueChildren(E);
}
-void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
+void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
VisitOverloadExpr(U);
if (!U->isImplicitAccess())
AddStmt(U->getBase());
}
-void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
+void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
AddStmt(E->getSubExpr());
AddTypeLoc(E->getWrittenTypeInfo());
}
-void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
+void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
WL.push_back(SizeOfPackExprParts(E, Parent));
}
-void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
+void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
// If the opaque value has a source expression, just transparently
// visit that. This is useful for (e.g.) pseudo-object expressions.
if (Expr *SourceExpr = E->getSourceExpr())
return Visit(SourceExpr);
}
-void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) {
+void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
AddStmt(E->getBody());
WL.push_back(LambdaExprParts(E, Parent));
}
-void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
// Treat the expression like its syntactic form.
Visit(E->getSyntacticForm());
}
-void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
+void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2148,7 +2192,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
switch (LI.getKind()) {
case VisitorJob::DeclVisitKind: {
- Decl *D = cast<DeclVisit>(&LI)->get();
+ const Decl *D = cast<DeclVisit>(&LI)->get();
if (!D)
continue;
@@ -2177,7 +2221,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::LabelRefVisitKind: {
- LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
+ const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
if (LabelStmt *stmt = LS->getStmt()) {
if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
TU))) {
@@ -2207,7 +2251,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::StmtVisitKind: {
- Stmt *S = cast<StmtVisit>(&LI)->get();
+ const Stmt *S = cast<StmtVisit>(&LI)->get();
if (!S)
continue;
@@ -2228,7 +2272,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
}
case VisitorJob::MemberExprPartsKind: {
// Handle the other pieces in the MemberExpr besides the base.
- MemberExpr *M = cast<MemberExprParts>(&LI)->get();
+ const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
// Visit the nested-name-specifier
if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
@@ -2251,7 +2295,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::DeclRefExprPartsKind: {
- DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
+ const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
// Visit nested-name-specifier, if present.
if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -2262,7 +2306,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::OverloadExprPartsKind: {
- OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
+ const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
// Visit the nested-name-specifier.
if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -2276,7 +2320,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::SizeOfPackExprPartsKind: {
- SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
+ const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
NamedDecl *Pack = E->getPack();
if (isa<TemplateTypeParmDecl>(Pack)) {
if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
@@ -2301,7 +2345,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
case VisitorJob::LambdaExprPartsKind: {
// Visit captures.
- LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
+ const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
CEnd = E->explicit_capture_end();
C != CEnd; ++C) {
@@ -2321,8 +2365,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
// Visit the whole type.
if (Visit(TL))
return true;
- } else if (isa<FunctionProtoTypeLoc>(TL)) {
- FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ } else if (FunctionProtoTypeLoc Proto =
+ TL.getAs<FunctionProtoTypeLoc>()) {
if (E->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
@@ -2347,7 +2391,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
return false;
}
-bool CursorVisitor::Visit(Stmt *S) {
+bool CursorVisitor::Visit(const Stmt *S) {
VisitorWorkList *WL = 0;
if (!WorkListFreeList.empty()) {
WL = WorkListFreeList.back();
@@ -2365,7 +2409,7 @@ bool CursorVisitor::Visit(Stmt *S) {
}
namespace {
-typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
+typedef SmallVector<SourceRange, 4> RefNamePieces;
RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
const DeclarationNameInfo &NI,
const SourceRange &QLoc,
@@ -2412,7 +2456,8 @@ RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
static llvm::sys::Mutex EnableMultithreadingMutex;
static bool EnabledMultithreading;
-static void fatal_error_handler(void *user_data, const std::string& reason) {
+static void fatal_error_handler(void *user_data, const std::string& reason,
+ bool gen_crash_diag) {
// Write the result out to stderr avoiding errs() because raw_ostreams can
// call report_fatal_error.
fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
@@ -2486,7 +2531,6 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
FileSystemOptions FileSystemOpts;
- FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
@@ -2560,9 +2604,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
- Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
- num_command_line_args,
- command_line_args));
+ Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
@@ -2662,6 +2704,12 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << source_filename << ": ";
+ for (int i = 0; i != num_command_line_args; ++i)
+ *Log << command_line_args[i] << " ";
+ }
+
ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
num_command_line_args, unsaved_files,
num_unsaved_files, options, 0 };
@@ -2715,20 +2763,24 @@ static void clang_saveTranslationUnit_Impl(void *UserData) {
SaveTranslationUnitInfo *STUI =
static_cast<SaveTranslationUnitInfo*>(UserData);
- CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx;
+ CIndexer *CXXIdx = STUI->TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
- bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
+ bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
}
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ' << FileName;
+ }
+
if (!TU)
return CXSaveError_InvalidTU;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
if (!CXXUnit->hasSema())
return CXSaveError_InvalidTU;
@@ -2769,13 +2821,14 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
if (CTUnit) {
// If the translation unit has been marked as unsafe to free, just discard
// it.
- if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
+ if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
return;
- delete static_cast<ASTUnit *>(CTUnit->TUData);
- disposeCXStringPool(CTUnit->StringPool);
+ delete cxtu::getASTUnit(CTUnit);
+ delete CTUnit->StringPool;
delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
+ delete CTUnit->FormatContext;
delete CTUnit;
}
}
@@ -2796,6 +2849,8 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
ReparseTranslationUnitInfo *RTUI =
static_cast<ReparseTranslationUnitInfo*>(UserData);
CXTranslationUnit TU = RTUI->TU;
+ if (!TU)
+ return;
// Reset the associated diagnostics.
delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
@@ -2807,14 +2862,11 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
(void) options;
RTUI->result = 1;
- if (!TU)
- return;
-
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
OwningPtr<std::vector<ASTUnit::RemappedFile> >
@@ -2841,6 +2893,10 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
unsigned num_unsaved_files,
struct CXUnsavedFile *unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU;
+ }
+
ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
options, 0 };
@@ -2853,7 +2909,7 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
fprintf(stderr, "libclang: crash detected during reparsing\n");
- static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+ cxtu::getASTUnit(TU)->setUnsafeToFree(true);
return 1;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -2864,14 +2920,17 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
if (!CTUnit)
- return createCXString("");
+ return cxstring::createEmpty();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
- return createCXString(CXXUnit->getOriginalSourceFileName(), true);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
+ return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- ASTUnit *CXXUnit = static_cast<ASTUnit*>(TU->TUData);
+ if (!TU)
+ return clang_getNullCursor();
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
}
@@ -2884,10 +2943,10 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
extern "C" {
CXString clang_getFileName(CXFile SFile) {
if (!SFile)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
FileEntry *FEnt = static_cast<FileEntry *>(SFile);
- return createCXString(FEnt->getName());
+ return cxstring::createRef(FEnt->getName());
}
time_t clang_getFileTime(CXFile SFile) {
@@ -2898,43 +2957,58 @@ time_t clang_getFileTime(CXFile SFile) {
return FEnt->getModificationTime();
}
-CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
- if (!tu)
+CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
+ if (!TU)
return 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
FileManager &FMgr = CXXUnit->getFileManager();
return const_cast<FileEntry *>(FMgr.getFile(file_name));
}
-unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
- if (!tu || !file)
+unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
+ if (!TU || !file)
return 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
FileEntry *FEnt = static_cast<FileEntry *>(file);
return CXXUnit->getPreprocessor().getHeaderSearchInfo()
.isFileMultipleIncludeGuarded(FEnt);
}
+int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
+ if (!file || !outID)
+ return 1;
+
+#ifdef LLVM_ON_WIN32
+ return 1; // inodes not supported on windows.
+#else
+ FileEntry *FEnt = static_cast<FileEntry *>(file);
+ outID->data[0] = FEnt->getDevice();
+ outID->data[1] = FEnt->getInode();
+ outID->data[2] = FEnt->getModificationTime();
+ return 0;
+#endif
+}
+
} // end: extern "C"
//===----------------------------------------------------------------------===//
// CXCursor Operations.
//===----------------------------------------------------------------------===//
-static Decl *getDeclFromExpr(Stmt *E) {
- if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+static const Decl *getDeclFromExpr(const Stmt *E) {
+ if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getDeclFromExpr(CE->getSubExpr());
- if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+ if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
return RefExpr->getDecl();
- if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
return ME->getMemberDecl();
- if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+ if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
return RE->getDecl();
- if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+ if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
if (PRE->isExplicitProperty())
return PRE->getExplicitProperty();
// It could be messaging both getter and setter as in:
@@ -2945,26 +3019,26 @@ static Decl *getDeclFromExpr(Stmt *E) {
return PRE->getImplicitPropertySetter();
return PRE->getImplicitPropertyGetter();
}
- if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
+ if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
return getDeclFromExpr(POE->getSyntacticForm());
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
+ if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
if (Expr *Src = OVE->getSourceExpr())
return getDeclFromExpr(Src);
- if (CallExpr *CE = dyn_cast<CallExpr>(E))
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E))
return getDeclFromExpr(CE->getCallee());
- if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
+ if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
if (!CE->isElidable())
return CE->getConstructor();
- if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
+ if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
return OME->getMethodDecl();
- if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
+ if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
return PE->getProtocol();
- if (SubstNonTypeTemplateParmPackExpr *NTTP
+ if (const SubstNonTypeTemplateParmPackExpr *NTTP
= dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
return NTTP->getParameterPack();
- if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+ if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
isa<ParmVarDecl>(SizeOfPack->getPack()))
return SizeOfPack->getPack();
@@ -2972,21 +3046,21 @@ static Decl *getDeclFromExpr(Stmt *E) {
return 0;
}
-static SourceLocation getLocationFromExpr(Expr *E) {
- if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+static SourceLocation getLocationFromExpr(const Expr *E) {
+ if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getLocationFromExpr(CE->getSubExpr());
- if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
+ if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
return /*FIXME:*/Msg->getLeftLoc();
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
return DRE->getLocation();
- if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
+ if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
return Member->getMemberLoc();
- if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
+ if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
return Ivar->getLocation();
- if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+ if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
return SizeOfPack->getPackLoc();
- if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
+ if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
return PropRef->getLocation();
return E->getLocStart();
@@ -3039,169 +3113,169 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent,
return clang_visitChildren(parent, visitWithBlock, block);
}
-static CXString getDeclSpelling(Decl *D) {
+static CXString getDeclSpelling(const Decl *D) {
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
- NamedDecl *ND = dyn_cast<NamedDecl>(D);
+ const NamedDecl *ND = dyn_cast<NamedDecl>(D);
if (!ND) {
- if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+ if (const ObjCPropertyImplDecl *PropImpl =
+ dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
- return createCXString(Property->getIdentifier()->getName());
+ return cxstring::createDup(Property->getIdentifier()->getName());
- if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
+ if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
if (Module *Mod = ImportD->getImportedModule())
- return createCXString(Mod->getFullModuleName());
+ return cxstring::createDup(Mod->getFullModuleName());
- return createCXString("");
+ return cxstring::createEmpty();
}
- if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
- return createCXString(OMD->getSelector().getAsString());
+ if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
+ return cxstring::createDup(OMD->getSelector().getAsString());
- if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
+ if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
// No, this isn't the same as the code below. getIdentifier() is non-virtual
// and returns different names. NamedDecl returns the class name and
// ObjCCategoryImplDecl returns the category name.
- return createCXString(CIMP->getIdentifier()->getNameStart());
+ return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
if (isa<UsingDirectiveDecl>(D))
- return createCXString("");
+ return cxstring::createEmpty();
SmallString<1024> S;
llvm::raw_svector_ostream os(S);
ND->printName(os);
- return createCXString(os.str());
+ return cxstring::createDup(os.str());
}
CXString clang_getCursorSpelling(CXCursor C) {
if (clang_isTranslationUnit(C.kind))
- return clang_getTranslationUnitSpelling(
- static_cast<CXTranslationUnit>(C.data[2]));
+ return clang_getTranslationUnitSpelling(getCursorTU(C));
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef: {
- ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
- return createCXString(Super->getIdentifier()->getNameStart());
+ const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
+ return cxstring::createRef(Super->getIdentifier()->getNameStart());
}
case CXCursor_ObjCClassRef: {
- ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
- return createCXString(Class->getIdentifier()->getNameStart());
+ const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+ return cxstring::createRef(Class->getIdentifier()->getNameStart());
}
case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
+ const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
assert(OID && "getCursorSpelling(): Missing protocol decl");
- return createCXString(OID->getIdentifier()->getNameStart());
+ return cxstring::createRef(OID->getIdentifier()->getNameStart());
}
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
- return createCXString(B->getType().getAsString());
+ const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+ return cxstring::createDup(B->getType().getAsString());
}
case CXCursor_TypeRef: {
- TypeDecl *Type = getCursorTypeRef(C).first;
+ const TypeDecl *Type = getCursorTypeRef(C).first;
assert(Type && "Missing type decl");
- return createCXString(getCursorContext(C).getTypeDeclType(Type).
+ return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
getAsString());
}
case CXCursor_TemplateRef: {
- TemplateDecl *Template = getCursorTemplateRef(C).first;
+ const TemplateDecl *Template = getCursorTemplateRef(C).first;
assert(Template && "Missing template decl");
- return createCXString(Template->getNameAsString());
+ return cxstring::createDup(Template->getNameAsString());
}
case CXCursor_NamespaceRef: {
- NamedDecl *NS = getCursorNamespaceRef(C).first;
+ const NamedDecl *NS = getCursorNamespaceRef(C).first;
assert(NS && "Missing namespace decl");
- return createCXString(NS->getNameAsString());
+ return cxstring::createDup(NS->getNameAsString());
}
case CXCursor_MemberRef: {
- FieldDecl *Field = getCursorMemberRef(C).first;
+ const FieldDecl *Field = getCursorMemberRef(C).first;
assert(Field && "Missing member decl");
- return createCXString(Field->getNameAsString());
+ return cxstring::createDup(Field->getNameAsString());
}
case CXCursor_LabelRef: {
- LabelStmt *Label = getCursorLabelRef(C).first;
+ const LabelStmt *Label = getCursorLabelRef(C).first;
assert(Label && "Missing label");
- return createCXString(Label->getName());
+ return cxstring::createRef(Label->getName());
}
case CXCursor_OverloadedDeclRef: {
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
- if (Decl *D = Storage.dyn_cast<Decl *>()) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- return createCXString(ND->getNameAsString());
- return createCXString("");
+ if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ return cxstring::createDup(ND->getNameAsString());
+ return cxstring::createEmpty();
}
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
- return createCXString(E->getName().getAsString());
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
+ return cxstring::createDup(E->getName().getAsString());
OverloadedTemplateStorage *Ovl
= Storage.get<OverloadedTemplateStorage*>();
if (Ovl->size() == 0)
- return createCXString("");
- return createCXString((*Ovl->begin())->getNameAsString());
+ return cxstring::createEmpty();
+ return cxstring::createDup((*Ovl->begin())->getNameAsString());
}
case CXCursor_VariableRef: {
- VarDecl *Var = getCursorVariableRef(C).first;
+ const VarDecl *Var = getCursorVariableRef(C).first;
assert(Var && "Missing variable decl");
- return createCXString(Var->getNameAsString());
+ return cxstring::createDup(Var->getNameAsString());
}
default:
- return createCXString("<not implemented>");
+ return cxstring::createRef("<not implemented>");
}
}
if (clang_isExpression(C.kind)) {
- Decl *D = getDeclFromExpr(getCursorExpr(C));
+ const Decl *D = getDeclFromExpr(getCursorExpr(C));
if (D)
return getDeclSpelling(D);
- return createCXString("");
+ return cxstring::createEmpty();
}
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
- return createCXString(Label->getName());
+ const Stmt *S = getCursorStmt(C);
+ if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
+ return cxstring::createRef(Label->getName());
- return createCXString("");
+ return cxstring::createEmpty();
}
if (C.kind == CXCursor_MacroExpansion)
- return createCXString(getCursorMacroExpansion(C)->getName()
+ return cxstring::createRef(getCursorMacroExpansion(C).getName()
->getNameStart());
if (C.kind == CXCursor_MacroDefinition)
- return createCXString(getCursorMacroDefinition(C)->getName()
+ return cxstring::createRef(getCursorMacroDefinition(C)->getName()
->getNameStart());
if (C.kind == CXCursor_InclusionDirective)
- return createCXString(getCursorInclusionDirective(C)->getFileName());
+ return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
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());
+ const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
+ return cxstring::createDup(AA->getAnnotation());
}
if (C.kind == CXCursor_AsmLabelAttr) {
- AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
- return createCXString(AA->getLabel());
+ const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
+ return cxstring::createDup(AA->getLabel());
}
- return createCXString("");
+ return cxstring::createEmpty();
}
CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
@@ -3213,8 +3287,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
ASTContext &Ctx = getCursorContext(C);
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
+ const Stmt *S = getCursorStmt(C);
+ if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
if (pieceIndex > 0)
return clang_getNullRange();
return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
@@ -3224,7 +3298,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
}
if (C.kind == CXCursor_ObjCMessageExpr) {
- if (ObjCMessageExpr *
+ if (const ObjCMessageExpr *
ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
if (pieceIndex >= ME->getNumSelectorLocs())
return clang_getNullRange();
@@ -3234,7 +3308,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
C.kind == CXCursor_ObjCClassMethodDecl) {
- if (ObjCMethodDecl *
+ if (const ObjCMethodDecl *
MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
if (pieceIndex >= MD->getNumSelectorLocs())
return clang_getNullRange();
@@ -3246,10 +3320,10 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
C.kind == CXCursor_ObjCCategoryImplDecl) {
if (pieceIndex > 0)
return clang_getNullRange();
- if (ObjCCategoryDecl *
+ if (const ObjCCategoryDecl *
CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
- if (ObjCCategoryImplDecl *
+ if (const ObjCCategoryImplDecl *
CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
}
@@ -3257,7 +3331,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
if (C.kind == CXCursor_ModuleImportDecl) {
if (pieceIndex > 0)
return clang_getNullRange();
- if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
+ if (const ImportDecl *ImportD =
+ dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
if (!Locs.empty())
return cxloc::translateSourceRange(Ctx,
@@ -3289,15 +3364,15 @@ CXString clang_getCursorDisplayName(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getCursorSpelling(C);
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
+ if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
D = FunTmpl->getTemplatedDecl();
- if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *Function;
@@ -3316,10 +3391,10 @@ CXString clang_getCursorDisplayName(CXCursor C) {
OS << "...";
}
OS << ")";
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
- if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
+ if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassTemplate;
@@ -3347,23 +3422,23 @@ CXString clang_getCursorDisplayName(CXCursor C) {
}
OS << ">";
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
- if (ClassTemplateSpecializationDecl *ClassSpec
+ if (const ClassTemplateSpecializationDecl *ClassSpec
= dyn_cast<ClassTemplateSpecializationDecl>(D)) {
// If the type was explicitly written, use that.
if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
- return createCXString(TSInfo->getType().getAsString(Policy));
+ return cxstring::createDup(TSInfo->getType().getAsString(Policy));
- SmallString<64> Str;
+ SmallString<128> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassSpec;
- OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateSpecializationType::PrintTemplateArgumentList(OS,
ClassSpec->getTemplateArgs().data(),
ClassSpec->getTemplateArgs().size(),
Policy);
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
return clang_getCursorSpelling(C);
@@ -3372,297 +3447,297 @@ CXString clang_getCursorDisplayName(CXCursor C) {
CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
switch (Kind) {
case CXCursor_FunctionDecl:
- return createCXString("FunctionDecl");
+ return cxstring::createRef("FunctionDecl");
case CXCursor_TypedefDecl:
- return createCXString("TypedefDecl");
+ return cxstring::createRef("TypedefDecl");
case CXCursor_EnumDecl:
- return createCXString("EnumDecl");
+ return cxstring::createRef("EnumDecl");
case CXCursor_EnumConstantDecl:
- return createCXString("EnumConstantDecl");
+ return cxstring::createRef("EnumConstantDecl");
case CXCursor_StructDecl:
- return createCXString("StructDecl");
+ return cxstring::createRef("StructDecl");
case CXCursor_UnionDecl:
- return createCXString("UnionDecl");
+ return cxstring::createRef("UnionDecl");
case CXCursor_ClassDecl:
- return createCXString("ClassDecl");
+ return cxstring::createRef("ClassDecl");
case CXCursor_FieldDecl:
- return createCXString("FieldDecl");
+ return cxstring::createRef("FieldDecl");
case CXCursor_VarDecl:
- return createCXString("VarDecl");
+ return cxstring::createRef("VarDecl");
case CXCursor_ParmDecl:
- return createCXString("ParmDecl");
+ return cxstring::createRef("ParmDecl");
case CXCursor_ObjCInterfaceDecl:
- return createCXString("ObjCInterfaceDecl");
+ return cxstring::createRef("ObjCInterfaceDecl");
case CXCursor_ObjCCategoryDecl:
- return createCXString("ObjCCategoryDecl");
+ return cxstring::createRef("ObjCCategoryDecl");
case CXCursor_ObjCProtocolDecl:
- return createCXString("ObjCProtocolDecl");
+ return cxstring::createRef("ObjCProtocolDecl");
case CXCursor_ObjCPropertyDecl:
- return createCXString("ObjCPropertyDecl");
+ return cxstring::createRef("ObjCPropertyDecl");
case CXCursor_ObjCIvarDecl:
- return createCXString("ObjCIvarDecl");
+ return cxstring::createRef("ObjCIvarDecl");
case CXCursor_ObjCInstanceMethodDecl:
- return createCXString("ObjCInstanceMethodDecl");
+ return cxstring::createRef("ObjCInstanceMethodDecl");
case CXCursor_ObjCClassMethodDecl:
- return createCXString("ObjCClassMethodDecl");
+ return cxstring::createRef("ObjCClassMethodDecl");
case CXCursor_ObjCImplementationDecl:
- return createCXString("ObjCImplementationDecl");
+ return cxstring::createRef("ObjCImplementationDecl");
case CXCursor_ObjCCategoryImplDecl:
- return createCXString("ObjCCategoryImplDecl");
+ return cxstring::createRef("ObjCCategoryImplDecl");
case CXCursor_CXXMethod:
- return createCXString("CXXMethod");
+ return cxstring::createRef("CXXMethod");
case CXCursor_UnexposedDecl:
- return createCXString("UnexposedDecl");
+ return cxstring::createRef("UnexposedDecl");
case CXCursor_ObjCSuperClassRef:
- return createCXString("ObjCSuperClassRef");
+ return cxstring::createRef("ObjCSuperClassRef");
case CXCursor_ObjCProtocolRef:
- return createCXString("ObjCProtocolRef");
+ return cxstring::createRef("ObjCProtocolRef");
case CXCursor_ObjCClassRef:
- return createCXString("ObjCClassRef");
+ return cxstring::createRef("ObjCClassRef");
case CXCursor_TypeRef:
- return createCXString("TypeRef");
+ return cxstring::createRef("TypeRef");
case CXCursor_TemplateRef:
- return createCXString("TemplateRef");
+ return cxstring::createRef("TemplateRef");
case CXCursor_NamespaceRef:
- return createCXString("NamespaceRef");
+ return cxstring::createRef("NamespaceRef");
case CXCursor_MemberRef:
- return createCXString("MemberRef");
+ return cxstring::createRef("MemberRef");
case CXCursor_LabelRef:
- return createCXString("LabelRef");
+ return cxstring::createRef("LabelRef");
case CXCursor_OverloadedDeclRef:
- return createCXString("OverloadedDeclRef");
+ return cxstring::createRef("OverloadedDeclRef");
case CXCursor_VariableRef:
- return createCXString("VariableRef");
+ return cxstring::createRef("VariableRef");
case CXCursor_IntegerLiteral:
- return createCXString("IntegerLiteral");
+ return cxstring::createRef("IntegerLiteral");
case CXCursor_FloatingLiteral:
- return createCXString("FloatingLiteral");
+ return cxstring::createRef("FloatingLiteral");
case CXCursor_ImaginaryLiteral:
- return createCXString("ImaginaryLiteral");
+ return cxstring::createRef("ImaginaryLiteral");
case CXCursor_StringLiteral:
- return createCXString("StringLiteral");
+ return cxstring::createRef("StringLiteral");
case CXCursor_CharacterLiteral:
- return createCXString("CharacterLiteral");
+ return cxstring::createRef("CharacterLiteral");
case CXCursor_ParenExpr:
- return createCXString("ParenExpr");
+ return cxstring::createRef("ParenExpr");
case CXCursor_UnaryOperator:
- return createCXString("UnaryOperator");
+ return cxstring::createRef("UnaryOperator");
case CXCursor_ArraySubscriptExpr:
- return createCXString("ArraySubscriptExpr");
+ return cxstring::createRef("ArraySubscriptExpr");
case CXCursor_BinaryOperator:
- return createCXString("BinaryOperator");
+ return cxstring::createRef("BinaryOperator");
case CXCursor_CompoundAssignOperator:
- return createCXString("CompoundAssignOperator");
+ return cxstring::createRef("CompoundAssignOperator");
case CXCursor_ConditionalOperator:
- return createCXString("ConditionalOperator");
+ return cxstring::createRef("ConditionalOperator");
case CXCursor_CStyleCastExpr:
- return createCXString("CStyleCastExpr");
+ return cxstring::createRef("CStyleCastExpr");
case CXCursor_CompoundLiteralExpr:
- return createCXString("CompoundLiteralExpr");
+ return cxstring::createRef("CompoundLiteralExpr");
case CXCursor_InitListExpr:
- return createCXString("InitListExpr");
+ return cxstring::createRef("InitListExpr");
case CXCursor_AddrLabelExpr:
- return createCXString("AddrLabelExpr");
+ return cxstring::createRef("AddrLabelExpr");
case CXCursor_StmtExpr:
- return createCXString("StmtExpr");
+ return cxstring::createRef("StmtExpr");
case CXCursor_GenericSelectionExpr:
- return createCXString("GenericSelectionExpr");
+ return cxstring::createRef("GenericSelectionExpr");
case CXCursor_GNUNullExpr:
- return createCXString("GNUNullExpr");
+ return cxstring::createRef("GNUNullExpr");
case CXCursor_CXXStaticCastExpr:
- return createCXString("CXXStaticCastExpr");
+ return cxstring::createRef("CXXStaticCastExpr");
case CXCursor_CXXDynamicCastExpr:
- return createCXString("CXXDynamicCastExpr");
+ return cxstring::createRef("CXXDynamicCastExpr");
case CXCursor_CXXReinterpretCastExpr:
- return createCXString("CXXReinterpretCastExpr");
+ return cxstring::createRef("CXXReinterpretCastExpr");
case CXCursor_CXXConstCastExpr:
- return createCXString("CXXConstCastExpr");
+ return cxstring::createRef("CXXConstCastExpr");
case CXCursor_CXXFunctionalCastExpr:
- return createCXString("CXXFunctionalCastExpr");
+ return cxstring::createRef("CXXFunctionalCastExpr");
case CXCursor_CXXTypeidExpr:
- return createCXString("CXXTypeidExpr");
+ return cxstring::createRef("CXXTypeidExpr");
case CXCursor_CXXBoolLiteralExpr:
- return createCXString("CXXBoolLiteralExpr");
+ return cxstring::createRef("CXXBoolLiteralExpr");
case CXCursor_CXXNullPtrLiteralExpr:
- return createCXString("CXXNullPtrLiteralExpr");
+ return cxstring::createRef("CXXNullPtrLiteralExpr");
case CXCursor_CXXThisExpr:
- return createCXString("CXXThisExpr");
+ return cxstring::createRef("CXXThisExpr");
case CXCursor_CXXThrowExpr:
- return createCXString("CXXThrowExpr");
+ return cxstring::createRef("CXXThrowExpr");
case CXCursor_CXXNewExpr:
- return createCXString("CXXNewExpr");
+ return cxstring::createRef("CXXNewExpr");
case CXCursor_CXXDeleteExpr:
- return createCXString("CXXDeleteExpr");
+ return cxstring::createRef("CXXDeleteExpr");
case CXCursor_UnaryExpr:
- return createCXString("UnaryExpr");
+ return cxstring::createRef("UnaryExpr");
case CXCursor_ObjCStringLiteral:
- return createCXString("ObjCStringLiteral");
+ return cxstring::createRef("ObjCStringLiteral");
case CXCursor_ObjCBoolLiteralExpr:
- return createCXString("ObjCBoolLiteralExpr");
+ return cxstring::createRef("ObjCBoolLiteralExpr");
case CXCursor_ObjCEncodeExpr:
- return createCXString("ObjCEncodeExpr");
+ return cxstring::createRef("ObjCEncodeExpr");
case CXCursor_ObjCSelectorExpr:
- return createCXString("ObjCSelectorExpr");
+ return cxstring::createRef("ObjCSelectorExpr");
case CXCursor_ObjCProtocolExpr:
- return createCXString("ObjCProtocolExpr");
+ return cxstring::createRef("ObjCProtocolExpr");
case CXCursor_ObjCBridgedCastExpr:
- return createCXString("ObjCBridgedCastExpr");
+ return cxstring::createRef("ObjCBridgedCastExpr");
case CXCursor_BlockExpr:
- return createCXString("BlockExpr");
+ return cxstring::createRef("BlockExpr");
case CXCursor_PackExpansionExpr:
- return createCXString("PackExpansionExpr");
+ return cxstring::createRef("PackExpansionExpr");
case CXCursor_SizeOfPackExpr:
- return createCXString("SizeOfPackExpr");
+ return cxstring::createRef("SizeOfPackExpr");
case CXCursor_LambdaExpr:
- return createCXString("LambdaExpr");
+ return cxstring::createRef("LambdaExpr");
case CXCursor_UnexposedExpr:
- return createCXString("UnexposedExpr");
+ return cxstring::createRef("UnexposedExpr");
case CXCursor_DeclRefExpr:
- return createCXString("DeclRefExpr");
+ return cxstring::createRef("DeclRefExpr");
case CXCursor_MemberRefExpr:
- return createCXString("MemberRefExpr");
+ return cxstring::createRef("MemberRefExpr");
case CXCursor_CallExpr:
- return createCXString("CallExpr");
+ return cxstring::createRef("CallExpr");
case CXCursor_ObjCMessageExpr:
- return createCXString("ObjCMessageExpr");
+ return cxstring::createRef("ObjCMessageExpr");
case CXCursor_UnexposedStmt:
- return createCXString("UnexposedStmt");
+ return cxstring::createRef("UnexposedStmt");
case CXCursor_DeclStmt:
- return createCXString("DeclStmt");
+ return cxstring::createRef("DeclStmt");
case CXCursor_LabelStmt:
- return createCXString("LabelStmt");
+ return cxstring::createRef("LabelStmt");
case CXCursor_CompoundStmt:
- return createCXString("CompoundStmt");
+ return cxstring::createRef("CompoundStmt");
case CXCursor_CaseStmt:
- return createCXString("CaseStmt");
+ return cxstring::createRef("CaseStmt");
case CXCursor_DefaultStmt:
- return createCXString("DefaultStmt");
+ return cxstring::createRef("DefaultStmt");
case CXCursor_IfStmt:
- return createCXString("IfStmt");
+ return cxstring::createRef("IfStmt");
case CXCursor_SwitchStmt:
- return createCXString("SwitchStmt");
+ return cxstring::createRef("SwitchStmt");
case CXCursor_WhileStmt:
- return createCXString("WhileStmt");
+ return cxstring::createRef("WhileStmt");
case CXCursor_DoStmt:
- return createCXString("DoStmt");
+ return cxstring::createRef("DoStmt");
case CXCursor_ForStmt:
- return createCXString("ForStmt");
+ return cxstring::createRef("ForStmt");
case CXCursor_GotoStmt:
- return createCXString("GotoStmt");
+ return cxstring::createRef("GotoStmt");
case CXCursor_IndirectGotoStmt:
- return createCXString("IndirectGotoStmt");
+ return cxstring::createRef("IndirectGotoStmt");
case CXCursor_ContinueStmt:
- return createCXString("ContinueStmt");
+ return cxstring::createRef("ContinueStmt");
case CXCursor_BreakStmt:
- return createCXString("BreakStmt");
+ return cxstring::createRef("BreakStmt");
case CXCursor_ReturnStmt:
- return createCXString("ReturnStmt");
+ return cxstring::createRef("ReturnStmt");
case CXCursor_GCCAsmStmt:
- return createCXString("GCCAsmStmt");
+ return cxstring::createRef("GCCAsmStmt");
case CXCursor_MSAsmStmt:
- return createCXString("MSAsmStmt");
+ return cxstring::createRef("MSAsmStmt");
case CXCursor_ObjCAtTryStmt:
- return createCXString("ObjCAtTryStmt");
+ return cxstring::createRef("ObjCAtTryStmt");
case CXCursor_ObjCAtCatchStmt:
- return createCXString("ObjCAtCatchStmt");
+ return cxstring::createRef("ObjCAtCatchStmt");
case CXCursor_ObjCAtFinallyStmt:
- return createCXString("ObjCAtFinallyStmt");
+ return cxstring::createRef("ObjCAtFinallyStmt");
case CXCursor_ObjCAtThrowStmt:
- return createCXString("ObjCAtThrowStmt");
+ return cxstring::createRef("ObjCAtThrowStmt");
case CXCursor_ObjCAtSynchronizedStmt:
- return createCXString("ObjCAtSynchronizedStmt");
+ return cxstring::createRef("ObjCAtSynchronizedStmt");
case CXCursor_ObjCAutoreleasePoolStmt:
- return createCXString("ObjCAutoreleasePoolStmt");
+ return cxstring::createRef("ObjCAutoreleasePoolStmt");
case CXCursor_ObjCForCollectionStmt:
- return createCXString("ObjCForCollectionStmt");
+ return cxstring::createRef("ObjCForCollectionStmt");
case CXCursor_CXXCatchStmt:
- return createCXString("CXXCatchStmt");
+ return cxstring::createRef("CXXCatchStmt");
case CXCursor_CXXTryStmt:
- return createCXString("CXXTryStmt");
+ return cxstring::createRef("CXXTryStmt");
case CXCursor_CXXForRangeStmt:
- return createCXString("CXXForRangeStmt");
+ return cxstring::createRef("CXXForRangeStmt");
case CXCursor_SEHTryStmt:
- return createCXString("SEHTryStmt");
+ return cxstring::createRef("SEHTryStmt");
case CXCursor_SEHExceptStmt:
- return createCXString("SEHExceptStmt");
+ return cxstring::createRef("SEHExceptStmt");
case CXCursor_SEHFinallyStmt:
- return createCXString("SEHFinallyStmt");
+ return cxstring::createRef("SEHFinallyStmt");
case CXCursor_NullStmt:
- return createCXString("NullStmt");
+ return cxstring::createRef("NullStmt");
case CXCursor_InvalidFile:
- return createCXString("InvalidFile");
+ return cxstring::createRef("InvalidFile");
case CXCursor_InvalidCode:
- return createCXString("InvalidCode");
+ return cxstring::createRef("InvalidCode");
case CXCursor_NoDeclFound:
- return createCXString("NoDeclFound");
+ return cxstring::createRef("NoDeclFound");
case CXCursor_NotImplemented:
- return createCXString("NotImplemented");
+ return cxstring::createRef("NotImplemented");
case CXCursor_TranslationUnit:
- return createCXString("TranslationUnit");
+ return cxstring::createRef("TranslationUnit");
case CXCursor_UnexposedAttr:
- return createCXString("UnexposedAttr");
+ return cxstring::createRef("UnexposedAttr");
case CXCursor_IBActionAttr:
- return createCXString("attribute(ibaction)");
+ return cxstring::createRef("attribute(ibaction)");
case CXCursor_IBOutletAttr:
- return createCXString("attribute(iboutlet)");
+ return cxstring::createRef("attribute(iboutlet)");
case CXCursor_IBOutletCollectionAttr:
- return createCXString("attribute(iboutletcollection)");
+ return cxstring::createRef("attribute(iboutletcollection)");
case CXCursor_CXXFinalAttr:
- return createCXString("attribute(final)");
+ return cxstring::createRef("attribute(final)");
case CXCursor_CXXOverrideAttr:
- return createCXString("attribute(override)");
+ return cxstring::createRef("attribute(override)");
case CXCursor_AnnotateAttr:
- return createCXString("attribute(annotate)");
+ return cxstring::createRef("attribute(annotate)");
case CXCursor_AsmLabelAttr:
- return createCXString("asm label");
+ return cxstring::createRef("asm label");
case CXCursor_PreprocessingDirective:
- return createCXString("preprocessing directive");
+ return cxstring::createRef("preprocessing directive");
case CXCursor_MacroDefinition:
- return createCXString("macro definition");
+ return cxstring::createRef("macro definition");
case CXCursor_MacroExpansion:
- return createCXString("macro expansion");
+ return cxstring::createRef("macro expansion");
case CXCursor_InclusionDirective:
- return createCXString("inclusion directive");
+ return cxstring::createRef("inclusion directive");
case CXCursor_Namespace:
- return createCXString("Namespace");
+ return cxstring::createRef("Namespace");
case CXCursor_LinkageSpec:
- return createCXString("LinkageSpec");
+ return cxstring::createRef("LinkageSpec");
case CXCursor_CXXBaseSpecifier:
- return createCXString("C++ base class specifier");
+ return cxstring::createRef("C++ base class specifier");
case CXCursor_Constructor:
- return createCXString("CXXConstructor");
+ return cxstring::createRef("CXXConstructor");
case CXCursor_Destructor:
- return createCXString("CXXDestructor");
+ return cxstring::createRef("CXXDestructor");
case CXCursor_ConversionFunction:
- return createCXString("CXXConversion");
+ return cxstring::createRef("CXXConversion");
case CXCursor_TemplateTypeParameter:
- return createCXString("TemplateTypeParameter");
+ return cxstring::createRef("TemplateTypeParameter");
case CXCursor_NonTypeTemplateParameter:
- return createCXString("NonTypeTemplateParameter");
+ return cxstring::createRef("NonTypeTemplateParameter");
case CXCursor_TemplateTemplateParameter:
- return createCXString("TemplateTemplateParameter");
+ return cxstring::createRef("TemplateTemplateParameter");
case CXCursor_FunctionTemplate:
- return createCXString("FunctionTemplate");
+ return cxstring::createRef("FunctionTemplate");
case CXCursor_ClassTemplate:
- return createCXString("ClassTemplate");
+ return cxstring::createRef("ClassTemplate");
case CXCursor_ClassTemplatePartialSpecialization:
- return createCXString("ClassTemplatePartialSpecialization");
+ return cxstring::createRef("ClassTemplatePartialSpecialization");
case CXCursor_NamespaceAlias:
- return createCXString("NamespaceAlias");
+ return cxstring::createRef("NamespaceAlias");
case CXCursor_UsingDirective:
- return createCXString("UsingDirective");
+ return cxstring::createRef("UsingDirective");
case CXCursor_UsingDeclaration:
- return createCXString("UsingDeclaration");
+ return cxstring::createRef("UsingDeclaration");
case CXCursor_TypeAliasDecl:
- return createCXString("TypeAliasDecl");
+ return cxstring::createRef("TypeAliasDecl");
case CXCursor_ObjCSynthesizeDecl:
- return createCXString("ObjCSynthesizeDecl");
+ return cxstring::createRef("ObjCSynthesizeDecl");
case CXCursor_ObjCDynamicDecl:
- return createCXString("ObjCDynamicDecl");
+ return cxstring::createRef("ObjCDynamicDecl");
case CXCursor_CXXAccessSpecifier:
- return createCXString("CXXAccessSpecifier");
+ return cxstring::createRef("CXXAccessSpecifier");
case CXCursor_ModuleImportDecl:
- return createCXString("ModuleImport");
+ return cxstring::createRef("ModuleImport");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3697,12 +3772,12 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
if (clang_isDeclaration(cursor.kind)) {
// Avoid having the implicit methods override the property decls.
- if (ObjCMethodDecl *MD
+ if (const ObjCMethodDecl *MD
= dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
if (MD->isImplicit())
return CXChildVisit_Break;
- } else if (ObjCInterfaceDecl *ID
+ } else if (const ObjCInterfaceDecl *ID
= dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
// Check that when we have multiple @class references in the same line,
// that later ones do not override the previous ones.
@@ -3712,7 +3787,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
// 'Foo' even though the cursor location was at 'Foo'.
if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
BestCursor->kind == CXCursor_ObjCClassRef)
- if (ObjCInterfaceDecl *PrevID
+ if (const ObjCInterfaceDecl *PrevID
= dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
if (PrevID != ID &&
!PrevID->isThisDeclarationADefinition() &&
@@ -3720,7 +3795,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
return CXChildVisit_Break;
}
- } else if (DeclaratorDecl *DD
+ } else if (const DeclaratorDecl *DD
= dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
SourceLocation StartLoc = DD->getSourceRange().getBegin();
// Check that when we have multiple declarators in the same line,
@@ -3733,7 +3808,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
return CXChildVisit_Break;
Data->VisitedDeclaratorDeclStartLoc = StartLoc;
- } else if (ObjCPropertyImplDecl *PropImp
+ } else if (const ObjCPropertyImplDecl *PropImp
= dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
(void)PropImp;
// Check that when we have multiple @synthesize in the same line,
@@ -3750,7 +3825,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
if (clang_isExpression(cursor.kind) &&
clang_isDeclaration(BestCursor->kind)) {
- if (Decl *D = getCursorDecl(*BestCursor)) {
+ if (const Decl *D = getCursorDecl(*BestCursor)) {
// Avoid having the cursor of an expression replace the declaration cursor
// when the expression source range overlaps the declaration range.
// This can happen for C++ constructor expressions whose range generally
@@ -3782,14 +3857,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
if (!TU)
return clang_getNullCursor();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
CXCursor Result = cxcursor::getCursor(TU, SLoc);
- bool Logging = getenv("LIBCLANG_LOGGING");
- if (Logging) {
+ LOG_FUNC_SECTION {
CXFile SearchFile;
unsigned SearchLine, SearchColumn;
CXFile ResultFile;
@@ -3798,18 +3872,19 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
- clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
- clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
+ clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+ clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
&ResultColumn, 0);
SearchFileName = clang_getFileName(SearchFile);
ResultFileName = clang_getFileName(ResultFile);
KindSpelling = clang_getCursorKindSpelling(Result.kind);
USR = clang_getCursorUSR(Result);
- fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
- clang_getCString(SearchFileName), SearchLine, SearchColumn,
- clang_getCString(KindSpelling),
- clang_getCString(ResultFileName), ResultLine, ResultColumn,
- clang_getCString(USR), IsDef);
+ *Log << llvm::format("(%s:%d:%d) = %s",
+ clang_getCString(SearchFileName), SearchLine, SearchColumn,
+ clang_getCString(KindSpelling))
+ << llvm::format("(%s:%d:%d):%s%s",
+ clang_getCString(ResultFileName), ResultLine, ResultColumn,
+ clang_getCString(USR), IsDef);
clang_disposeString(SearchFileName);
clang_disposeString(ResultFileName);
clang_disposeString(KindSpelling);
@@ -3822,13 +3897,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
= clang_getCursorKindSpelling(Definition.kind);
CXFile DefinitionFile;
unsigned DefinitionLine, DefinitionColumn;
- clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
+ clang_getFileLocation(DefinitionLoc, &DefinitionFile,
&DefinitionLine, &DefinitionColumn, 0);
CXString DefinitionFileName = clang_getFileName(DefinitionFile);
- fprintf(stderr, " -> %s(%s:%d:%d)\n",
- clang_getCString(DefinitionKindSpelling),
- clang_getCString(DefinitionFileName),
- DefinitionLine, DefinitionColumn);
+ *Log << llvm::format(" -> %s(%s:%d:%d)",
+ clang_getCString(DefinitionKindSpelling),
+ clang_getCString(DefinitionFileName),
+ DefinitionLine, DefinitionColumn);
clang_disposeString(DefinitionFileName);
clang_disposeString(DefinitionKindSpelling);
}
@@ -3842,6 +3917,18 @@ CXCursor clang_getNullCursor(void) {
}
unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
+ // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
+ // can't set consistently. For example, when visiting a DeclStmt we will set
+ // it but we don't set it on the result of clang_getCursorDefinition for
+ // a reference of the same declaration.
+ // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
+ // when visiting a DeclStmt currently, the AST should be enhanced to be able
+ // to provide that kind of info.
+ if (clang_isDeclaration(X.kind))
+ X.data[1] = 0;
+ if (clang_isDeclaration(Y.kind))
+ Y.data[1] = 0;
+
return X == Y;
}
@@ -3850,7 +3937,7 @@ unsigned clang_hashCursor(CXCursor C) {
if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
Index = 1;
- return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
+ return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
std::make_pair(C.kind, C.data[Index]));
}
@@ -3907,50 +3994,51 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef: {
- std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ std::pair<const ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCSuperClassRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCProtocolRef: {
- std::pair<ObjCProtocolDecl *, SourceLocation> P
+ std::pair<const ObjCProtocolDecl *, SourceLocation> P
= getCursorObjCProtocolRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCClassRef: {
- std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ std::pair<const ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCClassRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_TypeRef: {
- std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
+ std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_TemplateRef: {
- std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
+ std::pair<const TemplateDecl *, SourceLocation> P =
+ getCursorTemplateRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_NamespaceRef: {
- std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
+ std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_MemberRef: {
- std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
+ std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_VariableRef: {
- std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C);
+ std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
if (!BaseSpec)
return clang_getNullLocation();
@@ -3963,7 +4051,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
}
case CXCursor_LabelRef: {
- std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
+ std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
return cxloc::translateSourceLocation(getCursorContext(C), P.second);
}
@@ -3992,7 +4080,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (C.kind == CXCursor_MacroExpansion) {
SourceLocation L
- = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
+ = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
return cxloc::translateSourceLocation(getCursorContext(C), L);
}
@@ -4010,7 +4098,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullLocation();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullLocation();
@@ -4020,13 +4108,13 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
Loc = VD->getLocation();
}
// For ObjC methods, give the start location of the method name.
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Loc = MD->getSelectorStartLoc();
return cxloc::translateSourceLocation(getCursorContext(C), Loc);
@@ -4042,7 +4130,7 @@ CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
if (SLoc.isInvalid())
return clang_getNullCursor();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
// Translate the given source location to make it point at the beginning of
// the token under the cursor.
@@ -4118,7 +4206,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
if (C.kind == CXCursor_MacroExpansion) {
ASTUnit *TU = getCursorASTUnit(C);
- SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
return TU->mapRangeFromPreamble(Range);
}
@@ -4143,7 +4231,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
}
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return SourceRange();
@@ -4153,7 +4241,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
R.setBegin(VD->getLocation());
}
@@ -4166,7 +4254,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
/// the decl-specifier-seq for declarations.
static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return SourceRange();
@@ -4178,7 +4266,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
StartLoc = TI->getTypeLoc().getLocStart();
- } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
+ } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
StartLoc = TI->getTypeLoc().getLocStart();
}
@@ -4192,7 +4280,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
R.setBegin(VD->getLocation());
}
@@ -4219,12 +4307,13 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
CXTranslationUnit tu = getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
- if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+ if (const ObjCPropertyImplDecl *PropImpl =
+ dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return MakeCXCursor(Property, tu);
@@ -4232,8 +4321,8 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
}
if (clang_isExpression(C.kind)) {
- Expr *E = getCursorExpr(C);
- Decl *D = getDeclFromExpr(E);
+ const Expr *E = getCursorExpr(C);
+ const Decl *D = getDeclFromExpr(E);
if (D) {
CXCursor declCursor = MakeCXCursor(D, tu);
declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
@@ -4241,15 +4330,15 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return declCursor;
}
- if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
+ if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
return MakeCursorOverloadedDeclRef(Ovl, tu);
return clang_getNullCursor();
}
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
+ const Stmt *S = getCursorStmt(C);
+ if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
if (LabelDecl *label = Goto->getLabel())
if (LabelStmt *labelS = label->getStmt())
return MakeCXCursor(labelS, getCursorDecl(C), tu);
@@ -4258,7 +4347,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
}
if (C.kind == CXCursor_MacroExpansion) {
- if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
+ if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
return MakeMacroDefinitionCursor(Def, tu);
}
@@ -4270,16 +4359,16 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
- if (ObjCProtocolDecl *Def = Prot->getDefinition())
+ const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
+ if (const ObjCProtocolDecl *Def = Prot->getDefinition())
return MakeCXCursor(Def, tu);
return MakeCXCursor(Prot, tu);
}
case CXCursor_ObjCClassRef: {
- ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
- if (ObjCInterfaceDecl *Def = Class->getDefinition())
+ const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+ if (const ObjCInterfaceDecl *Def = Class->getDefinition())
return MakeCXCursor(Def, tu);
return MakeCXCursor(Class, tu);
@@ -4298,7 +4387,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return MakeCXCursor(getCursorMemberRef(C).first, tu );
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
tu ));
}
@@ -4306,9 +4395,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
case CXCursor_LabelRef:
// FIXME: We end up faking the "parent" declaration here because we
// don't want to make CXCursor larger.
- return MakeCXCursor(getCursorLabelRef(C).first,
- static_cast<ASTUnit*>(tu->TUData)->getASTContext()
- .getTranslationUnitDecl(),
+ return MakeCXCursor(getCursorLabelRef(C).first,
+ cxtu::getASTUnit(tu)->getASTContext()
+ .getTranslationUnitDecl(),
tu);
case CXCursor_OverloadedDeclRef:
@@ -4341,7 +4430,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
@@ -4373,10 +4462,12 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::Label: // FIXME: Is this right??
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
+ case Decl::OMPThreadPrivate:
return C;
// Declaration kinds that don't make any sense here, but are
// nonetheless harmless.
+ case Decl::Empty:
case Decl::TranslationUnit:
break;
@@ -4408,13 +4499,13 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::CXXConversion: {
const FunctionDecl *Def = 0;
if (cast<FunctionDecl>(D)->getBody(Def))
- return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
+ return MakeCXCursor(Def, TU);
return clang_getNullCursor();
}
case Decl::Var: {
// Ask the variable if it has a definition.
- if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+ if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
}
@@ -4444,14 +4535,14 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
TU));
case Decl::ObjCMethod: {
- ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
+ const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
if (Method->isThisDeclarationADefinition())
return C;
// Dig out the method definition in the associated
// @implementation, if we have it.
// FIXME: The ASTs should make finding the definition easier.
- if (ObjCInterfaceDecl *Class
+ if (const ObjCInterfaceDecl *Class
= dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
@@ -4469,7 +4560,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
case Decl::ObjCProtocol:
- if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
+ if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
@@ -4479,9 +4570,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
// reference to an Objective-C class, produce the @interface as
// the definition; when we were provided with the interface,
// produce the @implementation as the definition.
- ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
+ const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
if (WasReference) {
- if (ObjCInterfaceDecl *Def = IFace->getDefinition())
+ if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
return MakeCXCursor(Def, TU);
} else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
return MakeCXCursor(Impl, TU);
@@ -4494,9 +4585,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
case Decl::ObjCCompatibleAlias:
- if (ObjCInterfaceDecl *Class
+ if (const ObjCInterfaceDecl *Class
= cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
- if (ObjCInterfaceDecl *Def = Class->getDefinition())
+ if (const ObjCInterfaceDecl *Def = Class->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
@@ -4526,13 +4617,13 @@ CXCursor clang_getCanonicalCursor(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return C;
- if (Decl *D = getCursorDecl(C)) {
- if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
+ if (const Decl *D = getCursorDecl(C)) {
+ if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
return MakeCXCursor(CatD, getCursorTU(C));
- if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
- if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
return MakeCXCursor(IFD, getCursorTU(C));
return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
@@ -4550,15 +4641,15 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) {
return 0;
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
return E->getNumDecls();
if (OverloadedTemplateStorage *S
= Storage.dyn_cast<OverloadedTemplateStorage*>())
return S->size();
- Decl *D = Storage.get<Decl*>();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+ const Decl *D = Storage.get<const Decl *>();
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
return Using->shadow_size();
return 0;
@@ -4573,15 +4664,15 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
CXTranslationUnit TU = getCursorTU(cursor);
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
return MakeCXCursor(E->decls_begin()[index], TU);
if (OverloadedTemplateStorage *S
= Storage.dyn_cast<OverloadedTemplateStorage*>())
return MakeCXCursor(S->begin()[index], TU);
- Decl *D = Storage.get<Decl*>();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
+ const Decl *D = Storage.get<const Decl *>();
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
// FIXME: This is, unfortunately, linear time.
UsingDecl::shadow_iterator Pos = Using->shadow_begin();
std::advance(Pos, index);
@@ -4599,8 +4690,7 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,
unsigned *endLine,
unsigned *endColumn) {
assert(getCursorDecl(C) && "CXCursor has null decl");
- NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
- FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
SourceManager &SM = FD->getASTContext().getSourceManager();
@@ -4619,26 +4709,26 @@ CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
switch (C.kind) {
case CXCursor_MemberRefExpr:
- if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
+ if (const 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)))
+ if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
E->getQualifierLoc().getSourceRange(),
E->getOptionalExplicitTemplateArgs());
break;
case CXCursor_CallExpr:
- if (CXXOperatorCallExpr *OCE =
+ if (const CXXOperatorCallExpr *OCE =
dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
- Expr *Callee = OCE->getCallee();
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+ const Expr *Callee = OCE->getCallee();
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Callee = ICE->getSubExpr();
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
DRE->getQualifierLoc().getSourceRange());
}
@@ -4694,13 +4784,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
case CXToken_Identifier:
case CXToken_Keyword:
// We know we have an IdentifierInfo*, so use that.
- return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
+ return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
->getNameStart());
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(StringRef(Text, CXTok.int_data[2]));
+ return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
}
case CXToken_Punctuation:
@@ -4710,9 +4800,9 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
// We have to find the starting buffer pointer the hard way, by
// deconstructing the source location.
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
- return createCXString("");
+ return cxstring::createEmpty();
SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
std::pair<FileID, unsigned> LocInfo
@@ -4721,13 +4811,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
StringRef Buffer
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
if (Invalid)
- return createCXString("");
+ return cxstring::createEmpty();
- return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
+ return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
}
CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullLocation();
@@ -4736,7 +4826,7 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
}
CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullRange();
@@ -4748,9 +4838,9 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
SmallVectorImpl<CXToken> &CXTokens) {
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(Range.getBegin());
+ = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(Range.getEnd());
+ = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
// Cannot tokenize across files.
if (BeginLocInfo.first != EndLocInfo.first)
@@ -4789,7 +4879,7 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
// - Kind-specific fields
if (Tok.isLiteral()) {
CXTok.int_data[0] = CXToken_Literal;
- CXTok.ptr_data = (void *)Tok.getLiteralData();
+ CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
} else if (Tok.is(tok::raw_identifier)) {
// Lookup the identifier to determine whether we have a keyword.
IdentifierInfo *II
@@ -4818,12 +4908,19 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
CXToken **Tokens, unsigned *NumTokens) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ' << Range;
+ }
+
if (Tokens)
*Tokens = 0;
if (NumTokens)
*NumTokens = 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ if (!TU)
+ return;
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit || !Tokens || !NumTokens)
return;
@@ -4855,7 +4952,6 @@ void clang_disposeTokens(CXTranslationUnit TU,
// Token annotation APIs.
//===----------------------------------------------------------------------===//
-typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
CXCursor parent,
CXClientData client_data);
@@ -4864,7 +4960,6 @@ static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
namespace {
class AnnotateTokensWorker {
- AnnotateTokensData &Annotated;
CXToken *Tokens;
CXCursor *Cursors;
unsigned NumTokens;
@@ -4877,9 +4972,10 @@ class AnnotateTokensWorker {
struct PostChildrenInfo {
CXCursor Cursor;
SourceRange CursorRange;
+ unsigned BeforeReachingCursorIdx;
unsigned BeforeChildrenTokenIdx;
};
- llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
+ SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
bool MoreTokens() const { return TokIdx < NumTokens; }
unsigned NextToken() const { return TokIdx; }
@@ -4895,23 +4991,22 @@ class AnnotateTokensWorker {
}
void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
- void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+ bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
SourceRange);
public:
- AnnotateTokensWorker(AnnotateTokensData &annotated,
- CXToken *tokens, CXCursor *cursors, unsigned numTokens,
- CXTranslationUnit tu, SourceRange RegionOfInterest)
- : Annotated(annotated), Tokens(tokens), Cursors(cursors),
+ AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
+ CXTranslationUnit TU, SourceRange RegionOfInterest)
+ : Tokens(tokens), Cursors(cursors),
NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
- AnnotateVis(tu,
+ AnnotateVis(TU,
AnnotateTokensVisitor, this,
/*VisitPreprocessorLast=*/true,
/*VisitIncludedEntities=*/false,
RegionOfInterest,
/*VisitDeclsOnly=*/false,
AnnotateTokensPostChildrenVisitor),
- SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
+ SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
HasContextSensitiveKeywords(false) { }
void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
@@ -4935,27 +5030,13 @@ void AnnotateTokensWorker::AnnotateTokens() {
// Walk the AST within the region of interest, annotating tokens
// along the way.
AnnotateVis.visitFileRegion();
+}
- for (unsigned I = 0 ; I < TokIdx ; ++I) {
- AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
- if (Pos != Annotated.end() &&
- (clang_isInvalid(Cursors[I].kind) ||
- Pos->second.kind != CXCursor_PreprocessingDirective))
- Cursors[I] = Pos->second;
- }
-
- // Finish up annotating any tokens left.
- if (!MoreTokens())
+static inline void updateCursorAnnotation(CXCursor &Cursor,
+ const CXCursor &updateC) {
+ if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
return;
-
- const CXCursor &C = clang_getNullCursor();
- for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
- if (I < PreprocessingTokIdx && clang_isPreprocessing(Cursors[I].kind))
- continue;
-
- AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
- Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
- }
+ Cursor = updateC;
}
/// \brief It annotates and advances tokens with a cursor until the comparison
@@ -4970,11 +5051,12 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
while (MoreTokens()) {
const unsigned I = NextToken();
if (isFunctionMacroToken(I))
- return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
+ if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
+ return;
SourceLocation TokLoc = GetTokenLoc(I);
if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
- Cursors[I] = updateC;
+ updateCursorAnnotation(Cursors[I], updateC);
AdvanceToken();
continue;
}
@@ -4983,7 +5065,8 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
}
/// \brief Special annotation handling for macro argument tokens.
-void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
+/// \returns true if it advanced beyond all macro tokens, false otherwise.
+bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
CXCursor updateC,
RangeComparisonResult compResult,
SourceRange range) {
@@ -5013,13 +5096,15 @@ void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
atLeastOneCompFail = true;
}
- if (!atLeastOneCompFail)
- TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+ if (atLeastOneCompFail)
+ return false;
+
+ TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+ return true;
}
enum CXChildVisitResult
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
- CXSourceLocation Loc = clang_getCursorLocation(cursor);
SourceRange cursorRange = getRawCursorExtent(cursor);
if (cursorRange.isInvalid())
return CXChildVisit_Recurse;
@@ -5027,20 +5112,20 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
if (!HasContextSensitiveKeywords) {
// Objective-C properties can have context-sensitive keywords.
if (cursor.kind == CXCursor_ObjCPropertyDecl) {
- if (ObjCPropertyDecl *Property
+ if (const ObjCPropertyDecl *Property
= dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
}
// Objective-C methods can have context-sensitive keywords.
else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
cursor.kind == CXCursor_ObjCClassMethodDecl) {
- if (ObjCMethodDecl *Method
+ if (const ObjCMethodDecl *Method
= dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
if (Method->getObjCDeclQualifier())
HasContextSensitiveKeywords = true;
else {
- for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
+ for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
+ PEnd = Method->param_end();
P != PEnd; ++P) {
if ((*P)->getObjCDeclQualifier()) {
HasContextSensitiveKeywords = true;
@@ -5052,7 +5137,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
}
// C++ methods can have context-sensitive keywords.
else if (cursor.kind == CXCursor_CXXMethod) {
- if (CXXMethodDecl *Method
+ if (const CXXMethodDecl *Method
= dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
HasContextSensitiveKeywords = true;
@@ -5063,20 +5148,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
cursor.kind == CXCursor_ClassDecl ||
cursor.kind == CXCursor_ClassTemplate ||
cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
- if (Decl *D = getCursorDecl(cursor))
+ if (const Decl *D = getCursorDecl(cursor))
if (D->hasAttr<FinalAttr>())
HasContextSensitiveKeywords = true;
}
}
if (clang_isPreprocessing(cursor.kind)) {
- // For macro expansions, just note where the beginning of the macro
- // expansion occurs.
- if (cursor.kind == CXCursor_MacroExpansion) {
- Annotated[Loc.int_data] = cursor;
- return CXChildVisit_Recurse;
- }
-
// Items in the preprocessing record are kept separate from items in
// declarations, so we keep a separate token index.
unsigned SavedTokIdx = TokIdx;
@@ -5108,7 +5186,17 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
case RangeAfter:
break;
case RangeOverlap:
- Cursors[I] = cursor;
+ // For macro expansions, just note where the beginning of the macro
+ // expansion occurs.
+ if (cursor.kind == CXCursor_MacroExpansion) {
+ if (TokLoc == cursorRange.getBegin())
+ Cursors[I] = cursor;
+ AdvanceToken();
+ break;
+ }
+ // We may have already annotated macro names inside macro definitions.
+ if (Cursors[I].kind != CXCursor_MacroExpansion)
+ Cursors[I] = cursor;
AdvanceToken();
continue;
}
@@ -5124,48 +5212,14 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
if (cursorRange.isInvalid())
return CXChildVisit_Continue;
-
- SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
- // Adjust the annotated range based specific declarations.
+ unsigned BeforeReachingCursorIdx = NextToken();
const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
- if (clang_isDeclaration(cursorK)) {
- Decl *D = cxcursor::getCursorDecl(cursor);
-
- SourceLocation StartLoc;
- if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) {
- if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
- StartLoc = TI->getTypeLoc().getLocStart();
- } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) {
- if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
- StartLoc = TI->getTypeLoc().getLocStart();
- }
-
- if (StartLoc.isValid() && L.isValid() &&
- SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
- cursorRange.setBegin(StartLoc);
- }
-
- // If the location of the cursor occurs within a macro instantiation, record
- // the spelling location of the cursor in our annotation map. We can then
- // paper over the token labelings during a post-processing step to try and
- // get cursor mappings for tokens that are the *arguments* of a macro
- // instantiation.
- if (L.isMacroID()) {
- unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
- // Only invalidate the old annotation if it isn't part of a preprocessing
- // directive. Here we assume that the default construction of CXCursor
- // results in CXCursor.kind being an initialized value (i.e., 0). If
- // this isn't the case, we can fix by doing lookup + insertion.
-
- CXCursor &oldC = Annotated[rawEncoding];
- if (!clang_isPreprocessing(oldC.kind))
- oldC = cursor;
- }
-
const enum CXCursorKind K = clang_getCursorKind(parent);
const CXCursor updateC =
- (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
+ (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
+ // Attributes are annotated out-of-order, skip tokens until we reach it.
+ clang_isAttribute(cursor.kind))
? clang_getNullCursor() : parent;
annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
@@ -5176,13 +5230,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
// include the variable declaration, e.g.:
// MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
if (clang_isExpression(cursorK)) {
- Expr *E = getCursorExpr(cursor);
- if (Decl *D = getCursorParentDecl(cursor)) {
+ const Expr *E = getCursorExpr(cursor);
+ if (const Decl *D = getCursorParentDecl(cursor)) {
const unsigned I = NextToken();
if (E->getLocStart().isValid() && D->getLocation().isValid() &&
E->getLocStart() == D->getLocation() &&
E->getLocStart() == GetTokenLoc(I)) {
- Cursors[I] = updateC;
+ updateCursorAnnotation(Cursors[I], updateC);
AdvanceToken();
}
}
@@ -5197,6 +5251,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
PostChildrenInfo Info;
Info.Cursor = cursor;
Info.CursorRange = cursorRange;
+ Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Info.BeforeChildrenTokenIdx = NextToken();
PostChildrenInfos.push_back(Info);
@@ -5227,6 +5282,11 @@ bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
Cursors[I] = cursor;
}
+ // Attributes are annotated out-of-order, rewind TokIdx to when we first
+ // encountered the attribute cursor.
+ if (clang_isAttribute(cursor.kind))
+ TokIdx = Info.BeforeReachingCursorIdx;
+
PostChildrenInfos.pop_back();
return false;
}
@@ -5263,7 +5323,7 @@ public:
if (cursor.kind != CXCursor_MacroExpansion)
return CXChildVisit_Continue;
- SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
+ SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
if (macroRange.getBegin() == macroRange.getEnd())
return CXChildVisit_Continue; // it's not a function macro.
@@ -5321,16 +5381,34 @@ namespace {
};
}
+/// \brief Used by \c annotatePreprocessorTokens.
+/// \returns true if lexing was finished, false otherwise.
+static bool lexNext(Lexer &Lex, Token &Tok,
+ unsigned &NextIdx, unsigned NumTokens) {
+ if (NextIdx >= NumTokens)
+ return true;
+
+ ++NextIdx;
+ Lex.LexFromRawLexer(Tok);
+ if (Tok.is(tok::eof))
+ return true;
+
+ return false;
+}
+
static void annotatePreprocessorTokens(CXTranslationUnit TU,
SourceRange RegionOfInterest,
- AnnotateTokensData &Annotated) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ CXCursor *Cursors,
+ CXToken *Tokens,
+ unsigned NumTokens) {
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = CXXUnit->getPreprocessor();
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+ = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+ = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
if (BeginLocInfo.first != EndLocInfo.first)
return;
@@ -5347,44 +5425,77 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
Buffer.end());
Lex.SetCommentRetentionState(true);
+ unsigned NextIdx = 0;
// 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);
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+ unsigned TokIdx = NextIdx-1;
+ assert(Tok.getLocation() ==
+ SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
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.
+ // We have found a preprocessing directive. Annotate the tokens
+ // 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;
+
+ SourceLocation BeginLoc = Tok.getLocation();
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+
+ MacroInfo *MI = 0;
+ if (Tok.is(tok::raw_identifier) &&
+ StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+
+ if (Tok.is(tok::raw_identifier)) {
+ StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
+ IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+ SourceLocation MappedTokLoc =
+ CXXUnit->mapLocationToPreamble(Tok.getLocation());
+ MI = getMacroInfo(II, MappedTokLoc, TU);
+ }
}
+
+ bool finished = false;
+ do {
+ if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
+ finished = true;
+ break;
+ }
+ // If we are in a macro definition, check if the token was ever a
+ // macro name and annotate it if that's the case.
+ if (MI) {
+ SourceLocation SaveLoc = Tok.getLocation();
+ Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
+ MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
+ Tok.setLocation(SaveLoc);
+ if (MacroDef)
+ Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
+ Tok.getLocation(), TU);
+ }
+ } while (!Tok.isAtStartOfLine());
+
+ unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
+ assert(TokIdx <= LastIdx);
+ SourceLocation EndLoc =
+ SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
+ CXCursor Cursor =
+ MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
+
+ for (; TokIdx <= LastIdx; ++TokIdx)
+ updateCursorAnnotation(Cursors[TokIdx], Cursor);
- if (Tok.isAtStartOfLine())
- goto reprocess;
-
- continue;
+ if (finished)
+ break;
+ goto reprocess;
}
-
- if (Tok.is(tok::eof))
- break;
}
}
@@ -5396,7 +5507,7 @@ static void clang_annotateTokensImpl(void *UserData) {
const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
@@ -5408,14 +5519,20 @@ static void clang_annotateTokensImpl(void *UserData) {
cxloc::translateSourceLocation(clang_getTokenLocation(TU,
Tokens[NumTokens-1])));
- // 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.
- annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
-
+ annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
+
+ // If begin location points inside a macro argument, set it to the expansion
+ // location so we can have the full context when annotating semantically.
+ {
+ SourceManager &SM = CXXUnit->getSourceManager();
+ SourceLocation Loc =
+ SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
+ if (Loc.isMacroID())
+ RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
+ }
+
if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
// Search and mark tokens that are macro argument expansions.
MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
@@ -5430,8 +5547,7 @@ static void clang_annotateTokensImpl(void *UserData) {
// Annotate all of the source locations in the region of interest that map to
// a specific cursor.
- AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
- TU, RegionOfInterest);
+ AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
// FIXME: We use a ridiculous stack size here because the data-recursion
// algorithm uses a large stack frame than the non-data recursive version,
@@ -5449,7 +5565,7 @@ static void clang_annotateTokensImpl(void *UserData) {
if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
- if (ObjCPropertyDecl *Property
+ if (const ObjCPropertyDecl *Property
= dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
if (Property->getPropertyAttributesAsWritten() != 0 &&
llvm::StringSwitch<bool>(II->getName())
@@ -5500,16 +5616,24 @@ extern "C" {
void clang_annotateTokens(CXTranslationUnit TU,
CXToken *Tokens, unsigned NumTokens,
CXCursor *Cursors) {
-
- if (NumTokens == 0 || !Tokens || !Cursors)
+ if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
+ LOG_FUNC_SECTION { *Log << "<null input>"; }
return;
+ }
+
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ';
+ CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
+ CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
+ *Log << clang_getRange(bloc, eloc);
+ }
// Any token we don't specifically annotate will have a NULL cursor.
CXCursor C = clang_getNullCursor();
for (unsigned I = 0; I != NumTokens; ++I)
Cursors[I] = C;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return;
@@ -5534,8 +5658,8 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
if (!clang_isDeclaration(cursor.kind))
return CXLinkage_Invalid;
- Decl *D = cxcursor::getCursorDecl(cursor);
- if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
+ const Decl *D = cxcursor::getCursorDecl(cursor);
+ if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
switch (ND->getLinkage()) {
case NoLinkage: return CXLinkage_NoLinkage;
case InternalLinkage: return CXLinkage_Internal;
@@ -5604,7 +5728,7 @@ extern "C" {
enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind))
- if (Decl *D = cxcursor::getCursorDecl(cursor)) {
+ if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
return CXAvailability_Available;
@@ -5631,12 +5755,14 @@ static CXVersion convertVersion(VersionTuple In) {
Out.Major = In.getMajor();
- if (llvm::Optional<unsigned> Minor = In.getMinor())
+ Optional<unsigned> Minor = In.getMinor();
+ if (Minor.hasValue())
Out.Minor = *Minor;
else
return Out;
- if (llvm::Optional<unsigned> Subminor = In.getSubminor())
+ Optional<unsigned> Subminor = In.getSubminor();
+ if (Subminor.hasValue())
Out.Subminor = *Subminor;
return Out;
@@ -5652,16 +5778,16 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_deprecated)
*always_deprecated = 0;
if (deprecated_message)
- *deprecated_message = cxstring::createCXString("", /*DupString=*/false);
+ *deprecated_message = cxstring::createEmpty();
if (always_unavailable)
*always_unavailable = 0;
if (unavailable_message)
- *unavailable_message = cxstring::createCXString("", /*DupString=*/false);
+ *unavailable_message = cxstring::createEmpty();
if (!clang_isDeclaration(cursor.kind))
return 0;
- Decl *D = cxcursor::getCursorDecl(cursor);
+ const Decl *D = cxcursor::getCursorDecl(cursor);
if (!D)
return 0;
@@ -5672,7 +5798,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_deprecated)
*always_deprecated = 1;
if (deprecated_message)
- *deprecated_message = cxstring::createCXString(Deprecated->getMessage());
+ *deprecated_message = cxstring::createDup(Deprecated->getMessage());
continue;
}
@@ -5680,8 +5806,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_unavailable)
*always_unavailable = 1;
if (unavailable_message) {
- *unavailable_message
- = cxstring::createCXString(Unavailable->getMessage());
+ *unavailable_message = cxstring::createDup(Unavailable->getMessage());
}
continue;
}
@@ -5689,12 +5814,12 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
if (N < availability_size) {
availability[N].Platform
- = cxstring::createCXString(Avail->getPlatform()->getName());
+ = cxstring::createDup(Avail->getPlatform()->getName());
availability[N].Introduced = convertVersion(Avail->getIntroduced());
availability[N].Deprecated = convertVersion(Avail->getDeprecated());
availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
availability[N].Unavailable = Avail->getUnavailable();
- availability[N].Message = cxstring::createCXString(Avail->getMessage());
+ availability[N].Message = cxstring::createDup(Avail->getMessage());
}
++N;
}
@@ -5718,15 +5843,15 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
/// \brief If the given cursor is the "templated" declaration
/// descibing a class or function template, return the class or
/// function template.
-static Decl *maybeGetTemplateCursor(Decl *D) {
+static const Decl *maybeGetTemplateCursor(const Decl *D) {
if (!D)
return 0;
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
return FunTmpl;
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
return ClassTmpl;
@@ -5735,8 +5860,8 @@ static Decl *maybeGetTemplateCursor(Decl *D) {
CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor)) {
- DeclContext *DC = D->getDeclContext();
+ if (const Decl *D = getCursorDecl(cursor)) {
+ const DeclContext *DC = D->getDeclContext();
if (!DC)
return clang_getNullCursor();
@@ -5746,7 +5871,7 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
}
if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor))
+ if (const Decl *D = getCursorDecl(cursor))
return MakeCXCursor(D, getCursorTU(cursor));
}
@@ -5755,8 +5880,8 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor)) {
- DeclContext *DC = D->getLexicalDeclContext();
+ if (const Decl *D = getCursorDecl(cursor)) {
+ const DeclContext *DC = D->getLexicalDeclContext();
if (!DC)
return clang_getNullCursor();
@@ -5774,8 +5899,8 @@ CXFile clang_getIncludedFile(CXCursor cursor) {
if (cursor.kind != CXCursor_InclusionDirective)
return 0;
- InclusionDirective *ID = getCursorInclusionDirective(cursor);
- return (void *)ID->getFile();
+ const InclusionDirective *ID = getCursorInclusionDirective(cursor);
+ return const_cast<FileEntry *>(ID->getFile());
}
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
@@ -5793,7 +5918,7 @@ CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
CXString clang_Cursor_getRawCommentText(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
const Decl *D = getCursorDecl(C);
ASTContext &Context = getCursorContext(C);
@@ -5803,12 +5928,12 @@ CXString clang_Cursor_getRawCommentText(CXCursor C) {
// Don't duplicate the string because RawText points directly into source
// code.
- return createCXString(RawText, false);
+ return cxstring::createRef(RawText);
}
CXString clang_Cursor_getBriefCommentText(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
const Decl *D = getCursorDecl(C);
const ASTContext &Context = getCursorContext(C);
@@ -5819,10 +5944,10 @@ CXString clang_Cursor_getBriefCommentText(CXCursor C) {
// Don't duplicate the string because RawComment ensures that this memory
// will not go away.
- return createCXString(BriefText, false);
+ return cxstring::createRef(BriefText);
}
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
}
CXComment clang_Cursor_getParsedComment(CXCursor C) {
@@ -5838,7 +5963,8 @@ CXComment clang_Cursor_getParsedComment(CXCursor C) {
CXModule clang_Cursor_getModule(CXCursor C) {
if (C.kind == CXCursor_ModuleImportDecl) {
- if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
+ if (const ImportDecl *ImportD =
+ dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
return ImportD->getImportedModule();
}
@@ -5854,32 +5980,38 @@ CXModule clang_Module_getParent(CXModule CXMod) {
CXString clang_Module_getName(CXModule CXMod) {
if (!CXMod)
- return createCXString("");
+ return cxstring::createEmpty();
Module *Mod = static_cast<Module*>(CXMod);
- return createCXString(Mod->Name);
+ return cxstring::createDup(Mod->Name);
}
CXString clang_Module_getFullName(CXModule CXMod) {
if (!CXMod)
- return createCXString("");
+ return cxstring::createEmpty();
Module *Mod = static_cast<Module*>(CXMod);
- return createCXString(Mod->getFullModuleName());
+ return cxstring::createDup(Mod->getFullModuleName());
}
-unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
- if (!CXMod)
+unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
+ CXModule CXMod) {
+ if (!TU || !CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
- return Mod->TopHeaders.size();
+ FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
+ ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ return TopHeaders.size();
}
-CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
- if (!CXMod)
+CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
+ CXModule CXMod, unsigned Index) {
+ if (!TU || !CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
+ FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
- if (Index < Mod->TopHeaders.size())
- return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
+ ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ if (Index < TopHeaders.size())
+ return const_cast<FileEntry *>(TopHeaders[Index]);
return 0;
}
@@ -5895,9 +6027,10 @@ unsigned clang_CXXMethod_isStatic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- CXXMethodDecl *Method = 0;
- Decl *D = cxcursor::getCursorDecl(C);
- if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+ const CXXMethodDecl *Method = 0;
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const FunctionTemplateDecl *FunTmpl =
+ dyn_cast_or_null<FunctionTemplateDecl>(D))
Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
else
Method = dyn_cast_or_null<CXXMethodDecl>(D);
@@ -5908,9 +6041,10 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- CXXMethodDecl *Method = 0;
- Decl *D = cxcursor::getCursorDecl(C);
- if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+ const CXXMethodDecl *Method = 0;
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const FunctionTemplateDecl *FunTmpl =
+ dyn_cast_or_null<FunctionTemplateDecl>(D))
Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
else
Method = dyn_cast_or_null<CXXMethodDecl>(D);
@@ -5927,7 +6061,7 @@ CXType clang_getIBOutletCollectionType(CXCursor C) {
if (C.kind != CXCursor_IBOutletCollectionAttr)
return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
- IBOutletCollectionAttr *A =
+ const IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
@@ -6004,7 +6138,7 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
return usage;
}
- ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
+ ASTUnit *astUnit = cxtu::getASTUnit(TU);
OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
ASTContext &astContext = astUnit->getASTContext();
@@ -6167,11 +6301,205 @@ void cxindex::printDiagsToStderr(ASTUnit *Unit) {
#endif
}
+MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
+ SourceLocation MacroDefLoc,
+ CXTranslationUnit TU){
+ if (MacroDefLoc.isInvalid() || !TU)
+ return 0;
+ if (!II.hadMacroDefinition())
+ return 0;
+
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = Unit->getPreprocessor();
+ MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
+ if (MD) {
+ for (MacroDirective::DefInfo
+ Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+ if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
+ return Def.getMacroInfo();
+ }
+ }
+
+ return 0;
+}
+
+const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
+ CXTranslationUnit TU) {
+ if (!MacroDef || !TU)
+ return 0;
+ const IdentifierInfo *II = MacroDef->getName();
+ if (!II)
+ return 0;
+
+ return getMacroInfo(*II, MacroDef->getLocation(), TU);
+}
+
+MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
+ const Token &Tok,
+ CXTranslationUnit TU) {
+ if (!MI || !TU)
+ return 0;
+ if (Tok.isNot(tok::raw_identifier))
+ return 0;
+
+ if (MI->getNumTokens() == 0)
+ return 0;
+ SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
+ MI->getDefinitionEndLoc());
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+
+ // Check that the token is inside the definition and not its argument list.
+ SourceManager &SM = Unit->getSourceManager();
+ if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
+ return 0;
+ if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
+ return 0;
+
+ Preprocessor &PP = Unit->getPreprocessor();
+ PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
+ if (!PPRec)
+ return 0;
+
+ StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
+ IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+ if (!II.hadMacroDefinition())
+ return 0;
+
+ // Check that the identifier is not one of the macro arguments.
+ if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
+ return 0;
+
+ MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
+ if (!InnerMD)
+ return 0;
+
+ return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
+}
+
+MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU) {
+ if (Loc.isInvalid() || !MI || !TU)
+ return 0;
+
+ if (MI->getNumTokens() == 0)
+ return 0;
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = Unit->getPreprocessor();
+ if (!PP.getPreprocessingRecord())
+ return 0;
+ Loc = Unit->getSourceManager().getSpellingLoc(Loc);
+ Token Tok;
+ if (PP.getRawToken(Loc, Tok))
+ return 0;
+
+ return checkForMacroInMacroDefinition(MI, Tok, TU);
+}
+
extern "C" {
CXString clang_getClangVersion() {
- return createCXString(getClangFullVersion());
+ return cxstring::createDup(getClangFullVersion());
}
} // end: extern "C"
+Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
+ if (TU) {
+ if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
+ LogOS << '<' << Unit->getMainFileName() << '>';
+ if (Unit->isMainFileAST())
+ LogOS << " (" << Unit->getASTFileName() << ')';
+ return *this;
+ }
+ }
+
+ LogOS << "<NULL TU>";
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
+ *this << FE->getName();
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXCursor cursor) {
+ CXString cursorName = clang_getCursorDisplayName(cursor);
+ *this << cursorName << "@" << clang_getCursorLocation(cursor);
+ clang_disposeString(cursorName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
+ CXFile File;
+ unsigned Line, Column;
+ clang_getFileLocation(Loc, &File, &Line, &Column, 0);
+ CXString FileName = clang_getFileName(File);
+ *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
+ clang_disposeString(FileName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXSourceRange range) {
+ CXSourceLocation BLoc = clang_getRangeStart(range);
+ CXSourceLocation ELoc = clang_getRangeEnd(range);
+
+ CXFile BFile;
+ unsigned BLine, BColumn;
+ clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
+
+ CXFile EFile;
+ unsigned ELine, EColumn;
+ clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
+
+ CXString BFileName = clang_getFileName(BFile);
+ if (BFile == EFile) {
+ *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
+ BLine, BColumn, ELine, EColumn);
+ } else {
+ CXString EFileName = clang_getFileName(EFile);
+ *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
+ BLine, BColumn)
+ << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
+ ELine, EColumn);
+ clang_disposeString(EFileName);
+ }
+ clang_disposeString(BFileName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXString Str) {
+ *this << clang_getCString(Str);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
+ LogOS << Fmt;
+ return *this;
+}
+
+cxindex::Logger::~Logger() {
+ LogOS.flush();
+
+ llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+
+ static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
+
+ raw_ostream &OS = llvm::errs();
+ OS << "[libclang:" << Name << ':';
+
+ // FIXME: Portability.
+#if HAVE_PTHREAD_H && __APPLE__
+ mach_port_t tid = pthread_mach_thread_np(pthread_self());
+ OS << tid << ':';
+#endif
+
+ llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
+ OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
+ OS << Msg.str() << '\n';
+
+ if (Trace) {
+ llvm::sys::PrintStackTrace(stderr);
+ OS << "--------------------------------------------------\n";
+ }
+}
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 9bc3efa..c68dde7 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -26,7 +26,7 @@ unsigned clang_isVirtualBase(CXCursor C) {
if (C.kind != CXCursor_CXXBaseSpecifier)
return 0;
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
return B->isVirtual();
}
@@ -56,14 +56,13 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
switch (C.kind) {
case CXCursor_ClassTemplate:
case CXCursor_FunctionTemplate:
- if (TemplateDecl *Template
+ if (const TemplateDecl *Template
= dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
- return MakeCXCursor(Template->getTemplatedDecl(),
- static_cast<CXTranslationUnit>(C.data[2])).kind;
+ return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
break;
case CXCursor_ClassTemplatePartialSpecialization:
- if (ClassTemplateSpecializationDecl *PartialSpec
+ if (const ClassTemplateSpecializationDecl *PartialSpec
= dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
getCursorDecl(C))) {
switch (PartialSpec->getTagKind()) {
@@ -87,16 +86,16 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
Decl *Template = 0;
- if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
- if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+ if (const ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
Template = PartialSpec->getSpecializedTemplate();
- else if (ClassTemplateSpecializationDecl *ClassSpec
+ else if (const ClassTemplateSpecializationDecl *ClassSpec
= dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *> Result
@@ -108,21 +107,21 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
} else
Template = CXXRecord->getInstantiatedFromMemberClass();
- } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Template = Function->getPrimaryTemplate();
if (!Template)
Template = Function->getInstantiatedFromMemberFunction();
- } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->isStaticDataMember())
Template = Var->getInstantiatedFromStaticDataMember();
- } else if (RedeclarableTemplateDecl *Tmpl
+ } else if (const RedeclarableTemplateDecl *Tmpl
= dyn_cast<RedeclarableTemplateDecl>(D))
Template = Tmpl->getInstantiatedFromMemberTemplate();
if (!Template)
return clang_getNullCursor();
- return MakeCXCursor(Template, static_cast<CXTranslationUnit>(C.data[2]));
+ return MakeCXCursor(Template, getCursorTU(C));
}
} // end extern "C"
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 46af661..f79de29 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -13,16 +13,16 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
-#include "CXString.h"
+#include "CIndexDiagnostic.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXString.h"
-#include "CIndexDiagnostic.h"
-#include "clang/AST/Type.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -32,11 +32,12 @@
#include "llvm/Support/Atomic.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Program.h"
-#include <cstdlib>
#include <cstdio>
+#include <cstdlib>
+#include <string>
#ifdef UDP_CODE_COMPLETION_LOGGER
@@ -48,7 +49,7 @@
#endif
using namespace clang;
-using namespace clang::cxstring;
+using namespace clang::cxindex;
extern "C" {
@@ -111,7 +112,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
unsigned chunk_number) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr || chunk_number >= CCStr->size())
- return createCXString((const char*)0);
+ return cxstring::createNull();
switch ((*CCStr)[chunk_number].Kind) {
case CodeCompletionString::CK_TypedText:
@@ -134,11 +135,11 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
case CodeCompletionString::CK_Equal:
case CodeCompletionString::CK_HorizontalSpace:
case CodeCompletionString::CK_VerticalSpace:
- return createCXString((*CCStr)[chunk_number].Text, false);
+ return cxstring::createRef((*CCStr)[chunk_number].Text);
case CodeCompletionString::CK_Optional:
// Note: treated as an empty text block.
- return createCXString("");
+ return cxstring::createEmpty();
}
llvm_unreachable("Invalid CodeCompletionString Kind!");
@@ -209,8 +210,8 @@ unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
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);
+ return CCStr ? cxstring::createRef(CCStr->getAnnotation(annotation_number))
+ : cxstring::createNull();
}
CXString
@@ -221,9 +222,9 @@ clang_getCompletionParent(CXCompletionString completion_string,
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *)0);
+ return cxstring::createNull();
- return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getParentContextName());
}
CXString
@@ -231,14 +232,20 @@ clang_getCompletionBriefComment(CXCompletionString completion_string) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
- return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getBriefComment());
}
-
+namespace {
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
+///
+/// Normally, clients of CXString shouldn't care whether or not a CXString is
+/// managed by a pool or by explicitly malloc'ed memory. But
+/// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
+/// not rely on the StringPool in the TU.
struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
~AllocatedCXCodeCompleteResults();
@@ -287,8 +294,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \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;
+ std::string ContainerUSR;
+
/// \brief a boolean value indicating whether there is complete information
/// about the container
unsigned ContainerIsIncomplete;
@@ -298,6 +307,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
std::string Selector;
};
+} // end anonymous namespace
+
/// \brief Tracks the number of code-completion result objects that are
/// currently active.
///
@@ -317,7 +328,6 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
Contexts(CXCompletionContext_Unknown),
ContainerKind(CXCursor_InvalidCode),
- ContainerUSR(createCXString("")),
ContainerIsIncomplete(1)
{
if (getenv("LIBCLANG_OBJTRACKING")) {
@@ -328,9 +338,7 @@ 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)
@@ -587,24 +595,13 @@ namespace {
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;
-
+
+ AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
+
+ CXString CursorUSR = clang_getCursorUSR(cursor);
+ AllocatedResults.ContainerUSR = clang_getCString(CursorUSR);
+ clang_disposeString(CursorUSR);
+
const Type *type = baseType.getTypePtrOrNull();
if (type != NULL) {
AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
@@ -615,7 +612,7 @@ namespace {
}
else {
AllocatedResults.ContainerKind = CXCursor_InvalidCode;
- AllocatedResults.ContainerUSR = createCXString("");
+ AllocatedResults.ContainerUSR.clear();
AllocatedResults.ContainerIsIncomplete = 1;
}
}
@@ -684,11 +681,11 @@ void clang_codeCompleteAt_Impl(void *UserData) {
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
- ASTUnit *AST = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *AST = cxtu::getASTUnit(TU);
if (!AST)
return;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
@@ -819,14 +816,25 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' '
+ << complete_filename << ':' << complete_line << ':' << complete_column;
+ }
+
CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
complete_column, unsaved_files, num_unsaved_files,
options, 0 };
+
+ if (getenv("LIBCLANG_NOTHREADS")) {
+ clang_codeCompleteAt_Impl(&CCAI);
+ return CCAI.result;
+ }
+
llvm::CrashRecoveryContext CRC;
if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
fprintf(stderr, "libclang: crash detected in code completion\n");
- static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+ cxtu::getASTUnit(TU)->setUnsafeToFree(true);
return 0;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -897,9 +905,9 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
-
- return createCXString(clang_getCString(Results->ContainerUSR));
+ return cxstring::createEmpty();
+
+ return cxstring::createRef(Results->ContainerUSR.c_str());
}
@@ -907,9 +915,9 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
+ return cxstring::createEmpty();
- return createCXString(Results->Selector);
+ return cxstring::createDup(Results->Selector);
}
} // end extern "C"
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 3154480..0e9dde8 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -27,7 +27,6 @@
using namespace clang;
using namespace clang::cxloc;
-using namespace clang::cxstring;
using namespace clang::cxdiag;
using namespace llvm;
@@ -62,17 +61,17 @@ public:
}
CXString getSpelling() const {
- return createCXString(StringRef(Message), false);
+ return cxstring::createRef(Message.c_str());
}
CXString getDiagnosticOption(CXString *Disable) const {
if (Disable)
- *Disable = createCXString("", false);
- return createCXString("", false);
+ *Disable = cxstring::createEmpty();
+ return cxstring::createEmpty();
}
unsigned getCategory() const { return 0; }
- CXString getCategoryText() const { return createCXString(""); }
+ CXString getCategoryText() const { return cxstring::createEmpty(); }
unsigned getNumRanges() const { return 0; }
CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
@@ -80,7 +79,7 @@ public:
CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
- return createCXString("", false);
+ return cxstring::createEmpty();
}
};
@@ -158,7 +157,7 @@ public:
CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
bool checkIfChanged) {
- ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *AU = cxtu::getASTUnit(TU);
if (TU->Diagnostics && checkIfChanged) {
// In normal use, ASTUnit's diagnostics should not change unless we reparse.
@@ -191,7 +190,7 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
if (!TU->Diagnostics) {
CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
TU->Diagnostics = Set;
- llvm::IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
+ IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
&*DOpts, Set);
@@ -209,7 +208,7 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
extern "C" {
unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
- if (!Unit->TUData)
+ if (!cxtu::getASTUnit(Unit))
return 0;
return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
}
@@ -227,7 +226,7 @@ CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
}
CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
- if (!Unit->TUData)
+ if (!cxtu::getASTUnit(Unit))
return 0;
return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
}
@@ -239,7 +238,7 @@ void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
if (!Diagnostic)
- return createCXString("");
+ return cxstring::createEmpty();
CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
@@ -354,7 +353,7 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
Out << "]";
}
- return createCXString(Out.str(), true);
+ return cxstring::createDup(Out.str());
}
unsigned clang_defaultDiagnosticDisplayOptions() {
@@ -377,17 +376,17 @@ CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getSpelling();
- return createCXString("");
+ return cxstring::createEmpty();
}
CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
if (Disable)
- *Disable = createCXString("");
+ *Disable = cxstring::createEmpty();
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getDiagnosticOption(Disable);
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
@@ -398,13 +397,13 @@ unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
CXString clang_getDiagnosticCategoryName(unsigned Category) {
// Kept for backwards compatibility.
- return createCXString(DiagnosticIDs::getCategoryNameFromID(Category));
+ return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
}
CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getCategoryText();
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
@@ -432,7 +431,7 @@ CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
if (!D || FixIt >= D->getNumFixIts()) {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
- return createCXString("");
+ return cxstring::createEmpty();
}
return D->getFixIt(FixIt, ReplacementRange);
}
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index ec76898..2a55af5 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -8,19 +8,21 @@
//===----------------------------------------------------------------------===//
#include "CursorVisitor.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
#include "CXTranslationUnit.h"
-
-#include "clang/Frontend/ASTUnit.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace cxcursor;
+using namespace cxindex;
static void getTopOverriddenMethods(CXTranslationUnit TU,
- Decl *D,
- SmallVectorImpl<Decl *> &Methods) {
+ const Decl *D,
+ SmallVectorImpl<const Decl *> &Methods) {
if (!D)
return;
if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
@@ -44,15 +46,15 @@ namespace {
struct FindFileIdRefVisitData {
CXTranslationUnit TU;
FileID FID;
- Decl *Dcl;
+ const Decl *Dcl;
int SelectorIdIdx;
CXCursorAndRangeVisitor visitor;
- typedef SmallVector<Decl *, 8> TopMethodsTy;
+ typedef SmallVector<const Decl *, 8> TopMethodsTy;
TopMethodsTy TopMethods;
FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID,
- Decl *D, int selectorIdIdx,
+ const Decl *D, int selectorIdIdx,
CXCursorAndRangeVisitor visitor)
: TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) {
Dcl = getCanonical(D);
@@ -60,7 +62,7 @@ struct FindFileIdRefVisitData {
}
ASTContext &getASTContext() const {
- return static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ return cxtu::getASTUnit(TU)->getASTContext();
}
/// \brief We are looking to find all semantically relevant identifiers,
@@ -74,24 +76,25 @@ struct FindFileIdRefVisitData {
///
/// 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 {
+ const Decl *getCanonical(const Decl *D) const {
if (!D)
return 0;
D = D->getCanonicalDecl();
- if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) {
+ if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) {
if (ImplD->getClassInterface())
return getCanonical(ImplD->getClassInterface());
- } else if (CXXConstructorDecl *CXXCtorD = dyn_cast<CXXConstructorDecl>(D)) {
+ } else if (const CXXConstructorDecl *CXXCtorD =
+ dyn_cast<CXXConstructorDecl>(D)) {
return getCanonical(CXXCtorD->getParent());
}
return D;
}
- bool isHit(Decl *D) const {
+ bool isHit(const Decl *D) const {
if (!D)
return false;
@@ -106,7 +109,7 @@ struct FindFileIdRefVisitData {
}
private:
- bool isOverriddingMethod(Decl *D) const {
+ bool isOverriddingMethod(const Decl *D) const {
if (std::find(TopMethods.begin(), TopMethods.end(), D) !=
TopMethods.end())
return true;
@@ -148,7 +151,7 @@ static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
if (!clang_isDeclaration(declCursor.kind))
return CXChildVisit_Recurse;
- Decl *D = cxcursor::getCursorDecl(declCursor);
+ const Decl *D = cxcursor::getCursorDecl(declCursor);
if (!D)
return CXChildVisit_Continue;
@@ -202,32 +205,31 @@ static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
return CXChildVisit_Recurse;
}
- data->visitor.visit(data->visitor.context, cursor,
- cxloc::translateSourceRange(Ctx, Loc));
+ if (data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
}
return CXChildVisit_Recurse;
}
-static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
- const FileEntry *File,
- CXCursorAndRangeVisitor Visitor) {
+static bool findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
+ const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
assert(clang_isDeclaration(declCursor.kind));
- ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
- SourceManager &SM = Unit->getSourceManager();
+ SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
FileID FID = SM.translateFile(File);
- Decl *Dcl = cxcursor::getCursorDecl(declCursor);
+ const Decl *Dcl = cxcursor::getCursorDecl(declCursor);
if (!Dcl)
- return;
+ return false;
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 (const DeclContext *DC = Dcl->getParentFunctionOrMethod()) {
+ return clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU),
+ findFileIdRefVisit, &data);
}
SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
@@ -237,7 +239,7 @@ static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
/*VisitIncludedEntities=*/false,
Range,
/*VisitDeclsOnly=*/true);
- FindIdRefsVisitor.visitFileRegion();
+ return FindIdRefsVisitor.visitFileRegion();
}
namespace {
@@ -267,7 +269,7 @@ static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
if (cursor.kind == CXCursor_MacroDefinition)
Macro = getCursorMacroDefinition(cursor)->getName();
else if (cursor.kind == CXCursor_MacroExpansion)
- Macro = getCursorMacroExpansion(cursor)->getName();
+ Macro = getCursorMacroExpansion(cursor).getName();
if (!Macro)
return CXChildVisit_Continue;
@@ -298,19 +300,20 @@ static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
return CXChildVisit_Continue;
}
- data->visitor.visit(data->visitor.context, cursor,
- cxloc::translateSourceRange(Ctx, Loc));
+ if (data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
return CXChildVisit_Continue;
}
-static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
+static bool findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
const FileEntry *File,
CXCursorAndRangeVisitor Visitor) {
if (Cursor.kind != CXCursor_MacroDefinition &&
Cursor.kind != CXCursor_MacroExpansion)
- return;
+ return false;
- ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
FileID FID = SM.translateFile(File);
@@ -318,9 +321,9 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
if (Cursor.kind == CXCursor_MacroDefinition)
Macro = getCursorMacroDefinition(Cursor)->getName();
else
- Macro = getCursorMacroExpansion(Cursor)->getName();
+ Macro = getCursorMacroExpansion(Cursor).getName();
if (!Macro)
- return;
+ return false;
FindFileMacroRefVisitData data(*Unit, File, Macro, Visitor);
@@ -330,7 +333,73 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
/*VisitPreprocessorLast=*/false,
/*VisitIncludedEntities=*/false,
Range);
- FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
+ return FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
+}
+
+namespace {
+
+struct FindFileIncludesVisitor {
+ ASTUnit &Unit;
+ const FileEntry *File;
+ CXCursorAndRangeVisitor visitor;
+
+ FindFileIncludesVisitor(ASTUnit &Unit, const FileEntry *File,
+ CXCursorAndRangeVisitor visitor)
+ : Unit(Unit), File(File), visitor(visitor) { }
+
+ ASTContext &getASTContext() const {
+ return Unit.getASTContext();
+ }
+
+ enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+ if (cursor.kind != CXCursor_InclusionDirective)
+ return CXChildVisit_Continue;
+
+ SourceLocation
+ Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
+
+ ASTContext &Ctx = getASTContext();
+ SourceManager &SM = Ctx.getSourceManager();
+
+ // We are looking for includes in a specific file.
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+ if (SM.getFileEntryForID(LocInfo.first) != File)
+ return CXChildVisit_Continue;
+
+ if (visitor.visit(visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
+ return CXChildVisit_Continue;
+ }
+
+ static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent,
+ CXClientData client_data) {
+ return static_cast<FindFileIncludesVisitor*>(client_data)->
+ visit(cursor, parent);
+ }
+};
+
+} // anonymous namespace
+
+static bool findIncludesInFile(CXTranslationUnit TU, const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
+ assert(TU && File && Visitor.visit);
+
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ SourceManager &SM = Unit->getSourceManager();
+
+ FileID FID = SM.translateFile(File);
+
+ FindFileIncludesVisitor IncludesVisitor(*Unit, File, Visitor);
+
+ SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
+ CursorVisitor InclusionCursorsVisitor(TU,
+ FindFileIncludesVisitor::visit,
+ &IncludesVisitor,
+ /*VisitPreprocessorLast=*/false,
+ /*VisitIncludedEntities=*/false,
+ Range);
+ return InclusionCursorsVisitor.visitPreprocessedEntitiesInRegion();
}
@@ -340,44 +409,48 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
extern "C" {
-void clang_findReferencesInFile(CXCursor cursor, CXFile file,
- CXCursorAndRangeVisitor visitor) {
- bool Logging = ::getenv("LIBCLANG_LOGGING");
+CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
if (clang_Cursor_isNull(cursor)) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null cursor\n";
- return;
+ if (Log)
+ *Log << "Null cursor";
+ return CXResult_Invalid;
}
if (cursor.kind == CXCursor_NoDeclFound) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Got CXCursor_NoDeclFound\n";
- return;
+ if (Log)
+ *Log << "Got CXCursor_NoDeclFound";
+ return CXResult_Invalid;
}
if (!file) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null file\n";
- return;
+ if (Log)
+ *Log << "Null file";
+ return CXResult_Invalid;
}
if (!visitor.visit) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null visitor\n";
- return;
+ if (Log)
+ *Log << "Null visitor";
+ return CXResult_Invalid;
}
+ if (Log)
+ *Log << cursor << " @" << static_cast<const FileEntry *>(file);
+
ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
if (!CXXUnit)
- return;
+ return CXResult_Invalid;
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
if (cursor.kind == CXCursor_MacroDefinition ||
cursor.kind == CXCursor_MacroExpansion) {
- findMacroRefsInFile(cxcursor::getCursorTU(cursor),
- cursor,
- static_cast<const FileEntry *>(file),
- visitor);
- return;
+ if (findMacroRefsInFile(cxcursor::getCursorTU(cursor),
+ cursor,
+ static_cast<const FileEntry *>(file),
+ visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
}
// We are interested in semantics of identifiers so for C++ constructor exprs
@@ -392,16 +465,51 @@ void clang_findReferencesInFile(CXCursor cursor, CXFile file,
CXCursor refCursor = clang_getCursorReferenced(cursor);
if (!clang_isDeclaration(refCursor.kind)) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: cursor is not referencing a "
- "declaration\n";
- return;
+ if (Log)
+ *Log << "cursor is not referencing a declaration";
+ return CXResult_Invalid;
}
- findIdRefsInFile(cxcursor::getCursorTU(cursor),
- refCursor,
- static_cast<const FileEntry *>(file),
- visitor);
+ if (findIdRefsInFile(cxcursor::getCursorTU(cursor),
+ refCursor,
+ static_cast<const FileEntry *>(file),
+ visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
+}
+
+CXResult clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
+
+ if (!TU) {
+ if (Log)
+ *Log << "Null CXTranslationUnit";
+ return CXResult_Invalid;
+ }
+ if (!file) {
+ if (Log)
+ *Log << "Null file";
+ return CXResult_Invalid;
+ }
+ if (!visitor.visit) {
+ if (Log)
+ *Log << "Null visitor";
+ return CXResult_Invalid;
+ }
+
+ if (Log)
+ *Log << TU << " @" << static_cast<const FileEntry *>(file);
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+ if (!CXXUnit)
+ return CXResult_Invalid;
+
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ if (findIncludesInFile(TU, static_cast<const FileEntry *>(file), visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
}
static enum CXVisitorResult _visitCursorAndRange(void *context,
@@ -411,13 +519,21 @@ static enum CXVisitorResult _visitCursorAndRange(void *context,
return INVOKE_BLOCK2(block, cursor, range);
}
-void clang_findReferencesInFileWithBlock(CXCursor cursor,
- CXFile file,
- CXCursorAndRangeVisitorBlock block) {
+CXResult clang_findReferencesInFileWithBlock(CXCursor cursor,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
CXCursorAndRangeVisitor visitor = { block,
block ? _visitCursorAndRange : 0 };
return clang_findReferencesInFile(cursor, file, visitor);
}
+CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit TU,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
+ CXCursorAndRangeVisitor visitor = { block,
+ block ? _visitCursorAndRange : 0 };
+ return clang_findIncludesInFile(TU, file, visitor);
+}
+
} // end: extern "C"
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 848ca31..a6d3115 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
#include "CXSourceLocation.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/SmallString.h"
@@ -25,7 +25,7 @@ extern "C" {
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
CXClientData clientData) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
@@ -64,7 +64,8 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
// Callback to the client.
// FIXME: We should have a function to construct CXFiles.
- CB((CXFile) FI.getContentCache()->OrigEntry,
+ CB(static_cast<CXFile>(
+ const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)),
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 6140032..a911ce5 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -22,14 +22,13 @@
#include "llvm/Support/raw_ostream.h"
using namespace clang;
-using namespace clang::cxstring;
//===----------------------------------------------------------------------===//
// USR generation.
//===----------------------------------------------------------------------===//
namespace {
-class USRGenerator : public DeclVisitor<USRGenerator> {
+class USRGenerator : public ConstDeclVisitor<USRGenerator> {
OwningPtr<SmallString<128> > OwnedBuf;
SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
@@ -67,37 +66,37 @@ public:
bool ignoreResults() const { return IgnoreResults; }
// Visitation methods from generating USRs from AST elements.
- void VisitDeclContext(DeclContext *D);
- void VisitFieldDecl(FieldDecl *D);
- void VisitFunctionDecl(FunctionDecl *D);
- void VisitNamedDecl(NamedDecl *D);
- void VisitNamespaceDecl(NamespaceDecl *D);
- void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void VisitObjCContainerDecl(ObjCContainerDecl *CD);
- void VisitObjCMethodDecl(ObjCMethodDecl *MD);
- void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitTagDecl(TagDecl *D);
- void VisitTypedefDecl(TypedefDecl *D);
- void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- void VisitVarDecl(VarDecl *D);
- void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- void VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+ void VisitDeclContext(const DeclContext *D);
+ void VisitFieldDecl(const FieldDecl *D);
+ void VisitFunctionDecl(const FunctionDecl *D);
+ void VisitNamedDecl(const NamedDecl *D);
+ void VisitNamespaceDecl(const NamespaceDecl *D);
+ void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
+ void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
+ void VisitClassTemplateDecl(const ClassTemplateDecl *D);
+ void VisitObjCContainerDecl(const ObjCContainerDecl *CD);
+ void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
+ void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
+ void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
+ void VisitTagDecl(const TagDecl *D);
+ void VisitTypedefDecl(const TypedefDecl *D);
+ void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
+ void VisitVarDecl(const VarDecl *D);
+ void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
+ void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
+ void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
IgnoreResults = true;
}
- void VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
IgnoreResults = true;
}
- void VisitUsingDecl(UsingDecl *D) {
+ void VisitUsingDecl(const UsingDecl *D) {
IgnoreResults = true;
}
- void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+ void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
IgnoreResults = true;
}
- void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
IgnoreResults = true;
}
@@ -151,25 +150,19 @@ bool USRGenerator::EmitDeclName(const NamedDecl *D) {
return startSize == endSize;
}
-static bool InAnonymousNamespace(const Decl *D) {
- if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext()))
- return ND->isAnonymousNamespace();
- return false;
-}
-
static inline bool ShouldGenerateLocation(const NamedDecl *D) {
- return D->getLinkage() != ExternalLinkage && !InAnonymousNamespace(D);
+ return D->getLinkage() != ExternalLinkage;
}
-void USRGenerator::VisitDeclContext(DeclContext *DC) {
- if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
+void USRGenerator::VisitDeclContext(const DeclContext *DC) {
+ if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
Visit(D);
}
-void USRGenerator::VisitFieldDecl(FieldDecl *D) {
+void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
// The USR for an ivar declared in a class extension is based on the
// ObjCInterfaceDecl, not the ObjCCategoryDecl.
- if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
Visit(ID);
else
VisitDeclContext(D->getDeclContext());
@@ -181,7 +174,7 @@ void USRGenerator::VisitFieldDecl(FieldDecl *D) {
}
}
-void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
+void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
if (ShouldGenerateLocation(D) && GenLoc(D))
return;
@@ -208,7 +201,8 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
}
// Mangle in type information for the arguments.
- for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ for (FunctionDecl::param_const_iterator I = D->param_begin(),
+ E = D->param_end();
I != E; ++I) {
Out << '#';
if (ParmVarDecl *PD = *I)
@@ -217,7 +211,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
if (D->isVariadic())
Out << '.';
Out << '#';
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
if (MD->isStatic())
Out << 'S';
if (unsigned quals = MD->getTypeQualifiers())
@@ -225,7 +219,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
}
}
-void USRGenerator::VisitNamedDecl(NamedDecl *D) {
+void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
VisitDeclContext(D->getDeclContext());
Out << "@";
@@ -238,7 +232,7 @@ void USRGenerator::VisitNamedDecl(NamedDecl *D) {
}
}
-void USRGenerator::VisitVarDecl(VarDecl *D) {
+void USRGenerator::VisitVarDecl(const VarDecl *D) {
// VarDecls can be declared 'extern' within a function or method body,
// but their enclosing DeclContext is the function, not the TU. We need
// to check the storage class to correctly generate the USR.
@@ -260,17 +254,19 @@ void USRGenerator::VisitVarDecl(VarDecl *D) {
Out << '@' << s;
}
-void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+void USRGenerator::VisitNonTypeTemplateParmDecl(
+ const NonTypeTemplateParmDecl *D) {
GenLoc(D);
return;
}
-void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+void USRGenerator::VisitTemplateTemplateParmDecl(
+ const TemplateTemplateParmDecl *D) {
GenLoc(D);
return;
}
-void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
if (D->isAnonymousNamespace()) {
Out << "@aN";
return;
@@ -281,29 +277,29 @@ void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
Out << "@N@" << D->getName();
}
-void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
VisitFunctionDecl(D->getTemplatedDecl());
}
-void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
VisitTagDecl(D->getTemplatedDecl());
}
-void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
VisitDeclContext(D->getDeclContext());
if (!IgnoreResults)
Out << "@NA@" << D->getName();
}
-void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
- DeclContext *container = D->getDeclContext();
- if (ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
+void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+ const DeclContext *container = D->getDeclContext();
+ if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
Visit(pd);
}
else {
// The USR for a method declared in a class extension or category is based on
// the ObjCInterfaceDecl, not the ObjCCategoryDecl.
- ObjCInterfaceDecl *ID = D->getClassInterface();
+ const ObjCInterfaceDecl *ID = D->getClassInterface();
if (!ID) {
IgnoreResults = true;
return;
@@ -318,7 +314,7 @@ void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
N.printName(Out);
}
-void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) {
switch (D->getKind()) {
default:
llvm_unreachable("Invalid ObjC container.");
@@ -327,8 +323,8 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
GenObjCClass(D->getName());
break;
case Decl::ObjCCategory: {
- ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
- ObjCInterfaceDecl *ID = CD->getClassInterface();
+ const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
+ const ObjCInterfaceDecl *ID = CD->getClassInterface();
if (!ID) {
// Handle invalid code where the @interface might not
// have been specified.
@@ -349,8 +345,8 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
break;
}
case Decl::ObjCCategoryImpl: {
- ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
- ObjCInterfaceDecl *ID = CD->getClassInterface();
+ const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
+ const ObjCInterfaceDecl *ID = CD->getClassInterface();
if (!ID) {
// Handle invalid code where the @interface might not
// have been specified.
@@ -368,17 +364,17 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
}
}
-void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
// The USR for a property declared in a class extension or category is based
// on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
- if (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
Visit(ID);
else
Visit(cast<Decl>(D->getDeclContext()));
GenObjCProperty(D->getName());
}
-void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
VisitObjCPropertyDecl(PD);
return;
@@ -387,7 +383,7 @@ void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
IgnoreResults = true;
}
-void USRGenerator::VisitTagDecl(TagDecl *D) {
+void USRGenerator::VisitTagDecl(const TagDecl *D) {
// Add the location of the tag decl to handle resolution across
// translation units.
if (ShouldGenerateLocation(D) && GenLoc(D))
@@ -397,7 +393,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
VisitDeclContext(D->getDeclContext());
bool AlreadyStarted = false;
- if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+ if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
AlreadyStarted = true;
@@ -409,7 +405,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
case TTK_Enum: llvm_unreachable("enum template");
}
VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
- } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
AlreadyStarted = true;
@@ -449,7 +445,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
}
// For a class template specialization, mangle the template arguments.
- if (ClassTemplateSpecializationDecl *Spec
+ if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(D)) {
const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
Out << '>';
@@ -460,17 +456,17 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
}
}
-void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
if (ShouldGenerateLocation(D) && GenLoc(D))
return;
- DeclContext *DC = D->getDeclContext();
- if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
+ const DeclContext *DC = D->getDeclContext();
+ if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
Visit(DCN);
Out << "@T@";
Out << D->getName();
}
-void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
GenLoc(D);
return;
}
@@ -593,6 +589,14 @@ void USRGenerator::VisitType(QualType T) {
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
case BuiltinType::Dependent:
+ case BuiltinType::OCLImage1d:
+ case BuiltinType::OCLImage1dArray:
+ case BuiltinType::OCLImage1dBuffer:
+ case BuiltinType::OCLImage2d:
+ case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage3d:
+ case BuiltinType::OCLEvent:
+ case BuiltinType::OCLSampler:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
@@ -806,7 +810,7 @@ bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
return true;
USRGenerator UG(&D->getASTContext(), &Buf);
- UG->Visit(const_cast<Decl*>(D));
+ UG->Visit(D);
if (UG->ignoreResults())
return true;
@@ -820,22 +824,22 @@ CXString clang_getCursorUSR(CXCursor C) {
const CXCursorKind &K = clang_getCursorKind(C);
if (clang_isDeclaration(K)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
- return createCXString("");
+ return cxstring::createEmpty();
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
- return createCXString("");
+ return cxstring::createEmpty();
bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
if (Ignore) {
- disposeCXStringBuf(buf);
- return createCXString("");
+ buf->dispose();
+ return cxstring::createEmpty();
}
// Return the C-string, but don't make a copy since it is already in
@@ -847,11 +851,11 @@ CXString clang_getCursorUSR(CXCursor C) {
if (K == CXCursor_MacroDefinition) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
- return createCXString("");
+ return cxstring::createEmpty();
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
- return createCXString("");
+ return cxstring::createEmpty();
{
USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
@@ -863,14 +867,14 @@ CXString clang_getCursorUSR(CXCursor C) {
return createCXString(buf);
}
- return createCXString("");
+ return cxstring::createEmpty();
}
CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCIvar(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCMethod(const char *name,
@@ -879,26 +883,26 @@ CXString clang_constructUSR_ObjCMethod(const char *name,
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCMethod(name, isInstanceMethod);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCClass(const char *name) {
USRGenerator UG;
UG->GenObjCClass(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCProtocol(const char *name) {
USRGenerator UG;
UG->GenObjCProtocol(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCCategory(const char *class_name,
const char *category_name) {
USRGenerator UG;
UG->GenObjCCategory(class_name, category_name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCProperty(const char *property,
@@ -906,7 +910,7 @@ CXString clang_constructUSR_ObjCProperty(const char *property,
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCProperty(property);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
} // end extern "C"
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index d458789..d89e0a4 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-
#include "clang/AST/Decl.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
@@ -24,12 +23,11 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
-
+#include "llvm/Support/raw_ostream.h"
#include <cstdio>
-#include <vector>
#include <sstream>
+#include <vector>
#ifdef __CYGWIN__
#include <cygwin/version.h>
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 1e5fb82..08162c5 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -26,6 +26,11 @@ namespace llvm {
namespace clang {
class ASTUnit;
+ class MacroInfo;
+ class MacroDefinition;
+ class SourceLocation;
+ class Token;
+ class IdentifierInfo;
class CIndexer {
bool OnlyLocalDecls;
@@ -33,7 +38,6 @@ class CIndexer {
unsigned Options; // CXGlobalOptFlags.
llvm::sys::Path ResourcesPath;
- std::string WorkingDir;
public:
CIndexer() : OnlyLocalDecls(false), DisplayDiagnostics(false),
@@ -59,9 +63,6 @@ public:
/// \brief Get the path of the clang resource files.
std::string getClangResourcesPath();
-
- const std::string &getWorkingDirectory() const { return WorkingDir; }
- void setWorkingDirectory(const std::string &Dir) { WorkingDir = Dir; }
};
/**
@@ -98,6 +99,30 @@ public:
namespace cxindex {
void printDiagsToStderr(ASTUnit *Unit);
+
+ /// \brief If \c MacroDefLoc points at a macro definition with \c II as
+ /// its name, this retrieves its MacroInfo.
+ MacroInfo *getMacroInfo(const IdentifierInfo &II,
+ SourceLocation MacroDefLoc,
+ CXTranslationUnit TU);
+
+ /// \brief Retrieves the corresponding MacroInfo of a MacroDefinition.
+ const MacroInfo *getMacroInfo(const MacroDefinition *MacroDef,
+ CXTranslationUnit TU);
+
+ /// \brief If \c Loc resides inside the definition of \c MI and it points at
+ /// an identifier that has ever been a macro name, this returns the latest
+ /// MacroDefinition for that name, otherwise it returns NULL.
+ MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU);
+
+ /// \brief If \c Tok resides inside the definition of \c MI and it points at
+ /// an identifier that has ever been a macro name, this returns the latest
+ /// MacroDefinition for that name, otherwise it returns NULL.
+ MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ const Token &Tok,
+ CXTranslationUnit TU);
}
}
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
new file mode 100644
index 0000000..57e01ae
--- /dev/null
+++ b/tools/libclang/CLog.h
@@ -0,0 +1,101 @@
+//===- CLog.h - Logging Interface -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBCLANG_CLOG_H
+#define LLVM_LIBCLANG_CLOG_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+namespace llvm {
+class format_object_base;
+}
+
+namespace clang {
+ class FileEntry;
+
+namespace cxindex {
+
+class Logger;
+typedef IntrusiveRefCntPtr<Logger> LogRef;
+
+/// \brief Collects logging output and writes it to stderr when it's destructed.
+/// Common use case:
+/// \code
+/// if (LogRef Log = Logger::make(__func__)) {
+/// *Log << "stuff";
+/// }
+/// \endcode
+class Logger : public RefCountedBase<Logger> {
+ std::string Name;
+ bool Trace;
+ SmallString<64> Msg;
+ llvm::raw_svector_ostream LogOS;
+public:
+ static const char *getEnvVar() {
+ static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
+ return sCachedVar;
+ }
+ static bool isLoggingEnabled() { return getEnvVar() != 0; }
+ static bool isStackTracingEnabled() {
+ if (const char *EnvOpt = Logger::getEnvVar())
+ return llvm::StringRef(EnvOpt) == "2";
+ return false;
+ }
+ static LogRef make(llvm::StringRef name,
+ bool trace = isStackTracingEnabled()) {
+ if (isLoggingEnabled())
+ return new Logger(name, trace);
+ return 0;
+ }
+
+ explicit Logger(llvm::StringRef name, bool trace)
+ : Name(name), Trace(trace), LogOS(Msg) { }
+ ~Logger();
+
+ Logger &operator<<(CXTranslationUnit);
+ Logger &operator<<(const FileEntry *FE);
+ Logger &operator<<(CXCursor cursor);
+ Logger &operator<<(CXSourceLocation);
+ Logger &operator<<(CXSourceRange);
+ Logger &operator<<(CXString);
+ Logger &operator<<(llvm::StringRef Str) { LogOS << Str; return *this; }
+ Logger &operator<<(const char *Str) {
+ if (Str)
+ LogOS << Str;
+ return *this;
+ }
+ Logger &operator<<(unsigned long N) { LogOS << N; return *this; }
+ Logger &operator<<(long N) { LogOS << N ; return *this; }
+ Logger &operator<<(unsigned int N) { LogOS << N; return *this; }
+ Logger &operator<<(int N) { LogOS << N; return *this; }
+ Logger &operator<<(char C) { LogOS << C; return *this; }
+ Logger &operator<<(unsigned char C) { LogOS << C; return *this; }
+ Logger &operator<<(signed char C) { LogOS << C; return *this; }
+ Logger &operator<<(const llvm::format_object_base &Fmt);
+};
+
+}
+}
+
+/// \brief Macros to automate common uses of Logger. Like this:
+/// \code
+/// LOG_FUNC_SECTION {
+/// *Log << "blah";
+/// }
+/// \endcode
+#define LOG_SECTION(NAME) if (LogRef Log = clang::cxindex::Logger::make(NAME))
+#define LOG_FUNC_SECTION LOG_SECTION(LLVM_FUNCTION_NAME)
+
+#endif
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 1426c42..c5a975b 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
asmparser
support
+ bitreader
mc
)
@@ -38,6 +39,7 @@ set(SOURCES
Indexing.cpp
IndexingContext.cpp
IndexingContext.h
+ SimpleFormatContext.h
../../include/clang-c/Index.h
)
@@ -54,6 +56,7 @@ set(LIBRARIES
clangLex
clangTooling
clangBasic
+ clangFormat
)
set(GENERATED_HEADERS
@@ -71,7 +74,7 @@ if( LLVM_ENABLE_PIC )
set(SHARED_LIBRARY TRUE)
add_clang_library(libclang ${SOURCES})
target_link_libraries(libclang ${LIBRARIES})
- add_dependencies(libclang ${GENERATED_HEADERS})
+ add_dependencies(libclang ${GENERATED_HEADERS} clang-headers)
if(WIN32)
set_target_properties(libclang
@@ -105,7 +108,7 @@ endif()
if( NOT BUILD_SHARED_LIBS AND NOT WIN32 )
add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBRARIES})
- add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS})
+ add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS} clang-headers)
set_target_properties(${LIBCLANG_STATIC_TARGET_NAME}
PROPERTIES
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index fa149a0..1c127e1 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -12,23 +12,23 @@
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
-#include "CXString.h"
#include "CXComment.h"
#include "CXCursor.h"
-
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/CommentVisitor.h"
+#include "CXString.h"
+#include "SimpleFormatContext.h"
#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/CommentVisitor.h"
#include "clang/AST/Decl.h"
-
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-
#include <climits>
using namespace clang;
-using namespace clang::cxstring;
using namespace clang::comments;
using namespace clang::cxcomment;
@@ -123,18 +123,18 @@ unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
CXString clang_TextComment_getText(CXComment CXC) {
const TextComment *TC = getASTNodeAs<TextComment>(CXC);
if (!TC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(TC->getText(), /*DupString=*/ false);
+ return cxstring::createRef(TC->getText());
}
CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
- return createCXString(ICC->getCommandName(Traits), /*DupString=*/ false);
+ return cxstring::createRef(ICC->getCommandName(Traits));
}
enum CXCommentInlineCommandRenderKind
@@ -171,17 +171,17 @@ CXString clang_InlineCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC || ArgIdx >= ICC->getNumArgs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(ICC->getArgText(ArgIdx), /*DupString=*/ false);
+ return cxstring::createRef(ICC->getArgText(ArgIdx));
}
CXString clang_HTMLTagComment_getTagName(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HTC->getTagName(), /*DupString=*/ false);
+ return cxstring::createRef(HTC->getTagName());
}
unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
@@ -203,26 +203,26 @@ unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HST->getAttr(AttrIdx).Name, /*DupString=*/ false);
+ return cxstring::createRef(HST->getAttr(AttrIdx).Name);
}
CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HST->getAttr(AttrIdx).Value, /*DupString=*/ false);
+ return cxstring::createRef(HST->getAttr(AttrIdx).Value);
}
CXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
- return createCXString(BCC->getCommandName(Traits), /*DupString=*/ false);
+ return cxstring::createRef(BCC->getCommandName(Traits));
}
unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
@@ -237,9 +237,9 @@ CXString clang_BlockCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC || ArgIdx >= BCC->getNumArgs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(BCC->getArgText(ArgIdx), /*DupString=*/ false);
+ return cxstring::createRef(BCC->getArgText(ArgIdx));
}
CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
@@ -253,9 +253,9 @@ CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC || !PCC->hasParamName())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(PCC->getParamNameAsWritten(), /*DupString=*/ false);
+ return cxstring::createRef(PCC->getParamNameAsWritten());
}
unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
@@ -304,9 +304,9 @@ enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC || !TPCC->hasParamName())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(TPCC->getParamNameAsWritten(), /*DupString=*/ false);
+ return cxstring::createRef(TPCC->getParamNameAsWritten());
}
unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
@@ -337,17 +337,17 @@ CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
const VerbatimBlockLineComment *VBL =
getASTNodeAs<VerbatimBlockLineComment>(CXC);
if (!VBL)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(VBL->getText(), /*DupString=*/ false);
+ return cxstring::createRef(VBL->getText());
}
CXString clang_VerbatimLineComment_getText(CXComment CXC) {
const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
if (!VLC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(VLC->getText(), /*DupString=*/ false);
+ return cxstring::createRef(VLC->getText());
}
} // end extern "C"
@@ -410,6 +410,7 @@ struct FullCommentParts {
const CommandTraits &Traits);
const BlockContentComment *Brief;
+ const BlockContentComment *Headerfile;
const ParagraphComment *FirstParagraph;
const BlockCommandComment *Returns;
SmallVector<const ParamCommandComment *, 8> Params;
@@ -419,7 +420,7 @@ struct FullCommentParts {
FullCommentParts::FullCommentParts(const FullComment *C,
const CommandTraits &Traits) :
- Brief(NULL), FirstParagraph(NULL), Returns(NULL) {
+ Brief(NULL), Headerfile(NULL), FirstParagraph(NULL), Returns(NULL) {
for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
I != E; ++I) {
const Comment *Child = *I;
@@ -447,6 +448,10 @@ FullCommentParts::FullCommentParts(const FullComment *C,
Brief = BCC;
break;
}
+ if (!Headerfile && Info->IsHeaderfileCommand) {
+ Headerfile = BCC;
+ break;
+ }
if (!Returns && Info->IsReturnsCommand) {
Returns = BCC;
break;
@@ -749,6 +754,8 @@ void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
FullCommentParts Parts(C, Traits);
bool FirstParagraphIsBrief = false;
+ if (Parts.Headerfile)
+ visit(Parts.Headerfile);
if (Parts.Brief)
visit(Parts.Brief);
else if (Parts.FirstParagraph) {
@@ -830,23 +837,23 @@ extern "C" {
CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
SmallString<128> HTML;
CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC));
Converter.visit(HTC);
- return createCXString(HTML.str(), /* DupString = */ true);
+ return cxstring::createDup(HTML.str());
}
CXString clang_FullComment_getAsHTML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
SmallString<1024> HTML;
CommentASTToHTMLConverter Converter(FC, HTML, getCommandTraits(CXC));
Converter.visit(FC);
- return createCXString(HTML.str(), /* DupString = */ true);
+ return cxstring::createDup(HTML.str());
}
} // end extern "C"
@@ -859,8 +866,12 @@ public:
CommentASTToXMLConverter(const FullComment *FC,
SmallVectorImpl<char> &Str,
const CommandTraits &Traits,
- const SourceManager &SM) :
- FC(FC), Result(Str), Traits(Traits), SM(SM) { }
+ const SourceManager &SM,
+ SimpleFormatContext &SFC,
+ unsigned FUID) :
+ FC(FC), Result(Str), Traits(Traits), SM(SM),
+ FormatRewriterContext(SFC),
+ FormatInMemoryUniqueId(FUID) { }
// Inline content.
void visitTextComment(const TextComment *C);
@@ -870,6 +881,10 @@ public:
// Block content.
void visitParagraphComment(const ParagraphComment *C);
+
+ void appendParagraphCommentWithKind(const ParagraphComment *C,
+ StringRef Kind);
+
void visitBlockCommandComment(const BlockCommandComment *C);
void visitParamCommandComment(const ParamCommandComment *C);
void visitTParamCommandComment(const TParamCommandComment *C);
@@ -882,6 +897,9 @@ public:
// Helpers.
void appendToResultWithXMLEscaping(StringRef S);
+ void formatTextOfDeclaration(const DeclInfo *DI,
+ SmallString<128> &Declaration);
+
private:
const FullComment *FC;
@@ -890,6 +908,8 @@ private:
const CommandTraits &Traits;
const SourceManager &SM;
+ SimpleFormatContext &FormatRewriterContext;
+ unsigned FormatInMemoryUniqueId;
};
void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
@@ -898,10 +918,40 @@ void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
const LangOptions &LangOpts = Context.getLangOpts();
llvm::raw_svector_ostream OS(Str);
PrintingPolicy PPolicy(LangOpts);
- PPolicy.SuppressAttributes = true;
+ PPolicy.PolishForDeclaration = true;
PPolicy.TerseOutput = true;
ThisDecl->CurrentDecl->print(OS, PPolicy,
- /*Indentation*/0, /*PrintInstantiation*/true);
+ /*Indentation*/0, /*PrintInstantiation*/false);
+}
+
+void CommentASTToXMLConverter::formatTextOfDeclaration(
+ const DeclInfo *DI,
+ SmallString<128> &Declaration) {
+ // FIXME. formatting API expects null terminated input string.
+ // There might be more efficient way of doing this.
+ std::string StringDecl = Declaration.str();
+
+ // Formatter specific code.
+ // Form a unique in memory buffer name.
+ SmallString<128> filename;
+ filename += "xmldecl";
+ filename += llvm::utostr(FormatInMemoryUniqueId);
+ filename += ".xd";
+ FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl);
+ SourceLocation Start =
+ FormatRewriterContext.Sources.getLocForStartOfFile(ID).getLocWithOffset(0);
+ unsigned Length = Declaration.size();
+
+ std::vector<CharSourceRange>
+ Ranges(1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
+ ASTContext &Context = DI->CurrentDecl->getASTContext();
+ const LangOptions &LangOpts = Context.getLangOpts();
+ Lexer Lex(ID, FormatRewriterContext.Sources.getBuffer(ID),
+ FormatRewriterContext.Sources, LangOpts);
+ tooling::Replacements Replace =
+ reformat(format::getLLVMStyle(), Lex, FormatRewriterContext.Sources, Ranges);
+ applyAllReplacements(Replace, FormatRewriterContext.Rewrite);
+ Declaration = FormatRewriterContext.getRewrittenText(ID);
}
} // end unnamed namespace
@@ -959,10 +1009,20 @@ void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C
}
void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
+ appendParagraphCommentWithKind(C, StringRef());
+}
+
+void CommentASTToXMLConverter::appendParagraphCommentWithKind(
+ const ParagraphComment *C,
+ StringRef ParagraphKind) {
if (C->isWhitespace())
return;
- Result << "<Para>";
+ if (ParagraphKind.empty())
+ Result << "<Para>";
+ else
+ Result << "<Para kind=\"" << ParagraphKind << "\">";
+
for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
I != E; ++I) {
visit(*I);
@@ -971,7 +1031,33 @@ void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C)
}
void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
- visit(C->getParagraph());
+ StringRef ParagraphKind;
+
+ switch (C->getCommandID()) {
+ case CommandTraits::KCI_attention:
+ case CommandTraits::KCI_author:
+ case CommandTraits::KCI_authors:
+ case CommandTraits::KCI_bug:
+ case CommandTraits::KCI_copyright:
+ case CommandTraits::KCI_date:
+ case CommandTraits::KCI_invariant:
+ case CommandTraits::KCI_note:
+ case CommandTraits::KCI_post:
+ case CommandTraits::KCI_pre:
+ case CommandTraits::KCI_remark:
+ case CommandTraits::KCI_remarks:
+ case CommandTraits::KCI_sa:
+ case CommandTraits::KCI_see:
+ case CommandTraits::KCI_since:
+ case CommandTraits::KCI_todo:
+ case CommandTraits::KCI_version:
+ case CommandTraits::KCI_warning:
+ ParagraphKind = C->getCommandName(Traits);
+ default:
+ break;
+ }
+
+ appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind);
}
void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
@@ -1022,9 +1108,14 @@ void CommentASTToXMLConverter::visitVerbatimBlockComment(
if (NumLines == 0)
return;
- Result << llvm::StringSwitch<const char *>(C->getCommandName(Traits))
- .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">")
- .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">");
+ switch (C->getCommandID()) {
+ case CommandTraits::KCI_code:
+ Result << "<Verbatim xml:space=\"preserve\" kind=\"code\">";
+ break;
+ default:
+ Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
+ break;
+ }
for (unsigned i = 0; i != NumLines; ++i) {
appendToResultWithXMLEscaping(C->getText(i));
if (i + 1 != NumLines)
@@ -1162,13 +1253,21 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
RootEndTag = "</Other>";
Result << "<Other><Name>unknown</Name>";
}
+
+ if (Parts.Headerfile) {
+ Result << "<Headerfile>";
+ visit(Parts.Headerfile);
+ Result << "</Headerfile>";
+ }
{
// Pretty-print the declaration.
Result << "<Declaration>";
SmallString<128> Declaration;
getSourceTextOfDeclaration(DI, Declaration);
+ formatTextOfDeclaration(DI, Declaration);
appendToResultWithXMLEscaping(Declaration);
+
Result << "</Declaration>";
}
@@ -1183,7 +1282,7 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
Result << "</Abstract>";
FirstParagraphIsBrief = true;
}
-
+
if (Parts.TParams.size() != 0) {
Result << "<TemplateParameters>";
for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
@@ -1322,15 +1421,26 @@ extern "C" {
CXString clang_FullComment_getAsXML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
- return createCXString((const char *) 0);
-
+ return cxstring::createNull();
+ ASTContext &Context = FC->getDeclInfo()->CurrentDecl->getASTContext();
CXTranslationUnit TU = CXC.TranslationUnit;
- SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
+ SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
+
+ if (!TU->FormatContext) {
+ TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
+ } else if ((TU->FormatInMemoryUniqueId % 1000) == 0) {
+ // Delete after some number of iterators, so the buffers don't grow
+ // too large.
+ delete TU->FormatContext;
+ TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
+ }
SmallString<1024> XML;
- CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM);
+ CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM,
+ *TU->FormatContext,
+ TU->FormatInMemoryUniqueId++);
Converter.visit(FC);
- return createCXString(XML.str(), /* DupString = */ true);
+ return cxstring::createDup(XML.str());
}
} // end extern "C"
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index 5134317..0780a65 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -14,11 +14,10 @@
#ifndef LLVM_CLANG_CXCOMMENT_H
#define LLVM_CLANG_CXCOMMENT_H
-#include "clang-c/Index.h"
#include "CXTranslationUnit.h"
-
-#include "clang/AST/Comment.h"
+#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Comment.h"
#include "clang/Frontend/ASTUnit.h"
namespace clang {
@@ -50,7 +49,7 @@ inline const T *getASTNodeAs(CXComment CXC) {
}
inline ASTContext &getASTContext(CXComment CXC) {
- return static_cast<ASTUnit *>(CXC.TranslationUnit->TUData)->getASTContext();
+ return cxtu::getASTUnit(CXC.TranslationUnit)->getASTContext();
}
inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 7bd319a..e35ac27 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -1,10 +1,9 @@
#include "clang-c/CXCompilationDatabase.h"
-#include "clang/Tooling/CompilationDatabase.h"
#include "CXString.h"
+#include "clang/Tooling/CompilationDatabase.h"
using namespace clang;
using namespace clang::tooling;
-using namespace clang::cxstring;
extern "C" {
@@ -59,6 +58,17 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
return 0;
}
+CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
+ if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
+ const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+ if (!CCmd.empty())
+ return new AllocatedCXCompileCommands( CCmd );
+ }
+
+ return 0;
+}
+
void
clang_CompileCommands_dispose(CXCompileCommands Cmds)
{
@@ -96,10 +106,10 @@ CXString
clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
{
if (!CCmd)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
- return createCXString(cmd->Directory);
+ return cxstring::createRef(cmd->Directory.c_str());
}
unsigned
@@ -115,14 +125,14 @@ CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
{
if (!CCmd)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
if (Arg >= Cmd->CommandLine.size())
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
- return createCXString(Cmd->CommandLine[Arg]);
+ return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
}
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 8d3e169..7b01ec2 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -15,9 +15,9 @@
#include "CXTranslationUnit.h"
#include "CXCursor.h"
-#include "CXType.h"
#include "CXString.h"
-#include "clang/Frontend/ASTUnit.h"
+#include "CXType.h"
+#include "clang-c/Index.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -25,7 +25,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang-c/Index.h"
+#include "clang/Frontend/ASTUnit.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -53,14 +53,14 @@ static CXCursorKind GetCursorKind(const Attr *A) {
return CXCursor_UnexposedAttr;
}
-CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
+CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
CXTranslationUnit TU) {
assert(A && Parent && TU && "Invalid arguments!");
- CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
+ CXCursor C = { GetCursorKind(A), 0, { Parent, A, TU } };
return C;
}
-CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
+CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
SourceRange RegionOfInterest,
bool FirstInDeclGroup) {
assert(D && TU && "Invalid arguments!");
@@ -89,7 +89,8 @@ CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
return C;
}
-CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
+CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
+ CXTranslationUnit TU,
SourceRange RegionOfInterest) {
assert(S && TU && "Invalid arguments!");
CXCursorKind K = CXCursor_NotImplemented;
@@ -493,34 +494,32 @@ CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
return C;
}
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCSuperClassRef);
- return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Proto && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCProtocolRef, 0, { (void*)Proto, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Proto, RawLoc, TU } };
return C;
}
-std::pair<ObjCProtocolDecl *, SourceLocation>
+std::pair<const ObjCProtocolDecl *, SourceLocation>
cxcursor::getCursorObjCProtocolRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCProtocolRef);
- return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCProtocolDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
@@ -530,50 +529,47 @@ CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
if (!Class)
return MakeCXCursorInvalid(CXCursor_InvalidCode);
assert(TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCClassRef, 0, { (void*)Class, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
return C;
}
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCClassRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCClassRef);
- return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Type && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TypeRef, 0, { (void*)Type, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
return C;
}
-std::pair<TypeDecl *, SourceLocation>
+std::pair<const TypeDecl *, SourceLocation>
cxcursor::getCursorTypeRef(CXCursor C) {
assert(C.kind == CXCursor_TypeRef);
- return std::make_pair(static_cast<TypeDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const TypeDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Template && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TemplateRef, 0, { (void*)Template, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
return C;
}
-std::pair<TemplateDecl *, SourceLocation>
+std::pair<const TemplateDecl *, SourceLocation>
cxcursor::getCursorTemplateRef(CXCursor C) {
assert(C.kind == CXCursor_TemplateRef);
- return std::make_pair(static_cast<TemplateDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const TemplateDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
@@ -582,69 +578,66 @@ CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
"Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_NamespaceRef, 0, { (void*)NS, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
return C;
}
-std::pair<NamedDecl *, SourceLocation>
+std::pair<const NamedDecl *, SourceLocation>
cxcursor::getCursorNamespaceRef(CXCursor C) {
assert(C.kind == CXCursor_NamespaceRef);
- return std::make_pair(static_cast<NamedDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const NamedDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Var && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_VariableRef, 0, { (void*)Var, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_VariableRef, 0, { Var, RawLoc, TU } };
return C;
}
-std::pair<VarDecl *, SourceLocation>
+std::pair<const VarDecl *, SourceLocation>
cxcursor::getCursorVariableRef(CXCursor C) {
assert(C.kind == CXCursor_VariableRef);
- return std::make_pair(static_cast<VarDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const VarDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Field && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_MemberRef, 0, { (void*)Field, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
return C;
}
-std::pair<FieldDecl *, SourceLocation>
+std::pair<const FieldDecl *, SourceLocation>
cxcursor::getCursorMemberRef(CXCursor C) {
assert(C.kind == CXCursor_MemberRef);
- return std::make_pair(static_cast<FieldDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const FieldDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
CXTranslationUnit TU){
- CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { (void*)B, 0, TU } };
+ CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
return C;
}
-CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
+const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
assert(C.kind == CXCursor_CXXBaseSpecifier);
- return static_cast<CXXBaseSpecifier*>(C.data[0]);
+ return static_cast<const CXXBaseSpecifier*>(C.data[0]);
}
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
CXTranslationUnit TU) {
CXCursor C = { CXCursor_PreprocessingDirective, 0,
- { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
- reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
+ { Range.getBegin().getPtrEncoding(),
+ Range.getEnd().getPtrEncoding(),
TU }
};
return C;
@@ -652,23 +645,21 @@ CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
assert(C.kind == CXCursor_PreprocessingDirective);
- SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t> (C.data[0])),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t> (C.data[1])));
+ SourceRange Range(SourceLocation::getFromPtrEncoding(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
ASTUnit *TU = getCursorASTUnit(C);
return TU->mapRangeFromPreamble(Range);
}
-CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
+CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinition *MI,
CXTranslationUnit TU) {
CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
return C;
}
-MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
+const MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
assert(C.kind == CXCursor_MacroDefinition);
- return static_cast<MacroDefinition *>(C.data[0]);
+ return static_cast<const MacroDefinition *>(C.data[0]);
}
CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
@@ -677,9 +668,28 @@ CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
return C;
}
-MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
- assert(C.kind == CXCursor_MacroExpansion);
- return static_cast<MacroExpansion *>(C.data[0]);
+CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinition *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU) {
+ assert(Loc.isValid());
+ CXCursor C = { CXCursor_MacroExpansion, 0, { MI, Loc.getPtrEncoding(), TU } };
+ return C;
+}
+
+const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
+ if (isPseudo())
+ return getAsMacroDefinition()->getName();
+ return getAsMacroExpansion()->getName();
+}
+const MacroDefinition *cxcursor::MacroExpansionCursor::getDefinition() const {
+ if (isPseudo())
+ return getAsMacroDefinition();
+ return getAsMacroExpansion()->getDefinition();
+}
+SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
+ if (isPseudo())
+ return getPseudoLoc();
+ return getAsMacroExpansion()->getSourceRange();
}
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
@@ -688,33 +698,32 @@ CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
return C;
}
-InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
+const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
assert(C.kind == CXCursor_InclusionDirective);
- return static_cast<InclusionDirective *>(C.data[0]);
+ return static_cast<const InclusionDirective *>(C.data[0]);
}
CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Label && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
return C;
}
-std::pair<LabelStmt*, SourceLocation>
+std::pair<const LabelStmt *, SourceLocation>
cxcursor::getCursorLabelRef(CXCursor C) {
assert(C.kind == CXCursor_LabelRef);
- return std::make_pair(static_cast<LabelStmt *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const LabelStmt *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
-CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
CXTranslationUnit TU) {
assert(E && TU && "Invalid arguments!");
OverloadedDeclRefStorage Storage(E);
- void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
+ void *RawLoc = E->getNameLoc().getPtrEncoding();
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
@@ -722,11 +731,11 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
return C;
}
-CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(D && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
OverloadedDeclRefStorage Storage(D);
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
@@ -739,7 +748,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
@@ -751,34 +760,34 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
assert(C.kind == CXCursor_OverloadedDeclRef);
- return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(
+ const_cast<void *>(C.data[0])),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
-Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
- return (Decl *)Cursor.data[0];
+const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
+ return static_cast<const Decl *>(Cursor.data[0]);
}
-Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
+const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
}
-Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
+const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
Cursor.kind == CXCursor_ObjCProtocolRef ||
Cursor.kind == CXCursor_ObjCClassRef)
return 0;
- return (Stmt *)Cursor.data[1];
+ return static_cast<const Stmt *>(Cursor.data[1]);
}
-Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
- return (Attr *)Cursor.data[1];
+const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
+ return static_cast<const Attr *>(Cursor.data[1]);
}
-Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
- return (Decl *)Cursor.data[0];
+const Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
+ return static_cast<const Decl *>(Cursor.data[0]);
}
ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
@@ -786,14 +795,14 @@ ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
}
ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
- CXTranslationUnit TU = static_cast<CXTranslationUnit>(Cursor.data[2]);
+ CXTranslationUnit TU = getCursorTU(Cursor);
if (!TU)
return 0;
- return static_cast<ASTUnit *>(TU->TUData);
+ return cxtu::getASTUnit(TU);
}
CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
- return static_cast<CXTranslationUnit>(Cursor.data[2]);
+ return static_cast<CXTranslationUnit>(const_cast<void*>(Cursor.data[2]));
}
void cxcursor::getOverriddenCursors(CXCursor cursor,
@@ -809,7 +818,7 @@ void cxcursor::getOverriddenCursors(CXCursor cursor,
for (SmallVector<const NamedDecl *, 8>::iterator
I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) {
- overridden.push_back(MakeCXCursor(const_cast<NamedDecl*>(*I), TU));
+ overridden.push_back(MakeCXCursor(*I, TU));
}
}
@@ -861,12 +870,13 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
if (cursor.xdata == 0)
return cursor;
- Expr *E = getCursorExpr(cursor);
+ const Expr *E = getCursorExpr(cursor);
TypeSourceInfo *Type = 0;
- if (CXXUnresolvedConstructExpr *
+ if (const CXXUnresolvedConstructExpr *
UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
Type = UnCtor->getTypeSourceInfo();
- } else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
+ } else if (const CXXTemporaryObjectExpr *Tmp =
+ dyn_cast<CXXTemporaryObjectExpr>(E)){
Type = Tmp->getTypeSourceInfo();
}
@@ -880,7 +890,7 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
Ty = ElabT->getNamedType();
- ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
+ ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
}
@@ -922,30 +932,48 @@ CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
int clang_Cursor_getNumArguments(CXCursor C) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
return MD->param_size();
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
return FD->param_size();
}
+ if (clang_isExpression(C.kind)) {
+ const Expr *E = cxcursor::getCursorExpr(C);
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ return CE->getNumArgs();
+ }
+ }
+
return -1;
}
CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
- if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
if (i < MD->param_size())
return cxcursor::MakeCXCursor(MD->param_begin()[i],
cxcursor::getCursorTU(C));
- } else if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
if (i < FD->param_size())
return cxcursor::MakeCXCursor(FD->param_begin()[i],
cxcursor::getCursorTU(C));
}
}
+ if (clang_isExpression(C.kind)) {
+ const Expr *E = cxcursor::getCursorExpr(C);
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ if (i < CE->getNumArgs()) {
+ return cxcursor::MakeCXCursor(CE->getArg(i),
+ getCursorDecl(C),
+ cxcursor::getCursorTU(C));
+ }
+ }
+ }
+
return clang_getNullCursor();
}
@@ -973,7 +1001,7 @@ public:
return MakeCXCursorInvalid(CXCursor_NoDeclFound);
}
static inline unsigned getHashValue(const CXCursor &cursor) {
- return llvm::DenseMapInfo<std::pair<void*,void*> >
+ return llvm::DenseMapInfo<std::pair<const void *, const void *> >
::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
}
static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
@@ -1018,10 +1046,10 @@ unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
enum CXCursorKind kind = clang_getCursorKind(cursor);
if (clang_isDeclaration(kind)) {
- Decl *decl = getCursorDecl(cursor);
- if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
+ const Decl *decl = getCursorDecl(cursor);
+ if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
ASTUnit *unit = getCursorASTUnit(cursor);
- CodeCompletionResult Result(namedDecl);
+ CodeCompletionResult Result(namedDecl, CCP_Declaration);
CodeCompletionString *String
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
@@ -1032,10 +1060,10 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
}
}
else if (kind == CXCursor_MacroDefinition) {
- MacroDefinition *definition = getCursorMacroDefinition(cursor);
+ const MacroDefinition *definition = getCursorMacroDefinition(cursor);
const IdentifierInfo *MacroInfo = definition->getName();
ASTUnit *unit = getCursorASTUnit(cursor);
- CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
+ CodeCompletionResult Result(MacroInfo);
CodeCompletionString *String
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
@@ -1050,7 +1078,7 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
namespace {
struct OverridenCursorsPool {
- typedef llvm::SmallVector<CXCursor, 2> CursorVec;
+ typedef SmallVector<CXCursor, 2> CursorVec;
std::vector<CursorVec*> AllCursors;
std::vector<CursorVec*> AvailableCursors;
@@ -1137,7 +1165,8 @@ void clang_disposeOverriddenCursors(CXCursor *overridden) {
// which has a back-reference to the TU and the vector.
--overridden;
OverridenCursorsPool::CursorVec *Vec =
- static_cast<OverridenCursorsPool::CursorVec*>(overridden->data[0]);
+ static_cast<OverridenCursorsPool::CursorVec *>(
+ const_cast<void *>(overridden->data[0]));
CXTranslationUnit TU = getCursorTU(*overridden);
assert(Vec && TU);
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 120b881..957d519 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -42,17 +42,18 @@ class TemplateDecl;
class TemplateName;
class TypeDecl;
class VarDecl;
+class IdentifierInfo;
namespace cxcursor {
CXCursor getCursor(CXTranslationUnit, SourceLocation);
-CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent,
+CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
CXTranslationUnit TU);
-CXCursor MakeCXCursor(clang::Decl *D, CXTranslationUnit TU,
+CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange(),
bool FirstInDeclGroup = true);
-CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent,
+CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = 0);
@@ -64,7 +65,7 @@ CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCSuperClassRef(CXCursor C);
/// \brief Create an Objective-C protocol reference at the given location.
@@ -74,7 +75,7 @@ CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCProtocolDecl *, SourceLocation>
+std::pair<const ObjCProtocolDecl *, SourceLocation>
getCursorObjCProtocolRef(CXCursor C);
/// \brief Create an Objective-C class reference at the given location.
@@ -84,7 +85,7 @@ CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
/// \brief Unpack an ObjCClassRef cursor into the class it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCClassRef(CXCursor C);
/// \brief Create a type reference at the given location.
@@ -93,7 +94,7 @@ CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
/// \brief Unpack a TypeRef cursor into the class it references
/// and optionally the location where the reference occurred.
-std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
+std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
/// \brief Create a reference to a template at the given location.
CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
@@ -101,7 +102,8 @@ CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
/// \brief Unpack a TemplateRef cursor into the template it references and
/// the location where the reference occurred.
-std::pair<TemplateDecl *, SourceLocation> getCursorTemplateRef(CXCursor C);
+std::pair<const TemplateDecl *, SourceLocation>
+ getCursorTemplateRef(CXCursor C);
/// \brief Create a reference to a namespace or namespace alias at the given
/// location.
@@ -110,7 +112,7 @@ CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc,
/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias
/// it references and the location where the reference occurred.
-std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
+std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
/// \brief Create a reference to a variable at the given location.
CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
@@ -118,7 +120,7 @@ CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
/// \brief Unpack a VariableRef cursor into the variable it references and the
/// location where the where the reference occurred.
-std::pair<VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
+std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
/// \brief Create a reference to a field at the given location.
CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
@@ -126,14 +128,14 @@ CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
/// \brief Unpack a MemberRef cursor into the field it references and the
/// location where the reference occurred.
-std::pair<FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
+std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
/// \brief Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
CXTranslationUnit TU);
/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
-CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
+const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
/// \brief Create a preprocessing directive cursor.
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
@@ -143,19 +145,62 @@ CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange getCursorPreprocessingDirective(CXCursor C);
/// \brief Create a macro definition cursor.
-CXCursor MakeMacroDefinitionCursor(MacroDefinition *, CXTranslationUnit TU);
+CXCursor MakeMacroDefinitionCursor(const MacroDefinition *,
+ CXTranslationUnit TU);
/// \brief Unpack a given macro definition cursor to retrieve its
/// source range.
-MacroDefinition *getCursorMacroDefinition(CXCursor C);
+const MacroDefinition *getCursorMacroDefinition(CXCursor C);
/// \brief Create a macro expansion cursor.
CXCursor MakeMacroExpansionCursor(MacroExpansion *,
CXTranslationUnit TU);
-/// \brief Unpack a given macro expansion cursor to retrieve its
-/// source range.
-MacroExpansion *getCursorMacroExpansion(CXCursor C);
+/// \brief Create a "pseudo" macro expansion cursor, using a macro definition
+/// and a source location.
+CXCursor MakeMacroExpansionCursor(MacroDefinition *, SourceLocation Loc,
+ CXTranslationUnit TU);
+
+/// \brief Wraps a macro expansion cursor and provides a common interface
+/// for a normal macro expansion cursor or a "pseudo" one.
+///
+/// "Pseudo" macro expansion cursors (essentially a macro definition along with
+/// a source location) are created in special cases, for example they can be
+/// created for identifiers inside macro definitions, if these identifiers are
+/// macro names.
+class MacroExpansionCursor {
+ CXCursor C;
+
+ bool isPseudo() const {
+ return C.data[1] != 0;
+ }
+ const MacroDefinition *getAsMacroDefinition() const {
+ assert(isPseudo());
+ return static_cast<const MacroDefinition *>(C.data[0]);
+ }
+ const MacroExpansion *getAsMacroExpansion() const {
+ assert(!isPseudo());
+ return static_cast<const MacroExpansion *>(C.data[0]);
+ }
+ SourceLocation getPseudoLoc() const {
+ assert(isPseudo());
+ return SourceLocation::getFromPtrEncoding(C.data[1]);
+ }
+
+public:
+ MacroExpansionCursor(CXCursor C) : C(C) {
+ assert(C.kind == CXCursor_MacroExpansion);
+ }
+
+ const IdentifierInfo *getName() const;
+ const MacroDefinition *getDefinition() const;
+ SourceRange getSourceRange() const;
+};
+
+/// \brief Unpack a given macro expansion cursor to retrieve its info.
+static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
+ return C;
+}
/// \brief Create an inclusion directive cursor.
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
@@ -163,7 +208,7 @@ CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
/// \brief Unpack a given inclusion directive cursor to retrieve its
/// source range.
-InclusionDirective *getCursorInclusionDirective(CXCursor C);
+const InclusionDirective *getCursorInclusionDirective(CXCursor C);
/// \brief Create a label reference at the given location.
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
@@ -171,13 +216,14 @@ CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
/// \brief Unpack a label reference into the label statement it refers to and
/// the location of the reference.
-std::pair<LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
+std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
/// \brief Create a overloaded declaration reference cursor for an expression.
-CXCursor MakeCursorOverloadedDeclRef(OverloadExpr *E, CXTranslationUnit TU);
+CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
+ CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a declaration.
-CXCursor MakeCursorOverloadedDeclRef(Decl *D, SourceLocation Location,
+CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a template name.
@@ -186,7 +232,7 @@ CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
CXTranslationUnit TU);
/// \brief Internal storage for an overloaded declaration reference cursor;
-typedef llvm::PointerUnion3<OverloadExpr *, Decl *,
+typedef llvm::PointerUnion3<const OverloadExpr *, const Decl *,
OverloadedTemplateStorage *>
OverloadedDeclRefStorage;
@@ -195,11 +241,11 @@ typedef llvm::PointerUnion3<OverloadExpr *, Decl *,
std::pair<OverloadedDeclRefStorage, SourceLocation>
getCursorOverloadedDeclRef(CXCursor C);
-Decl *getCursorDecl(CXCursor Cursor);
-Expr *getCursorExpr(CXCursor Cursor);
-Stmt *getCursorStmt(CXCursor Cursor);
-Attr *getCursorAttr(CXCursor Cursor);
-Decl *getCursorParentDecl(CXCursor Cursor);
+const Decl *getCursorDecl(CXCursor Cursor);
+const Expr *getCursorExpr(CXCursor Cursor);
+const Stmt *getCursorStmt(CXCursor Cursor);
+const Attr *getCursorAttr(CXCursor Cursor);
+const Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index e5b6ccc..b02fdd6 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -1,15 +1,15 @@
-/*===-- CXLoadedDiagnostic.cpp - Handling of persisent diags -*- C++ -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* Implements handling of persisent diagnostics. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
+//===-- CXLoadedDiagnostic.cpp - Handling of persisent diags ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements handling of persisent diagnostics.
+//
+//===----------------------------------------------------------------------===//
#include "CXLoadedDiagnostic.h"
#include "CXString.h"
@@ -23,16 +23,13 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <assert.h>
-
using namespace clang;
-using namespace clang::cxstring;
//===----------------------------------------------------------------------===//
// Extend CXDiagnosticSetImpl which contains strings for diagnostics.
//===----------------------------------------------------------------------===//
-typedef llvm::DenseMap<unsigned, llvm::StringRef> Strings;
+typedef llvm::DenseMap<unsigned, const char *> Strings;
namespace {
class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
@@ -40,8 +37,6 @@ public:
CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {}
virtual ~CXLoadedDiagnosticSetImpl() {}
- llvm::StringRef makeString(const char *blob, unsigned blobLen);
-
llvm::BumpPtrAllocator Alloc;
Strings Categories;
Strings WarningFlags;
@@ -50,17 +45,15 @@ public:
FileSystemOptions FO;
FileManager FakeFiles;
llvm::DenseMap<unsigned, const FileEntry *> Files;
-};
-}
-llvm::StringRef CXLoadedDiagnosticSetImpl::makeString(const char *blob,
- unsigned bloblen) {
- char *mem = Alloc.Allocate<char>(bloblen + 1);
- memcpy(mem, blob, bloblen);
- // Add a null terminator for those clients accessing the buffer
- // like a c-string.
- mem[bloblen] = '\0';
- return llvm::StringRef(mem, bloblen);
+ /// \brief Copy the string into our own allocator.
+ const char *copyString(StringRef Blob) {
+ char *mem = Alloc.Allocate<char>(Blob.size() + 1);
+ memcpy(mem, Blob.data(), Blob.size());
+ mem[Blob.size()] = '\0';
+ return mem;
+ }
+};
}
//===----------------------------------------------------------------------===//
@@ -102,17 +95,17 @@ CXSourceLocation CXLoadedDiagnostic::getLocation() const {
}
CXString CXLoadedDiagnostic::getSpelling() const {
- return cxstring::createCXString(Spelling, false);
+ return cxstring::createRef(Spelling);
}
CXString CXLoadedDiagnostic::getDiagnosticOption(CXString *Disable) const {
if (DiagOption.empty())
- return createCXString("");
+ return cxstring::createEmpty();
// FIXME: possibly refactor with logic in CXStoredDiagnostic.
if (Disable)
- *Disable = createCXString((Twine("-Wno-") + DiagOption).str());
- return createCXString((Twine("-W") + DiagOption).str());
+ *Disable = cxstring::createDup((Twine("-Wno-") + DiagOption).str());
+ return cxstring::createDup((Twine("-W") + DiagOption).str());
}
unsigned CXLoadedDiagnostic::getCategory() const {
@@ -120,7 +113,7 @@ unsigned CXLoadedDiagnostic::getCategory() const {
}
CXString CXLoadedDiagnostic::getCategoryText() const {
- return cxstring::createCXString(CategoryText);
+ return cxstring::createDup(CategoryText);
}
unsigned CXLoadedDiagnostic::getNumRanges() const {
@@ -141,7 +134,7 @@ CXString CXLoadedDiagnostic::getFixIt(unsigned FixIt,
assert(FixIt < FixIts.size());
if (ReplacementRange)
*ReplacementRange = FixIts[FixIt].first;
- return FixIts[FixIt].second;
+ return cxstring::createRef(FixIts[FixIt].second);
}
void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
@@ -200,7 +193,7 @@ class DiagLoader {
if (error)
*error = code;
if (errorString)
- *errorString = createCXString(err);
+ *errorString = cxstring::createDup(err);
}
void reportInvalidFile(llvm::StringRef err) {
@@ -216,22 +209,20 @@ class DiagLoader {
StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
llvm::StringRef errorContext,
unsigned &BlockOrRecordID,
- const bool atTopLevel = false);
+ bool atTopLevel = false);
LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
Strings &strings, llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString = false);
LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
- llvm::StringRef &RetStr,
+ const char *&RetStr,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString = false);
LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags,
@@ -248,7 +239,7 @@ public:
if (error)
*error = CXLoadDiag_None;
if (errorString)
- *errorString = createCXString("");
+ *errorString = cxstring::createEmpty();
}
CXDiagnosticSet load(const char *file);
@@ -286,8 +277,7 @@ CXDiagnosticSet DiagLoader::load(const char *file) {
return 0;
}
- OwningPtr<CXLoadedDiagnosticSetImpl>
- Diags(new CXLoadedDiagnosticSetImpl());
+ OwningPtr<CXLoadedDiagnosticSetImpl> Diags(new CXLoadedDiagnosticSetImpl());
while (true) {
unsigned BlockID = 0;
@@ -328,7 +318,7 @@ CXDiagnosticSet DiagLoader::load(const char *file) {
StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
llvm::StringRef errorContext,
unsigned &blockOrRecordID,
- const bool atTopLevel) {
+ bool atTopLevel) {
blockOrRecordID = 0;
@@ -425,9 +415,7 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
}
RecordData Record;
- const char *Blob;
- unsigned BlobLen;
- unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen);
+ unsigned recordID = Stream.readRecord(blockOrCode, Record);
if (recordID == serialized_diags::RECORD_VERSION) {
if (Record.size() < 1) {
@@ -435,7 +423,7 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
return Failure;
}
if (Record[0] > MaxSupportedVersion) {
- reportInvalidFile("diagnosics file is a newer version than the one "
+ reportInvalidFile("diagnostics file is a newer version than the one "
"supported");
return Failure;
}
@@ -445,32 +433,31 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
}
LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
- llvm::StringRef &RetStr,
+ const char *&RetStr,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString) {
// Basic buffer overflow check.
- if (BlobLen > 65536) {
+ if (Blob.size() > 65536) {
reportInvalidFile(std::string("Out-of-bounds string in ") +
std::string(errorContext));
return Failure;
}
- if (allowEmptyString && Record.size() >= 1 && BlobLen == 0) {
+ if (allowEmptyString && Record.size() >= 1 && Blob.size() == 0) {
RetStr = "";
return Success;
}
- if (Record.size() < 1 || BlobLen == 0) {
+ if (Record.size() < 1 || Blob.size() == 0) {
reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
+ std::string(" entry"));
return Failure;
}
- RetStr = TopDiags.makeString(BlobStart, BlobLen);
+ RetStr = TopDiags.copyString(Blob);
return Success;
}
@@ -478,11 +465,10 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
Strings &strings,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString) {
- llvm::StringRef RetStr;
- if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen,
+ const char *RetStr;
+ if (readString(TopDiags, RetStr, errorContext, Record, Blob,
allowEmptyString))
return Failure;
strings[Record[0]] = RetStr;
@@ -512,7 +498,7 @@ LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
reportInvalidFile("Corrupted file entry in source location");
return Failure;
}
- Loc.file = (void*) FE;
+ Loc.file = const_cast<FileEntry *>(FE);
Loc.line = Record[offset++];
Loc.column = Record[offset++];
Loc.offset = Record[offset++];
@@ -582,10 +568,8 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
// Read the record.
Record.clear();
- const char *BlobStart = 0;
- unsigned BlobLen = 0;
- unsigned recID = Stream.ReadRecord(blockOrCode, Record,
- BlobStart, BlobLen);
+ StringRef Blob;
+ unsigned recID = Stream.readRecord(blockOrCode, Record, &Blob);
if (recID < serialized_diags::RECORD_FIRST ||
recID > serialized_diags::RECORD_LAST)
@@ -596,20 +580,19 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
continue;
case serialized_diags::RECORD_CATEGORY:
if (readString(TopDiags, TopDiags.Categories, "category", Record,
- BlobStart, BlobLen,
- /* allowEmptyString */ true))
+ Blob, /* allowEmptyString */ true))
return Failure;
continue;
case serialized_diags::RECORD_DIAG_FLAG:
if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
- BlobStart, BlobLen))
+ Blob))
return Failure;
continue;
case serialized_diags::RECORD_FILENAME: {
if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
- BlobStart, BlobLen))
+ Blob))
return Failure;
if (Record.size() < 3) {
@@ -638,11 +621,11 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
CXSourceRange SR;
if (readRange(TopDiags, Record, 0, SR))
return Failure;
- llvm::StringRef RetStr;
- if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen,
+ const char *RetStr;
+ if (readString(TopDiags, RetStr, "FIXIT", Record, Blob,
/* allowEmptyString */ true))
return Failure;
- D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false)));
+ D->FixIts.push_back(std::make_pair(SR, RetStr));
continue;
}
@@ -655,7 +638,7 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
unsigned diagFlag = Record[offset++];
D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
D->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
- D->Spelling = TopDiags.makeString(BlobStart, BlobLen);
+ D->Spelling = TopDiags.copyString(Blob);
continue;
}
}
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index d4a321e..d4b11d5 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -82,8 +82,8 @@ public:
Location DiagLoc;
std::vector<CXSourceRange> Ranges;
- std::vector<std::pair<CXSourceRange, CXString> > FixIts;
- llvm::StringRef Spelling;
+ std::vector<std::pair<CXSourceRange, const char *> > FixIts;
+ const char *Spelling;
llvm::StringRef DiagOption;
llvm::StringRef CategoryText;
unsigned severity;
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index a6bf8fc..bc8d575 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -12,15 +12,17 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
-
#include "CIndexer.h"
-#include "CXString.h"
+#include "CLog.h"
+#include "CXLoadedDiagnostic.h"
#include "CXSourceLocation.h"
+#include "CXString.h"
#include "CXTranslationUnit.h"
-#include "CXLoadedDiagnostic.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
using namespace clang;
-using namespace clang::cxstring;
+using namespace clang::cxindex;
//===----------------------------------------------------------------------===//
// Internal predicates on CXSourceLocations.
@@ -116,40 +118,41 @@ CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
extern "C" {
-CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+CXSourceLocation clang_getLocation(CXTranslationUnit TU,
CXFile file,
unsigned line,
unsigned column) {
- if (!tu || !file)
+ if (!TU || !file)
return clang_getNullLocation();
- bool Logging = ::getenv("LIBCLANG_LOGGING");
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
const FileEntry *File = static_cast<const FileEntry *>(file);
SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
- if (Logging)
- llvm::errs() << "clang_getLocation(\"" << File->getName()
- << "\", " << line << ", " << column << ") = invalid\n";
+ if (Log)
+ *Log << llvm::format("(\"%s\", %d, %d) = invalid",
+ File->getName(), line, column);
return clang_getNullLocation();
}
- if (Logging)
- llvm::errs() << "clang_getLocation(\"" << File->getName()
- << "\", " << line << ", " << column << ") = "
- << SLoc.getRawEncoding() << "\n";
+ CXSourceLocation CXLoc =
+ cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
+ if (Log)
+ *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName(), line, column)
+ << CXLoc;
- return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
+ return CXLoc;
}
-CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
+CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
CXFile file,
unsigned offset) {
- if (!tu || !file)
+ if (!TU || !file)
return clang_getNullLocation();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceLocation SLoc
= CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
@@ -183,7 +186,7 @@ static void createNullLocation(CXFile *file, unsigned *line,
static void createNullLocation(CXString *filename, unsigned *line,
unsigned *column, unsigned *offset = 0) {
if (filename)
- *filename = createCXString("");
+ *filename = cxstring::createEmpty();
if (line)
*line = 0;
if (column)
@@ -228,7 +231,7 @@ void clang_getExpansionLocation(CXSourceLocation location,
}
if (file)
- *file = (void *)SM.getFileEntryForSLocEntry(sloc);
+ *file = const_cast<FileEntry *>(SM.getFileEntryForSLocEntry(sloc));
if (line)
*line = SM.getExpansionLineNumber(ExpansionLoc);
if (column)
@@ -259,7 +262,7 @@ void clang_getPresumedLocation(CXSourceLocation location,
PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
if (filename)
- *filename = createCXString(PreLoc.getFilename());
+ *filename = cxstring::createRef(PreLoc.getFilename());
if (line)
*line = PreLoc.getLine();
if (column)
@@ -295,16 +298,8 @@ void clang_getSpellingLocation(CXSourceLocation location,
const SourceManager &SM =
*static_cast<const SourceManager*>(location.ptr_data[0]);
- SourceLocation SpellLoc = Loc;
- if (SpellLoc.isMacroID()) {
- SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
- if (SimpleSpellingLoc.isFileID() &&
- SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
- SpellLoc = SimpleSpellingLoc;
- else
- SpellLoc = SM.getExpansionLoc(SpellLoc);
- }
-
+ // FIXME: This should call SourceManager::getSpellingLoc().
+ SourceLocation SpellLoc = SM.getFileLoc(Loc);
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
FileID FID = LocInfo.first;
unsigned FileOffset = LocInfo.second;
@@ -313,7 +308,7 @@ void clang_getSpellingLocation(CXSourceLocation location,
return createNullLocation(file, line, column, offset);
if (file)
- *file = (void *)SM.getFileEntryForID(FID);
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
@@ -322,5 +317,41 @@ void clang_getSpellingLocation(CXSourceLocation location,
*offset = FileOffset;
}
-} // end extern "C"
+void clang_getFileLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+
+ if (!isASTUnitSourceLocation(location)) {
+ CXLoadedDiagnostic::decodeLocation(location, file, line,
+ column, offset);
+ return;
+ }
+
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ SourceLocation FileLoc = SM.getFileLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(FileLoc);
+ FileID FID = LocInfo.first;
+ unsigned FileOffset = LocInfo.second;
+ if (FID.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ if (file)
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ if (line)
+ *line = SM.getLineNumber(FID, FileOffset);
+ if (column)
+ *column = SM.getColumnNumber(FID, FileOffset);
+ if (offset)
+ *offset = FileOffset;
+}
+
+} // end extern "C"
diff --git a/tools/libclang/CXSourceLocation.h b/tools/libclang/CXSourceLocation.h
index 6c5e858..f97ac1f 100644
--- a/tools/libclang/CXSourceLocation.h
+++ b/tools/libclang/CXSourceLocation.h
@@ -15,9 +15,9 @@
#define LLVM_CLANG_CXSOURCELOCATION_H
#include "clang-c/Index.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/AST/ASTContext.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
namespace clang {
@@ -32,7 +32,7 @@ translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts,
if (Loc.isInvalid())
clang_getNullLocation();
- CXSourceLocation Result = { { (void*) &SM, (void*) &LangOpts, },
+ CXSourceLocation Result = { { &SM, &LangOpts, },
Loc.getRawEncoding() };
return Result;
}
diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp
index fa331de..9731616 100644
--- a/tools/libclang/CXStoredDiagnostic.cpp
+++ b/tools/libclang/CXStoredDiagnostic.cpp
@@ -26,7 +26,6 @@
using namespace clang;
using namespace clang::cxloc;
-using namespace clang::cxstring;
CXDiagnosticSeverity CXStoredDiagnostic::getSeverity() const {
switch (Diag.getLevel()) {
@@ -49,7 +48,7 @@ CXSourceLocation CXStoredDiagnostic::getLocation() const {
}
CXString CXStoredDiagnostic::getSpelling() const {
- return createCXString(Diag.getMessage(), false);
+ return cxstring::createRef(Diag.getMessage());
}
CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const {
@@ -57,17 +56,17 @@ CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const {
StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
if (!Option.empty()) {
if (Disable)
- *Disable = createCXString((Twine("-Wno-") + Option).str());
- return createCXString((Twine("-W") + Option).str());
+ *Disable = cxstring::createDup((Twine("-Wno-") + Option).str());
+ return cxstring::createDup((Twine("-W") + Option).str());
}
if (ID == diag::fatal_too_many_errors) {
if (Disable)
- *Disable = createCXString("-ferror-limit=0");
- return createCXString("-ferror-limit=");
+ *Disable = cxstring::createRef("-ferror-limit=0");
+ return cxstring::createRef("-ferror-limit=");
}
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned CXStoredDiagnostic::getCategory() const {
@@ -76,7 +75,7 @@ unsigned CXStoredDiagnostic::getCategory() const {
CXString CXStoredDiagnostic::getCategoryText() const {
unsigned catID = DiagnosticIDs::getCategoryNumberForDiag(Diag.getID());
- return createCXString(DiagnosticIDs::getCategoryNameFromID(catID));
+ return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(catID));
}
unsigned CXStoredDiagnostic::getNumRanges() const {
@@ -109,6 +108,6 @@ CXString CXStoredDiagnostic::getFixIt(unsigned FixIt,
*ReplacementRange = translateSourceRange(Diag.getLocation().getManager(),
LangOpts, Hint.RemoveRange);
}
- return createCXString(Hint.CodeToInsert);
+ return cxstring::createDup(Hint.CodeToInsert);
}
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index bb09cd5..1523034 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -15,48 +15,93 @@
#include "CXString.h"
#include "CXTranslationUnit.h"
-#include "clang/Frontend/ASTUnit.h"
#include "clang-c/Index.h"
+#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
-using namespace clang::cxstring;
-enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
+/// Describes the kind of underlying data in CXString.
+enum CXStringFlag {
+ /// CXString contains a 'const char *' that it doesn't own.
+ CXS_Unmanaged,
+
+ /// CXString contains a 'const char *' that it allocated with malloc().
+ CXS_Malloc,
+
+ /// CXString contains a CXStringBuf that needs to be returned to the
+ /// CXStringPool.
+ CXS_StringBuf
+};
+
+namespace clang {
+namespace cxstring {
//===----------------------------------------------------------------------===//
// Basic generation of CXStrings.
//===----------------------------------------------------------------------===//
-CXString cxstring::createCXString(const char *String, bool DupString){
+CXString createEmpty() {
CXString Str;
- if (DupString) {
- Str.data = strdup(String);
- Str.private_flags = (unsigned) CXS_Malloc;
- } else {
- Str.data = (void*)String;
- Str.private_flags = (unsigned) CXS_Unmanaged;
- }
+ Str.data = "";
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createNull() {
+ CXString Str;
+ Str.data = 0;
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createRef(const char *String) {
+ if (String && String[0] == '\0')
+ return createEmpty();
+
+ CXString Str;
+ Str.data = String;
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createDup(const char *String) {
+ if (!String)
+ return createNull();
+
+ if (String[0] == '\0')
+ return createEmpty();
+
+ CXString Str;
+ Str.data = strdup(String);
+ Str.private_flags = CXS_Malloc;
return Str;
}
-CXString cxstring::createCXString(StringRef String, bool DupString) {
+CXString createRef(StringRef String) {
+ // If the string is not nul-terminated, we have to make a copy.
+ // This is doing a one past end read, and should be removed!
+ if (!String.empty() && String.data()[String.size()] != 0)
+ return createDup(String);
+
CXString Result;
- if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
- char *Spelling = (char *)malloc(String.size() + 1);
- memmove(Spelling, String.data(), String.size());
- Spelling[String.size()] = 0;
- Result.data = Spelling;
- Result.private_flags = (unsigned) CXS_Malloc;
- } else {
- Result.data = (void*) String.data();
- Result.private_flags = (unsigned) CXS_Unmanaged;
- }
+ Result.data = String.data();
+ Result.private_flags = (unsigned) CXS_Unmanaged;
return Result;
}
-CXString cxstring::createCXString(CXStringBuf *buf) {
+CXString createDup(StringRef String) {
+ CXString Result;
+ char *Spelling = static_cast<char *>(malloc(String.size() + 1));
+ memmove(Spelling, String.data(), String.size());
+ Spelling[String.size()] = 0;
+ Result.data = Spelling;
+ Result.private_flags = (unsigned) CXS_Malloc;
+ return Result;
+}
+
+CXString createCXString(CXStringBuf *buf) {
CXString Str;
Str.data = buf;
Str.private_flags = (unsigned) CXS_StringBuf;
@@ -68,43 +113,38 @@ CXString cxstring::createCXString(CXStringBuf *buf) {
// String pools.
//===----------------------------------------------------------------------===//
-
-typedef std::vector<CXStringBuf *> CXStringPool;
-
-void *cxstring::createCXStringPool() {
- return new CXStringPool();
-}
-
-void cxstring::disposeCXStringPool(void *p) {
- CXStringPool *pool = static_cast<CXStringPool*>(p);
- if (pool) {
- for (CXStringPool::iterator I = pool->begin(), E = pool->end();
- I != E; ++I) {
- delete *I;
- }
- delete pool;
+CXStringPool::~CXStringPool() {
+ for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end();
+ I != E; ++I) {
+ delete *I;
}
}
-CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
- CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool);
- if (pool->empty())
+CXStringBuf *CXStringPool::getCXStringBuf(CXTranslationUnit TU) {
+ if (Pool.empty())
return new CXStringBuf(TU);
- CXStringBuf *buf = pool->back();
- buf->Data.clear();
- pool->pop_back();
- return buf;
+
+ CXStringBuf *Buf = Pool.back();
+ Buf->Data.clear();
+ Pool.pop_back();
+ return Buf;
+}
+
+CXStringBuf *getCXStringBuf(CXTranslationUnit TU) {
+ return TU->StringPool->getCXStringBuf(TU);
}
-void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
- if (buf)
- static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
+void CXStringBuf::dispose() {
+ TU->StringPool->Pool.push_back(this);
}
-bool cxstring::isManagedByPool(CXString str) {
+bool isManagedByPool(CXString str) {
return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
}
+} // end namespace cxstring
+} // end namespace clang
+
//===----------------------------------------------------------------------===//
// libClang public APIs.
//===----------------------------------------------------------------------===//
@@ -112,9 +152,9 @@ bool cxstring::isManagedByPool(CXString str) {
extern "C" {
const char *clang_getCString(CXString string) {
if (string.private_flags == (unsigned) CXS_StringBuf) {
- return ((CXStringBuf*)string.data)->Data.data();
+ return static_cast<const cxstring::CXStringBuf *>(string.data)->Data.data();
}
- return (const char*) string.data;
+ return static_cast<const char *>(string.data);
}
void clang_disposeString(CXString string) {
@@ -123,10 +163,11 @@ void clang_disposeString(CXString string) {
break;
case CXS_Malloc:
if (string.data)
- free((void*)string.data);
+ free(const_cast<void *>(string.data));
break;
case CXS_StringBuf:
- disposeCXStringBuf((CXStringBuf *) string.data);
+ static_cast<cxstring::CXStringBuf *>(
+ const_cast<void *>(string.data))->dispose();
break;
}
}
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index c354bd2..7032033 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -16,36 +16,82 @@
#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
+#include <string>
namespace clang {
namespace cxstring {
-
-struct CXStringBuf {
- SmallString<128> Data;
- CXTranslationUnit TU;
- CXStringBuf(CXTranslationUnit tu) : TU(tu) {}
-};
-/// \brief Create a CXString object from a C string.
-CXString createCXString(const char *String, bool DupString = false);
+struct CXStringBuf;
+
+/// \brief Create a CXString object for an empty "" string.
+CXString createEmpty();
+
+/// \brief Create a CXString object for an NULL string.
+///
+/// A NULL string should be used as an "invalid" value in case of errors.
+CXString createNull();
+
+/// \brief Create a CXString object from a nul-terminated C string. New
+/// CXString may contain a pointer to \p String.
+///
+/// \p String should not be changed by the caller afterwards.
+CXString createRef(const char *String);
+
+/// \brief Create a CXString object from a nul-terminated C string. New
+/// CXString will contain a copy of \p String.
+///
+/// \p String can be changed or freed by the caller.
+CXString createDup(const char *String);
+
+/// \brief Create a CXString object from a StringRef. New CXString may
+/// contain a pointer to the undrelying data of \p String.
+///
+/// \p String should not be changed by the caller afterwards.
+CXString createRef(StringRef String);
+
+/// \brief Create a CXString object from a StringRef. New CXString will
+/// contain a copy of \p String.
+///
+/// \p String can be changed or freed by the caller.
+CXString createDup(StringRef String);
-/// \brief Create a CXString object from a StringRef.
-CXString createCXString(StringRef String, bool DupString = true);
+// Usually std::string is intended to be used as backing storage for CXString.
+// In this case, call \c createRef(String.c_str()).
+//
+// If you need to make a copy, call \c createDup(StringRef(String)).
+CXString createRef(std::string String) LLVM_DELETED_FUNCTION;
/// \brief Create a CXString object that is backed by a string buffer.
CXString createCXString(CXStringBuf *buf);
-/// \brief Create an opaque string pool used for fast geneneration of strings.
-void *createCXStringPool();
+/// \brief A string pool used for fast allocation/deallocation of strings.
+class CXStringPool {
+public:
+ ~CXStringPool();
+
+ CXStringBuf *getCXStringBuf(CXTranslationUnit TU);
+
+private:
+ std::vector<CXStringBuf *> Pool;
+
+ friend struct CXStringBuf;
+};
+
+struct CXStringBuf {
+ SmallString<128> Data;
+ CXTranslationUnit TU;
+
+ CXStringBuf(CXTranslationUnit TU) : TU(TU) {}
+
+ /// \brief Return this buffer to the pool.
+ void dispose();
+};
-/// \brief Dispose of a string pool.
-void disposeCXStringPool(void *pool);
-
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 37789aa..699b74a 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -14,24 +14,34 @@
#ifndef LLVM_CLANG_CXTRANSLATIONUNIT_H
#define LLVM_CLANG_CXTRANSLATIONUNIT_H
-extern "C" {
+#include "clang-c/Index.h"
+#include "CXString.h"
+
+namespace clang {
+ class ASTUnit;
+ class CIndexer;
+ class SimpleFormatContext;
+} // namespace clang
+
struct CXTranslationUnitImpl {
- void *CIdx;
- void *TUData;
- void *StringPool;
+ clang::CIndexer *CIdx;
+ clang::ASTUnit *TheASTUnit;
+ clang::cxstring::CXStringPool *StringPool;
void *Diagnostics;
void *OverridenCursorsPool;
+ clang::SimpleFormatContext *FormatContext;
+ unsigned FormatInMemoryUniqueId;
};
-}
namespace clang {
- class ASTUnit;
- class CIndexer;
-
namespace cxtu {
-CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU);
-
+CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU);
+
+static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
+ return TU->TheASTUnit;
+}
+
class CXTUOwner {
CXTranslationUnitImpl *TU;
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 4e031d2..6f87fc5 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -12,15 +12,15 @@
//===--------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
#include "CXCursor.h"
#include "CXString.h"
+#include "CXTranslationUnit.h"
#include "CXType.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/Frontend/ASTUnit.h"
using namespace clang;
@@ -97,7 +97,7 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
CXTypeKind TK = CXType_Invalid;
if (TU && !T.isNull()) {
- ASTContext &Ctx = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
if (Ctx.getLangOpts().ObjC1) {
QualType UnqualT = T.getUnqualifiedType();
if (Ctx.isObjCIdType(UnqualT))
@@ -131,27 +131,32 @@ CXType clang_getCursorType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);
- ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ if (!TU)
+ return MakeCXType(QualType(), TU);
+
+ ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
if (clang_isExpression(C.kind)) {
QualType T = cxcursor::getCursorExpr(C)->getType();
return MakeCXType(T, TU);
}
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return MakeCXType(QualType(), TU);
- if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
return MakeCXType(Context.getTypeDeclType(TD), TU);
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+ if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return MakeCXType(Context.getObjCInterfaceType(ID), TU);
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
return MakeCXType(VD->getType(), TU);
- if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
+ if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
return MakeCXType(PD->getType(), TU);
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return MakeCXType(FD->getType(), TU);
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
return MakeCXType(QualType(), TU);
}
@@ -197,14 +202,29 @@ CXType clang_getCursorType(CXCursor C) {
return MakeCXType(QualType(), TU);
}
+CXString clang_getTypeSpelling(CXType CT) {
+ QualType T = GetQualType(CT);
+ if (T.isNull())
+ return cxstring::createEmpty();
+
+ CXTranslationUnit TU = GetTU(CT);
+ SmallString<64> Str;
+ llvm::raw_svector_ostream OS(Str);
+ PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
+
+ T.print(OS, PP);
+
+ return cxstring::createDup(OS.str());
+}
+
CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
+ if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
QualType T = TD->getUnderlyingType();
return MakeCXType(T, TU);
}
@@ -220,9 +240,9 @@ CXType clang_getEnumDeclIntegerType(CXCursor C) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
+ if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
QualType T = TD->getIntegerType();
return MakeCXType(T, TU);
}
@@ -237,9 +257,9 @@ long long clang_getEnumConstantDeclValue(CXCursor C) {
using namespace cxcursor;
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
+ if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
return TD->getInitVal().getSExtValue();
}
@@ -253,9 +273,9 @@ unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
using namespace cxcursor;
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
+ if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
return TD->getInitVal().getZExtValue();
}
@@ -265,6 +285,21 @@ unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
return ULLONG_MAX;
}
+int clang_getFieldDeclBitWidth(CXCursor C) {
+ using namespace cxcursor;
+
+ if (clang_isDeclaration(C.kind)) {
+ const Decl *D = getCursorDecl(C);
+
+ if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
+ if (FD->isBitField())
+ return FD->getBitWidthValue(getCursorContext(C));
+ }
+ }
+
+ return -1;
+}
+
CXType clang_getCanonicalType(CXType CT) {
if (CT.kind == CXType_Invalid)
return CT;
@@ -275,8 +310,9 @@ CXType clang_getCanonicalType(CXType CT) {
if (T.isNull())
return MakeCXType(QualType(), GetTU(CT));
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
+ return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
+ .getCanonicalType(T),
+ TU);
}
unsigned clang_isConstQualifiedType(CXType CT) {
@@ -427,7 +463,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(Vector);
}
#undef TKIND
- return cxstring::createCXString(s);
+ return cxstring::createRef(s);
}
unsigned clang_equalTypes(CXType A, CXType B) {
@@ -465,6 +501,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
TCALLINGCONV(PnaclCall);
+ TCALLINGCONV(IntelOclBicc);
}
#undef TCALLINGCONV
}
@@ -517,7 +554,7 @@ CXType clang_getResultType(CXType X) {
CXType clang_getCursorResultType(CXCursor C) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
@@ -533,9 +570,8 @@ unsigned clang_isPODType(CXType X) {
return 0;
CXTranslationUnit TU = GetTU(X);
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- return T.isPODType(AU->getASTContext()) ? 1 : 0;
+ return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
}
CXType clang_getElementType(CXType CT) {
@@ -617,32 +653,30 @@ long long clang_getArraySize(CXType CT) {
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return cxstring::createCXString("");
+ return cxstring::createEmpty();
- Decl *D = static_cast<Decl*>(C.data[0]);
- CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- ASTContext &Ctx = AU->getASTContext();
+ const Decl *D = cxcursor::getCursorDecl(C);
+ ASTContext &Ctx = cxcursor::getCursorContext(C);
std::string encoding;
- if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
- return cxstring::createCXString("?");
- } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
+ return cxstring::createRef("?");
+ } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
- else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
else {
QualType Ty;
- if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
Ty = Ctx.getTypeDeclType(TD);
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ty = VD->getType();
- else return cxstring::createCXString("?");
+ else return cxstring::createRef("?");
Ctx.getObjCEncodingForType(Ty, encoding);
}
- return cxstring::createCXString(encoding);
+ return cxstring::createDup(encoding);
}
} // end: extern "C"
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index 7cf7508..53d864d 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -10,10 +10,9 @@
#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
-#include "Index_Internal.h"
#include "CXCursor.h"
#include "CXTranslationUnit.h"
-
+#include "Index_Internal.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/TypeLocVisitor.h"
@@ -34,10 +33,11 @@ public:
MemberRefVisitKind, SizeOfPackExprPartsKind,
LambdaExprPartsKind, PostChildrenVisitKind };
protected:
- void *data[3];
+ const void *data[3];
CXCursor parent;
Kind K;
- VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
+ VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = 0,
+ const void *d3 = 0)
: parent(C), K(k) {
data[0] = d1;
data[1] = d2;
@@ -70,7 +70,7 @@ private:
/// \brief The declaration that serves at the parent of any statement or
/// expression nodes.
- Decl *StmtParent;
+ const Decl *StmtParent;
/// \brief The visitor function.
CXCursorVisitor Visitor;
@@ -116,15 +116,16 @@ private:
/// \param R a half-open source range retrieved from the abstract syntax tree.
RangeComparisonResult CompareRegionOfInterest(SourceRange R);
- void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
+ bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
class SetParentRAII {
CXCursor &Parent;
- Decl *&StmtParent;
+ const Decl *&StmtParent;
CXCursor OldParent;
public:
- SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
+ SetParentRAII(CXCursor &Parent, const Decl *&StmtParent,
+ CXCursor NewParent)
: Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
{
Parent = NewParent;
@@ -147,7 +148,7 @@ public:
SourceRange RegionOfInterest = SourceRange(),
bool VisitDeclsOnly = false,
PostChildrenVisitorTy PostChildrenVisitor = 0)
- : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
+ : TU(TU), AU(cxtu::getASTUnit(TU)),
Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
ClientData(ClientData),
VisitPreprocessorLast(VisitPreprocessorLast),
@@ -171,14 +172,14 @@ public:
}
}
- ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
+ ASTUnit *getASTUnit() const { return AU; }
CXTranslationUnit getTU() const { return TU; }
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
/// \brief Visit declarations and preprocessed entities for the file region
/// designated by \see RegionOfInterest.
- void visitFileRegion();
+ bool visitFileRegion();
bool visitPreprocessedEntitiesInRegion();
@@ -198,7 +199,7 @@ public:
bool VisitAttributes(Decl *D);
bool VisitBlockDecl(BlockDecl *B);
bool VisitCXXRecordDecl(CXXRecordDecl *D);
- llvm::Optional<bool> shouldVisitCursor(CXCursor C);
+ Optional<bool> shouldVisitCursor(CXCursor C);
bool VisitDeclContext(DeclContext *DC);
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
bool VisitTypedefDecl(TypedefDecl *D);
@@ -258,8 +259,8 @@ public:
// Data-recursive visitor functions.
bool IsInRegionOfInterest(CXCursor C);
bool RunVisitorWorkList(VisitorWorkList &WL);
- void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
- LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
+ void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);
+ LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
};
}
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 3614206..95d74ef 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "RecursiveASTVisitor.h"
using namespace clang;
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 4b6706f..d7fb959 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "clang/AST/DeclVisitor.h"
using namespace clang;
@@ -16,39 +15,41 @@ using namespace cxindex;
namespace {
-class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
+class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
IndexingContext &IndexCtx;
public:
explicit IndexingDeclVisitor(IndexingContext &indexCtx)
: IndexCtx(indexCtx) { }
- void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) {
+ void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = 0) {
if (!Parent) Parent = D;
if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
} else {
- if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
+ if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
IndexCtx.handleVar(Parm);
- } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- for (FunctionDecl::param_iterator
- PI = FD->param_begin(), PE = FD->param_end(); PI != PE; ++PI) {
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ for (FunctionDecl::param_const_iterator PI = FD->param_begin(),
+ PE = FD->param_end();
+ PI != PE; ++PI) {
IndexCtx.handleVar(*PI);
}
}
}
}
- void handleObjCMethod(ObjCMethodDecl *D) {
+ void handleObjCMethod(const ObjCMethodDecl *D) {
IndexCtx.handleObjCMethod(D);
if (D->isImplicit())
return;
IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
- for (ObjCMethodDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I)
+ for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
+ E = D->param_end();
+ I != E; ++I)
handleDeclarator(*I, D);
if (D->isThisDeclarationADefinition()) {
@@ -59,14 +60,14 @@ public:
}
}
- bool VisitFunctionDecl(FunctionDecl *D) {
+ bool VisitFunctionDecl(const FunctionDecl *D) {
IndexCtx.handleFunction(D);
handleDeclarator(D);
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
- for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
- E = Ctor->init_end();
+ for (CXXConstructorDecl::init_const_iterator I = Ctor->init_begin(),
+ E = Ctor->init_end();
I != E; ++I) {
CXXCtorInitializer *Init = *I;
if (Init->isWritten()) {
@@ -87,14 +88,14 @@ public:
return true;
}
- bool VisitVarDecl(VarDecl *D) {
+ bool VisitVarDecl(const VarDecl *D) {
IndexCtx.handleVar(D);
handleDeclarator(D);
IndexCtx.indexBody(D->getInit(), D);
return true;
}
- bool VisitFieldDecl(FieldDecl *D) {
+ bool VisitFieldDecl(const FieldDecl *D) {
IndexCtx.handleField(D);
handleDeclarator(D);
if (D->isBitField())
@@ -103,27 +104,27 @@ public:
IndexCtx.indexBody(D->getInClassInitializer(), D);
return true;
}
-
- bool VisitEnumConstantDecl(EnumConstantDecl *D) {
+
+ bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
IndexCtx.handleEnumerator(D);
IndexCtx.indexBody(D->getInitExpr(), D);
return true;
}
- bool VisitTypedefNameDecl(TypedefNameDecl *D) {
+ bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
IndexCtx.handleTypedefName(D);
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
return true;
}
- bool VisitTagDecl(TagDecl *D) {
+ bool VisitTagDecl(const TagDecl *D) {
// Non-free standing tags are handled in indexTypeSourceInfo.
if (D->isFreeStanding())
IndexCtx.indexTagDecl(D);
return true;
}
- bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
IndexCtx.handleObjCInterface(D);
if (D->isThisDeclarationADefinition()) {
@@ -133,7 +134,7 @@ public:
return true;
}
- bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
IndexCtx.handleObjCProtocol(D);
if (D->isThisDeclarationADefinition()) {
@@ -143,7 +144,7 @@ public:
return true;
}
- bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
const ObjCInterfaceDecl *Class = D->getClassInterface();
if (!Class)
return true;
@@ -171,7 +172,7 @@ public:
return true;
}
- bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+ bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
IndexCtx.handleObjCCategory(D);
IndexCtx.indexTUDeclsInObjCContainer();
@@ -179,7 +180,7 @@ public:
return true;
}
- bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
const ObjCCategoryDecl *Cat = D->getCategoryDecl();
if (!Cat)
return true;
@@ -191,7 +192,7 @@ public:
return true;
}
- bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
// Methods associated with a property, even user-declared ones, are
// handled when we handle the property.
if (D->isPropertyAccessor())
@@ -201,7 +202,7 @@ public:
return true;
}
- bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
handleObjCMethod(MD);
@@ -213,7 +214,7 @@ public:
return true;
}
- bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
ObjCPropertyDecl *PD = D->getPropertyDecl();
IndexCtx.handleSynthesizedObjCProperty(D);
@@ -240,13 +241,13 @@ public:
return true;
}
- bool VisitNamespaceDecl(NamespaceDecl *D) {
+ bool VisitNamespaceDecl(const NamespaceDecl *D) {
IndexCtx.handleNamespace(D);
IndexCtx.indexDeclContext(D);
return true;
}
- bool VisitUsingDecl(UsingDecl *D) {
+ bool VisitUsingDecl(const UsingDecl *D) {
// FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
// we should do better.
@@ -259,7 +260,7 @@ public:
return true;
}
- bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
// FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
// we should do better.
@@ -269,14 +270,14 @@ public:
return true;
}
- bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ bool VisitClassTemplateDecl(const ClassTemplateDecl *D) {
IndexCtx.handleClassTemplate(D);
if (D->isThisDeclarationADefinition())
IndexCtx.indexDeclContext(D->getTemplatedDecl());
return true;
}
- bool VisitClassTemplateSpecializationDecl(
+ bool VisitClassTemplateSpecializationDecl(const
ClassTemplateSpecializationDecl *D) {
// FIXME: Notify subsequent callbacks if info comes from implicit
// instantiation.
@@ -287,7 +288,7 @@ public:
return true;
}
- bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
IndexCtx.handleFunctionTemplate(D);
FunctionDecl *FD = D->getTemplatedDecl();
handleDeclarator(FD, D);
@@ -300,13 +301,13 @@ public:
return true;
}
- bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
IndexCtx.handleTypeAliasTemplate(D);
IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
return true;
}
- bool VisitImportDecl(ImportDecl *D) {
+ bool VisitImportDecl(const ImportDecl *D) {
IndexCtx.importedModule(D);
return true;
}
@@ -318,7 +319,7 @@ void IndexingContext::indexDecl(const Decl *D) {
if (D->isImplicit() && shouldIgnoreIfImplicit(D))
return;
- bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
+ bool Handled = IndexingDeclVisitor(*this).Visit(D);
if (!Handled && isa<DeclContext>(D))
indexDeclContext(cast<DeclContext>(D));
}
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index 67a06f2..2c771c8 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "RecursiveASTVisitor.h"
using namespace clang;
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 714a36e..2a504db 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -8,28 +8,31 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
+#include "CIndexDiagnostic.h"
+#include "CIndexer.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
-#include "CXTranslationUnit.h"
#include "CXString.h"
-#include "CIndexDiagnostic.h"
-#include "CIndexer.h"
-
+#include "CXTranslationUnit.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclVisitor.h"
#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/Utils.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PPCallbacks.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "clang/Lex/PPConditionalDirectiveRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/SemaConsumer.h"
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
using namespace clang;
-using namespace cxstring;
using namespace cxtu;
using namespace cxindex;
@@ -38,6 +41,204 @@ static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx);
namespace {
//===----------------------------------------------------------------------===//
+// Skip Parsed Bodies
+//===----------------------------------------------------------------------===//
+
+#ifdef LLVM_ON_WIN32
+
+// FIXME: On windows it is disabled since current implementation depends on
+// file inodes.
+
+class SessionSkipBodyData { };
+
+class TUSkipBodyControl {
+public:
+ TUSkipBodyControl(SessionSkipBodyData &sessionData,
+ PPConditionalDirectiveRecord &ppRec,
+ Preprocessor &pp) { }
+ bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
+ return false;
+ }
+ void finished() { }
+};
+
+#else
+
+/// \brief A "region" in source code identified by the file/offset of the
+/// preprocessor conditional directive that it belongs to.
+/// Multiple, non-consecutive ranges can be parts of the same region.
+///
+/// As an example of different regions separated by preprocessor directives:
+///
+/// \code
+/// #1
+/// #ifdef BLAH
+/// #2
+/// #ifdef CAKE
+/// #3
+/// #endif
+/// #2
+/// #endif
+/// #1
+/// \endcode
+///
+/// There are 3 regions, with non-consecutive parts:
+/// #1 is identified as the beginning of the file
+/// #2 is identified as the location of "#ifdef BLAH"
+/// #3 is identified as the location of "#ifdef CAKE"
+///
+class PPRegion {
+ ino_t ino;
+ time_t ModTime;
+ dev_t dev;
+ unsigned Offset;
+public:
+ PPRegion() : ino(), ModTime(), dev(), Offset() {}
+ PPRegion(dev_t dev, ino_t ino, unsigned offset, time_t modTime)
+ : ino(ino), ModTime(modTime), dev(dev), Offset(offset) {}
+
+ ino_t getIno() const { return ino; }
+ dev_t getDev() const { return dev; }
+ unsigned getOffset() const { return Offset; }
+ time_t getModTime() const { return ModTime; }
+
+ bool isInvalid() const { return *this == PPRegion(); }
+
+ friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
+ return lhs.dev == rhs.dev && lhs.ino == rhs.ino &&
+ lhs.Offset == rhs.Offset && lhs.ModTime == rhs.ModTime;
+ }
+};
+
+typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
+
+} // end anonymous namespace
+
+namespace llvm {
+ template <> struct isPodLike<PPRegion> {
+ static const bool value = true;
+ };
+
+ template <>
+ struct DenseMapInfo<PPRegion> {
+ static inline PPRegion getEmptyKey() {
+ return PPRegion(0, 0, unsigned(-1), 0);
+ }
+ static inline PPRegion getTombstoneKey() {
+ return PPRegion(0, 0, unsigned(-2), 0);
+ }
+
+ static unsigned getHashValue(const PPRegion &S) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddInteger(S.getIno());
+ ID.AddInteger(S.getDev());
+ ID.AddInteger(S.getOffset());
+ ID.AddInteger(S.getModTime());
+ return ID.ComputeHash();
+ }
+
+ static bool isEqual(const PPRegion &LHS, const PPRegion &RHS) {
+ return LHS == RHS;
+ }
+ };
+}
+
+namespace {
+
+class SessionSkipBodyData {
+ llvm::sys::Mutex Mux;
+ PPRegionSetTy ParsedRegions;
+
+public:
+ SessionSkipBodyData() : Mux(/*recursive=*/false) {}
+ ~SessionSkipBodyData() {
+ //llvm::errs() << "RegionData: " << Skipped.size() << " - " << Skipped.getMemorySize() << "\n";
+ }
+
+ void copyTo(PPRegionSetTy &Set) {
+ llvm::MutexGuard MG(Mux);
+ Set = ParsedRegions;
+ }
+
+ void update(ArrayRef<PPRegion> Regions) {
+ llvm::MutexGuard MG(Mux);
+ ParsedRegions.insert(Regions.begin(), Regions.end());
+ }
+};
+
+class TUSkipBodyControl {
+ SessionSkipBodyData &SessionData;
+ PPConditionalDirectiveRecord &PPRec;
+ Preprocessor &PP;
+
+ PPRegionSetTy ParsedRegions;
+ SmallVector<PPRegion, 32> NewParsedRegions;
+ PPRegion LastRegion;
+ bool LastIsParsed;
+
+public:
+ TUSkipBodyControl(SessionSkipBodyData &sessionData,
+ PPConditionalDirectiveRecord &ppRec,
+ Preprocessor &pp)
+ : SessionData(sessionData), PPRec(ppRec), PP(pp) {
+ SessionData.copyTo(ParsedRegions);
+ }
+
+ bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
+ PPRegion region = getRegion(Loc, FID, FE);
+ if (region.isInvalid())
+ return false;
+
+ // Check common case, consecutive functions in the same region.
+ if (LastRegion == region)
+ return LastIsParsed;
+
+ LastRegion = region;
+ LastIsParsed = ParsedRegions.count(region);
+ if (!LastIsParsed)
+ NewParsedRegions.push_back(region);
+ return LastIsParsed;
+ }
+
+ void finished() {
+ SessionData.update(NewParsedRegions);
+ }
+
+private:
+ PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE) {
+ SourceLocation RegionLoc = PPRec.findConditionalDirectiveRegionLoc(Loc);
+ if (RegionLoc.isInvalid()) {
+ if (isParsedOnceInclude(FE))
+ return PPRegion(FE->getDevice(), FE->getInode(), 0,
+ FE->getModificationTime());
+ return PPRegion();
+ }
+
+ const SourceManager &SM = PPRec.getSourceManager();
+ assert(RegionLoc.isFileID());
+ FileID RegionFID;
+ unsigned RegionOffset;
+ llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
+
+ if (RegionFID != FID) {
+ if (isParsedOnceInclude(FE))
+ return PPRegion(FE->getDevice(), FE->getInode(), 0,
+ FE->getModificationTime());
+ return PPRegion();
+ }
+
+ return PPRegion(FE->getDevice(), FE->getInode(), RegionOffset,
+ FE->getModificationTime());
+ }
+
+ bool isParsedOnceInclude(const FileEntry *FE) {
+ return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
+ }
+};
+
+#endif
+
+//===----------------------------------------------------------------------===//
// IndexPPCallbacks
//===----------------------------------------------------------------------===//
@@ -80,19 +281,20 @@ public:
}
/// MacroDefined - This hook is called whenever a macro definition is seen.
- virtual void MacroDefined(const Token &Id, const MacroInfo *MI) {
+ virtual void MacroDefined(const Token &Id, const MacroDirective *MD) {
}
/// MacroUndefined - This hook is called whenever a macro #undef is seen.
/// MI is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// MacroExpands - This is called by when a macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
}
-
+
/// SourceRangeSkipped - This hook is called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// #if/#else directive and ends after the #endif/#else directive.
@@ -106,10 +308,11 @@ public:
class IndexingConsumer : public ASTConsumer {
IndexingContext &IndexCtx;
+ TUSkipBodyControl *SKCtrl;
public:
- explicit IndexingConsumer(IndexingContext &indexCtx)
- : IndexCtx(indexCtx) { }
+ IndexingConsumer(IndexingContext &indexCtx, TUSkipBodyControl *skCtrl)
+ : IndexCtx(indexCtx), SKCtrl(skCtrl) { }
// ASTConsumer Implementation
@@ -119,6 +322,8 @@ public:
}
virtual void HandleTranslationUnit(ASTContext &Ctx) {
+ if (SKCtrl)
+ SKCtrl->finished();
}
virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
@@ -152,6 +357,32 @@ public:
IndexCtx.indexDecl(D);
}
+
+ virtual bool shouldSkipFunctionBody(Decl *D) {
+ if (!SKCtrl) {
+ // Always skip bodies.
+ return true;
+ }
+
+ const SourceManager &SM = IndexCtx.getASTContext().getSourceManager();
+ SourceLocation Loc = D->getLocation();
+ if (Loc.isMacroID())
+ return false;
+ if (SM.isInSystemHeader(Loc))
+ return true; // always skip bodies from system headers.
+
+ FileID FID;
+ unsigned Offset;
+ llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
+ // Don't skip bodies from main files; this may be revisited.
+ if (SM.getMainFileID() == FID)
+ return false;
+ const FileEntry *FE = SM.getFileEntryForID(FID);
+ if (!FE)
+ return false;
+
+ return SKCtrl->isParsed(Loc, FID, FE);
+ }
};
//===----------------------------------------------------------------------===//
@@ -181,13 +412,17 @@ class IndexingFrontendAction : public ASTFrontendAction {
IndexingContext IndexCtx;
CXTranslationUnit CXTU;
+ SessionSkipBodyData *SKData;
+ OwningPtr<TUSkipBodyControl> SKCtrl;
+
public:
IndexingFrontendAction(CXClientData clientData,
IndexerCallbacks &indexCallbacks,
unsigned indexOptions,
- CXTranslationUnit cxTU)
+ CXTranslationUnit cxTU,
+ SessionSkipBodyData *skData)
: IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
- CXTU(cxTU) { }
+ CXTU(cxTU), SKData(skData) { }
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
@@ -202,7 +437,15 @@ public:
Preprocessor &PP = CI.getPreprocessor();
PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
IndexCtx.setPreprocessor(PP);
- return new IndexingConsumer(IndexCtx);
+
+ if (SKData) {
+ PPConditionalDirectiveRecord *
+ PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
+ PP.addPPCallbacks(PPRec);
+ SKCtrl.reset(new TUSkipBodyControl(*SKData, *PPRec, PP));
+ }
+
+ return new IndexingConsumer(IndexCtx, SKCtrl.get());
}
virtual void EndSourceFileAction() {
@@ -222,6 +465,14 @@ public:
// clang_indexSourceFileUnit Implementation
//===----------------------------------------------------------------------===//
+struct IndexSessionData {
+ CXIndex CIdx;
+ OwningPtr<SessionSkipBodyData> SkipBodyData;
+
+ explicit IndexSessionData(CXIndex cIdx)
+ : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
+};
+
struct IndexSourceFileInfo {
CXIndexAction idxAction;
CXClientData client_data;
@@ -253,7 +504,7 @@ struct MemBufferOwner {
static void clang_indexSourceFile_Impl(void *UserData) {
IndexSourceFileInfo *ITUI =
static_cast<IndexSourceFileInfo*>(UserData);
- CXIndex CIdx = (CXIndex)ITUI->idxAction;
+ CXIndexAction cxIdxAction = ITUI->idxAction;
CXClientData client_data = ITUI->client_data;
IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
unsigned index_callbacks_size = ITUI->index_callbacks_size;
@@ -271,7 +522,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
*out_TU = 0;
bool requestedToGetTU = (out_TU != 0);
- if (!CIdx)
+ if (!cxIdxAction)
return;
if (!client_index_callbacks || index_callbacks_size == 0)
return;
@@ -282,18 +533,21 @@ static void clang_indexSourceFile_Impl(void *UserData) {
? index_callbacks_size : sizeof(CB);
memcpy(&CB, client_index_callbacks, ClientCBSize);
- CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+ IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
+ CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
- CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
+ bool CaptureDiagnostics = !Logger::isLoggingEnabled();
+
+ CaptureDiagnosticConsumer *CaptureDiag = 0;
+ if (CaptureDiagnostics)
+ CaptureDiag = new CaptureDiagnosticConsumer();
// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
- num_command_line_args,
- command_line_args,
CaptureDiag,
/*ShouldOwnClient=*/true,
/*ShouldCloneClient=*/false));
@@ -359,7 +613,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
CInvok->getDiagnosticOpts().IgnoreWarnings = true;
ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
- /*CaptureDiagnostics=*/true,
+ CaptureDiagnostics,
/*UserFilesAreVolatile=*/true);
OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
@@ -367,9 +621,17 @@ static void clang_indexSourceFile_Impl(void *UserData) {
llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
CXTUCleanup(CXTU.get());
+ // Enable the skip-parsed-bodies optimization only for C++; this may be
+ // revisited.
+ bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
+ CInvok->getLangOpts()->CPlusPlus;
+ if (SkipBodies)
+ CInvok->getFrontendOpts().SkipFunctionBodies = true;
+
OwningPtr<IndexingFrontendAction> IndexAction;
IndexAction.reset(new IndexingFrontendAction(client_data, CB,
- index_options, CXTU->getTU()));
+ index_options, CXTU->getTU(),
+ SkipBodies ? IdxSession->SkipBodyData.get() : 0));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
@@ -404,7 +666,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
Persistent,
CXXIdx->getClangResourcesPath(),
OnlyLocalDecls,
- /*CaptureDiagnostics=*/true,
+ CaptureDiagnostics,
PrecompilePreamble,
CacheCodeCompletionResults,
/*IncludeBriefCommentsInCodeCompletion=*/false,
@@ -502,7 +764,7 @@ static void clang_indexTranslationUnit_Impl(void *UserData) {
if (!client_index_callbacks || index_callbacks_size == 0)
return;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
@@ -520,13 +782,13 @@ static void clang_indexTranslationUnit_Impl(void *UserData) {
IndexCtxCleanup(IndexCtx.get());
OwningPtr<IndexingConsumer> IndexConsumer;
- IndexConsumer.reset(new IndexingConsumer(*IndexCtx));
+ IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
IndexConsumerCleanup(IndexConsumer.get());
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
if (!Unit)
return;
@@ -690,12 +952,12 @@ void clang_index_setClientEntity(const CXIdxEntityInfo *info,
}
CXIndexAction clang_IndexAction_create(CXIndex CIdx) {
- // For now, CXIndexAction is featureless.
- return CIdx;
+ return new IndexSessionData(CIdx);
}
void clang_IndexAction_dispose(CXIndexAction idxAction) {
- // For now, CXIndexAction is featureless.
+ if (idxAction)
+ delete static_cast<IndexSessionData *>(idxAction);
}
int clang_indexSourceFile(CXIndexAction idxAction,
@@ -710,6 +972,11 @@ int clang_indexSourceFile(CXIndexAction idxAction,
unsigned num_unsaved_files,
CXTranslationUnit *out_TU,
unsigned TU_options) {
+ LOG_FUNC_SECTION {
+ *Log << source_filename << ": ";
+ for (int i = 0; i != num_command_line_args; ++i)
+ *Log << command_line_args[i] << " ";
+ }
IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks,
index_callbacks_size, index_options,
@@ -760,6 +1027,9 @@ int clang_indexTranslationUnit(CXIndexAction idxAction,
unsigned index_callbacks_size,
unsigned index_options,
CXTranslationUnit TU) {
+ LOG_FUNC_SECTION {
+ *Log << TU;
+ }
IndexTranslationUnitInfo ITUI = { idxAction, client_data, index_callbacks,
index_callbacks_size, index_options, TU,
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index d4daa49..3368922 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -8,12 +8,11 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-#include "CXTranslationUnit.h"
#include "CIndexDiagnostic.h"
-
-#include "clang/Frontend/ASTUnit.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/Frontend/ASTUnit.h"
using namespace clang;
using namespace cxindex;
@@ -70,7 +69,7 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
AttrI != AttrE; ++AttrI) {
const Attr *A = *AttrI;
- CXCursor C = MakeCXCursor(A, const_cast<Decl *>(D), IdxCtx.CXTU);
+ CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);
CXIdxLoc Loc = IdxCtx.getIndexLoc(A->getLocation());
switch (C.kind) {
default:
@@ -166,16 +165,16 @@ SourceLocation IndexingContext::CXXBasesListInfo::getBaseLoc(
if (TL.isNull())
return Loc;
- if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL))
- TL = QL->getUnqualifiedLoc();
+ if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>())
+ TL = QL.getUnqualifiedLoc();
- if (const ElaboratedTypeLoc *EL = dyn_cast<ElaboratedTypeLoc>(&TL))
- return EL->getNamedTypeLoc().getBeginLoc();
- if (const DependentNameTypeLoc *DL = dyn_cast<DependentNameTypeLoc>(&TL))
- return DL->getNameLoc();
- if (const DependentTemplateSpecializationTypeLoc *
- DTL = dyn_cast<DependentTemplateSpecializationTypeLoc>(&TL))
- return DTL->getTemplateNameLoc();
+ if (ElaboratedTypeLoc EL = TL.getAs<ElaboratedTypeLoc>())
+ return EL.getNamedTypeLoc().getBeginLoc();
+ if (DependentNameTypeLoc DL = TL.getAs<DependentNameTypeLoc>())
+ return DL.getNameLoc();
+ if (DependentTemplateSpecializationTypeLoc DTL =
+ TL.getAs<DependentTemplateSpecializationTypeLoc>())
+ return DTL.getTemplateNameLoc();
return Loc;
}
@@ -197,11 +196,11 @@ const char *ScratchAlloc::copyCStr(StringRef Str) {
void IndexingContext::setASTContext(ASTContext &ctx) {
Ctx = &ctx;
- static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
+ cxtu::getASTUnit(CXTU)->setASTContext(&ctx);
}
void IndexingContext::setPreprocessor(Preprocessor &PP) {
- static_cast<ASTUnit*>(CXTU->TUData)->setPreprocessor(&PP);
+ cxtu::getASTUnit(CXTU)->setPreprocessor(&PP);
}
bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
@@ -232,7 +231,9 @@ bool IndexingContext::shouldAbort() {
void IndexingContext::enteredMainFile(const FileEntry *File) {
if (File && CB.enteredMainFile) {
- CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0);
+ CXIdxClientFile idxFile =
+ CB.enteredMainFile(ClientData,
+ static_cast<CXFile>(const_cast<FileEntry *>(File)), 0);
FileMap[File] = idxFile;
}
}
@@ -248,7 +249,8 @@ void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
ScratchAlloc SA(*this);
CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
SA.toCStr(filename),
- (CXFile)File,
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(File)),
isImport, isAngled, isModuleImport };
CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
FileMap[File] = idxFile;
@@ -264,7 +266,8 @@ void IndexingContext::importedModule(const ImportDecl *ImportD) {
std::string ModuleName = Mod->getFullModuleName();
CXIdxImportedASTFileInfo Info = {
- (CXFile)Mod->getASTFile(),
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(Mod->getASTFile())),
Mod,
getIndexLoc(ImportD->getLocation()),
ImportD->isImplicit()
@@ -278,7 +281,8 @@ void IndexingContext::importedPCH(const FileEntry *File) {
return;
CXIdxImportedASTFileInfo Info = {
- (CXFile)File,
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(File)),
/*module=*/NULL,
getIndexLoc(SourceLocation()),
/*isImplicit=*/false
@@ -365,8 +369,18 @@ bool IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
}
bool IndexingContext::handleFunction(const FunctionDecl *D) {
- DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
- D->isThisDeclarationADefinition());
+ bool isDef = D->isThisDeclarationADefinition();
+ bool isContainer = isDef;
+ bool isSkipped = false;
+ if (D->hasSkippedBody()) {
+ isSkipped = true;
+ isDef = true;
+ isContainer = false;
+ }
+
+ DeclInfo DInfo(!D->isFirstDeclaration(), isDef, isContainer);
+ if (isSkipped)
+ DInfo.flags |= CXIdxDeclFlag_Skipped;
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
@@ -549,8 +563,18 @@ bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
}
bool IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
- DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
- D->isThisDeclarationADefinition());
+ bool isDef = D->isThisDeclarationADefinition();
+ bool isContainer = isDef;
+ bool isSkipped = false;
+ if (D->hasSkippedBody()) {
+ isSkipped = true;
+ isDef = true;
+ isContainer = false;
+ }
+
+ DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer);
+ if (isSkipped)
+ DInfo.flags |= CXIdxDeclFlag_Skipped;
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
@@ -625,8 +649,7 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
if (!D)
return false;
- CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
- const_cast<Decl*>(cast<Decl>(DC)), CXTU)
+ CXCursor Cursor = E ? MakeCXCursor(E, cast<Decl>(DC), CXTU)
: getRefCursor(D, Loc);
return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
}
@@ -808,7 +831,7 @@ IndexingContext::getEntityContainer(const Decl *D) const {
if (const ClassTemplateDecl *ClassTempl = dyn_cast<ClassTemplateDecl>(D)) {
DC = ClassTempl->getTemplatedDecl();
- } if (const FunctionTemplateDecl *
+ } else if (const FunctionTemplateDecl *
FuncTempl = dyn_cast<FunctionTemplateDecl>(D)) {
DC = FuncTempl->getTemplatedDecl();
}
@@ -844,7 +867,7 @@ CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
if (Loc.isInvalid())
return idxLoc;
- idxLoc.ptr_data[0] = (void*)this;
+ idxLoc.ptr_data[0] = const_cast<IndexingContext *>(this);
idxLoc.int_data = Loc.getRawEncoding();
return idxLoc;
}
@@ -870,7 +893,7 @@ void IndexingContext::translateLoc(SourceLocation Loc,
if (indexFile)
*indexFile = getIndexFile(FE);
if (file)
- *file = (void *)FE;
+ *file = const_cast<FileEntry *>(FE);
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 0fc7238..c9097c5 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -7,11 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Index_Internal.h"
#include "CXCursor.h"
-
-#include "clang/AST/DeclObjC.h"
+#include "Index_Internal.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/DenseSet.h"
#include <deque>
@@ -89,6 +88,7 @@ struct DeclInfo : public CXIdxDeclInfo {
attributes = 0;
numAttributes = 0;
declAsContainer = semanticContainer = lexicalContainer = 0;
+ flags = 0;
}
DeclInfo(DInfoKind K,
bool isRedeclaration, bool isDefinition, bool isContainer)
@@ -99,6 +99,7 @@ struct DeclInfo : public CXIdxDeclInfo {
attributes = 0;
numAttributes = 0;
declAsContainer = semanticContainer = lexicalContainer = 0;
+ flags = 0;
}
};
@@ -493,7 +494,7 @@ private:
void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo);
CXCursor getCursor(const Decl *D) {
- return cxcursor::MakeCXCursor(const_cast<Decl*>(D), CXTU);
+ return cxcursor::MakeCXCursor(D, CXTU);
}
CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 93f63cf..f33f345 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -16,12 +16,15 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
-USEDLIBS = clangARCMigrate.a clangRewriteCore.a clangRewriteFrontend.a \
- clangFrontend.a clangDriver.a \
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
+USEDLIBS = clangFrontend.a clangDriver.a \
+ clangTooling.a \
clangSerialization.a \
- clangParse.a clangSema.a clangEdit.a clangAnalysis.a \
- clangAST.a clangLex.a clangTooling.a clangBasic.a
+ clangParse.a clangSema.a \
+ clangARCMigrate.a clangRewriteFrontend.a clangRewriteCore.a \
+ clangAnalysis.a clangEdit.a \
+ clangAST.a clangLex.a clangBasic.a \
+ clangFormat.a
include $(CLANG_LEVEL)/Makefile
@@ -54,7 +57,7 @@ ifeq ($(HOST_OS),Darwin)
endif
# If we're doing an Apple-style build, add the LTO object path.
- ifeq ($(RC_BUILDIT),YES)
+ ifeq ($(RC_XBS),YES)
TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/clang-lto.XXXXXX)
LLVMLibsOptions += -Wl,-object_path_lto -Wl,$(TempFile)
endif
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
index 4844204..5862e12 100644
--- a/tools/libclang/RecursiveASTVisitor.h
+++ b/tools/libclang/RecursiveASTVisitor.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -535,7 +536,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL));
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -1199,6 +1200,8 @@ DEF_TRAVERSE_DECL(BlockDecl, {
return true;
})
+DEF_TRAVERSE_DECL(EmptyDecl, { })
+
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
TRY_TO(TraverseStmt(D->getAsmString()));
})
@@ -1323,6 +1326,14 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+ for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
+ E = D->varlist_end();
+ I != E; ++I) {
+ TRY_TO(TraverseStmt(*I));
+ }
+ })
+
// A helper method for TemplateDecl's children.
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
@@ -2027,8 +2038,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
// Visit the whole type.
TRY_TO(TraverseTypeLoc(TL));
- } else if (isa<FunctionProtoTypeLoc>(TL)) {
- FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
if (S->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
diff --git a/tools/libclang/SimpleFormatContext.h b/tools/libclang/SimpleFormatContext.h
new file mode 100644
index 0000000..016d0b6
--- /dev/null
+++ b/tools/libclang/SimpleFormatContext.h
@@ -0,0 +1,75 @@
+//===--- SimpleFormatContext.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+///
+/// \brief Defines a utility class for use of clang-format in libclang
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
+#define LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+
+/// \brief A small class to be used by libclang clients to format
+/// a declaration string in memory. This object is instantiated once
+/// and used each time a formatting is needed.
+class SimpleFormatContext {
+public:
+ SimpleFormatContext(LangOptions Options)
+ : DiagOpts(new DiagnosticOptions()),
+ Diagnostics(new DiagnosticsEngine(new DiagnosticIDs,
+ DiagOpts.getPtr())),
+ Files((FileSystemOptions())),
+ Sources(*Diagnostics, Files),
+ Rewrite(Sources, Options) {
+ Diagnostics->setClient(new IgnoringDiagConsumer, true);
+ }
+
+ ~SimpleFormatContext() { }
+
+ FileID createInMemoryFile(StringRef Name, StringRef Content) {
+ const llvm::MemoryBuffer *Source =
+ llvm::MemoryBuffer::getMemBuffer(Content);
+ const FileEntry *Entry =
+ Files.getVirtualFile(Name, Source->getBufferSize(), 0);
+ Sources.overrideFileContents(Entry, Source, true);
+ assert(Entry != NULL);
+ return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
+ }
+
+ std::string getRewrittenText(FileID ID) {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ Rewrite.getEditBuffer(ID).write(OS);
+ OS.flush();
+ return Result;
+ }
+
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
+ FileManager Files;
+ SourceManager Sources;
+ Rewriter Rewrite;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 4495b66..d99f24e 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -98,6 +98,8 @@ clang_equalLocations
clang_equalRanges
clang_equalTypes
clang_executeOnThread
+clang_findIncludesInFile
+clang_findIncludesInFileWithBlock
clang_findReferencesInFile
clang_findReferencesInFileWithBlock
clang_formatDiagnostic
@@ -160,10 +162,13 @@ clang_getElementType
clang_getEnumConstantDeclUnsignedValue
clang_getEnumConstantDeclValue
clang_getEnumDeclIntegerType
+clang_getFieldDeclBitWidth
clang_getExpansionLocation
clang_getFile
+clang_getFileLocation
clang_getFileName
clang_getFileTime
+clang_getFileUniqueID
clang_getFunctionTypeCallingConv
clang_getIBOutletCollectionType
clang_getIncludedFile
@@ -202,6 +207,7 @@ clang_getTranslationUnitCursor
clang_getTranslationUnitSpelling
clang_getTypeDeclaration
clang_getTypeKindSpelling
+clang_getTypeSpelling
clang_getTypedefDeclUnderlyingType
clang_hashCursor
clang_indexLoc_getCXSourceLocation
@@ -250,6 +256,7 @@ clang_tokenize
clang_CompilationDatabase_fromDirectory
clang_CompilationDatabase_dispose
clang_CompilationDatabase_getCompileCommands
+clang_CompilationDatabase_getAllCompileCommands
clang_CompileCommands_dispose
clang_CompileCommands_getSize
clang_CompileCommands_getCommand
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 8717225..bb6dd95 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -31,11 +31,11 @@ my $DefaultCCompiler;
my $DefaultCXXCompiler;
if (`uname -a` =~ m/Darwin/) {
- $DefaultCCompiler = 'clang';
- $DefaultCXXCompiler = 'clang++';
+ $DefaultCCompiler = 'clang';
+ $DefaultCXXCompiler = 'clang++';
} else {
- $DefaultCCompiler = 'gcc';
- $DefaultCXXCompiler = 'g++';
+ $DefaultCCompiler = 'gcc';
+ $DefaultCXXCompiler = 'g++';
}
if ($FindBin::Script =~ /c\+\+-analyzer/) {
@@ -252,6 +252,7 @@ sub Analyze {
print $ofh $_;
print STDERR $_;
}
+ close $ofh;
waitpid($pid,0);
close(FROM_CHILD);
@@ -269,7 +270,7 @@ sub Analyze {
$HtmlDir, $ParserRejects, $ofile);
} else {
ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
- $HtmlDir, $OtherError, $ofile);
+ $HtmlDir, $OtherError, $ofile);
}
}
else {
@@ -389,6 +390,7 @@ my %LangMap = (
'cxx' => 'c++',
'txx' => 'c++',
'cc' => 'c++',
+ 'C' => 'c++',
'ii' => 'c++',
'i' => 'c-cpp-output',
'm' => 'objective-c',
@@ -489,6 +491,15 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
next;
}
+ if ($Arg =~ /-msse.*/) {
+ push @CompileOpts,$Arg;
+ next;
+ }
+ # Handle the case where there isn't a space after -iquote
+ if ($Arg =~ /-iquote.*/) {
+ push @CompileOpts,$Arg;
+ next;
+ }
# Options with possible arguments that should pass through to linker.
if (defined $LinkerOptionMap{$ArgKey}) {
@@ -617,7 +628,7 @@ if ($Action eq 'compile' or $Action eq 'link') {
my @Archs = keys %ArchsSeen;
# Skip the file if we don't support the architectures specified.
exit 0 if ($HadArch && scalar(@Archs) == 0);
-
+
foreach my $file (@Files) {
# Determine the language for the file.
my $FileLang = $Lang;
@@ -671,7 +682,7 @@ if ($Action eq 'compile' or $Action eq 'link') {
$ResultFile = $f;
# If the HtmlDir is not set, we sould clean up the plist files.
if (!defined $HtmlDir || -z $HtmlDir) {
- $CleanupFile = $f;
+ $CleanupFile = $f;
}
}
}
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index a13b235..32eecc0 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -17,6 +17,7 @@ use warnings;
use FindBin qw($RealBin);
use Digest::MD5;
use File::Basename;
+use File::Find;
use Term::ANSIColor;
use Term::ANSIColor qw(:constants);
use Cwd qw/ getcwd abs_path /;
@@ -57,6 +58,16 @@ sub Diag {
}
}
+sub ErrorDiag {
+ if ($UseColor) {
+ print STDERR BOLD, RED "$Prog: ";
+ print STDERR RESET, RED @_;
+ print STDERR RESET;
+ } else {
+ print STDERR "$Prog: @_";
+ }
+}
+
sub DiagCrashes {
my $Dir = shift;
Diag ("The analyzer encountered problems on some source files.\n");
@@ -67,14 +78,14 @@ sub DiagCrashes {
sub DieDiag {
if ($UseColor) {
- print BOLD, RED "$Prog: ";
- print RESET, RED @_;
- print RESET;
+ print STDERR BOLD, RED "$Prog: ";
+ print STDERR RESET, RED @_;
+ print STDERR RESET;
}
else {
- print "$Prog: ", @_;
+ print STDERR "$Prog: ", @_;
}
- exit(0);
+ exit 1;
}
##----------------------------------------------------------------------------##
@@ -89,7 +100,7 @@ if (grep /^--help-checkers$/, @ARGV) {
my ($sign, $name, @text) = split ' ', $_;
print $name, $/ if $sign eq '+';
}
- exit 1;
+ exit 0;
}
##----------------------------------------------------------------------------##
@@ -110,13 +121,8 @@ sub GetHTMLRunDir {
my $Dir = shift @_;
my $TmpMode = 0;
if (!defined $Dir) {
- if (`uname` =~ /Darwin/) {
- $Dir = $ENV{'TMPDIR'};
- if (!defined $Dir) { $Dir = "/tmp"; }
- }
- else {
- $Dir = "/tmp";
- }
+ $Dir = $ENV{'TMPDIR'};
+ if (!defined $Dir) { $Dir = "/tmp"; }
$TmpMode = 1;
}
@@ -288,10 +294,11 @@ sub UpdateInFilePath {
sub AddStatLine {
my $Line = shift;
my $Stats = shift;
+ my $File = shift;
print $Line . "\n";
- my $Regex = qr/(.*?)\ :\ (.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable
+ my $Regex = qr/(.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable
\ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList:
\ (yes|no)/x;
@@ -301,12 +308,12 @@ sub AddStatLine {
# Create a hash of the interesting fields
my $Row = {
- Filename => $1,
- Function => $2,
- Total => $3,
- Unreachable => $4,
- Aborted => $5,
- Empty => $6
+ Filename => $File,
+ Function => $1,
+ Total => $2,
+ Unreachable => $3,
+ Aborted => $4,
+ Empty => $5
};
# Add them to the stats array
@@ -387,7 +394,7 @@ sub ScanFile {
# Don't add internal statistics to the bug reports
if ($BugCategory =~ /statistics/i) {
- AddStatLine($BugDescription, $Stats);
+ AddStatLine($BugDescription, $Stats, $BugFile);
return;
}
@@ -475,11 +482,24 @@ sub CalcStats {
# Postprocess - Postprocess the results of an analysis scan.
##----------------------------------------------------------------------------##
+my @filesFound;
+my $baseDir;
+sub FileWanted {
+ my $baseDirRegEx = quotemeta $baseDir;
+ my $file = $File::Find::name;
+ if ($file =~ /report-.*\.html$/) {
+ my $relative_file = $file;
+ $relative_file =~ s/$baseDirRegEx//g;
+ push @filesFound, $relative_file;
+ }
+}
+
sub Postprocess {
my $Dir = shift;
my $BaseDir = shift;
my $AnalyzerStats = shift;
+ my $KeepEmpty = shift;
die "No directory specified." if (!defined $Dir);
@@ -487,21 +507,23 @@ sub Postprocess {
Diag("No bugs found.\n");
return 0;
}
-
- opendir(DIR, $Dir);
- my @files = grep { /^report-.*\.html$/ } readdir(DIR);
- closedir(DIR);
- if (scalar(@files) == 0 and ! -e "$Dir/failures") {
- Diag("Removing directory '$Dir' because it contains no reports.\n");
- system ("rm", "-fR", $Dir);
+ $baseDir = $Dir . "/";
+ find({ wanted => \&FileWanted, follow => 0}, $Dir);
+
+ if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") {
+ if (! $KeepEmpty) {
+ Diag("Removing directory '$Dir' because it contains no reports.\n");
+ system ("rm", "-fR", $Dir);
+ }
+ Diag("No bugs found.\n");
return 0;
}
# Scan each report file and build an index.
my @Index;
my @Stats;
- foreach my $file (@files) { ScanFile(\@Index, $Dir, $file, \@Stats); }
+ foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); }
# Scan the failures directory and use the information in the .info files
# to update the common prefix directory.
@@ -603,7 +625,7 @@ print OUT <<ENDTEXT;
</table>
ENDTEXT
- if (scalar(@files)) {
+ if (scalar(@filesFound)) {
# Print out the summary table.
my %Totals;
@@ -884,6 +906,39 @@ sub RunXcodebuild {
if ($IgnoreErrors) {
AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
}
+
+ # Detect the version of Xcode. If Xcode 4.6 or higher, use new
+ # in situ support for analyzer interposition without needed to override
+ # the compiler.
+ open(DETECT_XCODE, "xcodebuild -version |") or
+ die "error: cannot detect version of xcodebuild\n";
+
+ my $oldBehavior = 1;
+
+ while(<DETECT_XCODE>) {
+ if (/^Xcode (.+)$/) {
+ my $ver = $1;
+ if ($ver =~ /^([0-9]+[.][0-9]+)[^0-9]?/) {
+ if ($1 >= 4.6) {
+ $oldBehavior = 0;
+ last;
+ }
+ }
+ }
+ }
+ close(DETECT_XCODE);
+
+ if ($oldBehavior == 0) {
+ my $OutputDir = $Options->{"OUTPUT_DIR"};
+ my $CLANG = $Options->{"CLANG"};
+ push @$Args,
+ "RUN_CLANG_STATIC_ANALYZER=YES",
+ "CLANG_ANALYZER_OUTPUT=plist-html",
+ "CLANG_ANALYZER_EXEC=$CLANG",
+ "CLANG_ANALYZER_OUTPUT_DIR=$OutputDir";
+
+ return (system(@$Args) >> 8);
+ }
# Default to old behavior where we insert a bogus compiler.
SetEnv($Options);
@@ -1086,7 +1141,11 @@ ADVANCED OPTIONS:
scan-build uses the 'clang' executable relative to itself for static
analysis. One can override this behavior with this option by using the
'clang' packaged with Xcode (on OS X) or from the PATH.
-
+
+ --keep-empty
+
+ Don't remove the build results directory even if no issues were reported.
+
CONTROLLING CHECKERS:
A default group of checkers are always run unless explicitly disabled.
@@ -1253,6 +1312,7 @@ my $HtmlDir; # Parent directory to store HTML files.
my $IgnoreErrors = 0; # Ignore build errors.
my $ViewResults = 0; # View results when the build terminates.
my $ExitStatusFoundBugs = 0; # Exit status reflects whether bugs were found
+my $KeepEmpty = 0; # Don't remove output directory even with 0 results.
my @AnalysesToRun;
my $StoreModel;
my $ConstraintsModel;
@@ -1260,16 +1320,14 @@ my $InternalStats;
my $OutputFormat = "html";
my $AnalyzerStats = 0;
my $MaxLoop = 0;
+my $RequestDisplayHelp = 0;
+my $ForceDisplayHelp = 0;
+my $AnalyzerDiscoveryMethod;
if (!@ARGV) {
- DisplayHelp();
- exit 1;
+ $ForceDisplayHelp = 1
}
-
-my $displayHelp = 0;
-my $AnalyzerDiscoveryMethod;
-
while (@ARGV) {
# Scan for options we recognize.
@@ -1277,7 +1335,7 @@ while (@ARGV) {
my $arg = $ARGV[0];
if ($arg eq "-h" or $arg eq "--help") {
- $displayHelp = 1;
+ $RequestDisplayHelp = 1;
shift @ARGV;
next;
}
@@ -1446,15 +1504,20 @@ while (@ARGV) {
$AnalyzerDiscoveryMethod = $1;
next;
}
+ if ($arg eq "--keep-empty") {
+ shift @ARGV;
+ $KeepEmpty = 1;
+ next;
+ }
DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
last;
}
-if (!@ARGV and $displayHelp == 0) {
- Diag("No build command specified.\n\n");
- $displayHelp = 1;
+if (!@ARGV and !$RequestDisplayHelp) {
+ ErrorDiag("No build command specified.\n\n");
+ $ForceDisplayHelp = 1;
}
# Find 'clang'
@@ -1464,7 +1527,7 @@ if (!defined $AnalyzerDiscoveryMethod) {
$Clang = Cwd::realpath("$RealBin/clang");
}
if (!defined $Clang || ! -x $Clang) {
- if (!$displayHelp) {
+ if (!$RequestDisplayHelp && !$ForceDisplayHelp) {
DieDiag("error: Cannot find an executable 'clang' relative to scan-build." .
" Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n");
}
@@ -1485,21 +1548,22 @@ else {
}
else {
$Clang = Cwd::realpath($AnalyzerDiscoveryMethod);
- if (! -x $Clang) {
- DieDiag("Cannot find an executable clang at '$Clang'\n");
+ if (!defined $Clang or not -x $Clang) {
+ DieDiag("Cannot find an executable clang at '$AnalyzerDiscoveryMethod'\n");
}
}
}
-if ($displayHelp) {
+if ($ForceDisplayHelp || $RequestDisplayHelp) {
DisplayHelp();
- exit 1;
+ exit $ForceDisplayHelp;
}
$ClangCXX = $Clang;
$ClangCXX =~ s/\-\d+\.\d+$//;
$ClangCXX .= "++";
-$ClangVersion = HtmlEscape(`$Clang --version`);
+# Make sure to use "" to handle paths with spaces.
+$ClangVersion = HtmlEscape(`"$Clang" --version`);
# Determine where results go.
$CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
@@ -1568,9 +1632,9 @@ if (defined $OutputFormat) {
Diag "Analysis run complete.\n";
Diag "Analysis results (plist files) deposited in '$HtmlDir'\n";
}
- elsif ($OutputFormat =~ /html/) {
+ if ($OutputFormat =~ /html/) {
# Postprocess the HTML directory.
- my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats);
+ my $NumBugs = Postprocess($HtmlDir, $BaseDir, $AnalyzerStats, $KeepEmpty);
if ($ViewResults and -r "$HtmlDir/index.html") {
Diag "Analysis run complete.\n";
diff --git a/tools/scan-build/set-xcode-analyzer b/tools/scan-build/set-xcode-analyzer
index 93824af..3076b39 100755
--- a/tools/scan-build/set-xcode-analyzer
+++ b/tools/scan-build/set-xcode-analyzer
@@ -4,9 +4,13 @@
# want to the use the system version of Python on Mac OS X.
# This one has the scripting bridge enabled.
+import sys
+if sys.version_info < (2, 7):
+ print "set-xcode-analyzer requires Python 2.7 or later"
+ sys.exit(1)
+
import os
import subprocess
-import sys
import re
import tempfile
import shutil
@@ -41,6 +45,8 @@ def ModifySpec(path, isBuiltinAnalyzer, pathToChecker):
m = re.search('^(\s*ExecPath\s*=\s*")', line)
if m:
line = "".join([m.group(0), pathToChecker, '";\n'])
+ # Do not modify further ExecPath's later in the xcspec.
+ foundAnalyzer = False
t.write(line)
t.close()
print "(+) processing:", path
@@ -70,7 +76,7 @@ def main():
for x in NSWorkspace.sharedWorkspace().runningApplications():
if x.localizedName().find("Xcode") >= 0:
print "(-) You must quit Xcode first before modifying its configuration files."
- return
+ sys.exit(1)
isBuiltinAnalyzer = False
if options.path:
OpenPOWER on IntegriCloud