merge pnacl's clang 3.4 merge
diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..9b3aa8b
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1 @@
+BasedOnStyle: LLVM
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcd5c52..8d02bf0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,12 +19,14 @@
endif()
endif()
- if( NOT EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
- # Looking for bin/Debug/llvm-tblgen is a complete hack. How can we get
+ if (EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
+ set (PATH_TO_LLVM_CONFIG "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
+ elseif (EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
+ # Looking for bin/Debug/llvm-config is a complete hack. How can we get
# around this?
- if( NOT EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
- message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.")
- endif()
+ set (PATH_TO_LLVM_CONFIG "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
+ else()
+ message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.")
endif()
list(APPEND CMAKE_MODULE_PATH "${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
@@ -32,6 +34,8 @@
get_filename_component(PATH_TO_LLVM_BUILD ${CLANG_PATH_TO_LLVM_BUILD}
ABSOLUTE)
+ option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
+
include(AddLLVM)
include(TableGen)
include("${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
@@ -46,12 +50,8 @@
include_directories("${PATH_TO_LLVM_BUILD}/include" "${LLVM_MAIN_INCLUDE_DIR}")
link_directories("${PATH_TO_LLVM_BUILD}/lib")
- if( EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
- set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}")
- else()
- # FIXME: This is an utter hack.
- set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/Debug/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}")
- endif()
+ exec_program("${PATH_TO_LLVM_CONFIG} --bindir" OUTPUT_VARIABLE LLVM_BINARY_DIR)
+ set(LLVM_TABLEGEN_EXE "${LLVM_BINARY_DIR}/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}")
# Define the default arguments to use with 'lit', and an option for the user
# to override.
@@ -90,6 +90,16 @@
add_definitions( -DCLANG_VENDOR="${CLANG_VENDOR} " )
endif()
+set(CLANG_REPOSITORY_STRING "" CACHE STRING
+ "Vendor-specific text for showing the repository the source is taken from.")
+
+if(CLANG_REPOSITORY_STRING)
+ add_definitions(-DCLANG_REPOSITORY_STRING="${CLANG_REPOSITORY_STRING}")
+endif()
+
+set(CLANG_VENDOR_UTI "org.llvm.clang" CACHE STRING
+ "Vendor-specific uti.")
+
set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
@@ -151,7 +161,7 @@
endif ()
if (APPLE)
- set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
endif ()
configure_file(
@@ -189,6 +199,41 @@
endif()
endfunction(clang_tablegen)
+# FIXME: Generalize and move to llvm.
+function(add_clang_symbol_exports target_name export_file)
+ # Makefile.rules contains special cases for different platforms.
+ # We restrict ourselves to Darwin for the time being.
+ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ add_custom_command(OUTPUT symbol.exports
+ COMMAND sed -e "s/^/_/" < ${export_file} > symbol.exports
+ DEPENDS ${export_file}
+ VERBATIM
+ COMMENT "Creating export file for ${target_name}")
+ add_custom_target(${target_name}_exports DEPENDS symbol.exports)
+ set_property(DIRECTORY APPEND
+ PROPERTY ADDITIONAL_MAKE_CLEAN_FILES symbol.exports)
+
+ get_property(srcs TARGET ${target_name} PROPERTY SOURCES)
+ foreach(src ${srcs})
+ get_filename_component(extension ${src} EXT)
+ if(extension STREQUAL ".cpp")
+ set(first_source_file ${src})
+ break()
+ endif()
+ endforeach()
+
+ # Force re-linking when the exports file changes. Actually, it
+ # forces recompilation of the source file. The LINK_DEPENDS target
+ # property only works for makefile-based generators.
+ set_property(SOURCE ${first_source_file} APPEND PROPERTY
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/symbol.exports)
+
+ set_property(TARGET ${target_name} APPEND_STRING PROPERTY
+ LINK_FLAGS " -Wl,-exported_symbols_list,${CMAKE_CURRENT_BINARY_DIR}/symbol.exports")
+ add_dependencies(${target_name} ${target_name}_exports)
+ endif()
+endfunction(add_clang_symbol_exports)
+
macro(add_clang_library name)
llvm_process_sources(srcs ${ARGN})
if(MSVC_IDE OR XCODE)
@@ -228,11 +273,18 @@
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
target_link_libraries( ${name} ${LLVM_COMMON_LIBS} )
link_system_libs( ${name} )
+
+ if (SHARED_LIBRARY AND EXPORTED_SYMBOL_FILE)
+ add_clang_symbol_exports( ${name} ${EXPORTED_SYMBOL_FILE} )
+ endif()
- install(TARGETS ${name}
- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
- RUNTIME DESTINATION bin)
+ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
+ install(TARGETS ${name}
+ LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+ ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+ RUNTIME DESTINATION bin)
+ endif()
+
set_target_properties(${name} PROPERTIES FOLDER "Clang libraries")
endmacro(add_clang_library)
@@ -246,26 +298,58 @@
${CMAKE_CURRENT_SOURCE_DIR}/include
)
-install(DIRECTORY include/
- DESTINATION include
- FILES_MATCHING
- PATTERN "*.def"
- PATTERN "*.h"
- PATTERN "config.h" EXCLUDE
- PATTERN ".svn" EXCLUDE
- )
+if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+ install(DIRECTORY include/
+ DESTINATION include
+ FILES_MATCHING
+ PATTERN "*.def"
+ PATTERN "*.h"
+ PATTERN "config.h" EXCLUDE
+ PATTERN ".svn" EXCLUDE
+ )
-install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
+ DESTINATION include
+ FILES_MATCHING
+ PATTERN "CMakeFiles" EXCLUDE
+ PATTERN "*.inc"
+ )
+endif()
+
+install(DIRECTORY include/clang-c
DESTINATION include
FILES_MATCHING
- PATTERN "CMakeFiles" EXCLUDE
- PATTERN "*.inc"
+ PATTERN "*.h"
+ PATTERN ".svn" EXCLUDE
)
add_definitions( -D_GNU_SOURCE )
-# FIXME: They should be options.
-add_definitions(-DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_REWRITER -DCLANG_ENABLE_STATIC_ANALYZER)
+option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
+option(CLANG_ENABLE_REWRITER "Build rewriter." ON)
+option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON)
+
+if (NOT CLANG_ENABLE_REWRITER AND CLANG_ENABLE_ARCMT)
+ message(FATAL_ERROR "Cannot disable rewriter while enabling ARCMT")
+endif()
+
+if (NOT CLANG_ENABLE_REWRITER AND CLANG_ENABLE_STATIC_ANALYZER)
+ message(FATAL_ERROR "Cannot disable rewriter while enabling static analyzer")
+endif()
+
+if (NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT)
+ message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT")
+endif()
+
+if(CLANG_ENABLE_ARCMT)
+ add_definitions(-DCLANG_ENABLE_ARCMT)
+endif()
+if(CLANG_ENABLE_REWRITER)
+ add_definitions(-DCLANG_ENABLE_REWRITER)
+endif()
+if(CLANG_ENABLE_STATIC_ANALYZER)
+ add_definitions(-DCLANG_ENABLE_STATIC_ANALYZER)
+endif()
# Clang version information
set(CLANG_EXECUTABLE_VERSION
@@ -291,12 +375,16 @@
${LLVM_INCLUDE_TESTS})
if( CLANG_INCLUDE_TESTS )
- # TODO: docs.
- add_subdirectory(test) # XXX Emscripten: Backport fix from upstream LLVM 3.4 to actually skip tests if CLANG_INCLUDE_TESTS = OFF
-
+ add_subdirectory(test)
add_subdirectory(unittests)
endif()
+option(CLANG_INCLUDE_DOCS "Generate build targets for the Clang docs."
+ ${LLVM_INCLUDE_DOCS})
+if( CLANG_INCLUDE_DOCS )
+ add_subdirectory(docs)
+endif()
+
# Workaround for MSVS10 to avoid the Dialog Hell
# FIXME: This could be removed with future version of CMake.
if( CLANG_BUILT_STANDALONE AND MSVC_VERSION EQUAL 1600 )
@@ -309,3 +397,5 @@
set(BUG_REPORT_URL "http://llvm.org/bugs/" CACHE STRING
"Default URL where bug reports are to be submitted.")
+set(CLANG_ORDER_FILE "" CACHE FILEPATH
+ "Order file to use when compiling clang in order to improve startup time.")
diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT
index 13c0a9b..af50831 100644
--- a/CODE_OWNERS.TXT
+++ b/CODE_OWNERS.TXT
@@ -32,7 +32,7 @@
D: Clang LLVM IR generation
N: Chad Rosier
-E: mcrosier@apple.com
+E: mcrosier@codeaurora.org
D: MS-inline asm, and the compiler driver
N: Richard Smith
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 880a150..c103c70 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -266,6 +266,29 @@
def __ne__(self, other):
return not self.__eq__(other)
+ def __contains__(self, other):
+ """Useful to detect the Token/Lexer bug"""
+ if not isinstance(other, SourceLocation):
+ return False
+ if other.file is None and self.start.file is None:
+ pass
+ elif ( self.start.file.name != other.file.name or
+ other.file.name != self.end.file.name):
+ # same file name
+ return False
+ # same file, in between lines
+ if self.start.line < other.line < self.end.line:
+ return True
+ elif self.start.line == other.line:
+ # same file first line
+ if self.start.column <= other.column:
+ return True
+ elif other.line == self.end.line:
+ # same file last line
+ if other.column <= self.end.column:
+ return True
+ return False
+
def __repr__(self):
return "<SourceRange start %r, end %r>" % (self.start, self.end)
@@ -508,7 +531,7 @@
@staticmethod
def from_id(id):
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
- raise ValueError,'Unknown cursor kind'
+ raise ValueError,'Unknown cursor kind %d' % id
return CursorKind._kinds[id]
@staticmethod
@@ -721,10 +744,14 @@
# A reference to a labeled statement.
CursorKind.LABEL_REF = CursorKind(48)
-# A reference toa a set of overloaded functions or function templates
+# A reference to a set of overloaded functions or function templates
# that has not yet been resolved to a specific function or function template.
CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
+# A reference to a variable that occurs in some non-expression
+# context, e.g., a C++ lambda capture list.
+CursorKind.VARIABLE_REF = CursorKind(50)
+
###
# Invalid/Error Kinds
@@ -908,6 +935,26 @@
# pack.
CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
+# Represents a C++ lambda expression that produces a local function
+# object.
+#
+# \code
+# void abssort(float *x, unsigned N) {
+# std::sort(x, x + N,
+# [](float a, float b) {
+# return std::abs(a) < std::abs(b);
+# });
+# }
+# \endcode
+CursorKind.LAMBDA_EXPR = CursorKind(144)
+
+# Objective-c Boolean Literal.
+CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
+
+# Represents the "self" expression in a ObjC method.
+CursorKind.OBJ_SELF_EXPR = CursorKind(146)
+
+
# A statement whose specific kind is not exposed via this interface.
#
# Unexposed statements have the same operations as any other kind of statement;
@@ -999,6 +1046,9 @@
# Windows Structured Exception Handling's finally statement.
CursorKind.SEH_FINALLY_STMT = CursorKind(228)
+# A MS inline assembly statement extension.
+CursorKind.MS_ASM_STMT = CursorKind(229)
+
# The null statement.
CursorKind.NULL_STMT = CursorKind(230)
@@ -1028,6 +1078,7 @@
CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405)
CursorKind.ANNOTATE_ATTR = CursorKind(406)
CursorKind.ASM_LABEL_ATTR = CursorKind(407)
+CursorKind.PACKED_ATTR = CursorKind(408)
###
# Preprocessing
@@ -1036,6 +1087,12 @@
CursorKind.MACRO_INSTANTIATION = CursorKind(502)
CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
+###
+# Extra declaration
+
+# A module import declaration.
+CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
+
### Cursors ###
class Cursor(Structure):
@@ -1282,6 +1339,16 @@
return self._referenced
+ @property
+ def brief_comment(self):
+ """Returns the brief comment text associated with that Cursor"""
+ return conf.lib.clang_Cursor_getBriefCommentText(self)
+
+ @property
+ def raw_comment(self):
+ """Returns the raw comment text associated with that Cursor"""
+ return conf.lib.clang_Cursor_getRawCommentText(self)
+
def get_arguments(self):
"""Return an iterator for accessing the arguments of this cursor."""
num_args = conf.lib.clang_Cursor_getNumArguments(self)
@@ -1450,6 +1517,54 @@
TypeKind.FUNCTIONPROTO = TypeKind(111)
TypeKind.CONSTANTARRAY = TypeKind(112)
TypeKind.VECTOR = TypeKind(113)
+TypeKind.INCOMPLETEARRAY = TypeKind(114)
+TypeKind.VARIABLEARRAY = TypeKind(115)
+TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
+TypeKind.MEMBERPOINTER = TypeKind(117)
+
+class RefQualifierKind(object):
+ """Describes a specific ref-qualifier of a type."""
+
+ # The unique kind objects, indexed by id.
+ _kinds = []
+ _name_map = None
+
+ def __init__(self, value):
+ if value >= len(RefQualifierKind._kinds):
+ num_kinds = value - len(RefQualifierKind._kinds) + 1
+ RefQualifierKind._kinds += [None] * num_kinds
+ if RefQualifierKind._kinds[value] is not None:
+ raise ValueError, 'RefQualifierKind already loaded'
+ self.value = value
+ RefQualifierKind._kinds[value] = self
+ RefQualifierKind._name_map = None
+
+ def from_param(self):
+ return self.value
+
+ @property
+ def name(self):
+ """Get the enumeration name of this kind."""
+ if self._name_map is None:
+ self._name_map = {}
+ for key, value in RefQualifierKind.__dict__.items():
+ if isinstance(value, RefQualifierKind):
+ self._name_map[value] = key
+ return self._name_map[self]
+
+ @staticmethod
+ def from_id(id):
+ if (id >= len(RefQualifierKind._kinds) or
+ RefQualifierKind._kinds[id] is None):
+ raise ValueError, 'Unknown type kind %d' % id
+ return RefQualifierKind._kinds[id]
+
+ def __repr__(self):
+ return 'RefQualifierKind.%s' % (self.name,)
+
+RefQualifierKind.NONE = RefQualifierKind(0)
+RefQualifierKind.LVALUE = RefQualifierKind(1)
+RefQualifierKind.RVALUE = RefQualifierKind(2)
class Type(Structure):
"""
@@ -1625,6 +1740,12 @@
"""
return conf.lib.clang_getArraySize(self)
+ def get_class_type(self):
+ """
+ Retrieve the class type of the member pointer type.
+ """
+ return conf.lib.clang_Type_getClassType(self)
+
def get_align(self):
"""
Retrieve the alignment of the record.
@@ -1643,6 +1764,18 @@
"""
return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
+ def get_ref_qualifier(self):
+ """
+ Retrieve the ref-qualifier of the type.
+ """
+ return RefQualifierKind.from_id(
+ conf.lib.clang_Type_getCXXRefQualifier(self))
+
+ @property
+ def spelling(self):
+ """Retrieve the spelling of this Type."""
+ return conf.lib.clang_getTypeSpelling(self)
+
def __eq__(self, other):
if type(other) != type(self):
return False
@@ -1918,7 +2051,7 @@
def read(self, path):
"""Load a TranslationUnit from the given AST file."""
- return TranslationUnit.from_ast(path, self)
+ return TranslationUnit.from_ast_file(path, self)
def parse(self, path, args=None, unsaved_files=None, options = 0):
"""Load the translation unit from the given source code file by running
@@ -2590,6 +2723,10 @@
[Index, c_char_p],
c_object_p),
+ ("clang_CXXMethod_isPureVirtual",
+ [Cursor],
+ bool),
+
("clang_CXXMethod_isStatic",
[Cursor],
bool),
@@ -2973,6 +3110,11 @@
_CXString,
_CXString.from_result),
+ ("clang_getTypeSpelling",
+ [Type],
+ _CXString,
+ _CXString.from_result),
+
("clang_hashCursor",
[Cursor],
c_uint),
@@ -3077,17 +3219,36 @@
[Cursor],
bool),
+ ("clang_Cursor_getBriefCommentText",
+ [Cursor],
+ _CXString,
+ _CXString.from_result),
+
+ ("clang_Cursor_getRawCommentText",
+ [Cursor],
+ _CXString,
+ _CXString.from_result),
+
("clang_Type_getAlignOf",
[Type],
c_longlong),
+ ("clang_Type_getClassType",
+ [Type],
+ Type,
+ Type.from_result),
+
("clang_Type_getOffsetOf",
[Type, c_char_p],
c_longlong),
("clang_Type_getSizeOf",
[Type],
- c_ulonglong),
+ c_longlong),
+
+ ("clang_Type_getCXXRefQualifier",
+ [Type],
+ c_uint),
]
class LibclangError(Exception):
diff --git a/bindings/python/tests/cindex/test_comment.py b/bindings/python/tests/cindex/test_comment.py
new file mode 100644
index 0000000..d8f3129
--- /dev/null
+++ b/bindings/python/tests/cindex/test_comment.py
@@ -0,0 +1,40 @@
+from clang.cindex import TranslationUnit
+from tests.cindex.util import get_cursor
+
+def test_comment():
+ files = [('fake.c', """
+/// Aaa.
+int test1;
+
+/// Bbb.
+/// x
+void test2(void);
+
+void f() {
+
+}
+""")]
+ # make a comment-aware TU
+ tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
+ options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
+ test1 = get_cursor(tu, 'test1')
+ assert test1 is not None, "Could not find test1."
+ assert test1.type.is_pod()
+ raw = test1.raw_comment
+ brief = test1.brief_comment
+ assert raw == """/// Aaa."""
+ assert brief == """Aaa."""
+
+ test2 = get_cursor(tu, 'test2')
+ raw = test2.raw_comment
+ brief = test2.brief_comment
+ assert raw == """/// Bbb.\n/// x"""
+ assert brief == """Bbb. x"""
+
+ f = get_cursor(tu, 'f')
+ raw = f.raw_comment
+ brief = f.brief_comment
+ assert raw is None
+ assert brief is None
+
+
diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py
index f8466e5..8cabc51 100644
--- a/bindings/python/tests/cindex/test_cursor_kind.py
+++ b/bindings/python/tests/cindex/test_cursor_kind.py
@@ -4,8 +4,15 @@
assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL'
def test_get_all_kinds():
- assert CursorKind.UNEXPOSED_DECL in CursorKind.get_all_kinds()
- assert CursorKind.TRANSLATION_UNIT in CursorKind.get_all_kinds()
+ kinds = CursorKind.get_all_kinds()
+ assert CursorKind.UNEXPOSED_DECL in kinds
+ assert CursorKind.TRANSLATION_UNIT in kinds
+ assert CursorKind.VARIABLE_REF in kinds
+ assert CursorKind.LAMBDA_EXPR in kinds
+ assert CursorKind.OBJ_BOOL_LITERAL_EXPR in kinds
+ assert CursorKind.OBJ_SELF_EXPR in kinds
+ assert CursorKind.MS_ASM_STMT in kinds
+ assert CursorKind.MODULE_IMPORT_DECL in kinds
def test_kind_groups():
"""Check that every kind classifies to exactly one group."""
diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py
index 9bbed5a..a02c06f 100644
--- a/bindings/python/tests/cindex/test_type.py
+++ b/bindings/python/tests/cindex/test_type.py
@@ -132,6 +132,22 @@
assert a.type != None
assert a.type != 'foo'
+def test_type_spelling():
+ """Ensure Type.spelling works."""
+ tu = get_tu('int c[5]; int i[]; int x; int v[x];')
+ c = get_cursor(tu, 'c')
+ i = get_cursor(tu, 'i')
+ x = get_cursor(tu, 'x')
+ v = get_cursor(tu, 'v')
+ assert c is not None
+ assert i is not None
+ assert x is not None
+ assert v is not None
+ assert c.type.spelling == "int [5]"
+ assert i.type.spelling == "int []"
+ assert x.type.spelling == "int"
+ assert v.type.spelling == "int [x]"
+
def test_typekind_spelling():
"""Ensure TypeKind.spelling works."""
tu = get_tu('int a;')
@@ -237,12 +253,20 @@
def test_element_type():
"""Ensure Type.element_type works."""
- tu = get_tu('int i[5];')
+ tu = get_tu('int c[5]; int i[]; int x; int v[x];')
+ c = get_cursor(tu, 'c')
i = get_cursor(tu, 'i')
+ v = get_cursor(tu, 'v')
+ assert c is not None
assert i is not None
+ assert v is not None
- assert i.type.kind == TypeKind.CONSTANTARRAY
+ assert c.type.kind == TypeKind.CONSTANTARRAY
+ assert c.type.element_type.kind == TypeKind.INT
+ assert i.type.kind == TypeKind.INCOMPLETEARRAY
assert i.type.element_type.kind == TypeKind.INT
+ assert v.type.kind == TypeKind.VARIABLEARRAY
+ assert v.type.element_type.kind == TypeKind.INT
@raises(Exception)
def test_invalid_element_type():
@@ -361,3 +385,13 @@
assert teststruct.type.get_offset("bar") == bar
+def test_decay():
+ """Ensure decayed types are handled as the original type"""
+
+ tu = get_tu("void foo(int a[]);")
+ foo = get_cursor(tu, 'foo')
+ a = foo.type.argument_types()[0]
+
+ assert a.kind == TypeKind.INCOMPLETEARRAY
+ assert a.element_type.kind == TypeKind.INT
+ assert a.get_canonical().kind == TypeKind.INCOMPLETEARRAY
diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng
index 22371df..a8913a3 100644
--- a/bindings/xml/comment-xml-schema.rng
+++ b/bindings/xml/comment-xml-schema.rng
@@ -75,7 +75,6 @@
<optional>
<ref name="USR" />
</optional>
- <!-- TODO: Add exception specification. -->
<optional>
<ref name="Headerfile" />
</optional>
@@ -91,6 +90,9 @@
<optional>
<ref name="Parameters" />
</optional>
+ <optional>
+ <ref name="Exceptions" />
+ </optional>
<zeroOrMore>
<ref name="Availability" />
</zeroOrMore>
@@ -410,9 +412,14 @@
</data>
</element>
<optional>
- <element name="Index">
- <data type="nonNegativeInteger" />
- </element>
+ <choice>
+ <element name="Index">
+ <data type="nonNegativeInteger" />
+ </element>
+ <element name="IsVarArg">
+ <empty />
+ </element>
+ </choice>
</optional>
<element name="Direction">
<attribute name="isExplicit">
@@ -435,6 +442,14 @@
</element>
</define>
+ <define name="Exceptions">
+ <element name="Exceptions">
+ <oneOrMore>
+ <ref name="TextBlockContent" />
+ </oneOrMore>
+ </element>
+ </define>
+
<define name="Availability">
<element name="Availability">
<attribute name="distribution">
diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst
index 89e8644..4d5944d 100644
--- a/docs/AddressSanitizer.rst
+++ b/docs/AddressSanitizer.rst
@@ -114,8 +114,7 @@
(or a deprecated synonym `no_address_safety_analysis`)
to disable instrumentation of a particular function. This attribute may not be
supported by other compilers, so we suggest to use it together with
-``__has_feature(address_sanitizer)``. Note: currently, this attribute will be
-lost if the function is inlined.
+``__has_feature(address_sanitizer)``.
Initialization order checking
-----------------------------
@@ -126,6 +125,36 @@
you should set environment variable
``ASAN_OPTIONS=check_initialization_order=1``.
+Blacklist
+---------
+
+AddressSanitizer supports ``src`` and ``fun`` entity types in
+:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports
+in the specified source files or functions. Additionally, AddressSanitizer
+introduces ``global`` and ``type`` entity types that can be used to
+suppress error reports for out-of-bound access to globals with certain
+names and types (you may only specify class or struct types).
+
+You may use an ``init`` category to suppress reports about initialization-order
+problems happening in certain source files or with certain global variables.
+
+.. code-block:: bash
+
+ # Suppress error reports for code in a file or in a function:
+ src:bad_file.cpp
+ # Ignore all functions with names containing MyFooBar:
+ fun:*MyFooBar*
+ # Disable out-of-bound checks for global:
+ global:bad_array
+ # Disable out-of-bound checks for global instances of a given class ...
+ type:class.Namespace::BadClassName
+ # ... or a given struct. Use wildcard to deal with anonymous namespace.
+ type:struct.Namespace2::*::BadStructName
+ # Disable initialization-order checks for globals:
+ global:bad_init_global=init
+ type:*BadInitClassSubstring*=init
+ src:bad/init/files/*=init
+
Supported Platforms
===================
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
new file mode 100644
index 0000000..8528c7a
--- /dev/null
+++ b/docs/CMakeLists.txt
@@ -0,0 +1,51 @@
+
+if (DOXYGEN_FOUND)
+if (LLVM_ENABLE_DOXYGEN)
+ set(abs_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
+ set(abs_builddir ${CMAKE_CURRENT_BINARY_DIR})
+
+ if (HAVE_DOT)
+ set(DOT ${LLVM_PATH_DOT})
+ endif()
+
+ if (LLVM_DOXYGEN_EXTERNAL_SEARCH)
+ set(enable_searchengine "YES")
+ set(searchengine_url "${LLVM_DOXYGEN_SEARCHENGINE_URL}")
+ set(enable_server_based_search "YES")
+ set(enable_external_search "YES")
+ set(extra_search_mappings "${LLVM_DOXYGEN_SEARCH_MAPPINGS}")
+ else()
+ set(enable_searchengine "NO")
+ set(searchengine_url "")
+ set(enable_server_based_search "NO")
+ set(enable_external_search "NO")
+ set(extra_search_mappings "")
+ endif()
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxygen.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg @ONLY)
+
+ set(abs_top_srcdir)
+ set(abs_top_builddir)
+ set(DOT)
+ set(enable_searchengine)
+ set(searchengine_url)
+ set(enable_server_based_search)
+ set(enable_external_search)
+ set(extra_search_mappings)
+
+ add_custom_target(doxygen-clang
+ COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating clang doxygen documentation." VERBATIM)
+
+ if (LLVM_BUILD_DOCS)
+ add_dependencies(doxygen doxygen-clang)
+ endif()
+
+ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
+ DESTINATION docs/html)
+ endif()
+endif()
+endif()
diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst
index 964fc84..bc6b8a2 100644
--- a/docs/ClangFormat.rst
+++ b/docs/ClangFormat.rst
@@ -15,26 +15,73 @@
.. code-block:: console
- $ clang-format --help
+ $ clang-format -help
OVERVIEW: A tool to format C/C++/Obj-C code.
If no arguments are specified, it formats the code from standard input
and writes the result to the standard output.
- If <file> is given, it reformats the file. If -i is specified together
- with <file>, the file is edited in-place. Otherwise, the result is
- written to the standard output.
+ If <file>s are given, it reformats the files. If -i is specified
+ together with <file>s, the files are edited in-place. Otherwise, the
+ result is written to the standard output.
- USAGE: clang-format [options] [<file>]
+ USAGE: clang-format [options] [<file> ...]
OPTIONS:
- -fatal-assembler-warnings - Consider warnings as error
- -help - Display available options (-help-hidden for more)
- -i - Inplace edit <file>, if specified.
- -length=<int> - Format a range of this length, -1 for end of file.
- -offset=<int> - Format a range starting at this file offset.
- -stats - Enable statistics output from program
- -style=<string> - Coding style, currently supports: LLVM, Google, Chromium.
- -version - Display the version of this program
+
+ Clang-format options:
+
+ -cursor=<uint> - The position of the cursor when invoking
+ clang-format from an editor integration
+ -dump-config - Dump configuration options to stdout and exit.
+ Can be used with -style option.
+ -i - Inplace edit <file>s, if specified.
+ -length=<uint> - Format a range of this length (in bytes).
+ Multiple ranges can be formatted by specifying
+ several -offset and -length pairs.
+ When only a single -offset is specified without
+ -length, clang-format will format up to the end
+ of the file.
+ Can only be used with one input file.
+ -lines=<string> - <start line>:<end line> - format a range of
+ lines (both 1-based).
+ Multiple ranges can be formatted by specifying
+ several -lines arguments.
+ Can't be used with -offset and -length.
+ Can only be used with one input file.
+ -offset=<uint> - Format a range starting at this byte offset.
+ Multiple ranges can be formatted by specifying
+ several -offset and -length pairs.
+ Can only be used with one input file.
+ -output-replacements-xml - Output replacements as XML.
+ -style=<string> - Coding style, currently supports:
+ LLVM, Google, Chromium, Mozilla, WebKit.
+ Use -style=file to load style configuration from
+ .clang-format file located in one of the parent
+ directories of the source file (or current
+ directory for stdin).
+ Use -style="{key: value, ...}" to set specific
+ parameters, e.g.:
+ -style="{BasedOnStyle: llvm, IndentWidth: 8}"
+
+ General options:
+
+ -help - Display available options (-help-hidden for more)
+ -help-list - Display list of available options (-help-list-hidden for more)
+ -version - Display the version of this program
+
+
+When the desired code formatting style is different from the available options,
+the style can be customized using the ``-style="{key: value, ...}"`` option or
+by putting your style configuration in the ``.clang-format`` or ``_clang-format``
+file in your project's directory and using ``clang-format -style=file``.
+
+An easy way to create the ``.clang-format`` file is:
+
+.. code-block:: console
+
+ clang-format -style=llvm -dump-config > .clang-format
+
+Available style options are described in :doc:`ClangFormatStyleOptions`.
Vim Integration
@@ -96,6 +143,13 @@
shortcut in the BBEdit preferences, under Menus & Shortcuts.
+Visual Studio Integration
+=========================
+
+Download the latest Visual Studio plugin from the `alpha build site
+<http://llvm.org/builds/>`_. The default key-binding is Ctrl-R,Ctrl-F.
+
+
Script for patch reformatting
=============================
@@ -106,18 +160,19 @@
usage: clang-format-diff.py [-h] [-p P] [-style STYLE]
- Reformat changed lines in diff
+ Reformat changed lines in diff.
optional arguments:
-h, --help show this help message and exit
-p P strip the smallest prefix containing P slashes
- -style STYLE formatting style to apply (LLVM, Google, Chromium)
+ -style STYLE formatting style to apply (LLVM, Google, Chromium, Mozilla,
+ WebKit)
So to reformat all the lines in the latest :program:`git` commit, just do:
.. code-block:: console
- git diff -U0 HEAD^ | clang-format-diff.py
+ git diff -U0 HEAD^ | clang-format-diff.py -p1
The :option:`-U0` will create a diff without context lines (the script would format
those as well).
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
new file mode 100644
index 0000000..d73801c
--- /dev/null
+++ b/docs/ClangFormatStyleOptions.rst
@@ -0,0 +1,391 @@
+==========================
+Clang-Format Style Options
+==========================
+
+:doc:`ClangFormatStyleOptions` describes configurable formatting style options
+supported by :doc:`LibFormat` and :doc:`ClangFormat`.
+
+When using :program:`clang-format` command line utility or
+``clang::format::reformat(...)`` functions from code, one can either use one of
+the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit) or create a
+custom style by configuring specific style options.
+
+
+Configuring Style with clang-format
+===================================
+
+:program:`clang-format` supports two ways to provide custom style options:
+directly specify style configuration in the ``-style=`` command line option or
+use ``-style=file`` and put style configuration in the ``.clang-format`` or
+``_clang-format`` file in the project directory.
+
+When using ``-style=file``, :program:`clang-format` for each input file will
+try to find the ``.clang-format`` file located in the closest parent directory
+of the input file. When the standard input is used, the search is started from
+the current directory.
+
+The ``.clang-format`` file uses YAML format:
+
+.. code-block:: yaml
+
+ key1: value1
+ key2: value2
+ # A comment.
+ ...
+
+An easy way to get a valid ``.clang-format`` file containing all configuration
+options of a certain predefined style is:
+
+.. code-block:: console
+
+ clang-format -style=llvm -dump-config > .clang-format
+
+When specifying configuration in the ``-style=`` option, the same configuration
+is applied for all input files. The format of the configuration is:
+
+.. code-block:: console
+
+ -style='{key1: value1, key2: value2, ...}'
+
+
+Configuring Style in Code
+=========================
+
+When using ``clang::format::reformat(...)`` functions, the format is specified
+by supplying the `clang::format::FormatStyle
+<http://clang.llvm.org/doxygen/structclang_1_1format_1_1FormatStyle.html>`_
+structure.
+
+
+Configurable Format Style Options
+=================================
+
+This section lists the supported style options. Value type is specified for
+each option. For enumeration types possible values are specified both as a C++
+enumeration member (with a prefix, e.g. ``LS_Auto``), and as a value usable in
+the configuration (without a prefix: ``Auto``).
+
+
+**BasedOnStyle** (``string``)
+ The style used for all options not specifically set in the configuration.
+
+ This option is supported only in the :program:`clang-format` configuration
+ (both within ``-style='{...}'`` and the ``.clang-format`` file).
+
+ Possible values:
+
+ * ``LLVM``
+ A style complying with the `LLVM coding standards
+ <http://llvm.org/docs/CodingStandards.html>`_
+ * ``Google``
+ A style complying with `Google's C++ style guide
+ <http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>`_
+ * ``Chromium``
+ A style complying with `Chromium's style guide
+ <http://www.chromium.org/developers/coding-style>`_
+ * ``Mozilla``
+ A style complying with `Mozilla's style guide
+ <https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style>`_
+ * ``WebKit``
+ A style complying with `WebKit's style guide
+ <http://www.webkit.org/coding/coding-style.html>`_
+
+.. START_FORMAT_STYLE_OPTIONS
+
+**AccessModifierOffset** (``int``)
+ The extra indent or outdent of access modifiers, e.g. ``public:``.
+
+**AlignEscapedNewlinesLeft** (``bool``)
+ If ``true``, aligns escaped newlines as far left as possible.
+ Otherwise puts them into the right-most column.
+
+**AlignTrailingComments** (``bool``)
+ If ``true``, aligns trailing comments.
+
+**AllowAllParametersOfDeclarationOnNextLine** (``bool``)
+ Allow putting all parameters of a function declaration onto
+ the next line even if ``BinPackParameters`` is ``false``.
+
+**AllowShortIfStatementsOnASingleLine** (``bool``)
+ If ``true``, ``if (a) return;`` can be put on a single
+ line.
+
+**AllowShortLoopsOnASingleLine** (``bool``)
+ If ``true``, ``while (true) continue;`` can be put on a
+ single line.
+
+**AlwaysBreakBeforeMultilineStrings** (``bool``)
+ If ``true``, always break before multiline string literals.
+
+**AlwaysBreakTemplateDeclarations** (``bool``)
+ If ``true``, always break after the ``template<...>`` of a
+ template declaration.
+
+**BinPackParameters** (``bool``)
+ If ``false``, a function call's or function definition's parameters
+ will either all be on the same line or will have one line each.
+
+**BreakBeforeBinaryOperators** (``bool``)
+ If ``true``, binary operators will be placed after line breaks.
+
+**BreakBeforeBraces** (``BraceBreakingStyle``)
+ The brace breaking style to use.
+
+ Possible values:
+
+ * ``BS_Attach`` (in configuration: ``Attach``)
+ Always attach braces to surrounding context.
+ * ``BS_Linux`` (in configuration: ``Linux``)
+ Like ``Attach``, but break before braces on function, namespace and
+ class definitions.
+ * ``BS_Stroustrup`` (in configuration: ``Stroustrup``)
+ Like ``Attach``, but break before function definitions.
+ * ``BS_Allman`` (in configuration: ``Allman``)
+ Always break before braces.
+
+
+**BreakConstructorInitializersBeforeComma** (``bool``)
+ Always break constructor initializers before commas and align
+ the commas with the colon.
+
+**ColumnLimit** (``unsigned``)
+ The column limit.
+
+ A column limit of ``0`` means that there is no column limit. In this case,
+ clang-format will respect the input's line breaking decisions within
+ statements.
+
+**ConstructorInitializerAllOnOneLineOrOnePerLine** (``bool``)
+ If the constructor initializers don't fit on a line, put each
+ initializer on its own line.
+
+**ConstructorInitializerIndentWidth** (``unsigned``)
+ The number of characters to use for indentation of constructor
+ initializer lists.
+
+**Cpp11BracedListStyle** (``bool``)
+ If ``true``, format braced lists as best suited for C++11 braced
+ lists.
+
+ Important differences:
+ - No spaces inside the braced list.
+ - No line break before the closing brace.
+ - Indentation with the continuation indent, not with the block indent.
+
+ Fundamentally, C++11 braced lists are formatted exactly like function
+ calls would be formatted in their place. If the braced list follows a name
+ (e.g. a type or variable name), clang-format formats as if the ``{}`` were
+ the parentheses of a function call with that name. If there is no name,
+ a zero-length name is assumed.
+
+**DerivePointerBinding** (``bool``)
+ If ``true``, analyze the formatted file for the most common binding.
+
+**ExperimentalAutoDetectBinPacking** (``bool``)
+ If ``true``, clang-format detects whether function calls and
+ definitions are formatted with one parameter per line.
+
+ Each call can be bin-packed, one-per-line or inconclusive. If it is
+ inconclusive, e.g. completely on one line, but a decision needs to be
+ made, clang-format analyzes whether there are other bin-packed cases in
+ the input file and act accordingly.
+
+ NOTE: This is an experimental flag, that might go away or be renamed. Do
+ not use this in config files, etc. Use at your own risk.
+
+**IndentCaseLabels** (``bool``)
+ Indent case labels one level from the switch statement.
+
+ When ``false``, use the same indentation level as for the switch statement.
+ Switch statement body is always indented one level more than case labels.
+
+**IndentFunctionDeclarationAfterType** (``bool``)
+ If ``true``, indent when breaking function declarations which
+ are not also definitions after the type.
+
+**IndentWidth** (``unsigned``)
+ The number of columns to use for indentation.
+
+**MaxEmptyLinesToKeep** (``unsigned``)
+ The maximum number of consecutive empty lines to keep.
+
+**NamespaceIndentation** (``NamespaceIndentationKind``)
+ The indentation used for namespaces.
+
+ Possible values:
+
+ * ``NI_None`` (in configuration: ``None``)
+ Don't indent in namespaces.
+ * ``NI_Inner`` (in configuration: ``Inner``)
+ Indent only in inner namespaces (nested in other namespaces).
+ * ``NI_All`` (in configuration: ``All``)
+ Indent in all namespaces.
+
+
+**ObjCSpaceBeforeProtocolList** (``bool``)
+ Add a space in front of an Objective-C protocol list, i.e. use
+ ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
+
+**PenaltyBreakComment** (``unsigned``)
+ The penalty for each line break introduced inside a comment.
+
+**PenaltyBreakFirstLessLess** (``unsigned``)
+ The penalty for breaking before the first ``<<``.
+
+**PenaltyBreakString** (``unsigned``)
+ The penalty for each line break introduced inside a string literal.
+
+**PenaltyExcessCharacter** (``unsigned``)
+ The penalty for each character outside of the column limit.
+
+**PenaltyReturnTypeOnItsOwnLine** (``unsigned``)
+ Penalty for putting the return type of a function onto its own
+ line.
+
+**PointerBindsToType** (``bool``)
+ Set whether & and * bind to the type as opposed to the variable.
+
+**SpaceAfterControlStatementKeyword** (``bool``)
+ If ``true``, spaces will be inserted between 'for'/'if'/'while'/...
+ and '('.
+
+**SpaceBeforeAssignmentOperators** (``bool``)
+ If ``false``, spaces will be removed before assignment operators.
+
+**SpaceInEmptyParentheses** (``bool``)
+ If ``false``, spaces may be inserted into '()'.
+
+**SpacesBeforeTrailingComments** (``unsigned``)
+ The number of spaces to before trailing line comments.
+
+**SpacesInCStyleCastParentheses** (``bool``)
+ If ``false``, spaces may be inserted into C style casts.
+
+**SpacesInParentheses** (``bool``)
+ If ``true``, spaces will be inserted after every '(' and before
+ every ')'.
+
+**Standard** (``LanguageStandard``)
+ Format compatible with this standard, e.g. use
+ ``A<A<int> >`` instead of ``A<A<int>>`` for LS_Cpp03.
+
+ Possible values:
+
+ * ``LS_Cpp03`` (in configuration: ``Cpp03``)
+ Use C++03-compatible syntax.
+ * ``LS_Cpp11`` (in configuration: ``Cpp11``)
+ Use features of C++11 (e.g. ``A<A<int>>`` instead of
+ ``A<A<int> >``).
+ * ``LS_Auto`` (in configuration: ``Auto``)
+ Automatic detection based on the input.
+
+
+**TabWidth** (``unsigned``)
+ The number of columns used for tab stops.
+
+**UseTab** (``UseTabStyle``)
+ The way to use tab characters in the resulting file.
+
+ Possible values:
+
+ * ``UT_Never`` (in configuration: ``Never``)
+ Never use tab.
+ * ``UT_ForIndentation`` (in configuration: ``ForIndentation``)
+ Use tabs only for indentation.
+ * ``UT_Always`` (in configuration: ``Always``)
+ Use tabs whenever we need to fill whitespace that spans at least from
+ one tab stop to the next one.
+
+
+.. END_FORMAT_STYLE_OPTIONS
+
+Examples
+========
+
+A style similar to the `Linux Kernel style
+<https://www.kernel.org/doc/Documentation/CodingStyle>`_:
+
+.. code-block:: yaml
+
+ BasedOnStyle: LLVM
+ IndentWidth: 8
+ UseTab: Always
+ BreakBeforeBraces: Linux
+ AllowShortIfStatementsOnASingleLine: false
+ IndentCaseLabels: false
+
+The result is (imagine that tabs are used for indentation here):
+
+.. code-block:: c++
+
+ void test()
+ {
+ switch (x) {
+ case 0:
+ case 1:
+ do_something();
+ break;
+ case 2:
+ do_something_else();
+ break;
+ default:
+ break;
+ }
+ if (condition)
+ do_something_completely_different();
+
+ if (x == y) {
+ q();
+ } else if (x > y) {
+ w();
+ } else {
+ r();
+ }
+ }
+
+A style similar to the default Visual Studio formatting style:
+
+.. code-block:: yaml
+
+ UseTab: Never
+ IndentWidth: 4
+ BreakBeforeBraces: Allman
+ AllowShortIfStatementsOnASingleLine: false
+ IndentCaseLabels: false
+ ColumnLimit: 0
+
+The result is:
+
+.. code-block:: c++
+
+ void test()
+ {
+ switch (suffix)
+ {
+ case 0:
+ case 1:
+ do_something();
+ break;
+ case 2:
+ do_something_else();
+ break;
+ default:
+ break;
+ }
+ if (condition)
+ do_somthing_completely_different();
+
+ if (x == y)
+ {
+ q();
+ }
+ else if (x > y)
+ {
+ w();
+ }
+ else
+ {
+ r();
+ }
+ }
+
diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst
index 9312e6b..f8a7c36 100644
--- a/docs/ClangTools.rst
+++ b/docs/ClangTools.rst
@@ -88,8 +88,8 @@
<ClangFormat>` with the goal of automatically reformatting C++ sources files
according to configurable style guides. To do so, clang-format uses Clang's
``Lexer`` to transform an input file into a token stream and then changes all
-the whitespace around those tokens. The goal is for clang-format to both serve
-both as a user tool (ideally with powerful IDE integrations) and part of other
+the whitespace around those tokens. The goal is for clang-format to serve both
+as a user tool (ideally with powerful IDE integrations) and as part of other
refactoring tools, e.g. to do a reformatting of all the lines changed during a
renaming.
@@ -125,7 +125,7 @@
``foo`` is a standard container. We could also detect similar patterns for
arrays.
* ``make_shared`` / ``make_unique`` conversion. Part of this transformation
-can be incorporated into the ``auto`` transformation. Will convert
+ can be incorporated into the ``auto`` transformation. Will convert
.. code-block:: c++
diff --git a/docs/CrossCompilation.rst b/docs/CrossCompilation.rst
new file mode 100644
index 0000000..e655d89
--- /dev/null
+++ b/docs/CrossCompilation.rst
@@ -0,0 +1,204 @@
+===================================================================
+Cross-compilation using Clang
+===================================================================
+
+Introduction
+============
+
+This document will guide you in choosing the right Clang options
+for cross-compiling your code to a different architecture. It assumes you
+already know how to compile the code in question for the host architecture,
+and that you know how to choose additional include and library paths.
+
+However, this document is *not* a "how to" and won't help you setting your
+build system or Makefiles, nor choosing the right CMake options, etc.
+Also, it does not cover all the possible options, nor does it contain
+specific examples for specific architectures. For a concrete example, the
+`instructions for cross-compiling LLVM itself
+<http://llvm.org/docs/HowToCrossCompileLLVM.html>`_ may be of interest.
+
+After reading this document, you should be familiar with the main issues
+related to cross-compilation, and what main compiler options Clang provides
+for performing cross-compilation.
+
+Cross compilation issues
+========================
+
+In GCC world, every host/target combination has its own set of binaries,
+headers, libraries, etc. So, it's usually simple to download a package
+with all files in, unzip to a directory and point the build system to
+that compiler, that will know about its location and find all it needs to
+when compiling your code.
+
+On the other hand, Clang/LLVM is natively a cross-compiler, meaning that
+one set of programs can compile to all targets by setting the ``-target``
+option. That makes it a lot easier for programers wishing to compile to
+different platforms and architectures, and for compiler developers that
+only have to maintain one build system, and for OS distributions, that
+need only one set of main packages.
+
+But, as is true to any cross-compiler, and given the complexity of
+different architectures, OS's and options, it's not always easy finding
+the headers, libraries or binutils to generate target specific code.
+So you'll need special options to help Clang understand what target
+you're compiling to, where your tools are, etc.
+
+Another problem is that compilers come with standard libraries only (like
+``compiler-rt``, ``libcxx``, ``libgcc``, ``libm``, etc), so you'll have to
+find and make available to the build system, every other library required
+to build your software, that is specific to your target. It's not enough to
+have your host's libraries installed.
+
+Finally, not all toolchains are the same, and consequently, not every Clang
+option will work magically. Some options, like ``--sysroot`` (which
+effectively changes the logical root for headers and libraries), assume
+all your binaries and libraries are in the same directory, which may not
+true when your cross-compiler was installed by the distribution's package
+management. So, for each specific case, you may use more than one
+option, and in most cases, you'll end up setting include paths (``-I``) and
+library paths (``-L``) manually.
+
+To sum up, different toolchains can:
+ * be host/target specific or more flexible
+ * be in a single directory, or spread out across your system
+ * have different sets of libraries and headers by default
+ * need special options, which your build system won't be able to figure
+ out by itself
+
+General Cross-Compilation Options in Clang
+==========================================
+
+Target Triple
+-------------
+
+The basic option is to define the target architecture. For that, use
+``-target <triple>``. If you don't specify the target, CPU names won't
+match (since Clang assumes the host triple), and the compilation will
+go ahead, creating code for the host platform, which will break later
+on when assembling or linking.
+
+The triple has the general format ``<arch><sub>-<vendor>-<sys>-<abi>``, where:
+ * ``arch`` = ``x86``, ``arm``, ``thumb``, ``mips``, etc.
+ * ``sub`` = for ex. on ARM: ``v5``, ``v6m``, ``v7a``, ``v7m``, etc.
+ * ``vendor`` = ``pc``, ``apple``, ``nvidia``, ``ibm``, etc.
+ * ``sys`` = ``none``, ``linux``, ``win32``, ``darwin``, ``cuda``, etc.
+ * ``abi`` = ``eabi``, ``gnu``, ``android``, ``macho``, ``elf``, etc.
+
+The sub-architecture options are available for their own architectures,
+of course, so "x86v7a" doesn't make sense. The vendor needs to be
+specified only if there's a relevant change, for instance between PC
+and Apple. Most of the time it can be omitted (and Unknown)
+will be assumed, which sets the defaults for the specified architecture.
+The system name is generally the OS (linux, darwin), but could be special
+like the bare-metal "none".
+
+When a parameter is not important, they can be omitted, or you can
+choose ``unknown`` and the defaults will be used. If you choose a parameter
+that Clang doesn't know, like ``blerg``, it'll ignore and assume
+``unknown``, which is not always desired, so be careful.
+
+Finally, the ABI option is something that will pick default CPU/FPU,
+define the specific behaviour of your code (PCS, extensions),
+and also choose the correct library calls, etc.
+
+CPU, FPU, ABI
+-------------
+
+Once your target is specified, it's time to pick the hardware you'll
+be compiling to. For every architecture, a default set of CPU/FPU/ABI
+will be chosen, so you'll almost always have to change it via flags.
+
+Typical flags include:
+ * ``-mcpu=<cpu-name>``, like x86-64, swift, cortex-a15
+ * ``-fpu=<fpu-name>``, like SSE3, NEON, controlling the FP unit available
+ * ``-mfloat-abi=<fabi>``, like soft, hard, controlling which registers
+ to use for floating-point
+
+The default is normally the common denominator, so that Clang doesn't
+generate code that breaks. But that also means you won't get the best
+code for your specific hardware, which may mean orders of magnitude
+slower than you expect.
+
+For example, if your target is ``arm-none-eabi``, the default CPU will
+be ``arm7tdmi`` using soft float, which is extremely slow on modern cores,
+whereas if your triple is ``armv7a-none-eabi``, it'll be Cortex-A8 with
+NEON, but still using soft-float, which is much better, but still not
+great.
+
+Toolchain Options
+-----------------
+
+There are three main options to control access to your cross-compiler:
+``--sysroot``, ``-I``, and ``-L``. The two last ones are well known,
+but they're particularly important for additional libraries
+and headers that are specific to your target.
+
+There are two main ways to have a cross-compiler:
+
+#. When you have extracted your cross-compiler from a zip file into
+ a directory, you have to use ``--sysroot=<path>``. The path is the
+ root directory where you have unpacked your file, and Clang will
+ look for the directories ``bin``, ``lib``, ``include`` in there.
+
+ In this case, your setup should be pretty much done (if no
+ additional headers or libraries are needed), as Clang will find
+ all binaries it needs (assembler, linker, etc) in there.
+
+#. When you have installed via a package manager (modern Linux
+ distributions have cross-compiler packages available), make
+ sure the target triple you set is *also* the prefix of your
+ cross-compiler toolchain.
+
+ In this case, Clang will find the other binaries (assembler,
+ linker), but not always where the target headers and libraries
+ are. People add system-specific clues to Clang often, but as
+ things change, it's more likely that it won't find than the
+ other way around.
+
+ So, here, you'll be a lot safer if you specify the include/library
+ directories manually (via ``-I`` and ``-L``).
+
+Target-Specific Libraries
+=========================
+
+All libraries that you compile as part of your build will be
+cross-compiled to your target, and your build system will probably
+find them in the right place. But all dependencies that are
+normally checked against (like ``libxml`` or ``libz`` etc) will match
+against the host platform, not the target.
+
+So, if the build system is not aware that you want to cross-compile
+your code, it will get every dependency wrong, and your compilation
+will fail during build time, not configure time.
+
+Also, finding the libraries for your target are not as easy
+as for your host machine. There aren't many cross-libraries available
+as packages to most OS's, so you'll have to either cross-compile them
+from source, or download the package for your target platform,
+extract the libraries and headers, put them in specific directories
+and add ``-I`` and ``-L`` pointing to them.
+
+Also, some libraries have different dependencies on different targets,
+so configuration tools to find dependencies in the host can get the
+list wrong for the target platform. This means that the configuration
+of your build can get things wrong when setting their own library
+paths, and you'll have to augment it via additional flags (configure,
+Make, CMake, etc).
+
+Multilibs
+---------
+
+When you want to cross-compile to more than one configuration, for
+example hard-float-ARM and soft-float-ARM, you'll have to have multiple
+copies of you libraries and (possibly) headers.
+
+Some Linux distributions have support for Multilib, which handle that
+for you in an easier way, but if you're not careful and, for instance,
+forget to specify ``-ccc-gcc-name armv7l-linux-gnueabihf-gcc`` (which
+uses hard-float), Clang will pick the ``armv7l-linux-gnueabi-ld``
+(which uses soft-float) and linker errors will happen.
+
+The same is true if you're compiling for different ABIs, like ``gnueabi``
+and ``androideabi``, and might even link and run, but produce run-time
+errors, which are much harder to track down and fix.
+
diff --git a/docs/DataFlowSanitizer.rst b/docs/DataFlowSanitizer.rst
new file mode 100644
index 0000000..e0e9d74
--- /dev/null
+++ b/docs/DataFlowSanitizer.rst
@@ -0,0 +1,158 @@
+=================
+DataFlowSanitizer
+=================
+
+.. toctree::
+ :hidden:
+
+ DataFlowSanitizerDesign
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+DataFlowSanitizer is a generalised dynamic data flow analysis.
+
+Unlike other Sanitizer tools, this tool is not designed to detect a
+specific class of bugs on its own. Instead, it provides a generic
+dynamic data flow analysis framework to be used by clients to help
+detect application-specific issues within their own code.
+
+Usage
+=====
+
+With no program changes, applying DataFlowSanitizer to a program
+will not alter its behavior. To use DataFlowSanitizer, the program
+uses API functions to apply tags to data to cause it to be tracked, and to
+check the tag of a specific data item. DataFlowSanitizer manages
+the propagation of tags through the program according to its data flow.
+
+The APIs are defined in the header file ``sanitizer/dfsan_interface.h``.
+For further information about each function, please refer to the header
+file.
+
+ABI List
+--------
+
+DataFlowSanitizer uses a list of functions known as an ABI list to decide
+whether a call to a specific function should use the operating system's native
+ABI or whether it should use a variant of this ABI that also propagates labels
+through function parameters and return values. The ABI list file also controls
+how labels are propagated in the former case. DataFlowSanitizer comes with a
+default ABI list which is intended to eventually cover the glibc library on
+Linux but it may become necessary for users to extend the ABI list in cases
+where a particular library or function cannot be instrumented (e.g. because
+it is implemented in assembly or another language which DataFlowSanitizer does
+not support) or a function is called from a library or function which cannot
+be instrumented.
+
+DataFlowSanitizer's ABI list file is a :doc:`SanitizerSpecialCaseList`.
+The pass treats every function in the ``uninstrumented`` category in the
+ABI list file as conforming to the native ABI. Unless the ABI list contains
+additional categories for those functions, a call to one of those functions
+will produce a warning message, as the labelling behavior of the function
+is unknown. The other supported categories are ``discard``, ``functional``
+and ``custom``.
+
+* ``discard`` -- To the extent that this function writes to (user-accessible)
+ memory, it also updates labels in shadow memory (this condition is trivially
+ satisfied for functions which do not write to user-accessible memory). Its
+ return value is unlabelled.
+* ``functional`` -- Like ``discard``, except that the label of its return value
+ is the union of the label of its arguments.
+* ``custom`` -- Instead of calling the function, a custom wrapper ``__dfsw_F``
+ is called, where ``F`` is the name of the function. This function may wrap
+ the original function or provide its own implementation. This category is
+ generally used for uninstrumentable functions which write to user-accessible
+ memory or which have more complex label propagation behavior. The signature
+ of ``__dfsw_F`` is based on that of ``F`` with each argument having a
+ label of type ``dfsan_label`` appended to the argument list. If ``F``
+ is of non-void return type a final argument of type ``dfsan_label *``
+ is appended to which the custom function can store the label for the
+ return value. For example:
+
+.. code-block:: c++
+
+ void f(int x);
+ void __dfsw_f(int x, dfsan_label x_label);
+
+ void *memcpy(void *dest, const void *src, size_t n);
+ void *__dfsw_memcpy(void *dest, const void *src, size_t n,
+ dfsan_label dest_label, dfsan_label src_label,
+ dfsan_label n_label, dfsan_label *ret_label);
+
+If a function defined in the translation unit being compiled belongs to the
+``uninstrumented`` category, it will be compiled so as to conform to the
+native ABI. Its arguments will be assumed to be unlabelled, but it will
+propagate labels in shadow memory.
+
+For example:
+
+.. code-block:: none
+
+ # main is called by the C runtime using the native ABI.
+ fun:main=uninstrumented
+ fun:main=discard
+
+ # malloc only writes to its internal data structures, not user-accessible memory.
+ fun:malloc=uninstrumented
+ fun:malloc=discard
+
+ # tolower is a pure function.
+ fun:tolower=uninstrumented
+ fun:tolower=functional
+
+ # memcpy needs to copy the shadow from the source to the destination region.
+ # This is done in a custom function.
+ fun:memcpy=uninstrumented
+ fun:memcpy=custom
+
+Example
+=======
+
+The following program demonstrates label propagation by checking that
+the correct labels are propagated.
+
+.. code-block:: c++
+
+ #include <sanitizer/dfsan_interface.h>
+ #include <assert.h>
+
+ int main(void) {
+ int i = 1;
+ dfsan_label i_label = dfsan_create_label("i", 0);
+ dfsan_set_label(i_label, &i, sizeof(i));
+
+ int j = 2;
+ dfsan_label j_label = dfsan_create_label("j", 0);
+ dfsan_set_label(j_label, &j, sizeof(j));
+
+ int k = 3;
+ dfsan_label k_label = dfsan_create_label("k", 0);
+ dfsan_set_label(k_label, &k, sizeof(k));
+
+ dfsan_label ij_label = dfsan_get_label(i + j);
+ assert(dfsan_has_label(ij_label, i_label));
+ assert(dfsan_has_label(ij_label, j_label));
+ assert(!dfsan_has_label(ij_label, k_label));
+
+ dfsan_label ijk_label = dfsan_get_label(i + j + k);
+ assert(dfsan_has_label(ijk_label, i_label));
+ assert(dfsan_has_label(ijk_label, j_label));
+ assert(dfsan_has_label(ijk_label, k_label));
+
+ return 0;
+ }
+
+Current status
+==============
+
+DataFlowSanitizer is a work in progress, currently under development for
+x86\_64 Linux.
+
+Design
+======
+
+Please refer to the :doc:`design document<DataFlowSanitizerDesign>`.
diff --git a/docs/DataFlowSanitizerDesign.rst b/docs/DataFlowSanitizerDesign.rst
new file mode 100644
index 0000000..32db88b
--- /dev/null
+++ b/docs/DataFlowSanitizerDesign.rst
@@ -0,0 +1,220 @@
+DataFlowSanitizer Design Document
+=================================
+
+This document sets out the design for DataFlowSanitizer, a general
+dynamic data flow analysis. Unlike other Sanitizer tools, this tool is
+not designed to detect a specific class of bugs on its own. Instead,
+it provides a generic dynamic data flow analysis framework to be used
+by clients to help detect application-specific issues within their
+own code.
+
+DataFlowSanitizer is a program instrumentation which can associate
+a number of taint labels with any data stored in any memory region
+accessible by the program. The analysis is dynamic, which means that
+it operates on a running program, and tracks how the labels propagate
+through that program. The tool shall support a large (>100) number
+of labels, such that programs which operate on large numbers of data
+items may be analysed with each data item being tracked separately.
+
+Use Cases
+---------
+
+This instrumentation can be used as a tool to help monitor how data
+flows from a program's inputs (sources) to its outputs (sinks).
+This has applications from a privacy/security perspective in that
+one can audit how a sensitive data item is used within a program and
+ensure it isn't exiting the program anywhere it shouldn't be.
+
+Interface
+---------
+
+A number of functions are provided which will create taint labels,
+attach labels to memory regions and extract the set of labels
+associated with a specific memory region. These functions are declared
+in the header file ``sanitizer/dfsan_interface.h``.
+
+.. code-block:: c
+
+ /// Creates and returns a base label with the given description and user data.
+ dfsan_label dfsan_create_label(const char *desc, void *userdata);
+
+ /// Sets the label for each address in [addr,addr+size) to \c label.
+ void dfsan_set_label(dfsan_label label, void *addr, size_t size);
+
+ /// Sets the label for each address in [addr,addr+size) to the union of the
+ /// current label for that address and \c label.
+ void dfsan_add_label(dfsan_label label, void *addr, size_t size);
+
+ /// Retrieves the label associated with the given data.
+ ///
+ /// The type of 'data' is arbitrary. The function accepts a value of any type,
+ /// which can be truncated or extended (implicitly or explicitly) as necessary.
+ /// The truncation/extension operations will preserve the label of the original
+ /// value.
+ dfsan_label dfsan_get_label(long data);
+
+ /// Retrieves a pointer to the dfsan_label_info struct for the given label.
+ const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label);
+
+ /// Returns whether the given label label contains the label elem.
+ int dfsan_has_label(dfsan_label label, dfsan_label elem);
+
+ /// If the given label label contains a label with the description desc, returns
+ /// that label, else returns 0.
+ dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
+
+Taint label representation
+--------------------------
+
+As stated above, the tool must track a large number of taint
+labels. This poses an implementation challenge, as most multiple-label
+tainting systems assign one label per bit to shadow storage, and
+union taint labels using a bitwise or operation. This will not scale
+to clients which use hundreds or thousands of taint labels, as the
+label union operation becomes O(n) in the number of supported labels,
+and data associated with it will quickly dominate the live variable
+set, causing register spills and hampering performance.
+
+Instead, a low overhead approach is proposed which is best-case O(log\
+:sub:`2` n) during execution. The underlying assumption is that
+the required space of label unions is sparse, which is a reasonable
+assumption to make given that we are optimizing for the case where
+applications mostly copy data from one place to another, without often
+invoking the need for an actual union operation. The representation
+of a taint label is a 16-bit integer, and new labels are allocated
+sequentially from a pool. The label identifier 0 is special, and means
+that the data item is unlabelled.
+
+When a label union operation is requested at a join point (any
+arithmetic or logical operation with two or more operands, such as
+addition), the code checks whether a union is required, whether the
+same union has been requested before, and whether one union label
+subsumes the other. If so, it returns the previously allocated union
+label. If not, it allocates a new union label from the same pool used
+for new labels.
+
+Specifically, the instrumentation pass will insert code like this
+to decide the union label ``lu`` for a pair of labels ``l1``
+and ``l2``:
+
+.. code-block:: c
+
+ if (l1 == l2)
+ lu = l1;
+ else
+ lu = __dfsan_union(l1, l2);
+
+The equality comparison is outlined, to provide an early exit in
+the common cases where the program is processing unlabelled data, or
+where the two data items have the same label. ``__dfsan_union`` is
+a runtime library function which performs all other union computation.
+
+Further optimizations are possible, for example if ``l1`` is known
+at compile time to be zero (e.g. it is derived from a constant),
+``l2`` can be used for ``lu``, and vice versa.
+
+Memory layout and label management
+----------------------------------
+
+The following is the current memory layout for Linux/x86\_64:
+
++---------------+---------------+--------------------+
+| Start | End | Use |
++===============+===============+====================+
+| 0x700000008000|0x800000000000 | application memory |
++---------------+---------------+--------------------+
+| 0x200200000000|0x700000008000 | unused |
++---------------+---------------+--------------------+
+| 0x200000000000|0x200200000000 | union table |
++---------------+---------------+--------------------+
+| 0x000000010000|0x200000000000 | shadow memory |
++---------------+---------------+--------------------+
+| 0x000000000000|0x000000010000 | reserved by kernel |
++---------------+---------------+--------------------+
+
+Each byte of application memory corresponds to two bytes of shadow
+memory, which are used to store its taint label. As for LLVM SSA
+registers, we have not found it necessary to associate a label with
+each byte or bit of data, as some other tools do. Instead, labels are
+associated directly with registers. Loads will result in a union of
+all shadow labels corresponding to bytes loaded (which most of the
+time will be short circuited by the initial comparison) and stores will
+result in a copy of the label to the shadow of all bytes stored to.
+
+Propagating labels through arguments
+------------------------------------
+
+In order to propagate labels through function arguments and return values,
+DataFlowSanitizer changes the ABI of each function in the translation unit.
+There are currently two supported ABIs:
+
+* Args -- Argument and return value labels are passed through additional
+ arguments and by modifying the return type.
+
+* TLS -- Argument and return value labels are passed through TLS variables
+ ``__dfsan_arg_tls`` and ``__dfsan_retval_tls``.
+
+The main advantage of the TLS ABI is that it is more tolerant of ABI mismatches
+(TLS storage is not shared with any other form of storage, whereas extra
+arguments may be stored in registers which under the native ABI are not used
+for parameter passing and thus could contain arbitrary values). On the other
+hand the args ABI is more efficient and allows ABI mismatches to be more easily
+identified by checking for nonzero labels in nominally unlabelled programs.
+
+Implementing the ABI list
+-------------------------
+
+The `ABI list <DataFlowSanitizer.html#abi-list>`_ provides a list of functions
+which conform to the native ABI, each of which is callable from an instrumented
+program. This is implemented by replacing each reference to a native ABI
+function with a reference to a function which uses the instrumented ABI.
+Such functions are automatically-generated wrappers for the native functions.
+For example, given the ABI list example provided in the user manual, the
+following wrappers will be generated under the args ABI:
+
+.. code-block:: llvm
+
+ define linkonce_odr { i8*, i16 } @"dfsw$malloc"(i64 %0, i16 %1) {
+ entry:
+ %2 = call i8* @malloc(i64 %0)
+ %3 = insertvalue { i8*, i16 } undef, i8* %2, 0
+ %4 = insertvalue { i8*, i16 } %3, i16 0, 1
+ ret { i8*, i16 } %4
+ }
+
+ define linkonce_odr { i32, i16 } @"dfsw$tolower"(i32 %0, i16 %1) {
+ entry:
+ %2 = call i32 @tolower(i32 %0)
+ %3 = insertvalue { i32, i16 } undef, i32 %2, 0
+ %4 = insertvalue { i32, i16 } %3, i16 %1, 1
+ ret { i32, i16 } %4
+ }
+
+ define linkonce_odr { i8*, i16 } @"dfsw$memcpy"(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5) {
+ entry:
+ %labelreturn = alloca i16
+ %6 = call i8* @__dfsw_memcpy(i8* %0, i8* %1, i64 %2, i16 %3, i16 %4, i16 %5, i16* %labelreturn)
+ %7 = load i16* %labelreturn
+ %8 = insertvalue { i8*, i16 } undef, i8* %6, 0
+ %9 = insertvalue { i8*, i16 } %8, i16 %7, 1
+ ret { i8*, i16 } %9
+ }
+
+As an optimization, direct calls to native ABI functions will call the
+native ABI function directly and the pass will compute the appropriate label
+internally. This has the advantage of reducing the number of union operations
+required when the return value label is known to be zero (i.e. ``discard``
+functions, or ``functional`` functions with known unlabelled arguments).
+
+Checking ABI Consistency
+------------------------
+
+DFSan changes the ABI of each function in the module. This makes it possible
+for a function with the native ABI to be called with the instrumented ABI,
+or vice versa, thus possibly invoking undefined behavior. A simple way
+of statically detecting instances of this problem is to prepend the prefix
+"dfs$" to the name of each instrumented-ABI function.
+
+This will not catch every such problem; in particular function pointers passed
+across the instrumented-native barrier cannot be used on the other side.
+These problems could potentially be caught dynamically.
diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst
index 59dd2f9..6f55702 100644
--- a/docs/InternalsManual.rst
+++ b/docs/InternalsManual.rst
@@ -950,17 +950,13 @@
``DeclarationName`` is designed to efficiently represent any kind of name.
Given a ``DeclarationName`` ``N``, ``N.getNameKind()`` will produce a value
-that describes what kind of name ``N`` stores. There are 8 options (all of the
-names are inside the ``DeclarationName`` class).
+that describes what kind of name ``N`` stores. There are 10 options (all of
+the names are inside the ``DeclarationName`` class).
``Identifier``
The name is a simple identifier. Use ``N.getAsIdentifierInfo()`` to retrieve
the corresponding ``IdentifierInfo*`` pointing to the actual identifier.
- Note that C++ overloaded operators (e.g., "``operator+``") are represented as
- special kinds of identifiers. Use ``IdentifierInfo``'s
- ``getOverloadedOperatorID`` function to determine whether an identifier is an
- overloaded operator name.
``ObjCZeroArgSelector``, ``ObjCOneArgSelector``, ``ObjCMultiArgSelector``
@@ -999,6 +995,21 @@
Use ``N.getCXXOverloadedOperator()`` to retrieve the overloaded operator (a
value of type ``OverloadedOperatorKind``).
+``CXXLiteralOperatorName``
+
+ The name is a C++11 user defined literal operator. User defined
+ Literal operators are named according to the suffix they define,
+ e.g., "``_foo``" for "``operator "" _foo``". Use
+ ``N.getCXXLiteralIdentifier()`` to retrieve the corresponding
+ ``IdentifierInfo*`` pointing to the identifier.
+
+``CXXUsingDirective``
+
+ The name is a C++ using directive. Using directives are not really
+ NamedDecls, in that they all have the same name, but they are
+ implemented as such in order to store them in DeclContext
+ effectively.
+
``DeclarationName``\ s are cheap to create, copy, and compare. They require
only a single pointer's worth of storage in the common cases (identifiers,
zero- and one-argument Objective-C selectors) and use dense, uniqued storage
diff --git a/docs/IntroductionToTheClangAST.rst b/docs/IntroductionToTheClangAST.rst
index 81eb7ed..600a6c8 100644
--- a/docs/IntroductionToTheClangAST.rst
+++ b/docs/IntroductionToTheClangAST.rst
@@ -7,6 +7,12 @@
Clang, or use tools that work based on Clang's AST, like the AST
matchers.
+.. raw:: html
+
+ <center><iframe width="560" height="315" src="http://www.youtube.com/embed/VqCkCDFLSsc?vq=hd720" frameborder="0" allowfullscreen></iframe></center>
+
+`Slides <http://llvm.org/devmtg/2013-04/klimek-slides.pdf>`_
+
Introduction
============
@@ -27,9 +33,8 @@
=================
A good way to familarize yourself with the Clang AST is to actually look
-at it on some simple example code. Clang has a builtin AST-dump modes,
-which can be enabled with the flags ``-ast-dump`` and ``-ast-dump-xml``. Note
-that ``-ast-dump-xml`` currently only works with debug builds of clang.
+at it on some simple example code. Clang has a builtin AST-dump mode,
+which can be enabled with the flag ``-ast-dump``.
Let's look at a simple example AST:
@@ -41,40 +46,26 @@
return result;
}
- # Clang by default is a frontend for many tools; -cc1 tells it to directly
- # use the C++ compiler mode. -undef leaves out some internal declarations.
- $ clang -cc1 -undef -ast-dump-xml test.cc
+ # Clang by default is a frontend for many tools; -Xclang is used to pass
+ # options directly to the C++ frontend.
+ $ clang -Xclang -ast-dump -fsyntax-only test.cc
+ TranslationUnitDecl 0x5aea0d0 <<invalid sloc>>
... cutting out internal declarations of clang ...
- <TranslationUnit ptr="0x4871160">
- <Function ptr="0x48a5800" name="f" prototype="true">
- <FunctionProtoType ptr="0x4871de0" canonical="0x4871de0">
- <BuiltinType ptr="0x4871250" canonical="0x4871250"/>
- <parameters>
- <BuiltinType ptr="0x4871250" canonical="0x4871250"/>
- </parameters>
- </FunctionProtoType>
- <ParmVar ptr="0x4871d80" name="x" initstyle="c">
- <BuiltinType ptr="0x4871250" canonical="0x4871250"/>
- </ParmVar>
- <Stmt>
- (CompoundStmt 0x48a5a38 <t2.cc:1:14, line:4:1>
- (DeclStmt 0x48a59c0 <line:2:3, col:24>
- 0x48a58c0 "int result =
- (ParenExpr 0x48a59a0 <col:16, col:23> 'int'
- (BinaryOperator 0x48a5978 <col:17, col:21> 'int' '/'
- (ImplicitCastExpr 0x48a5960 <col:17> 'int' <LValueToRValue>
- (DeclRefExpr 0x48a5918 <col:17> 'int' lvalue ParmVar 0x4871d80 'x' 'int'))
- (IntegerLiteral 0x48a5940 <col:21> 'int' 42)))")
- (ReturnStmt 0x48a5a18 <line:3:3, col:10>
- (ImplicitCastExpr 0x48a5a00 <col:10> 'int' <LValueToRValue>
- (DeclRefExpr 0x48a59d8 <col:10> 'int' lvalue Var 0x48a58c0 'result' 'int'))))
+ `-FunctionDecl 0x5aeab50 <test.cc:1:1, line:4:1> f 'int (int)'
+ |-ParmVarDecl 0x5aeaa90 <line:1:7, col:11> x 'int'
+ `-CompoundStmt 0x5aead88 <col:14, line:4:1>
+ |-DeclStmt 0x5aead10 <line:2:3, col:24>
+ | `-VarDecl 0x5aeac10 <col:3, col:23> result 'int'
+ | `-ParenExpr 0x5aeacf0 <col:16, col:23> 'int'
+ | `-BinaryOperator 0x5aeacc8 <col:17, col:21> 'int' '/'
+ | |-ImplicitCastExpr 0x5aeacb0 <col:17> 'int' <LValueToRValue>
+ | | `-DeclRefExpr 0x5aeac68 <col:17> 'int' lvalue ParmVar 0x5aeaa90 'x' 'int'
+ | `-IntegerLiteral 0x5aeac90 <col:21> 'int' 42
+ `-ReturnStmt 0x5aead68 <line:3:3, col:10>
+ `-ImplicitCastExpr 0x5aead50 <col:10> 'int' <LValueToRValue>
+ `-DeclRefExpr 0x5aead28 <col:10> 'int' lvalue Var 0x5aeac10 'result' 'int'
- </Stmt>
- </Function>
- </TranslationUnit>
-
-In general, ``-ast-dump-xml`` dumps declarations in an XML-style format and
-statements in an S-expression-style format. The toplevel declaration in
+The toplevel declaration in
a translation unit is always the `translation unit
declaration <http://clang.llvm.org/doxygen/classclang_1_1TranslationUnitDecl.html>`_.
In this example, our first user written declaration is the `function
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 324feaf..ca1b7ea 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -159,12 +159,16 @@
# include "myinclude.h"
#endif
+To test for this feature, use ``#if defined(__has_include)``:
+
+.. code-block:: c++
+
// To avoid problem with non-clang compilers not having this macro.
- #if defined(__has_include) && __has_include("myinclude.h")
+ #if defined(__has_include)
+ #if __has_include("myinclude.h")
# include "myinclude.h"
#endif
-
-To test for this feature, use ``#if defined(__has_include)``.
+ #endif
.. _langext-__has_include_next:
@@ -185,9 +189,11 @@
#endif
// To avoid problem with non-clang compilers not having this macro.
- #if defined(__has_include_next) && __has_include_next("myinclude.h")
+ #if defined(__has_include_next)
+ #if __has_include_next("myinclude.h")
# include_next "myinclude.h"
#endif
+ #endif
Note that ``__has_include_next``, like the GNU extension ``#include_next``
directive, is intended for use in headers only, and will issue a warning if
@@ -801,8 +807,7 @@
``__has_extension(cxx_contextual_conversions)`` to determine if the C++1y rules
are used when performing an implicit conversion for an array bound in a
*new-expression*, the operand of a *delete-expression*, an integral constant
-expression, or a condition in a ``switch`` statement. Clang does not yet
-support this feature.
+expression, or a condition in a ``switch`` statement.
C++1y decltype(auto)
^^^^^^^^^^^^^^^^^^^^
@@ -821,9 +826,9 @@
C++1y generalized lambda capture
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Use ``__has_feature(cxx_generalized_capture)`` or
-``__has_extension(cxx_generalized_capture`` to determine if support for
-generalized lambda captures is enabled
+Use ``__has_feature(cxx_init_capture)`` or
+``__has_extension(cxx_init_capture)`` to determine if support for
+lambda captures with explicit initializers is enabled
(for instance, ``[n(0)] { return ++n; }``).
Clang does not yet support this feature.
@@ -843,7 +848,6 @@
``__has_extension(cxx_relaxed_constexpr)`` to determine if variable
declarations, local variable modification, and control flow constructs
are permitted in ``constexpr`` functions.
-Clang's implementation of this feature is incomplete.
C++1y return type deduction
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -852,7 +856,6 @@
``__has_extension(cxx_return_type_deduction)`` to determine if support
for return type deduction for functions (using ``auto`` as a return type)
is enabled.
-Clang's implementation of this feature is incomplete.
C++1y runtime-sized arrays
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -918,8 +921,8 @@
C11 ``_Thread_local``
^^^^^^^^^^^^^^^^^^^^^
-Use ``__has_feature(c_thread_local)`` to determine if support for
-``_Thread_local`` variables is enabled.
+Use ``__has_feature(c_thread_local)`` or ``__has_extension(c_thread_local)``
+to determine if support for ``_Thread_local`` variables is enabled.
Checks for Type Traits
======================
@@ -1173,8 +1176,52 @@
.. _langext-objc_method_family:
-The ``objc_method_family`` attribute
-------------------------------------
+
+Objective-C requiring a call to ``super`` in an override
+--------------------------------------------------------
+
+Some Objective-C classes allow a subclass to override a particular method in a
+parent class but expect that the overriding method also calls the overridden
+method in the parent class. For these cases, we provide an attribute to
+designate that a method requires a "call to ``super``" in the overriding
+method in the subclass.
+
+**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only
+be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+ - (void)foo __attribute__((objc_requires_super));
+
+This attribute can only be applied the method declarations within a class, and
+not a protocol. Currently this attribute does not enforce any placement of
+where the call occurs in the overriding method (such as in the case of
+``-dealloc`` where the call must appear at the end). It checks only that it
+exists.
+
+Note that on both OS X and iOS that the Foundation framework provides a
+convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
+attribute:
+
+.. code-block:: objc
+
+ - (void)foo NS_REQUIRES_SUPER;
+
+This macro is conditionally defined depending on the compiler's support for
+this attribute. If the compiler does not support the attribute the macro
+expands to nothing.
+
+Operationally, when a method has this annotation the compiler will warn if the
+implementation of an override in a subclass does not call super. For example:
+
+.. code-block:: objc
+
+ warning: method possibly missing a [super AnnotMeth] call
+ - (void) AnnotMeth{};
+ ^
+
+Objective-C Method Families
+---------------------------
Many methods in Objective-C have conventional meanings determined by their
selectors. It is sometimes useful to be able to mark a method as having a
@@ -1253,6 +1300,21 @@
``__has_attribute(ns_returns_retained)``, etc.
+Objective-C++ ABI: protocol-qualifier mangling of parameters
+------------------------------------------------------------
+
+Starting with LLVM 3.4, Clang produces a new mangling for parameters whose
+type is a qualified-``id`` (e.g., ``id<Foo>``). This mangling allows such
+parameters to be differentiated from those with the regular unqualified ``id``
+type.
+
+This was a non-backward compatible mangling change to the ABI. This change
+allows proper overloading, and also prevents mangling conflicts with template
+parameters of protocol-qualified type.
+
+Query the presence of this new mangling with
+``__has_feature(objc_protocol_qualifier_mangling)``.
+
Function Overloading in C
=========================
@@ -1411,7 +1473,9 @@
target, the return value is always zero. This builtin takes no arguments and
produces an unsigned long long result.
-Query for this feature with ``__has_builtin(__builtin_readcyclecounter)``.
+Query for this feature with ``__has_builtin(__builtin_readcyclecounter)``. Note
+that even if present, its use may depend on run-time privilege or other OS
+controlled state.
.. _langext-__builtin_shufflevector:
@@ -1433,8 +1497,8 @@
.. code-block:: c++
- // Identity operation - return 4-element vector V1.
- __builtin_shufflevector(V1, V1, 0, 1, 2, 3)
+ // identity operation - return 4-element vector v1.
+ __builtin_shufflevector(v1, v1, 0, 1, 2, 3)
// "Splat" element 0 of V1 into a 4-element result.
__builtin_shufflevector(V1, V1, 0, 0, 0, 0)
@@ -1448,6 +1512,9 @@
// Concatenate every other element of 8-element vectors V1 and V2.
__builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)
+ // Shuffle v1 with some elements being undefined
+ __builtin_shufflevector(v1, v1, 3, -1, 1, -1)
+
**Description**:
The first two arguments to ``__builtin_shufflevector`` are vectors that have
@@ -1456,7 +1523,8 @@
and returned in a new vector. These element indices are numbered sequentially
starting with the first vector, continuing into the second vector. Thus, if
``vec1`` is a 4-element vector, index 5 would refer to the second element of
-``vec2``.
+``vec2``. An index of -1 can be used to indicate that the corresponding element
+in the returned vector is a don't care and can be optimized by the backend.
The result of ``__builtin_shufflevector`` is a vector with the same element
type as ``vec1``/``vec2`` but that has an element count equal to the number of
@@ -1464,6 +1532,50 @@
Query for this feature with ``__has_builtin(__builtin_shufflevector)``.
+``__builtin_convertvector``
+---------------------------
+
+``__builtin_convertvector`` is used to express generic vector
+type-conversion operations. The input vector and the output vector
+type must have the same number of elements.
+
+**Syntax**:
+
+.. code-block:: c++
+
+ __builtin_convertvector(src_vec, dst_vec_type)
+
+**Examples**:
+
+.. code-block:: c++
+
+ typedef double vector4double __attribute__((__vector_size__(32)));
+ typedef float vector4float __attribute__((__vector_size__(16)));
+ typedef short vector4short __attribute__((__vector_size__(8)));
+ vector4float vf; vector4short vs;
+
+ // convert from a vector of 4 floats to a vector of 4 doubles.
+ __builtin_convertvector(vf, vector4double)
+ // equivalent to:
+ (vector4double) { (double) vf[0], (double) vf[1], (double) vf[2], (double) vf[3] }
+
+ // convert from a vector of 4 shorts to a vector of 4 floats.
+ __builtin_convertvector(vs, vector4float)
+ // equivalent to:
+ (vector4float) { (float) vf[0], (float) vf[1], (float) vf[2], (float) vf[3] }
+
+**Description**:
+
+The first argument to ``__builtin_convertvector`` is a vector, and the second
+argument is a vector type with the same number of elements as the first
+argument.
+
+The result of ``__builtin_convertvector`` is a vector with the same element
+type as the second argument, with a value defined in terms of the action of a
+C-style cast applied to each element of the first argument.
+
+Query for this feature with ``__has_builtin(__builtin_convertvector)``.
+
``__builtin_unreachable``
-------------------------
@@ -1526,6 +1638,22 @@
implementation details of ``__sync_lock_test_and_set()``. The
``__sync_swap()`` builtin is a full barrier.
+``__builtin_addressof``
+-----------------------
+
+``__builtin_addressof`` performs the functionality of the built-in ``&``
+operator, ignoring any ``operator&`` overload. This is useful in constant
+expressions in C++11, where there is no other way to take the address of an
+object that overloads ``operator&``.
+
+**Example of use**:
+
+.. code-block:: c++
+
+ template<typename T> constexpr T *addressof(T &value) {
+ return __builtin_addressof(value);
+ }
+
Multiprecision Arithmetic Builtins
----------------------------------
@@ -1554,15 +1682,60 @@
.. code-block:: c
+ unsigned char __builtin_addcb (unsigned char x, unsigned char y, unsigned char carryin, unsigned char *carryout);
unsigned short __builtin_addcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
unsigned __builtin_addc (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
unsigned long __builtin_addcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);
unsigned long long __builtin_addcll(unsigned long long x, unsigned long long y, unsigned long long carryin, unsigned long long *carryout);
+ unsigned char __builtin_subcb (unsigned char x, unsigned char y, unsigned char carryin, unsigned char *carryout);
unsigned short __builtin_subcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
unsigned __builtin_subc (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
unsigned long __builtin_subcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);
unsigned long long __builtin_subcll(unsigned long long x, unsigned long long y, unsigned long long carryin, unsigned long long *carryout);
+Checked Arithmetic Builtins
+---------------------------
+
+Clang provides a set of builtins that implement checked arithmetic for security
+critical applications in a manner that is fast and easily expressable in C. As
+an example of their usage:
+
+.. code-block:: c
+
+ errorcode_t security_critical_application(...) {
+ unsigned x, y, result;
+ ...
+ if (__builtin_umul_overflow(x, y, &result))
+ return kErrorCodeHackers;
+ ...
+ use_multiply(result);
+ ...
+ }
+
+A complete enumeration of the builtins are:
+
+.. code-block:: c
+
+ bool __builtin_uadd_overflow (unsigned x, unsigned y, unsigned *sum);
+ bool __builtin_uaddl_overflow (unsigned long x, unsigned long y, unsigned long *sum);
+ bool __builtin_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *sum);
+ bool __builtin_usub_overflow (unsigned x, unsigned y, unsigned *diff);
+ bool __builtin_usubl_overflow (unsigned long x, unsigned long y, unsigned long *diff);
+ bool __builtin_usubll_overflow(unsigned long long x, unsigned long long y, unsigned long long *diff);
+ bool __builtin_umul_overflow (unsigned x, unsigned y, unsigned *prod);
+ bool __builtin_umull_overflow (unsigned long x, unsigned long y, unsigned long *prod);
+ bool __builtin_umulll_overflow(unsigned long long x, unsigned long long y, unsigned long long *prod);
+ bool __builtin_sadd_overflow (int x, int y, int *sum);
+ bool __builtin_saddl_overflow (long x, long y, long *sum);
+ bool __builtin_saddll_overflow(long long x, long long y, long long *sum);
+ bool __builtin_ssub_overflow (int x, int y, int *diff);
+ bool __builtin_ssubl_overflow (long x, long y, long *diff);
+ bool __builtin_ssubll_overflow(long long x, long long y, long long *diff);
+ bool __builtin_smul_overflow (int x, int y, int *prod);
+ bool __builtin_smull_overflow (long x, long y, long *prod);
+ bool __builtin_smulll_overflow(long long x, long long y, long long *prod);
+
+
.. _langext-__c11_atomic:
__c11_atomic builtins
@@ -1588,6 +1761,37 @@
* ``__c11_atomic_fetch_or``
* ``__c11_atomic_fetch_xor``
+Low-level ARM exclusive memory builtins
+---------------------------------------
+
+Clang provides overloaded builtins giving direct access to the three key ARM
+instructions for implementing atomic operations.
+
+.. code-block:: c
+
+ T __builtin_arm_ldrex(const volatile T *addr);
+ int __builtin_arm_strex(T val, volatile T *addr);
+ void __builtin_arm_clrex(void);
+
+The types ``T`` currently supported are:
+* Integer types with width at most 64 bits.
+* Floating-point types
+* Pointer types.
+
+Note that the compiler does not guarantee it will not insert stores which clear
+the exclusive monitor in between an ``ldrex`` and its paired ``strex``. In
+practice this is only usually a risk when the extra store is on the same cache
+line as the variable being modified and Clang will only insert stack stores on
+its own, so it is best not to use these operations on variables with automatic
+storage duration.
+
+Also, loads and stores may be implicit in code written between the ``ldrex`` and
+``strex``. Clang will not necessarily mitigate the effects of these either, so
+care should be exercised.
+
+For these reasons the higher level atomic primitives should be preferred where
+possible.
+
Non-standard C++11 Attributes
=============================
@@ -1649,7 +1853,7 @@
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_, `GCC variable
attributes <http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html>`_, and
`GCC type attributes
-<http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_. As with the GCC
+<http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_). As with the GCC
implementation, these attributes must appertain to the *declarator-id* in a
declaration, which means they must go either at the start of the declaration or
immediately after the name being declared.
@@ -1698,6 +1902,48 @@
movl %gs:(%eax), %eax
ret
+ARM Language Extensions
+-----------------------
+
+Interrupt attribute
+^^^^^^^^^^^^^^^^^^^
+
+Clang supports the GNU style ``__attribite__((interrupt("TYPE")))`` attribute on
+ARM targets. This attribute may be attached to a function definiton and
+instructs the backend to generate appropriate function entry/exit code so that
+it can be used directly as an interrupt service routine.
+
+ The parameter passed to the interrupt attribute is optional, but if
+provided it must be a string literal with one of the following values: "IRQ",
+"FIQ", "SWI", "ABORT", "UNDEF".
+
+The semantics are as follows:
+
+- If the function is AAPCS, Clang instructs the backend to realign the stack to
+ 8 bytes on entry. This is a general requirement of the AAPCS at public
+ interfaces, but may not hold when an exception is taken. Doing this allows
+ other AAPCS functions to be called.
+- If the CPU is M-class this is all that needs to be done since the architecture
+ itself is designed in such a way that functions obeying the normal AAPCS ABI
+ constraints are valid exception handlers.
+- If the CPU is not M-class, the prologue and epilogue are modified to save all
+ non-banked registers that are used, so that upon return the user-mode state
+ will not be corrupted. Note that to avoid unnecessary overhead, only
+ general-purpose (integer) registers are saved in this way. If VFP operations
+ are needed, that state must be saved manually.
+
+ Specifically, interrupt kinds other than "FIQ" will save all core registers
+ except "lr" and "sp". "FIQ" interrupts will save r0-r7.
+- If the CPU is not M-class, the return instruction is changed to one of the
+ canonical sequences permitted by the architecture for exception return. Where
+ possible the function itself will make the necessary "lr" adjustments so that
+ the "preferred return address" is selected.
+
+ Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
+ handler, where the offset from "lr" to the preferred return address depends on
+ the execution state of the code which generated the exception. In this case
+ a sequence equivalent to "movs pc, lr" will be used.
+
Extensions for Static Analysis
==============================
@@ -1735,8 +1981,8 @@
Use ``__attribute__((no_sanitize_thread))`` on a function declaration
to specify that checks for data races on plain (non-atomic) memory accesses
should not be inserted by ThreadSanitizer.
-The function may still be instrumented by the tool
-to avoid false positives in other places.
+The function is still instrumented by the tool to avoid false positives and
+provide meaningful stack traces.
.. _langext-memory_sanitizer:
@@ -1905,15 +2151,72 @@
locks. Arguments must be lockable type, and there must be at least one
argument.
+Consumed Annotation Checking
+============================
+
+Clang supports additional attributes for checking basic resource management
+properties, specifically for unique objects that have a single owning reference.
+The following attributes are currently supported, although **the implementation
+for these annotations is currently in development and are subject to change.**
+
+``consumable``
+--------------
+
+Each class that uses any of the following annotations must first be marked
+using the consumable attribute. Failure to do so will result in a warning.
+
+``set_typestate(new_state)``
+----------------------------
+
+Annotate methods that transition an object into a new state with
+``__attribute__((set_typestate(new_state)))``. The new new state must be
+unconsumed, consumed, or unknown.
+
+``callable_when(...)``
+----------------------
+
+Use ``__attribute__((callable_when(...)))`` to indicate what states a method
+may be called in. Valid states are unconsumed, consumed, or unknown. Each
+argument to this attribute must be a quoted string. E.g.:
+
+``__attribute__((callable_when("unconsumed", "unknown")))``
+
+``tests_typestate(tested_state)``
+---------------------------------
+
+Use ``__attribute__((tests_typestate(tested_state)))`` to indicate that a method
+returns true if the object is in the specified state..
+
+``param_typestate(expected_state)``
+-----------------------------------
+
+This attribute specifies expectations about function parameters. Calls to an
+function with annotated parameters will issue a warning if the corresponding
+argument isn't in the expected state. The attribute is also used to set the
+initial state of the parameter when analyzing the function's body.
+
+``return_typestate(ret_state)``
+-------------------------------
+
+The ``return_typestate`` attribute can be applied to functions or parameters.
+When applied to a function the attribute specifies the state of the returned
+value. The function's body is checked to ensure that it always returns a value
+in the specified state. On the caller side, values returned by the annotated
+function are initialized to the given state.
+
+If the attribute is applied to a function parameter it modifies the state of
+an argument after a call to the function returns. The function's body is
+checked to ensure that the parameter is in the expected state before returning.
+
Type Safety Checking
====================
Clang supports additional attributes to enable checking type safety properties
-that can't be enforced by C type system. Usecases include:
+that can't be enforced by the C type system. Use cases include:
* MPI library implementations, where these attributes enable checking that
- buffer type matches the passed ``MPI_Datatype``;
-* for HDF5 library there is a similar usecase as MPI;
+ the buffer type matches the passed ``MPI_Datatype``;
+* for HDF5 library there is a similar use case to MPI;
* checking types of variadic functions' arguments for functions like
``fcntl()`` and ``ioctl()``.
@@ -1948,7 +2251,7 @@
applicable type tags.
This attribute is primarily useful for checking arguments of variadic functions
-(``pointer_with_type_tag`` can be used in most of non-variadic cases).
+(``pointer_with_type_tag`` can be used in most non-variadic cases).
For example:
diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst
new file mode 100644
index 0000000..09d02cf
--- /dev/null
+++ b/docs/LeakSanitizer.rst
@@ -0,0 +1,28 @@
+================
+LeakSanitizer
+================
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+LeakSanitizer is a heap leak detector which is designed to be used on top of
+:doc:`AddressSanitizer` / :doc:`MemorySanitizer`, or as a standalone library.
+LeakSanitizer is a run-time tool which doesn't require compiler
+instrumentation.
+
+Current status
+==============
+
+LeakSanitizer is a work in progress, currently under development for
+x86\_64 Linux.
+
+More Information
+================
+
+Design wiki:
+`https://code.google.com/p/address-sanitizer/wiki/LeakSanitizerDesignDocument
+<https://code.google.com/p/address-sanitizer/wiki/LeakSanitizerDesignDocument>`_
+
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index e80e442..2c9b3aa 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -57,6 +57,18 @@
<p>The exception to that rule are matchers that can match on any node. Those
are marked with a * and are listed in the beginning of each category.</p>
+<p>Note that the categorization of matchers is a great help when you combine
+them into matcher expressions. You will usually want to form matcher expressions
+that read like english sentences by alternating between node matchers and
+narrowing or traversal matchers, like this:
+<pre>
+recordDecl(hasDescendant(
+ ifStmt(hasTrueExpression(
+ expr(hasDescendant(
+ ifStmt()))))))
+</pre>
+</p>
+
<!-- ======================================================================= -->
<h2 id="decl-matchers">Node Matchers</h2>
<!-- ======================================================================= -->
@@ -73,10 +85,32 @@
bind the matched node to the given string, to be later retrieved from the
match callback.</p>
+<p>It is important to remember that the arguments to node matchers are
+predicates on the same node, just with additional information about the type.
+This is often useful to make matcher expression more readable by inlining bind
+calls into redundant node matchers inside another node matcher:
+<pre>
+// This binds the CXXRecordDecl to "id", as the decl() matcher will stay on
+// the same node.
+recordDecl(decl().bind("id"), hasName("::MyClass"))
+</pre>
+</p>
+
<table>
<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
<!-- START_DECL_MATCHERS -->
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('ctorInitializer0')"><a name="ctorInitializer0Anchor">ctorInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="ctorInitializer0"><pre>Matches constructor initializers.
+
+Examples matches i(42).
+ class C {
+ C() : i(42) {}
+ int i;
+ };
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('accessSpecDecl0')"><a name="accessSpecDecl0Anchor">accessSpecDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1AccessSpecDecl.html">AccessSpecDecl</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="accessSpecDecl0"><pre>Matches C++ access specifier declarations.
@@ -134,6 +168,17 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('declaratorDecl0')"><a name="declaratorDecl0Anchor">declaratorDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="declaratorDecl0"><pre>Matches declarator declarations (field, variable, function
+and non-type template parameter declarations).
+
+Given
+ class X { int y; };
+declaratorDecl()
+ matches int y.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('destructorDecl0')"><a name="destructorDecl0Anchor">destructorDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDestructorDecl.html">CXXDestructorDecl</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="destructorDecl0"><pre>Matches explicit C++ destructor declarations.
@@ -175,6 +220,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('friendDecl0')"><a name="friendDecl0Anchor">friendDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FriendDecl.html">FriendDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="friendDecl0"><pre>Matches friend declarations.
+
+Given
+ class X { friend void foo(); };
+friendDecl()
+ matches 'friend void foo()'.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('functionDecl0')"><a name="functionDecl0Anchor">functionDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="functionDecl0"><pre>Matches function declarations.
@@ -212,6 +267,27 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('namespaceDecl0')"><a name="namespaceDecl0Anchor">namespaceDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamespaceDecl.html">NamespaceDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="namespaceDecl0"><pre>Matches a declaration of a namespace.
+
+Given
+ namespace {}
+ namespace test {}
+namespaceDecl()
+ matches "namespace {}" and "namespace test {}"
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('parmVarDecl0')"><a name="parmVarDecl0Anchor">parmVarDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="parmVarDecl0"><pre>Matches parameter variable declarations.
+
+Given
+ void f(int x);
+parmVarDecl()
+ matches int x.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('recordDecl0')"><a name="recordDecl0Anchor">recordDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="recordDecl0"><pre>Matches C++ class declarations.
@@ -221,6 +297,18 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('unresolvedUsingValueDecl0')"><a name="unresolvedUsingValueDecl0Anchor">unresolvedUsingValueDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingValueDecl.html">UnresolvedUsingValueDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="unresolvedUsingValueDecl0"><pre>Matches unresolved using value declarations.
+
+Given
+ template<typename X>
+ class C : private X {
+ using X::x;
+ };
+unresolvedUsingValueDecl()
+ matches using X::x </pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('usingDecl0')"><a name="usingDecl0Anchor">usingDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="usingDecl0"><pre>Matches using declarations.
@@ -341,6 +429,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('caseStmt0')"><a name="caseStmt0Anchor">caseStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CaseStmt.html">CaseStmt</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="caseStmt0"><pre>Matches case statements inside switch statements.
+
+Given
+ switch(a) { case 42: break; default: break; }
+caseStmt()
+ matches 'case 42: break;'.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('castExpr0')"><a name="castExpr0Anchor">castExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="castExpr0"><pre>Matches any cast nodes of Clang's AST.
@@ -460,6 +558,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('defaultStmt0')"><a name="defaultStmt0Anchor">defaultStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DefaultStmt.html">DefaultStmt</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="defaultStmt0"><pre>Matches default statements inside switch statements.
+
+Given
+ switch(a) { case 42: break; default: break; }
+defaultStmt()
+ matches 'default: break;'.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('deleteExpr0')"><a name="deleteExpr0Anchor">deleteExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDeleteExpr.html">CXXDeleteExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="deleteExpr0"><pre>Matches delete expressions.
@@ -523,6 +631,15 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('floatLiteral0')"><a name="floatLiteral0Anchor">floatLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="floatLiteral0"><pre>Matches float literals of all sizes encodings, e.g.
+1.0, 1.0f, 1.0L and 1e10.
+
+Does not match implicit conversions such as
+ float a = 10;
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('forRangeStmt0')"><a name="forRangeStmt0Anchor">forRangeStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="forRangeStmt0"><pre>Matches range-based for statements.
@@ -591,11 +708,10 @@
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('integerLiteral0')"><a name="integerLiteral0Anchor">integerLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="integerLiteral0"><pre>Matches integer literals of all sizes encodings.
+<tr><td colspan="4" class="doc" id="integerLiteral0"><pre>Matches integer literals of all sizes encodings, e.g.
+1, 1L, 0x1 and 1U.
-Not matching character-encoded integers such as L'a'.
-
-Example matches 1, 1L, 0x1, 1U
+Does not match character-encoded integers such as L'a'.
</pre></td></tr>
@@ -771,6 +887,14 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('temporaryObjectExpr0')"><a name="temporaryObjectExpr0Anchor">temporaryObjectExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="temporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments
+
+Example: Matches Foo(bar, bar)
+ Foo h = Foo(bar, bar);
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('thisExpr0')"><a name="thisExpr0Anchor">thisExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXThisExpr.html">CXXThisExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="thisExpr0"><pre>Matches implicit and explicit this expressions.
@@ -820,6 +944,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('unresolvedConstructExpr0')"><a name="unresolvedConstructExpr0Anchor">unresolvedConstructExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="unresolvedConstructExpr0"><pre>Matches unresolved constructor call expressions.
+
+Example matches T(t) in return statement of f
+ (matcher = unresolvedConstructExpr())
+ template <typename T>
+ void f(const T& t) { return T(t); }
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('userDefinedLiteral0')"><a name="userDefinedLiteral0Anchor">userDefinedLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UserDefinedLiteral.html">UserDefinedLiteral</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="userDefinedLiteral0"><pre>Matches user defined literal operator call.
@@ -837,285 +971,11 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('arrayTypeLoc0')"><a name="arrayTypeLoc0Anchor">arrayTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayTypeLoc.html">ArrayTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="arrayTypeLoc0"><pre>Matches all kinds of arrays.
-
-Given
- int a[] = { 2, 3 };
- int b[4];
- void f() { int c[a[0]]; }
-arrayType()
- matches "int a[]", "int b[4]" and "int c[a[0]]";
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('atomicTypeLoc0')"><a name="atomicTypeLoc0Anchor">atomicTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1AtomicTypeLoc.html">AtomicTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="atomicTypeLoc0"><pre>Matches atomic types.
-
-Given
- _Atomic(int) i;
-atomicType()
- matches "_Atomic(int) i"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('autoTypeLoc0')"><a name="autoTypeLoc0Anchor">autoTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1AutoTypeLoc.html">AutoTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="autoTypeLoc0"><pre>Matches types nodes representing C++11 auto types.
-
-Given:
- auto n = 4;
- int v[] = { 2, 3 }
- for (auto i : v) { }
-autoType()
- matches "auto n" and "auto i"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('blockPointerTypeLoc0')"><a name="blockPointerTypeLoc0Anchor">blockPointerTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockPointerTypeLoc.html">BlockPointerTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="blockPointerTypeLoc0"><pre>Matches block pointer types, i.e. types syntactically represented as
-"void (^)(int)".
-
-The pointee is always required to be a FunctionType.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('builtinTypeLoc0')"><a name="builtinTypeLoc0Anchor">builtinTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BuiltinTypeLoc.html">BuiltinTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="builtinTypeLoc0"><pre>Matches builtin Types.
-
-Given
- struct A {};
- A a;
- int b;
- float c;
- bool d;
-builtinType()
- matches "int b", "float c" and "bool d"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('complexTypeLoc0')"><a name="complexTypeLoc0Anchor">complexTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ComplexTypeLoc.html">ComplexTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="complexTypeLoc0"><pre>Matches C99 complex types.
-
-Given
- _Complex float f;
-complexType()
- matches "_Complex float f"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('constantArrayTypeLoc0')"><a name="constantArrayTypeLoc0Anchor">constantArrayTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConstantArrayTypeLoc.html">ConstantArrayTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="constantArrayTypeLoc0"><pre>Matches C arrays with a specified constant size.
-
-Given
- void() {
- int a[2];
- int b[] = { 2, 3 };
- int c[b[0]];
- }
-constantArrayType()
- matches "int a[2]"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('dependentSizedArrayTypeLoc0')"><a name="dependentSizedArrayTypeLoc0Anchor">dependentSizedArrayTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DependentSizedArrayTypeLoc.html">DependentSizedArrayTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="dependentSizedArrayTypeLoc0"><pre>Matches C++ arrays whose size is a value-dependent expression.
-
-Given
- template<typename T, int Size>
- class array {
- T data[Size];
- };
-dependentSizedArrayType
- matches "T data[Size]"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('elaboratedTypeLoc0')"><a name="elaboratedTypeLoc0Anchor">elaboratedTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ElaboratedTypeLoc.html">ElaboratedTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="elaboratedTypeLoc0"><pre>Matches types specified with an elaborated type keyword or with a
-qualified name.
-
-Given
- namespace N {
- namespace M {
- class D {};
- }
- }
- class C {};
-
- class C c;
- N::M::D d;
-
-elaboratedType() matches the type of the variable declarations of both
-c and d.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('functionTypeLoc0')"><a name="functionTypeLoc0Anchor">functionTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionTypeLoc.html">FunctionTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="functionTypeLoc0"><pre>Matches FunctionType nodes.
-
-Given
- int (*f)(int);
- void g();
-functionType()
- matches "int (*f)(int)" and the type of "g".
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('incompleteArrayTypeLoc0')"><a name="incompleteArrayTypeLoc0Anchor">incompleteArrayTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IncompleteArrayTypeLoc.html">IncompleteArrayTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="incompleteArrayTypeLoc0"><pre>Matches C arrays with unspecified size.
-
-Given
- int a[] = { 2, 3 };
- int b[42];
- void f(int c[]) { int d[a[0]]; };
-incompleteArrayType()
- matches "int a[]" and "int c[]"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('lValueReferenceTypeLoc0')"><a name="lValueReferenceTypeLoc0Anchor">lValueReferenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LValueReferenceTypeLoc.html">LValueReferenceTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="lValueReferenceTypeLoc0"><pre>Matches lvalue reference types.
-
-Given:
- int *a;
- int &b = *a;
- int &&c = 1;
- auto &d = b;
- auto &&e = c;
- auto &&f = 2;
- int g = 5;
-
-lValueReferenceType() matches the types of b, d, and e. e is
-matched since the type is deduced as int& by reference collapsing rules.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('memberPointerTypeLoc0')"><a name="memberPointerTypeLoc0Anchor">memberPointerTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerTypeLoc.html">MemberPointerTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="memberPointerTypeLoc0"><pre>Matches member pointer types.
-Given
- struct A { int i; }
- A::* ptr = A::i;
-memberPointerType()
- matches "A::* ptr"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('parenTypeLoc0')"><a name="parenTypeLoc0Anchor">parenTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParenTypeLoc.html">ParenTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="parenTypeLoc0"><pre>Matches ParenType nodes.
-
-Given
- int (*ptr_to_array)[4];
- int *array_of_ptrs[4];
-
-varDecl(hasType(pointsTo(parenType()))) matches ptr_to_array but not
-array_of_ptrs.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('pointerTypeLoc0')"><a name="pointerTypeLoc0Anchor">pointerTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="pointerTypeLoc0"><pre>Matches pointer types.
-
-Given
- int *a;
- int &b = *a;
- int c = 5;
-pointerType()
- matches "int *a"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('rValueReferenceTypeLoc0')"><a name="rValueReferenceTypeLoc0Anchor">rValueReferenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RValueReferenceTypeLoc.html">RValueReferenceTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="rValueReferenceTypeLoc0"><pre>Matches rvalue reference types.
-
-Given:
- int *a;
- int &b = *a;
- int &&c = 1;
- auto &d = b;
- auto &&e = c;
- auto &&f = 2;
- int g = 5;
-
-rValueReferenceType() matches the types of c and f. e is not
-matched as it is deduced to int& by reference collapsing rules.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('recordTypeLoc0')"><a name="recordTypeLoc0Anchor">recordTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordTypeLoc.html">RecordTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="recordTypeLoc0"><pre>Matches record types (e.g. structs, classes).
-
-Given
- class C {};
- struct S {};
-
- C c;
- S s;
-
-recordType() matches the type of the variable declarations of both c
-and s.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('referenceTypeLoc0')"><a name="referenceTypeLoc0Anchor">referenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html">ReferenceTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="referenceTypeLoc0"><pre>Matches both lvalue and rvalue reference types.
-
-Given
- int *a;
- int &b = *a;
- int &&c = 1;
- auto &d = b;
- auto &&e = c;
- auto &&f = 2;
- int g = 5;
-
-referenceType() matches the types of b, c, d, e, and f.
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('templateSpecializationTypeLoc0')"><a name="templateSpecializationTypeLoc0Anchor">templateSpecializationTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationTypeLoc.html">TemplateSpecializationTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="templateSpecializationTypeLoc0"><pre>Matches template specialization types.
-
-Given
- template <typename T>
- class C { };
-
- template class C<int>; A
- C<char> var; B
-
-templateSpecializationType() matches the type of the explicit
-instantiation in A and the type of the variable declaration in B.
-</pre></td></tr>
-
-
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('typeLoc0')"><a name="typeLoc0Anchor">typeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="typeLoc0"><pre>Matches TypeLocs in the clang AST.
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('typedefTypeLoc0')"><a name="typedefTypeLoc0Anchor">typedefTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefTypeLoc.html">TypedefTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="typedefTypeLoc0"><pre>Matches typedef types.
-
-Given
- typedef int X;
-typedefType()
- matches "typedef int X"
-</pre></td></tr>
-
-
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('variableArrayTypeLoc0')"><a name="variableArrayTypeLoc0Anchor">variableArrayTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VariableArrayTypeLoc.html">VariableArrayTypeLoc</a>>...</td></tr>
-<tr><td colspan="4" class="doc" id="variableArrayTypeLoc0"><pre>Matches C arrays with a specified size that is not an
-integer-constant-expression.
-
-Given
- void f() {
- int a[] = { 2, 3 }
- int b[42];
- int c[a[0]];
-variableArrayType()
- matches "int c[a[0]]"
-</pre></td></tr>
-
-
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('arrayType0')"><a name="arrayType0Anchor">arrayType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayType.html">ArrayType</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="arrayType0"><pre>Matches all kinds of arrays.
@@ -1381,6 +1241,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('unaryTransformType0')"><a name="unaryTransformType0Anchor">unaryTransformType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryTransformType.html">UnaryTransformType</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="unaryTransformType0"><pre>Matches types nodes representing unary type transformations.
+
+Given:
+ typedef __underlying_type(T) type;
+unaryTransformType()
+ matches "__underlying_type(T)"
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('variableArrayType0')"><a name="variableArrayType0Anchor">variableArrayType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VariableArrayType.html">VariableArrayType</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="variableArrayType0"><pre>Matches C arrays with a specified size that is not an
integer-constant-expression.
@@ -1411,14 +1281,14 @@
<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
<!-- START_NARROWING_MATCHERS -->
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('allOf0')"><a name="allOf0Anchor">allOf</a></td><td>Matcher<*> P1, Matcher<*> P2</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('allOf0')"><a name="allOf0Anchor">allOf</a></td><td>Matcher<*>, ..., Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="allOf0"><pre>Matches if all given matchers match.
Usable as: Any Matcher
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('anyOf0')"><a name="anyOf0Anchor">anyOf</a></td><td>Matcher<*> P1, Matcher<*> P2</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('anyOf0')"><a name="anyOf0Anchor">anyOf</a></td><td>Matcher<*>, ..., Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="anyOf0"><pre>Matches if any of the given matchers matches.
Usable as: Any Matcher
@@ -1472,6 +1342,16 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('argumentCountIs1')"><a name="argumentCountIs1Anchor">argumentCountIs</a></td><td>unsigned N</td></tr>
+<tr><td colspan="4" class="doc" id="argumentCountIs1"><pre>Checks that a call expression or a constructor call expression has
+a specific number of arguments (including absent default arguments).
+
+Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
+ void f(int x, int y);
+ f(0, 0);
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a constructor declaration that has been implicitly added
by the compiler (eg. implicit defaultcopy constructors).
@@ -1479,7 +1359,7 @@
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('isWritten0')"><a name="isWritten0Anchor">isWritten</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isWritten0"><pre>Matches a contructor initializer if it is explicitly written in
+<tr><td colspan="4" class="doc" id="isWritten0"><pre>Matches a constructor initializer if it is explicitly written in
code (as opposed to implicitly added by the compiler).
Given
@@ -1513,6 +1393,19 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isConst0')"><a name="isConst0Anchor">isConst</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isConst0"><pre>Matches if the given method declaration is const.
+
+Given
+struct A {
+ void foo() const;
+ void bar();
+};
+
+methodDecl(isConst()) matches A::foo() but not A::bar()
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isOverride0')"><a name="isOverride0Anchor">isOverride</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isOverride0"><pre>Matches if the given method declaration overrides another method.
@@ -1665,6 +1558,29 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('equalsBoundNode1')"><a name="equalsBoundNode1Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
+<tr><td colspan="4" class="doc" id="equalsBoundNode1"><pre>Matches if a node equals a previously bound node.
+
+Matches a node if it equals the node previously bound to ID.
+
+Given
+ class X { int a; int b; };
+recordDecl(
+ has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
+ has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
+ matches the class X, as a and b have the same type.
+
+Note that when multiple matches are involved via forEach* matchers,
+equalsBoundNodes acts as a filter.
+For example:
+compoundStmt(
+ forEachDescendant(varDecl().bind("d")),
+ forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
+will trigger a match for each combination of variable declaration
+and reference to that variable declaration within a compound statement.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl* Other</td></tr>
<tr><td colspan="4" class="doc" id="equalsNode0"><pre>Matches if a node equals another node.
@@ -1868,6 +1784,29 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('equalsBoundNode3')"><a name="equalsBoundNode3Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
+<tr><td colspan="4" class="doc" id="equalsBoundNode3"><pre>Matches if a node equals a previously bound node.
+
+Matches a node if it equals the node previously bound to ID.
+
+Given
+ class X { int a; int b; };
+recordDecl(
+ has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
+ has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
+ matches the class X, as a and b have the same type.
+
+Note that when multiple matches are involved via forEach* matchers,
+equalsBoundNodes acts as a filter.
+For example:
+compoundStmt(
+ forEachDescendant(varDecl().bind("d")),
+ forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
+will trigger a match for each combination of variable declaration
+and reference to that variable declaration within a compound statement.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasLocalQualifiers0')"><a name="hasLocalQualifiers0Anchor">hasLocalQualifiers</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="hasLocalQualifiers0"><pre>Matches QualType nodes that have local CV-qualifiers attached to
the node, not hidden within a typedef.
@@ -1912,6 +1851,29 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('equalsBoundNode0')"><a name="equalsBoundNode0Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
+<tr><td colspan="4" class="doc" id="equalsBoundNode0"><pre>Matches if a node equals a previously bound node.
+
+Matches a node if it equals the node previously bound to ID.
+
+Given
+ class X { int a; int b; };
+recordDecl(
+ has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
+ has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
+ matches the class X, as a and b have the same type.
+
+Note that when multiple matches are involved via forEach* matchers,
+equalsBoundNodes acts as a filter.
+For example:
+compoundStmt(
+ forEachDescendant(varDecl().bind("d")),
+ forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
+will trigger a match for each combination of variable declaration
+and reference to that variable declaration within a compound statement.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt* Other</td></tr>
<tr><td colspan="4" class="doc" id="equalsNode1"><pre>Matches if a node equals another node.
@@ -1935,6 +1897,29 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('equalsBoundNode2')"><a name="equalsBoundNode2Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr>
+<tr><td colspan="4" class="doc" id="equalsBoundNode2"><pre>Matches if a node equals a previously bound node.
+
+Matches a node if it equals the node previously bound to ID.
+
+Given
+ class X { int a; int b; };
+recordDecl(
+ has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
+ has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
+ matches the class X, as a and b have the same type.
+
+Note that when multiple matches are involved via forEach* matchers,
+equalsBoundNodes acts as a filter.
+For example:
+compoundStmt(
+ forEachDescendant(varDecl().bind("d")),
+ forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
+will trigger a match for each combination of variable declaration
+and reference to that variable declaration within a compound statement.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>></td><td class="name" onclick="toggle('ofKind0')"><a name="ofKind0Anchor">ofKind</a></td><td>UnaryExprOrTypeTrait Kind</td></tr>
<tr><td colspan="4" class="doc" id="ofKind0"><pre>Matches unary expressions of a certain kind.
@@ -2022,7 +2007,7 @@
<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
<!-- START_TRAVERSAL_MATCHERS -->
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('eachOf0')"><a name="eachOf0Anchor">eachOf</a></td><td>Matcher<*> P1, Matcher<*> P2</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('eachOf0')"><a name="eachOf0Anchor">eachOf</a></td><td>Matcher<*>, ..., Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="eachOf0"><pre>Matches if any of the given matchers matches.
Unlike anyOf, eachOf will generate a match result for each
@@ -2041,22 +2026,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('findAll0')"><a name="findAll0Anchor">findAll</a></td><td>Matcher<T> Matcher</td></tr>
-<tr><td colspan="4" class="doc" id="findAll0"><pre>Matches if the node or any descendant matches.
-
-Generates results for each match.
-
-For example, in:
- class A { class B {}; class C {}; };
-The matcher:
- recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m")))
-will generate results for A, B and C.
-
-Usable as: Any Matcher
-</pre></td></tr>
-
-
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEach0')"><a name="forEach0Anchor">forEach</a></td><td>Matcher<ChildT> ChildMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEach0')"><a name="forEach0Anchor">forEach</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="forEach0"><pre>Matches AST nodes that have child AST nodes that match the
provided matcher.
@@ -2074,7 +2044,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEachDescendant0')"><a name="forEachDescendant0Anchor">forEachDescendant</a></td><td>Matcher<DescendantT> DescendantMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEachDescendant0')"><a name="forEachDescendant0Anchor">forEachDescendant</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="forEachDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the
provided matcher.
@@ -2098,7 +2068,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('has0')"><a name="has0Anchor">has</a></td><td>Matcher<ChildT> ChildMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('has0')"><a name="has0Anchor">has</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="has0"><pre>Matches AST nodes that have child AST nodes that match the
provided matcher.
@@ -2113,7 +2083,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasAncestor0')"><a name="hasAncestor0Anchor">hasAncestor</a></td><td>Matcher<AncestorT> AncestorMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasAncestor0')"><a name="hasAncestor0Anchor">hasAncestor</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="hasAncestor0"><pre>Matches AST nodes that have an ancestor that matches the provided
matcher.
@@ -2126,7 +2096,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasDescendant0')"><a name="hasDescendant0Anchor">hasDescendant</a></td><td>Matcher<DescendantT> DescendantMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasDescendant0')"><a name="hasDescendant0Anchor">hasDescendant</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="hasDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the
provided matcher.
@@ -2142,7 +2112,7 @@
</pre></td></tr>
-<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasParent0')"><a name="hasParent0Anchor">hasParent</a></td><td>Matcher<ParentT> ParentMatcher</td></tr>
+<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasParent0')"><a name="hasParent0Anchor">hasParent</a></td><td>Matcher<*></td></tr>
<tr><td colspan="4" class="doc" id="hasParent0"><pre>Matches AST nodes that have a parent that matches the provided
matcher.
@@ -2177,8 +2147,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayTypeLoc.html">ArrayTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc1')"><a name="hasElementTypeLoc1Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="hasElementTypeLoc1"><pre>Matches arrays and C99 complex types that have a specific element
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayTypeLoc.html">ArrayTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc0')"><a name="hasElementTypeLoc0Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="hasElementTypeLoc0"><pre>Matches arrays and C99 complex types that have a specific element
type.
Given
@@ -2192,8 +2162,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayType.html">ArrayType</a>></td><td class="name" onclick="toggle('hasElementType1')"><a name="hasElementType1Anchor">hasElementType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="hasElementType1"><pre>Matches arrays and C99 complex types that have a specific element
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArrayType.html">ArrayType</a>></td><td class="name" onclick="toggle('hasElementType0')"><a name="hasElementType0Anchor">hasElementType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="hasElementType0"><pre>Matches arrays and C99 complex types that have a specific element
type.
Given
@@ -2271,8 +2241,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockPointerTypeLoc.html">BlockPointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc3')"><a name="pointeeLoc3Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointeeLoc3"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockPointerTypeLoc.html">BlockPointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc0')"><a name="pointeeLoc0Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointeeLoc0"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -2287,8 +2257,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockPointerType.html">BlockPointerType</a>></td><td class="name" onclick="toggle('pointee3')"><a name="pointee3Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointee3"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockPointerType.html">BlockPointerType</a>></td><td class="name" onclick="toggle('pointee0')"><a name="pointee0Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointee0"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -2303,17 +2273,65 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasDeclaration3')"><a name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument1')"><a name="hasAnyArgument1Anchor">hasAnyArgument</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyArgument1"><pre>Matches any argument of a call expression or a constructor call
+expression.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+Given
+ void x(int, int, int) { int y; x(1, y, 42); }
+callExpr(hasAnyArgument(declRefExpr()))
+ matches x(1, y, 42)
+with hasAnyArgument(...)
+ matching y
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+FIXME: Currently this will ignore parentheses and implicit casts on
+the argument before applying the inner matcher. We'll want to remove
+this to allow for greater control by the user once ignoreImplicit()
+has been implemented.
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasArgument1')"><a name="hasArgument1Anchor">hasArgument</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasArgument1"><pre>Matches the n'th argument of a call expression or a constructor
+call expression.
+
+Example matches y in x(y)
+ (matcher = callExpr(hasArgument(0, declRefExpr())))
+ void x(int) { int y; x(y); }
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasDeclaration12')"><a name="hasDeclaration12Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration12"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('forEachConstructorInitializer0')"><a name="forEachConstructorInitializer0Anchor">forEachConstructorInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forEachConstructorInitializer0"><pre>Matches each constructor initializer in a constructor definition.
+
+Given
+ class A { A() : i(42), j(42) {} int i; int j; };
+constructorDecl(forEachConstructorInitializer(forField(decl().bind("x"))))
+ will trigger two matches, binding for 'i' and 'j' respectively.
</pre></td></tr>
@@ -2375,7 +2393,7 @@
<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('thisPointerType1')"><a name="thisPointerType1Anchor">thisPointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('thisPointerType1')"><a name="thisPointerType1Anchor">thisPointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="thisPointerType1"><pre>Overloaded to match the type's declaration.
</pre></td></tr>
@@ -2438,7 +2456,7 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('callee1')"><a name="callee1Anchor">callee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('callee1')"><a name="callee1Anchor">callee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="callee1"><pre>Matches if the call expression's callee's declaration matches the
given matcher.
@@ -2458,6 +2476,11 @@
matches x(1, y, 42)
with hasAnyArgument(...)
matching y
+
+FIXME: Currently this will ignore parentheses and implicit casts on
+the argument before applying the inner matcher. We'll want to remove
+this to allow for greater control by the user once ignoreImplicit()
+has been implemented.
</pre></td></tr>
@@ -2471,17 +2494,38 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasDeclaration4')"><a name="hasDeclaration4Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration4"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasDeclaration13')"><a name="hasDeclaration13Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration13"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CaseStmt.html">CaseStmt</a>></td><td class="name" onclick="toggle('hasCaseConstant0')"><a name="hasCaseConstant0Anchor">hasCaseConstant</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCaseConstant0"><pre>If the given case statement does not use the GNU case range
+extension, matches the constant given in the statement.
+
+Given
+ switch (1) { case 1: case 1+1: case 3 ... 4: ; }
+caseStmt(hasCaseConstant(integerLiteral()))
+ matches "case 1:"
</pre></td></tr>
@@ -2523,8 +2567,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ComplexTypeLoc.html">ComplexTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc0')"><a name="hasElementTypeLoc0Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="hasElementTypeLoc0"><pre>Matches arrays and C99 complex types that have a specific element
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ComplexTypeLoc.html">ComplexTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc1')"><a name="hasElementTypeLoc1Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="hasElementTypeLoc1"><pre>Matches arrays and C99 complex types that have a specific element
type.
Given
@@ -2538,8 +2582,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>></td><td class="name" onclick="toggle('hasElementType0')"><a name="hasElementType0Anchor">hasElementType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="hasElementType0"><pre>Matches arrays and C99 complex types that have a specific element
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>></td><td class="name" onclick="toggle('hasElementType1')"><a name="hasElementType1Anchor">hasElementType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="hasElementType1"><pre>Matches arrays and C99 complex types that have a specific element
type.
Given
@@ -2591,6 +2635,30 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasDeclaration11')"><a name="hasDeclaration11Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration11"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('throughUsingDecl0')"><a name="throughUsingDecl0Anchor">throughUsingDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="throughUsingDecl0"><pre>Matches a DeclRefExpr that refers to a declaration through a
specific using shadow declaration.
@@ -2650,6 +2718,17 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc0')"><a name="hasTypeLoc0Anchor">hasTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
+<tr><td colspan="4" class="doc" id="hasTypeLoc0"><pre>Matches if the type location of the declarator decl's type matches
+the inner matcher.
+
+Given
+ int x;
+declaratorDecl(hasTypeLoc(loc(asString("int"))))
+ matches int x
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('hasDeclContext0')"><a name="hasDeclContext0Anchor">hasDeclContext</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasDeclContext0"><pre>Matches declarations whose declaration context, interpreted as a
Decl, matches InnerMatcher.
@@ -2722,6 +2801,30 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>></td><td class="name" onclick="toggle('hasDeclaration10')"><a name="hasDeclaration10Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration10"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>></td><td class="name" onclick="toggle('hasDestinationType0')"><a name="hasDestinationType0Anchor">hasDestinationType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasDestinationType0"><pre>Matches casts whose destination type matches a given matcher.
@@ -2730,8 +2833,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType2"><pre>Overloaded to match the declaration of the expression's or value
declaration's type.
In case of a value declaration (for example a variable declaration),
@@ -2906,7 +3009,7 @@
Given
if (A* a = GetAPointer()) {}
-hasConditionVariableStatment(...)
+hasConditionVariableStatement(...)
matches 'A* a = GetAPointer()'.
</pre></td></tr>
@@ -2919,17 +3022,75 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>></td><td class="name" onclick="toggle('hasDeclaration9')"><a name="hasDeclaration9Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration9"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>></td><td class="name" onclick="toggle('hasDeclaration8')"><a name="hasDeclaration8Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration8"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('hasDeclaration7')"><a name="hasDeclaration7Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration7"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
</pre></td></tr>
@@ -2961,8 +3122,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerTypeLoc.html">MemberPointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc2')"><a name="pointeeLoc2Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointeeLoc2"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerTypeLoc.html">MemberPointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc1')"><a name="pointeeLoc1Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointeeLoc1"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -2977,8 +3138,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerType.html">MemberPointerType</a>></td><td class="name" onclick="toggle('pointee2')"><a name="pointee2Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointee2"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerType.html">MemberPointerType</a>></td><td class="name" onclick="toggle('pointee1')"><a name="pointee1Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointee1"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -3072,8 +3233,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc1')"><a name="pointeeLoc1Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointeeLoc1"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc2')"><a name="pointeeLoc2Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointeeLoc2"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -3088,8 +3249,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerType.html">PointerType</a>></td><td class="name" onclick="toggle('pointee1')"><a name="pointee1Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointee1"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerType.html">PointerType</a>></td><td class="name" onclick="toggle('pointee2')"><a name="pointee2Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointee2"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -3117,32 +3278,66 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasDeclaration5')"><a name="hasDeclaration5Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration5"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasDeclaration6')"><a name="hasDeclaration6Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration6"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('pointsTo1')"><a name="pointsTo1Anchor">pointsTo</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('pointsTo1')"><a name="pointsTo1Anchor">pointsTo</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="pointsTo1"><pre>Overloaded to match the pointee type's declaration.
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('references1')"><a name="references1Anchor">references</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('references1')"><a name="references1Anchor">references</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="references1"><pre>Overloaded to match the referenced type's declaration.
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html">ReferenceTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc0')"><a name="pointeeLoc0Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointeeLoc0"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>></td><td class="name" onclick="toggle('hasDeclaration5')"><a name="hasDeclaration5Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration5"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html">ReferenceTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc3')"><a name="pointeeLoc3Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointeeLoc3"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -3157,8 +3352,8 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceType.html">ReferenceType</a>></td><td class="name" onclick="toggle('pointee0')"><a name="pointee0Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
-<tr><td colspan="4" class="doc" id="pointee0"><pre>Narrows PointerType (and similar) matchers to those where the
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceType.html">ReferenceType</a>></td><td class="name" onclick="toggle('pointee3')"><a name="pointee3Anchor">pointee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
+<tr><td colspan="4" class="doc" id="pointee3"><pre>Narrows PointerType (and similar) matchers to those where the
pointee matches a given matcher.
Given
@@ -3185,6 +3380,43 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>></td><td class="name" onclick="toggle('forEachSwitchCase0')"><a name="forEachSwitchCase0Anchor">forEachSwitchCase</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forEachSwitchCase0"><pre>Matches each case or default statement belonging to the given switch
+statement. This matcher may produce multiple matches.
+
+Given
+ switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } }
+switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
+ matches four times, with "c" binding each of "case 1:", "case 2:",
+"case 3:" and "case 4:", and "s" respectively binding "switch (1)",
+"switch (1)", "switch (2)" and "switch (2)".
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>></td><td class="name" onclick="toggle('hasDeclaration4')"><a name="hasDeclaration4Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration4"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>></td><td class="name" onclick="toggle('refersToDeclaration0')"><a name="refersToDeclaration0Anchor">refersToDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="refersToDeclaration0"><pre>Matches a TemplateArgument that refers to a certain declaration.
@@ -3212,17 +3444,66 @@
</pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasDeclaration3')"><a name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>></td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
+<tr><td>Matcher<T></td><td class="name" onclick="toggle('findAll0')"><a name="findAll0Anchor">findAll</a></td><td>Matcher<T> Matcher</td></tr>
+<tr><td colspan="4" class="doc" id="findAll0"><pre>Matches if the node or any descendant matches.
+
+Generates results for each match.
+
+For example, in:
+ class A { class B {}; class C {}; };
+The matcher:
+ recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m")))
+will generate results for A, B and C.
+
+Usable as: Any Matcher
</pre></td></tr>
@@ -3233,16 +3514,26 @@
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>></td><td class="name" onclick="toggle('hasDeclaration1')"><a name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a type if the declaration of the type matches the given
-matcher.
+<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
-In addition to being usable as Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, also usable as
-Matcher<T> for any T supporting the getDecl() member function. e.g. various
-subtypes of clang::Type.
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
-Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>,
- Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
</pre></td></tr>
@@ -3264,6 +3555,30 @@
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>></td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a node if the declaration associated with that node
+matches the given matcher.
+
+The associated declaration is:
+- for type nodes, the declaration of the underlying type
+- for CallExpr, the declaration of the callee
+- for MemberExpr, the declaration of the referenced member
+- for CXXConstructExpr, the declaration of the constructor
+
+Also usable as Matcher<T> for any T supporting the getDecl() member
+function. e.g. various subtypes of clang::Type and various expressions.
+FIXME: Add all node types for which this is matcher is usable due to
+getDecl().
+
+Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>,
+ Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>></td><td class="name" onclick="toggle('hasAnyUsingShadowDecl0')"><a name="hasAnyUsingShadowDecl0Anchor">hasAnyUsingShadowDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasAnyUsingShadowDecl0"><pre>Matches any using shadow declaration.
@@ -3286,8 +3601,8 @@
matches using X::b but not using X::a </pre></td></tr>
-<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasType2"><pre>Overloaded to match the declaration of the expression's or value
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value
declaration's type.
In case of a value declaration (for example a variable declaration),
diff --git a/docs/Makefile b/docs/Makefile
index 2608046..a76ce02 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -19,7 +19,12 @@
-e 's/@abs_srcdir@/./g' \
-e 's/@DOT@/dot/g' \
-e 's/@PACKAGE_VERSION@/mainline/' \
- -e 's/@abs_builddir@/./g' > $@
+ -e 's/@abs_builddir@/./g' \
+ -e 's/@enable_searchengine@/NO/g' \
+ -e 's/@searchengine_url@//g' \
+ -e 's/@enable_server_based_search@/NO/g' \
+ -e 's/@enable_external_search@/NO/g' \
+ -e 's/@extra_search_mappings@//g' > $@
endif
include $(CLANG_LEVEL)/Makefile
@@ -73,10 +78,10 @@
regendoc:
$(Echo) Building doxygen documentation
- $(Verb) if test -e $(PROJ_OBJ_DIR)/doxygen ; then \
- $(RM) -rf $(PROJ_OBJ_DIR)/doxygen ; \
- fi
+ $(Verb) $(RM) -rf $(PROJ_OBJ_DIR)/doxygen
$(Verb) $(DOXYGEN) $(PROJ_OBJ_DIR)/doxygen.cfg
+ $(Verb) sed -i "s/[$$]LatestRev[$$]/`svnversion $(PROJ_SRC_DIR)`/g" \
+ $(PROJ_OBJ_DIR)/doxygen/html/*.html
$(PROJ_OBJ_DIR)/doxygen.tar.gz: $(DOXYFILES) $(PROJ_OBJ_DIR)/doxygen.cfg
$(Echo) Packaging doxygen documentation
diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst
index 439acc4..5fc7e74 100644
--- a/docs/MemorySanitizer.rst
+++ b/docs/MemorySanitizer.rst
@@ -90,8 +90,16 @@
MemorySanitizer may still instrument such functions to avoid false positives.
This attribute may not be
supported by other compilers, so we suggest to use it together with
-``__has_feature(memory_sanitizer)``. Note: currently, this attribute will be
-lost if the function is inlined.
+``__has_feature(memory_sanitizer)``.
+
+Blacklist
+---------
+
+MemorySanitizer supports ``src`` and ``fun`` entity types in
+:doc:`SanitizerSpecialCaseList`, that can be used to relax MemorySanitizer
+checks for certain source files and functions. All "Use of uninitialized value"
+warnings will be suppressed and all values loaded from memory will be
+considered fully initialized.
Origin Tracking
===============
diff --git a/docs/Modules.rst b/docs/Modules.rst
index fdf597a..9fb4c77 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -2,13 +2,13 @@
Modules
=======
+.. warning::
+ The functionality described on this page is supported for C and
+ Objective-C. C++ support is experimental.
+
.. contents::
:local:
-.. warning::
- The functionality described on this page is still experimental! Please
- try it out and send us bug reports!
-
Introduction
============
Most software is built using a number of software libraries, including libraries supplied by the platform, internal libraries built as part of the software itself to provide structure, and third-party libraries. For each library, one needs to access both its interface (API) and its implementation. In the C family of languages, the interface to a library is accessed by including the appropriate header files(s):
@@ -106,24 +106,25 @@
=============
To enable modules, pass the command-line flag ``-fmodules`` [#]_. This will make any modules-enabled software libraries available as modules as well as introducing any modules-specific syntax. Additional `command-line parameters`_ are described in a separate section later.
-Import declaration
-------------------
-The most direct way to import a module is with an *import declaration*, which imports the named module:
+Objective-C Import declaration
+------------------------------
+Objective-C provides syntax for importing a module via an *@import declaration*, which imports the named module:
.. parsed-literal::
- import std;
+ @import std;
-The import declaration above imports the entire contents of the ``std`` module (which would contain, e.g., the entire C or C++ standard library) and make its API available within the current translation unit. To import only part of a module, one may use dot syntax to specific a particular submodule, e.g.,
+The @import declaration above imports the entire contents of the ``std`` module (which would contain, e.g., the entire C or C++ standard library) and make its API available within the current translation unit. To import only part of a module, one may use dot syntax to specific a particular submodule, e.g.,
.. parsed-literal::
- import std.io;
+ @import std.io;
Redundant import declarations are ignored, and one is free to import modules at any point within the translation unit, so long as the import declaration is at global scope.
-.. warning::
- The import declaration syntax described here does not actually exist. Rather, it is a straw man proposal that may very well change when modules are discussed in the C and C++ committees. See the section `Includes as imports`_ to see how modules get imported today.
+At present, there is no C or C++ syntax for import declarations. Clang
+will track the modules proposal in the C++ committee. See the section
+`Includes as imports`_ to see how modules get imported today.
Includes as imports
-------------------
@@ -148,6 +149,8 @@
.. note::
To actually see any benefits from modules, one first has to introduce module maps for the underlying C standard library and the libraries and headers on which it depends. The section `Modularizing a Platform`_ describes the steps one must take to write these module maps.
+
+One can use module maps without modules to check the integrity of the use of header files. To do this, use the ``-fmodule-maps`` option instead of the ``-fmodules`` option.
Compilation model
-----------------
@@ -165,6 +168,9 @@
``-fcxx-modules``
Enable the modules feature for C++ (EXPERIMENTAL and VERY BROKEN).
+``-fmodule-maps``
+ Enable interpretation of module maps (EXPERIMENTAL). This option is implied by ``-fmodules``.
+
``-fmodules-cache-path=<directory>``
Specify the path to the modules cache. If not provided, Clang will select a system-appropriate default.
@@ -183,6 +189,15 @@
``-module-file-info <module file name>``
Debugging aid that prints information about a given module file (with a ``.pcm`` extension), including the language and preprocessor options that particular module variant was built with.
+``-fmodules-decluse``
+ Enable checking of module ``use`` declarations.
+
+``-fmodule-name=module-id``
+ Consider a source file as a part of the given module.
+
+``-fmodule-map-file=<file>``
+ Load the given module map file if a header from its directory or one of its subdirectories is loaded.
+
Module Map Language
===================
@@ -231,8 +246,9 @@
``config_macros`` ``export`` ``module``
``conflict`` ``framework`` ``requires``
- ``exclude`` ``header`` ``umbrella``
- ``explicit`` ``link``
+ ``exclude`` ``header`` ``private``
+ ``explicit`` ``link`` ``umbrella``
+ ``extern`` ``use``
Module map file
---------------
@@ -258,6 +274,7 @@
*module-declaration*:
``explicit``:sub:`opt` ``framework``:sub:`opt` ``module`` *module-id* *attributes*:sub:`opt` '{' *module-member** '}'
+ ``extern`` ``module`` *module-id* *string-literal*
The *module-id* should consist of only a single *identifier*, which provides the name of the module being defined. Each module shall have a single definition.
@@ -286,10 +303,13 @@
*umbrella-dir-declaration*
*submodule-declaration*
*export-declaration*
+ *use-declaration*
*link-declaration*
*config-macros-declaration*
*conflict-declaration*
+An extern module references a module defined by the *module-id* in a file given by the *string-literal*. The file can be referenced either by an absolute path or by a path relative to the current map file.
+
Requires declaration
~~~~~~~~~~~~~~~~~~~~
A *requires-declaration* specifies the requirements that an importing translation unit must satisfy to use the module.
@@ -300,9 +320,12 @@
``requires`` *feature-list*
*feature-list*:
- *identifier* (',' *identifier*)*
+ *feature* (',' *feature*)*
-The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects or on certain platforms. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module.
+ *feature*:
+ ``!``:sub:`opt` *identifier*
+
+The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects or on certain platforms. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module. The optional ``!`` indicates that a feature is incompatible with the module.
The following features are defined:
@@ -360,6 +383,7 @@
*header-declaration*:
``umbrella``:sub:`opt` ``header`` *string-literal*
+ ``private`` ``header`` *string-literal*
``exclude`` ``header`` *string-literal*
A header declaration that does not contain ``exclude`` specifies a header that contributes to the enclosing module. Specifically, when the module is built, the named header will be parsed and its declarations will be (logically) placed into the enclosing submodule.
@@ -372,6 +396,8 @@
``-Wincomplete-umbrella`` warning option to ask Clang to complain
about headers not covered by the umbrella header or the module map.
+A header with the ``private`` specifier may not be included from outside the module itself.
+
A header with the ``exclude`` specifier is excluded from the module. It will not be included when the module is built, nor will it be considered to be part of the module.
**Example**: The C header ``assert.h`` is an excellent candidate for an excluded header, because it is meant to be included multiple times (possibly with different ``NDEBUG`` settings).
@@ -521,6 +547,36 @@
compatibility for programs that rely on transitive inclusion (i.e.,
all of them).
+Use declaration
+~~~~~~~~~~~~~~~
+A *use-declaration* specifies one of the other modules that the module is allowed to use. An import or include not matching one of these is rejected when the option *-fmodules-decluse*.
+
+.. parsed-literal::
+
+ *use-declaration*:
+ ``use`` *module-id*
+
+**Example**:: In the following example, use of A from C is not declared, so will trigger a warning.
+
+.. parsed-literal::
+
+ module A {
+ header "a.h"
+ }
+
+ module B {
+ header "b.h"
+ }
+
+ module C {
+ header "c.h"
+ use B
+ }
+
+When compiling a source file that implements a module, use the option ``-fmodule-name=``module-id to indicate that the source file is logically part of that module.
+
+The compiler at present only applies restrictions to the module directly being built.
+
Link declaration
~~~~~~~~~~~~~~~~
A *link-declaration* specifies a library or framework against which a program should be linked if the enclosing module is imported in any translation unit in that program.
diff --git a/docs/ObjectiveCLiterals.rst b/docs/ObjectiveCLiterals.rst
index 92e4fb6..8066d8f 100644
--- a/docs/ObjectiveCLiterals.rst
+++ b/docs/ObjectiveCLiterals.rst
@@ -218,12 +218,6 @@
raise an exception at runtime. When possible, the compiler will reject
``NULL`` character pointers used in boxed expressions.
-Availability
-------------
-
-Boxed expressions will be available in clang 3.2. It is not currently
-available in any Apple compiler.
-
Container Literals
==================
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index e764a09..597d481 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,6 +1,6 @@
-=======================
-Clang 3.3 Release Notes
-=======================
+=====================================
+Clang 3.4 (In-Progress) Release Notes
+=====================================
.. contents::
:local:
@@ -8,33 +8,57 @@
Written by the `LLVM Team <http://llvm.org/>`_
+.. warning::
+
+ These are in-progress notes for the upcoming Clang 3.4 release. You may
+ prefer the `Clang 3.3 Release Notes
+ <http://llvm.org/releases/3.3/tools/clang/docs/ReleaseNotes.html>`_.
+
Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 3.3. Here we
-describe the status of Clang in some detail, including major improvements from
-the previous release and new feature work. For the general LLVM release notes,
-see `the LLVM documentation <http://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
-releases may be downloaded from the `LLVM releases web site
-<http://llvm.org/releases/>`_.
+frontend, part of the LLVM Compiler Infrastructure, release 3.4. Here we
+describe the status of Clang in some detail, including major
+improvements from the previous release and new feature work. For the
+general LLVM release notes, see `the LLVM
+documentation <http://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
+releases may be downloaded from the `LLVM releases web
+site <http://llvm.org/releases/>`_.
-For more information about Clang or LLVM, including information about the latest
-release, please check out the main please see the `Clang Web Site
-<http://clang.llvm.org>`_ or the `LLVM Web Site <http://llvm.org>`_.
+For more information about Clang or LLVM, including information about
+the latest release, please check out the main please see the `Clang Web
+Site <http://clang.llvm.org>`_ or the `LLVM Web
+Site <http://llvm.org>`_.
-Note that if you are reading this file from a Subversion checkout or the main
-Clang web page, this document applies to the *next* release, not the current
-one. To see the release notes for a specific release, please see the `releases
-page <http://llvm.org/releases/>`_.
+Note that if you are reading this file from a Subversion checkout or the
+main Clang web page, this document applies to the *next* release, not
+the current one. To see the release notes for a specific release, please
+see the `releases page <http://llvm.org/releases/>`_.
-What's New in Clang 3.3?
+What's New in Clang 3.4?
========================
Some of the major new features and improvements to Clang are listed
here. Generic improvements to Clang as a whole or to its underlying
-infrastructure are described first, followed by language-specific sections with
-improvements to Clang's support for those languages.
+infrastructure are described first, followed by language-specific
+sections with improvements to Clang's support for those languages.
+
+Last release which will build as C++98
+--------------------------------------
+
+This is expected to be the last release of Clang which compiles using a C++98
+toolchain. We expect to start using some C++11 features in Clang starting after
+this release. That said, we are committed to supporting a reasonable set of
+modern C++ toolchains as the host compiler on all of the platforms. This will
+at least include Visual Studio 2012 on Windows, and Clang 3.1 or GCC 4.7.x on
+Mac and Linux. The final set of compilers (and the C++11 features they support)
+is not set in stone, but we wanted users of Clang to have a heads up that the
+next release will involve a substantial change in the host toolchain
+requirements.
+
+Note that this change is part of a change for the entire LLVM project, not just
+Clang.
Major New Features
------------------
@@ -44,67 +68,80 @@
Clang's diagnostics are constantly being improved to catch more issues,
explain them more clearly, and provide more accurate source information
-about them. The improvements since the 3.2 release include:
+about them. The improvements since the 3.3 release include:
-Extended Identifiers: Unicode Support and Universal Character Names
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- ...
-Clang 3.3 includes support for *extended identifiers* in C99 and C++.
-This feature allows identifiers to contain certain Unicode characters, as
-specified by the active language standard; these characters can be written
-directly in the source file using the UTF-8 encoding, or referred to using
-*universal character names* (``\u00E0``, ``\U000000E0``).
+New Compiler Flags
+------------------
+
+- Clang no longer special cases -O4 to enable lto. Explicitly pass -flto to
+ enable it.
+- Clang no longer fails on >= -O5. Uses -O3 instead.
+- Command line "clang -O3 -flto a.c -c" and "clang -emit-llvm a.c -c"
+ are no longer equivalent.
+- Clang now errors on unknown -m flags (``-munknown-to-clang``),
+ unknown -f flags (``-funknown-to-clang``) and unknown
+ options (``-what-is-this``).
C Language Changes in Clang
---------------------------
+- Added new checked arithmetic builtins for security critical applications.
+
+C11 Feature Support
+^^^^^^^^^^^^^^^^^^^
+
+...
+
C++ Language Changes in Clang
-----------------------------
-- Clang now correctly implements language linkage for functions and variables.
- This means that, for example, it is now possible to overload static functions
- declared in an ``extern "C"`` context. For backwards compatibility, an alias
- with the unmangled name is still emitted if it is the only one and has the
- ``used`` attribute.
+- Fixed an ABI regression, introduced in Clang 3.2, which affected
+ member offsets for classes inheriting from certain classes with tail padding.
+ See PR16537.
+
+- ...
+
+C++11 Feature Support
+^^^^^^^^^^^^^^^^^^^^^
+
+...
+
+Objective-C Language Changes in Clang
+-------------------------------------
+
+...
+
+OpenCL C Language Changes in Clang
+----------------------------------
+
+- OpenCL C "long" now always has a size of 64 bit, and all OpenCL C
+ types are aligned as specified in the OpenCL C standard. Also,
+ "char" is now always signed.
Internal API Changes
--------------------
-These are major API changes that have happened since the 3.2 release of
+These are major API changes that have happened since the 3.3 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
-Value Casting
-^^^^^^^^^^^^^
+Wide Character Types
+^^^^^^^^^^^^^^^^^^^^
-Certain type hierarchies (TypeLoc, CFGElement, ProgramPoint, and SVal) were
-misusing the llvm::cast machinery to perform undefined operations. Their APIs
-have been changed to use two member function templates that return values
-instead of pointers or references - "T castAs" and "Optional<T> getAs" (in the
-case of the TypeLoc hierarchy the latter is "T getAs" and you can use the
-boolean testability of a TypeLoc (or its 'validity') to verify that the cast
-succeeded). Essentially all previous 'cast' usage should be replaced with
-'castAs' and 'dyn_cast' should be replaced with 'getAs'. See r175462 for the
-first example of such a change along with many examples of how code was
-migrated to the new API.
+The ASTContext class now keeps track of two different types for wide character
+types: WCharTy and WideCharTy. WCharTy represents the built-in wchar_t type
+available in C++. WideCharTy is the type used for wide character literals; in
+C++ it is the same as WCharTy, but in C99, where wchar_t is a typedef, it is an
+integer type.
-Storage Class
-^^^^^^^^^^^^^
-
-For each variable and function Clang used to keep the storage class as written
-in the source, the linkage and a semantic storage class. This was a bit
-redundant and the semantic storage class has been removed. The method
-getStorageClass now returns what is written in the source code for that decl.
+...
libclang
--------
-The clang_CXCursorSet_contains() function previously incorrectly returned 0
-if it contained a CXCursor, contrary to what the documentation stated. This
-has been fixed so that the function returns a non-zero value if the set
-contains a cursor. This is API breaking change, but matches the intended
-original behavior. Moreover, this also fixes the issue of an invalid CXCursorSet
-appearing to contain any CXCursor.
+...
Static Analyzer
---------------
@@ -116,18 +153,19 @@
Core Analysis Improvements
==========================
-- Support for interprocedural reasoning about constructors and destructors.
-- New false positive suppression mechanisms that reduced the number of false
- null pointer dereference warnings due to interprocedural analysis.
-- Major performance enhancements to speed up interprocedural analysis
+- ...
New Issues Found
================
-- New memory error checks such as use-after-free with C++ 'delete'.
-- Detection of mismatched allocators and deallocators (e.g., using 'new' with
- 'free()', 'malloc()' with 'delete').
-- Additional checks for misuses of Apple Foundation framework collection APIs.
+- ...
+
+Python Binding Changes
+----------------------
+
+The following methods have been added:
+
+- ...
Significant Known Problems
==========================
@@ -135,11 +173,13 @@
Additional Information
======================
-A wide variety of additional information is available on the `Clang web page
-<http://clang.llvm.org/>`_. The web page contains versions of the API
-documentation which are up-to-date with the Subversion version of the source
-code. You can access versions of these documents specific to this release by
-going into the "``clang/docs/``" directory in the Clang tree.
+A wide variety of additional information is available on the `Clang web
+page <http://clang.llvm.org/>`_. The web page contains versions of the
+API documentation which are up-to-date with the Subversion version of
+the source code. You can access versions of these documents specific to
+this release by going into the "``clang/docs/``" directory in the Clang
+tree.
-If you have any questions or comments about Clang, please feel free to contact
-us via the `mailing list <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>`_.
+If you have any questions or comments about Clang, please feel free to
+contact us via the `mailing
+list <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>`_.
diff --git a/docs/SanitizerSpecialCaseList.rst b/docs/SanitizerSpecialCaseList.rst
new file mode 100644
index 0000000..8f4727c
--- /dev/null
+++ b/docs/SanitizerSpecialCaseList.rst
@@ -0,0 +1,79 @@
+===========================
+Sanitizer special case list
+===========================
+
+.. contents::
+ :local:
+
+Introduction
+============
+
+This document describes the way to disable or alter the behavior of
+sanitizer tools for certain source-level entities by providing a special
+file at compile-time.
+
+Goal and usage
+==============
+
+User of sanitizer tools, such as :doc:`AddressSanitizer`, :doc:`ThreadSanitizer`
+or :doc:`MemorySanitizer` may want to disable or alter some checks for
+certain source-level entities to:
+
+* speedup hot function, which is known to be correct;
+* ignore a function that does some low-level magic (e.g. walks through the
+ thread stack, bypassing the frame boundaries);
+* ignore a known problem.
+
+To achieve this, user may create a file listing the entities he wants to
+ignore, and pass it to clang at compile-time using
+``-fsanitize-blacklist`` flag. See :doc:`UsersManual` for details.
+
+Example
+=======
+
+.. code-block:: bash
+
+ $ cat foo.c
+ #include <stdlib.h>
+ void bad_foo() {
+ int *a = (int*)malloc(40);
+ a[10] = 1;
+ }
+ int main() { bad_foo(); }
+ $ cat blacklist.txt
+ # Ignore reports from bad_foo function.
+ fun:bad_foo
+ $ clang -fsanitize=address foo.c ; ./a.out
+ # AddressSanitizer prints an error report.
+ $ clang -fsanitize=address -fsanitize-blacklist=blacklist.txt foo.c ; ./a.out
+ # No error report here.
+
+Format
+======
+
+Each line contains an entity type, followed by a colon and a regular
+expression, specifying the names of the entities, optionally followed by
+an equals sign and a tool-specific category. Empty lines and lines starting
+with "#" are ignored. The meanining of ``*`` in regular expression for entity
+names is different - it is treated as in shell wildcarding. Two generic
+entity types are ``src`` and ``fun``, which allow user to add, respectively,
+source files and functions to special case list. Some sanitizer tools may
+introduce custom entity types - refer to tool-specific docs.
+
+.. code-block:: bash
+
+ # Lines starting with # are ignored.
+ # Turn off checks for the source file (use absolute path or path relative
+ # to the current working directory):
+ src:/path/to/source/file.c
+ # Turn off checks for a particular functions (use mangled names):
+ fun:MyFooBar
+ fun:_Z8MyFooBarv
+ # Extended regular expressions are supported:
+ fun:bad_(foo|bar)
+ src:bad_source[1-9].c
+ # Shell like usage of * is supported (* is treated as .*):
+ src:bad/sources/*
+ fun:*BadFunction*
+ # Specific sanitizer tools may introduce categories.
+ src:/special/path/*=special_sources
diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst
index 5e5ee48..194ad4a 100644
--- a/docs/ThreadSanitizer.rst
+++ b/docs/ThreadSanitizer.rst
@@ -91,11 +91,21 @@
One may use the function attribute
:ref:`no_sanitize_thread <langext-thread_sanitizer>`
to disable instrumentation of plain (non-atomic) loads/stores in a particular function.
-ThreadSanitizer may still instrument such functions to avoid false positives.
+ThreadSanitizer still instruments such functions to avoid false positives and
+provide meaningful stack traces.
This attribute may not be
supported by other compilers, so we suggest to use it together with
-``__has_feature(thread_sanitizer)``. Note: currently, this attribute will be
-lost if the function is inlined.
+``__has_feature(thread_sanitizer)``.
+
+Blacklist
+---------
+
+ThreadSanitizer supports ``src`` and ``fun`` entity types in
+:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports in
+the specified source files or functions. Unlike functions marked with
+:ref:`no_sanitize_thread <langext-thread_sanitizer>` attribute,
+blacklisted functions are not instrumented at all. This can lead to false positives
+due to missed synchronization via atomic operations and missed stack frames in reports.
Limitations
-----------
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 3dc07ab..e0a6838 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -44,6 +44,8 @@
driver and language features are intentionally designed to be as
compatible with the GNU GCC compiler as reasonably possible, easing
migration from GCC to Clang. In most cases, code "just works".
+Clang also provides an alternative driver, :ref:`clang-cl`, that is designed
+to be compatible with the Visual C++ compiler, cl.exe.
In addition to language specific features, Clang has a variety of
features that depend on what CPU architecture or operating system is
@@ -235,6 +237,11 @@
^
//
+**-fansi-escape-codes**
+ Controls whether ANSI escape codes are used instead of the Windows Console
+ API to output colored diagnostics. This option is only used on Windows and
+ defaults to off.
+
.. option:: -fdiagnostics-format=clang/msvc/vi
Changes diagnostic output format to better match IDEs and command line tools.
@@ -422,7 +429,7 @@
map<
[...],
map<
- [float != float],
+ [float != double],
[...]>>>
.. _cl_diag_warning_groups:
@@ -853,7 +860,7 @@
Clang provides a number of ways to control code generation. The options
are listed below.
-**-fsanitize=check1,check2,...**
+**-f[no-]sanitize=check1,check2,...**
Turn on runtime checks for various forms of undefined or suspicious
behavior.
@@ -889,13 +896,14 @@
includes all of the checks listed below other than
``unsigned-integer-overflow``.
- ``-fsanitize=undefined-trap``: This includes all sanitizers
+ - ``-fsanitize=undefined-trap``: This includes all sanitizers
included by ``-fsanitize=undefined``, except those that require
- runtime support. This group of sanitizers are generally used
- in conjunction with the ``-fsanitize-undefined-trap-on-error``
- flag, which causes traps to be emitted, rather than calls to
- runtime libraries. This includes all of the checks listed below
- other than ``unsigned-integer-overflow`` and ``vptr``.
+ runtime support. This group of sanitizers is intended to be
+ used in conjunction with the ``-fsanitize-undefined-trap-on-error``
+ flag. This includes all of the checks listed below other than
+ ``unsigned-integer-overflow`` and ``vptr``.
+ - ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data
+ flow analysis.
The following more fine-grained checks are also available:
@@ -913,6 +921,8 @@
destination.
- ``-fsanitize=float-divide-by-zero``: Floating point division by
zero.
+ - ``-fsanitize=function``: Indirect call of a function through a
+ function pointer of the wrong type (Linux, C++ and x86/x86_64 only).
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
- ``-fsanitize=null``: Use of a null pointer or creation of a null
reference.
@@ -941,6 +951,15 @@
it is of the wrong dynamic type, or that its lifetime has not
begun or has ended. Incompatible with ``-fno-rtti``.
+ You can turn off or modify checks for certain source files, functions
+ or even variables by providing a special file:
+
+ - ``-fsanitize-blacklist=/path/to/blacklist/file``: disable or modify
+ sanitizer checks for objects listed in the file. See
+ :doc:`SanitizerSpecialCaseList` for file format description.
+ - ``-fno-sanitize-blacklist``: don't use blacklist file, if it was
+ specified earlier in the command line.
+
Experimental features of AddressSanitizer (not ready for widespread
use, require explicit ``-fsanitize=address``):
@@ -958,10 +977,31 @@
uninitialized bits came from. Slows down execution by additional
1.5x-2x.
+ Extra features of UndefinedBehaviorSanitizer:
+
+ - ``-fno-sanitize-recover``: By default, after a sanitizer diagnoses
+ an issue, it will attempt to continue executing the program if there
+ is a reasonable behavior it can give to the faulting operation. This
+ option causes the program to abort instead.
+ - ``-fsanitize-undefined-trap-on-error``: Causes traps to be emitted
+ rather than calls to runtime libraries when a problem is detected.
+ This option is intended for use in cases where the sanitizer runtime
+ cannot be used (for instance, when building libc or a kernel module).
+ This is only compatible with the sanitizers in the ``undefined-trap``
+ group.
+
The ``-fsanitize=`` argument must also be provided when linking, in
- order to link to the appropriate runtime library. It is not possible
- to combine the ``-fsanitize=address`` and ``-fsanitize=thread``
- checkers in the same program.
+ order to link to the appropriate runtime library. When using
+ ``-fsanitize=vptr`` (or a group that includes it, such as
+ ``-fsanitize=undefined``) with a C++ program, the link must be
+ performed by ``clang++``, not ``clang``, in order to link against the
+ C++-specific parts of the runtime library.
+
+ It is not possible to combine more than one of the ``-fsanitize=address``,
+ ``-fsanitize=thread``, and ``-fsanitize=memory`` checkers in the same
+ program. The ``-fsanitize=undefined`` checks can be combined with other
+ sanitizers.
+
**-f[no-]address-sanitizer**
Deprecated synonym for :ref:`-f[no-]sanitize=address
<opt_fsanitize_address>`.
@@ -1007,6 +1047,26 @@
efficient model can be used. The TLS model can be overridden per
variable using the ``tls_model`` attribute.
+.. option:: -mhwdiv=[values]
+
+ Select the ARM modes (arm or thumb) that support hardware division
+ instructions.
+
+ Valid values are: ``arm``, ``thumb`` and ``arm,thumb``.
+ This option is used to indicate which mode (arm or thumb) supports
+ hardware division instructions. This only applies to the ARM
+ architecture.
+
+.. option:: -m[no-]crc
+
+ Enable or disable CRC instructions.
+
+ This option is used to indicate whether CRC instructions are to
+ be generated. This only applies to the ARM architecture.
+
+ CRC instructions are enabled by default on ARMv8.
+
+
Controlling Size of Debug Information
-------------------------------------
@@ -1179,29 +1239,39 @@
clang has some experimental support for extensions from Microsoft Visual
C++; to enable it, use the -fms-extensions command-line option. This is
-the default for Windows targets. Note that the support is incomplete;
-enabling Microsoft extensions will silently drop certain constructs
-(including ``__declspec`` and Microsoft-style asm statements).
+the default for Windows targets. Note that the support is incomplete.
+Some constructs such as dllexport on classes are ignored with a warning,
+and others such as `Microsoft IDL annotations
+<http://msdn.microsoft.com/en-us/library/8tesw2eh.aspx>`_ are silently
+ignored.
clang has a -fms-compatibility flag that makes clang accept enough
-invalid C++ to be able to parse most Microsoft headers. This flag is
-enabled by default for Windows targets.
+invalid C++ to be able to parse most Microsoft headers. For example, it
+allows `unqualified lookup of dependent base class members
+<http://clang.llvm.org/compatibility.html#dep_lookup_bases>`_, which is
+a common compatibility issue with clang. This flag is enabled by default
+for Windows targets.
-fdelayed-template-parsing lets clang delay all template instantiation
until the end of a translation unit. This flag is enabled by default for
Windows targets.
- clang allows setting ``_MSC_VER`` with ``-fmsc-version=``. It defaults to
- 1300 which is the same as Visual C/C++ 2003. Any number is supported
+ 1700 which is the same as Visual C/C++ 2012. Any number is supported
and can greatly affect what Windows SDK and c++stdlib headers clang
- can compile. This option will be removed when clang supports the full
- set of MS extensions required for these headers.
+ can compile.
- clang does not support the Microsoft extension where anonymous record
members can be declared using user defined typedefs.
-- clang supports the Microsoft "#pragma pack" feature for controlling
+- clang supports the Microsoft ``#pragma pack`` feature for controlling
record layout. GCC also contains support for this feature, however
where MSVC and GCC are incompatible clang follows the MSVC
definition.
+- clang supports the Microsoft ``#pragma comment(lib, "foo.lib")`` feature for
+ automatically linking against the specified library. Currently this feature
+ only works with the Visual C++ linker.
+- clang supports the Microsoft ``#pragma comment(linker, "/flag:foo")`` feature
+ for adding linker flags to COFF object files. The user is responsible for
+ ensuring that the linker understands the flags.
- clang defaults to C++11 for Windows targets.
.. _cxx:
@@ -1229,7 +1299,12 @@
.. option:: -ftemplate-depth=N
Sets the limit for recursively nested template instantiations to N. The
- default is 1024.
+ default is 256.
+
+.. option:: -foperator-arrow-depth=N
+
+ Sets the limit for iterative calls to 'operator->' functions to N. The
+ default is 256.
.. _objc:
@@ -1271,11 +1346,19 @@
limited number of ARM architectures. It does not yet fully support
ARMv5, for example.
+PowerPC
+^^^^^^^
+
+The support for PowerPC (especially PowerPC64) is considered stable
+on Linux and FreeBSD: it has been tested to correctly compile many
+large C and C++ codebases. PowerPC (32bit) is still missing certain
+features (e.g. PIC code on ELF platforms).
+
Other platforms
^^^^^^^^^^^^^^^
-clang currently contains some support for PPC and Sparc; however,
-significant pieces of code generation are still missing, and they
+clang currently contains some support for other architectures (e.g. Sparc);
+however, significant pieces of code generation are still missing, and they
haven't undergone significant testing.
clang contains limited support for the MSP430 embedded processor, but
@@ -1304,7 +1387,7 @@
Experimental supports are on Cygming.
-See also `Microsoft Extensions <c_ms>`.
+See also :ref:`Microsoft Extensions <c_ms>`.
Cygwin
""""""
@@ -1349,3 +1432,111 @@
`Some tests might fail <http://llvm.org/bugs/show_bug.cgi?id=9072>`_ on
``x86_64-w64-mingw32``.
+
+.. _clang-cl:
+
+clang-cl
+========
+
+clang-cl is an alternative command-line interface to Clang driver, designed for
+compatibility with the Visual C++ compiler, cl.exe.
+
+To enable clang-cl to find system headers, libraries, and the linker when run
+from the command-line, it should be executed inside a Visual Studio Native Tools
+Command Prompt or a regular Command Prompt where the environment has been set
+up using e.g. `vcvars32.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
+
+clang-cl can also be used from inside Visual Studio by using an LLVM Platform
+Toolset.
+
+Command-Line Options
+--------------------
+
+To be compatible with cl.exe, clang-cl supports most of the same command-line
+options. Those options can start with either ``/`` or ``-``. It also supports
+some of Clang's core options, such as the ``-W`` options.
+
+Options that are known to clang-cl, but not currently supported, are ignored
+with a warning. For example:
+
+ ::
+
+ clang-cl.exe: warning: argument unused during compilation: '/Zi'
+
+To suppress warnings about unused arguments, use the ``-Qunused-arguments`` option.
+
+Options that are not known to clang-cl will cause errors. If they are spelled with a
+leading ``/``, they will be mistaken for a filename:
+
+ ::
+
+ clang-cl.exe: error: no such file or directory: '/foobar'
+
+Please `file a bug <http://llvm.org/bugs/enter_bug.cgi?product=clang&component=Driver>`_
+for any valid cl.exe flags that clang-cl does not understand.
+
+Execute ``clang-cl /?`` to see a list of supported options:
+
+ ::
+
+ /? Display available options
+ /c Compile only
+ /D <macro[=value]> Define macro
+ /fallback Fall back to cl.exe if clang-cl fails to compile
+ /FA Output assembly code file during compilation
+ /Fa<file or directory> Output assembly code to this file during compilation
+ /Fe<file or directory> Set output executable file or directory (ends in / or \)
+ /FI<value> Include file before parsing
+ /Fo<file or directory> Set output object file, or directory (ends in / or \)
+ /GF- Disable string pooling
+ /GR- Disable RTTI
+ /GR Enable RTTI
+ /help Display available options
+ /I <dir> Add directory to include search path
+ /J Make char type unsigned
+ /LDd Create debug DLL
+ /LD Create DLL
+ /link <options> Forward options to the linker
+ /MDd Use DLL debug run-time
+ /MD Use DLL run-time
+ /MTd Use static debug run-time
+ /MT Use static run-time
+ /Ob0 Disable inlining
+ /Od Disable optimization
+ /Oi- Disable use of builtin functions
+ /Oi Enable use of builtin functions
+ /Os Optimize for size
+ /Ot Optimize for speed
+ /Ox Maximum optimization
+ /Oy- Disable frame pointer omission
+ /Oy Enable frame pointer omission
+ /O<n> Optimization level
+ /P Only run the preprocessor
+ /showIncludes Print info about included files to stderr
+ /TC Treat all source files as C
+ /Tc <filename> Specify a C source file
+ /TP Treat all source files as C++
+ /Tp <filename> Specify a C++ source file
+ /U <macro> Undefine macro
+ /W0 Disable all warnings
+ /W1 Enable -Wall
+ /W2 Enable -Wall
+ /W3 Enable -Wall
+ /W4 Enable -Wall
+ /Wall Enable -Wall
+ /WX- Do not treat warnings as errors
+ /WX Treat warnings as errors
+ /w Disable all warnings
+ /Zs Syntax-check only
+
+The /fallback Option
+^^^^^^^^^^^^^^^^^^^^
+
+When clang-cl is run with the ``/fallback`` option, it will first try to
+compile files itself. For any file that it fails to compile, it will fall back
+and try to compile the file by invoking cl.exe.
+
+This option is intended to be used as a temporary means to build projects where
+clang-cl cannot successfully compile all the files. clang-cl may fail to compile
+a file either because it cannot generate code for some C++ feature, or because
+it cannot parse some Microsoft language extension.
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst
index f8e6f82..14d6ae4 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/DebugChecks.rst
@@ -30,6 +30,10 @@
- debug.DumpLiveVars: Show the results of live variable analysis for each
top-level function being analyzed.
+- debug.ViewExplodedGraph: Show the Exploded Graphs generated for the
+ analysis of different functions in the input translation unit. When there
+ are several functions analyzed, display one graph per function. Beware
+ that these graphs may grow very large, even for small functions.
Path Tracking
=============
@@ -121,6 +125,19 @@
clang_analyzer_eval(value == 42); // expected-warning{{TRUE}}
}
+- void clang_analyzer_warnIfReached();
+
+ Generate a warning if this line of code gets reached by the analyzer.
+
+ Example usage::
+
+ if (true) {
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ }
+ else {
+ clang_analyzer_warnIfReached(); // no-warning
+ }
+
Statistics
==========
diff --git a/docs/analyzer/IPA.txt b/docs/analyzer/IPA.txt
index 01e73ce..14da71e 100644
--- a/docs/analyzer/IPA.txt
+++ b/docs/analyzer/IPA.txt
@@ -74,7 +74,7 @@
methods of the container classes in the Standard Template Library, should be
considered for inlining.
- -analyzer-config c++-template-inlining=[true | false]
+ -analyzer-config c++-stdlib-inlining=[true | false]
Currently, C++ standard library functions are considered for inlining by
default.
diff --git a/docs/analyzer/conf.py b/docs/analyzer/conf.py
index dff9610..3690f93 100644
--- a/docs/analyzer/conf.py
+++ b/docs/analyzer/conf.py
@@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
-version = '3.3'
+version = '3.4'
# The full version, including alpha/beta/rc tags.
-release = '3.3'
+release = '3.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/conf.py b/docs/conf.py
index 92741d2..183a285 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
-version = '3.3'
+version = '3.4'
# The full version, including alpha/beta/rc tags.
-release = '3.3'
+release = '3.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in
index ed9ffcb..61c0bd8 100644
--- a/docs/doxygen.cfg.in
+++ b/docs/doxygen.cfg.in
@@ -1224,7 +1224,30 @@
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-SEARCHENGINE = NO
+SEARCHENGINE = @enable_searchengine@
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = @enable_server_based_search@
+
+SEARCHENGINE_URL = @searchengine_url@
+
+EXTERNAL_SEARCH = @enable_external_search@
+
+EXTERNAL_SEARCH_ID = clang
+
+EXTRA_SEARCH_MAPPINGS = @extra_search_mappings@
diff --git a/docs/doxygen.footer b/docs/doxygen.footer
index 524e9a2..02db39f 100644
--- a/docs/doxygen.footer
+++ b/docs/doxygen.footer
@@ -1,6 +1,6 @@
<hr>
<p class="footer">
-Generated on $datetime by <a href="http://www.doxygen.org">Doxygen
+Generated on $datetime for r$LatestRev$ by <a href="http://www.doxygen.org">Doxygen
$doxygenversion</a>.</p>
<p class="footer">
diff --git a/docs/index.rst b/docs/index.rst
index 5cdfb6b..d026864 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -18,12 +18,20 @@
UsersManual
LanguageExtensions
+ CrossCompilation
AddressSanitizer
ThreadSanitizer
MemorySanitizer
+ DataFlowSanitizer
+ SanitizerSpecialCaseList
Modules
FAQ
+.. toctree::
+ :hidden:
+
+ LeakSanitizer
+
Using Clang as a Library
========================
@@ -51,6 +59,7 @@
ClangTools
ClangCheck
ClangFormat
+ ClangFormatStyleOptions
Design Documents
================
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
index d2394a8..a58986c 100644
--- a/docs/tools/clang.pod
+++ b/docs/tools/clang.pod
@@ -7,7 +7,7 @@
=head1 SYNOPSIS
B<clang> [B<-c>|B<-S>|B<-E>] B<-std=>I<standard> B<-g>
- [B<-O0>|B<-O1>|B<-O2>|B<-Os>|B<-Oz>|B<-O3>|B<-Ofast>|B<-O4>]
+ [B<-O0>|B<-O1>|B<-O2>|B<-O3>|B<-Ofast>|B<-Os>|B<-Oz>|B<-O>|B<-O4>]
B<-W>I<warnings...> B<-pedantic>
B<-I>I<dir...> B<-L>I<dir...>
B<-D>I<macro[=defn]>
@@ -81,7 +81,8 @@
The Clang Static Analyzer is a tool that scans source code to try to find bugs
through code analysis. This tool uses many parts of Clang and is built into the
-same driver.
+same driver. Please see L<http://clang-analyzer.llvm.org> for more details
+on how to use the static analyzer.
=head1 OPTIONS
@@ -112,10 +113,6 @@
If no stage selection option is specified, all stages above are run, and the
linker is run to combine the results into an executable or shared library.
-=item B<--analyze>
-
-Run the Clang Static Analyzer.
-
=back
@@ -263,20 +260,52 @@
=over
-=item B<-O0> B<-O1> B<-O2> B<-Os> B<-Oz> B<-O3> B<-Ofast> B<-O4>
+=item B<-O0> B<-O1> B<-O2> B<-O3> B<-Ofast> B<-Os> B<-Oz> B<-O> B<-O4>
-Specify which optimization level to use. B<-O0> means "no optimization": this
-level compiles the fastest and generates the most debuggable code. B<-O2> is a
-moderate level of optimization which enables most optimizations. B<-Os> is like
-B<-O2> with extra optimizations to reduce code size. B<-Oz> is like B<-Os>
-(and thus B<-O2>), but reduces code size further. B<-O3> is like B<-O2>,
-except that it enables optimizations that take longer to perform or that may
-generate larger code (in an attempt to make the program run faster).
-B<-Ofast> enables all the optimizations from B<-O3> along with other aggressive
-optimizations that may violate strict compliance with language standards. On
-supported platforms, B<-O4> enables link-time optimization; object files are
-stored in the LLVM bitcode file format and whole program optimization is done at
-link time. B<-O1> is somewhere between B<-O0> and B<-O2>.
+Specify which optimization level to use:
+
+=over
+
+=item B<-O0>
+
+Means "no optimization": this level compiles the fastest and
+generates the most debuggable code.
+
+=item B<-O1>
+
+Somewhere between B<-O0> and B<-O2>.
+
+=item B<-O2>
+
+Moderate level of optimization which enables most optimizations.
+
+=item B<-O3>
+
+Like B<-O2>, except that it enables optimizations that take longer to perform
+or that may generate larger code (in an attempt to make the program run faster).
+
+=item B<-Ofast>
+
+Enables all the optimizations from B<-O3> along with other aggressive
+optimizations that may violate strict compliance with language standards.
+
+=item B<-Os>
+
+Like B<-O2> with extra optimizations to reduce code size.
+
+=item B<-Oz>
+
+Like B<-Os> (and thus B<-O2>), but reduces code size further.
+
+=item B<-O>
+
+Equivalent to B<-O2>.
+
+=item B<-O4> and higher
+
+Currently equivalent to B<-O3>
+
+=back
=item B<-g>
diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py
index 4ed6822..564dc38 100644
--- a/docs/tools/dump_ast_matchers.py
+++ b/docs/tools/dump_ast_matchers.py
@@ -154,20 +154,25 @@
inner, name = m.groups()
add_matcher('Type', name, 'Matcher<%s>...' % inner,
comment, is_dyncast=True)
- add_matcher('TypeLoc', '%sLoc' % name, 'Matcher<%sLoc>...' % inner,
- comment, is_dyncast=True)
+ # FIXME: re-enable once we have implemented casting on the TypeLoc
+ # hierarchy.
+ # add_matcher('TypeLoc', '%sLoc' % name, 'Matcher<%sLoc>...' % inner,
+ # comment, is_dyncast=True)
return
m = re.match(""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER\(
\s*([^\s,]+\s*),
- \s*(?:[^\s,]+\s*)
+ \s*(?:[^\s,]+\s*),
+ \s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
\)\s*;\s*$""", declaration, flags=re.X)
if m:
- loc = m.group(1)
- name = m.group(2)
- result_types = extract_result_types(comment)
- if not result_types:
- raise Exception('Did not find allowed result types for: %s' % name)
+ loc, name, n_results, results = m.groups()[0:4]
+ result_types = [r.strip() for r in results.split(',')]
+
+ comment_result_types = extract_result_types(comment)
+ if (comment_result_types and
+ sorted(result_types) != sorted(comment_result_types)):
+ raise Exception('Inconsistent documentation for: %s' % name)
for result_type in result_types:
add_matcher(result_type, name, 'Matcher<Type>', comment)
if loc:
@@ -175,7 +180,31 @@
comment)
return
- m = re.match(r"""^\s*AST_(POLYMORPHIC_)?MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
+ m = re.match(r"""^\s*AST_POLYMORPHIC_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
+ \s*([^\s,]+)\s*,
+ \s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
+ (?:,\s*([^\s,]+)\s*
+ ,\s*([^\s,]+)\s*)?
+ (?:,\s*([^\s,]+)\s*
+ ,\s*([^\s,]+)\s*)?
+ (?:,\s*\d+\s*)?
+ \)\s*{\s*$""", declaration, flags=re.X)
+
+ if m:
+ p, n, name, n_results, results = m.groups()[0:5]
+ args = m.groups()[5:]
+ result_types = [r.strip() for r in results.split(',')]
+ if allowed_types and allowed_types != result_types:
+ raise Exception('Inconsistent documentation for: %s' % name)
+ if n not in ['', '2']:
+ raise Exception('Cannot parse "%s"' % declaration)
+ args = ', '.join('%s %s' % (args[i], args[i+1])
+ for i in range(0, len(args), 2) if args[i])
+ for result_type in result_types:
+ add_matcher(result_type, name, args, comment)
+ return
+
+ m = re.match(r"""^\s*AST_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
(?:\s*([^\s,]+)\s*,)?
\s*([^\s,]+)\s*
(?:,\s*([^\s,]+)\s*
@@ -185,8 +214,8 @@
(?:,\s*\d+\s*)?
\)\s*{\s*$""", declaration, flags=re.X)
if m:
- p, n, result, name = m.groups()[1:5]
- args = m.groups()[5:]
+ p, n, result, name = m.groups()[0:4]
+ args = m.groups()[4:]
if not result:
if not allowed_types:
raise Exception('Did not find allowed result types for: %s' % name)
@@ -201,6 +230,26 @@
add_matcher(result_type, name, args, comment)
return
+ # Parse ArgumentAdapting matchers.
+ m = re.match(
+ r"""^.*ArgumentAdaptingMatcherFunc<.*>\s*(?:LLVM_ATTRIBUTE_UNUSED\s*)
+ ([a-zA-Z]*)\s*=\s*{};$""",
+ declaration, flags=re.X)
+ if m:
+ name = m.groups()[0]
+ add_matcher('*', name, 'Matcher<*>', comment)
+ return
+
+ # Parse Variadic operator matchers.
+ m = re.match(
+ r"""^.*VariadicOperatorMatcherFunc\s*([a-zA-Z]*)\s*=\s*{.*};$""",
+ declaration, flags=re.X)
+ if m:
+ name = m.groups()[0]
+ add_matcher('*', name, 'Matcher<*>, ..., Matcher<*>', comment)
+ return
+
+
# Parse free standing matcher functions, like:
# Matcher<ResultType> Name(Matcher<ArgumentType> InnerMatcher) {
m = re.match(r"""^\s*(.*)\s+
@@ -270,7 +319,7 @@
declaration += ' ' + line
if ((not line.strip()) or
line.rstrip()[-1] == ';' or
- line.rstrip()[-1] == '{'):
+ (line.rstrip()[-1] == '{' and line.rstrip()[-3:] != '= {')):
if line.strip() and line.rstrip()[-1] == '{':
body = True
else:
diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py
new file mode 100644
index 0000000..0c8ca6d
--- /dev/null
+++ b/docs/tools/dump_format_style.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# A tool to parse the FormatStyle struct from Format.h and update the
+# documentation in ../ClangFormatStyleOptions.rst automatically.
+# Run from the directory in which this file is located to update the docs.
+
+import collections
+import re
+import urllib2
+
+FORMAT_STYLE_FILE = '../../include/clang/Format/Format.h'
+DOC_FILE = '../ClangFormatStyleOptions.rst'
+
+
+def substitute(text, tag, contents):
+ replacement = '\n.. START_%s\n\n%s\n\n.. END_%s\n' % (tag, contents, tag)
+ pattern = r'\n\.\. START_%s\n.*\n\.\. END_%s\n' % (tag, tag)
+ return re.sub(pattern, '%s', text, flags=re.S) % replacement
+
+def doxygen2rst(text):
+ text = re.sub(r'<tt>\s*(.*?)\s*<\/tt>', r'``\1``', text)
+ text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text)
+ text = re.sub(r'\\\w+ ', '', text)
+ return text
+
+def indent(text, columns):
+ indent = ' ' * columns
+ s = re.sub(r'\n([^\n])', '\n' + indent + '\\1', text, flags=re.S)
+ if s.startswith('\n'):
+ return s
+ return indent + s
+
+class Option:
+ def __init__(self, name, type, comment):
+ self.name = name
+ self.type = type
+ self.comment = comment.strip()
+ self.enum = None
+
+ def __str__(self):
+ s = '**%s** (``%s``)\n%s' % (self.name, self.type,
+ doxygen2rst(indent(self.comment, 2)))
+ if self.enum:
+ s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2)
+ return s
+
+class Enum:
+ def __init__(self, name, comment):
+ self.name = name
+ self.comment = comment.strip()
+ self.values = []
+
+ def __str__(self):
+ return '\n'.join(map(str, self.values))
+
+class EnumValue:
+ def __init__(self, name, comment):
+ self.name = name
+ self.comment = comment.strip()
+
+ def __str__(self):
+ return '* ``%s`` (in configuration: ``%s``)\n%s' % (
+ self.name,
+ re.sub('.*_', '', self.name),
+ doxygen2rst(indent(self.comment, 2)))
+
+def clean_comment_line(line):
+ return line[3:].strip() + '\n'
+
+def read_options(header):
+ class State:
+ BeforeStruct, Finished, InStruct, InFieldComment, InEnum, \
+ InEnumMemberComment = range(6)
+ state = State.BeforeStruct
+
+ options = []
+ enums = {}
+ comment = ''
+ enum = None
+
+ for line in header:
+ line = line.strip()
+ if state == State.BeforeStruct:
+ if line == 'struct FormatStyle {':
+ state = State.InStruct
+ elif state == State.InStruct:
+ if line.startswith('///'):
+ state = State.InFieldComment
+ comment = clean_comment_line(line)
+ elif line == '};':
+ state = State.Finished
+ break
+ elif state == State.InFieldComment:
+ if line.startswith('///'):
+ comment += clean_comment_line(line)
+ elif line.startswith('enum'):
+ state = State.InEnum
+ name = re.sub(r'enum\s+(\w+)\s*\{', '\\1', line)
+ enum = Enum(name, comment)
+ elif line.endswith(';'):
+ state = State.InStruct
+ field_type, field_name = re.match(r'(\w+)\s+(\w+);', line).groups()
+ option = Option(str(field_name), str(field_type), comment)
+ options.append(option)
+ else:
+ raise Exception('Invalid format, expected comment, field or enum')
+ elif state == State.InEnum:
+ if line.startswith('///'):
+ state = State.InEnumMemberComment
+ comment = clean_comment_line(line)
+ elif line == '};':
+ state = State.InStruct
+ enums[enum.name] = enum
+ else:
+ raise Exception('Invalid format, expected enum field comment or };')
+ elif state == State.InEnumMemberComment:
+ if line.startswith('///'):
+ comment += clean_comment_line(line)
+ else:
+ state = State.InEnum
+ enum.values.append(EnumValue(line.replace(',', ''), comment))
+ if state != State.Finished:
+ raise Exception('Not finished by the end of file')
+
+ for option in options:
+ if not option.type in ['bool', 'unsigned', 'int']:
+ if enums.has_key(option.type):
+ option.enum = enums[option.type]
+ else:
+ raise Exception('Unknown type: %s' % option.type)
+ return options
+
+options = read_options(open(FORMAT_STYLE_FILE))
+
+options = sorted(options, key=lambda x: x.name)
+options_text = '\n\n'.join(map(str, options))
+
+contents = open(DOC_FILE).read()
+
+contents = substitute(contents, 'FORMAT_STYLE_OPTIONS', options_text)
+
+with open(DOC_FILE, 'w') as output:
+ output.write(contents)
+
diff --git a/examples/clang-interpreter/Makefile b/examples/clang-interpreter/Makefile
index 0c4d35c..55a8e6f 100644
--- a/examples/clang-interpreter/Makefile
+++ b/examples/clang-interpreter/Makefile
@@ -15,8 +15,8 @@
# No plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
-LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter ipo \
- linker selectiondag asmparser instrumentation
+LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter irreader \
+ ipo linker selectiondag asmparser instrumentation option
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a clangCodeGen.a \
clangParse.a clangSema.a clangStaticAnalyzerFrontend.a \
clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index 3d0d640..e00583d 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -21,6 +21,7 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
@@ -34,11 +35,11 @@
// GetMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement GetMainExecutable
// without being given the address of a function in the main executable).
-llvm::sys::Path GetExecutablePath(const char *Argv0) {
+std::string GetExecutablePath(const char *Argv0) {
// This just needs to be some symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
void *MainAddr = (void*) (intptr_t) GetExecutablePath;
- return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
+ return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
}
static int Execute(llvm::Module *Mod, char * const *envp) {
@@ -67,14 +68,14 @@
int main(int argc, const char **argv, char * const *envp) {
void *MainAddr = (void*) (intptr_t) GetExecutablePath;
- llvm::sys::Path Path = GetExecutablePath(argv[0]);
+ std::string Path = GetExecutablePath(argv[0]);
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
TextDiagnosticPrinter *DiagClient =
new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
- Driver TheDriver(Path.str(), llvm::sys::getProcessTriple(), "a.out", Diags);
+ Driver TheDriver(Path, llvm::sys::getProcessTriple(), "a.out", Diags);
TheDriver.setTitle("clang interpreter");
// FIXME: This is a hack to try to force the driver to do something we can
@@ -94,7 +95,7 @@
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
- C->PrintJob(OS, C->getJobs(), "; ", true);
+ Jobs.Print(OS, "; ", true);
Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
return 1;
}
@@ -117,7 +118,7 @@
// Show the invocation, with -v.
if (CI->getHeaderSearchOpts().Verbose) {
llvm::errs() << "clang invocation:\n";
- C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
+ Jobs.Print(llvm::errs(), "\n", true);
llvm::errs() << "\n";
}
diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h
index ff1ec63..fd65418 100644
--- a/include/clang-c/CXCompilationDatabase.h
+++ b/include/clang-c/CXCompilationDatabase.h
@@ -58,7 +58,7 @@
*/
typedef enum {
/*
- * \brief No error occured
+ * \brief No error occurred
*/
CXCompilationDatabase_NoError = 0,
@@ -142,6 +142,24 @@
clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
/**
+ * \brief Get the number of source mappings for the compiler invocation.
+ */
+CINDEX_LINKAGE unsigned
+clang_CompileCommand_getNumMappedSources(CXCompileCommand);
+
+/**
+ * \brief Get the I'th mapped source path for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I);
+
+/**
+ * \brief Get the I'th mapped source content for the compiler invocation.
+ */
+CINDEX_LINKAGE CXString
+clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
+
+/**
* @}
*/
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index 34cab5e..592c4dc 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -46,7 +46,7 @@
CINDEX_LINKAGE const char *clang_getCString(CXString string);
/**
- * \brief Free the given string,
+ * \brief Free the given string.
*/
CINDEX_LINKAGE void clang_disposeString(CXString string);
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index d8c37eb..95d54c2 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -16,9 +16,7 @@
#ifndef CLANG_C_INDEX_H
#define CLANG_C_INDEX_H
-#include <sys/stat.h>
#include <time.h>
-#include <stdio.h>
#include "clang-c/Platform.h"
#include "clang-c/CXString.h"
@@ -32,7 +30,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 19
+#define CINDEX_VERSION_MINOR 20
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -414,6 +412,12 @@
CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location);
/**
+ * \brief Returns non-zero if the given source location is in the main file of
+ * the corresponding translation unit.
+ */
+CINDEX_LINKAGE int clang_Location_isFromMainFile(CXSourceLocation location);
+
+/**
* \brief Retrieve a NULL (invalid) source range.
*/
CINDEX_LINKAGE CXSourceRange clang_getNullRange(void);
@@ -723,7 +727,7 @@
* \brief Retrieve the child diagnostics of a CXDiagnostic.
*
* This CXDiagnosticSet does not need to be released by
- * clang_diposeDiagnosticSet.
+ * clang_disposeDiagnosticSet.
*/
CINDEX_LINKAGE CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);
@@ -763,7 +767,7 @@
* \brief Options to control the display of diagnostics.
*
* The values in this enum are meant to be combined to customize the
- * behavior of \c clang_displayDiagnostic().
+ * behavior of \c clang_formatDiagnostic().
*/
enum CXDiagnosticDisplayOptions {
/**
@@ -850,7 +854,7 @@
* default behavior of the clang compiler.
*
* \returns A set of display options suitable for use with \c
- * clang_displayDiagnostic().
+ * clang_formatDiagnostic().
*/
CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
@@ -1942,7 +1946,7 @@
*/
CXCursor_CompoundStmt = 202,
- /** \brief A case statment.
+ /** \brief A case statement.
*/
CXCursor_CaseStmt = 203,
@@ -2062,7 +2066,11 @@
*/
CXCursor_DeclStmt = 231,
- CXCursor_LastStmt = CXCursor_DeclStmt,
+ /** \brief OpenMP parallel directive.
+ */
+ CXCursor_OMPParallelDirective = 232,
+
+ CXCursor_LastStmt = CXCursor_OMPParallelDirective,
/**
* \brief Cursor that represents the translation unit itself.
@@ -2087,7 +2095,8 @@
CXCursor_CXXOverrideAttr = 405,
CXCursor_AnnotateAttr = 406,
CXCursor_AsmLabelAttr = 407,
- CXCursor_LastAttr = CXCursor_AsmLabelAttr,
+ CXCursor_PackedAttr = 408,
+ CXCursor_LastAttr = CXCursor_PackedAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -2666,7 +2675,11 @@
CXType_FunctionNoProto = 110,
CXType_FunctionProto = 111,
CXType_ConstantArray = 112,
- CXType_Vector = 113
+ CXType_Vector = 113,
+ CXType_IncompleteArray = 114,
+ CXType_VariableArray = 115,
+ CXType_DependentSizedArray = 116,
+ CXType_MemberPointer = 117
};
/**
@@ -2683,6 +2696,8 @@
CXCallingConv_AAPCS_VFP = 7,
CXCallingConv_PnaclCall = 8,
CXCallingConv_IntelOclBicc = 9,
+ CXCallingConv_X86_64Win64 = 10,
+ CXCallingConv_X86_64SysV = 11,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
@@ -2955,6 +2970,13 @@
CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T);
/**
+ * \brief Return the class type of an member pointer type.
+ *
+ * If a non-member-pointer type is passed in, an invalid type is returned.
+ */
+CINDEX_LINKAGE CXType clang_Type_getClassType(CXType T);
+
+/**
* \brief Return the size of a type in bytes as per C++[expr.sizeof] standard.
*
* If the type declaration is invalid, CXTypeLayoutError_Invalid is returned.
@@ -2980,6 +3002,23 @@
*/
CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
+enum CXRefQualifierKind {
+ /** \brief No ref-qualifier was provided. */
+ CXRefQualifier_None = 0,
+ /** \brief An lvalue ref-qualifier was provided (\c &). */
+ CXRefQualifier_LValue,
+ /** \brief An rvalue ref-qualifier was provided (\c &&). */
+ CXRefQualifier_RValue
+};
+
+/**
+ * \brief Retrieve the ref-qualifier kind of a function or method.
+ *
+ * The ref-qualifier is returned for C++ functions or methods. For other types
+ * or non-C++ declarations, CXRefQualifier_None is returned.
+ */
+CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);
+
/**
* \brief Returns non-zero if the cursor specifies a Record member that is a
* bitfield.
@@ -3414,6 +3453,13 @@
CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
/**
+ * \brief Given a cursor that represents an ObjC method or property declaration,
+ * return non-zero if the declaration was affected by "@optional".
+ * Returns zero if the cursor is not such a declaration or it is "@required".
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
+
+/**
* \brief Returns non-zero if the given cursor is a variadic function or method.
*/
CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
@@ -4035,6 +4081,12 @@
*/
/**
+ * \brief Determine if a C++ member function or member function template is
+ * pure virtual.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C);
+
+/**
* \brief Determine if a C++ member function or member function template is
* declared 'static'.
*/
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index c167d3c..196f6c0 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -97,6 +97,8 @@
FileRemapper Remapper;
public:
+ bool HadARCErrors;
+
MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient,
StringRef outputDir = StringRef());
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 2daaf73..45c8b4e 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -57,14 +57,12 @@
/// \brief Migrates to modern ObjC syntax.
class ObjCMigrateAction : public WrapperFrontendAction {
std::string MigrateDir;
- bool MigrateLiterals;
- bool MigrateSubscripting;
+ unsigned ObjCMigAction;
FileRemapper Remapper;
CompilerInstance *CompInst;
public:
ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
- bool migrateLiterals,
- bool migrateSubscripting);
+ unsigned migrateAction);
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index 94c9e8f..f7677cc 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -53,7 +53,6 @@
StringRef outputDir = StringRef());
void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
- void remap(StringRef filePath, StringRef newPath);
void applyMappings(PreprocessorOptions &PPOpts) const;
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index ec8faa4..b4fd2af 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -168,6 +168,13 @@
MakeUninit();
}
+ /// \brief Returns whether the object performed allocations.
+ ///
+ /// If APValues are constructed via placement new, \c needsCleanup()
+ /// indicates whether the destructor must be called in order to correctly
+ /// free all allocated memory.
+ bool needsCleanup() const;
+
/// \brief Swaps the contents of this and the given APValue.
void swap(APValue &RHS);
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index ae77943..7b6fa94 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CLANG_AST_ASTCONSUMER_H
#define LLVM_CLANG_AST_ASTCONSUMER_H
+#include "llvm/ADT/StringRef.h"
+
namespace clang {
class ASTContext;
class CXXRecordDecl;
@@ -70,6 +72,10 @@
/// can be defined in declspecs).
virtual void HandleTagDeclDefinition(TagDecl *D) {}
+ /// \brief This callback is invoked the first time each TagDecl is required to
+ /// be complete.
+ virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
+
/// \brief Invoked when a function is implicitly instantiated.
/// Note that at this point point it does not have a body, its body is
/// instantiated at the end of the translation unit and passed to
@@ -86,6 +92,21 @@
/// The default implementation passes it to HandleTopLevelDecl.
virtual void HandleImplicitImportDecl(ImportDecl *D);
+ /// \brief Handle a pragma that appends to Linker Options. Currently this
+ /// only exists to support Microsoft's #pragma comment(linker, "/foo").
+ virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {}
+
+ /// \brief Handle a pragma that emits a mismatch identifier and value to the
+ /// object file for the linker to work with. Currently, this only exists to
+ /// support Microsoft's #pragma detect_mismatch.
+ virtual void HandleDetectMismatch(llvm::StringRef Name,
+ llvm::StringRef Value) {}
+
+ /// \brief Handle a dependent library created by a pragma in the source.
+ /// Currently this only exists to support Microsoft's
+ /// #pragma comment(lib, "/foo").
+ virtual void HandleDependentLibrary(llvm::StringRef Lib) {}
+
/// CompleteTentativeDefinition - Callback invoked at the end of a translation
/// unit to notify the consumer that the given tentative definition should be
/// completed.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index c5d3337..f420e85 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -19,11 +19,9 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/LambdaMangleContext.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
@@ -47,6 +45,7 @@
namespace clang {
class FileManager;
+ class AtomicExpr;
class ASTRecordLayout;
class BlockExpr;
class CharUnits;
@@ -55,9 +54,11 @@
class ExternalASTSource;
class ASTMutationListener;
class IdentifierTable;
+ class MaterializeTemporaryExpr;
class SelectorTable;
class TargetInfo;
class CXXABI;
+ class MangleNumberingContext;
// Decls
class MangleContext;
class ObjCIvarDecl;
@@ -81,6 +82,7 @@
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
mutable llvm::FoldingSet<PointerType> PointerTypes;
+ mutable llvm::FoldingSet<DecayedType> DecayedTypes;
mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
@@ -146,7 +148,7 @@
mutable TypeInfoMap MemoizedTypeInfo;
/// \brief A cache mapping from CXXRecordDecls to key functions.
- llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
+ llvm::DenseMap<const CXXRecordDecl*, LazyDeclPtr> KeyFunctions;
/// \brief Mapping from ObjCContainers to their ObjCImplementations.
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*> ObjCImpls;
@@ -163,6 +165,11 @@
llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
ClassScopeSpecializationPattern;
+ /// \brief Mapping from materialized temporaries with static storage duration
+ /// that appear in constant initializers to their evaluated values.
+ llvm::DenseMap<const MaterializeTemporaryExpr*, APValue>
+ MaterializedTemporaryValues;
+
/// \brief Representation of a "canonical" template template parameter that
/// is used in canonical template names.
class CanonicalTemplateTemplateParm : public llvm::FoldingSetNode {
@@ -190,6 +197,9 @@
/// \brief The typedef for the __uint128_t type.
mutable TypedefDecl *UInt128Decl;
+
+ /// \brief The typedef for the __float128 stub type.
+ mutable TypeDecl *Float128StubDecl;
/// \brief The typedef for the target specific predefined
/// __builtin_va_list type.
@@ -261,13 +271,30 @@
/// wasting space in the Decl class.
llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;
- /// \brief Keeps track of the static data member templates from which
- /// static data members of class template specializations were instantiated.
+ /// \brief A mapping from non-redeclarable declarations in modules that were
+ /// merged with other declarations to the canonical declaration that they were
+ /// merged into.
+ llvm::DenseMap<Decl*, Decl*> MergedDecls;
+
+public:
+ /// \brief A type synonym for the TemplateOrInstantiation mapping.
+ typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
+ TemplateOrSpecializationInfo;
+
+private:
+
+ /// \brief A mapping to contain the template or declaration that
+ /// a variable declaration describes or was instantiated from,
+ /// respectively.
///
- /// This data structure stores the mapping from instantiations of static
- /// data members to the static data member representations within the
- /// class template from which they were instantiated along with the kind
- /// of instantiation or specialization (a TemplateSpecializationKind - 1).
+ /// For non-templates, this value will be NULL. For variable
+ /// declarations that describe a variable template, this will be a
+ /// pointer to a VarTemplateDecl. For static data members
+ /// of class template specializations, this will be the
+ /// MemberSpecializationInfo referring to the member variable that was
+ /// instantiated or specialized. Thus, the mapping will keep track of
+ /// the static data member templates from which static data members of
+ /// class template specializations were instantiated.
///
/// Given the following example:
///
@@ -286,8 +313,8 @@
/// This mapping will contain an entry that maps from the VarDecl for
/// X<int>::value to the corresponding VarDecl for X<T>::value (within the
/// class template X) and will be marked TSK_ImplicitInstantiation.
- llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>
- InstantiatedFromStaticDataMember;
+ llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
+ TemplateOrInstantiation;
/// \brief Keeps track of the declaration from which a UsingDecl was
/// created during instantiation.
@@ -328,12 +355,15 @@
typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
- /// \brief Mapping from each declaration context to its corresponding lambda
- /// mangling context.
- llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
+ /// \brief Mapping from each declaration context to its corresponding
+ /// mangling numbering context (used for constructs like lambdas which
+ /// need to be consistently numbered for the mangler).
+ llvm::DenseMap<const DeclContext *, MangleNumberingContext *>
+ MangleNumberingContexts;
- llvm::DenseMap<const DeclContext *, unsigned> UnnamedMangleContexts;
- llvm::DenseMap<const TagDecl *, unsigned> UnnamedMangleNumbers;
+ /// \brief Side-table of mangling numbers for declarations which rarely
+ /// need them (like static local vars).
+ llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
@@ -368,6 +398,10 @@
/// \brief The logical -> physical address space map.
const LangAS::Map *AddrSpaceMap;
+ /// \brief Address space map mangling must be used with language specific
+ /// address spaces (e.g. OpenCL/CUDA)
+ bool AddrSpaceMapMangling;
+
friend class ASTDeclReader;
friend class ASTReader;
friend class ASTWriter;
@@ -419,22 +453,7 @@
return getParents(ast_type_traits::DynTypedNode::create(Node));
}
- ParentVector getParents(const ast_type_traits::DynTypedNode &Node) {
- assert(Node.getMemoizationData() &&
- "Invariant broken: only nodes that support memoization may be "
- "used in the parent map.");
- if (!AllParents) {
- // We always need to run over the whole translation unit, as
- // hasAncestor can escape any subtree.
- AllParents.reset(
- ParentMapASTVisitor::buildMap(*getTranslationUnitDecl()));
- }
- ParentMap::const_iterator I = AllParents->find(Node.getMemoizationData());
- if (I == AllParents->end()) {
- return ParentVector();
- }
- return I->second;
- }
+ ParentVector getParents(const ast_type_traits::DynTypedNode &Node);
const clang::PrintingPolicy &getPrintingPolicy() const {
return PrintingPolicy;
@@ -451,7 +470,7 @@
return BumpAlloc;
}
- void *Allocate(unsigned Size, unsigned Align = 8) const {
+ void *Allocate(size_t Size, unsigned Align = 8) const {
return BumpAlloc.Allocate(Size, Align);
}
void Deallocate(void *Ptr) const { }
@@ -470,6 +489,19 @@
const TargetInfo &getTargetInfo() const { return *Target; }
+ /// getIntTypeForBitwidth -
+ /// sets integer QualTy according to specified details:
+ /// bitwidth, signed/unsigned.
+ /// Returns empty type if there is no appropriate target types.
+ QualType getIntTypeForBitwidth(unsigned DestWidth,
+ unsigned Signed) const;
+ /// getRealTypeForBitwidth -
+ /// sets floating point QualTy according to specified bitwidth.
+ /// Returns empty type if there is no appropriate target types.
+ QualType getRealTypeForBitwidth(unsigned DestWidth) const;
+
+ bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
+
const LangOptions& getLangOpts() const { return LangOpts; }
DiagnosticsEngine &getDiagnostics() const;
@@ -580,7 +612,12 @@
/// preprocessor is not available.
comments::FullComment *getCommentForDecl(const Decl *D,
const Preprocessor *PP) const;
-
+
+ /// Return parsed documentation comment attached to a given declaration.
+ /// Returns NULL if no comment is attached. Does not look at any
+ /// redeclarations of the declaration.
+ comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
+
comments::FullComment *cloneFullComment(comments::FullComment *FC,
const Decl *D) const;
@@ -601,9 +638,13 @@
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
+ // FIXME: Remove ?
MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
const VarDecl *Var);
+ TemplateOrSpecializationInfo
+ getTemplateOrSpecializationInfo(const VarDecl *Var);
+
FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);
void setClassScopeSpecializationPattern(FunctionDecl *FD,
@@ -615,6 +656,9 @@
TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
+ void setTemplateOrSpecializationInfo(VarDecl *Inst,
+ TemplateOrSpecializationInfo TSI);
+
/// \brief If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
@@ -632,31 +676,6 @@
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
- /// \brief Return \c true if \p FD is a zero-length bitfield which follows
- /// the non-bitfield \p LastFD.
- bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
- const FieldDecl *LastFD) const;
-
- /// \brief Return \c true if \p FD is a zero-length bitfield which follows
- /// the bitfield \p LastFD.
- bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
- const FieldDecl *LastFD) const;
-
- /// \brief Return \c true if \p FD is a bitfield which follows the bitfield
- /// \p LastFD.
- bool BitfieldFollowsBitfield(const FieldDecl *FD,
- const FieldDecl *LastFD) const;
-
- /// \brief Return \c true if \p FD is not a bitfield which follows the
- /// bitfield \p LastFD.
- bool NonBitfieldFollowsBitfield(const FieldDecl *FD,
- const FieldDecl *LastFD) const;
-
- /// \brief Return \c true if \p FD is a bitfield which follows the
- /// non-bitfield \p LastFD.
- bool BitfieldFollowsNonBitfield(const FieldDecl *FD,
- const FieldDecl *LastFD) const;
-
// Access to the set of methods overridden by the given C++ method.
typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
overridden_cxx_method_iterator
@@ -732,7 +751,15 @@
return import_iterator(FirstLocalImport);
}
import_iterator local_import_end() const { return import_iterator(); }
-
+
+ Decl *getPrimaryMergedDecl(Decl *D) {
+ Decl *Result = MergedDecls.lookup(D);
+ return Result ? Result : D;
+ }
+ void setPrimaryMergedDecl(Decl *D, Decl *Primary) {
+ MergedDecls[D] = Primary;
+ }
+
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
@@ -740,7 +767,8 @@
CanQualType VoidTy;
CanQualType BoolTy;
CanQualType CharTy;
- CanQualType WCharTy; // [C++ 3.9.1p5], integer type in C99.
+ CanQualType WCharTy; // [C++ 3.9.1p5].
+ CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default promotions.
CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
@@ -809,6 +837,9 @@
/// \brief Retrieve the declaration for the 128-bit unsigned integer type.
TypedefDecl *getUInt128Decl() const;
+
+ /// \brief Retrieve the declaration for a 128-bit float stub type.
+ TypeDecl *getFloat128StubType() const;
//===--------------------------------------------------------------------===//
// Type Constructors
@@ -884,6 +915,14 @@
return CanQualType::CreateUnsafe(getPointerType((QualType) T));
}
+ /// \brief Return the uniqued reference to the decayed version of the given
+ /// type. Can only be called on array and function types which decay to
+ /// pointer types.
+ QualType getDecayedType(QualType T) const;
+ CanQualType getDecayedType(CanQualType T) const {
+ return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
+ }
+
/// \brief Return the uniqued reference to the atomic type for the specified
/// type.
QualType getAtomicType(QualType T) const;
@@ -1104,7 +1143,7 @@
/// \brief C++11 deduced auto type.
QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto,
- bool IsDependent = false) const;
+ bool IsDependent) const;
/// \brief C++11 deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
@@ -1130,11 +1169,15 @@
/// <stdint.h>.
CanQualType getUIntMaxType() const;
- /// \brief In C++, this returns the unique wchar_t type. In C99, this
- /// returns a type compatible with the type defined in <stddef.h> as defined
- /// by the target.
+ /// \brief Return the unique wchar_t type available in C++ (and available as
+ /// __wchar_t as a Microsoft extension).
QualType getWCharType() const { return WCharTy; }
+ /// \brief Return the type of wide characters. In C++, this returns the
+ /// unique wchar_t type. In C99, this returns a type compatible with the type
+ /// defined in <stddef.h> as defined by the target.
+ QualType getWideCharType() const { return WideCharTy; }
+
/// \brief Return the type of "signed wchar_t".
///
/// Used when in C++, as a GCC extension.
@@ -1607,14 +1650,17 @@
/// \pre \p D must not be a bitfield type, as bitfields do not have a valid
/// alignment.
///
- /// If \p RefAsPointee, references are treated like their underlying type
- /// (for alignof), else they're treated like pointers (for CodeGen).
- CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false) const;
+ /// If \p ForAlignof, references are treated like their underlying type
+ /// and large arrays don't get any special treatment. If not \p ForAlignof
+ /// it computes the value expected by CodeGen: references are treated like
+ /// pointers and large arrays get extra alignment.
+ CharUnits getDeclAlign(const Decl *D, bool ForAlignof = false) const;
/// \brief Get or compute information about the layout of the specified
/// record (struct/union/class) \p D, which indicates its size and field
/// position information.
const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
+ const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const;
/// \brief Get or compute information about the layout of the specified
/// Objective-C interface.
@@ -1721,6 +1767,9 @@
getCanonicalType(T2).getTypePtr();
}
+ bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
+ const ObjCMethodDecl *MethodImp);
+
bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2);
/// \brief Retrieves the "canonical" nested name specifier for a
@@ -1749,19 +1798,9 @@
NestedNameSpecifier *
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
- /// \brief Retrieves the default calling convention to use for
- /// C++ instance methods.
- CallingConv getDefaultCXXMethodCallConv(bool isVariadic);
-
- /// \brief Retrieves the canonical representation of the given
- /// calling convention.
- CallingConv getCanonicalCallConv(CallingConv CC) const;
-
- /// \brief Determines whether two calling conventions name the same
- /// calling convention.
- bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
- return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
- }
+ /// \brief Retrieves the default calling convention for the current target.
+ CallingConv getDefaultCallingConvention(bool isVariadic,
+ bool IsCXXMethod) const;
/// \brief Retrieves the "canonical" template name that refers to a
/// given template.
@@ -1899,6 +1938,12 @@
return (*AddrSpaceMap)[AS - LangAS::Offset];
}
+ bool addressSpaceMapManglingFor(unsigned AS) const {
+ return AddrSpaceMapMangling ||
+ AS < LangAS::Offset ||
+ AS >= LangAS::Offset + LangAS::Count;
+ }
+
private:
// Helper for integer ordering
unsigned getIntegerRank(const Type *T) const;
@@ -1925,7 +1970,6 @@
bool isObjCSelType(QualType T) const {
return T == getObjCSelType();
}
- bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS);
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
bool ForCompare);
@@ -2092,12 +2136,15 @@
/// it is not used.
bool DeclMustBeEmitted(const Decl *D);
- void addUnnamedTag(const TagDecl *Tag);
- int getUnnamedTagManglingNumber(const TagDecl *Tag) const;
+ void setManglingNumber(const NamedDecl *ND, unsigned Number);
+ unsigned getManglingNumber(const NamedDecl *ND) const;
- /// \brief Retrieve the lambda mangling number for a lambda expression.
- unsigned getLambdaManglingNumber(CXXMethodDecl *CallOperator);
-
+ /// \brief Retrieve the context for computing mangling numbers in the given
+ /// DeclContext.
+ MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
+
+ MangleNumberingContext *createMangleNumberingContext() const;
+
/// \brief Used by ParmVarDecl to store on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
void setParameterIndex(const ParmVarDecl *D, unsigned index);
@@ -2105,7 +2152,12 @@
/// \brief Used by ParmVarDecl to retrieve on the side the
/// index of the parameter when it exceeds the size of the normal bitfield.
unsigned getParameterIndex(const ParmVarDecl *D) const;
-
+
+ /// \brief Get the storage for the constant value of a materialized temporary
+ /// of static storage duration.
+ APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
+ bool MayCreate);
+
//===--------------------------------------------------------------------===//
// Statistics
//===--------------------------------------------------------------------===//
@@ -2197,93 +2249,21 @@
const ObjCImplementationDecl *Impl) const;
private:
- /// \brief A set of deallocations that should be performed when the
+ /// \brief A set of deallocations that should be performed when the
/// ASTContext is destroyed.
- SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations;
-
+ typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> >
+ DeallocationMap;
+ DeallocationMap Deallocations;
+
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
- /// \brief A counter used to uniquely identify "blocks".
- mutable unsigned int UniqueBlockByRefTypeID;
-
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
- /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
- /// parents as defined by the \c RecursiveASTVisitor.
- ///
- /// Note that the relationship described here is purely in terms of AST
- /// traversal - there are other relationships (for example declaration context)
- /// in the AST that are better modeled by special matchers.
- ///
- /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
- class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
- public:
- /// \brief Builds and returns the translation unit's parent map.
- ///
- /// The caller takes ownership of the returned \c ParentMap.
- static ParentMap *buildMap(TranslationUnitDecl &TU) {
- ParentMapASTVisitor Visitor(new ParentMap);
- Visitor.TraverseDecl(&TU);
- return Visitor.Parents;
- }
-
- private:
- typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
-
- ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) {
- }
-
- bool shouldVisitTemplateInstantiations() const {
- return true;
- }
- bool shouldVisitImplicitCode() const {
- return true;
- }
- // Disables data recursion. We intercept Traverse* methods in the RAV, which
- // are not triggered during data recursion.
- bool shouldUseDataRecursionFor(clang::Stmt *S) const {
- return false;
- }
-
- template <typename T>
- bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
- if (Node == NULL)
- return true;
- if (ParentStack.size() > 0)
- // FIXME: Currently we add the same parent multiple times, for example
- // when we visit all subexpressions of template instantiations; this is
- // suboptimal, bug benign: the only way to visit those is with
- // hasAncestor / hasParent, and those do not create new matches.
- // The plan is to enable DynTypedNode to be storable in a map or hash
- // map. The main problem there is to implement hash functions /
- // comparison operators for all types that DynTypedNode supports that
- // do not have pointer identity.
- (*Parents)[Node].push_back(ParentStack.back());
- ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
- bool Result = (this ->* traverse) (Node);
- ParentStack.pop_back();
- return Result;
- }
-
- bool TraverseDecl(Decl *DeclNode) {
- return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
- }
-
- bool TraverseStmt(Stmt *StmtNode) {
- return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
- }
-
- ParentMap *Parents;
- llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
-
- friend class RecursiveASTVisitor<ParentMapASTVisitor>;
- };
-
llvm::OwningPtr<ParentMap> AllParents;
};
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 64e955e..1635511 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+ SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"
#undef DIAG
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
new file mode 100644
index 0000000..4f32798
--- /dev/null
+++ b/include/clang/AST/ASTFwd.h
@@ -0,0 +1,28 @@
+//===--- ASTFwd.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 Forward declaration of all AST node types.
+///
+//===-------------------------------------------------------------===//
+
+namespace clang {
+
+class Decl;
+#define DECL(DERIVED, BASE) class DERIVED##Decl;
+#include "clang/AST/DeclNodes.inc"
+class Stmt;
+#define STMT(DERIVED, BASE) class DERIVED;
+#include "clang/AST/StmtNodes.inc"
+class Type;
+#define TYPE(DERIVED, BASE) class DERIVED##Type;
+#include "clang/AST/TypeNodes.def"
+class CXXCtorInitializer;
+
+} // end namespace clang
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index 1672ab2..b74c8ee 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -271,6 +271,14 @@
/// Subclasses can override this function to observe all of the \c From ->
/// \c To declaration mappings as they are imported.
virtual Decl *Imported(Decl *From, Decl *To);
+
+ /// \brief Called by StructuralEquivalenceContext. If a RecordDecl is
+ /// being compared to another RecordDecl as part of import, completing the
+ /// other RecordDecl may trigger importation of the first RecordDecl. This
+ /// happens especially for anonymous structs. If the original of the second
+ /// RecordDecl can be found, we can complete it without the need for
+ /// importation, eliminating this loop.
+ virtual Decl *GetOriginalDecl(Decl *To) { return NULL; }
/// \brief Determine whether the given types are structurally
/// equivalent.
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
new file mode 100644
index 0000000..358ac71
--- /dev/null
+++ b/include/clang/AST/ASTLambda.h
@@ -0,0 +1,80 @@
+//===--- ASTLambda.h - Lambda Helper Functions --------------*- C++ -*-===//
+//
+// 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 provides some common utility functions for processing
+/// Lambda related AST Constructs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDA_H
+#define LLVM_CLANG_AST_LAMBDA_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace clang {
+inline StringRef getLambdaStaticInvokerName() {
+ return "__invoke";
+}
+// This function returns true if M is a specialization, a template,
+// or a non-generic lambda call operator.
+inline bool isLambdaCallOperator(const CXXMethodDecl *MD) {
+ const CXXRecordDecl *LambdaClass = MD->getParent();
+ if (!LambdaClass || !LambdaClass->isLambda()) return false;
+ return MD->getOverloadedOperator() == OO_Call;
+}
+
+inline bool isLambdaCallOperator(const DeclContext *DC) {
+ if (!DC || !isa<CXXMethodDecl>(DC)) return false;
+ return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
+}
+
+inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
+ if (!MD) return false;
+ CXXRecordDecl *LambdaClass = MD->getParent();
+ if (LambdaClass && LambdaClass->isGenericLambda())
+ return isLambdaCallOperator(MD) &&
+ MD->isFunctionTemplateSpecialization();
+ return false;
+}
+
+inline bool isLambdaConversionOperator(CXXConversionDecl *C) {
+ return C ? C->getParent()->isLambda() : false;
+}
+
+inline bool isLambdaConversionOperator(Decl *D) {
+ if (!D) return false;
+ if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D))
+ return isLambdaConversionOperator(Conv);
+ if (FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(D))
+ if (CXXConversionDecl *Conv =
+ dyn_cast_or_null<CXXConversionDecl>(F->getTemplatedDecl()))
+ return isLambdaConversionOperator(Conv);
+ return false;
+}
+
+inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
+ return isGenericLambdaCallOperatorSpecialization(
+ dyn_cast<CXXMethodDecl>(DC));
+}
+
+
+// This returns the parent DeclContext ensuring that the correct
+// parent DeclContext is returned for Lambdas
+inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
+ if (isLambdaCallOperator(DC))
+ return DC->getParent()->getParent();
+ else
+ return DC->getParent();
+}
+
+} // clang
+
+#endif // LLVM_CLANG_AST_LAMBDA_H
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 6b70285..6d12a92 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -27,8 +27,11 @@
class ObjCContainerDecl;
class ObjCInterfaceDecl;
class ObjCPropertyDecl;
+ class QualType;
class TagDecl;
class VarDecl;
+ class VarTemplateDecl;
+ class VarTemplateSpecializationDecl;
/// \brief An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
@@ -53,9 +56,18 @@
/// \brief A template specialization (or partial one) was added to the
/// template declaration.
+ virtual void
+ AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+ const VarTemplateSpecializationDecl *D) {}
+
+ /// \brief A template specialization (or partial one) was added to the
+ /// template declaration.
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {}
+ /// \brief A function's return type has been deduced.
+ virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
+
/// \brief An implicit member got a definition.
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
@@ -78,6 +90,11 @@
const ObjCPropertyDecl *OrigProp,
const ObjCCategoryDecl *ClassExt) {}
+ /// \brief A declaration is marked used which was not previously marked used.
+ ///
+ /// \param D the declaration marked used
+ virtual void DeclarationMarkedUsed(const Decl *D) {}
+
// NOTE: If new methods are added they should also be added to
// MultiplexASTMutationListener.
};
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 4688b12..087ad56 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -7,22 +7,132 @@
//
//===----------------------------------------------------------------------===//
//
-// Provides a dynamically typed node container that can be used to store
-// an AST base node at runtime in the same storage in a type safe way.
+// Provides a dynamic type identifier and a dynamically typed node container
+// that can be used to store an AST base node at runtime in the same storage in
+// a type safe way.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_AST_TYPE_TRAITS_H
#define LLVM_CLANG_AST_AST_TYPE_TRAITS_H
+#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/Support/AlignOf.h"
+namespace llvm {
+
+class raw_ostream;
+
+}
+
namespace clang {
+
+struct PrintingPolicy;
+
namespace ast_type_traits {
+/// \brief Kind identifier.
+///
+/// It can be constructed from any node kind and allows for runtime type
+/// hierarchy checks.
+/// Use getFromNodeKind<T>() to construct them.
+class ASTNodeKind {
+public:
+ /// \brief Empty identifier. It matches nothing.
+ ASTNodeKind() : KindId(NKI_None) {}
+
+ /// \brief Construct an identifier for T.
+ template <class T>
+ static ASTNodeKind getFromNodeKind() {
+ return ASTNodeKind(KindToKindId<T>::Id);
+ }
+
+ /// \brief Returns \c true if \c this and \c Other represent the same kind.
+ bool isSame(ASTNodeKind Other) const;
+
+ /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
+ bool isBaseOf(ASTNodeKind Other) const;
+
+ /// \brief String representation of the kind.
+ StringRef asStringRef() const;
+
+private:
+ /// \brief Kind ids.
+ ///
+ /// Includes all possible base and derived kinds.
+ enum NodeKindId {
+ NKI_None,
+ NKI_CXXCtorInitializer,
+ NKI_TemplateArgument,
+ NKI_NestedNameSpecifier,
+ NKI_NestedNameSpecifierLoc,
+ NKI_QualType,
+ NKI_TypeLoc,
+ NKI_Decl,
+#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
+#include "clang/AST/DeclNodes.inc"
+ NKI_Stmt,
+#define STMT(DERIVED, BASE) NKI_##DERIVED,
+#include "clang/AST/StmtNodes.inc"
+ NKI_Type,
+#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
+#include "clang/AST/TypeNodes.def"
+ NKI_NumberOfKinds
+ };
+
+ /// \brief Use getFromNodeKind<T>() to construct the kind.
+ ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+
+ /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
+ /// Derived.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+
+ /// \brief Helper meta-function to convert a kind T to its enum value.
+ ///
+ /// This struct is specialized below for all known kinds.
+ template <class T> struct KindToKindId {
+ static const NodeKindId Id = NKI_None;
+ };
+
+ /// \brief Per kind info.
+ struct KindInfo {
+ /// \brief The id of the parent kind, or None if it has no parent.
+ NodeKindId ParentId;
+ /// \brief Name of the kind.
+ const char *Name;
+ };
+ static const KindInfo AllKindInfo[NKI_NumberOfKinds];
+
+ NodeKindId KindId;
+};
+
+#define KIND_TO_KIND_ID(Class) \
+ template <> struct ASTNodeKind::KindToKindId<Class> { \
+ static const NodeKindId Id = NKI_##Class; \
+ };
+KIND_TO_KIND_ID(CXXCtorInitializer)
+KIND_TO_KIND_ID(TemplateArgument)
+KIND_TO_KIND_ID(NestedNameSpecifier)
+KIND_TO_KIND_ID(NestedNameSpecifierLoc)
+KIND_TO_KIND_ID(QualType)
+KIND_TO_KIND_ID(TypeLoc)
+KIND_TO_KIND_ID(Decl)
+KIND_TO_KIND_ID(Stmt)
+KIND_TO_KIND_ID(Type)
+#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
+#include "clang/AST/DeclNodes.inc"
+#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
+#include "clang/AST/StmtNodes.inc"
+#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
+#include "clang/AST/TypeNodes.def"
+#undef KIND_TO_KIND_ID
+
/// \brief A dynamically typed AST node container.
///
/// Stores an AST node in a type safe way. This allows writing code that
@@ -32,7 +142,7 @@
/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
/// and \c get<T>() to retrieve the node as type T if the types match.
///
-/// See \c NodeTypeTag for which node base types are currently supported;
+/// See \c ASTNodeKind for which node base types are currently supported;
/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
/// the supported base types.
class DynTypedNode {
@@ -49,15 +159,15 @@
/// convertible to \c T.
///
/// For types that have identity via their pointer in the AST
- /// (like \c Stmt and \c Decl) the returned pointer points to the
- /// referenced AST node.
+ /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
+ /// pointer points to the referenced AST node.
/// For other types (like \c QualType) the value is stored directly
/// in the \c DynTypedNode, and the returned pointer points at
/// the storage inside DynTypedNode. For those nodes, do not
/// use the pointer outside the scope of the DynTypedNode.
template <typename T>
const T *get() const {
- return BaseConverter<T>::get(Tag, Storage.buffer);
+ return BaseConverter<T>::get(NodeKind, Storage.buffer);
}
/// \brief Returns a pointer that identifies the stored AST node.
@@ -67,142 +177,171 @@
/// method returns NULL.
const void *getMemoizationData() const;
+ /// \brief Prints the node to the given output stream.
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
+
+ /// \brief Dumps the node to the given output stream.
+ void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
+
+ /// \brief For nodes which represent textual entities in the source code,
+ /// return their SourceRange. For all other nodes, return SourceRange().
+ SourceRange getSourceRange() const;
+
+ /// @{
+ /// \brief Imposes an order on \c DynTypedNode.
+ ///
+ /// Supports comparison of nodes that support memoization.
+ /// FIXME: Implement comparsion for other node types (currently
+ /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
+ bool operator<(const DynTypedNode &Other) const {
+ assert(getMemoizationData() && Other.getMemoizationData());
+ return getMemoizationData() < Other.getMemoizationData();
+ }
+ bool operator==(const DynTypedNode &Other) const {
+ // Nodes with different types cannot be equal.
+ if (!NodeKind.isSame(Other.NodeKind))
+ return false;
+
+ // FIXME: Implement for other types.
+ if (ASTNodeKind::getFromNodeKind<QualType>().isBaseOf(NodeKind)) {
+ return *get<QualType>() == *Other.get<QualType>();
+ }
+ assert(getMemoizationData() && Other.getMemoizationData());
+ return getMemoizationData() == Other.getMemoizationData();
+ }
+ bool operator!=(const DynTypedNode &Other) const {
+ return !operator==(Other);
+ }
+ /// @}
+
private:
/// \brief Takes care of converting from and to \c T.
template <typename T, typename EnablerT = void> struct BaseConverter;
- /// \brief Supported base node types.
- enum NodeTypeTag {
- NT_Decl,
- NT_Stmt,
- NT_NestedNameSpecifier,
- NT_NestedNameSpecifierLoc,
- NT_QualType,
- NT_Type,
- NT_TypeLoc
- } Tag;
+ /// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
+ template <typename T, typename BaseT> struct DynCastPtrConverter {
+ static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+ if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
+ return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
+ return NULL;
+ }
+ static DynTypedNode create(const BaseT &Node) {
+ DynTypedNode Result;
+ Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ new (Result.Storage.buffer) const BaseT * (&Node);
+ return Result;
+ }
+ };
+
+ /// \brief Converter that stores T* (by pointer).
+ template <typename T> struct PtrConverter {
+ static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+ if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+ return *reinterpret_cast<T *const *>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const T &Node) {
+ DynTypedNode Result;
+ Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ new (Result.Storage.buffer) const T * (&Node);
+ return Result;
+ }
+ };
+
+ /// \brief Converter that stores T (by value).
+ template <typename T> struct ValueConverter {
+ static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+ if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
+ return reinterpret_cast<const T *>(Storage);
+ return NULL;
+ }
+ static DynTypedNode create(const T &Node) {
+ DynTypedNode Result;
+ Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
+ new (Result.Storage.buffer) T(Node);
+ return Result;
+ }
+ };
+
+ ASTNodeKind NodeKind;
/// \brief Stores the data of the node.
///
- /// Note that we can store \c Decls and \c Stmts by pointer as they are
- /// guaranteed to be unique pointers pointing to dedicated storage in the
- /// AST. \c QualTypes on the other hand do not have storage or unique
+ /// Note that we can store \c Decls, \c Stmts, \c Types,
+ /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
+ /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
+ /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
+ /// \c TemplateArguments on the other hand do not have storage or unique
/// pointers and thus need to be stored by value.
- llvm::AlignedCharArrayUnion<Decl *, Stmt *, NestedNameSpecifier,
- NestedNameSpecifierLoc, QualType, Type,
- TypeLoc> Storage;
+ typedef llvm::AlignedCharArrayUnion<
+ Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *>
+ KindsByPointer;
+ llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument,
+ NestedNameSpecifierLoc, QualType, TypeLoc>
+ Storage;
};
-// FIXME: Pull out abstraction for the following.
-template<typename T> struct DynTypedNode::BaseConverter<T,
- typename llvm::enable_if<llvm::is_base_of<Decl, T> >::type> {
- static const T *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_Decl)
- return dyn_cast<T>(*reinterpret_cast<Decl*const*>(Storage));
- return NULL;
- }
- static DynTypedNode create(const Decl &Node) {
- DynTypedNode Result;
- Result.Tag = NT_Decl;
- new (Result.Storage.buffer) const Decl*(&Node);
- return Result;
- }
-};
-template<typename T> struct DynTypedNode::BaseConverter<T,
- typename llvm::enable_if<llvm::is_base_of<Stmt, T> >::type> {
- static const T *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_Stmt)
- return dyn_cast<T>(*reinterpret_cast<Stmt*const*>(Storage));
- return NULL;
- }
- static DynTypedNode create(const Stmt &Node) {
- DynTypedNode Result;
- Result.Tag = NT_Stmt;
- new (Result.Storage.buffer) const Stmt*(&Node);
- return Result;
- }
-};
-template<typename T> struct DynTypedNode::BaseConverter<T,
- typename llvm::enable_if<llvm::is_base_of<Type, T> >::type> {
- static const T *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_Type)
- return dyn_cast<T>(*reinterpret_cast<Type*const*>(Storage));
- return NULL;
- }
- static DynTypedNode create(const Type &Node) {
- DynTypedNode Result;
- Result.Tag = NT_Type;
- new (Result.Storage.buffer) const Type*(&Node);
- return Result;
- }
-};
-template<> struct DynTypedNode::BaseConverter<NestedNameSpecifier, void> {
- static const NestedNameSpecifier *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_NestedNameSpecifier)
- return *reinterpret_cast<NestedNameSpecifier*const*>(Storage);
- return NULL;
- }
- static DynTypedNode create(const NestedNameSpecifier &Node) {
- DynTypedNode Result;
- Result.Tag = NT_NestedNameSpecifier;
- new (Result.Storage.buffer) const NestedNameSpecifier*(&Node);
- return Result;
- }
-};
-template<> struct DynTypedNode::BaseConverter<NestedNameSpecifierLoc, void> {
- static const NestedNameSpecifierLoc *get(NodeTypeTag Tag,
- const char Storage[]) {
- if (Tag == NT_NestedNameSpecifierLoc)
- return reinterpret_cast<const NestedNameSpecifierLoc*>(Storage);
- return NULL;
- }
- static DynTypedNode create(const NestedNameSpecifierLoc &Node) {
- DynTypedNode Result;
- Result.Tag = NT_NestedNameSpecifierLoc;
- new (Result.Storage.buffer) NestedNameSpecifierLoc(Node);
- return Result;
- }
-};
-template<> struct DynTypedNode::BaseConverter<QualType, void> {
- static const QualType *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_QualType)
- return reinterpret_cast<const QualType*>(Storage);
- return NULL;
- }
- static DynTypedNode create(const QualType &Node) {
- DynTypedNode Result;
- Result.Tag = NT_QualType;
- new (Result.Storage.buffer) QualType(Node);
- return Result;
- }
-};
-template<> struct DynTypedNode::BaseConverter<TypeLoc, void> {
- static const TypeLoc *get(NodeTypeTag Tag, const char Storage[]) {
- if (Tag == NT_TypeLoc)
- return reinterpret_cast<const TypeLoc*>(Storage);
- return NULL;
- }
- static DynTypedNode create(const TypeLoc &Node) {
- DynTypedNode Result;
- Result.Tag = NT_TypeLoc;
- new (Result.Storage.buffer) TypeLoc(Node);
- return Result;
- }
-};
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, typename llvm::enable_if<llvm::is_base_of<
+ Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, typename llvm::enable_if<llvm::is_base_of<
+ Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, typename llvm::enable_if<llvm::is_base_of<
+ Type, T> >::type> : public DynCastPtrConverter<T, Type> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+ NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+ CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+ TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+ NestedNameSpecifierLoc,
+ void> : public ValueConverter<NestedNameSpecifierLoc> {};
+
+template <>
+struct DynTypedNode::BaseConverter<QualType,
+ void> : public ValueConverter<QualType> {};
+
+template <>
+struct DynTypedNode::BaseConverter<
+ TypeLoc, void> : public ValueConverter<TypeLoc> {};
+
// The only operation we allow on unsupported types is \c get.
// This allows to conveniently use \c DynTypedNode when having an arbitrary
// AST node that is not supported, but prevents misuse - a user cannot create
// a DynTypedNode from arbitrary types.
template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
- static const T *get(NodeTypeTag Tag, const char Storage[]) { return NULL; }
+ static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
+ return NULL;
+ }
};
inline const void *DynTypedNode::getMemoizationData() const {
- switch (Tag) {
- case NT_Decl: return BaseConverter<Decl>::get(Tag, Storage.buffer);
- case NT_Stmt: return BaseConverter<Stmt>::get(Tag, Storage.buffer);
- default: return NULL;
- };
+ if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(NodeKind)) {
+ return BaseConverter<Decl>::get(NodeKind, Storage.buffer);
+ } else if (ASTNodeKind::getFromNodeKind<Stmt>().isBaseOf(NodeKind)) {
+ return BaseConverter<Stmt>::get(NodeKind, Storage.buffer);
+ } else if (ASTNodeKind::getFromNodeKind<Type>().isBaseOf(NodeKind)) {
+ return BaseConverter<Type>::get(NodeKind, Storage.buffer);
+ } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
+ return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
+ }
+ return NULL;
}
} // end namespace ast_type_traits
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index 5a56b4d..e8be670 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -22,12 +22,21 @@
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
class ASTUnresolvedSet {
- typedef ASTVector<DeclAccessPair> DeclsTy;
+ struct DeclsTy : ASTVector<DeclAccessPair> {
+ DeclsTy() {}
+ DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {}
+
+ bool isLazy() const { return getTag(); }
+ void setLazy(bool Lazy) { setTag(Lazy); }
+ };
+
DeclsTy Decls;
ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
+ friend class LazyASTUnresolvedSet;
+
public:
ASTUnresolvedSet() {}
ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
@@ -48,7 +57,7 @@
/// Replaces the given declaration with the new one, once.
///
/// \return true if the set changed
- bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) {
+ bool replace(const NamedDecl *Old, NamedDecl *New, AccessSpecifier AS) {
for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
if (I->getDecl() == Old) {
I->set(New, AS);
@@ -58,10 +67,7 @@
return false;
}
- void erase(unsigned I) {
- Decls[I] = Decls.back();
- Decls.pop_back();
- }
+ void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
void clear() { Decls.clear(); }
@@ -79,7 +85,29 @@
DeclAccessPair &operator[](unsigned I) { return Decls[I]; }
const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
};
-
+
+/// \brief An UnresolvedSet-like class that might not have been loaded from the
+/// external AST source yet.
+class LazyASTUnresolvedSet {
+ mutable ASTUnresolvedSet Impl;
+
+ void getFromExternalSource(ASTContext &C) const;
+
+public:
+ ASTUnresolvedSet &get(ASTContext &C) const {
+ if (Impl.Decls.isLazy())
+ getFromExternalSource(C);
+ return Impl;
+ }
+
+ void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
+ void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
+ assert(Impl.empty() || Impl.Decls.isLazy());
+ Impl.Decls.setLazy(true);
+ Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS);
+ }
+};
+
} // namespace clang
#endif
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 669e50d..6db918e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -55,16 +55,24 @@
template<typename T>
class ASTVector {
- T *Begin, *End, *Capacity;
+private:
+ T *Begin, *End;
+ llvm::PointerIntPair<T*, 1, bool> Capacity;
void setEnd(T *P) { this->End = P; }
+protected:
+ // Make a tag bit available to users of this class.
+ // FIXME: This is a horrible hack.
+ bool getTag() const { return Capacity.getInt(); }
+ void setTag(bool B) { Capacity.setInt(B); }
+
public:
// Default ctor - Initialize to empty.
- ASTVector() : Begin(NULL), End(NULL), Capacity(NULL) { }
+ ASTVector() : Begin(0), End(0), Capacity(0, false) {}
- ASTVector(ASTContext &C, unsigned N)
- : Begin(NULL), End(NULL), Capacity(NULL) {
+ ASTVector(const ASTContext &C, unsigned N)
+ : Begin(0), End(0), Capacity(0, false) {
reserve(C, N);
}
@@ -155,8 +163,8 @@
return const_pointer(Begin);
}
- void push_back(const_reference Elt, ASTContext &C) {
- if (End < Capacity) {
+ void push_back(const_reference Elt, const ASTContext &C) {
+ if (End < this->capacity_ptr()) {
Retry:
new (End) T(Elt);
++End;
@@ -166,19 +174,19 @@
goto Retry;
}
- void reserve(ASTContext &C, unsigned N) {
- if (unsigned(Capacity-Begin) < N)
+ void reserve(const ASTContext &C, unsigned N) {
+ if (unsigned(this->capacity_ptr()-Begin) < N)
grow(C, N);
}
/// capacity - Return the total number of elements in the currently allocated
/// buffer.
- size_t capacity() const { return Capacity - Begin; }
+ size_t capacity() const { return this->capacity_ptr() - Begin; }
/// append - Add the specified range to the end of the SmallVector.
///
template<typename in_iter>
- void append(ASTContext &C, in_iter in_start, in_iter in_end) {
+ void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
if (NumInputs == 0)
@@ -197,7 +205,7 @@
/// append - Add the specified range to the end of the SmallVector.
///
- void append(ASTContext &C, size_type NumInputs, const T &Elt) {
+ void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
// Grow allocated space if needed.
if (NumInputs > size_type(this->capacity_ptr()-this->end()))
this->grow(C, this->size()+NumInputs);
@@ -214,13 +222,13 @@
std::uninitialized_copy(I, E, Dest);
}
- iterator insert(ASTContext &C, iterator I, const T &Elt) {
+ iterator insert(const ASTContext &C, iterator I, const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
- push_back(Elt);
+ push_back(Elt, C);
return this->end()-1;
}
- if (this->EndX < this->CapacityX) {
+ if (this->End < this->capacity_ptr()) {
Retry:
new (this->end()) T(this->back());
this->setEnd(this->end()+1);
@@ -235,7 +243,7 @@
goto Retry;
}
- iterator insert(ASTContext &C, iterator I, size_type NumToInsert,
+ iterator insert(const ASTContext &C, iterator I, size_type NumToInsert,
const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
append(C, NumToInsert, Elt);
@@ -284,7 +292,7 @@
}
template<typename ItTy>
- iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) {
+ iterator insert(const ASTContext &C, iterator I, ItTy From, ItTy To) {
if (I == this->end()) { // Important special case for empty vector.
append(C, From, To);
return this->end()-1;
@@ -335,7 +343,7 @@
return I;
}
- void resize(ASTContext &C, unsigned N, const T &NV) {
+ void resize(const ASTContext &C, unsigned N, const T &NV) {
if (N < this->size()) {
this->destroy_range(this->begin()+N, this->end());
this->setEnd(this->begin()+N);
@@ -350,7 +358,7 @@
private:
/// grow - double the size of the allocated memory, guaranteeing space for at
/// least one more element or MinSize if specified.
- void grow(ASTContext &C, size_type MinSize = 1);
+ void grow(const ASTContext &C, size_type MinSize = 1);
void construct_range(T *S, T *E, const T &Elt) {
for (; S != E; ++S)
@@ -365,13 +373,16 @@
}
protected:
- iterator capacity_ptr() { return (iterator)this->Capacity; }
+ const_iterator capacity_ptr() const {
+ return (iterator) Capacity.getPointer();
+ }
+ iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
};
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T>
-void ASTVector<T>::grow(ASTContext &C, size_t MinSize) {
- size_t CurCapacity = Capacity-Begin;
+void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
+ size_t CurCapacity = this->capacity();
size_t CurSize = size();
size_t NewCapacity = 2*CurCapacity;
if (NewCapacity < MinSize)
@@ -394,7 +405,7 @@
// ASTContext never frees any memory.
Begin = NewElts;
End = NewElts+CurSize;
- Capacity = Begin+NewCapacity;
+ Capacity.setPointer(Begin+NewCapacity);
}
} // end: clang namespace
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 27dcef2..7dbf413 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_ATTR_H
#include "clang/AST/AttrIterator.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
@@ -145,7 +146,7 @@
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
// Relies on relative order of enum emission with respect to param attrs.
- return (A->getKind() <= attr::LAST_MS_INHERITABLE &&
+ return (A->getKind() <= attr::LAST_MS_INHERITANCE &&
A->getKind() > attr::LAST_INHERITABLE_PARAM);
}
};
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 2983e04..dbe4ad0 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -287,9 +287,9 @@
// Iterate over the set of overriding virtual methods in a given
// subobject.
- typedef SmallVector<UniqueVirtualMethod, 4>::iterator
+ typedef SmallVectorImpl<UniqueVirtualMethod>::iterator
overriding_iterator;
- typedef SmallVector<UniqueVirtualMethod, 4>::const_iterator
+ typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator
overriding_const_iterator;
// Add a new overriding method for a particular subobject.
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9460757..9c699b7 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -81,7 +81,7 @@
operator QualType() const { return Stored; }
/// \brief Implicit conversion to bool.
- operator bool() const { return !isNull(); }
+ LLVM_EXPLICIT operator bool() const { return !isNull(); }
bool isNull() const {
return Stored.isNull();
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 082c672..09ff682 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -19,21 +19,20 @@
#include "llvm/Support/MathExtras.h"
namespace clang {
-
+
/// CharUnits - This is an opaque type for sizes expressed in character units.
- /// Instances of this type represent a quantity as a multiple of the size
+ /// Instances of this type represent a quantity as a multiple of the size
/// of the standard C type, char, on the target architecture. As an opaque
/// type, CharUnits protects you from accidentally combining operations on
- /// quantities in bit units and character units.
+ /// quantities in bit units and character units.
///
- /// It should be noted that characters and bytes are distinct concepts. Bytes
- /// refer to addressable units of data storage on the target machine, and
- /// characters are members of a set of elements used for the organization,
- /// control, or representation of data. According to C99, bytes are allowed
- /// to exceed characters in size, although currently, clang only supports
- /// architectures where the two are the same size.
- ///
- /// For portability, never assume that a target character is 8 bits wide. Use
+ /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned
+ /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to
+ /// the same quantity of storage. However, we use the term 'character unit'
+ /// rather than 'byte' to avoid an implication that a character unit is
+ /// exactly 8 bits.
+ ///
+ /// For portability, never assume that a target character is 8 bits wide. Use
/// CharUnit values wherever you calculate sizes, offsets, or alignments
/// in character units.
class CharUnits {
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index c02a82f..28849f5 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -699,7 +699,10 @@
unsigned ParamIndex;
public:
- enum { InvalidParamIndex = ~0U };
+ enum LLVM_ENUM_INT_TYPE(unsigned) {
+ InvalidParamIndex = ~0U,
+ VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
+ };
ParamCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd,
@@ -755,14 +758,25 @@
return ParamIndex != InvalidParamIndex;
}
+ bool isVarArgParam() const LLVM_READONLY {
+ return ParamIndex == VarArgParamIndex;
+ }
+
+ void setIsVarArgParam() {
+ ParamIndex = VarArgParamIndex;
+ assert(isParamIndexValid());
+ }
+
unsigned getParamIndex() const LLVM_READONLY {
assert(isParamIndexValid());
+ assert(!isVarArgParam());
return ParamIndex;
}
void setParamIndex(unsigned Index) {
ParamIndex = Index;
assert(isParamIndexValid());
+ assert(!isVarArgParam());
}
};
@@ -1097,10 +1111,6 @@
return ThisDeclInfo;
}
- DeclInfo *getThisDeclInfo() const LLVM_READONLY {
- return ThisDeclInfo;
- }
-
ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
};
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index d1f5209..dde7a14 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -67,6 +67,9 @@
/// a template parameter (\\tparam or an alias).
unsigned IsTParamCommand : 1;
+ /// True if this command is \\throws or an alias.
+ unsigned IsThrowsCommand : 1;
+
/// True if this command is \\deprecated or an alias.
unsigned IsDeprecatedCommand : 1;
@@ -142,6 +145,8 @@
llvm_unreachable("the command should be known");
}
+ const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const;
+
const CommandInfo *getCommandInfo(unsigned CommandID) const;
const CommandInfo *registerUnknownCommand(StringRef CommandName);
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index 8c88494..ed323da 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -15,6 +15,7 @@
bit IsReturnsCommand = 0;
bit IsParamCommand = 0;
bit IsTParamCommand = 0;
+ bit IsThrowsCommand = 0;
bit IsDeprecatedCommand = 0;
bit IsHeaderfileCommand = 0;
@@ -109,6 +110,10 @@
// HeaderDoc command for template parameter documentation.
def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; }
+def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; }
+def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; }
+def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; }
+
def Deprecated : BlockCommand<"deprecated"> {
let IsEmptyParagraphAllowed = 1;
let IsDeprecatedCommand = 1;
@@ -200,11 +205,17 @@
def Subpage : VerbatimLineCommand<"subpage">;
def Ref : VerbatimLineCommand<"ref">;
+def Relates : VerbatimLineCommand<"relates">;
+def Related : VerbatimLineCommand<"related">;
+def RelatesAlso : VerbatimLineCommand<"relatesalso">;
+def RelatedAlso : VerbatimLineCommand<"relatedalso">;
+
//===----------------------------------------------------------------------===//
// DeclarationVerbatimLineCommand
//===----------------------------------------------------------------------===//
// Doxygen commands.
+def Def : DeclarationVerbatimLineCommand<"def">;
def Fn : DeclarationVerbatimLineCommand<"fn">;
def Namespace : DeclarationVerbatimLineCommand<"namespace">;
def Overload : DeclarationVerbatimLineCommand<"overload">;
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
index 6e89410..312da06 100644
--- a/include/clang/AST/CommentDiagnostic.h
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -16,7 +16,7 @@
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
+ SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM,
#define COMMENTSTART
#include "clang/Basic/DiagnosticCommentKinds.inc"
#undef DIAG
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index d6a1072..7e00813 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -61,10 +61,8 @@
void consumeToken() {
if (MoreLATokens.empty())
L.lex(Tok);
- else {
- Tok = MoreLATokens.back();
- MoreLATokens.pop_back();
- }
+ else
+ Tok = MoreLATokens.pop_back_val();
}
void putBack(const Token &OldTok) {
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 15e454d..3910960 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -58,9 +58,6 @@
/// AST node for the \\brief command and its aliases.
const BlockCommandComment *BriefCommand;
- /// AST node for the \\returns command and its aliases.
- const BlockCommandComment *ReturnsCommand;
-
/// AST node for the \\headerfile command.
const BlockCommandComment *HeaderfileCommand;
@@ -211,7 +208,11 @@
bool isFunctionDecl();
bool isAnyFunctionDecl();
+
+ /// \returns \c true if declaration that this comment is attached to declares
+ /// a function pointer.
bool isFunctionPointerVarDecl();
+ bool isFunctionOrMethodVariadic();
bool isObjCMethodDecl();
bool isObjCPropertyDecl();
bool isTemplateOrSpecialization();
@@ -220,6 +221,8 @@
bool isUnionDecl();
bool isObjCInterfaceDecl();
bool isObjCProtocolDecl();
+ bool isClassTemplateDecl();
+ bool isFunctionTemplateDecl();
ArrayRef<const ParmVarDecl *> getParamVars();
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index a0c76c0..244a7b8 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
namespace clang {
struct ASTTemplateArgumentListInfo;
@@ -43,6 +44,7 @@
class TemplateParameterList;
class TypeLoc;
class UnresolvedSetImpl;
+class VarTemplateDecl;
/// \brief A container of type source information.
///
@@ -109,7 +111,6 @@
private:
NamedDecl *getUnderlyingDeclImpl();
- void verifyLinkage() const;
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -142,7 +143,7 @@
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
- void printName(raw_ostream &os) const { return Name.printName(os); }
+ void printName(raw_ostream &os) const { os << Name; }
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
@@ -189,10 +190,13 @@
using Decl::isModulePrivate;
using Decl::setModulePrivate;
-
+
/// \brief Determine whether this declaration is hidden from name lookup.
bool isHidden() const { return Hidden; }
-
+
+ /// \brief Set whether this declaration is hidden from name lookup.
+ void setHidden(bool Hide) { Hidden = Hide; }
+
/// \brief Determine whether this declaration is a C++ class member.
bool isCXXClassMember() const {
const DeclContext *DC = getDeclContext();
@@ -212,11 +216,24 @@
bool isCXXInstanceMember() const;
/// \brief Determine what kind of linkage this entity has.
- Linkage getLinkage() const;
+ /// This is not the linkage as defined by the standard or the codegen notion
+ /// of linkage. It is just an implementation detail that is used to compute
+ /// those.
+ Linkage getLinkageInternal() const;
+
+ /// \brief Get the linkage from a semantic point of view. Entities in
+ /// anonymous namespaces are external (in c++98).
+ Linkage getFormalLinkage() const {
+ return clang::getFormalLinkage(getLinkageInternal());
+ }
/// \brief True if this decl has external linkage.
- bool hasExternalLinkage() const {
- return getLinkage() == ExternalLinkage;
+ bool hasExternalFormalLinkage() const {
+ return isExternalFormalLinkage(getLinkageInternal());
+ }
+
+ bool isExternallyVisible() const {
+ return clang::isExternallyVisible(getLinkageInternal());
}
/// \brief Determines the visibility of this entity.
@@ -256,6 +273,13 @@
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
+ NamedDecl *getMostRecentDecl() {
+ return cast<NamedDecl>(static_cast<Decl *>(this)->getMostRecentDecl());
+ }
+ const NamedDecl *getMostRecentDecl() const {
+ return const_cast<NamedDecl*>(this)->getMostRecentDecl();
+ }
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstNamed && K <= lastNamed; }
};
@@ -351,6 +375,7 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
/// \brief Returns true if this is an anonymous namespace declaration.
///
@@ -377,7 +402,7 @@
/// \brief Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace() {
- if (isFirstDeclaration())
+ if (isFirstDecl())
return this;
return AnonOrFirstNamespaceAndInline.getPointer();
@@ -385,7 +410,7 @@
/// \brief Get the original (first) namespace declaration.
const NamespaceDecl *getOriginalNamespace() const {
- if (isFirstDeclaration())
+ if (isFirstDecl())
return this;
return AnonOrFirstNamespaceAndInline.getPointer();
@@ -394,9 +419,7 @@
/// \brief Return true if this declaration is an original (first) declaration
/// of the namespace. This is false for non-original (subsequent) namespace
/// declarations and anonymous namespaces.
- bool isOriginalNamespace() const {
- return isFirstDeclaration();
- }
+ bool isOriginalNamespace() const { return isFirstDecl(); }
/// \brief Retrieve the anonymous namespace nested inside this namespace,
/// if any.
@@ -689,11 +712,21 @@
/// \brief Whether this variable is (C++0x) constexpr.
unsigned IsConstexpr : 1;
+
+ /// \brief Whether this variable is the implicit variable for a lambda
+ /// init-capture.
+ unsigned IsInitCapture : 1;
+
+ /// \brief Whether this local extern variable's previous declaration was
+ /// declared in the same block scope. This controls whether we should merge
+ /// the type of this declaration with its previous declaration.
+ unsigned PreviousDeclInSameBlockScope : 1;
};
- enum { NumVarDeclBits = 12 };
+ enum { NumVarDeclBits = 14 };
friend class ASTDeclReader;
friend class StmtIteratorBase;
+ friend class ASTNodeImporter;
protected:
enum { NumParameterIndexBits = 8 };
@@ -732,15 +765,8 @@
};
VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass SC)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
- assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
- assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
- AllBits = 0;
- VarDeclBits.SClass = SC;
- // Everything else is implicitly initialized to false.
- }
+ SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, StorageClass SC);
typedef Redeclarable<VarDecl> redeclarable_base;
virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
@@ -757,6 +783,7 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -797,7 +824,8 @@
/// is a non-static local variable.
bool hasLocalStorage() const {
if (getStorageClass() == SC_None)
- return !isFileVarDecl();
+ // Second check is for C++11 [dcl.stc]p4.
+ return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
@@ -808,7 +836,10 @@
/// isStaticLocal - Returns true if a variable with function scope is a
/// static local variable.
bool isStaticLocal() const {
- return getStorageClass() == SC_Static && !isFileVarDecl();
+ return (getStorageClass() == SC_Static ||
+ // C++11 [dcl.stc]p4
+ (getStorageClass() == SC_None && getTSCSpec() == TSCS_thread_local))
+ && !isFileVarDecl();
}
/// \brief Returns true if a variable has extern or __private_extern__
@@ -818,12 +849,19 @@
getStorageClass() == SC_PrivateExtern;
}
- /// hasGlobalStorage - Returns true for all variables that do not
- /// have local storage. This includs all global variables as well
- /// as static variables declared within a function.
+ /// \brief Returns true for all variables that do not have local storage.
+ ///
+ /// This includes all global variables as well as static variables declared
+ /// within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
- /// Compute the language linkage.
+ /// \brief Get the storage duration of this variable, per C++ [basic.stc].
+ StorageDuration getStorageDuration() const {
+ return hasLocalStorage() ? SD_Automatic :
+ getTSCSpec() ? SD_Thread : SD_Static;
+ }
+
+ /// \brief Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
/// \brief Determines whether this variable is a variable with
@@ -847,7 +885,7 @@
bool isLocalVarDecl() const {
if (getKind() != Decl::Var)
return false;
- if (const DeclContext *DC = getDeclContext())
+ if (const DeclContext *DC = getLexicalDeclContext())
return DC->getRedeclContext()->isFunctionOrMethod();
return false;
}
@@ -857,7 +895,7 @@
bool isFunctionOrMethodVarDecl() const {
if (getKind() != Decl::Var)
return false;
- const DeclContext *DC = getDeclContext()->getRedeclContext();
+ const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
}
@@ -908,10 +946,6 @@
return const_cast<VarDecl*>(this)->getActingDefinition();
}
- /// \brief Determine whether this is a tentative definition of a
- /// variable in C.
- bool isTentativeDefinitionNow() const;
-
/// \brief Get the real (not just tentative) definition for this declaration.
VarDecl *getDefinition(ASTContext &);
const VarDecl *getDefinition(ASTContext &C) const {
@@ -933,10 +967,11 @@
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
- if (getKind() != Decl::Var)
+ Kind K = getKind();
+ if (K == ParmVar || K == ImplicitParam)
return false;
- if (getDeclContext()->getRedeclContext()->isFileContext())
+ if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
return true;
if (isStaticDataMember())
@@ -1000,20 +1035,6 @@
void setInit(Expr *I);
- /// \brief Determine whether this variable is a reference that
- /// extends the lifetime of its temporary initializer.
- ///
- /// A reference extends the lifetime of its temporary initializer if
- /// it's initializer is an rvalue that would normally go out of scope
- /// at the end of the initializer (a full expression). In such cases,
- /// the reference itself takes ownership of the temporary, which will
- /// be destroyed when the reference goes out of scope. For example:
- ///
- /// \code
- /// const int &r = 1.0; // creates a temporary of type 'int'
- /// \endcode
- bool extendsLifetimeOfTemporary() const;
-
/// \brief Determine whether this variable's value can be used in a
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
@@ -1123,15 +1144,34 @@
bool isConstexpr() const { return VarDeclBits.IsConstexpr; }
void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; }
+ /// Whether this variable is the implicit variable for a lambda init-capture.
+ bool isInitCapture() const { return VarDeclBits.IsInitCapture; }
+ void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; }
+
+ /// Whether this local extern variable declaration's previous declaration
+ /// was declared in the same block scope. Only correct in C++.
+ bool isPreviousDeclInSameBlockScope() const {
+ return VarDeclBits.PreviousDeclInSameBlockScope;
+ }
+ void setPreviousDeclInSameBlockScope(bool Same) {
+ VarDeclBits.PreviousDeclInSameBlockScope = Same;
+ }
+
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
VarDecl *getInstantiatedFromStaticDataMember() const;
- /// \brief If this variable is a static data member, determine what kind of
+ /// \brief If this variable is an instantiation of a variable template or a
+ /// static data member of a class template, determine what kind of
/// template specialization or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
+ /// \brief If this variable is an instantiation of a variable template or a
+ /// static data member of a class template, determine its point of
+ /// instantiation.
+ SourceLocation getPointOfInstantiation() const;
+
/// \brief If this variable is an instantiation of a static data member of a
/// class template specialization, retrieves the member specialization
/// information.
@@ -1142,6 +1182,26 @@
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
+ /// \brief Specify that this variable is an instantiation of the
+ /// static data member VD.
+ void setInstantiationOfStaticDataMember(VarDecl *VD,
+ TemplateSpecializationKind TSK);
+
+ /// \brief Retrieves the variable template that is described by this
+ /// variable declaration.
+ ///
+ /// Every variable template is represented as a VarTemplateDecl and a
+ /// VarDecl. The former contains template properties (such as
+ /// the template parameter lists) while the latter contains the
+ /// actual description of the template's
+ /// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
+ /// VarDecl that from a VarTemplateDecl, while
+ /// getDescribedVarTemplate() retrieves the VarTemplateDecl from
+ /// a VarDecl.
+ VarTemplateDecl *getDescribedVarTemplate() const;
+
+ void setDescribedVarTemplate(VarTemplateDecl *Template);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
@@ -1314,11 +1374,7 @@
ParmVarDeclBits.HasInheritedDefaultArg = I;
}
- QualType getOriginalType() const {
- if (getTypeSourceInfo())
- return getTypeSourceInfo()->getType();
- return getType();
- }
+ QualType getOriginalType() const;
/// \brief Determine whether this parameter is actually a function
/// parameter pack.
@@ -1517,6 +1573,7 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation NLoc,
@@ -1701,6 +1758,10 @@
/// entry point into an executable program.
bool isMain() const;
+ /// \brief Determines whether this function is a MSVCRT user defined entry
+ /// point.
+ bool isMSVCRTEntryPoint() const;
+
/// \brief Determines whether this operator new or delete is one
/// of the reserved global placement operators:
/// void *operator new(size_t, void *);
@@ -1716,6 +1777,28 @@
/// This function must be an allocation or deallocation function.
bool isReservedGlobalPlacementOperator() const;
+ /// \brief Determines whether this function is one of the replaceable
+ /// global allocation functions:
+ /// void *operator new(size_t);
+ /// void *operator new(size_t, const std::nothrow_t &) noexcept;
+ /// void *operator new[](size_t);
+ /// void *operator new[](size_t, const std::nothrow_t &) noexcept;
+ /// void operator delete(void *) noexcept;
+ /// void operator delete(void *, std::size_t) noexcept; [C++1y]
+ /// void operator delete(void *, const std::nothrow_t &) noexcept;
+ /// void operator delete[](void *) noexcept;
+ /// void operator delete[](void *, std::size_t) noexcept; [C++1y]
+ /// void operator delete[](void *, const std::nothrow_t &) noexcept;
+ /// These functions have special behavior under C++1y [expr.new]:
+ /// An implementation is allowed to omit a call to a replaceable global
+ /// allocation function. [...]
+ bool isReplaceableGlobalAllocationFunction() const;
+
+ /// \brief Determine whether this function is a sized global deallocation
+ /// function in C++1y. If so, find and return the corresponding unsized
+ /// deallocation function.
+ FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const;
+
/// Compute the language linkage.
LanguageLinkage getLanguageLinkage() const;
@@ -2039,7 +2122,7 @@
/// FieldDecl - An instance of this class is created by Sema::ActOnField to
/// represent a member of a struct/union/class.
-class FieldDecl : public DeclaratorDecl {
+class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
// FIXME: This can be packed into the bitfields in Decl.
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
@@ -2153,6 +2236,10 @@
SourceRange getSourceRange() const LLVM_READONLY;
+ /// Retrieves the canonical declaration of this field.
+ FieldDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
@@ -2165,7 +2252,7 @@
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ValueDecl {
+class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
Stmt *Init; // an integer constant expression
llvm::APSInt Val; // The value.
protected:
@@ -2191,6 +2278,10 @@
SourceRange getSourceRange() const LLVM_READONLY;
+ /// Retrieves the canonical declaration of this enumerator.
+ EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == EnumConstant; }
@@ -2289,14 +2380,14 @@
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
virtual void anchor();
- /// UnderlyingType - This is the type the typedef is set to.
- TypeSourceInfo *TInfo;
+ typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
+ llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
protected:
TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
TypeSourceInfo *TInfo)
- : TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {}
+ : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
virtual TypedefNameDecl *getNextRedeclaration() {
@@ -2315,25 +2406,30 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
+
+ bool isModed() const { return MaybeModedTInfo.is<ModedTInfo*>(); }
TypeSourceInfo *getTypeSourceInfo() const {
- return TInfo;
+ return isModed()
+ ? MaybeModedTInfo.get<ModedTInfo*>()->first
+ : MaybeModedTInfo.get<TypeSourceInfo*>();
+ }
+ QualType getUnderlyingType() const {
+ return isModed()
+ ? MaybeModedTInfo.get<ModedTInfo*>()->second
+ : MaybeModedTInfo.get<TypeSourceInfo*>()->getType();
+ }
+ void setTypeSourceInfo(TypeSourceInfo *newType) {
+ MaybeModedTInfo = newType;
+ }
+ void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) {
+ MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy);
}
/// Retrieves the canonical declaration of this typedef-name.
- TypedefNameDecl *getCanonicalDecl() {
- return getFirstDeclaration();
- }
- const TypedefNameDecl *getCanonicalDecl() const {
- return getFirstDeclaration();
- }
-
- QualType getUnderlyingType() const {
- return TInfo->getType();
- }
- void setTypeSourceInfo(TypeSourceInfo *newType) {
- TInfo = newType;
- }
+ TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2436,6 +2532,9 @@
/// This option is only enabled when modules are enabled.
bool MayHaveOutOfDateDef : 1;
+ /// Has the full definition of this type been required by a use somewhere in
+ /// the TU.
+ bool IsCompleteDefinitionRequired : 1;
private:
SourceLocation RBraceLoc;
@@ -2443,33 +2542,33 @@
// to be used for the (uncommon) case of out-of-line declarations.
typedef QualifierInfo ExtInfo;
- /// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name
+ /// \brief If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
/// otherwise, if the tag declaration is anonymous and it is part of
/// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
+ /// otherwise, if the tag declaration is anonymous and it is used as a
+ /// declaration specifier for variables, it points to the first VarDecl (used
+ /// for mangling);
/// otherwise, it is a null (TypedefNameDecl) pointer.
- llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier;
+ llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier;
- bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); }
- ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); }
+ bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); }
+ ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); }
const ExtInfo *getExtInfo() const {
- return TypedefNameDeclOrQualifier.get<ExtInfo*>();
+ return NamedDeclOrQualifier.get<ExtInfo *>();
}
protected:
- TagDecl(Kind DK, TagKind TK, DeclContext *DC,
- SourceLocation L, IdentifierInfo *Id,
- TagDecl *PrevDecl, SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK),
- TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) {
+ TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
+ IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL)
+ : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK),
+ IsCompleteDefinition(false), IsBeingDefined(false),
+ IsEmbeddedInDeclarator(false), IsFreeStanding(false),
+ IsCompleteDefinitionRequired(false),
+ NamedDeclOrQualifier((NamedDecl *)0) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
- TagDeclKind = TK;
- IsCompleteDefinition = false;
- IsBeingDefined = false;
- IsEmbeddedInDeclarator = false;
- IsFreeStanding = false;
- setPreviousDeclaration(PrevDecl);
+ setPreviousDecl(PrevDecl);
}
typedef Redeclarable<TagDecl> redeclarable_base;
@@ -2492,6 +2591,7 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
@@ -2522,6 +2622,12 @@
return IsCompleteDefinition;
}
+ /// \brief Return true if this complete decl is
+ /// required to be complete for some existing use.
+ bool isCompleteDefinitionRequired() const {
+ return IsCompleteDefinitionRequired;
+ }
+
/// isBeingDefined - Return true if this decl is currently being defined.
bool isBeingDefined() const {
return IsBeingDefined;
@@ -2563,6 +2669,10 @@
void setCompleteDefinition(bool V) { IsCompleteDefinition = V; }
+ void setCompleteDefinitionRequired(bool V = true) {
+ IsCompleteDefinitionRequired = V;
+ }
+
// FIXME: Return StringRef;
const char *getKindName() const {
return TypeWithKeyword::getTagTypeKindName(getTagKind());
@@ -2599,10 +2709,21 @@
return (getDeclName() || getTypedefNameForAnonDecl());
}
- TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? 0 :
- TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
+ bool hasDeclaratorForAnonDecl() const {
+ return dyn_cast_or_null<DeclaratorDecl>(
+ NamedDeclOrQualifier.get<NamedDecl *>());
}
+ DeclaratorDecl *getDeclaratorForAnonDecl() const {
+ return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>(
+ NamedDeclOrQualifier.get<NamedDecl *>());
+ }
+
+ TypedefNameDecl *getTypedefNameForAnonDecl() const {
+ return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>(
+ NamedDeclOrQualifier.get<NamedDecl *>());
+ }
+
+ void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; }
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
@@ -2702,21 +2823,22 @@
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
const EnumDecl *getCanonicalDecl() const {
- return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ return const_cast<EnumDecl*>(this)->getCanonicalDecl();
}
- const EnumDecl *getPreviousDecl() const {
- return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl());
- }
EnumDecl *getPreviousDecl() {
- return cast_or_null<EnumDecl>(TagDecl::getPreviousDecl());
+ return cast_or_null<EnumDecl>(
+ static_cast<TagDecl *>(this)->getPreviousDecl());
+ }
+ const EnumDecl *getPreviousDecl() const {
+ return const_cast<EnumDecl*>(this)->getPreviousDecl();
}
- const EnumDecl *getMostRecentDecl() const {
- return cast<EnumDecl>(TagDecl::getMostRecentDecl());
- }
EnumDecl *getMostRecentDecl() {
- return cast<EnumDecl>(TagDecl::getMostRecentDecl());
+ return cast<EnumDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
+ }
+ const EnumDecl *getMostRecentDecl() const {
+ return const_cast<EnumDecl*>(this)->getMostRecentDecl();
}
EnumDecl *getDefinition() const {
@@ -2912,18 +3034,19 @@
IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
- const RecordDecl *getPreviousDecl() const {
- return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl());
- }
RecordDecl *getPreviousDecl() {
- return cast_or_null<RecordDecl>(TagDecl::getPreviousDecl());
+ return cast_or_null<RecordDecl>(
+ static_cast<TagDecl *>(this)->getPreviousDecl());
+ }
+ const RecordDecl *getPreviousDecl() const {
+ return const_cast<RecordDecl*>(this)->getPreviousDecl();
}
- const RecordDecl *getMostRecentDecl() const {
- return cast<RecordDecl>(TagDecl::getMostRecentDecl());
- }
RecordDecl *getMostRecentDecl() {
- return cast<RecordDecl>(TagDecl::getMostRecentDecl());
+ return cast<RecordDecl>(static_cast<TagDecl *>(this)->getMostRecentDecl());
+ }
+ const RecordDecl *getMostRecentDecl() const {
+ return const_cast<RecordDecl*>(this)->getMostRecentDecl();
}
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
@@ -3106,13 +3229,17 @@
Capture *Captures;
unsigned NumCaptures;
+ unsigned ManglingNumber;
+ Decl *ManglingContextDecl;
+
protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block),
IsVariadic(false), CapturesCXXThis(false),
BlockMissingReturnType(true), IsConversionFromLambda(false),
ParamInfo(0), NumParams(0), Body(0),
- SignatureAsWritten(0), Captures(0), NumCaptures(0) {}
+ SignatureAsWritten(0), Captures(0), NumCaptures(0),
+ ManglingNumber(0), ManglingContextDecl(0) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3182,6 +3309,18 @@
const Capture *end,
bool capturesCXXThis);
+ unsigned getBlockManglingNumber() const {
+ return ManglingNumber;
+ }
+ Decl *getBlockManglingContextDecl() const {
+ return ManglingContextDecl;
+ }
+
+ void setBlockMangling(unsigned Number, Decl *Ctx) {
+ ManglingNumber = Number;
+ ManglingContextDecl = Ctx;
+ }
+
virtual SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
@@ -3354,7 +3493,7 @@
}
template<typename decl_type>
-void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
+void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Note: This routine is implemented here because we need both NamedDecl
// and Redeclarable to be defined.
@@ -3364,10 +3503,16 @@
// Point to previous. Make sure that this is actually the most recent
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
- First = PrevDecl->getFirstDeclaration();
+ First = PrevDecl->getFirstDecl();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
decl_type *MostRecent = First->RedeclLink.getNext();
RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
+
+ // If the declaration was previously visible, a redeclaration of it remains
+ // visible even if it wouldn't be visible by itself.
+ static_cast<decl_type*>(this)->IdentifierNamespace |=
+ MostRecent->getIdentifierNamespace() &
+ (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
} else {
// Make this first.
First = static_cast<decl_type*>(this);
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
index 5731308..3c5056c 100644
--- a/include/clang/AST/DeclAccessPair.h
+++ b/include/clang/AST/DeclAccessPair.h
@@ -28,7 +28,7 @@
/// A POD class for pairing a NamedDecl* with an access specifier.
/// Can be put into unions.
class DeclAccessPair {
- NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+ uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
enum { Mask = 0x3 };
@@ -40,10 +40,10 @@
}
NamedDecl *getDecl() const {
- return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+ return reinterpret_cast<NamedDecl*>(~Mask & Ptr);
}
AccessSpecifier getAccess() const {
- return AccessSpecifier(Mask & (uintptr_t) Ptr);
+ return AccessSpecifier(Mask & Ptr);
}
void setDecl(NamedDecl *D) {
@@ -53,8 +53,7 @@
set(getDecl(), AS);
}
void set(NamedDecl *D, AccessSpecifier AS) {
- Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
- reinterpret_cast<uintptr_t>(D));
+ Ptr = uintptr_t(AS) | reinterpret_cast<uintptr_t>(D);
}
operator NamedDecl*() const { return getDecl(); }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 754facf..26eea64 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -16,6 +16,7 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
@@ -31,6 +32,7 @@
class DependentDiagnostic;
class EnumDecl;
class FunctionDecl;
+class LinkageComputer;
class LinkageSpecDecl;
class Module;
class NamedDecl;
@@ -157,7 +159,12 @@
/// This declaration is a C++ operator declared in a non-class
/// context. All such operators are also in IDNS_Ordinary.
/// C++ lexical operator lookup looks for these.
- IDNS_NonMemberOperator = 0x0400
+ IDNS_NonMemberOperator = 0x0400,
+
+ /// This declaration is a function-local extern declaration of a
+ /// variable or function. This may also be IDNS_Ordinary if it
+ /// has been declared outside any function.
+ IDNS_LocalExtern = 0x0800
};
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
@@ -284,19 +291,16 @@
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 12;
- /// \brief Whether the \c CachedLinkage field is active.
- ///
- /// This field is only valid for NamedDecls subclasses.
- mutable unsigned HasCachedLinkage : 1;
-
- /// \brief If \c HasCachedLinkage, the linkage of this declaration.
- ///
- /// This field is only valid for NamedDecls subclasses.
- mutable unsigned CachedLinkage : 2;
+ /// \brief If 0, we have not computed the linkage of this declaration.
+ /// Otherwise, it is the linkage + 1.
+ mutable unsigned CacheValidAndLinkage : 3;
friend class ASTDeclWriter;
friend class ASTDeclReader;
friend class ASTReader;
+ friend class LinkageComputer;
+
+ template<typename decl_type> friend class Redeclarable;
private:
void CheckAccessDeclContext() const;
@@ -309,7 +313,7 @@
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), FromASTFile(0), Hidden(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- HasCachedLinkage(0)
+ CacheValidAndLinkage(0)
{
if (StatisticsEnabled) add(DK);
}
@@ -319,7 +323,7 @@
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), FromASTFile(0), Hidden(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- HasCachedLinkage(0)
+ CacheValidAndLinkage(0)
{
if (StatisticsEnabled) add(DK);
}
@@ -341,6 +345,18 @@
/// \brief Update a potentially out-of-date declaration.
void updateOutOfDate(IdentifierInfo &II) const;
+ Linkage getCachedLinkage() const {
+ return Linkage(CacheValidAndLinkage - 1);
+ }
+
+ void setCachedLinkage(Linkage L) const {
+ CacheValidAndLinkage = L + 1;
+ }
+
+ bool hasCachedLinkage() const {
+ return CacheValidAndLinkage;
+ }
+
public:
/// \brief Source range that this declaration covers.
@@ -419,7 +435,6 @@
return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
}
const AttrVec &getAttrs() const;
- void swapAttrs(Decl *D);
void dropAttrs();
void addAttr(Attr *A) {
@@ -490,7 +505,16 @@
/// whether the function is used.
bool isUsed(bool CheckUsedAttr = true) const;
- void setUsed(bool U = true) { Used = U; }
+ /// \brief Set whether the declaration is used, in the sense of odr-use.
+ ///
+ /// This should only be used immediately after creating a declaration.
+ void setIsUsed() { Used = true; }
+
+ /// \brief Mark the declaration used, in the sense of odr-use.
+ ///
+ /// This notifies any mutation listeners in addition to setting a bit
+ /// indicating the declaration is used.
+ void markUsed(ASTContext &C);
/// \brief Whether this declaration was referenced.
bool isReferenced() const;
@@ -513,13 +537,13 @@
NextInContextAndBits.setInt(Bits);
}
-protected:
/// \brief Whether this declaration was marked as being private to the
/// module in which it was defined.
- bool isModulePrivate() const {
+ bool isModulePrivate() const {
return NextInContextAndBits.getInt() & ModulePrivateFlag;
}
-
+
+protected:
/// \brief Specify whether this declaration was marked as being private
/// to the module in which it was defined.
void setModulePrivate(bool MP = true) {
@@ -761,7 +785,12 @@
const Decl *getPreviousDecl() const {
return const_cast<Decl *>(this)->getPreviousDeclImpl();
}
-
+
+ /// \brief True if this is the first declaration in its redeclaration chain.
+ bool isFirstDecl() const {
+ return getPreviousDecl() == 0;
+ }
+
/// \brief Retrieve the most recent declaration that declares the same entity
/// as this declaration (which may be this declaration).
Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
@@ -777,8 +806,10 @@
/// top-level Stmt* of that body. Otherwise this method returns null.
virtual Stmt* getBody() const { return 0; }
- /// \brief Returns true if this Decl represents a declaration for a body of
+ /// \brief Returns true if this \c Decl represents a declaration for a body of
/// code, such as a function or method definition.
+ /// Note that \c hasBody can also return true if any redeclaration of this
+ /// \c Decl represents a declaration for a body of code.
virtual bool hasBody() const { return getBody() != 0; }
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
@@ -808,37 +839,71 @@
bool isFunctionOrFunctionTemplate() const;
/// \brief Changes the namespace of this declaration to reflect that it's
+ /// a function-local extern declaration.
+ ///
+ /// These declarations appear in the lexical context of the extern
+ /// declaration, but in the semantic context of the enclosing namespace
+ /// scope.
+ void setLocalExternDecl() {
+ assert((IdentifierNamespace == IDNS_Ordinary ||
+ IdentifierNamespace == IDNS_OrdinaryFriend) &&
+ "namespace is not ordinary");
+
+ Decl *Prev = getPreviousDecl();
+ IdentifierNamespace &= ~IDNS_Ordinary;
+
+ IdentifierNamespace |= IDNS_LocalExtern;
+ if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
+ IdentifierNamespace |= IDNS_Ordinary;
+ }
+
+ /// \brief Determine whether this is a block-scope declaration with linkage.
+ /// This will either be a local variable declaration declared 'extern', or a
+ /// local function declaration.
+ bool isLocalExternDecl() {
+ return IdentifierNamespace & IDNS_LocalExtern;
+ }
+
+ /// \brief Changes the namespace of this declaration to reflect that it's
/// the object of a friend declaration.
///
/// These declarations appear in the lexical context of the friending
/// class, but in the semantic context of the actual entity. This property
/// applies only to a specific decl object; other redeclarations of the
/// same entity may not (and probably don't) share this property.
- void setObjectOfFriendDecl(bool PreviouslyDeclared) {
+ void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
unsigned OldNS = IdentifierNamespace;
assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
- IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ IDNS_TagFriend | IDNS_OrdinaryFriend |
+ IDNS_LocalExtern)) &&
"namespace includes neither ordinary nor tag");
assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
- IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ IDNS_TagFriend | IDNS_OrdinaryFriend |
+ IDNS_LocalExtern)) &&
"namespace includes other than ordinary or tag");
- IdentifierNamespace = 0;
+ Decl *Prev = getPreviousDecl();
+ IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
+
if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
IdentifierNamespace |= IDNS_TagFriend;
- if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type;
+ if (PerformFriendInjection ||
+ (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
+ IdentifierNamespace |= IDNS_Tag | IDNS_Type;
}
- if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
+ if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {
IdentifierNamespace |= IDNS_OrdinaryFriend;
- if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary;
+ if (PerformFriendInjection ||
+ (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
+ IdentifierNamespace |= IDNS_Ordinary;
}
}
enum FriendObjectKind {
- FOK_None, // not a friend object
- FOK_Declared, // a friend of a previously-declared entity
- FOK_Undeclared // a friend of a previously-undeclared entity
+ FOK_None, ///< Not a friend object.
+ FOK_Declared, ///< A friend of a previously-declared entity.
+ FOK_Undeclared ///< A friend of a previously-undeclared entity.
};
/// \brief Determines whether this declaration is the object of a
@@ -846,11 +911,11 @@
///
/// There is currently no direct way to find the associated FriendDecl.
FriendObjectKind getFriendObjectKind() const {
- unsigned mask
- = (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
+ unsigned mask =
+ (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
if (!mask) return FOK_None;
- return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ?
- FOK_Declared : FOK_Undeclared);
+ return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared
+ : FOK_Undeclared);
}
/// Specifies that this declaration is a C++ overloaded non-member.
@@ -877,9 +942,6 @@
// Same as dump(), but forces color printing.
LLVM_ATTRIBUTE_USED void dumpColor() const;
void dump(raw_ostream &Out) const;
- // Debuggers don't usually respect default arguments.
- LLVM_ATTRIBUTE_USED void dumpXML() const;
- void dumpXML(raw_ostream &OS) const;
private:
void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
@@ -974,6 +1036,7 @@
mutable Decl *LastDecl;
friend class ExternalASTSource;
+ friend class ASTDeclReader;
friend class ASTWriter;
/// \brief Build up a chain of declarations.
@@ -1096,6 +1159,14 @@
/// C++0x scoped enums), and C++ linkage specifications.
bool isTransparentContext() const;
+ /// \brief Determines whether this context or some of its ancestors is a
+ /// linkage specification context that specifies C linkage.
+ bool isExternCContext() const;
+
+ /// \brief Determines whether this context or some of its ancestors is a
+ /// linkage specification context that specifies C++ linkage.
+ bool isExternCXXContext() const;
+
/// \brief Determine whether this declaration context is equivalent
/// to the declaration context DC.
bool Equals(const DeclContext *DC) const {
@@ -1429,12 +1500,20 @@
return const_cast<DeclContext*>(this)->lookup(Name);
}
+ /// \brief Find the declarations with the given name that are visible
+ /// within this context; don't attempt to retrieve anything from an
+ /// external source.
+ lookup_result noload_lookup(DeclarationName Name);
+
/// \brief A simplistic name lookup mechanism that performs name lookup
/// into this declaration context without consulting the external source.
///
/// This function should almost never be used, because it subverts the
/// usual relationship between a DeclContext and the external source.
/// See the ASTImporter for the (few, but important) use cases.
+ ///
+ /// FIXME: This is very inefficient; replace uses of it with uses of
+ /// noload_lookup.
void localUncachedLookup(DeclarationName Name,
SmallVectorImpl<NamedDecl *> &Results);
@@ -1458,10 +1537,16 @@
/// of looking up every possible name.
class all_lookups_iterator;
+ /// \brief Iterators over all possible lookups within this context.
all_lookups_iterator lookups_begin() const;
-
all_lookups_iterator lookups_end() const;
+ /// \brief Iterators over all possible lookups within this context that are
+ /// currently loaded; don't attempt to retrieve anything from an external
+ /// source.
+ all_lookups_iterator noload_lookups_begin() const;
+ all_lookups_iterator noload_lookups_end() const;
+
/// udir_iterator - Iterates through the using-directives stored
/// within this context.
typedef UsingDirectiveDecl * const * udir_iterator;
@@ -1532,6 +1617,8 @@
static bool classof(const DeclContext *D) { return true; }
LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
+ LLVM_ATTRIBUTE_USED void dumpLookups() const;
+ LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const;
private:
void reconcileExternalVisibleStorage();
@@ -1548,6 +1635,8 @@
friend class DependentDiagnostic;
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+ template<decl_iterator (DeclContext::*Begin)() const,
+ decl_iterator (DeclContext::*End)() const>
void buildLookupImpl(DeclContext *DCtx);
void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
bool Rediscoverable);
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index c483dde..dbc4132 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the C++ Decl subclasses, other than those for
-// templates (in DeclTemplate.h) and friends (in DeclFriend.h).
-//
+///
+/// \file
+/// \brief Defines the C++ Decl subclasses, other than those for templates
+/// (found in DeclTemplate.h) and friends (in DeclFriend.h).
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_DECLCXX_H
@@ -88,7 +89,7 @@
namespace clang {
-/// @brief Represents an access specifier followed by colon ':'.
+/// \brief Represents an access specifier followed by colon ':'.
///
/// An objects of this class represents sugar for the syntactic occurrence
/// of an access specifier followed by a colon in the list of member
@@ -146,16 +147,16 @@
/// level of access (public, protected, private) is used for the
/// derivation. For example:
///
-/// @code
+/// \code
/// class A { };
/// class B { };
/// class C : public virtual A, protected B { };
-/// @endcode
+/// \endcode
///
/// In this code, C will have two CXXBaseSpecifiers, one for "public
/// virtual A" and the other for "protected B".
class CXXBaseSpecifier {
- /// Range - The source code range that covers the full base
+ /// \brief The source code range that covers the full base
/// specifier, including the "virtual" (if present) and access
/// specifier (if present).
SourceRange Range;
@@ -167,25 +168,26 @@
/// \brief Whether this is a virtual base class or not.
bool Virtual : 1;
- /// BaseOfClass - Whether this is the base of a class (true) or of a
- /// struct (false). This determines the mapping from the access
- /// specifier as written in the source code to the access specifier
- /// used for semantic analysis.
+ /// \brief Whether this is the base of a class (true) or of a struct (false).
+ ///
+ /// This determines the mapping from the access specifier as written in the
+ /// source code to the access specifier used for semantic analysis.
bool BaseOfClass : 1;
- /// Access - Access specifier as written in the source code (which
- /// may be AS_none). The actual type of data stored here is an
- /// AccessSpecifier, but we use "unsigned" here to work around a
- /// VC++ bug.
+ /// \brief Access specifier as written in the source code (may be AS_none).
+ ///
+ /// The actual type of data stored here is an AccessSpecifier, but we use
+ /// "unsigned" here to work around a VC++ bug.
unsigned Access : 2;
- /// InheritConstructors - Whether the class contains a using declaration
+ /// \brief Whether the class contains a using declaration
/// to inherit the named class's constructors.
bool InheritConstructors : 1;
- /// BaseTypeInfo - The type of the base class. This will be a class or struct
- /// (or a typedef of such). The source code range does not include the
- /// "virtual" or access specifier.
+ /// \brief The type of the base class.
+ ///
+ /// This will be a class or struct (or a typedef of such). The source code
+ /// range does not include the \c virtual or the access specifier.
TypeSourceInfo *BaseTypeInfo;
public:
@@ -196,14 +198,12 @@
: Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
- /// getSourceRange - Retrieves the source range that contains the
- /// entire base specifier.
+ /// \brief Retrieves the source range that contains the entire base specifier.
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
- /// isVirtual - Determines whether the base class is a virtual base
- /// class (or not).
+ /// \brief Determines whether the base class is a virtual base class (or not).
bool isVirtual() const { return Virtual; }
/// \brief Determine whether this base class is a base of a class declared
@@ -226,11 +226,11 @@
return EllipsisLoc;
}
- /// getAccessSpecifier - Returns the access specifier for this base
- /// specifier. This is the actual base specifier as used for
- /// semantic analysis, so the result can never be AS_none. To
- /// retrieve the access specifier as written in the source code, use
- /// getAccessSpecifierAsWritten().
+ /// \brief Returns the access specifier for this base specifier.
+ ///
+ /// This is the actual base specifier as used for semantic analysis, so
+ /// the result can never be AS_none. To retrieve the access specifier as
+ /// written in the source code, use getAccessSpecifierAsWritten().
AccessSpecifier getAccessSpecifier() const {
if ((AccessSpecifier)Access == AS_none)
return BaseOfClass? AS_private : AS_public;
@@ -238,19 +238,23 @@
return (AccessSpecifier)Access;
}
- /// getAccessSpecifierAsWritten - Retrieves the access specifier as
- /// written in the source code (which may mean that no access
- /// specifier was explicitly written). Use getAccessSpecifier() to
- /// retrieve the access specifier for use in semantic analysis.
+ /// \brief Retrieves the access specifier as written in the source code
+ /// (which may mean that no access specifier was explicitly written).
+ ///
+ /// Use getAccessSpecifier() to retrieve the access specifier for use in
+ /// semantic analysis.
AccessSpecifier getAccessSpecifierAsWritten() const {
return (AccessSpecifier)Access;
}
- /// getType - Retrieves the type of the base class. This type will
- /// always be an unqualified class type.
- QualType getType() const { return BaseTypeInfo->getType(); }
+ /// \brief Retrieves the type of the base class.
+ ///
+ /// This type will always be an unqualified class type.
+ QualType getType() const {
+ return BaseTypeInfo->getType().getUnqualifiedType();
+ }
- /// getTypeLoc - Retrieves the type and source location of the base class.
+ /// \brief Retrieves the type and source location of the base class.
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
@@ -264,7 +268,8 @@
MSIM_Unspecified
};
-/// CXXRecordDecl - Represents a C++ struct/union/class.
+/// \brief Represents a C++ struct/union/class.
+///
/// FIXME: This class will disappear once we've properly taught RecordDecl
/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
@@ -288,32 +293,32 @@
/// \brief True if this class has any user-declared constructors.
bool UserDeclaredConstructor : 1;
- /// The user-declared special members which this class has.
+ /// \brief The user-declared special members which this class has.
unsigned UserDeclaredSpecialMembers : 6;
- /// Aggregate - True when this class is an aggregate.
+ /// \brief True when this class is an aggregate.
bool Aggregate : 1;
- /// PlainOldData - True when this class is a POD-type.
+ /// \brief True when this class is a POD-type.
bool PlainOldData : 1;
- /// Empty - true when this class is empty for traits purposes,
+ /// true when this class is empty for traits purposes,
/// i.e. has no data members other than 0-width bit-fields, has no
/// virtual function/base, and doesn't inherit from a non-empty
/// class. Doesn't take union-ness into account.
bool Empty : 1;
- /// Polymorphic - True when this class is polymorphic, i.e. has at
+ /// \brief True when this class is polymorphic, i.e., has at
/// least one virtual member or derives from a polymorphic class.
bool Polymorphic : 1;
- /// Abstract - True when this class is abstract, i.e. has at least
+ /// \brief True when this class is abstract, i.e., has at least
/// one pure virtual function, (that can come from a base class).
bool Abstract : 1;
- /// IsStandardLayout - True when this class has standard layout.
+ /// \brief True when this class has standard layout.
///
- /// C++0x [class]p7. A standard-layout class is a class that:
+ /// C++11 [class]p7. A standard-layout class is a class that:
/// * has no non-static data members of type non-standard-layout class (or
/// array of such types) or reference,
/// * has no virtual functions (10.3) and no virtual base classes (10.1),
@@ -327,20 +332,19 @@
/// member.
bool IsStandardLayout : 1;
- /// HasNoNonEmptyBases - True when there are no non-empty base classes.
+ /// \brief True when there are no non-empty base classes.
///
/// This is a helper bit of state used to implement IsStandardLayout more
/// efficiently.
bool HasNoNonEmptyBases : 1;
- /// HasPrivateFields - True when there are private non-static data members.
+ /// \brief True when there are private non-static data members.
bool HasPrivateFields : 1;
- /// HasProtectedFields - True when there are protected non-static data
- /// members.
+ /// \brief True when there are protected non-static data members.
bool HasProtectedFields : 1;
- /// HasPublicFields - True when there are private non-static data members.
+ /// \brief True when there are private non-static data members.
bool HasPublicFields : 1;
/// \brief True if this class (or any subobject) has mutable fields.
@@ -353,8 +357,10 @@
bool HasInClassInitializer : 1;
/// \brief True if any field is of reference type, and does not have an
- /// in-class initializer. In this case, value-initialization of this class
- /// is illegal in C++98 even if the class has a trivial default constructor.
+ /// in-class initializer.
+ ///
+ /// In this case, value-initialization of this class is illegal in C++98
+ /// even if the class has a trivial default constructor.
bool HasUninitializedReferenceMember : 1;
/// \brief These flags are \c true if a defaulted corresponding special
@@ -389,30 +395,29 @@
/// members which have not yet been declared.
unsigned DeclaredNonTrivialSpecialMembers : 6;
- /// HasIrrelevantDestructor - True when this class has a destructor with no
- /// semantic effect.
+ /// \brief True when this class has a destructor with no semantic effect.
bool HasIrrelevantDestructor : 1;
- /// HasConstexprNonCopyMoveConstructor - True when this class has at least
- /// one user-declared constexpr constructor which is neither the copy nor
- /// move constructor.
+ /// \brief True when this class has at least one user-declared constexpr
+ /// constructor which is neither the copy nor move constructor.
bool HasConstexprNonCopyMoveConstructor : 1;
- /// DefaultedDefaultConstructorIsConstexpr - True if a defaulted default
- /// constructor for this class would be constexpr.
+ /// \brief True if a defaulted default constructor for this class would
+ /// be constexpr.
bool DefaultedDefaultConstructorIsConstexpr : 1;
- /// HasConstexprDefaultConstructor - True if this class has a constexpr
- /// default constructor (either user-declared or implicitly declared).
+ /// \brief True if this class has a constexpr default constructor.
+ ///
+ /// This is true for either a user-declared constexpr default constructor
+ /// or an implicitly declared constexpr default constructor..
bool HasConstexprDefaultConstructor : 1;
- /// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
- /// one non-static data member or base class of non-literal or volatile
- /// type.
+ /// \brief True when this class contains at least one non-static data
+ /// member or base class of non-literal or volatile type.
bool HasNonLiteralTypeFieldsOrBases : 1;
- /// ComputedVisibleConversions - True when visible conversion functions are
- /// already computed and are available.
+ /// \brief True when visible conversion functions are already computed
+ /// and are available.
bool ComputedVisibleConversions : 1;
/// \brief Whether we have a C++11 user-provided default constructor (not
@@ -439,50 +444,44 @@
/// const-qualified reference parameter or a non-reference parameter.
bool HasDeclaredCopyAssignmentWithConstParam : 1;
- /// \brief Whether an implicit move constructor was attempted to be declared
- /// but would have been deleted.
- bool FailedImplicitMoveConstructor : 1;
-
- /// \brief Whether an implicit move assignment operator was attempted to be
- /// declared but would have been deleted.
- bool FailedImplicitMoveAssignment : 1;
-
/// \brief Whether this class describes a C++ lambda.
bool IsLambda : 1;
- /// NumBases - The number of base class specifiers in Bases.
+ /// \brief The number of base class specifiers in Bases.
unsigned NumBases;
- /// NumVBases - The number of virtual base class specifiers in VBases.
+ /// \brief The number of virtual base class specifiers in VBases.
unsigned NumVBases;
- /// Bases - Base classes of this class.
+ /// \brief Base classes of this class.
+ ///
/// FIXME: This is wasted space for a union.
LazyCXXBaseSpecifiersPtr Bases;
- /// VBases - direct and indirect virtual base classes of this class.
+ /// \brief direct and indirect virtual base classes of this class.
LazyCXXBaseSpecifiersPtr VBases;
- /// Conversions - Overload set containing the conversion functions
- /// of this C++ class (but not its inherited conversion
- /// functions). Each of the entries in this overload set is a
- /// CXXConversionDecl.
- ASTUnresolvedSet Conversions;
+ /// \brief The conversion functions of this C++ class (but not its
+ /// inherited conversion functions).
+ ///
+ /// Each of the entries in this overload set is a CXXConversionDecl.
+ LazyASTUnresolvedSet Conversions;
- /// VisibleConversions - Overload set containing the conversion
- /// functions of this C++ class and all those inherited conversion
- /// functions that are visible in this class. Each of the entries
- /// in this overload set is a CXXConversionDecl or a
+ /// \brief The conversion functions of this C++ class and all those
+ /// inherited conversion functions that are visible in this class.
+ ///
+ /// Each of the entries in this overload set is a CXXConversionDecl or a
/// FunctionTemplateDecl.
- ASTUnresolvedSet VisibleConversions;
+ LazyASTUnresolvedSet VisibleConversions;
- /// Definition - The declaration which defines this record.
+ /// \brief The declaration which defines this record.
CXXRecordDecl *Definition;
- /// FirstFriend - The first friend declaration in this class, or
- /// null if there aren't any. This is actually currently stored
- /// in reverse order.
- FriendDecl *FirstFriend;
+ /// \brief The first friend declaration in this class, or null if there
+ /// aren't any.
+ ///
+ /// This is actually currently stored in reverse order.
+ LazyDeclPtr FirstFriend;
/// \brief Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
@@ -507,10 +506,12 @@
struct LambdaDefinitionData : public DefinitionData {
typedef LambdaExpr::Capture Capture;
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent)
- : DefinitionData(D), Dependent(Dependent), NumCaptures(0),
- NumExplicitCaptures(0), ManglingNumber(0), ContextDecl(0), Captures(0),
- MethodTyInfo(Info)
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
+ bool Dependent, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault)
+ : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
+ CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
+ ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
{
IsLambda = true;
}
@@ -522,14 +523,20 @@
/// within the default argument of a function template, because the
/// lambda will have been created with the enclosing context as its
/// declaration context, rather than function. This is an unfortunate
- /// artifact of having to parse the default arguments before
+ /// artifact of having to parse the default arguments before.
unsigned Dependent : 1;
- /// \brief The number of captures in this lambda.
- unsigned NumCaptures : 16;
+ /// \brief Whether this lambda is a generic lambda.
+ unsigned IsGenericLambda : 1;
+
+ /// \brief The Default Capture.
+ unsigned CaptureDefault : 2;
+
+ /// \brief The number of captures in this lambda is limited 2^NumCaptures.
+ unsigned NumCaptures : 15;
/// \brief The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 15;
+ unsigned NumExplicitCaptures : 13;
/// \brief The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
@@ -547,6 +554,7 @@
/// \brief The type of the call method.
TypeSourceInfo *MethodTyInfo;
+
};
struct DefinitionData &data() {
@@ -569,7 +577,7 @@
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
- /// For non-templates, this value will be NULL. For record
+ /// For non-templates, this value will be null. For record
/// declarations that describe a class template, this will be a
/// pointer to a ClassTemplateDecl. For member
/// classes of class template specializations, this will be the
@@ -597,27 +605,29 @@
friend class ASTNodeImporter;
+ /// \brief Get the head of our list of friend declarations, possibly
+ /// deserializing the friends from an external AST source.
+ FriendDecl *getFirstFriend() const;
+
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
public:
- /// base_class_iterator - Iterator that traverses the base classes
- /// of a class.
+ /// \brief Iterator that traverses the base classes of a class.
typedef CXXBaseSpecifier* base_class_iterator;
- /// base_class_const_iterator - Iterator that traverses the base
- /// classes of a class.
+ /// \brief Iterator that traverses the base classes of a class.
typedef const CXXBaseSpecifier* base_class_const_iterator;
- /// reverse_base_class_iterator = Iterator that traverses the base classes
- /// of a class in reverse order.
+ /// \brief Iterator that traverses the base classes of a class in reverse
+ /// order.
typedef std::reverse_iterator<base_class_iterator>
reverse_base_class_iterator;
- /// reverse_base_class_iterator = Iterator that traverses the base classes
- /// of a class in reverse order.
+ /// \brief Iterator that traverses the base classes of a class in reverse
+ /// order.
typedef std::reverse_iterator<base_class_const_iterator>
reverse_base_class_const_iterator;
@@ -628,18 +638,21 @@
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
- const CXXRecordDecl *getPreviousDecl() const {
- return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl());
- }
CXXRecordDecl *getPreviousDecl() {
- return cast_or_null<CXXRecordDecl>(RecordDecl::getPreviousDecl());
+ return cast_or_null<CXXRecordDecl>(
+ static_cast<RecordDecl *>(this)->getPreviousDecl());
+ }
+ const CXXRecordDecl *getPreviousDecl() const {
+ return const_cast<CXXRecordDecl*>(this)->getPreviousDecl();
+ }
+
+ CXXRecordDecl *getMostRecentDecl() {
+ return cast<CXXRecordDecl>(
+ static_cast<RecordDecl *>(this)->getMostRecentDecl());
}
const CXXRecordDecl *getMostRecentDecl() const {
- return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl());
- }
- CXXRecordDecl *getMostRecentDecl() {
- return cast_or_null<CXXRecordDecl>(RecordDecl::getMostRecentDecl());
+ return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
}
CXXRecordDecl *getDefinition() const {
@@ -655,18 +668,18 @@
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda);
+ bool DependentLambda, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
bool isDynamicClass() const {
return data().Polymorphic || data().NumVBases != 0;
}
- /// setBases - Sets the base classes of this struct or class.
+ /// \brief Sets the base classes of this struct or class.
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
- /// getNumBases - Retrieves the number of base classes of this
- /// class.
+ /// \brief Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
base_class_iterator bases_begin() { return data().getBases(); }
@@ -688,8 +701,7 @@
return reverse_base_class_const_iterator(bases_begin());
}
- /// getNumVBases - Retrieves the number of virtual base classes of this
- /// class.
+ /// \brief Retrieves the number of virtual base classes of this class.
unsigned getNumVBases() const { return data().NumVBases; }
base_class_iterator vbases_begin() { return data().getVBases(); }
@@ -720,12 +732,12 @@
/// special methods, etc.
typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
- /// method_begin - Method begin iterator. Iterates in the order the methods
+ /// \brief Method begin iterator. Iterates in the order the methods
/// were declared.
method_iterator method_begin() const {
return method_iterator(decls_begin());
}
- /// method_end - Method end iterator.
+ /// \brief Method past-the-end iterator.
method_iterator method_end() const {
return method_iterator(decls_end());
}
@@ -749,18 +761,20 @@
/// Determines whether this record has any friends.
bool hasFriends() const {
- return data().FirstFriend != 0;
+ return data().FirstFriend.isValid();
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move constructor that is not deleted.
bool hasSimpleMoveConstructor() const {
- return !hasUserDeclaredMoveConstructor() && hasMoveConstructor();
+ return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
+ !data().DefaultedMoveConstructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const {
- return !hasUserDeclaredMoveAssignment() && hasMoveAssignment();
+ return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
+ !data().DefaultedMoveAssignmentIsDeleted;
}
/// \brief \c true if we know for sure that this class has an accessible
/// destructor that is not deleted.
@@ -784,22 +798,22 @@
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor);
}
- /// hasUserDeclaredConstructor - Whether this class has any
- /// user-declared constructors. When true, a default constructor
- /// will not be implicitly declared.
+ /// \brief Determine whether this class has any user-declared constructors.
+ ///
+ /// When true, a default constructor will not be implicitly declared.
bool hasUserDeclaredConstructor() const {
return data().UserDeclaredConstructor;
}
- /// hasUserProvidedDefaultconstructor - Whether this class has a
- /// user-provided default constructor per C++0x.
+ /// \brief Whether this class has a user-provided default constructor
+ /// per C++11.
bool hasUserProvidedDefaultConstructor() const {
return data().UserProvidedDefaultConstructor;
}
- /// hasUserDeclaredCopyConstructor - Whether this class has a
- /// user-declared copy constructor. When false, a copy constructor
- /// will be implicitly declared.
+ /// \brief Determine whether this class has a user-declared copy constructor.
+ ///
+ /// When false, a copy constructor will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
return data().UserDeclaredSpecialMembers & SMF_CopyConstructor;
}
@@ -830,9 +844,11 @@
implicitCopyConstructorHasConstParam());
}
- /// hasUserDeclaredMoveOperation - Whether this class has a user-
- /// declared move constructor or assignment operator. When false, a
- /// move constructor and assignment operator may be implicitly declared.
+ /// \brief Whether this class has a user-declared move constructor or
+ /// assignment operator.
+ ///
+ /// When false, a move constructor and assignment operator may be
+ /// implicitly declared.
bool hasUserDeclaredMoveOperation() const {
return data().UserDeclaredSpecialMembers &
(SMF_MoveConstructor | SMF_MoveAssignment);
@@ -850,28 +866,23 @@
needsImplicitMoveConstructor();
}
- /// \brief Determine whether implicit move constructor generation for this
- /// class has failed before.
- bool hasFailedImplicitMoveConstructor() const {
- return data().FailedImplicitMoveConstructor;
- }
-
- /// \brief Set whether implicit move constructor generation for this class
- /// has failed before.
- void setFailedImplicitMoveConstructor(bool Failed = true) {
- data().FailedImplicitMoveConstructor = Failed;
+ /// \brief Set that we attempted to declare an implicitly move
+ /// constructor, but overload resolution failed so we deleted it.
+ void setImplicitMoveConstructorIsDeleted() {
+ assert((data().DefaultedMoveConstructorIsDeleted ||
+ needsOverloadResolutionForMoveConstructor()) &&
+ "move constructor should not be deleted");
+ data().DefaultedMoveConstructorIsDeleted = true;
}
/// \brief Determine whether this class should get an implicit move
/// constructor or if any existing special member function inhibits this.
bool needsImplicitMoveConstructor() const {
- return !hasFailedImplicitMoveConstructor() &&
- !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
+ return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveAssignment() &&
- !hasUserDeclaredDestructor() &&
- !data().DefaultedMoveConstructorIsDeleted;
+ !hasUserDeclaredDestructor();
}
/// \brief Determine whether we need to eagerly declare a defaulted move
@@ -880,9 +891,10 @@
return data().NeedOverloadResolutionForMoveConstructor;
}
- /// hasUserDeclaredCopyAssignment - Whether this class has a
- /// user-declared copy assignment operator. When false, a copy
- /// assigment operator will be implicitly declared.
+ /// \brief Determine whether this class has a user-declared copy assignment
+ /// operator.
+ ///
+ /// When false, a copy assigment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
return data().UserDeclaredSpecialMembers & SMF_CopyAssignment;
}
@@ -907,7 +919,7 @@
/// \brief Determine whether this class has a copy assignment operator with
/// a parameter type which is a reference to a const-qualified type or is not
- /// a reference..
+ /// a reference.
bool hasCopyAssignmentWithConstParam() const {
return data().HasDeclaredCopyAssignmentWithConstParam ||
(needsImplicitCopyAssignment() &&
@@ -926,29 +938,24 @@
needsImplicitMoveAssignment();
}
- /// \brief Determine whether implicit move assignment generation for this
- /// class has failed before.
- bool hasFailedImplicitMoveAssignment() const {
- return data().FailedImplicitMoveAssignment;
- }
-
- /// \brief Set whether implicit move assignment generation for this class
- /// has failed before.
- void setFailedImplicitMoveAssignment(bool Failed = true) {
- data().FailedImplicitMoveAssignment = Failed;
+ /// \brief Set that we attempted to declare an implicit move assignment
+ /// operator, but overload resolution failed so we deleted it.
+ void setImplicitMoveAssignmentIsDeleted() {
+ assert((data().DefaultedMoveAssignmentIsDeleted ||
+ needsOverloadResolutionForMoveAssignment()) &&
+ "move assignment should not be deleted");
+ data().DefaultedMoveAssignmentIsDeleted = true;
}
/// \brief Determine whether this class should get an implicit move
/// assignment operator or if any existing special member function inhibits
/// this.
bool needsImplicitMoveAssignment() const {
- return !hasFailedImplicitMoveAssignment() &&
- !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
+ return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) &&
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor() &&
- !data().DefaultedMoveAssignmentIsDeleted;
+ !hasUserDeclaredDestructor();
}
/// \brief Determine whether we need to eagerly declare a move assignment
@@ -957,9 +964,9 @@
return data().NeedOverloadResolutionForMoveAssignment;
}
- /// hasUserDeclaredDestructor - Whether this class has a
- /// user-declared destructor. When false, a destructor will be
- /// implicitly declared.
+ /// \brief Determine whether this class has a user-declared destructor.
+ ///
+ /// When false, a destructor will be implicitly declared.
bool hasUserDeclaredDestructor() const {
return data().UserDeclaredSpecialMembers & SMF_Destructor;
}
@@ -979,15 +986,42 @@
/// \brief Determine whether this class describes a lambda function object.
bool isLambda() const { return hasDefinition() && data().IsLambda; }
+ /// \brief Determine whether this class describes a generic
+ /// lambda function object (i.e. function call operator is
+ /// a template).
+ bool isGenericLambda() const;
+
+ /// \brief Retrieve the lambda call operator of the closure type
+ /// if this is a closure type.
+ CXXMethodDecl *getLambdaCallOperator() const;
+
+ /// \brief Retrieve the lambda static invoker, the address of which
+ /// is returned by the conversion operator, and the body of which
+ /// is forwarded to the lambda call operator.
+ CXXMethodDecl *getLambdaStaticInvoker() const;
+
+ /// \brief Retrieve the generic lambda's template parameter list.
+ /// Returns null if the class does not represent a lambda or a generic
+ /// lambda.
+ TemplateParameterList *getGenericLambdaTemplateParameterList() const;
+
+ LambdaCaptureDefault getLambdaCaptureDefault() const {
+ assert(isLambda());
+ return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
+ }
+
/// \brief For a closure type, retrieve the mapping from captured
- /// variables and this to the non-static data members that store the
+ /// variables and \c this to the non-static data members that store the
/// values or references of the captures.
///
/// \param Captures Will be populated with the mapping from captured
/// variables to the corresponding fields.
///
/// \param ThisCapture Will be set to the field declaration for the
- /// 'this' capture.
+ /// \c this capture.
+ ///
+ /// \note No entries will be added for init-captures, as they do not capture
+ /// variables.
void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const;
@@ -1001,10 +1035,10 @@
typedef UnresolvedSetIterator conversion_iterator;
conversion_iterator conversion_begin() const {
- return data().Conversions.begin();
+ return data().Conversions.get(getASTContext()).begin();
}
conversion_iterator conversion_end() const {
- return data().Conversions.end();
+ return data().Conversions.get(getASTContext()).end();
}
/// Removes a conversion function from this class. The conversion
@@ -1012,38 +1046,39 @@
/// this class must currently be in the process of being defined.
void removeConversion(const NamedDecl *Old);
- /// getVisibleConversionFunctions - get all conversion functions visible
- /// in current class; including conversion function templates.
+ /// \brief Get all conversion functions visible in current class,
+ /// including conversion function templates.
std::pair<conversion_iterator, conversion_iterator>
getVisibleConversionFunctions();
- /// isAggregate - Whether this class is an aggregate (C++
- /// [dcl.init.aggr]), which is a class with no user-declared
- /// constructors, no private or protected non-static data members,
- /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
+ /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]),
+ /// which is a class with no user-declared constructors, no private
+ /// or protected non-static data members, no base classes, and no virtual
+ /// functions (C++ [dcl.init.aggr]p1).
bool isAggregate() const { return data().Aggregate; }
- /// hasInClassInitializer - Whether this class has any in-class initializers
+ /// \brief Whether this class has any in-class initializers
/// for non-static data members.
bool hasInClassInitializer() const { return data().HasInClassInitializer; }
/// \brief Whether this class or any of its subobjects has any members of
- /// reference type which would make value-initialization ill-formed, per
- /// C++03 [dcl.init]p5:
- /// -- if T is a non-union class type without a user-declared constructor,
- /// then every non-static data member and base-class component of T is
- /// value-initialized
- /// [...]
- /// A program that calls for [...] value-initialization of an entity of
- /// reference type is ill-formed.
+ /// reference type which would make value-initialization ill-formed.
+ ///
+ /// Per C++03 [dcl.init]p5:
+ /// - if T is a non-union class type without a user-declared constructor,
+ /// then every non-static data member and base-class component of T is
+ /// value-initialized [...] A program that calls for [...]
+ /// value-initialization of an entity of reference type is ill-formed.
bool hasUninitializedReferenceMember() const {
return !isUnion() && !hasUserDeclaredConstructor() &&
data().HasUninitializedReferenceMember;
}
- /// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
- /// that is an aggregate that has no non-static non-POD data members, no
- /// reference data members, no user-defined copy assignment operator and no
+ /// \brief Whether this class is a POD-type (C++ [class]p4)
+ ///
+ /// For purposes of this function a class is POD if it is an aggregate
+ /// that has no non-static non-POD data members, no reference data
+ /// members, no user-defined copy assignment operator and no
/// user-defined destructor.
///
/// Note that this is the C++ TR1 definition of POD.
@@ -1053,26 +1088,33 @@
/// it contains only public fields, no bases, tag kind is not 'class', etc.
bool isCLike() const;
- /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
- /// means it has a virtual function, virtual base, data member (other than
- /// 0-width bit-field) or inherits from a non-empty class. Does NOT include
- /// a check for union-ness.
+ /// \brief Determine whether this is an empty class in the sense of
+ /// (C++11 [meta.unary.prop]).
+ ///
+ /// A non-union class is empty iff it has a virtual function, virtual base,
+ /// data member (other than 0-width bit-field) or inherits from a non-empty
+ /// class.
+ ///
+ /// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
- /// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
+ /// Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
- /// isAbstract - Whether this class is abstract (C++ [class.abstract]),
- /// which means that the class contains or inherits a pure virtual function.
+ /// \brief Determine whether this class has a pure virtual function.
+ ///
+ /// The class is is abstract per (C++ [class.abstract]p2) if it declares
+ /// a pure virtual function or inherits a pure virtual function that is
+ /// not overridden.
bool isAbstract() const { return data().Abstract; }
- /// isStandardLayout - Whether this class has standard layout
+ /// \brief Determine whether this class has standard layout per
/// (C++ [class]p7)
bool isStandardLayout() const { return data().IsStandardLayout; }
- /// \brief Whether this class, or any of its class subobjects, contains a
- /// mutable field.
+ /// \brief Determine whether this class, or any of its class subobjects,
+ /// contains a mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
/// \brief Determine whether this class has a trivial default constructor
@@ -1180,47 +1222,49 @@
return !(data().HasTrivialSpecialMembers & SMF_Destructor);
}
- // hasIrrelevantDestructor - Whether this class has a destructor which has no
- // semantic effect. Any such destructor will be trivial, public, defaulted
- // and not deleted, and will call only irrelevant destructors.
+ /// \brief Determine whether this class has a destructor which has no
+ /// semantic effect.
+ ///
+ /// Any such destructor will be trivial, public, defaulted and not deleted,
+ /// and will call only irrelevant destructors.
bool hasIrrelevantDestructor() const {
return data().HasIrrelevantDestructor;
}
- // hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal or
- // volatile type non-static data member or base class.
+ /// \brief Determine whether this class has a non-literal or/ volatile type
+ /// non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const {
return data().HasNonLiteralTypeFieldsOrBases;
}
- // isTriviallyCopyable - Whether this class is considered trivially copyable
- // (C++0x [class]p6).
+ /// \brief Determine whether this class is considered trivially copyable per
+ /// (C++11 [class]p6).
bool isTriviallyCopyable() const;
- // isTrivial - Whether this class is considered trivial
- //
- // C++0x [class]p6
- // A trivial class is a class that has a trivial default constructor and
- // is trivially copiable.
+ /// \brief Determine whether this class is considered trivial.
+ ///
+ /// C++11 [class]p6:
+ /// "A trivial class is a class that has a trivial default constructor and
+ /// is trivially copiable."
bool isTrivial() const {
return isTriviallyCopyable() && hasTrivialDefaultConstructor();
}
- // isLiteral - Whether this class is a literal type.
- //
- // C++11 [basic.types]p10
- // A class type that has all the following properties:
- // -- it has a trivial destructor
- // -- every constructor call and full-expression in the
- // brace-or-equal-intializers for non-static data members (if any) is
- // a constant expression.
- // -- it is an aggregate type or has at least one constexpr constructor or
- // constructor template that is not a copy or move constructor, and
- // -- all of its non-static data members and base classes are of literal
- // types
- //
- // We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
- // treating types with trivial default constructors as literal types.
+ /// \brief Determine whether this class is a literal type.
+ ///
+ /// C++11 [basic.types]p10:
+ /// A class type that has all the following properties:
+ /// - it has a trivial destructor
+ /// - every constructor call and full-expression in the
+ /// brace-or-equal-intializers for non-static data members (if any) is
+ /// a constant expression.
+ /// - it is an aggregate type or has at least one constexpr constructor
+ /// or constructor template that is not a copy or move constructor, and
+ /// - all of its non-static data members and base classes are of literal
+ /// types
+ ///
+ /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
+ /// treating types with trivial default constructors as literal types.
bool isLiteral() const {
return hasTrivialDestructor() &&
(isAggregate() || hasConstexprNonCopyMoveConstructor() ||
@@ -1231,15 +1275,15 @@
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
- /// This routine will return non-NULL for (non-templated) member
+ /// This routine will return non-null for (non-templated) member
/// classes of class templates. For example, given:
///
- /// @code
+ /// \code
/// template<typename T>
/// struct X {
/// struct A { };
/// };
- /// @endcode
+ /// \endcode
///
/// The declaration for X<int>::A is a (non-templated) CXXRecordDecl
/// whose parent is the class template specialization X<int>. For
@@ -1257,7 +1301,7 @@
}
/// \brief Specify that this record is an instantiation of the
- /// member class RD.
+ /// member class \p RD.
void setInstantiationOfMemberClass(CXXRecordDecl *RD,
TemplateSpecializationKind TSK);
@@ -1288,10 +1332,10 @@
/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
- /// getDestructor - Returns the destructor decl for this class.
+ /// \brief Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
- /// isLocalClass - If the class is a local class [class.local], returns
+ /// \brief If the class is a local class [class.local], returns
/// the enclosing function declaration.
const FunctionDecl *isLocalClass() const {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
@@ -1300,6 +1344,11 @@
return dyn_cast<FunctionDecl>(getDeclContext());
}
+ FunctionDecl *isLocalClass() {
+ return const_cast<FunctionDecl*>(
+ const_cast<const CXXRecordDecl*>(this)->isLocalClass());
+ }
+
/// \brief Determine whether this dependent class is a current instantiation,
/// when viewed from within the given context.
bool isCurrentInstantiation(const DeclContext *CurContext) const;
@@ -1328,7 +1377,7 @@
/// \param Paths will contain the paths taken from the current class to the
/// given \p Base class.
///
- /// \returns true if this class is derived from Base, false otherwise.
+ /// \returns true if this class is derived from \p Base, false otherwise.
///
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
@@ -1367,6 +1416,13 @@
/// The class itself does not count as a base class. This routine
/// returns false if the class has non-computable base classes.
///
+ /// \param BaseMatches Callback invoked for each (direct or indirect) base
+ /// class of this type, or if \p AllowShortCircuit is true then until a call
+ /// returns false.
+ ///
+ /// \param UserData Passed as the second argument of every call to
+ /// \p BaseMatches.
+ ///
/// \param AllowShortCircuit if false, forces the callback to be called
/// for every base class, even if a dependent or non-matching base was
/// found.
@@ -1471,12 +1527,12 @@
/// \brief Get the indirect primary bases for this class.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
- /// viewInheritance - Renders and displays an inheritance diagram
+ /// Renders and displays an inheritance diagram
/// for this C++ class and all of its base classes (transitively) using
/// GraphViz.
void viewInheritance(ASTContext& Context) const;
- /// MergeAccess - Calculates the access of a decl that is reached
+ /// \brief Calculates the access of a decl that is reached
/// along a path.
static AccessSpecifier MergeAccess(AccessSpecifier PathAccess,
AccessSpecifier DeclAccess) {
@@ -1575,8 +1631,10 @@
friend class ASTWriter;
};
-/// CXXMethodDecl - Represents a static or instance method of a
-/// struct/union/class.
+/// \brief Represents a static or instance method of a struct/union/class.
+///
+/// In the terminology of the C++ Standard, these are the (static and
+/// non-static) member functions, whether virtual or not.
class CXXMethodDecl : public FunctionDecl {
virtual void anchor();
protected:
@@ -1606,6 +1664,18 @@
bool isStatic() const;
bool isInstance() const { return !isStatic(); }
+ /// Returns true if the given operator is implicitly static in a record
+ /// context.
+ static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
+ // [class.free]p1:
+ // Any allocation function for a class T is a static member
+ // (even if not explicitly declared static).
+ // [class.free]p6 Any deallocation function for a class X is a static member
+ // (even if not explicitly declared static).
+ return OOK == OO_New || OOK == OO_Array_New || OOK == OO_Delete ||
+ OOK == OO_Array_Delete;
+ }
+
bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); }
bool isVolatile() const { return getType()->castAs<FunctionType>()->isVolatile(); }
@@ -1633,14 +1703,22 @@
/// \brief Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
- const CXXMethodDecl *getCanonicalDecl() const {
- return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
- }
CXXMethodDecl *getCanonicalDecl() {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
+ const CXXMethodDecl *getCanonicalDecl() const {
+ return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
+ }
- /// isUserProvided - True if this method is user-declared and was not
+ CXXMethodDecl *getMostRecentDecl() {
+ return cast<CXXMethodDecl>(
+ static_cast<FunctionDecl *>(this)->getMostRecentDecl());
+ }
+ const CXXMethodDecl *getMostRecentDecl() const {
+ return const_cast<CXXMethodDecl*>(this)->getMostRecentDecl();
+ }
+
+ /// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
return !(isDeleted() || getCanonicalDecl()->isDefaulted());
@@ -1655,21 +1733,22 @@
method_iterator end_overridden_methods() const;
unsigned size_overridden_methods() const;
- /// getParent - Returns the parent of this method declaration, which
+ /// Returns the parent of this method declaration, which
/// is the class in which this method is defined.
const CXXRecordDecl *getParent() const {
return cast<CXXRecordDecl>(FunctionDecl::getParent());
}
- /// getParent - Returns the parent of this method declaration, which
+ /// Returns the parent of this method declaration, which
/// is the class in which this method is defined.
CXXRecordDecl *getParent() {
return const_cast<CXXRecordDecl *>(
cast<CXXRecordDecl>(FunctionDecl::getParent()));
}
- /// getThisType - Returns the type of 'this' pointer.
- /// Should only be called for instance methods.
+ /// \brief Returns the type of the \c this pointer.
+ ///
+ /// Should only be called for instance (i.e., non-static) methods.
QualType getThisType(ASTContext &C) const;
unsigned getTypeQualifiers() const {
@@ -1702,11 +1781,11 @@
/// or clone the function call operator.
bool isLambdaStaticInvoker() const;
- /// \brief Find the method in RD that corresponds to this one.
+ /// \brief Find the method in \p RD that corresponds to this one.
///
- /// Find if RD or one of the classes it inherits from override this method.
- /// If so, return it. RD is assumed to be a subclass of the class defining
- /// this method (or be the class itself), unless MayBeBase is set to true.
+ /// Find if \p RD or one of the classes it inherits from override this method.
+ /// If so, return it. \p RD is assumed to be a subclass of the class defining
+ /// this method (or be the class itself), unless \p MayBeBase is set to true.
CXXMethodDecl *
getCorrespondingMethodInClass(const CXXRecordDecl *RD,
bool MayBeBase = false);
@@ -1725,20 +1804,21 @@
}
};
-/// CXXCtorInitializer - Represents a C++ base or member
-/// initializer, which is part of a constructor initializer that
+/// \brief Represents a C++ base or member initializer.
+///
+/// This is part of a constructor initializer that
/// initializes one non-static member variable or one base class. For
/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
/// initializers:
///
-/// @code
+/// \code
/// class A { };
/// class B : public A {
/// float f;
/// public:
/// B(A& a) : A(a), f(3.14159) { }
/// };
-/// @endcode
+/// \endcode
class CXXCtorInitializer {
/// \brief Either the base class name/delegating constructor type (stored as
/// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field
@@ -1747,7 +1827,9 @@
Initializee;
/// \brief The source location for the field name or, for a base initializer
- /// pack expansion, the location of the ellipsis. In the case of a delegating
+ /// pack expansion, the location of the ellipsis.
+ ///
+ /// In the case of a delegating
/// constructor, it will still include the type's source location as the
/// Initializee points to the CXXConstructorDecl (to allow loop detection).
SourceLocation MemberOrEllipsisLocation;
@@ -1756,29 +1838,28 @@
/// end up constructing an object (when multiple arguments are involved).
Stmt *Init;
- /// LParenLoc - Location of the left paren of the ctor-initializer.
+ /// \brief Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
- /// RParenLoc - Location of the right paren of the ctor-initializer.
+ /// \brief Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
/// \brief If the initializee is a type, whether that type makes this
/// a delegating initialization.
bool IsDelegating : 1;
- /// IsVirtual - If the initializer is a base initializer, this keeps track
+ /// \brief If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
bool IsVirtual : 1;
- /// IsWritten - Whether or not the initializer is explicitly written
+ /// \brief Whether or not the initializer is explicitly written
/// in the sources.
bool IsWritten : 1;
- /// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
- /// number keeps track of the textual order of this initializer in the
- /// original sources, counting from 0; otherwise, if IsWritten is false,
- /// it stores the number of array index variables stored after this
- /// object in memory.
+ /// If IsWritten is true, then this number keeps track of the textual order
+ /// of this initializer in the original sources, counting from 0; otherwise,
+ /// it stores the number of array index variables stored after this object
+ /// in memory.
unsigned SourceOrderOrNumArrayIndices : 13;
CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
@@ -1786,25 +1867,25 @@
SourceLocation R, VarDecl **Indices, unsigned NumIndices);
public:
- /// CXXCtorInitializer - Creates a new base-class initializer.
+ /// \brief Creates a new base-class initializer.
explicit
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
SourceLocation L, Expr *Init, SourceLocation R,
SourceLocation EllipsisLoc);
- /// CXXCtorInitializer - Creates a new member initializer.
+ /// \brief Creates a new member initializer.
explicit
CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
- /// CXXCtorInitializer - Creates a new anonymous field initializer.
+ /// \brief Creates a new anonymous field initializer.
explicit
CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
- /// CXXCtorInitializer - Creates a new delegating Initializer.
+ /// \brief Creates a new delegating initializer.
explicit
CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init, SourceLocation R);
@@ -1816,14 +1897,13 @@
Expr *Init, SourceLocation R,
VarDecl **Indices, unsigned NumIndices);
- /// isBaseInitializer - Returns true when this initializer is
- /// initializing a base class.
+ /// \brief Determine whether this initializer is initializing a base class.
bool isBaseInitializer() const {
return Initializee.is<TypeSourceInfo*>() && !IsDelegating;
}
- /// isMemberInitializer - Returns true when this initializer is
- /// initializing a non-static data member.
+ /// \brief Determine whether this initializer is initializing a non-static
+ /// data member.
bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
bool isAnyMemberInitializer() const {
@@ -1834,15 +1914,18 @@
return Initializee.is<IndirectFieldDecl*>();
}
- /// isInClassMemberInitializer - Returns true when this initializer is an
- /// implicit ctor initializer generated for a field with an initializer
- /// defined on the member declaration.
+ /// \brief Determine whether this initializer is an implicit initializer
+ /// generated for a field with an initializer defined on the member
+ /// declaration.
+ ///
+ /// In-class member initializers (also known as "non-static data member
+ /// initializations", NSDMIs) were introduced in C++11.
bool isInClassMemberInitializer() const {
return isa<CXXDefaultInitExpr>(Init);
}
- /// isDelegatingInitializer - Returns true when this initializer is creating
- /// a delegating constructor.
+ /// \brief Determine whether this initializer is creating a delegating
+ /// constructor.
bool isDelegatingInitializer() const {
return Initializee.is<TypeSourceInfo*>() && IsDelegating;
}
@@ -1864,7 +1947,7 @@
TypeLoc getBaseClassLoc() const;
/// If this is a base class initializer, returns the type of the base class.
- /// Otherwise, returns NULL.
+ /// Otherwise, returns null.
const Type *getBaseClass() const;
/// Returns whether the base is virtual or not.
@@ -1880,9 +1963,8 @@
return Initializee.dyn_cast<TypeSourceInfo *>();
}
- /// getMember - If this is a member initializer, returns the
- /// declaration of the non-static data member being
- /// initialized. Otherwise, returns NULL.
+ /// \brief If this is a member initializer, returns the declaration of the
+ /// non-static data member being initialized. Otherwise, returns null.
FieldDecl *getMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
@@ -1912,7 +1994,7 @@
/// \brief Determine the source range covering the entire initializer.
SourceRange getSourceRange() const LLVM_READONLY;
- /// isWritten - Returns true if this initializer is explicitly written
+ /// \brief Determine whether this initializer is explicitly written
/// in the source code.
bool isWritten() const { return IsWritten; }
@@ -1922,9 +2004,13 @@
return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
}
- /// \brief Set the source order of this initializer. This method can only
- /// be called once for each initializer; it cannot be called on an
- /// initializer having a positive number of (implicit) array indices.
+ /// \brief Set the source order of this initializer.
+ ///
+ /// This can only be called once for each initializer; it cannot be called
+ /// on an initializer having a positive number of (implicit) array indices.
+ ///
+ /// This assumes that the initialzier was written in the source code, and
+ /// ensures that isWritten() returns true.
void setSourceOrder(int pos) {
assert(!IsWritten &&
"calling twice setSourceOrder() on the same initializer");
@@ -1969,34 +2055,28 @@
Expr *getInit() const { return static_cast<Expr*>(Init); }
};
-/// CXXConstructorDecl - Represents a C++ constructor within a
-/// class. For example:
+/// \brief Represents a C++ constructor within a class.
///
-/// @code
+/// For example:
+///
+/// \code
/// class X {
/// public:
/// explicit X(int); // represented by a CXXConstructorDecl.
/// };
-/// @endcode
+/// \endcode
class CXXConstructorDecl : public CXXMethodDecl {
virtual void anchor();
- /// IsExplicitSpecified - Whether this constructor declaration has the
- /// 'explicit' keyword specified.
+ /// \brief Whether this constructor declaration has the \c explicit keyword
+ /// specified.
bool IsExplicitSpecified : 1;
- /// ImplicitlyDefined - Whether this constructor was implicitly
- /// defined by the compiler. When false, the constructor was defined
- /// by the user. In C++03, this flag will have the same value as
- /// Implicit. In C++0x, however, a constructor that is
- /// explicitly defaulted (i.e., defined with " = default") will have
- /// @c !Implicit && ImplicitlyDefined.
- bool ImplicitlyDefined : 1;
-
- /// Support for base and member initializers.
- /// CtorInitializers - The arguments used to initialize the base
- /// or member.
+ /// \name Support for base and member initializers.
+ /// \{
+ /// \brief The arguments used to initialize the base or member.
CXXCtorInitializer **CtorInitializers;
unsigned NumCtorInitializers;
+ /// \}
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
@@ -2005,8 +2085,8 @@
bool isImplicitlyDeclared, bool isConstexpr)
: CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
- CtorInitializers(0), NumCtorInitializers(0) {
+ IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0),
+ NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -2020,52 +2100,31 @@
bool isInline, bool isImplicitlyDeclared,
bool isConstexpr);
- /// isExplicitSpecified - Whether this constructor declaration has the
- /// 'explicit' keyword specified.
+ /// \brief Determine whether this constructor declaration has the
+ /// \c explicit keyword specified.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
- /// isExplicit - Whether this constructor was marked "explicit" or not.
+ /// \brief Determine whether this constructor was marked "explicit" or not.
bool isExplicit() const {
- return cast<CXXConstructorDecl>(getFirstDeclaration())
- ->isExplicitSpecified();
+ return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
}
- /// isImplicitlyDefined - Whether this constructor was implicitly
- /// defined. If false, then this constructor was defined by the
- /// user. This operation can only be invoked if the constructor has
- /// already been defined.
- bool isImplicitlyDefined() const {
- assert(isThisDeclarationADefinition() &&
- "Can only get the implicit-definition flag once the "
- "constructor has been defined");
- return ImplicitlyDefined;
- }
-
- /// setImplicitlyDefined - Set whether this constructor was
- /// implicitly defined or not.
- void setImplicitlyDefined(bool ID) {
- assert(isThisDeclarationADefinition() &&
- "Can only set the implicit-definition flag once the constructor "
- "has been defined");
- ImplicitlyDefined = ID;
- }
-
- /// init_iterator - Iterates through the member/base initializer list.
+ /// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer **init_iterator;
- /// init_const_iterator - Iterates through the memberbase initializer list.
+ /// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
- /// init_begin() - Retrieve an iterator to the first initializer.
+ /// \brief Retrieve an iterator to the first initializer.
init_iterator init_begin() { return CtorInitializers; }
- /// begin() - Retrieve an iterator to the first initializer.
+ /// \brief Retrieve an iterator to the first initializer.
init_const_iterator init_begin() const { return CtorInitializers; }
- /// init_end() - Retrieve an iterator past the last initializer.
+ /// \brief Retrieve an iterator past the last initializer.
init_iterator init_end() {
return CtorInitializers + NumCtorInitializers;
}
- /// end() - Retrieve an iterator past the last initializer.
+ /// \brief Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
return CtorInitializers + NumCtorInitializers;
}
@@ -2088,8 +2147,8 @@
return init_const_reverse_iterator(init_begin());
}
- /// getNumArgs - Determine the number of arguments used to
- /// initialize the member or base.
+ /// \brief Determine the number of arguments used to initialize the member
+ /// or base.
unsigned getNumCtorInitializers() const {
return NumCtorInitializers;
}
@@ -2102,37 +2161,36 @@
CtorInitializers = initializers;
}
- /// isDelegatingConstructor - Whether this constructor is a
- /// delegating constructor
+ /// \brief Determine whether this constructor is a delegating constructor.
bool isDelegatingConstructor() const {
return (getNumCtorInitializers() == 1) &&
CtorInitializers[0]->isDelegatingInitializer();
}
- /// getTargetConstructor - When this constructor delegates to
- /// another, retrieve the target
+ /// \brief When this constructor delegates to another, retrieve the target.
CXXConstructorDecl *getTargetConstructor() const;
- /// isDefaultConstructor - Whether this constructor is a default
+ /// Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
/// default-initialize a class of this type.
bool isDefaultConstructor() const;
- /// isCopyConstructor - Whether this constructor is a copy
- /// constructor (C++ [class.copy]p2, which can be used to copy the
- /// class. @p TypeQuals will be set to the qualifiers on the
- /// argument type. For example, @p TypeQuals would be set to @c
+ /// \brief Whether this constructor is a copy constructor (C++ [class.copy]p2,
+ /// which can be used to copy the class.
+ ///
+ /// \p TypeQuals will be set to the qualifiers on the
+ /// argument type. For example, \p TypeQuals would be set to \c
/// Qualifiers::Const for the following copy constructor:
///
- /// @code
+ /// \code
/// class X {
/// public:
/// X(const X&);
/// };
- /// @endcode
+ /// \endcode
bool isCopyConstructor(unsigned &TypeQuals) const;
- /// isCopyConstructor - Whether this constructor is a copy
+ /// Whether this constructor is a copy
/// constructor (C++ [class.copy]p2, which can be used to copy the
/// class.
bool isCopyConstructor() const {
@@ -2166,7 +2224,7 @@
return isCopyOrMoveConstructor(Quals);
}
- /// isConvertingConstructor - Whether this constructor is a
+ /// Whether this constructor is a
/// converting constructor (C++ [class.conv.ctor]), which can be
/// used for user-defined conversions.
bool isConvertingConstructor(bool AllowExplicit) const;
@@ -2197,24 +2255,18 @@
friend class ASTDeclWriter;
};
-/// CXXDestructorDecl - Represents a C++ destructor within a
-/// class. For example:
+/// \brief Represents a C++ destructor within a class.
///
-/// @code
+/// For example:
+///
+/// \code
/// class X {
/// public:
/// ~X(); // represented by a CXXDestructorDecl.
/// };
-/// @endcode
+/// \endcode
class CXXDestructorDecl : public CXXMethodDecl {
virtual void anchor();
- /// ImplicitlyDefined - Whether this destructor was implicitly
- /// defined by the compiler. When false, the destructor was defined
- /// by the user. In C++03, this flag will have the same value as
- /// Implicit. In C++0x, however, a destructor that is
- /// explicitly defaulted (i.e., defined with " = default") will have
- /// @c !Implicit && ImplicitlyDefined.
- bool ImplicitlyDefined : 1;
FunctionDecl *OperatorDelete;
@@ -2224,7 +2276,7 @@
bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- ImplicitlyDefined(false), OperatorDelete(0) {
+ OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -2237,26 +2289,6 @@
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- /// isImplicitlyDefined - Whether this destructor was implicitly
- /// defined. If false, then this destructor was defined by the
- /// user. This operation can only be invoked if the destructor has
- /// already been defined.
- bool isImplicitlyDefined() const {
- assert(isThisDeclarationADefinition() &&
- "Can only get the implicit-definition flag once the destructor has "
- "been defined");
- return ImplicitlyDefined;
- }
-
- /// setImplicitlyDefined - Set whether this destructor was
- /// implicitly defined or not.
- void setImplicitlyDefined(bool ID) {
- assert(isThisDeclarationADefinition() &&
- "Can only set the implicit-definition flag once the destructor has "
- "been defined");
- ImplicitlyDefined = ID;
- }
-
void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
@@ -2268,19 +2300,20 @@
friend class ASTDeclWriter;
};
-/// CXXConversionDecl - Represents a C++ conversion function within a
-/// class. For example:
+/// \brief Represents a C++ conversion function within a class.
///
-/// @code
+/// For example:
+///
+/// \code
/// class X {
/// public:
/// operator bool();
/// };
-/// @endcode
+/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
virtual void anchor();
- /// IsExplicitSpecified - Whether this conversion function declaration is
- /// marked "explicit", meaning that it can only be applied when the user
+ /// Whether this conversion function declaration is marked
+ /// "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
@@ -2303,21 +2336,20 @@
SourceLocation EndLocation);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// IsExplicitSpecified - Whether this conversion function declaration is
- /// marked "explicit", meaning that it can only be applied when the user
- /// explicitly wrote a cast. This is a C++0x feature.
+ /// Whether this conversion function declaration is marked
+ /// "explicit", meaning that it can only be used for direct initialization
+ /// (including explitly written casts). This is a C++11 feature.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
- /// isExplicit - Whether this is an explicit conversion operator
- /// (C++0x only). Explicit conversion operators are only considered
- /// when the user has explicitly written a cast.
+ /// \brief Whether this is an explicit conversion operator (C++11 and later).
+ ///
+ /// Explicit conversion operators are only considered for direct
+ /// initialization, e.g., when the user has explicitly written a cast.
bool isExplicit() const {
- return cast<CXXConversionDecl>(getFirstDeclaration())
- ->isExplicitSpecified();
+ return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
}
- /// getConversionType - Returns the type that this conversion
- /// function is converting to.
+ /// \brief Returns the type that this conversion function is converting to.
QualType getConversionType() const {
return getType()->getAs<FunctionType>()->getResultType();
}
@@ -2334,32 +2366,37 @@
friend class ASTDeclWriter;
};
-/// LinkageSpecDecl - This represents a linkage specification. For example:
-/// extern "C" void foo();
+/// \brief Represents a linkage specification.
///
+/// For example:
+/// \code
+/// extern "C" void foo();
+/// \endcode
class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
public:
- /// LanguageIDs - Used to represent the language in a linkage
- /// specification. The values are part of the serialization abi for
- /// ASTs and cannot be changed without altering that abi. To help
- /// ensure a stable abi for this, we choose the DW_LANG_ encodings
+ /// \brief Represents the language in a linkage specification.
+ ///
+ /// The values are part of the serialization ABI for
+ /// ASTs and cannot be changed without altering that ABI. To help
+ /// ensure a stable ABI for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
enum LanguageIDs {
lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
};
private:
- /// Language - The language for this linkage specification.
+ /// \brief The language for this linkage specification.
unsigned Language : 3;
- /// True if this linkage spec has brances. This is needed so that hasBraces()
- /// returns the correct result while the linkage spec body is being parsed.
- /// Once RBraceLoc has been set this is not used, so it doesn't need to be
- /// serialized.
+ /// \brief True if this linkage spec has braces.
+ ///
+ /// This is needed so that hasBraces() returns the correct result while the
+ /// linkage spec body is being parsed. Once RBraceLoc has been set this is
+ /// not used, so it doesn't need to be serialized.
unsigned HasBraces : 1;
- /// ExternLoc - The source location for the extern keyword.
+ /// \brief The source location for the extern keyword.
SourceLocation ExternLoc;
- /// RBraceLoc - The source location for the right brace (if valid).
+ /// \brief The source location for the right brace (if valid).
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
@@ -2417,34 +2454,38 @@
}
};
-/// UsingDirectiveDecl - Represents C++ using-directive. For example:
+/// \brief Represents C++ using-directive.
///
+/// For example:
+/// \code
/// using namespace std;
+/// \endcode
///
-// NB: UsingDirectiveDecl should be Decl not NamedDecl, but we provide
-// artificial names for all using-directives in order to store
-// them in DeclContext effectively.
+/// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide
+/// artificial names for all using-directives in order to store
+/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
virtual void anchor();
- /// \brief The location of the "using" keyword.
+ /// \brief The location of the \c using keyword.
SourceLocation UsingLoc;
- /// SourceLocation - Location of 'namespace' token.
+ /// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
/// \brief The nested-name-specifier that precedes the namespace.
NestedNameSpecifierLoc QualifierLoc;
- /// NominatedNamespace - Namespace nominated by using-directive.
+ /// \brief The namespace nominated by this using-directive.
NamedDecl *NominatedNamespace;
/// Enclosing context containing both using-directive and nominated
/// namespace.
DeclContext *CommonAncestor;
- /// getUsingDirectiveName - Returns special DeclarationName used by
- /// using-directives. This is only used by DeclContext for storing
- /// UsingDirectiveDecls in its lookup structure.
+ /// \brief Returns special DeclarationName used by using-directives.
+ ///
+ /// This is only used by DeclContext for storing UsingDirectiveDecls in
+ /// its lookup structure.
static DeclarationName getName() {
return DeclarationName::getUsingDirectiveName();
}
@@ -2475,7 +2516,7 @@
return NominatedNamespace;
}
- /// getNominatedNamespace - Returns namespace nominated by using-directive.
+ /// \brief Returns the namespace nominated by this using-directive.
NamespaceDecl *getNominatedNamespace();
const NamespaceDecl *getNominatedNamespace() const {
@@ -2487,14 +2528,14 @@
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
- /// \brief Return the location of the "using" keyword.
+ /// \brief Return the location of the \c using keyword.
SourceLocation getUsingLoc() const { return UsingLoc; }
// FIXME: Could omit 'Key' in name.
- /// getNamespaceKeyLocation - Returns location of namespace keyword.
+ /// \brief Returns the location of the \c namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
- /// getIdentLocation - Returns location of identifier.
+ /// \brief Returns the location of this using declaration's identifier.
SourceLocation getIdentLocation() const { return getLocation(); }
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2523,23 +2564,25 @@
///
/// For example:
///
-/// @code
+/// \code
/// namespace Foo = Bar;
-/// @endcode
+/// \endcode
class NamespaceAliasDecl : public NamedDecl {
virtual void anchor();
- /// \brief The location of the "namespace" keyword.
+ /// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
- /// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
+ /// \brief The location of the namespace's identifier.
+ ///
+ /// This is accessed by TargetNameLoc.
SourceLocation IdentLoc;
/// \brief The nested-name-specifier that precedes the namespace.
NestedNameSpecifierLoc QualifierLoc;
- /// Namespace - The Decl that this alias points to. Can either be a
- /// NamespaceDecl or a NamespaceAliasDecl.
+ /// \brief The Decl that this alias points to, either a NamespaceDecl or
+ /// a NamespaceAliasDecl.
NamedDecl *Namespace;
NamespaceAliasDecl(DeclContext *DC, SourceLocation NamespaceLoc,
@@ -2579,7 +2622,7 @@
/// "namespace foo = ns::bar;".
SourceLocation getAliasLoc() const { return getLocation(); }
- /// Returns the location of the 'namespace' keyword.
+ /// Returns the location of the \c namespace keyword.
SourceLocation getNamespaceLoc() const { return NamespaceLoc; }
/// Returns the location of the identifier in the named namespace.
@@ -2611,7 +2654,7 @@
/// (resolved) using declaration.
///
/// For example,
-/// @code
+/// \code
/// namespace A {
/// void foo();
/// }
@@ -2619,8 +2662,8 @@
/// using A::foo; // <- a UsingDecl
/// // Also creates a UsingShadowDecl for A::foo() in B
/// }
-/// @endcode
-class UsingShadowDecl : public NamedDecl {
+/// \endcode
+class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
virtual void anchor();
/// The referenced declaration.
@@ -2643,6 +2686,17 @@
setImplicit();
}
+ typedef Redeclarable<UsingShadowDecl> redeclarable_base;
+ virtual UsingShadowDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
+ }
+ virtual UsingShadowDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
+ }
+ virtual UsingShadowDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
+ }
+
public:
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
@@ -2651,7 +2705,20 @@
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
+
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
+
+ virtual UsingShadowDecl *getCanonicalDecl() {
+ return getFirstDecl();
+ }
+ virtual const UsingShadowDecl *getCanonicalDecl() const {
+ return getFirstDecl();
+ }
+
/// \brief Gets the underlying declaration which has been brought into the
/// local scope.
NamedDecl *getTargetDecl() const { return Underlying; }
@@ -2683,20 +2750,20 @@
/// \brief Represents a C++ using-declaration.
///
/// For example:
-/// @code
+/// \code
/// using someNameSpace::someIdentifier;
-/// @endcode
+/// \endcode
class UsingDecl : public NamedDecl {
virtual void anchor();
- /// \brief The source location of the "using" location itself.
+ /// \brief The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in the ValueDecl base class.
+ /// \brief Provides source/type location info for the declaration name
+ /// embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
/// \brief The first shadow declaration of the shadow decl chain associated
@@ -2708,18 +2775,18 @@
UsingDecl(DeclContext *DC, SourceLocation UL,
NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
+ const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, IsTypeNameArg) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) {
}
public:
- /// \brief Returns the source location of the "using" keyword.
- SourceLocation getUsingLocation() const { return UsingLocation; }
+ /// \brief Return the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
- void setUsingLocation(SourceLocation L) { UsingLocation = L; }
+ void setUsingLoc(SourceLocation L) { UsingLocation = L; }
/// \brief Retrieve the nested-name-specifier that qualifies the name,
/// with source-location information.
@@ -2734,13 +2801,16 @@
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
+ /// \brief Return true if it is a C++03 access declaration (no 'using').
+ bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
+
/// \brief Return true if the using declaration has 'typename'.
- bool isTypeName() const { return FirstUsingShadow.getInt(); }
+ bool hasTypename() const { return FirstUsingShadow.getInt(); }
/// \brief Sets whether the using declaration has 'typename'.
- void setTypeName(bool TN) { FirstUsingShadow.setInt(TN); }
+ void setTypename(bool TN) { FirstUsingShadow.setInt(TN); }
- /// \brief Iterates through the using shadow declarations assosiated with
+ /// \brief Iterates through the using shadow declarations associated with
/// this using declaration.
class shadow_iterator {
/// \brief The current using shadow declaration.
@@ -2796,13 +2866,11 @@
SourceLocation UsingL,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
- bool IsTypeNameArg);
+ bool HasTypenameKeyword);
static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(UsingLocation, getNameInfo().getEndLoc());
- }
+
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2817,11 +2885,11 @@
/// Unlike non-dependent using declarations, these *only* bring through
/// non-types; otherwise they would break two-phase lookup.
///
-/// @code
+/// \code
/// template \<class T> class A : public Base<T> {
/// using Base<T>::foo;
/// };
-/// @endcode
+/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl {
virtual void anchor();
@@ -2831,8 +2899,8 @@
/// \brief The nested-name-specifier that precedes the name.
NestedNameSpecifierLoc QualifierLoc;
- /// DNLoc - Provides source/type location info for the
- /// declaration name embedded in the ValueDecl base class.
+ /// \brief Provides source/type location info for the declaration name
+ /// embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
@@ -2852,6 +2920,9 @@
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
+ /// \brief Return true if it is a C++03 access declaration (no 'using').
+ bool isAccessDeclaration() const { return UsingLocation.isInvalid(); }
+
/// \brief Retrieve the nested-name-specifier that qualifies the name,
/// with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
@@ -2873,9 +2944,7 @@
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(UsingLocation, getNameInfo().getEndLoc());
- }
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -2884,23 +2953,20 @@
friend class ASTDeclWriter;
};
-/// @brief Represents a dependent using declaration which was marked with
+/// \brief Represents a dependent using declaration which was marked with
/// \c typename.
///
-/// @code
+/// \code
/// template \<class T> class A : public Base<T> {
/// using typename Base<T>::foo;
/// };
-/// @endcode
+/// \endcode
///
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
class UnresolvedUsingTypenameDecl : public TypeDecl {
virtual void anchor();
- /// \brief The source location of the 'using' keyword
- SourceLocation UsingLocation;
-
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 84f3698..9c626c8 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
@@ -26,23 +27,29 @@
class DependentDiagnostic;
-/// StoredDeclsList - This is an array of decls optimized a common case of only
-/// containing one entry.
+/// \brief An array of decls optimized for the common case of only containing
+/// one entry.
struct StoredDeclsList {
- /// DeclsTy - When in vector form, this is what the Data pointer points to.
+ /// \brief When in vector form, this is what the Data pointer points to.
typedef SmallVector<NamedDecl *, 4> DeclsTy;
+ /// \brief A collection of declarations, with a flag to indicate if we have
+ /// further external declarations.
+ typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
+
/// \brief The stored data, which will be either a pointer to a NamedDecl,
- /// or a pointer to a vector.
- llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
+ /// or a pointer to a vector with a flag to indicate if there are further
+ /// external declarations.
+ llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
public:
StoredDeclsList() {}
StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = new DeclsTy(*RHSVec);
+ Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec),
+ RHS.hasExternalDecls());
}
~StoredDeclsList() {
@@ -56,7 +63,7 @@
delete Vector;
Data = RHS.Data;
if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = new DeclsTy(*RHSVec);
+ Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls());
return *this;
}
@@ -66,8 +73,27 @@
return Data.dyn_cast<NamedDecl *>();
}
+ DeclsAndHasExternalTy getAsVectorAndHasExternal() const {
+ return Data.dyn_cast<DeclsAndHasExternalTy>();
+ }
+
DeclsTy *getAsVector() const {
- return Data.dyn_cast<DeclsTy *>();
+ return getAsVectorAndHasExternal().getPointer();
+ }
+
+ bool hasExternalDecls() const {
+ return getAsVectorAndHasExternal().getInt();
+ }
+
+ void setHasExternalDecls() {
+ if (DeclsTy *Vec = getAsVector())
+ Data = DeclsAndHasExternalTy(Vec, true);
+ else {
+ DeclsTy *VT = new DeclsTy();
+ if (NamedDecl *OldD = getAsDecl())
+ VT->push_back(OldD);
+ Data = DeclsAndHasExternalTy(VT, true);
+ }
}
void setOnlyValue(NamedDecl *ND) {
@@ -110,6 +136,8 @@
Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
std::mem_fun(&Decl::isFromASTFile)),
Vec.end());
+ // Don't have any external decls any more.
+ Data = DeclsAndHasExternalTy(&Vec, false);
}
}
@@ -165,12 +193,14 @@
/// not a redeclaration to merge it into the appropriate place in our list.
///
void AddSubsequentDecl(NamedDecl *D) {
+ assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
+
// If this is the second decl added to the list, convert this to vector
// form.
if (NamedDecl *OldD = getAsDecl()) {
DeclsTy *VT = new DeclsTy();
VT->push_back(OldD);
- Data = VT;
+ Data = DeclsAndHasExternalTy(VT, false);
}
DeclsTy &Vec = *getAsVector();
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 3a12878..be6f2eb 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -220,7 +220,7 @@
};
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
- return friend_iterator(data().FirstFriend);
+ return friend_iterator(getFirstFriend());
}
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
@@ -228,7 +228,7 @@
}
inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
- assert(FD->NextFriend == 0 && "friend already has next friend?");
+ assert(!FD->NextFriend && "friend already has next friend?");
FD->NextFriend = data().FirstFriend;
data().FirstFriend = FD;
}
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index 4477c25..c16975a 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -37,6 +37,8 @@
StoredDeclsMap::iterator End)
: It(It), End(End) {}
+ DeclarationName getLookupName() const { return It->first; }
+
reference operator*() const { return It->second.getLookupResult(); }
pointer operator->() const { return It->second.getLookupResult(); }
@@ -66,7 +68,7 @@
}
};
-DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
if (Primary->hasExternalVisibleStorage())
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
@@ -75,7 +77,7 @@
return all_lookups_iterator();
}
-DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
+inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
if (Primary->hasExternalVisibleStorage())
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
@@ -84,6 +86,22 @@
return all_lookups_iterator();
}
+inline
+DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
+ DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+ if (StoredDeclsMap *Map = Primary->getLookupPtr())
+ return all_lookups_iterator(Map->begin(), Map->end());
+ return all_lookups_iterator();
+}
+
+inline
+DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
+ DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
+ if (StoredDeclsMap *Map = Primary->getLookupPtr())
+ return all_lookups_iterator(Map->end(), Map->end());
+ return all_lookups_iterator();
+}
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 40de013..2e760d6 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -452,7 +452,7 @@
}
/// \brief Determine whether this method has a body.
- virtual bool hasBody() const { return Body; }
+ virtual bool hasBody() const { return Body.isValid(); }
/// \brief Retrieve the body of this method, if it has one.
virtual Stmt *getBody() const;
@@ -463,7 +463,7 @@
void setBody(Stmt *B) { Body = B; }
/// \brief Returns whether this specific method is a definition.
- bool isThisDeclarationADefinition() const { return Body; }
+ bool isThisDeclarationADefinition() const { return hasBody(); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -553,6 +553,9 @@
typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap;
+ typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
+ ProtocolPropertyMap;
+
typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
/// This routine collects list of properties to be implemented in the class.
@@ -1133,6 +1136,8 @@
return lookupInstanceVariable(IVarName, ClassDeclared);
}
+ ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name);
+
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
@@ -1196,14 +1201,11 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() {
- return getFirstDeclaration();
- }
- const ObjCInterfaceDecl *getCanonicalDecl() const {
- return getFirstDeclaration();
- }
+ ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Low-level accessor
const Type *getTypeForDecl() const { return TypeForDecl; }
@@ -1244,10 +1246,12 @@
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized)
+ bool synthesized,
+ bool backingIvarReferencedInAccessor)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
+ NextIvar(0), DeclAccess(ac), Synthesized(synthesized),
+ BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
@@ -1255,7 +1259,8 @@
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL,
- bool synthesized=false);
+ bool synthesized=false,
+ bool backingIvarReferencedInAccessor=false);
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1277,6 +1282,13 @@
return DeclAccess == None ? Protected : AccessControl(DeclAccess);
}
+ void setBackingIvarReferencedInAccessor(bool val) {
+ BackingIvarReferencedInAccessor = val;
+ }
+ bool getBackingIvarReferencedInAccessor() const {
+ return BackingIvarReferencedInAccessor;
+ }
+
void setSynthesize(bool synth) { Synthesized = synth; }
bool getSynthesize() const { return Synthesized; }
@@ -1291,6 +1303,7 @@
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
unsigned Synthesized : 1;
+ unsigned BackingIvarReferencedInAccessor : 1;
};
@@ -1502,17 +1515,17 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() {
- return getFirstDeclaration();
- }
- const ObjCProtocolDecl *getCanonicalDecl() const {
- return getFirstDeclaration();
- }
+ ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
virtual void collectPropertiesToImplement(PropertyMap &PM,
PropertyDeclOrder &PO) const;
+
+void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
+ ProtocolPropertyMap &PM) const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index ca92040..42fe907 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -1,4 +1,4 @@
-//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===//
+//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file defines OpenMP nodes.
+/// \brief This file defines OpenMP nodes for declarative directives.
///
//===----------------------------------------------------------------------===//
@@ -20,8 +20,6 @@
namespace clang {
-class DeclRefExpr;
-
/// \brief This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
///
@@ -43,29 +41,29 @@
OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
Decl(DK, DC, L), NumVars(0) { }
- ArrayRef<const DeclRefExpr *> getVars() const {
- return ArrayRef<const DeclRefExpr *>(
- reinterpret_cast<const DeclRefExpr * const *>(this + 1),
+ ArrayRef<const Expr *> getVars() const {
+ return ArrayRef<const Expr *>(
+ reinterpret_cast<const Expr * const *>(this + 1),
NumVars);
}
- llvm::MutableArrayRef<DeclRefExpr *> getVars() {
- return llvm::MutableArrayRef<DeclRefExpr *>(
- reinterpret_cast<DeclRefExpr **>(this + 1),
+ llvm::MutableArrayRef<Expr *> getVars() {
+ return llvm::MutableArrayRef<Expr *>(
+ reinterpret_cast<Expr **>(this + 1),
NumVars);
}
- void setVars(ArrayRef<DeclRefExpr *> VL);
+ void setVars(ArrayRef<Expr *> VL);
public:
static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
- ArrayRef<DeclRefExpr *> VL);
+ ArrayRef<Expr *> VL);
static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
unsigned ID, unsigned N);
- typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator;
- typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator;
+ typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+ typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 425a617..24bd28a 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -34,6 +34,8 @@
class NonTypeTemplateParmDecl;
class TemplateTemplateParmDecl;
class TypeAliasTemplateDecl;
+class VarTemplateDecl;
+class VarTemplatePartialSpecializationDecl;
/// \brief Stores a template parameter of any kind.
typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
@@ -629,9 +631,9 @@
template <class decl_type> friend class RedeclarableTemplate;
/// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); }
- const RedeclarableTemplateDecl *getCanonicalDecl() const {
- return getFirstDeclaration();
+ RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
+ const RedeclarableTemplateDecl *getCanonicalDecl() const {
+ return getFirstDecl();
}
/// \brief Determines whether this template was a specialization of a
@@ -713,6 +715,7 @@
using redeclarable_base::redecls_end;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
+ using redeclarable_base::isFirstDecl;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -743,7 +746,7 @@
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
- Common() : InjectedArgs(0) { }
+ Common() : InjectedArgs(), LazySpecializations() { }
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
@@ -757,6 +760,13 @@
/// template, and is allocated lazily, since most function templates do not
/// require the use of this information.
TemplateArgument *InjectedArgs;
+
+ /// \brief If non-null, points to an array of specializations known only
+ /// by their external declaration IDs.
+ ///
+ /// The first value in the array is the number of of specializations
+ /// that follow.
+ uint32_t *LazySpecializations;
};
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@@ -771,12 +781,13 @@
friend class FunctionDecl;
+ /// \brief Load any lazily-loaded specializations from the external source.
+ void LoadLazySpecializations() const;
+
/// \brief Retrieve the set of function template specializations of this
/// function template.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() const {
- return getCommonPtr()->Specializations;
- }
+ getSpecializations() const;
/// \brief Add a specialization of this function template.
///
@@ -815,14 +826,14 @@
/// NULL if no such declaration exists.
FunctionTemplateDecl *getPreviousDecl() {
return cast_or_null<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
const FunctionTemplateDecl *getPreviousDecl() const {
return cast_or_null<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
@@ -847,7 +858,7 @@
/// arguments for a function template, the notion is convenient when
/// we need to perform substitutions inside the definition of a function
/// template.
- std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs();
+ ArrayRef<TemplateArgument> getInjectedTemplateArgs();
/// \brief Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1377,7 +1388,7 @@
/// \brief The template argument list deduced for the class template
/// partial specialization itself.
- TemplateArgumentList *TemplateArgs;
+ const TemplateArgumentList *TemplateArgs;
};
/// \brief The template that this specialization specializes
@@ -1402,7 +1413,7 @@
ExplicitSpecializationInfo *ExplicitInfo;
/// \brief The template arguments used to describe this specialization.
- TemplateArgumentList *TemplateArgs;
+ const TemplateArgumentList *TemplateArgs;
/// \brief The point where this template was instantiated (if any)
SourceLocation PointOfInstantiation;
@@ -1438,9 +1449,9 @@
bool Qualified) const;
ClassTemplateSpecializationDecl *getMostRecentDecl() {
- CXXRecordDecl *Recent
- = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDecl());
- if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
+ CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
+ this)->getMostRecentDecl();
+ while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
// FIXME: Does injected class name need to be in the redeclarations chain?
assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
Recent = Recent->getPreviousDecl();
@@ -1553,7 +1564,7 @@
/// instantiation of the given class template partial specialization whose
/// template arguments have been deduced.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
- TemplateArgumentList *TemplateArgs) {
+ const TemplateArgumentList *TemplateArgs) {
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
"Already set to a class template partial specialization!");
SpecializedPartialSpecialization *PS
@@ -1639,13 +1650,7 @@
/// \brief The source info for the template arguments as written.
/// FIXME: redundant with TypeAsWritten?
- TemplateArgumentLoc *ArgsAsWritten;
- unsigned NumArgsAsWritten;
-
- /// \brief Sequence number indicating when this class template partial
- /// specialization was added to the set of partial specializations for
- /// its owning class template.
- unsigned SequenceNumber;
+ const ASTTemplateArgumentListInfo *ArgsAsWritten;
/// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
@@ -1663,16 +1668,12 @@
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
unsigned NumArgs,
- TemplateArgumentLoc *ArgInfos,
- unsigned NumArgInfos,
- ClassTemplatePartialSpecializationDecl *PrevDecl,
- unsigned SequenceNumber);
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ ClassTemplatePartialSpecializationDecl *PrevDecl);
ClassTemplatePartialSpecializationDecl()
: ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
- TemplateParams(0), ArgsAsWritten(0),
- NumArgsAsWritten(0), SequenceNumber(0),
- InstantiatedFromMember(0, false) { }
+ TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1684,15 +1685,15 @@
unsigned NumArgs,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl,
- unsigned SequenceNumber);
+ ClassTemplatePartialSpecializationDecl *PrevDecl);
static ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
return cast<ClassTemplatePartialSpecializationDecl>(
- ClassTemplateSpecializationDecl::getMostRecentDecl());
+ static_cast<ClassTemplateSpecializationDecl *>(
+ this)->getMostRecentDecl());
}
/// Get the list of template parameters
@@ -1701,19 +1702,10 @@
}
/// Get the template arguments as written.
- TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
}
- /// Get the number of template arguments as written.
- unsigned getNumTemplateArgsAsWritten() const {
- return NumArgsAsWritten;
- }
-
- /// \brief Get the sequence number for this class template partial
- /// specialization.
- unsigned getSequenceNumber() const { return SequenceNumber; }
-
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
@@ -1735,15 +1727,15 @@
/// \c Outer<float>::Inner<U*>, this function would return
/// \c Outer<T>::Inner<U*>.
ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
- ClassTemplatePartialSpecializationDecl *First
- = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ ClassTemplatePartialSpecializationDecl *First =
+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getPointer();
}
void setInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *PartialSpec) {
- ClassTemplatePartialSpecializationDecl *First
- = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ ClassTemplatePartialSpecializationDecl *First =
+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
First->InstantiatedFromMember.setPointer(PartialSpec);
}
@@ -1764,15 +1756,15 @@
/// struct X<int>::Inner<T*> { /* ... */ };
/// \endcode
bool isMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First
- = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ ClassTemplatePartialSpecializationDecl *First =
+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
return First->InstantiatedFromMember.getInt();
}
/// \brief Note that this member template is a specialization.
void setMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First
- = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
+ ClassTemplatePartialSpecializationDecl *First =
+ cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
assert(First->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
return First->InstantiatedFromMember.setInt(true);
@@ -1821,7 +1813,7 @@
QualType InjectedClassNameType;
/// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
+ /// partial specializations) known only by their external declaration IDs.
///
/// The first value in the array is the number of of specializations/
/// partial specializations that follow.
@@ -1900,14 +1892,23 @@
/// NULL if no such declaration exists.
ClassTemplateDecl *getPreviousDecl() {
return cast_or_null<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this class template, or
/// NULL if no such declaration exists.
const ClassTemplateDecl *getPreviousDecl() const {
return cast_or_null<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<const RedeclarableTemplateDecl *>(
+ this)->getPreviousDecl());
+ }
+
+ ClassTemplateDecl *getMostRecentDecl() {
+ return cast<ClassTemplateDecl>(
+ static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
+ }
+ const ClassTemplateDecl *getMostRecentDecl() const {
+ return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
}
ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
@@ -1926,11 +1927,6 @@
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
void *InsertPos);
- /// \brief Return the next partial specialization sequence number.
- unsigned getNextPartialSpecSequenceNumber() {
- return getPartialSpecializations().size();
- }
-
/// \brief Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
@@ -2139,14 +2135,15 @@
/// NULL if no such declaration exists.
TypeAliasTemplateDecl *getPreviousDecl() {
return cast_or_null<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
const TypeAliasTemplateDecl *getPreviousDecl() const {
return cast_or_null<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getPreviousDecl());
+ static_cast<const RedeclarableTemplateDecl *>(
+ this)->getPreviousDecl());
}
TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
@@ -2239,6 +2236,578 @@
inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
: Function(FTD) { }
+/// \brief Represents a variable template specialization, which refers to
+/// a variable template with a given set of template arguments.
+///
+/// Variable template specializations represent both explicit
+/// specializations of variable templates, as in the example below, and
+/// implicit instantiations of variable templates.
+///
+/// \code
+/// template<typename T> constexpr T pi = T(3.1415926535897932385);
+///
+/// template<>
+/// constexpr float pi<float>; // variable template specialization pi<float>
+/// \endcode
+class VarTemplateSpecializationDecl : public VarDecl,
+ public llvm::FoldingSetNode {
+
+ /// \brief Structure that stores information about a variable template
+ /// specialization that was instantiated from a variable template partial
+ /// specialization.
+ struct SpecializedPartialSpecialization {
+ /// \brief The variable template partial specialization from which this
+ /// variable template specialization was instantiated.
+ VarTemplatePartialSpecializationDecl *PartialSpecialization;
+
+ /// \brief The template argument list deduced for the variable template
+ /// partial specialization itself.
+ const TemplateArgumentList *TemplateArgs;
+ };
+
+ /// \brief The template that this specialization specializes.
+ llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
+ SpecializedTemplate;
+
+ /// \brief Further info for explicit template specialization/instantiation.
+ struct ExplicitSpecializationInfo {
+ /// \brief The type-as-written.
+ TypeSourceInfo *TypeAsWritten;
+ /// \brief The location of the extern keyword.
+ SourceLocation ExternLoc;
+ /// \brief The location of the template keyword.
+ SourceLocation TemplateKeywordLoc;
+
+ ExplicitSpecializationInfo()
+ : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ };
+
+ /// \brief Further info for explicit template specialization/instantiation.
+ /// Does not apply to implicit specializations.
+ ExplicitSpecializationInfo *ExplicitInfo;
+
+ /// \brief The template arguments used to describe this specialization.
+ const TemplateArgumentList *TemplateArgs;
+ TemplateArgumentListInfo TemplateArgsInfo;
+
+ /// \brief The point where this template was instantiated (if any).
+ SourceLocation PointOfInstantiation;
+
+ /// \brief The kind of specialization this declaration refers to.
+ /// Really a value of type TemplateSpecializationKind.
+ unsigned SpecializationKind : 3;
+
+protected:
+ VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ VarTemplateDecl *SpecializedTemplate,
+ QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ explicit VarTemplateSpecializationDecl(Kind DK);
+
+public:
+ static VarTemplateSpecializationDecl *
+ Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
+ unsigned NumArgs);
+ static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+
+ virtual void getNameForDiagnostic(raw_ostream &OS,
+ const PrintingPolicy &Policy,
+ bool Qualified) const;
+
+ VarTemplateSpecializationDecl *getMostRecentDecl() {
+ VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
+ return cast<VarTemplateSpecializationDecl>(Recent);
+ }
+
+ /// \brief Retrieve the template that this specialization specializes.
+ VarTemplateDecl *getSpecializedTemplate() const;
+
+ /// \brief Retrieve the template arguments of the variable template
+ /// specialization.
+ const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
+
+ // TODO: Always set this when creating the new specialization?
+ void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
+
+ const TemplateArgumentListInfo &getTemplateArgsInfo() const {
+ return TemplateArgsInfo;
+ }
+
+ /// \brief Determine the kind of specialization that this
+ /// declaration represents.
+ TemplateSpecializationKind getSpecializationKind() const {
+ return static_cast<TemplateSpecializationKind>(SpecializationKind);
+ }
+
+ bool isExplicitSpecialization() const {
+ return getSpecializationKind() == TSK_ExplicitSpecialization;
+ }
+
+ /// \brief True if this declaration is an explicit specialization,
+ /// explicit instantiation declaration, or explicit instantiation
+ /// definition.
+ bool isExplicitInstantiationOrSpecialization() const {
+ switch (getTemplateSpecializationKind()) {
+ case TSK_ExplicitSpecialization:
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ return true;
+
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ return false;
+ }
+ llvm_unreachable("bad template specialization kind");
+ }
+
+ void setSpecializationKind(TemplateSpecializationKind TSK) {
+ SpecializationKind = TSK;
+ }
+
+ /// \brief Get the point of instantiation (if any), or null if none.
+ SourceLocation getPointOfInstantiation() const {
+ return PointOfInstantiation;
+ }
+
+ void setPointOfInstantiation(SourceLocation Loc) {
+ assert(Loc.isValid() && "point of instantiation must be valid!");
+ PointOfInstantiation = Loc;
+ }
+
+ /// \brief If this variable template specialization is an instantiation of
+ /// a template (rather than an explicit specialization), return the
+ /// variable template or variable template partial specialization from which
+ /// it was instantiated.
+ llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
+ getInstantiatedFrom() const {
+ if (getSpecializationKind() != TSK_ImplicitInstantiation &&
+ getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
+ getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+ return llvm::PointerUnion<VarTemplateDecl *,
+ VarTemplatePartialSpecializationDecl *>();
+
+ if (SpecializedPartialSpecialization *PartialSpec =
+ SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+ return PartialSpec->PartialSpecialization;
+
+ return SpecializedTemplate.get<VarTemplateDecl *>();
+ }
+
+ /// \brief Retrieve the variable template or variable template partial
+ /// specialization which was specialized by this.
+ llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
+ getSpecializedTemplateOrPartial() const {
+ if (SpecializedPartialSpecialization *PartialSpec =
+ SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+ return PartialSpec->PartialSpecialization;
+
+ return SpecializedTemplate.get<VarTemplateDecl *>();
+ }
+
+ /// \brief Retrieve the set of template arguments that should be used
+ /// to instantiate the initializer of the variable template or variable
+ /// template partial specialization from which this variable template
+ /// specialization was instantiated.
+ ///
+ /// \returns For a variable template specialization instantiated from the
+ /// primary template, this function will return the same template arguments
+ /// as getTemplateArgs(). For a variable template specialization instantiated
+ /// from a variable template partial specialization, this function will the
+ /// return deduced template arguments for the variable template partial
+ /// specialization itself.
+ const TemplateArgumentList &getTemplateInstantiationArgs() const {
+ if (SpecializedPartialSpecialization *PartialSpec =
+ SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
+ return *PartialSpec->TemplateArgs;
+
+ return getTemplateArgs();
+ }
+
+ /// \brief Note that this variable template specialization is actually an
+ /// instantiation of the given variable template partial specialization whose
+ /// template arguments have been deduced.
+ void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
+ const TemplateArgumentList *TemplateArgs) {
+ assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+ "Already set to a variable template partial specialization!");
+ SpecializedPartialSpecialization *PS =
+ new (getASTContext()) SpecializedPartialSpecialization();
+ PS->PartialSpecialization = PartialSpec;
+ PS->TemplateArgs = TemplateArgs;
+ SpecializedTemplate = PS;
+ }
+
+ /// \brief Note that this variable template specialization is an instantiation
+ /// of the given variable template.
+ void setInstantiationOf(VarTemplateDecl *TemplDecl) {
+ assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
+ "Previously set to a variable template partial specialization!");
+ SpecializedTemplate = TemplDecl;
+ }
+
+ /// \brief Sets the type of this specialization as it was written by
+ /// the user.
+ void setTypeAsWritten(TypeSourceInfo *T) {
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+ ExplicitInfo->TypeAsWritten = T;
+ }
+ /// \brief Gets the type of this specialization as it was written by
+ /// the user, if it was so written.
+ TypeSourceInfo *getTypeAsWritten() const {
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ }
+
+ /// \brief Gets the location of the extern keyword, if present.
+ SourceLocation getExternLoc() const {
+ return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+ }
+ /// \brief Sets the location of the extern keyword.
+ void setExternLoc(SourceLocation Loc) {
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+ ExplicitInfo->ExternLoc = Loc;
+ }
+
+ /// \brief Sets the location of the template keyword.
+ void setTemplateKeywordLoc(SourceLocation Loc) {
+ if (!ExplicitInfo)
+ ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
+ ExplicitInfo->TemplateKeywordLoc = Loc;
+ }
+ /// \brief Gets the location of the template keyword, if present.
+ SourceLocation getTemplateKeywordLoc() const {
+ return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, ASTContext &Context) {
+ ID.AddInteger(NumTemplateArgs);
+ for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ TemplateArgs[Arg].Profile(ID, Context);
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K >= firstVarTemplateSpecialization &&
+ K <= lastVarTemplateSpecialization;
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
+class VarTemplatePartialSpecializationDecl
+ : public VarTemplateSpecializationDecl {
+ virtual void anchor();
+
+ /// \brief The list of template parameters
+ TemplateParameterList *TemplateParams;
+
+ /// \brief The source info for the template arguments as written.
+ /// FIXME: redundant with TypeAsWritten?
+ const ASTTemplateArgumentListInfo *ArgsAsWritten;
+
+ /// \brief The variable template partial specialization from which this
+ /// variable template partial specialization was instantiated.
+ ///
+ /// The boolean value will be true to indicate that this variable template
+ /// partial specialization was specialized at this level.
+ llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
+ InstantiatedFromMember;
+
+ VarTemplatePartialSpecializationDecl(
+ ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, TemplateParameterList *Params,
+ VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
+ StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
+ const ASTTemplateArgumentListInfo *ArgInfos);
+
+ VarTemplatePartialSpecializationDecl()
+ : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
+ TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
+
+public:
+ static VarTemplatePartialSpecializationDecl *
+ Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, TemplateParameterList *Params,
+ VarTemplateDecl *SpecializedTemplate, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
+ unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
+
+ static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+
+ VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
+ return cast<VarTemplatePartialSpecializationDecl>(
+ static_cast<VarTemplateSpecializationDecl *>(
+ this)->getMostRecentDecl());
+ }
+
+ /// Get the list of template parameters
+ TemplateParameterList *getTemplateParameters() const {
+ return TemplateParams;
+ }
+
+ /// Get the template arguments as written.
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ArgsAsWritten;
+ }
+
+ /// \brief Retrieve the member variable template partial specialization from
+ /// which this particular variable template partial specialization was
+ /// instantiated.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct Outer {
+ /// template<typename U> U Inner;
+ /// template<typename U> U* Inner<U*> = (U*)(0); // #1
+ /// };
+ ///
+ /// template int* Outer<float>::Inner<int*>;
+ /// \endcode
+ ///
+ /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
+ /// end up instantiating the partial specialization
+ /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
+ /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
+ /// \c Outer<float>::Inner<U*>, this function would return
+ /// \c Outer<T>::Inner<U*>.
+ VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
+ VarTemplatePartialSpecializationDecl *First =
+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ return First->InstantiatedFromMember.getPointer();
+ }
+
+ void
+ setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
+ VarTemplatePartialSpecializationDecl *First =
+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ First->InstantiatedFromMember.setPointer(PartialSpec);
+ }
+
+ /// \brief Determines whether this variable template partial specialization
+ /// was a specialization of a member partial specialization.
+ ///
+ /// In the following example, the member template partial specialization
+ /// \c X<int>::Inner<T*> is a member specialization.
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> U Inner;
+ /// template<typename U> U* Inner<U*> = (U*)(0);
+ /// };
+ ///
+ /// template<> template<typename T>
+ /// U* X<int>::Inner<T*> = (T*)(0) + 1;
+ /// \endcode
+ bool isMemberSpecialization() {
+ VarTemplatePartialSpecializationDecl *First =
+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ return First->InstantiatedFromMember.getInt();
+ }
+
+ /// \brief Note that this member template is a specialization.
+ void setMemberSpecialization() {
+ VarTemplatePartialSpecializationDecl *First =
+ cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
+ assert(First->InstantiatedFromMember.getPointer() &&
+ "Only member templates can be member template specializations");
+ return First->InstantiatedFromMember.setInt(true);
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K == VarTemplatePartialSpecialization;
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
+/// Declaration of a variable template.
+class VarTemplateDecl : public RedeclarableTemplateDecl {
+ static void DeallocateCommon(void *Ptr);
+
+protected:
+ /// \brief Data that is common to all of the declarations of a given
+ /// variable template.
+ struct Common : CommonBase {
+ Common() : LazySpecializations() {}
+
+ /// \brief The variable template specializations for this variable
+ /// template, including explicit specializations and instantiations.
+ llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
+
+ /// \brief The variable template partial specializations for this variable
+ /// template.
+ llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
+ PartialSpecializations;
+
+ /// \brief If non-null, points to an array of specializations (including
+ /// partial specializations) known ownly by their external declaration IDs.
+ ///
+ /// The first value in the array is the number of of specializations/
+ /// partial specializations that follow.
+ uint32_t *LazySpecializations;
+ };
+
+ /// \brief Load any lazily-loaded specializations from the external source.
+ void LoadLazySpecializations() const;
+
+ /// \brief Retrieve the set of specializations of this variable template.
+ llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
+ getSpecializations() const;
+
+ /// \brief Retrieve the set of partial specializations of this class
+ /// template.
+ llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
+ getPartialSpecializations();
+
+ VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
+
+ VarTemplateDecl(EmptyShell Empty)
+ : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
+ DeclarationName(), 0, 0) {}
+
+ CommonBase *newCommon(ASTContext &C) const;
+
+ Common *getCommonPtr() const {
+ return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
+ }
+
+public:
+ /// \brief Get the underlying variable declarations of the template.
+ VarDecl *getTemplatedDecl() const {
+ return static_cast<VarDecl *>(TemplatedDecl);
+ }
+
+ /// \brief Returns whether this template declaration defines the primary
+ /// variable pattern.
+ bool isThisDeclarationADefinition() const {
+ return getTemplatedDecl()->isThisDeclarationADefinition();
+ }
+
+ VarTemplateDecl *getDefinition();
+
+ /// \brief Create a variable template node.
+ static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl,
+ VarTemplateDecl *PrevDecl);
+
+ /// \brief Create an empty variable template node.
+ static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ /// \brief Return the specialization with the provided arguments if it exists,
+ /// otherwise return the insertion point.
+ VarTemplateSpecializationDecl *
+ findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+ void *&InsertPos);
+
+ /// \brief Insert the specified specialization knowing that it is not already
+ /// in. InsertPos must be obtained from findSpecialization.
+ void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
+
+ VarTemplateDecl *getCanonicalDecl() {
+ return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
+ }
+ const VarTemplateDecl *getCanonicalDecl() const {
+ return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
+ }
+
+ /// \brief Retrieve the previous declaration of this variable template, or
+ /// NULL if no such declaration exists.
+ VarTemplateDecl *getPreviousDecl() {
+ return cast_or_null<VarTemplateDecl>(
+ static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
+ }
+
+ /// \brief Retrieve the previous declaration of this variable template, or
+ /// NULL if no such declaration exists.
+ const VarTemplateDecl *getPreviousDecl() const {
+ return cast_or_null<VarTemplateDecl>(
+ static_cast<const RedeclarableTemplateDecl *>(
+ this)->getPreviousDecl());
+ }
+
+ VarTemplateDecl *getInstantiatedFromMemberTemplate() {
+ return cast_or_null<VarTemplateDecl>(
+ RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
+ }
+
+ /// \brief Return the partial specialization with the provided arguments if it
+ /// exists, otherwise return the insertion point.
+ VarTemplatePartialSpecializationDecl *
+ findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
+ void *&InsertPos);
+
+ /// \brief Insert the specified partial specialization knowing that it is not
+ /// already in. InsertPos must be obtained from findPartialSpecialization.
+ void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
+ void *InsertPos);
+
+ /// \brief Retrieve the partial specializations as an ordered list.
+ void getPartialSpecializations(
+ SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
+
+ /// \brief Find a variable template partial specialization which was
+ /// instantiated
+ /// from the given member partial specialization.
+ ///
+ /// \param D a member variable template partial specialization.
+ ///
+ /// \returns the variable template partial specialization which was
+ /// instantiated
+ /// from the given member partial specialization, or NULL if no such partial
+ /// specialization exists.
+ VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
+ VarTemplatePartialSpecializationDecl *D);
+
+ typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
+
+ spec_iterator spec_begin() const {
+ return makeSpecIterator(getSpecializations(), false);
+ }
+
+ spec_iterator spec_end() const {
+ return makeSpecIterator(getSpecializations(), true);
+ }
+
+ typedef SpecIterator<VarTemplatePartialSpecializationDecl>
+ partial_spec_iterator;
+
+ partial_spec_iterator partial_spec_begin() {
+ return makeSpecIterator(getPartialSpecializations(), false);
+ }
+
+ partial_spec_iterator partial_spec_end() {
+ return makeSpecIterator(getPartialSpecializations(), true);
+ }
+
+ // Implement isa/cast/dyncast support
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == VarTemplate; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
} /* end of namespace clang */
#endif
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index f28882b..00766c2 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -182,11 +182,16 @@
// operator bool() - Evaluates true when this declaration name is
// non-empty.
- operator bool() const {
+ LLVM_EXPLICIT operator bool() const {
return ((Ptr & PtrMask) != 0) ||
(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
}
+ /// \brief Evaluates true when this declaration name is empty.
+ bool isEmpty() const {
+ return !*this;
+ }
+
/// Predicate functions for querying what type of name this is.
bool isIdentifier() const { return getStoredNameKind() == StoredIdentifier; }
bool isObjCZeroArgSelector() const {
@@ -210,9 +215,6 @@
/// getNameAsString - Retrieve the human-readable string for this name.
std::string getAsString() const;
- /// printName - Print the human-readable name to a stream.
- void printName(raw_ostream &OS) const;
-
/// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
/// this declaration name, or NULL if this declaration name isn't a
/// simple identifier.
@@ -302,6 +304,8 @@
void dump() const;
};
+raw_ostream &operator<<(raw_ostream &OS, DeclarationName N);
+
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index 2e3cbfa..12c4fcc 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -53,7 +53,7 @@
if (E->getCond()->isValueDependent())
return;
// Only the selected subexpression matters; the other one is not evaluated.
- return this->Visit(E->getChosenSubExpr(Context));
+ return this->Visit(E->getChosenSubExpr());
}
void VisitDesignatedInitExpr(DesignatedInitExpr *E) {
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 4ff1257..f2648b9 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -277,7 +277,6 @@
MLV_IncompleteType,
MLV_ConstQualified,
MLV_ArrayType,
- MLV_ReadonlyProperty,
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting,
@@ -483,21 +482,22 @@
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
+ bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
SourceLocation *Loc = 0,
bool isEvaluated = true) const;
- bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const;
+ bool isIntegerConstantExpr(const ASTContext &Ctx,
+ SourceLocation *Loc = 0) const;
/// isCXX98IntegralConstantExpr - Return true if this expression is an
/// integral constant expression in C++98. Can only be used in C++.
- bool isCXX98IntegralConstantExpr(ASTContext &Ctx) const;
+ bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const;
/// isCXX11ConstantExpr - Return true if this expression is a constant
/// expression in C++11. Can only be used in C++.
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- bool isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result = 0,
+ bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0,
SourceLocation *Loc = 0) const;
/// isPotentialConstantExpr - Return true if this function's definition
@@ -579,15 +579,14 @@
/// \brief Determine whether this expression involves a call to any function
/// that is not trivial.
bool hasNonTrivialCall(ASTContext &Ctx);
-
+
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
/// integer.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
-
- void EvaluateForOverflow(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag) const;
+
+ void EvaluateForOverflow(const ASTContext &Ctx) const;
/// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
/// lvalue with link time known address, with no side-effects.
@@ -760,10 +759,10 @@
/// Walk outwards from an expression we want to bind a reference to and
/// find the expression whose lifetime needs to be extended. Record
- /// the adjustments needed along the path.
- const Expr *
- skipRValueSubobjectAdjustments(
- SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+ /// the LHSs of comma expressions and adjustments needed along the path.
+ const Expr *skipRValueSubobjectAdjustments(
+ SmallVectorImpl<const Expr *> &CommaLHS,
+ SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
/// Skip irrelevant expressions to find what should be materialize for
/// binding with a reference.
@@ -893,7 +892,7 @@
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
/// \brief Helper to retrieve the optional NamedDecl through which this
- /// reference occured.
+ /// reference occurred.
NamedDecl *&getInternalFoundDecl() {
assert(hasFoundDecl());
if (hasQualifier())
@@ -902,12 +901,12 @@
}
/// \brief Helper to retrieve the optional NamedDecl through which this
- /// reference occured.
+ /// reference occurred.
NamedDecl *getInternalFoundDecl() const {
return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
}
- DeclRefExpr(ASTContext &Ctx,
+ DeclRefExpr(const ASTContext &Ctx,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D, bool refersToEnclosingLocal,
@@ -922,7 +921,7 @@
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
- void computeDependence(ASTContext &C);
+ void computeDependence(const ASTContext &C);
public:
DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T,
@@ -938,7 +937,7 @@
computeDependence(D->getASTContext());
}
- static DeclRefExpr *Create(ASTContext &Context,
+ static DeclRefExpr *Create(const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
@@ -948,7 +947,7 @@
NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
- static DeclRefExpr *Create(ASTContext &Context,
+ static DeclRefExpr *Create(const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
@@ -959,7 +958,7 @@
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
- static DeclRefExpr *CreateEmpty(ASTContext &Context,
+ static DeclRefExpr *CreateEmpty(const ASTContext &Context,
bool HasQualifier,
bool HasFoundDecl,
bool HasTemplateKWAndArgsInfo,
@@ -1000,7 +999,7 @@
return getInternalQualifierLoc();
}
- /// \brief Get the NamedDecl through which this reference occured.
+ /// \brief Get the NamedDecl through which this reference occurred.
///
/// This Decl may be different from the ValueDecl actually referred to in the
/// presence of using declarations, etc. It always returns non-NULL, and may
@@ -1151,6 +1150,7 @@
Func,
Function,
LFunction, // Same as Function, but as wide string.
+ FuncDName,
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
@@ -1221,13 +1221,15 @@
else
return llvm::APInt(BitWidth, VAL);
}
- void setIntValue(ASTContext &C, const llvm::APInt &Val);
+ void setIntValue(const ASTContext &C, const llvm::APInt &Val);
};
class APIntStorage : private APNumericStorage {
public:
llvm::APInt getValue() const { return getIntValue(); }
- void setValue(ASTContext &C, const llvm::APInt &Val) { setIntValue(C, Val); }
+ void setValue(const ASTContext &C, const llvm::APInt &Val) {
+ setIntValue(C, Val);
+ }
};
class APFloatStorage : private APNumericStorage {
@@ -1235,7 +1237,7 @@
llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
return llvm::APFloat(Semantics, getIntValue());
}
- void setValue(ASTContext &C, const llvm::APFloat &Val) {
+ void setValue(const ASTContext &C, const llvm::APFloat &Val) {
setIntValue(C, Val.bitcastToAPInt());
}
};
@@ -1250,17 +1252,17 @@
public:
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
// or UnsignedLongLongTy
- IntegerLiteral(ASTContext &C, const llvm::APInt &V, QualType type,
+ IntegerLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
SourceLocation l);
/// \brief Returns a new integer literal with value 'V' and type 'type'.
/// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
/// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
/// \param V - the value that the returned integer literal contains.
- static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V,
+ static IntegerLiteral *Create(const ASTContext &C, const llvm::APInt &V,
QualType type, SourceLocation l);
/// \brief Returns a new empty integer literal.
- static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
+ static IntegerLiteral *Create(const ASTContext &C, EmptyShell Empty);
SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
@@ -1328,21 +1330,21 @@
class FloatingLiteral : public Expr, private APFloatStorage {
SourceLocation Loc;
- FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
+ FloatingLiteral(const ASTContext &C, const llvm::APFloat &V, bool isexact,
QualType Type, SourceLocation L);
/// \brief Construct an empty floating-point literal.
- explicit FloatingLiteral(ASTContext &C, EmptyShell Empty);
+ explicit FloatingLiteral(const ASTContext &C, EmptyShell Empty);
public:
- static FloatingLiteral *Create(ASTContext &C, const llvm::APFloat &V,
+ static FloatingLiteral *Create(const ASTContext &C, const llvm::APFloat &V,
bool isexact, QualType Type, SourceLocation L);
- static FloatingLiteral *Create(ASTContext &C, EmptyShell Empty);
+ static FloatingLiteral *Create(const ASTContext &C, EmptyShell Empty);
llvm::APFloat getValue() const {
return APFloatStorage::getValue(getSemantics());
}
- void setValue(ASTContext &C, const llvm::APFloat &Val) {
+ void setValue(const ASTContext &C, const llvm::APFloat &Val) {
assert(&getSemantics() == &Val.getSemantics() && "Inconsistent semantics");
APFloatStorage::setValue(C, Val);
}
@@ -1420,7 +1422,7 @@
};
/// StringLiteral - This represents a string literal expression, e.g. "foo"
-/// or L"bar" (wide strings). The actual string is returned by getStrData()
+/// or L"bar" (wide strings). The actual string is returned by getBytes()
/// is NOT null-terminated, and the length of the string is determined by
/// calling getByteLength(). The C type for a string is always a
/// ConstantArrayType. In C++, the char type is const qualified, in C it is
@@ -1469,19 +1471,19 @@
public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
- static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind,
- bool Pascal, QualType Ty,
+ static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ StringKind Kind, bool Pascal, QualType Ty,
const SourceLocation *Loc, unsigned NumStrs);
/// Simple constructor for string literals made from one token.
- static StringLiteral *Create(ASTContext &C, StringRef Str, StringKind Kind,
- bool Pascal, QualType Ty,
+ static StringLiteral *Create(const ASTContext &C, StringRef Str,
+ StringKind Kind, bool Pascal, QualType Ty,
SourceLocation Loc) {
return Create(C, Str, Kind, Pascal, Ty, &Loc, 1);
}
/// \brief Construct an empty string literal.
- static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs);
+ static StringLiteral *CreateEmpty(const ASTContext &C, unsigned NumStrs);
StringRef getString() const {
assert(CharByteWidth==1
@@ -1520,7 +1522,7 @@
unsigned getCharByteWidth() const { return CharByteWidth; }
/// \brief Sets the string data to the given string data.
- void setString(ASTContext &C, StringRef Str,
+ void setString(const ASTContext &C, StringRef Str,
StringKind Kind, bool IsPascal);
StringKind getKind() const { return static_cast<StringKind>(Kind); }
@@ -1853,7 +1855,7 @@
// Number of sub-expressions (i.e. array subscript expressions).
unsigned NumExprs;
- OffsetOfExpr(ASTContext &C, QualType type,
+ OffsetOfExpr(const ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
SourceLocation RParenLoc);
@@ -1864,12 +1866,12 @@
public:
- static OffsetOfExpr *Create(ASTContext &C, QualType type,
+ static OffsetOfExpr *Create(const ASTContext &C, QualType type,
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
ArrayRef<OffsetOfNode> comps,
ArrayRef<Expr*> exprs, SourceLocation RParenLoc);
- static OffsetOfExpr *CreateEmpty(ASTContext &C,
+ static OffsetOfExpr *CreateEmpty(const ASTContext &C,
unsigned NumComps, unsigned NumExprs);
/// getOperatorLoc - Return the location of the operator.
@@ -2133,10 +2135,11 @@
protected:
// These versions of the constructor are for derived classes.
- CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
+ CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs,
ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
SourceLocation rparenloc);
- CallExpr(ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty);
+ CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
+ EmptyShell Empty);
Stmt *getPreArg(unsigned i) {
assert(i < getNumPreArgs() && "Prearg access out of range!");
@@ -2154,11 +2157,11 @@
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
public:
- CallExpr(ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
+ CallExpr(const ASTContext& C, Expr *fn, ArrayRef<Expr*> args, QualType t,
ExprValueKind VK, SourceLocation rparenloc);
/// \brief Build an empty call expression.
- CallExpr(ASTContext &C, StmtClass SC, EmptyShell Empty);
+ CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty);
const Expr *getCallee() const { return cast<Expr>(SubExprs[FN]); }
Expr *getCallee() { return cast<Expr>(SubExprs[FN]); }
@@ -2206,7 +2209,7 @@
/// setNumArgs - This changes the number of arguments present in this call.
/// Any orphaned expressions are deleted by this, and any new operands are set
/// to null.
- void setNumArgs(ASTContext& C, unsigned NumArgs);
+ void setNumArgs(const ASTContext& C, unsigned NumArgs);
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
@@ -2360,7 +2363,7 @@
HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false),
HadMultipleCandidates(false) {}
- static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
+ static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *memberdecl, DeclAccessPair founddecl,
@@ -2747,12 +2750,13 @@
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
}
- static ImplicitCastExpr *Create(ASTContext &Context, QualType T,
+ static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
CastKind Kind, Expr *Operand,
const CXXCastPath *BasePath,
ExprValueKind Cat);
- static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
+ static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
+ unsigned PathSize);
SourceLocation getLocStart() const LLVM_READONLY {
return getSubExpr()->getLocStart();
@@ -2838,13 +2842,14 @@
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
public:
- static CStyleCastExpr *Create(ASTContext &Context, QualType T,
+ static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K,
Expr *Op, const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy, SourceLocation L,
SourceLocation R);
- static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
+ static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
+ unsigned PathSize);
SourceLocation getLParenLoc() const { return LPLoc; }
void setLParenLoc(SourceLocation L) { LPLoc = L; }
@@ -3412,7 +3417,7 @@
unsigned NumExprs;
public:
- ShuffleVectorExpr(ASTContext &C, ArrayRef<Expr*> args, QualType Type,
+ ShuffleVectorExpr(const ASTContext &C, ArrayRef<Expr*> args, QualType Type,
SourceLocation BLoc, SourceLocation RP);
/// \brief Build an empty vector-shuffle expression.
@@ -3450,11 +3455,11 @@
return cast<Expr>(SubExprs[Index]);
}
- void setExprs(ASTContext &C, Expr ** Exprs, unsigned NumExprs);
+ void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
- unsigned getShuffleMaskIdx(ASTContext &Ctx, unsigned N) const {
+ llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
assert((N < NumExprs - 2) && "Shuffle idx out of range!");
- return getExpr(N+2)->EvaluateKnownConstInt(Ctx).getZExtValue();
+ return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
}
// Iterators
@@ -3463,6 +3468,60 @@
}
};
+/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
+/// This AST node provides support for converting a vector type to another
+/// vector type of the same arity.
+class ConvertVectorExpr : public Expr {
+private:
+ Stmt *SrcExpr;
+ TypeSourceInfo *TInfo;
+ SourceLocation BuiltinLoc, RParenLoc;
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
+
+public:
+ ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType,
+ ExprValueKind VK, ExprObjectKind OK,