Vendor import of clang trunk r135360:
http://llvm.org/svn/llvm-project/cfe/trunk@135360
This commit is contained in:
parent
29cafa66ad
commit
180abc3db9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=224135 svn path=/vendor/clang/clang-r135360/; revision=224136; tag=vendor/clang/clang-r135360
@ -20,7 +20,11 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
|
||||
endif()
|
||||
|
||||
if( NOT EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
|
||||
message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.")
|
||||
# Looking for bin/Debug/tblgen is a complete hack. How can we get
|
||||
# around this?
|
||||
if( NOT EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
|
||||
message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
|
||||
@ -42,7 +46,12 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
|
||||
include_directories("${PATH_TO_LLVM_BUILD}/include" "${LLVM_MAIN_INCLUDE_DIR}")
|
||||
link_directories("${PATH_TO_LLVM_BUILD}/lib")
|
||||
|
||||
set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/tblgen")
|
||||
if( EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/tblgen${CMAKE_EXECUTABLE_SUFFIX}" )
|
||||
set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/tblgen")
|
||||
else()
|
||||
# FIXME: This is an utter hack.
|
||||
set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/Debug/tblgen")
|
||||
endif()
|
||||
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
|
||||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
|
||||
|
27
INPUTS/cfg-big-switch.c
Normal file
27
INPUTS/cfg-big-switch.c
Normal file
@ -0,0 +1,27 @@
|
||||
#define EXPAND_2_CASES(i, x, y) CASE(i, x, y); CASE(i + 1, x, y);
|
||||
#define EXPAND_4_CASES(i, x, y) EXPAND_2_CASES(i, x, y) EXPAND_2_CASES(i + 2, x, y)
|
||||
#define EXPAND_8_CASES(i, x, y) EXPAND_4_CASES(i, x, y) EXPAND_4_CASES(i + 4, x, y)
|
||||
#define EXPAND_16_CASES(i, x, y) EXPAND_8_CASES(i, x, y) EXPAND_8_CASES(i + 8, x, y)
|
||||
#define EXPAND_32_CASES(i, x, y) EXPAND_16_CASES(i, x, y) EXPAND_16_CASES(i + 16, x, y)
|
||||
#define EXPAND_64_CASES(i, x, y) EXPAND_32_CASES(i, x, y) EXPAND_32_CASES(i + 32, x, y)
|
||||
#define EXPAND_128_CASES(i, x, y) EXPAND_64_CASES(i, x, y) EXPAND_64_CASES(i + 64, x, y)
|
||||
#define EXPAND_256_CASES(i, x, y) EXPAND_128_CASES(i, x, y) EXPAND_128_CASES(i + 128, x, y)
|
||||
#define EXPAND_512_CASES(i, x, y) EXPAND_256_CASES(i, x, y) EXPAND_256_CASES(i + 256, x, y)
|
||||
#define EXPAND_1024_CASES(i, x, y) EXPAND_512_CASES(i, x, y) EXPAND_512_CASES(i + 512, x, y)
|
||||
#define EXPAND_2048_CASES(i, x, y) EXPAND_1024_CASES(i, x, y) EXPAND_1024_CASES(i + 1024, x, y)
|
||||
#define EXPAND_4096_CASES(i, x, y) EXPAND_2048_CASES(i, x, y) EXPAND_2048_CASES(i + 2048, x, y)
|
||||
|
||||
// This has a *monstrous* single fan-out in the CFG, across 8000 blocks inside
|
||||
// the while loop.
|
||||
unsigned cfg_big_switch(int x) {
|
||||
unsigned y = 0;
|
||||
while (x > 0) {
|
||||
switch(x) {
|
||||
#define CASE(i, x, y) \
|
||||
case i: { int case_var = 3*x + i; y += case_var - 1; break; }
|
||||
EXPAND_4096_CASES(0, x, y);
|
||||
}
|
||||
--x;
|
||||
}
|
||||
return y;
|
||||
}
|
20
INPUTS/cfg-long-chain1.c
Normal file
20
INPUTS/cfg-long-chain1.c
Normal file
@ -0,0 +1,20 @@
|
||||
#define EXPAND_2_BRANCHES(i, x, y) BRANCH(i, x, y); BRANCH(i + 1, x, y);
|
||||
#define EXPAND_4_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i + 2, x, y)
|
||||
#define EXPAND_8_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i + 4, x, y)
|
||||
#define EXPAND_16_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i + 8, x, y)
|
||||
#define EXPAND_32_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i + 16, x, y)
|
||||
#define EXPAND_64_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i + 32, x, y)
|
||||
#define EXPAND_128_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i + 64, x, y)
|
||||
#define EXPAND_256_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i + 128, x, y)
|
||||
#define EXPAND_512_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i + 256, x, y)
|
||||
#define EXPAND_1024_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i + 512, x, y)
|
||||
#define EXPAND_2048_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i + 1024, x, y)
|
||||
#define EXPAND_4096_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i + 2048, x, y)
|
||||
|
||||
unsigned cfg_long_chain_single_exit(unsigned x) {
|
||||
unsigned y = 0;
|
||||
#define BRANCH(i, x, y) if ((x % 13171) < i) { int var = x / 13171; y ^= var; }
|
||||
EXPAND_4096_BRANCHES(1, x, y);
|
||||
#undef BRANCH
|
||||
return y;
|
||||
}
|
20
INPUTS/cfg-long-chain2.c
Normal file
20
INPUTS/cfg-long-chain2.c
Normal file
@ -0,0 +1,20 @@
|
||||
#define EXPAND_2_BRANCHES(i, x, y) BRANCH(i, x, y); BRANCH(i + 1, x, y);
|
||||
#define EXPAND_4_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i + 2, x, y)
|
||||
#define EXPAND_8_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i + 4, x, y)
|
||||
#define EXPAND_16_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i + 8, x, y)
|
||||
#define EXPAND_32_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i + 16, x, y)
|
||||
#define EXPAND_64_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i + 32, x, y)
|
||||
#define EXPAND_128_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i + 64, x, y)
|
||||
#define EXPAND_256_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i + 128, x, y)
|
||||
#define EXPAND_512_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i + 256, x, y)
|
||||
#define EXPAND_1024_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i + 512, x, y)
|
||||
#define EXPAND_2048_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i + 1024, x, y)
|
||||
#define EXPAND_4096_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i + 2048, x, y)
|
||||
|
||||
unsigned cfg_long_chain_multiple_exit(unsigned x) {
|
||||
unsigned y = 0;
|
||||
#define BRANCH(i, x, y) if (((x % 13171) + ++y) < i) { int var = x / 13171 + y; return var; }
|
||||
EXPAND_4096_BRANCHES(1, x, y);
|
||||
#undef BRANCH
|
||||
return 42;
|
||||
}
|
21
INPUTS/cfg-long-chain3.c
Normal file
21
INPUTS/cfg-long-chain3.c
Normal file
@ -0,0 +1,21 @@
|
||||
#define EXPAND_2_BRANCHES(i, x, y) BRANCH(i, x, y); BRANCH(i + 1, x, y);
|
||||
#define EXPAND_4_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i, x, y) EXPAND_2_BRANCHES(i + 2, x, y)
|
||||
#define EXPAND_8_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i, x, y) EXPAND_4_BRANCHES(i + 4, x, y)
|
||||
#define EXPAND_16_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i, x, y) EXPAND_8_BRANCHES(i + 8, x, y)
|
||||
#define EXPAND_32_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i, x, y) EXPAND_16_BRANCHES(i + 16, x, y)
|
||||
#define EXPAND_64_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i, x, y) EXPAND_32_BRANCHES(i + 32, x, y)
|
||||
#define EXPAND_128_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i, x, y) EXPAND_64_BRANCHES(i + 64, x, y)
|
||||
#define EXPAND_256_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i, x, y) EXPAND_128_BRANCHES(i + 128, x, y)
|
||||
#define EXPAND_512_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i, x, y) EXPAND_256_BRANCHES(i + 256, x, y)
|
||||
#define EXPAND_1024_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i, x, y) EXPAND_512_BRANCHES(i + 512, x, y)
|
||||
#define EXPAND_2048_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i, x, y) EXPAND_1024_BRANCHES(i + 1024, x, y)
|
||||
#define EXPAND_4096_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i, x, y) EXPAND_2048_BRANCHES(i + 2048, x, y)
|
||||
|
||||
unsigned cfg_long_chain_many_preds(unsigned x) {
|
||||
unsigned y = 0;
|
||||
#define BRANCH(i, x, y) if ((x % 13171) < i) { int var = x / 13171; y ^= var; } else
|
||||
EXPAND_4096_BRANCHES(1, x, y);
|
||||
#undef BRANCH
|
||||
int var = x / 13171; y^= var;
|
||||
return y;
|
||||
}
|
36
INPUTS/cfg-nested-switches.c
Normal file
36
INPUTS/cfg-nested-switches.c
Normal file
@ -0,0 +1,36 @@
|
||||
#define EXPAND_2_INNER_CASES(i, x, y) INNER_CASE(i, x, y); INNER_CASE(i + 1, x, y);
|
||||
#define EXPAND_4_INNER_CASES(i, x, y) EXPAND_2_INNER_CASES(i, x, y) EXPAND_2_INNER_CASES(i + 2, x, y)
|
||||
#define EXPAND_8_INNER_CASES(i, x, y) EXPAND_4_INNER_CASES(i, x, y) EXPAND_4_INNER_CASES(i + 4, x, y)
|
||||
#define EXPAND_16_INNER_CASES(i, x, y) EXPAND_8_INNER_CASES(i, x, y) EXPAND_8_INNER_CASES(i + 8, x, y)
|
||||
#define EXPAND_32_INNER_CASES(i, x, y) EXPAND_16_INNER_CASES(i, x, y) EXPAND_16_INNER_CASES(i + 16, x, y)
|
||||
#define EXPAND_64_INNER_CASES(i, x, y) EXPAND_32_INNER_CASES(i, x, y) EXPAND_32_INNER_CASES(i + 32, x, y)
|
||||
|
||||
#define EXPAND_2_OUTER_CASES(i, x, y) OUTER_CASE(i, x, y); OUTER_CASE(i + 1, x, y);
|
||||
#define EXPAND_4_OUTER_CASES(i, x, y) EXPAND_2_OUTER_CASES(i, x, y) EXPAND_2_OUTER_CASES(i + 2, x, y)
|
||||
#define EXPAND_8_OUTER_CASES(i, x, y) EXPAND_4_OUTER_CASES(i, x, y) EXPAND_4_OUTER_CASES(i + 4, x, y)
|
||||
#define EXPAND_16_OUTER_CASES(i, x, y) EXPAND_8_OUTER_CASES(i, x, y) EXPAND_8_OUTER_CASES(i + 8, x, y)
|
||||
#define EXPAND_32_OUTER_CASES(i, x, y) EXPAND_16_OUTER_CASES(i, x, y) EXPAND_16_OUTER_CASES(i + 16, x, y)
|
||||
#define EXPAND_64_OUTER_CASES(i, x, y) EXPAND_32_OUTER_CASES(i, x, y) EXPAND_32_OUTER_CASES(i + 32, x, y)
|
||||
|
||||
// Rather than a single monstrous fan-out, this fans out in smaller increments,
|
||||
// but to a similar size.
|
||||
unsigned cfg_nested_switch(int x) {
|
||||
unsigned y = 0;
|
||||
while (x > 0) {
|
||||
switch (x) {
|
||||
#define INNER_CASE(i, x, y) \
|
||||
case i: { int case_var = 3*x + i; y += case_var - 1; break; }
|
||||
#define OUTER_CASE(i, x, y) \
|
||||
case i: { \
|
||||
int case_var = y >> 8; \
|
||||
switch (case_var) { \
|
||||
EXPAND_64_INNER_CASES(0, x, y); \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
EXPAND_64_OUTER_CASES(0, x, y);
|
||||
}
|
||||
--x;
|
||||
}
|
||||
return y;
|
||||
}
|
@ -4,7 +4,7 @@ LLVM Release License
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2007-2010 University of Illinois at Urbana-Champaign.
|
||||
Copyright (c) 2007-2011 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
@ -321,6 +321,10 @@ def is_statement(self):
|
||||
"""Test if this is a statement kind."""
|
||||
return CursorKind_is_stmt(self)
|
||||
|
||||
def is_attribute(self):
|
||||
"""Test if this is an attribute kind."""
|
||||
return CursorKind_is_attribute(self)
|
||||
|
||||
def is_invalid(self):
|
||||
"""Test if this is an invalid kind."""
|
||||
return CursorKind_is_inv(self)
|
||||
@ -978,8 +982,9 @@ def get_includes(self):
|
||||
headers.
|
||||
"""
|
||||
def visitor(fobj, lptr, depth, includes):
|
||||
loc = lptr.contents
|
||||
includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
|
||||
if depth > 0:
|
||||
loc = lptr.contents
|
||||
includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
|
||||
|
||||
# Automatically adapt CIndex/ctype pointers to python objects
|
||||
includes = []
|
||||
@ -1074,7 +1079,7 @@ class File(ClangObject):
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the complete file and path name of the file."""
|
||||
return File_name(self)
|
||||
return _CXString_getCString(File_name(self))
|
||||
|
||||
@property
|
||||
def time(self):
|
||||
@ -1147,6 +1152,10 @@ def is_input_file(self):
|
||||
CursorKind_is_stmt.argtypes = [CursorKind]
|
||||
CursorKind_is_stmt.restype = bool
|
||||
|
||||
CursorKind_is_attribute = lib.clang_isAttribute
|
||||
CursorKind_is_attribute.argtypes = [CursorKind]
|
||||
CursorKind_is_attribute.restype = bool
|
||||
|
||||
CursorKind_is_inv = lib.clang_isInvalid
|
||||
CursorKind_is_inv.argtypes = [CursorKind]
|
||||
CursorKind_is_inv.restype = bool
|
||||
@ -1183,6 +1192,11 @@ def is_input_file(self):
|
||||
Cursor_spelling.restype = _CXString
|
||||
Cursor_spelling.errcheck = _CXString.from_result
|
||||
|
||||
Cursor_displayname = lib.clang_getCursorDisplayName
|
||||
Cursor_displayname.argtypes = [Cursor]
|
||||
Cursor_displayname.restype = _CXString
|
||||
Cursor_displayname.errcheck = _CXString.from_result
|
||||
|
||||
Cursor_loc = lib.clang_getCursorLocation
|
||||
Cursor_loc.argtypes = [Cursor]
|
||||
Cursor_loc.restype = SourceLocation
|
||||
@ -1253,7 +1267,7 @@ def is_input_file(self):
|
||||
# File Functions
|
||||
File_name = lib.clang_getFileName
|
||||
File_name.argtypes = [File]
|
||||
File_name.restype = c_char_p
|
||||
File_name.restype = _CXString
|
||||
|
||||
File_time = lib.clang_getFileTime
|
||||
File_time.argtypes = [File]
|
||||
|
@ -18,10 +18,14 @@ def test_kind_groups():
|
||||
|
||||
for k in CursorKind.get_all_kinds():
|
||||
group = [n for n in ('is_declaration', 'is_reference', 'is_expression',
|
||||
'is_statement', 'is_invalid')
|
||||
'is_statement', 'is_invalid', 'is_attribute')
|
||||
if getattr(k, n)()]
|
||||
|
||||
if k == CursorKind.TRANSLATION_UNIT:
|
||||
if k in ( CursorKind.TRANSLATION_UNIT,
|
||||
CursorKind.MACRO_DEFINITION,
|
||||
CursorKind.MACRO_INSTANTIATION,
|
||||
CursorKind.INCLUSION_DIRECTIVE,
|
||||
CursorKind.PREPROCESSING_DIRECTIVE):
|
||||
assert len(group) == 0
|
||||
else:
|
||||
assert len(group) == 1
|
||||
|
@ -58,24 +58,27 @@ def test_unsaved_files_2():
|
||||
spellings = [c.spelling for c in tu.cursor.get_children()]
|
||||
assert spellings[-1] == 'x'
|
||||
|
||||
def normpaths_equal(path1, path2):
|
||||
""" Compares two paths for equality after normalizing them with
|
||||
os.path.normpath
|
||||
"""
|
||||
return os.path.normpath(path1) == os.path.normpath(path2)
|
||||
|
||||
def test_includes():
|
||||
def eq(expected, actual):
|
||||
if not actual.is_input_file:
|
||||
return expected[0] == actual.source.name and \
|
||||
expected[1] == actual.include.name
|
||||
return normpaths_equal(expected[0], actual.source.name) and \
|
||||
normpaths_equal(expected[1], actual.include.name)
|
||||
else:
|
||||
return expected[1] == actual.include.name
|
||||
return normpaths_equal(expected[1], actual.include.name)
|
||||
|
||||
src = os.path.join(kInputsDir, 'include.cpp')
|
||||
h1 = os.path.join(kInputsDir, "header1.h")
|
||||
h2 = os.path.join(kInputsDir, "header2.h")
|
||||
h3 = os.path.join(kInputsDir, "header3.h")
|
||||
inc = [(None, src), (src, h1), (h1, h3), (src, h2), (h2, h3)]
|
||||
inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)]
|
||||
|
||||
index = Index.create()
|
||||
tu = index.parse(src)
|
||||
for i in zip(inc, tu.get_includes()):
|
||||
assert eq(i[0], i[1])
|
||||
|
||||
|
||||
|
@ -373,6 +373,12 @@
|
||||
90FD6D90103C3D80005F5B73 /* TypeXML.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = TypeXML.def; path = clang/Frontend/TypeXML.def; sourceTree = "<group>"; };
|
||||
90FD6D91103C3D80005F5B73 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = clang/Frontend/Utils.h; sourceTree = "<group>"; };
|
||||
90FD6DB5103D977E005F5B73 /* index-test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "index-test.cpp"; path = "tools/index-test/index-test.cpp"; sourceTree = "<group>"; };
|
||||
BB20603B131EDDBF003C3343 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
BB20603C131EDDBF003C3343 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||
BB206041131EDDDA003C3343 /* ARRMT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARRMT.h; sourceTree = "<group>"; };
|
||||
BB206043131EDE03003C3343 /* arrmt-test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "arrmt-test.cpp"; sourceTree = "<group>"; };
|
||||
BB206044131EDE03003C3343 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||
BB206045131EDE03003C3343 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||
BB5C372812A5057500259F53 /* DumpXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpXML.cpp; path = /Volumes/Data/llvm/tools/clang/lib/AST/DumpXML.cpp; sourceTree = "<absolute>"; };
|
||||
BBA5AB141309C2FA000B38F1 /* AdjustedReturnValueChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdjustedReturnValueChecker.cpp; sourceTree = "<group>"; };
|
||||
BBA5AB151309C2FA000B38F1 /* AnalyzerStatsChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnalyzerStatsChecker.cpp; sourceTree = "<group>"; };
|
||||
@ -561,7 +567,6 @@
|
||||
BF9FEE321225E898003A8B71 /* ItaniumCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ItaniumCXXABI.cpp; path = lib/CodeGen/ItaniumCXXABI.cpp; sourceTree = "<group>"; };
|
||||
BF9FEE341225E8B1003A8B71 /* MicrosoftCXXABI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MicrosoftCXXABI.cpp; path = lib/CodeGen/MicrosoftCXXABI.cpp; sourceTree = "<group>"; };
|
||||
BF9FEE361225E8CF003A8B71 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = lib/CodeGen/README.txt; sourceTree = "<group>"; };
|
||||
BF9FEE371225E925003A8B71 /* BoostConAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BoostConAction.cpp; path = lib/Frontend/BoostConAction.cpp; sourceTree = "<group>"; };
|
||||
BF9FEE451225EA24003A8B71 /* DelayedDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DelayedDiagnostic.h; path = clang/Sema/DelayedDiagnostic.h; sourceTree = "<group>"; };
|
||||
BF9FEE511226FE9F003A8B71 /* ParseAST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ParseAST.cpp; path = lib/Parse/ParseAST.cpp; sourceTree = "<group>"; };
|
||||
BF9FEE531226FEC1003A8B71 /* RAIIObjectsForParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RAIIObjectsForParser.h; path = lib/Parse/RAIIObjectsForParser.h; sourceTree = "<group>"; };
|
||||
@ -777,6 +782,7 @@
|
||||
08FB7795FE84155DC02AAC07 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB20603A131EDDBF003C3343 /* ARRMigrate */,
|
||||
BBA5AB121309C2FA000B38F1 /* StaticAnalyzer */,
|
||||
57EB5660121B034300ECA335 /* Serialization */,
|
||||
BFE2F67911DA95590007EDC0 /* Rewrite */,
|
||||
@ -899,7 +905,6 @@
|
||||
352246E00F5C6BC000D0D279 /* Frontend */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF9FEE371225E925003A8B71 /* BoostConAction.cpp */,
|
||||
1AFDD8701161085D00AE030A /* ASTMerge.cpp */,
|
||||
9012911C1048068D0083456D /* ASTUnit.cpp */,
|
||||
1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */,
|
||||
@ -1105,6 +1110,38 @@
|
||||
name = "index-test";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BB20603A131EDDBF003C3343 /* ARRMigrate */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB20603B131EDDBF003C3343 /* CMakeLists.txt */,
|
||||
BB20603C131EDDBF003C3343 /* Makefile */,
|
||||
BDDF60E91337BF40009F1764 /* Transforms.cpp */,
|
||||
);
|
||||
name = ARRMigrate;
|
||||
path = lib/ARRMigrate;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BB206040131EDDDA003C3343 /* ARRMigrate */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB206041131EDDDA003C3343 /* ARRMT.h */,
|
||||
);
|
||||
name = ARRMigrate;
|
||||
path = clang/ARRMigrate;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BB206042131EDE03003C3343 /* arrmt-test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BD8A47E7133D32660066FE40 /* ARRMT.cpp */,
|
||||
BB206043131EDE03003C3343 /* arrmt-test.cpp */,
|
||||
BB206044131EDE03003C3343 /* CMakeLists.txt */,
|
||||
BB206045131EDE03003C3343 /* Makefile */,
|
||||
);
|
||||
name = "arrmt-test";
|
||||
path = "tools/arrmt-test";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BBA5AB121309C2FA000B38F1 /* StaticAnalyzer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1575,6 +1612,7 @@
|
||||
DED7D72E0A524295003AD0FB /* include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB206040131EDDDA003C3343 /* ARRMigrate */,
|
||||
DED7D7300A524295003AD0FB /* Basic */,
|
||||
DED7D7390A524295003AD0FB /* Lex */,
|
||||
DE1F21F20A7D84E800FBF588 /* Parse */,
|
||||
@ -1724,6 +1762,7 @@
|
||||
DEDFE61F0F7B3AE10035BD10 /* Tools */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB206042131EDE03003C3343 /* arrmt-test */,
|
||||
90F9EFA8104ABDC400D09A15 /* c-index-test */,
|
||||
9012911E104812DA0083456D /* CIndex */,
|
||||
90FD6DB4103D9763005F5B73 /* index-test */,
|
||||
|
1857
docs/AutomaticReferenceCounting.html
Normal file
1857
docs/AutomaticReferenceCounting.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -317,7 +317,7 @@ would be rewritten to be:
|
||||
int flags; //refcount;
|
||||
int size;
|
||||
int captured_i;
|
||||
} i = { NULL, &i, 0, sizeof(struct _block_byref_i), 11 };
|
||||
} i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 };
|
||||
|
||||
i.forwarding->captured_i = 11;
|
||||
|
||||
@ -476,7 +476,7 @@ struct _block_byref_obj {
|
||||
int size;
|
||||
void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
|
||||
void (*byref_dispose)(struct _block_byref_i *);
|
||||
int captured_obj;
|
||||
id captured_obj;
|
||||
};
|
||||
|
||||
void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
|
||||
|
@ -151,7 +151,7 @@ For example, given class Foo with member function fighter(void):
|
||||
...a Block that used foo would import the variables as const variations:
|
||||
const Foo block_foo = foo; // const copy constructor
|
||||
const Foo &block_fooRef = fooRef;
|
||||
const Foo *block_fooPtr = fooPtr;
|
||||
Foo *const block_fooPtr = fooPtr;
|
||||
|
||||
Stack-local objects are copied into a Block via a copy const constructor. If no such constructor exists, it is considered an error to reference such objects from within the Block compound statements. A destructor is run as control leaves the compound statement that contains the Block literal expression.
|
||||
|
||||
|
@ -405,7 +405,7 @@
|
||||
to each compilation sequence. For example, the list of used
|
||||
temporary files (which must be removed once compilation is
|
||||
finished) and result files (which should be removed if
|
||||
compilation files).</p>
|
||||
compilation fails).</p>
|
||||
|
||||
<h4 id="int_unified_parsing">Unified Parsing & Pipelining</h4>
|
||||
|
||||
|
@ -68,7 +68,6 @@ td {
|
||||
<li><a href="#Constants">Constant Folding in the Clang AST</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="libIndex.html">The Index Library</a></li>
|
||||
<li><a href="#Howtos">Howto guides</a>
|
||||
<ul>
|
||||
<li><a href="#AddingAttributes">How to add an attribute</a></li>
|
||||
@ -1213,8 +1212,8 @@ void g();
|
||||
void g(int);
|
||||
</pre>
|
||||
<p>the <code>DeclContext::lookup</code> operation will return
|
||||
an <code>OverloadedFunctionDecl</code> that contains both
|
||||
declarations of "g". Clients that perform semantic analysis on a
|
||||
a <code>DeclContext::lookup_result</code> that contains a range of iterators
|
||||
over declarations of "g". Clients that perform semantic analysis on a
|
||||
program that is not concerned with the actual source code will
|
||||
primarily use this semantics-centric view.</p>
|
||||
|
||||
@ -1396,8 +1395,8 @@ namespace N {
|
||||
nodes in Snippet #1, each of which is a declaration context that
|
||||
contains a single declaration of "f". However, the semantics-centric
|
||||
view provided by name lookup into the namespace <code>N</code> for
|
||||
"f" will return an <code>OverloadedFunctionDecl</code> that contains
|
||||
both declarations of "f".</p>
|
||||
"f" will return a <code>DeclContext::lookup_result</code> that contains
|
||||
a range of iterators over declarations of "f".</p>
|
||||
|
||||
<p><code>DeclContext</code> manages multiply-defined declaration
|
||||
contexts internally. The
|
||||
|
@ -1,13 +1,17 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
|
||||
<html>
|
||||
<head>
|
||||
<title>Clang Language Extensions</title>
|
||||
<link type="text/css" rel="stylesheet" href="../menu.css" />
|
||||
<link type="text/css" rel="stylesheet" href="../content.css" />
|
||||
<style type="text/css">
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Clang LanguageExtensions</title>
|
||||
<link type="text/css" rel="stylesheet" href="../menu.css">
|
||||
<link type="text/css" rel="stylesheet" href="../content.css">
|
||||
<style type="text/css">
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@ -25,12 +29,12 @@ td {
|
||||
<li><a href="#vectors">Vectors and Extended Vectors</a></li>
|
||||
<li><a href="#deprecated">Messages on <tt>deprecated</tt> and <tt>unavailable</tt> attributes</a></li>
|
||||
<li><a href="#attributes-on-enumerators">Attributes on enumerators</a></li>
|
||||
<li><a href="#checking_language_features">Checks for Standard Language Features</a></li>
|
||||
<li><a href="#checking_language_features">Checks for Standard Language Features</a>
|
||||
<ul>
|
||||
<li><a href="#cxx_exceptions">C++ exceptions</a></li>
|
||||
<li><a href="#cxx_rtti">C++ RTTI</a></li>
|
||||
</ul>
|
||||
<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a>
|
||||
<ul>
|
||||
<li><a href="#cxx0x">C++0x</a>
|
||||
<ul>
|
||||
@ -39,6 +43,7 @@ td {
|
||||
<li><a href="#cxx_alias_templates">C++0x alias templates</a></li>
|
||||
<li><a href="#cxx_attributes">C++0x attributes</a></li>
|
||||
<li><a href="#cxx_default_function_template_args">C++0x default template arguments in function templates</a></li>
|
||||
<li><a href="#cxx_delegating_constructor">C++0x delegating constructors</a></li>
|
||||
<li><a href="#cxx_deleted_functions">C++0x deleted functions</a></li>
|
||||
<li><a href="#cxx_lambdas">C++0x lambdas</a></li>
|
||||
<li><a href="#cxx_nullptr">C++0x nullptr</a></li>
|
||||
@ -53,18 +58,19 @@ td {
|
||||
<li><a href="#cxx_strong_enums">C++0x strongly-typed enumerations</a></li>
|
||||
<li><a href="#cxx_trailing_return">C++0x trailing return type</a></li>
|
||||
<li><a href="#cxx_noexcept">C++0x noexcept specification</a></li>
|
||||
</ul>
|
||||
</ul></li>
|
||||
<li><a href="#c1x">C1X</a>
|
||||
<ul>
|
||||
<li><a href="#c_generic_selections">C1X generic selections</a></li>
|
||||
<li><a href="#c_static_assert">C1X <tt>_Static_assert()</tt></a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</ul></li>
|
||||
</ul> </li>
|
||||
<li><a href="#checking_type_traits">Checks for Type Traits</a></li>
|
||||
<li><a href="#blocks">Blocks</a></li>
|
||||
<li><a href="#objc_features">Objective-C Features</a>
|
||||
<ul>
|
||||
<li><a href="#objc_instancetype">Related result types</a></li>
|
||||
<li><a href="#objc_arc">Automatic reference counting</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
|
||||
@ -104,7 +110,7 @@ code without having to resort to something like autoconf or fragile "compiler
|
||||
version checks".</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__has_builtin">__has_builtin</h3>
|
||||
<h3><a name="__has_builtin">__has_builtin</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>This function-like macro takes a single identifier argument that is the name
|
||||
@ -129,7 +135,7 @@ not. It can be used like this:</p>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__has_feature_extension">__has_feature and __has_extension</h3>
|
||||
<h3><a name="__has_feature_extension"> __has_feature and __has_extension</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>These function-like macros take a single identifier argument that is the
|
||||
@ -174,7 +180,7 @@ non-standardized features, i.e. features not prefixed <code>c_</code>,
|
||||
<p>The feature tag is described along with the language feature below.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__has_attribute">__has_attribute</h3>
|
||||
<h3><a name="__has_attribute">__has_attribute</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>This function-like macro takes a single identifier argument that is the name
|
||||
@ -208,7 +214,7 @@ check for the existence of an include file before doing
|
||||
a possibly failing #include directive.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__has_include">__has_include</h3>
|
||||
<h3><a name="__has_include">__has_include</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>This function-like macro takes a single file name string argument that
|
||||
@ -218,12 +224,12 @@ be found using the include paths, or 0 otherwise:</p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
// Note the two possible file name string formats.
|
||||
#if __has_include("myinclude.h") && __has_include(<stdint.h>)
|
||||
#if __has_include("myinclude.h") && __has_include(<stdint.h>)
|
||||
# include "myinclude.h"
|
||||
#endif
|
||||
|
||||
// To avoid problem with non-clang compilers not having this macro.
|
||||
#if defined(__has_include) && __has_include("myinclude.h")
|
||||
#if defined(__has_include) && __has_include("myinclude.h")
|
||||
# include "myinclude.h"
|
||||
#endif
|
||||
</pre>
|
||||
@ -232,7 +238,7 @@ be found using the include paths, or 0 otherwise:</p>
|
||||
<p>To test for this feature, use #if defined(__has_include).</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__has_include_next">__has_include_next</h3>
|
||||
<h3><a name="__has_include_next">__has_include_next</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>This function-like macro takes a single file name string argument that
|
||||
@ -244,12 +250,12 @@ be found using the include paths, or 0 otherwise:</p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
// Note the two possible file name string formats.
|
||||
#if __has_include_next("myinclude.h") && __has_include_next(<stdint.h>)
|
||||
#if __has_include_next("myinclude.h") && __has_include_next(<stdint.h>)
|
||||
# include_next "myinclude.h"
|
||||
#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) && __has_include_next("myinclude.h")
|
||||
# include_next "myinclude.h"
|
||||
#endif
|
||||
</pre>
|
||||
@ -410,115 +416,120 @@ noted.</p>
|
||||
C++0x standard. As a result, all these features are enabled
|
||||
with the <tt>-std=c++0x</tt> option when compiling C++ code.</p>
|
||||
|
||||
<h4 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
|
||||
<h4 id="cxx_decltype">C++0x <tt>decltype()</tt></h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_decltype)</tt> or
|
||||
<tt>__has_extension(cxx_decltype)</tt> to determine if support for the
|
||||
<tt>decltype()</tt> specifier is enabled.</p>
|
||||
|
||||
<h4 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h3>
|
||||
<h4 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_access_control_sfinae)</tt> or <tt>__has_extension(cxx_access_control_sfinae)</tt> to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170">C++ DR1170</a>.</p>
|
||||
|
||||
<h4 id="cxx_alias_templates">C++0x alias templates</h3>
|
||||
<h4 id="cxx_alias_templates">C++0x alias templates</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_alias_templates)</tt> or
|
||||
<tt>__has_extension(cxx_alias_templates)</tt> to determine if support for
|
||||
C++0x's alias declarations and alias templates is enabled.</p>
|
||||
|
||||
<h4 id="cxx_attributes">C++0x attributes</h3>
|
||||
<h4 id="cxx_attributes">C++0x attributes</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_attributes)</tt> or
|
||||
<tt>__has_extension(cxx_attributes)</tt> to determine if support for attribute
|
||||
parsing with C++0x's square bracket notation is enabled.</p>
|
||||
|
||||
<h4 id="cxx_default_function_template_args">C++0x default template arguments in function templates</h3>
|
||||
<h4 id="cxx_default_function_template_args">C++0x default template arguments in function templates</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_default_function_template_args)</tt> or
|
||||
<tt>__has_extension(cxx_default_function_template_args)</tt> to determine
|
||||
if support for default template arguments in function templates is enabled.</p>
|
||||
|
||||
<h4 id="cxx_deleted_functions">C++0x deleted functions</tt></h3>
|
||||
<h4 id="cxx_delegating_constructors">C++0x delegating constructors</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_delegating_constructors)</tt> to determine if
|
||||
support for delegating constructors is enabled.</p>
|
||||
|
||||
<h4 id="cxx_deleted_functions">C++0x <tt>delete</tt>d functions</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_deleted_functions)</tt> or
|
||||
<tt>__has_extension(cxx_deleted_functions)</tt> to determine if support for
|
||||
deleted function definitions (with <tt>= delete</tt>) is enabled.</p>
|
||||
|
||||
<h4 id="cxx_lambdas">C++0x lambdas</h3>
|
||||
<h4 id="cxx_lambdas">C++0x lambdas</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_lambdas)</tt> or
|
||||
<tt>__has_extension(cxx_lambdas)</tt> to determine if support for lambdas
|
||||
is enabled. clang does not currently implement this feature.</p>
|
||||
|
||||
<h4 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
|
||||
<h4 id="cxx_nullptr">C++0x <tt>nullptr</tt></h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_nullptr)</tt> or
|
||||
<tt>__has_extension(cxx_nullptr)</tt> to determine if support for
|
||||
<tt>nullptr</tt> is enabled.</p>
|
||||
|
||||
<h4 id="cxx_override_control">C++0x <tt>override control</tt></h3>
|
||||
<h4 id="cxx_override_control">C++0x <tt>override control</tt></h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_override_control)</tt> or
|
||||
<tt>__has_extension(cxx_override_control)</tt> to determine if support for
|
||||
the override control keywords is enabled.</p>
|
||||
|
||||
<h4 id="cxx_reference_qualified_functions">C++0x reference-qualified functions</h3>
|
||||
<h4 id="cxx_reference_qualified_functions">C++0x reference-qualified functions</h4>
|
||||
<p>Use <tt>__has_feature(cxx_reference_qualified_functions)</tt> or
|
||||
<tt>__has_extension(cxx_reference_qualified_functions)</tt> to determine
|
||||
if support for reference-qualified functions (e.g., member functions with
|
||||
<code>&</code> or <code>&&</code> applied to <code>*this</code>)
|
||||
is enabled.</p>
|
||||
|
||||
<h4 id="cxx_range_for">C++0x range-based for loop</tt></h3>
|
||||
<h4 id="cxx_range_for">C++0x range-based <tt>for</tt> loop</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_range_for)</tt> or
|
||||
<tt>__has_extension(cxx_range_for)</tt> to determine if support for the
|
||||
range-based for loop is enabled. </p>
|
||||
|
||||
<h4 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
|
||||
<h4 id="cxx_rvalue_references">C++0x rvalue references</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> or
|
||||
<tt>__has_extension(cxx_rvalue_references)</tt> to determine if support for
|
||||
rvalue references is enabled. </p>
|
||||
|
||||
<h4 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
|
||||
<h4 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_static_assert)</tt> or
|
||||
<tt>__has_extension(cxx_static_assert)</tt> to determine if support for
|
||||
compile-time assertions using <tt>static_assert</tt> is enabled.</p>
|
||||
|
||||
<h4 id="cxx_auto_type">C++0x type inference</h3>
|
||||
<h4 id="cxx_auto_type">C++0x type inference</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_auto_type)</tt> or
|
||||
<tt>__has_extension(cxx_auto_type)</tt> to determine C++0x type inference is
|
||||
supported using the <tt>auto</tt> specifier. If this is disabled, <tt>auto</tt>
|
||||
will instead be a storage class specifier, as in C or C++98.</p>
|
||||
|
||||
<h4 id="cxx_variadic_templates">C++0x variadic templates</h3>
|
||||
<h4 id="cxx_variadic_templates">C++0x variadic templates</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_variadic_templates)</tt> or
|
||||
<tt>__has_extension(cxx_variadic_templates)</tt> to determine if support
|
||||
for variadic templates is enabled.</p>
|
||||
|
||||
<h4 id="cxx_inline_namespaces">C++0x inline namespaces</h3>
|
||||
<h4 id="cxx_inline_namespaces">C++0x inline namespaces</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_inline_namespaces)</tt> or
|
||||
<tt>__has_extension(cxx_inline_namespaces)</tt> to determine if support for
|
||||
inline namespaces is enabled.</p>
|
||||
|
||||
<h4 id="cxx_trailing_return">C++0x trailing return type</h3>
|
||||
<h4 id="cxx_trailing_return">C++0x trailing return type</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_trailing_return)</tt> or
|
||||
<tt>__has_extension(cxx_trailing_return)</tt> to determine if support for the
|
||||
alternate function declaration syntax with trailing return type is enabled.</p>
|
||||
|
||||
<h4 id="cxx_noexcept">C++0x noexcept</h3>
|
||||
<h4 id="cxx_noexcept">C++0x noexcept</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_noexcept)</tt> or
|
||||
<tt>__has_extension(cxx_noexcept)</tt> to determine if support for noexcept
|
||||
exception specifications is enabled.</p>
|
||||
|
||||
<h4 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
|
||||
<h4 id="cxx_strong_enums">C++0x strongly typed enumerations</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(cxx_strong_enums)</tt> or
|
||||
<tt>__has_extension(cxx_strong_enums)</tt> to determine if support for
|
||||
@ -530,7 +541,7 @@ strongly typed, scoped enumerations is enabled.</p>
|
||||
C1X standard. As a result, all these features are enabled
|
||||
with the <tt>-std=c1x</tt> option when compiling C code.</p>
|
||||
|
||||
<h4 id="c_generic_selections">C1X generic selections</h2>
|
||||
<h4 id="c_generic_selections">C1X generic selections</h4>
|
||||
|
||||
<p>Use <tt>__has_feature(c_generic_selections)</tt> or
|
||||
<tt>__has_extension(c_generic_selections)</tt> to determine if support for
|
||||
@ -544,7 +555,7 @@ C1X draft standard.</p>
|
||||
appropriate standard, but in C++, which lacks the type compatibility rules
|
||||
used in C, types are considered compatible only if they are equivalent.</p>
|
||||
|
||||
<h4 id="c_static_assert">C1X <tt>_Static_assert()</tt></h3>
|
||||
<h4 id="c_static_assert">C1X <tt>_Static_assert()</tt></h4>
|
||||
|
||||
<p>Use <tt>__has_feature(c_static_assert)</tt> or
|
||||
<tt>__has_extension(c_static_assert)</tt> to determine if support for
|
||||
@ -554,7 +565,7 @@ compile-time assertions using <tt>_Static_assert</tt> is enabled.</p>
|
||||
<h2 id="checking_type_traits">Checks for Type Traits</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>Clang supports the <a hef="http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html">GNU C++ type traits</a> and a subset of the <a href="http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx">Microsoft Visual C++ Type traits</a>. For each supported type trait <code>__X</code>, <code>__has_extension(X)</code> indicates the presence of the type trait. For example:
|
||||
<p>Clang supports the <a href="http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html">GNU C++ type traits</a> and a subset of the <a href="http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx">Microsoft Visual C++ Type traits</a>. For each supported type trait <code>__X</code>, <code>__has_extension(X)</code> indicates the presence of the type trait. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#if __has_extension(is_convertible_to)
|
||||
@ -640,7 +651,7 @@ to have the type <code>NSArray *</code>. If neither <code>alloc</code> nor <code
|
||||
<p>To determine whether a method has a related result type, the first
|
||||
word in the camel-case selector (e.g., "init" in "initWithObjects") is
|
||||
considered, and the method will a related result type if its return
|
||||
type is compatible with the type of its class and if
|
||||
type is compatible with the type of its class and if</p>
|
||||
|
||||
<ul>
|
||||
|
||||
@ -650,7 +661,7 @@ type is compatible with the type of its class and if
|
||||
<li>the first word is "autorelease", "init", "retain", or "self",
|
||||
and the method is an instance method.</li>
|
||||
|
||||
</ul></p>
|
||||
</ul>
|
||||
|
||||
<p>If a method with a related result type is overridden by a subclass
|
||||
method, the subclass method must also return a type that is compatible
|
||||
@ -669,6 +680,12 @@ property access via the given method. In all other respects, a method
|
||||
with a related result type is treated the same way as method without a
|
||||
related result type.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="objc_arc">Automatic reference counting </h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>Clang provides support for <a href="AutomaticReferenceCounting.html">automated reference counting</a> in Objective-C, which eliminates the need for manual retain/release/autorelease message sends. There are two feature macros associated with automatic reference counting: <code>__has_feature(objc_arc)</code> indicates the availability of automated reference counting in general, while <code>__has_feature(objc_arc_weak)</code> indicates that automated reference counting also includes support for <code>__weak</code> pointers to Objective-C objects.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="overloading-in-c">Function Overloading in C</h2>
|
||||
<!-- ======================================================================= -->
|
||||
@ -790,7 +807,7 @@ vector support</a> instead of builtins, in order to reduce the number of
|
||||
builtins that we need to implement.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__builtin_shufflevector">__builtin_shufflevector</h3>
|
||||
<h3><a name="__builtin_shufflevector">__builtin_shufflevector</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p><tt>__builtin_shufflevector</tt> is used to express generic vector
|
||||
@ -842,7 +859,7 @@ the number of indices specified.
|
||||
<p>Query for this feature with __has_builtin(__builtin_shufflevector).</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__builtin_unreachable">__builtin_unreachable</h3>
|
||||
<h3><a name="__builtin_unreachable">__builtin_unreachable</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p><tt>__builtin_unreachable</tt> is used to indicate that a specific point in
|
||||
@ -880,7 +897,7 @@ no arguments and produces a void result.
|
||||
<p>Query for this feature with __has_builtin(__builtin_unreachable).</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3 id="__sync_swap">__sync_swap</h3>
|
||||
<h3><a name="__sync_swap">__sync_swap</a></h3>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p><tt>__sync_swap</tt> is used to atomically swap integers or pointers in
|
||||
@ -896,7 +913,7 @@ memory.
|
||||
<p><b>Example of Use:</b></p>
|
||||
|
||||
<pre>
|
||||
int old_value = __sync_swap(&value, new_value);
|
||||
int old_value = __sync_swap(&value, new_value);
|
||||
</pre>
|
||||
|
||||
<p><b>Description:</b></p>
|
||||
|
@ -846,6 +846,10 @@ variants "__asm__" and "__typeof__" are recognized in all modes.</li>
|
||||
<li>The Apple "blocks" extension is recognized by default in gnu* modes
|
||||
on some platforms; it can be enabled in any mode with the "-fblocks"
|
||||
option.</li>
|
||||
<li>Arrays that are VLA's according to the standard, but which can be constant
|
||||
folded by the frontend are treated as fixed size arrays. This occurs for
|
||||
things like "int X[(1, 2)];", which is technically a VLA. c* modes are
|
||||
strictly compliant and treat these as VLAs.</li>
|
||||
</ul>
|
||||
|
||||
<p>Differences between *89 and *99 modes:</p>
|
||||
@ -882,11 +886,6 @@ extensions are not implemented yet:</p>
|
||||
the uses described in the bug, this is likely to be implemented at some
|
||||
point, at least partially.</li>
|
||||
|
||||
<li>clang does not support code generation for local variables pinned to
|
||||
registers (<a href="http://llvm.org/bugs/show_bug.cgi?id=3933">bug 3933</a>).
|
||||
This is a relatively small feature, so it is likely to be implemented
|
||||
relatively soon.</li>
|
||||
|
||||
<li>clang does not support decimal floating point types (_Decimal32 and
|
||||
friends) or fixed-point types (_Fract and friends); nobody has expressed
|
||||
interest in these features yet, so it's hard to say when they will be
|
||||
@ -937,16 +936,9 @@ extension appears to be rarely used. Note that clang <em>does</em> support
|
||||
flexible array members (arrays with a zero or unspecified size at the end of
|
||||
a structure).</li>
|
||||
|
||||
<li>clang does not support duplicate definitions of a function where one is
|
||||
inline. This complicates clients of the AST which normally can expect there is
|
||||
at most one definition for each function. Source code using this feature should
|
||||
be changed to define the inline and out-of-line definitions in separate
|
||||
translation units.</li>
|
||||
|
||||
<li>clang does not have an equivalent to gcc's "fold"; this means that
|
||||
clang doesn't accept some constructs gcc might accept in contexts where a
|
||||
constant expression is required, like "x-x" where x is a variable, or calls
|
||||
to C library functions like strlen.</li>
|
||||
constant expression is required, like "x-x" where x is a variable.</li>
|
||||
|
||||
<li>clang does not support multiple alternative constraints in inline asm; this
|
||||
is an extremely obscure feature which would be complicated to implement
|
||||
|
@ -1,4 +0,0 @@
|
||||
<title>'clang' C frontend documentation</title>
|
||||
|
||||
None yet, sorry :(
|
||||
|
@ -833,14 +833,24 @@ enum CXTranslationUnit_Flags {
|
||||
|
||||
/**
|
||||
* \brief Used to indicate that the "detailed" preprocessing record,
|
||||
* if requested, should also contain nested macro instantiations.
|
||||
* if requested, should also contain nested macro expansions.
|
||||
*
|
||||
* Nested macro instantiations (i.e., macro instantiations that occur
|
||||
* inside another macro instantiation) can, in some code bases, require
|
||||
* Nested macro expansions (i.e., macro expansions that occur
|
||||
* inside another macro expansion) can, in some code bases, require
|
||||
* a large amount of storage to due preprocessor metaprogramming. Moreover,
|
||||
* its fairly rare that this information is useful for libclang clients.
|
||||
*/
|
||||
CXTranslationUnit_NestedMacroInstantiations = 0x40
|
||||
CXTranslationUnit_NestedMacroExpansions = 0x40,
|
||||
|
||||
/**
|
||||
* \brief Legacy name to indicate that the "detailed" preprocessing record,
|
||||
* if requested, should contain nested macro expansions.
|
||||
*
|
||||
* \see CXTranslationUnit_NestedMacroExpansions for the current name for this
|
||||
* value, and its semantics. This is just an alias.
|
||||
*/
|
||||
CXTranslationUnit_NestedMacroInstantiations =
|
||||
CXTranslationUnit_NestedMacroExpansions
|
||||
};
|
||||
|
||||
/**
|
||||
@ -932,6 +942,41 @@ enum CXSaveTranslationUnit_Flags {
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
|
||||
|
||||
/**
|
||||
* \brief Describes the kind of error that occurred (if any) in a call to
|
||||
* \c clang_saveTranslationUnit().
|
||||
*/
|
||||
enum CXSaveError {
|
||||
/**
|
||||
* \brief Indicates that no error occurred while saving a translation unit.
|
||||
*/
|
||||
CXSaveError_None = 0,
|
||||
|
||||
/**
|
||||
* \brief Indicates that an unknown error occurred while attempting to save
|
||||
* the file.
|
||||
*
|
||||
* This error typically indicates that file I/O failed when attempting to
|
||||
* write the file.
|
||||
*/
|
||||
CXSaveError_Unknown = 1,
|
||||
|
||||
/**
|
||||
* \brief Indicates that errors during translation prevented this attempt
|
||||
* to save the translation unit.
|
||||
*
|
||||
* Errors that prevent the translation unit from being saved can be
|
||||
* extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic().
|
||||
*/
|
||||
CXSaveError_TranslationErrors = 2,
|
||||
|
||||
/**
|
||||
* \brief Indicates that the translation unit to be saved was somehow
|
||||
* invalid (e.g., NULL).
|
||||
*/
|
||||
CXSaveError_InvalidTU = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Saves a translation unit into a serialized representation of
|
||||
* that translation unit on disk.
|
||||
@ -951,8 +996,9 @@ CINDEX_LINKAGE unsigned clang_defaultSaveOptions(CXTranslationUnit TU);
|
||||
* is saved. This should be a bitwise OR of the
|
||||
* CXSaveTranslationUnit_XXX flags.
|
||||
*
|
||||
* \returns Zero if the translation unit was saved successfully, a
|
||||
* non-zero value otherwise.
|
||||
* \returns A value that will match one of the enumerators of the CXSaveError
|
||||
* enumeration. Zero (CXSaveError_None) indicates that the translation unit was
|
||||
* saved successfully, while a non-zero value indicates that a problem occurred.
|
||||
*/
|
||||
CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU,
|
||||
const char *FileName,
|
||||
@ -1385,7 +1431,8 @@ enum CXCursorKind {
|
||||
/* Preprocessing */
|
||||
CXCursor_PreprocessingDirective = 500,
|
||||
CXCursor_MacroDefinition = 501,
|
||||
CXCursor_MacroInstantiation = 502,
|
||||
CXCursor_MacroExpansion = 502,
|
||||
CXCursor_MacroInstantiation = CXCursor_MacroExpansion,
|
||||
CXCursor_InclusionDirective = 503,
|
||||
CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective,
|
||||
CXCursor_LastPreprocessing = CXCursor_InclusionDirective
|
||||
@ -1473,6 +1520,11 @@ CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind);
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind);
|
||||
|
||||
/**
|
||||
* \brief Determine whether the given cursor kind represents an attribute.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind);
|
||||
|
||||
/**
|
||||
* \brief Determine whether the given cursor kind represents an invalid
|
||||
* cursor.
|
||||
@ -2829,6 +2881,137 @@ enum CXCodeComplete_Flags {
|
||||
CXCodeComplete_IncludeCodePatterns = 0x02
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Bits that represent the context under which completion is occurring.
|
||||
*
|
||||
* The enumerators in this enumeration may be bitwise-OR'd together if multiple
|
||||
* contexts are occurring simultaneously.
|
||||
*/
|
||||
enum CXCompletionContext {
|
||||
/**
|
||||
* \brief The context for completions is unexposed, as only Clang results
|
||||
* should be included. (This is equivalent to having no context bits set.)
|
||||
*/
|
||||
CXCompletionContext_Unexposed = 0,
|
||||
|
||||
/**
|
||||
* \brief Completions for any possible type should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_AnyType = 1 << 0,
|
||||
|
||||
/**
|
||||
* \brief Completions for any possible value (variables, function calls, etc.)
|
||||
* should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_AnyValue = 1 << 1,
|
||||
/**
|
||||
* \brief Completions for values that resolve to an Objective-C object should
|
||||
* be included in the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCObjectValue = 1 << 2,
|
||||
/**
|
||||
* \brief Completions for values that resolve to an Objective-C selector
|
||||
* should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCSelectorValue = 1 << 3,
|
||||
/**
|
||||
* \brief Completions for values that resolve to a C++ class type should be
|
||||
* included in the results.
|
||||
*/
|
||||
CXCompletionContext_CXXClassTypeValue = 1 << 4,
|
||||
|
||||
/**
|
||||
* \brief Completions for fields of the member being accessed using the dot
|
||||
* operator should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_DotMemberAccess = 1 << 5,
|
||||
/**
|
||||
* \brief Completions for fields of the member being accessed using the arrow
|
||||
* operator should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_ArrowMemberAccess = 1 << 6,
|
||||
/**
|
||||
* \brief Completions for properties of the Objective-C object being accessed
|
||||
* using the dot operator should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCPropertyAccess = 1 << 7,
|
||||
|
||||
/**
|
||||
* \brief Completions for enum tags should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_EnumTag = 1 << 8,
|
||||
/**
|
||||
* \brief Completions for union tags should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_UnionTag = 1 << 9,
|
||||
/**
|
||||
* \brief Completions for struct tags should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_StructTag = 1 << 10,
|
||||
|
||||
/**
|
||||
* \brief Completions for C++ class names should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_ClassTag = 1 << 11,
|
||||
/**
|
||||
* \brief Completions for C++ namespaces and namespace aliases should be
|
||||
* included in the results.
|
||||
*/
|
||||
CXCompletionContext_Namespace = 1 << 12,
|
||||
/**
|
||||
* \brief Completions for C++ nested name specifiers should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_NestedNameSpecifier = 1 << 13,
|
||||
|
||||
/**
|
||||
* \brief Completions for Objective-C interfaces (classes) should be included
|
||||
* in the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCInterface = 1 << 14,
|
||||
/**
|
||||
* \brief Completions for Objective-C protocols should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCProtocol = 1 << 15,
|
||||
/**
|
||||
* \brief Completions for Objective-C categories should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCCategory = 1 << 16,
|
||||
/**
|
||||
* \brief Completions for Objective-C instance messages should be included
|
||||
* in the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCInstanceMessage = 1 << 17,
|
||||
/**
|
||||
* \brief Completions for Objective-C class messages should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCClassMessage = 1 << 18,
|
||||
/**
|
||||
* \brief Completions for Objective-C selector names should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_ObjCSelectorName = 1 << 19,
|
||||
|
||||
/**
|
||||
* \brief Completions for preprocessor macro names should be included in
|
||||
* the results.
|
||||
*/
|
||||
CXCompletionContext_MacroName = 1 << 20,
|
||||
|
||||
/**
|
||||
* \brief Natural language completions should be included in the results.
|
||||
*/
|
||||
CXCompletionContext_NaturalLanguage = 1 << 21,
|
||||
|
||||
/**
|
||||
* \brief The current context is unknown, so set all contexts.
|
||||
*/
|
||||
CXCompletionContext_Unknown = ((1 << 22) - 1)
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Returns a default set of code-completion options that can be
|
||||
* passed to\c clang_codeCompleteAt().
|
||||
@ -2949,6 +3132,19 @@ CINDEX_LINKAGE
|
||||
CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
|
||||
unsigned Index);
|
||||
|
||||
/**
|
||||
* \brief Determines what compeltions are appropriate for the context
|
||||
* the given code completion.
|
||||
*
|
||||
* \param Results the code completion results to query
|
||||
*
|
||||
* \returns the kinds of completions that are appropriate for use
|
||||
* along with the given code completion results.
|
||||
*/
|
||||
CINDEX_LINKAGE
|
||||
unsigned long long clang_codeCompleteGetContexts(
|
||||
CXCodeCompleteResults *Results);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@ -3001,6 +3197,51 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu,
|
||||
CXInclusionVisitor visitor,
|
||||
CXClientData client_data);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** \defgroup CINDEX_REMAPPING Remapping functions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A remapping of original source files and their translated files.
|
||||
*/
|
||||
typedef void *CXRemapping;
|
||||
|
||||
/**
|
||||
* \brief Retrieve a remapping.
|
||||
*
|
||||
* \param path the path that contains metadata about remappings.
|
||||
*
|
||||
* \returns the requested remapping. This remapping must be freed
|
||||
* via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
|
||||
*/
|
||||
CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path);
|
||||
|
||||
/**
|
||||
* \brief Determine the number of remappings.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping);
|
||||
|
||||
/**
|
||||
* \brief Get the original and the associated filename from the remapping.
|
||||
*
|
||||
* \param original If non-NULL, will be set to the original filename.
|
||||
*
|
||||
* \param transformed If non-NULL, will be set to the filename that the original
|
||||
* is associated with.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index,
|
||||
CXString *original, CXString *transformed);
|
||||
|
||||
/**
|
||||
* \brief Dispose the remapping.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_remap_dispose(CXRemapping);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
94
include/clang/ARCMigrate/ARCMT.h
Normal file
94
include/clang/ARCMigrate/ARCMT.h
Normal file
@ -0,0 +1,94 @@
|
||||
//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_ARCMT_H
|
||||
|
||||
#include "clang/ARCMigrate/FileRemapper.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class DiagnosticClient;
|
||||
|
||||
namespace arcmt {
|
||||
class MigrationPass;
|
||||
|
||||
/// \brief Creates an AST with the provided CompilerInvocation but with these
|
||||
/// changes:
|
||||
/// -if a PCH/PTH is set, the original header is used instead
|
||||
/// -Automatic Reference Counting mode is enabled
|
||||
///
|
||||
/// It then checks the AST and produces errors/warning for ARC migration issues
|
||||
/// that the user needs to handle manually.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool checkForManualIssues(CompilerInvocation &CI,
|
||||
llvm::StringRef Filename, InputKind Kind,
|
||||
DiagnosticClient *DiagClient);
|
||||
|
||||
/// \brief Works similar to checkForManualIssues but instead of checking, it
|
||||
/// applies automatic modifications to source files to conform to ARC.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool applyTransformations(CompilerInvocation &origCI,
|
||||
llvm::StringRef Filename, InputKind Kind,
|
||||
DiagnosticClient *DiagClient);
|
||||
|
||||
/// \brief Applies automatic modifications and produces temporary files
|
||||
/// and metadata into the \arg outputDir path.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
|
||||
llvm::StringRef Filename, InputKind Kind,
|
||||
DiagnosticClient *DiagClient,
|
||||
llvm::StringRef outputDir);
|
||||
|
||||
/// \brief Get the set of file remappings from the \arg outputDir path that
|
||||
/// migrateWithTemporaryFiles produced.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
|
||||
llvm::StringRef outputDir,
|
||||
DiagnosticClient *DiagClient);
|
||||
|
||||
typedef void (*TransformFn)(MigrationPass &pass);
|
||||
|
||||
std::vector<TransformFn> getAllTransformations();
|
||||
|
||||
class MigrationProcess {
|
||||
CompilerInvocation OrigCI;
|
||||
DiagnosticClient *DiagClient;
|
||||
FileRemapper Remapper;
|
||||
|
||||
public:
|
||||
MigrationProcess(const CompilerInvocation &CI, DiagnosticClient *diagClient,
|
||||
llvm::StringRef outputDir = llvm::StringRef());
|
||||
|
||||
class RewriteListener {
|
||||
public:
|
||||
virtual ~RewriteListener();
|
||||
|
||||
virtual void start(ASTContext &Ctx) { }
|
||||
virtual void finish() { }
|
||||
|
||||
virtual void insert(SourceLocation loc, llvm::StringRef text) { }
|
||||
virtual void remove(CharSourceRange range) { }
|
||||
};
|
||||
|
||||
bool applyTransform(TransformFn trans, RewriteListener *listener = 0);
|
||||
|
||||
FileRemapper &getRemapper() { return Remapper; }
|
||||
};
|
||||
|
||||
} // end namespace arcmt
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
47
include/clang/ARCMigrate/ARCMTActions.h
Normal file
47
include/clang/ARCMigrate/ARCMTActions.h
Normal file
@ -0,0 +1,47 @@
|
||||
//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
|
||||
|
||||
#include "clang/Frontend/FrontendAction.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
|
||||
namespace clang {
|
||||
namespace arcmt {
|
||||
|
||||
class CheckAction : public WrapperFrontendAction {
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
CheckAction(FrontendAction *WrappedAction);
|
||||
};
|
||||
|
||||
class ModifyAction : public WrapperFrontendAction {
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
ModifyAction(FrontendAction *WrappedAction);
|
||||
};
|
||||
|
||||
class MigrateAction : public WrapperFrontendAction {
|
||||
std::string MigrateDir;
|
||||
protected:
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
|
||||
public:
|
||||
MigrateAction(FrontendAction *WrappedAction, llvm::StringRef migrateDir);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
76
include/clang/ARCMigrate/FileRemapper.h
Normal file
76
include/clang/ARCMigrate/FileRemapper.h
Normal file
@ -0,0 +1,76 @@
|
||||
//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
|
||||
#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
class FileManager;
|
||||
class FileEntry;
|
||||
class Diagnostic;
|
||||
class CompilerInvocation;
|
||||
|
||||
namespace arcmt {
|
||||
|
||||
class FileRemapper {
|
||||
// FIXME: Reuse the same FileManager for multiple ASTContexts.
|
||||
llvm::OwningPtr<FileManager> FileMgr;
|
||||
|
||||
typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
|
||||
typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
|
||||
MappingsTy FromToMappings;
|
||||
|
||||
llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings;
|
||||
|
||||
public:
|
||||
FileRemapper();
|
||||
~FileRemapper();
|
||||
|
||||
bool initFromDisk(llvm::StringRef outputDir, Diagnostic &Diag,
|
||||
bool ignoreIfFilesChanged);
|
||||
bool flushToDisk(llvm::StringRef outputDir, Diagnostic &Diag);
|
||||
|
||||
bool overwriteOriginal(Diagnostic &Diag,
|
||||
llvm::StringRef outputDir = llvm::StringRef());
|
||||
|
||||
void remap(llvm::StringRef filePath, llvm::MemoryBuffer *memBuf);
|
||||
void remap(llvm::StringRef filePath, llvm::StringRef newPath);
|
||||
|
||||
void applyMappings(CompilerInvocation &CI) const;
|
||||
|
||||
void transferMappingsAndClear(CompilerInvocation &CI);
|
||||
|
||||
void clear(llvm::StringRef outputDir = llvm::StringRef());
|
||||
|
||||
private:
|
||||
void remap(const FileEntry *file, llvm::MemoryBuffer *memBuf);
|
||||
void remap(const FileEntry *file, const FileEntry *newfile);
|
||||
|
||||
const FileEntry *getOriginalFile(llvm::StringRef filePath);
|
||||
void resetTarget(Target &targ);
|
||||
|
||||
bool report(const std::string &err, Diagnostic &Diag);
|
||||
|
||||
std::string getRemapInfoFile(llvm::StringRef outputDir);
|
||||
};
|
||||
|
||||
} // end namespace arcmt
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -124,7 +124,10 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
|
||||
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
|
||||
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
|
||||
mutable llvm::FoldingSet<SubstTemplateTemplateParmPackStorage>
|
||||
mutable llvm::FoldingSet<SubstTemplateTemplateParmStorage>
|
||||
SubstTemplateTemplateParms;
|
||||
mutable llvm::ContextualFoldingSet<SubstTemplateTemplateParmPackStorage,
|
||||
ASTContext&>
|
||||
SubstTemplateTemplateParmPacks;
|
||||
|
||||
/// \brief The set of nested name specifiers.
|
||||
@ -993,6 +996,18 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
return getExtQualType(T, Qs);
|
||||
}
|
||||
|
||||
/// getLifetimeQualifiedType - Returns a type with the given
|
||||
/// lifetime qualifier.
|
||||
QualType getLifetimeQualifiedType(QualType type,
|
||||
Qualifiers::ObjCLifetime lifetime) {
|
||||
assert(type.getObjCLifetime() == Qualifiers::OCL_None);
|
||||
assert(lifetime != Qualifiers::OCL_None);
|
||||
|
||||
Qualifiers qs;
|
||||
qs.addObjCLifetime(lifetime);
|
||||
return getQualifiedType(type, qs);
|
||||
}
|
||||
|
||||
DeclarationNameInfo getNameForTemplate(TemplateName Name,
|
||||
SourceLocation NameLoc) const;
|
||||
|
||||
@ -1007,6 +1022,8 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
const IdentifierInfo *Name) const;
|
||||
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
|
||||
OverloadedOperatorKind Operator) const;
|
||||
TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
|
||||
TemplateName replacement) const;
|
||||
TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
|
||||
const TemplateArgument &ArgPack) const;
|
||||
|
||||
@ -1044,7 +1061,9 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
|
||||
/// isObjCNSObjectType - Return true if this is an NSObject object with
|
||||
/// its NSObject attribute set.
|
||||
bool isObjCNSObjectType(QualType Ty) const;
|
||||
static bool isObjCNSObjectType(QualType Ty) {
|
||||
return Ty->isObjCNSObjectType();
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Sizing and Analysis
|
||||
@ -1315,6 +1334,18 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
/// getConstantArrayElementCount - Returns number of constant array elements.
|
||||
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
|
||||
|
||||
/// \brief Perform adjustment on the parameter type of a function.
|
||||
///
|
||||
/// This routine adjusts the given parameter type @p T to the actual
|
||||
/// parameter type used by semantic analysis (C99 6.7.5.3p[7,8],
|
||||
/// C++ [dcl.fct]p3). The adjusted parameter type is returned.
|
||||
QualType getAdjustedParameterType(QualType T);
|
||||
|
||||
/// \brief Retrieve the parameter type as adjusted for use in the signature
|
||||
/// of a function, decaying array and function types and removing top-level
|
||||
/// cv-qualifiers.
|
||||
QualType getSignatureParameterType(QualType T);
|
||||
|
||||
/// getArrayDecayedType - Return the properly qualified result of decaying the
|
||||
/// specified array type to a pointer. This operation is non-trivial when
|
||||
/// handling typedefs etc. The canonical type of "T" must be an array type,
|
||||
@ -1328,6 +1359,10 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
/// integer type.
|
||||
QualType getPromotedIntegerType(QualType PromotableType) const;
|
||||
|
||||
/// \brief Recurses in pointer/array types until it finds an objc retainable
|
||||
/// type and returns its ownership.
|
||||
Qualifiers::ObjCLifetime getInnerObjCOwnership(QualType T) const;
|
||||
|
||||
/// \brief Whether this is a promotable bitfield reference according
|
||||
/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
|
||||
///
|
||||
@ -1382,6 +1417,7 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
|
||||
bool typesAreCompatible(QualType T1, QualType T2,
|
||||
bool CompareUnqualified = false); // C99 6.2.7p1
|
||||
|
||||
bool propertyTypesAreCompatible(QualType, QualType);
|
||||
bool typesAreBlockPointerCompatible(QualType, QualType);
|
||||
|
||||
bool isObjCIdType(QualType T) const {
|
||||
|
@ -33,16 +33,18 @@ namespace clang {
|
||||
/// diagnostics. It is meant to be used as the argument to
|
||||
/// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
|
||||
/// pointer.
|
||||
void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
|
||||
intptr_t Val,
|
||||
const char *Modifier,
|
||||
unsigned ModLen,
|
||||
const char *Argument,
|
||||
unsigned ArgLen,
|
||||
const Diagnostic::ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie);
|
||||
void FormatASTNodeDiagnosticArgument(
|
||||
Diagnostic::ArgumentKind Kind,
|
||||
intptr_t Val,
|
||||
const char *Modifier,
|
||||
unsigned ModLen,
|
||||
const char *Argument,
|
||||
unsigned ArgLen,
|
||||
const Diagnostic::ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie,
|
||||
llvm::SmallVectorImpl<intptr_t> &QualTypeVals);
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -250,7 +250,6 @@ class CanProxyBase {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPODType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isEnumeralType)
|
||||
@ -295,6 +294,7 @@ class CanProxyBase {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
|
||||
|
||||
/// \brief Retrieve the proxy-adaptor type.
|
||||
///
|
||||
|
@ -702,8 +702,12 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
/// \brief Whether this variable is the for-range-declaration in a C++0x
|
||||
/// for-range statement.
|
||||
unsigned CXXForRangeDecl : 1;
|
||||
|
||||
/// \brief Whether this variable is an ARC pseudo-__strong
|
||||
/// variable; see isARCPseudoStrong() for details.
|
||||
unsigned ARCPseudoStrong : 1;
|
||||
};
|
||||
enum { NumVarDeclBits = 13 }; // two reserved bits for now
|
||||
enum { NumVarDeclBits = 13 }; // one reserved bit
|
||||
|
||||
friend class ASTDeclReader;
|
||||
friend class StmtIteratorBase;
|
||||
@ -975,6 +979,20 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
|
||||
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;
|
||||
|
||||
EvaluatedStmt *EnsureEvaluatedStmt() const {
|
||||
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
|
||||
if (!Eval) {
|
||||
@ -1102,6 +1120,13 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
/// a C++0x for-range statement.
|
||||
bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
|
||||
void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
|
||||
|
||||
/// \brief Determine whether this variable is an ARC pseudo-__strong
|
||||
/// variable. A pseudo-__strong variable has a __strong-qualified
|
||||
/// type but does not actually retain the object written into it.
|
||||
/// Generally such variables are also 'const' for safety.
|
||||
bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; }
|
||||
void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; }
|
||||
|
||||
/// \brief If this variable is an instantiated static data member of a
|
||||
/// class template specialization, returns the templated static data member
|
||||
@ -2014,6 +2039,11 @@ class FieldDecl : public DeclaratorDecl {
|
||||
InitializerOrBitWidth.setPointer(BW);
|
||||
InitializerOrBitWidth.setInt(1);
|
||||
}
|
||||
/// removeBitWidth - Remove the bitfield width from this member.
|
||||
void removeBitWidth() {
|
||||
assert(isBitField() && "no bit width to remove");
|
||||
InitializerOrBitWidth.setPointer(0);
|
||||
}
|
||||
|
||||
/// hasInClassInitializer - Determine whether this member has a C++0x in-class
|
||||
/// initializer.
|
||||
@ -2956,6 +2986,8 @@ class BlockDecl : public Decl, public DeclContext {
|
||||
|
||||
bool capturesCXXThis() const { return CapturesCXXThis; }
|
||||
|
||||
bool capturesVariable(const VarDecl *var) const;
|
||||
|
||||
void setCaptures(ASTContext &Context,
|
||||
const Capture *begin,
|
||||
const Capture *end,
|
||||
|
@ -381,7 +381,24 @@ class Decl {
|
||||
attr_iterator attr_end() const {
|
||||
return hasAttrs() ? getAttrs().end() : 0;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void dropAttr() {
|
||||
if (!HasAttrs) return;
|
||||
|
||||
AttrVec &Attrs = getAttrs();
|
||||
for (unsigned i = 0, e = Attrs.size(); i != e; /* in loop */) {
|
||||
if (isa<T>(Attrs[i])) {
|
||||
Attrs.erase(Attrs.begin() + i);
|
||||
--e;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
if (Attrs.empty())
|
||||
HasAttrs = false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
specific_attr_iterator<T> specific_attr_begin() const {
|
||||
return specific_attr_iterator<T>(attr_begin());
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/TypeLoc.h"
|
||||
#include "clang/AST/UnresolvedSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -641,6 +641,18 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isArcWeakrefUnavailable - Checks for a class or one of its super classes
|
||||
/// to be incompatible with __weak references. Returns true if it is.
|
||||
bool isArcWeakrefUnavailable() const {
|
||||
const ObjCInterfaceDecl *Class = this;
|
||||
while (Class) {
|
||||
if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
|
||||
return true;
|
||||
Class = Class->getSuperClass();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
|
||||
ObjCInterfaceDecl *&ClassDeclared);
|
||||
ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
|
||||
@ -1240,6 +1252,9 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
/// IvarInitializers - The arguments used to initialize the ivars
|
||||
CXXCtorInitializer **IvarInitializers;
|
||||
unsigned NumIvarInitializers;
|
||||
|
||||
/// true if class has a .cxx_[construct,destruct] method.
|
||||
bool HasCXXStructors : 1;
|
||||
|
||||
/// true of class extension has at least one bitfield ivar.
|
||||
bool HasSynthBitfield : 1;
|
||||
@ -1249,7 +1264,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
ObjCInterfaceDecl *superDecl)
|
||||
: ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
|
||||
SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
|
||||
HasSynthBitfield(false) {}
|
||||
HasCXXStructors(false), HasSynthBitfield(false) {}
|
||||
public:
|
||||
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
@ -1287,6 +1302,9 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
void setIvarInitializers(ASTContext &C,
|
||||
CXXCtorInitializer ** initializers,
|
||||
unsigned numInitializers);
|
||||
|
||||
bool hasCXXStructors() const { return HasCXXStructors; }
|
||||
void setHasCXXStructors(bool val) { HasCXXStructors = val; }
|
||||
|
||||
bool hasSynthBitfield() const { return HasSynthBitfield; }
|
||||
void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
|
||||
@ -1393,7 +1411,16 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
OBJC_PR_copy = 0x20,
|
||||
OBJC_PR_nonatomic = 0x40,
|
||||
OBJC_PR_setter = 0x80,
|
||||
OBJC_PR_atomic = 0x100
|
||||
OBJC_PR_atomic = 0x100,
|
||||
OBJC_PR_weak = 0x200,
|
||||
OBJC_PR_strong = 0x400,
|
||||
OBJC_PR_unsafe_unretained = 0x800
|
||||
// Adding a property should change NumPropertyAttrsBits
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 12
|
||||
};
|
||||
|
||||
enum SetterKind { Assign, Retain, Copy };
|
||||
@ -1401,8 +1428,8 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
private:
|
||||
SourceLocation AtLoc; // location of @property
|
||||
TypeSourceInfo *DeclType;
|
||||
unsigned PropertyAttributes : 9;
|
||||
unsigned PropertyAttributesAsWritten : 9;
|
||||
unsigned PropertyAttributes : NumPropertyAttrsBits;
|
||||
unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
|
||||
// @required/@optional
|
||||
unsigned PropertyImplementation : 2;
|
||||
|
||||
@ -1445,6 +1472,12 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
PropertyAttributeKind getPropertyAttributesAsWritten() const {
|
||||
return PropertyAttributeKind(PropertyAttributesAsWritten);
|
||||
}
|
||||
|
||||
bool hasWrittenStorageAttribute() const {
|
||||
return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
|
||||
OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
|
||||
OBJC_PR_weak);
|
||||
}
|
||||
|
||||
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
|
||||
PropertyAttributesAsWritten = PRVal;
|
||||
@ -1466,7 +1499,7 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
/// the property setter. This is only valid if the property has been
|
||||
/// defined to have a setter.
|
||||
SetterKind getSetterKind() const {
|
||||
if (PropertyAttributes & OBJC_PR_retain)
|
||||
if (PropertyAttributes & (OBJC_PR_retain|OBJC_PR_strong))
|
||||
return Retain;
|
||||
if (PropertyAttributes & OBJC_PR_copy)
|
||||
return Copy;
|
||||
|
@ -314,6 +314,10 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
|
||||
return (TemplateSpecializationKind)(Template.getInt() + 1);
|
||||
}
|
||||
|
||||
bool isExplicitSpecialization() const {
|
||||
return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
|
||||
}
|
||||
|
||||
/// \brief Set the template specialization kind.
|
||||
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
|
||||
assert(TSK != TSK_Undeclared &&
|
||||
@ -1398,6 +1402,10 @@ class ClassTemplateSpecializationDecl
|
||||
return static_cast<TemplateSpecializationKind>(SpecializationKind);
|
||||
}
|
||||
|
||||
bool isExplicitSpecialization() const {
|
||||
return getSpecializationKind() == TSK_ExplicitSpecialization;
|
||||
}
|
||||
|
||||
void setSpecializationKind(TemplateSpecializationKind TSK) {
|
||||
SpecializationKind = TSK;
|
||||
}
|
||||
|
@ -492,6 +492,9 @@ struct DeclarationNameInfo {
|
||||
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this name involves a template parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Determine whether this name contains an unexpanded
|
||||
/// parameter pack.
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
@ -57,9 +57,12 @@ class Expr : public Stmt {
|
||||
|
||||
protected:
|
||||
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
|
||||
bool TD, bool VD, bool ContainsUnexpandedParameterPack) : Stmt(SC) {
|
||||
bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
|
||||
: Stmt(SC)
|
||||
{
|
||||
ExprBits.TypeDependent = TD;
|
||||
ExprBits.ValueDependent = VD;
|
||||
ExprBits.InstantiationDependent = ID;
|
||||
ExprBits.ValueKind = VK;
|
||||
ExprBits.ObjectKind = OK;
|
||||
ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
|
||||
@ -95,7 +98,11 @@ class Expr : public Stmt {
|
||||
bool isValueDependent() const { return ExprBits.ValueDependent; }
|
||||
|
||||
/// \brief Set whether this expression is value-dependent or not.
|
||||
void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; }
|
||||
void setValueDependent(bool VD) {
|
||||
ExprBits.ValueDependent = VD;
|
||||
if (VD)
|
||||
ExprBits.InstantiationDependent = true;
|
||||
}
|
||||
|
||||
/// isTypeDependent - Determines whether this expression is
|
||||
/// type-dependent (C++ [temp.dep.expr]), which means that its type
|
||||
@ -111,7 +118,37 @@ class Expr : public Stmt {
|
||||
bool isTypeDependent() const { return ExprBits.TypeDependent; }
|
||||
|
||||
/// \brief Set whether this expression is type-dependent or not.
|
||||
void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; }
|
||||
void setTypeDependent(bool TD) {
|
||||
ExprBits.TypeDependent = TD;
|
||||
if (TD)
|
||||
ExprBits.InstantiationDependent = true;
|
||||
}
|
||||
|
||||
/// \brief Whether this expression is instantiation-dependent, meaning that
|
||||
/// it depends in some way on a template parameter, even if neither its type
|
||||
/// nor (constant) value can change due to the template instantiation.
|
||||
///
|
||||
/// In the following example, the expression \c sizeof(sizeof(T() + T())) is
|
||||
/// instantiation-dependent (since it involves a template parameter \c T), but
|
||||
/// is neither type- nor value-dependent, since the type of the inner
|
||||
/// \c sizeof is known (\c std::size_t) and therefore the size of the outer
|
||||
/// \c sizeof is known.
|
||||
///
|
||||
/// \code
|
||||
/// template<typename T>
|
||||
/// void f(T x, T y) {
|
||||
/// sizeof(sizeof(T() + T());
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
bool isInstantiationDependent() const {
|
||||
return ExprBits.InstantiationDependent;
|
||||
}
|
||||
|
||||
/// \brief Set whether this expression is instantiation-dependent or not.
|
||||
void setInstantiationDependent(bool ID) {
|
||||
ExprBits.InstantiationDependent = ID;
|
||||
}
|
||||
|
||||
/// \brief Whether this expression contains an unexpanded parameter
|
||||
/// pack (for C++0x variadic templates).
|
||||
@ -501,6 +538,14 @@ class Expr : public Stmt {
|
||||
/// the rules of C++ [expr.unary.noexcept].
|
||||
CanThrowResult CanThrow(ASTContext &C) const;
|
||||
|
||||
/// IgnoreImpCasts - Skip past any implicit casts which might
|
||||
/// surround this expression. Only skips ImplicitCastExprs.
|
||||
Expr *IgnoreImpCasts();
|
||||
|
||||
/// IgnoreImplicit - Skip past any implicit AST nodes which might
|
||||
/// surround this expression.
|
||||
Expr *IgnoreImplicit() { return cast<Expr>(Stmt::IgnoreImplicit()); }
|
||||
|
||||
/// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
|
||||
/// its subexpression. If that subexpression is also a ParenExpr,
|
||||
/// then this method recursively returns its subexpression, and so forth.
|
||||
@ -555,7 +600,10 @@ class Expr : public Stmt {
|
||||
|
||||
/// \brief Whether this expression is an implicit reference to 'this' in C++.
|
||||
bool isImplicitCXXThis() const;
|
||||
|
||||
|
||||
const Expr *IgnoreImpCasts() const {
|
||||
return const_cast<Expr*>(this)->IgnoreImpCasts();
|
||||
}
|
||||
const Expr *IgnoreParens() const {
|
||||
return const_cast<Expr*>(this)->IgnoreParens();
|
||||
}
|
||||
@ -595,7 +643,9 @@ class OpaqueValueExpr : public Expr {
|
||||
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
|
||||
ExprObjectKind OK = OK_Ordinary)
|
||||
: Expr(OpaqueValueExprClass, T, VK, OK,
|
||||
T->isDependentType(), T->isDependentType(), false),
|
||||
T->isDependentType(), T->isDependentType(),
|
||||
T->isInstantiationDependentType(),
|
||||
false),
|
||||
SourceExpr(0), Loc(Loc) {
|
||||
}
|
||||
|
||||
@ -664,7 +714,8 @@ struct ExplicitTemplateArgumentList {
|
||||
|
||||
void initializeFrom(const TemplateArgumentListInfo &List);
|
||||
void initializeFrom(const TemplateArgumentListInfo &List,
|
||||
bool &Dependent, bool &ContainsUnexpandedParameterPack);
|
||||
bool &Dependent, bool &InstantiationDependent,
|
||||
bool &ContainsUnexpandedParameterPack);
|
||||
void copyInto(TemplateArgumentListInfo &List) const;
|
||||
static std::size_t sizeFor(unsigned NumTemplateArgs);
|
||||
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
|
||||
@ -746,9 +797,10 @@ class DeclRefExpr : public Expr {
|
||||
void computeDependence();
|
||||
|
||||
public:
|
||||
DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L)
|
||||
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
|
||||
D(D), Loc(L) {
|
||||
DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L,
|
||||
const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
|
||||
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
|
||||
D(D), Loc(L), DNLoc(LocInfo) {
|
||||
DeclRefExprBits.HasQualifier = 0;
|
||||
DeclRefExprBits.HasExplicitTemplateArgs = 0;
|
||||
DeclRefExprBits.HasFoundDecl = 0;
|
||||
@ -936,6 +988,7 @@ class PredefinedExpr : public Expr {
|
||||
PredefinedExpr(SourceLocation l, QualType type, IdentType IT)
|
||||
: Expr(PredefinedExprClass, type, VK_LValue, OK_Ordinary,
|
||||
type->isDependentType(), type->isDependentType(),
|
||||
type->isInstantiationDependentType(),
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Loc(l), Type(IT) {}
|
||||
|
||||
@ -1023,7 +1076,7 @@ class IntegerLiteral : public Expr {
|
||||
IntegerLiteral(ASTContext &C, const llvm::APInt &V,
|
||||
QualType type, SourceLocation l)
|
||||
: Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
Loc(l) {
|
||||
assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
|
||||
assert(V.getBitWidth() == C.getIntWidth(type) &&
|
||||
@ -1066,7 +1119,7 @@ class CharacterLiteral : public Expr {
|
||||
// type should be IntTy
|
||||
CharacterLiteral(unsigned value, bool iswide, QualType type, SourceLocation l)
|
||||
: Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
Value(value), Loc(l), IsWide(iswide) {
|
||||
}
|
||||
|
||||
@ -1101,7 +1154,7 @@ class FloatingLiteral : public Expr {
|
||||
FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact,
|
||||
QualType Type, SourceLocation L)
|
||||
: Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
IsExact(isexact), Loc(L) {
|
||||
setValue(C, V);
|
||||
}
|
||||
@ -1152,7 +1205,7 @@ class ImaginaryLiteral : public Expr {
|
||||
public:
|
||||
ImaginaryLiteral(Expr *val, QualType Ty)
|
||||
: Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
Val(val) {}
|
||||
|
||||
/// \brief Build an empty imaginary literal.
|
||||
@ -1200,21 +1253,20 @@ class StringLiteral : public Expr {
|
||||
SourceLocation TokLocs[1];
|
||||
|
||||
StringLiteral(QualType Ty) :
|
||||
Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false) {}
|
||||
Expr(StringLiteralClass, Ty, VK_LValue, OK_Ordinary, false, false, false,
|
||||
false) {}
|
||||
|
||||
public:
|
||||
/// This is the "fully general" constructor that allows representation of
|
||||
/// strings formed from multiple concatenated tokens.
|
||||
static StringLiteral *Create(ASTContext &C, const char *StrData,
|
||||
unsigned ByteLength, bool Wide, bool Pascal,
|
||||
QualType Ty,
|
||||
static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide,
|
||||
bool Pascal, QualType Ty,
|
||||
const SourceLocation *Loc, unsigned NumStrs);
|
||||
|
||||
/// Simple constructor for string literals made from one token.
|
||||
static StringLiteral *Create(ASTContext &C, const char *StrData,
|
||||
unsigned ByteLength, bool Wide,
|
||||
static StringLiteral *Create(ASTContext &C, llvm::StringRef Str, bool Wide,
|
||||
bool Pascal, QualType Ty, SourceLocation Loc) {
|
||||
return Create(C, StrData, ByteLength, Wide, Pascal, Ty, &Loc, 1);
|
||||
return Create(C, Str, Wide, Pascal, Ty, &Loc, 1);
|
||||
}
|
||||
|
||||
/// \brief Construct an empty string literal.
|
||||
@ -1289,6 +1341,7 @@ class ParenExpr : public Expr {
|
||||
: Expr(ParenExprClass, val->getType(),
|
||||
val->getValueKind(), val->getObjectKind(),
|
||||
val->isTypeDependent(), val->isValueDependent(),
|
||||
val->isInstantiationDependent(),
|
||||
val->containsUnexpandedParameterPack()),
|
||||
L(l), R(r), Val(val) {}
|
||||
|
||||
@ -1345,6 +1398,8 @@ class UnaryOperator : public Expr {
|
||||
: Expr(UnaryOperatorClass, type, VK, OK,
|
||||
input->isTypeDependent() || type->isDependentType(),
|
||||
input->isValueDependent(),
|
||||
(input->isInstantiationDependent() ||
|
||||
type->isInstantiationDependentType()),
|
||||
input->containsUnexpandedParameterPack()),
|
||||
Opc(opc), Loc(l), Val(input) {}
|
||||
|
||||
@ -1640,6 +1695,7 @@ class UnaryExprOrTypeTraitExpr : public Expr {
|
||||
false, // Never type-dependent (C++ [temp.dep.expr]p3).
|
||||
// Value-dependent if the argument is type-dependent.
|
||||
TInfo->getType()->isDependentType(),
|
||||
TInfo->getType()->isInstantiationDependentType(),
|
||||
TInfo->getType()->containsUnexpandedParameterPack()),
|
||||
Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
|
||||
Argument.Ty = TInfo;
|
||||
@ -1652,6 +1708,7 @@ class UnaryExprOrTypeTraitExpr : public Expr {
|
||||
false, // Never type-dependent (C++ [temp.dep.expr]p3).
|
||||
// Value-dependent if the argument is type-dependent.
|
||||
E->isTypeDependent(),
|
||||
E->isInstantiationDependent(),
|
||||
E->containsUnexpandedParameterPack()),
|
||||
Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
|
||||
Argument.Ex = E;
|
||||
@ -1729,6 +1786,8 @@ class ArraySubscriptExpr : public Expr {
|
||||
: Expr(ArraySubscriptExprClass, t, VK, OK,
|
||||
lhs->isTypeDependent() || rhs->isTypeDependent(),
|
||||
lhs->isValueDependent() || rhs->isValueDependent(),
|
||||
(lhs->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
RBracketLoc(rbracketloc) {
|
||||
@ -1986,7 +2045,9 @@ class MemberExpr : public Expr {
|
||||
const DeclarationNameInfo &NameInfo, QualType ty,
|
||||
ExprValueKind VK, ExprObjectKind OK)
|
||||
: Expr(MemberExprClass, ty, VK, OK,
|
||||
base->isTypeDependent(), base->isValueDependent(),
|
||||
base->isTypeDependent(),
|
||||
base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
base->containsUnexpandedParameterPack()),
|
||||
Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
|
||||
MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
|
||||
@ -2003,6 +2064,7 @@ class MemberExpr : public Expr {
|
||||
ExprValueKind VK, ExprObjectKind OK)
|
||||
: Expr(MemberExprClass, ty, VK, OK,
|
||||
base->isTypeDependent(), base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
base->containsUnexpandedParameterPack()),
|
||||
Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
|
||||
IsArrow(isarrow),
|
||||
@ -2188,6 +2250,8 @@ class CompoundLiteralExpr : public Expr {
|
||||
: Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary,
|
||||
tinfo->getType()->isDependentType(),
|
||||
init->isValueDependent(),
|
||||
(init->isInstantiationDependent() ||
|
||||
tinfo->getType()->isInstantiationDependentType()),
|
||||
init->containsUnexpandedParameterPack()),
|
||||
LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
|
||||
|
||||
@ -2276,6 +2340,9 @@ class CastExpr : public Expr {
|
||||
case CK_IntegralComplexToReal:
|
||||
case CK_IntegralComplexCast:
|
||||
case CK_IntegralComplexToFloatingComplex:
|
||||
case CK_ObjCProduceObject:
|
||||
case CK_ObjCConsumeObject:
|
||||
case CK_ObjCReclaimReturnedObject:
|
||||
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
|
||||
// fallthrough to check for null base path
|
||||
|
||||
@ -2318,6 +2385,8 @@ class CastExpr : public Expr {
|
||||
// Cast expressions are value-dependent if the type is
|
||||
// dependent or if the subexpression is value-dependent.
|
||||
ty->isDependentType() || (op && op->isValueDependent()),
|
||||
(ty->isInstantiationDependentType() ||
|
||||
(op && op->isInstantiationDependent())),
|
||||
(ty->containsUnexpandedParameterPack() ||
|
||||
op->containsUnexpandedParameterPack())),
|
||||
Op(op) {
|
||||
@ -2426,6 +2495,13 @@ class ImplicitCastExpr : public CastExpr {
|
||||
static bool classof(const ImplicitCastExpr *) { return true; }
|
||||
};
|
||||
|
||||
inline Expr *Expr::IgnoreImpCasts() {
|
||||
Expr *e = this;
|
||||
while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
|
||||
e = ice->getSubExpr();
|
||||
return e;
|
||||
}
|
||||
|
||||
/// ExplicitCastExpr - An explicit cast written in the source
|
||||
/// code.
|
||||
///
|
||||
@ -2551,6 +2627,8 @@ class BinaryOperator : public Expr {
|
||||
: Expr(BinaryOperatorClass, ResTy, VK, OK,
|
||||
lhs->isTypeDependent() || rhs->isTypeDependent(),
|
||||
lhs->isValueDependent() || rhs->isValueDependent(),
|
||||
(lhs->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
Opc(opc), OpLoc(opLoc) {
|
||||
@ -2653,6 +2731,8 @@ class BinaryOperator : public Expr {
|
||||
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
|
||||
lhs->isTypeDependent() || rhs->isTypeDependent(),
|
||||
lhs->isValueDependent() || rhs->isValueDependent(),
|
||||
(lhs->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
Opc(opc), OpLoc(opLoc) {
|
||||
@ -2713,11 +2793,11 @@ class AbstractConditionalOperator : public Expr {
|
||||
protected:
|
||||
AbstractConditionalOperator(StmtClass SC, QualType T,
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
bool TD, bool VD,
|
||||
bool TD, bool VD, bool ID,
|
||||
bool ContainsUnexpandedParameterPack,
|
||||
SourceLocation qloc,
|
||||
SourceLocation cloc)
|
||||
: Expr(SC, T, VK, OK, TD, VD, ContainsUnexpandedParameterPack),
|
||||
: Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack),
|
||||
QuestionLoc(qloc), ColonLoc(cloc) {}
|
||||
|
||||
AbstractConditionalOperator(StmtClass SC, EmptyShell Empty)
|
||||
@ -2765,6 +2845,9 @@ class ConditionalOperator : public AbstractConditionalOperator {
|
||||
(lhs->isTypeDependent() || rhs->isTypeDependent()),
|
||||
(cond->isValueDependent() || lhs->isValueDependent() ||
|
||||
rhs->isValueDependent()),
|
||||
(cond->isInstantiationDependent() ||
|
||||
lhs->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(cond->containsUnexpandedParameterPack() ||
|
||||
lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack()),
|
||||
@ -2833,6 +2916,8 @@ class BinaryConditionalOperator : public AbstractConditionalOperator {
|
||||
: AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK,
|
||||
(common->isTypeDependent() || rhs->isTypeDependent()),
|
||||
(common->isValueDependent() || rhs->isValueDependent()),
|
||||
(common->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(common->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack()),
|
||||
qloc, cloc),
|
||||
@ -2914,7 +2999,8 @@ class AddrLabelExpr : public Expr {
|
||||
public:
|
||||
AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
|
||||
QualType t)
|
||||
: Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false),
|
||||
: Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false,
|
||||
false),
|
||||
AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
|
||||
|
||||
/// \brief Build an empty address of a label expression.
|
||||
@ -2953,10 +3039,12 @@ class StmtExpr : public Expr {
|
||||
SourceLocation LParenLoc, RParenLoc;
|
||||
public:
|
||||
// FIXME: Does type-dependence need to be computed differently?
|
||||
// FIXME: Do we need to compute instantiation instantiation-dependence for
|
||||
// statements? (ugh!)
|
||||
StmtExpr(CompoundStmt *substmt, QualType T,
|
||||
SourceLocation lp, SourceLocation rp) :
|
||||
Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
|
||||
T->isDependentType(), false, false),
|
||||
T->isDependentType(), false, false, false),
|
||||
SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
|
||||
|
||||
/// \brief Build an empty statement expression.
|
||||
@ -3073,6 +3161,9 @@ class ChooseExpr : public Expr {
|
||||
QualType t, ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation RP, bool TypeDependent, bool ValueDependent)
|
||||
: Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent,
|
||||
(cond->isInstantiationDependent() ||
|
||||
lhs->isInstantiationDependent() ||
|
||||
rhs->isInstantiationDependent()),
|
||||
(cond->containsUnexpandedParameterPack() ||
|
||||
lhs->containsUnexpandedParameterPack() ||
|
||||
rhs->containsUnexpandedParameterPack())),
|
||||
@ -3134,7 +3225,8 @@ class GNUNullExpr : public Expr {
|
||||
|
||||
public:
|
||||
GNUNullExpr(QualType Ty, SourceLocation Loc)
|
||||
: Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false),
|
||||
: Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false,
|
||||
false),
|
||||
TokenLoc(Loc) { }
|
||||
|
||||
/// \brief Build an empty GNU __null expression.
|
||||
@ -3166,6 +3258,8 @@ class VAArgExpr : public Expr {
|
||||
SourceLocation RPLoc, QualType t)
|
||||
: Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary,
|
||||
t->isDependentType(), false,
|
||||
(TInfo->getType()->isInstantiationDependentType() ||
|
||||
e->isInstantiationDependent()),
|
||||
(TInfo->getType()->containsUnexpandedParameterPack() ||
|
||||
e->containsUnexpandedParameterPack())),
|
||||
Val(e), TInfo(TInfo),
|
||||
@ -3537,9 +3631,9 @@ class DesignatedInitExpr : public Expr {
|
||||
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
|
||||
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
|
||||
|
||||
IdentifierInfo * getFieldName();
|
||||
IdentifierInfo *getFieldName() const;
|
||||
|
||||
FieldDecl *getField() {
|
||||
FieldDecl *getField() const {
|
||||
assert(Kind == FieldDesignator && "Only valid on a field designator");
|
||||
if (Field.NameOrField & 0x01)
|
||||
return 0;
|
||||
@ -3612,12 +3706,18 @@ class DesignatedInitExpr : public Expr {
|
||||
unsigned size() const { return NumDesignators; }
|
||||
|
||||
// Iterator access to the designators.
|
||||
typedef Designator* designators_iterator;
|
||||
typedef Designator *designators_iterator;
|
||||
designators_iterator designators_begin() { return Designators; }
|
||||
designators_iterator designators_end() {
|
||||
return Designators + NumDesignators;
|
||||
}
|
||||
|
||||
typedef const Designator *const_designators_iterator;
|
||||
const_designators_iterator designators_begin() const { return Designators; }
|
||||
const_designators_iterator designators_end() const {
|
||||
return Designators + NumDesignators;
|
||||
}
|
||||
|
||||
typedef std::reverse_iterator<designators_iterator>
|
||||
reverse_designators_iterator;
|
||||
reverse_designators_iterator designators_rbegin() {
|
||||
@ -3627,6 +3727,15 @@ class DesignatedInitExpr : public Expr {
|
||||
return reverse_designators_iterator(designators_begin());
|
||||
}
|
||||
|
||||
typedef std::reverse_iterator<const_designators_iterator>
|
||||
const_reverse_designators_iterator;
|
||||
const_reverse_designators_iterator designators_rbegin() const {
|
||||
return const_reverse_designators_iterator(designators_end());
|
||||
}
|
||||
const_reverse_designators_iterator designators_rend() const {
|
||||
return const_reverse_designators_iterator(designators_begin());
|
||||
}
|
||||
|
||||
Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
|
||||
|
||||
void setDesignators(ASTContext &C, const Designator *Desigs,
|
||||
@ -3708,7 +3817,7 @@ class ImplicitValueInitExpr : public Expr {
|
||||
public:
|
||||
explicit ImplicitValueInitExpr(QualType ty)
|
||||
: Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary,
|
||||
false, false, false) { }
|
||||
false, false, ty->isInstantiationDependentType(), false) { }
|
||||
|
||||
/// \brief Construct an empty implicit value initialization.
|
||||
explicit ImplicitValueInitExpr(EmptyShell Empty)
|
||||
@ -3735,7 +3844,7 @@ class ParenListExpr : public Expr {
|
||||
|
||||
public:
|
||||
ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
|
||||
unsigned numexprs, SourceLocation rparenloc);
|
||||
unsigned numexprs, SourceLocation rparenloc, QualType T);
|
||||
|
||||
/// \brief Build an empty paren list.
|
||||
explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }
|
||||
@ -3909,6 +4018,7 @@ class ExtVectorElementExpr : public Expr {
|
||||
: Expr(ExtVectorElementExprClass, ty, VK,
|
||||
(VK == VK_RValue ? OK_Ordinary : OK_VectorComponent),
|
||||
base->isTypeDependent(), base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
base->containsUnexpandedParameterPack()),
|
||||
Base(base), Accessor(&accessor), AccessorLoc(loc) {}
|
||||
|
||||
@ -3963,7 +4073,10 @@ class BlockExpr : public Expr {
|
||||
public:
|
||||
BlockExpr(BlockDecl *BD, QualType ty)
|
||||
: Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
|
||||
ty->isDependentType(), false, false),
|
||||
ty->isDependentType(), false,
|
||||
// FIXME: Check for instantiate-dependence in the statement?
|
||||
ty->isInstantiationDependentType(),
|
||||
false),
|
||||
TheBlock(BD) {}
|
||||
|
||||
/// \brief Build an empty block expression.
|
||||
@ -4037,26 +4150,36 @@ class BlockDeclRefExpr : public Expr {
|
||||
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
|
||||
/// This AST node provides support for reinterpreting a type to another
|
||||
/// type of the same size.
|
||||
class AsTypeExpr : public Expr {
|
||||
class AsTypeExpr : public Expr { // Should this be an ExplicitCastExpr?
|
||||
private:
|
||||
Expr* SrcExpr;
|
||||
QualType DstType;
|
||||
Stmt *SrcExpr;
|
||||
SourceLocation BuiltinLoc, RParenLoc;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
|
||||
|
||||
public:
|
||||
AsTypeExpr(Expr* SrcExpr, QualType DstType,
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation BuiltinLoc, SourceLocation RParenLoc)
|
||||
: Expr(AsTypeExprClass, DstType, VK, OK, false, false, false),
|
||||
SrcExpr(SrcExpr), DstType(DstType),
|
||||
BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
|
||||
|
||||
/// \brief Build an empty __builtin_astype
|
||||
explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {}
|
||||
: Expr(AsTypeExprClass, DstType, VK, OK,
|
||||
DstType->isDependentType(),
|
||||
DstType->isDependentType() || SrcExpr->isValueDependent(),
|
||||
(DstType->isInstantiationDependentType() ||
|
||||
SrcExpr->isInstantiationDependent()),
|
||||
(DstType->containsUnexpandedParameterPack() ||
|
||||
SrcExpr->containsUnexpandedParameterPack())),
|
||||
SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {}
|
||||
|
||||
/// getSrcExpr - Return the Expr to be converted.
|
||||
Expr *getSrcExpr() const { return SrcExpr; }
|
||||
QualType getDstType() const { return DstType; }
|
||||
Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
|
||||
|
||||
/// getBuiltinLoc - Return the location of the __builtin_astype token.
|
||||
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
|
||||
|
||||
/// getRParenLoc - Return the location of final right parenthesis.
|
||||
SourceLocation getRParenLoc() const { return RParenLoc; }
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
return SourceRange(BuiltinLoc, RParenLoc);
|
||||
@ -4068,7 +4191,7 @@ class AsTypeExpr : public Expr {
|
||||
static bool classof(const AsTypeExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(); }
|
||||
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
|
@ -330,7 +330,7 @@ class CXXBoolLiteralExpr : public Expr {
|
||||
public:
|
||||
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
|
||||
Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
Value(val), Loc(l) {}
|
||||
|
||||
explicit CXXBoolLiteralExpr(EmptyShell Empty)
|
||||
@ -359,7 +359,7 @@ class CXXNullPtrLiteralExpr : public Expr {
|
||||
public:
|
||||
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
|
||||
Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
Loc(l) {}
|
||||
|
||||
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
|
||||
@ -395,6 +395,7 @@ class CXXTypeidExpr : public Expr {
|
||||
false,
|
||||
// typeid is value-dependent if the type or expression are dependent
|
||||
Operand->getType()->isDependentType(),
|
||||
Operand->getType()->isInstantiationDependentType(),
|
||||
Operand->getType()->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
@ -404,6 +405,7 @@ class CXXTypeidExpr : public Expr {
|
||||
false,
|
||||
// typeid is value-dependent if the type or expression are dependent
|
||||
Operand->isTypeDependent() || Operand->isValueDependent(),
|
||||
Operand->isInstantiationDependent(),
|
||||
Operand->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
@ -471,12 +473,14 @@ class CXXUuidofExpr : public Expr {
|
||||
CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
|
||||
false, Operand->getType()->isDependentType(),
|
||||
Operand->getType()->isInstantiationDependentType(),
|
||||
Operand->getType()->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R)
|
||||
: Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary,
|
||||
false, Operand->isTypeDependent(),
|
||||
Operand->isInstantiationDependent(),
|
||||
Operand->containsUnexpandedParameterPack()),
|
||||
Operand(Operand), Range(R) { }
|
||||
|
||||
@ -552,6 +556,7 @@ class CXXThisExpr : public Expr {
|
||||
// 'this' is type-dependent if the class type of the enclosing
|
||||
// member function is dependent (C++ [temp.dep.expr]p2)
|
||||
Type->isDependentType(), Type->isDependentType(),
|
||||
Type->isInstantiationDependentType(),
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Loc(L), Implicit(isImplicit) { }
|
||||
|
||||
@ -581,23 +586,35 @@ class CXXThisExpr : public Expr {
|
||||
class CXXThrowExpr : public Expr {
|
||||
Stmt *Op;
|
||||
SourceLocation ThrowLoc;
|
||||
/// \brief Whether the thrown variable (if any) is in scope.
|
||||
unsigned IsThrownVariableInScope : 1;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
|
||||
public:
|
||||
// Ty is the void type which is used as the result type of the
|
||||
// exepression. The l is the location of the throw keyword. expr
|
||||
// can by null, if the optional expression to throw isn't present.
|
||||
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
|
||||
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l,
|
||||
bool IsThrownVariableInScope) :
|
||||
Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false,
|
||||
expr && expr->isInstantiationDependent(),
|
||||
expr && expr->containsUnexpandedParameterPack()),
|
||||
Op(expr), ThrowLoc(l) {}
|
||||
Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {}
|
||||
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
|
||||
|
||||
const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
|
||||
Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
|
||||
void setSubExpr(Expr *E) { Op = E; }
|
||||
|
||||
SourceLocation getThrowLoc() const { return ThrowLoc; }
|
||||
void setThrowLoc(SourceLocation L) { ThrowLoc = L; }
|
||||
|
||||
/// \brief Determines whether the variable thrown by this expression (if any!)
|
||||
/// is within the innermost try block.
|
||||
///
|
||||
/// This information is required to determine whether the NRVO can apply to
|
||||
/// this variable.
|
||||
bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
if (getSubExpr() == 0)
|
||||
return SourceRange(ThrowLoc, ThrowLoc);
|
||||
@ -636,14 +653,14 @@ class CXXDefaultArgExpr : public Expr {
|
||||
? param->getType().getNonReferenceType()
|
||||
: param->getDefaultArg()->getType(),
|
||||
param->getDefaultArg()->getValueKind(),
|
||||
param->getDefaultArg()->getObjectKind(), false, false, false),
|
||||
param->getDefaultArg()->getObjectKind(), false, false, false, false),
|
||||
Param(param, false), Loc(Loc) { }
|
||||
|
||||
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
|
||||
Expr *SubExpr)
|
||||
: Expr(SC, SubExpr->getType(),
|
||||
SubExpr->getValueKind(), SubExpr->getObjectKind(),
|
||||
false, false, false),
|
||||
false, false, false, false),
|
||||
Param(param, true), Loc(Loc) {
|
||||
*reinterpret_cast<Expr **>(this + 1) = SubExpr;
|
||||
}
|
||||
@ -742,6 +759,7 @@ class CXXBindTemporaryExpr : public Expr {
|
||||
: Expr(CXXBindTemporaryExprClass, SubExpr->getType(),
|
||||
VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(),
|
||||
SubExpr->isValueDependent(),
|
||||
SubExpr->isInstantiationDependent(),
|
||||
SubExpr->containsUnexpandedParameterPack()),
|
||||
Temp(temp), SubExpr(SubExpr) { }
|
||||
|
||||
@ -995,7 +1013,7 @@ class CXXScalarValueInitExpr : public Expr {
|
||||
TypeSourceInfo *TypeInfo,
|
||||
SourceLocation rParenLoc ) :
|
||||
Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary,
|
||||
false, false, false),
|
||||
false, false, Type->isInstantiationDependentType(), false),
|
||||
RParenLoc(rParenLoc), TypeInfo(TypeInfo) {}
|
||||
|
||||
explicit CXXScalarValueInitExpr(EmptyShell Shell)
|
||||
@ -1241,6 +1259,7 @@ class CXXDeleteExpr : public Expr {
|
||||
bool arrayFormAsWritten, bool usualArrayDeleteWantsSize,
|
||||
FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc)
|
||||
: Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false,
|
||||
arg->isInstantiationDependent(),
|
||||
arg->containsUnexpandedParameterPack()),
|
||||
GlobalDelete(globalDelete),
|
||||
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
|
||||
@ -1500,6 +1519,7 @@ class UnaryTypeTraitExpr : public Expr {
|
||||
SourceLocation rparen, QualType ty)
|
||||
: Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
|
||||
false, queried->getType()->isDependentType(),
|
||||
queried->getType()->isInstantiationDependentType(),
|
||||
queried->getType()->containsUnexpandedParameterPack()),
|
||||
UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
|
||||
|
||||
@ -1558,6 +1578,8 @@ class BinaryTypeTraitExpr : public Expr {
|
||||
: Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
|
||||
lhsType->getType()->isDependentType() ||
|
||||
rhsType->getType()->isDependentType(),
|
||||
(lhsType->getType()->isInstantiationDependentType() ||
|
||||
rhsType->getType()->isInstantiationDependentType()),
|
||||
(lhsType->getType()->containsUnexpandedParameterPack() ||
|
||||
rhsType->getType()->containsUnexpandedParameterPack())),
|
||||
BTT(btt), Value(value), Loc(loc), RParen(rparen),
|
||||
@ -1625,6 +1647,8 @@ class ArrayTypeTraitExpr : public Expr {
|
||||
Expr *dimension, SourceLocation rparen, QualType ty)
|
||||
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
|
||||
false, queried->getType()->isDependentType(),
|
||||
(queried->getType()->isInstantiationDependentType() ||
|
||||
(dimension && dimension->isInstantiationDependent())),
|
||||
queried->getType()->containsUnexpandedParameterPack()),
|
||||
ATT(att), Value(value), Dimension(dimension),
|
||||
Loc(loc), RParen(rparen), QueriedType(queried) { }
|
||||
@ -1684,6 +1708,7 @@ class ExpressionTraitExpr : public Expr {
|
||||
false, // Not type-dependent
|
||||
// Value-dependent if the argument is type-dependent.
|
||||
queried->isTypeDependent(),
|
||||
queried->isInstantiationDependent(),
|
||||
queried->containsUnexpandedParameterPack()),
|
||||
ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { }
|
||||
|
||||
@ -1736,8 +1761,9 @@ class OverloadExpr : public Expr {
|
||||
const DeclarationNameInfo &NameInfo,
|
||||
const TemplateArgumentListInfo *TemplateArgs,
|
||||
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
|
||||
bool KnownDependent = false,
|
||||
bool KnownContainsUnexpandedParameterPack = false);
|
||||
bool KnownDependent,
|
||||
bool KnownInstantiationDependent,
|
||||
bool KnownContainsUnexpandedParameterPack);
|
||||
|
||||
OverloadExpr(StmtClass K, EmptyShell Empty)
|
||||
: Expr(K, Empty), Results(0), NumResults(0),
|
||||
@ -1880,7 +1906,7 @@ class UnresolvedLookupExpr : public OverloadExpr {
|
||||
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
|
||||
bool StdIsAssociatedNamespace)
|
||||
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo,
|
||||
TemplateArgs, Begin, End),
|
||||
TemplateArgs, Begin, End, false, false, false),
|
||||
RequiresADL(RequiresADL),
|
||||
StdIsAssociatedNamespace(StdIsAssociatedNamespace),
|
||||
Overloaded(Overloaded), NamingClass(NamingClass)
|
||||
@ -2727,6 +2753,7 @@ class CXXNoexceptExpr : public Expr {
|
||||
: Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary,
|
||||
/*TypeDependent*/false,
|
||||
/*ValueDependent*/Val == CT_Dependent,
|
||||
Val == CT_Dependent || Operand->isInstantiationDependent(),
|
||||
Operand->containsUnexpandedParameterPack()),
|
||||
Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen)
|
||||
{ }
|
||||
@ -2787,7 +2814,8 @@ class PackExpansionExpr : public Expr {
|
||||
llvm::Optional<unsigned> NumExpansions)
|
||||
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
|
||||
Pattern->getObjectKind(), /*TypeDependent=*/true,
|
||||
/*ValueDependent=*/true, /*ContainsUnexpandedParameterPack=*/false),
|
||||
/*ValueDependent=*/true, /*InstantiationDependent=*/true,
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
EllipsisLoc(EllipsisLoc),
|
||||
NumExpansions(NumExpansions? *NumExpansions + 1 : 0),
|
||||
Pattern(Pattern) { }
|
||||
@ -2874,6 +2902,7 @@ class SizeOfPackExpr : public Expr {
|
||||
SourceLocation PackLoc, SourceLocation RParenLoc)
|
||||
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
|
||||
/*TypeDependent=*/false, /*ValueDependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
|
||||
Length(0), Pack(Pack) { }
|
||||
@ -2885,6 +2914,7 @@ class SizeOfPackExpr : public Expr {
|
||||
unsigned Length)
|
||||
: Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary,
|
||||
/*TypeDependent=*/false, /*ValueDependent=*/false,
|
||||
/*InstantiationDependent=*/false,
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
|
||||
Length(Length), Pack(Pack) { }
|
||||
@ -2927,6 +2957,53 @@ class SizeOfPackExpr : public Expr {
|
||||
child_range children() { return child_range(); }
|
||||
};
|
||||
|
||||
/// \brief Represents a reference to a non-type template parameter
|
||||
/// that has been substituted with a template argument.
|
||||
class SubstNonTypeTemplateParmExpr : public Expr {
|
||||
/// \brief The replaced parameter.
|
||||
NonTypeTemplateParmDecl *Param;
|
||||
|
||||
/// \brief The replacement expression.
|
||||
Stmt *Replacement;
|
||||
|
||||
/// \brief The location of the non-type template parameter reference.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
|
||||
: Expr(SubstNonTypeTemplateParmExprClass, Empty) { }
|
||||
|
||||
public:
|
||||
SubstNonTypeTemplateParmExpr(QualType type,
|
||||
ExprValueKind valueKind,
|
||||
SourceLocation loc,
|
||||
NonTypeTemplateParmDecl *param,
|
||||
Expr *replacement)
|
||||
: Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary,
|
||||
replacement->isTypeDependent(), replacement->isValueDependent(),
|
||||
replacement->isInstantiationDependent(),
|
||||
replacement->containsUnexpandedParameterPack()),
|
||||
Param(param), Replacement(replacement), NameLoc(loc) {}
|
||||
|
||||
SourceLocation getNameLoc() const { return NameLoc; }
|
||||
SourceRange getSourceRange() const { return NameLoc; }
|
||||
|
||||
Expr *getReplacement() const { return cast<Expr>(Replacement); }
|
||||
|
||||
NonTypeTemplateParmDecl *getParameter() const { return Param; }
|
||||
|
||||
static bool classof(const Stmt *s) {
|
||||
return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
|
||||
}
|
||||
static bool classof(const SubstNonTypeTemplateParmExpr *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Replacement, &Replacement+1); }
|
||||
};
|
||||
|
||||
/// \brief Represents a reference to a non-type template parameter pack that
|
||||
/// has been substituted with a non-template argument pack.
|
||||
///
|
||||
@ -2953,8 +3030,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
|
||||
/// \brief The location of the non-type template parameter pack reference.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
|
||||
: Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
|
||||
|
||||
public:
|
||||
SubstNonTypeTemplateParmPackExpr(QualType T,
|
||||
@ -2962,9 +3041,6 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
|
||||
SourceLocation NameLoc,
|
||||
const TemplateArgument &ArgPack);
|
||||
|
||||
SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
|
||||
: Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { }
|
||||
|
||||
/// \brief Retrieve the non-type template parameter pack being substituted.
|
||||
NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
|
||||
|
||||
@ -2987,6 +3063,66 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
|
||||
// Iterators
|
||||
child_range children() { return child_range(); }
|
||||
};
|
||||
|
||||
/// \brief Represents a prvalue temporary that written into memory so that
|
||||
/// a reference can bind to it.
|
||||
///
|
||||
/// Prvalue expressions are materialized when they need to have an address
|
||||
/// in memory for a reference to bind to. This happens when binding a
|
||||
/// reference to the result of a conversion, e.g.,
|
||||
///
|
||||
/// \code
|
||||
/// const int &r = 1.0;
|
||||
/// \endcode
|
||||
///
|
||||
/// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
|
||||
/// then materialized via a \c MaterializeTemporaryExpr, and the reference
|
||||
/// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
|
||||
/// (either an lvalue or an xvalue, depending on the kind of reference binding
|
||||
/// to it), maintaining the invariant that references always bind to glvalues.
|
||||
class MaterializeTemporaryExpr : public Expr {
|
||||
/// \brief The temporary-generating expression whose value will be
|
||||
/// materialized.
|
||||
Stmt *Temporary;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
|
||||
public:
|
||||
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
|
||||
bool BoundToLvalueReference)
|
||||
: Expr(MaterializeTemporaryExprClass, T,
|
||||
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
|
||||
Temporary->isTypeDependent(), Temporary->isValueDependent(),
|
||||
Temporary->isInstantiationDependent(),
|
||||
Temporary->containsUnexpandedParameterPack()),
|
||||
Temporary(Temporary) { }
|
||||
|
||||
MaterializeTemporaryExpr(EmptyShell Empty)
|
||||
: Expr(MaterializeTemporaryExprClass, Empty) { }
|
||||
|
||||
/// \brief Retrieve the temporary-generating subexpression whose value will
|
||||
/// be materialized into a glvalue.
|
||||
Expr *GetTemporaryExpr() const { return reinterpret_cast<Expr *>(Temporary); }
|
||||
|
||||
/// \brief Determine whether this materialized temporary is bound to an
|
||||
/// lvalue reference; otherwise, it's bound to an rvalue reference.
|
||||
bool isBoundToLvalueReference() const {
|
||||
return getValueKind() == VK_LValue;
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const { return Temporary->getSourceRange(); }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == MaterializeTemporaryExprClass;
|
||||
}
|
||||
static bool classof(const MaterializeTemporaryExpr *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() { return child_range(&Temporary, &Temporary + 1); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ObjCStringLiteral : public Expr {
|
||||
public:
|
||||
ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
|
||||
: Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
String(SL), AtLoc(L) {}
|
||||
explicit ObjCStringLiteral(EmptyShell Empty)
|
||||
: Expr(ObjCStringLiteralClass, Empty) {}
|
||||
@ -67,6 +67,7 @@ class ObjCEncodeExpr : public Expr {
|
||||
: Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
|
||||
EncodedType->getType()->isDependentType(),
|
||||
EncodedType->getType()->isDependentType(),
|
||||
EncodedType->getType()->isInstantiationDependentType(),
|
||||
EncodedType->getType()->containsUnexpandedParameterPack()),
|
||||
EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
|
||||
|
||||
@ -106,7 +107,7 @@ class ObjCSelectorExpr : public Expr {
|
||||
ObjCSelectorExpr(QualType T, Selector selInfo,
|
||||
SourceLocation at, SourceLocation rp)
|
||||
: Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
SelName(selInfo), AtLoc(at), RParenLoc(rp){}
|
||||
explicit ObjCSelectorExpr(EmptyShell Empty)
|
||||
: Expr(ObjCSelectorExprClass, Empty) {}
|
||||
@ -146,7 +147,7 @@ class ObjCProtocolExpr : public Expr {
|
||||
ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
|
||||
SourceLocation at, SourceLocation rp)
|
||||
: Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
|
||||
false),
|
||||
false, false),
|
||||
TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
|
||||
explicit ObjCProtocolExpr(EmptyShell Empty)
|
||||
: Expr(ObjCProtocolExprClass, Empty) {}
|
||||
@ -186,6 +187,7 @@ class ObjCIvarRefExpr : public Expr {
|
||||
bool arrow = false, bool freeIvar = false) :
|
||||
Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
|
||||
/*TypeDependent=*/false, base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
base->containsUnexpandedParameterPack()),
|
||||
D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {}
|
||||
|
||||
@ -248,6 +250,7 @@ class ObjCPropertyRefExpr : public Expr {
|
||||
SourceLocation l, Expr *base)
|
||||
: Expr(ObjCPropertyRefExprClass, t, VK, OK,
|
||||
/*TypeDependent=*/false, base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
base->containsUnexpandedParameterPack()),
|
||||
PropertyOrGetter(PD, false), Setter(0),
|
||||
IdLoc(l), ReceiverLoc(), Receiver(base) {
|
||||
@ -257,7 +260,7 @@ class ObjCPropertyRefExpr : public Expr {
|
||||
ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation l, SourceLocation sl, QualType st)
|
||||
: Expr(ObjCPropertyRefExprClass, t, VK, OK,
|
||||
/*TypeDependent=*/false, false,
|
||||
/*TypeDependent=*/false, false, st->isInstantiationDependentType(),
|
||||
st->containsUnexpandedParameterPack()),
|
||||
PropertyOrGetter(PD, false), Setter(0),
|
||||
IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
|
||||
@ -267,7 +270,7 @@ class ObjCPropertyRefExpr : public Expr {
|
||||
QualType T, ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation IdLoc, Expr *Base)
|
||||
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
|
||||
Base->isValueDependent(),
|
||||
Base->isValueDependent(), Base->isInstantiationDependent(),
|
||||
Base->containsUnexpandedParameterPack()),
|
||||
PropertyOrGetter(Getter, true), Setter(Setter),
|
||||
IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
|
||||
@ -277,7 +280,7 @@ class ObjCPropertyRefExpr : public Expr {
|
||||
QualType T, ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation IdLoc,
|
||||
SourceLocation SuperLoc, QualType SuperTy)
|
||||
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
|
||||
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
|
||||
PropertyOrGetter(Getter, true), Setter(Setter),
|
||||
IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
|
||||
}
|
||||
@ -286,7 +289,7 @@ class ObjCPropertyRefExpr : public Expr {
|
||||
QualType T, ExprValueKind VK, ExprObjectKind OK,
|
||||
SourceLocation IdLoc,
|
||||
SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
|
||||
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
|
||||
: Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
|
||||
PropertyOrGetter(Getter, true), Setter(Setter),
|
||||
IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
|
||||
}
|
||||
@ -456,7 +459,11 @@ class ObjCMessageExpr : public Expr {
|
||||
///
|
||||
/// When non-zero, we have a method declaration; otherwise, we just
|
||||
/// have a selector.
|
||||
unsigned HasMethod : 8;
|
||||
unsigned HasMethod : 1;
|
||||
|
||||
/// \brief Whether this message send is a "delegate init call",
|
||||
/// i.e. a call of an init method on self from within an init method.
|
||||
unsigned IsDelegateInitCall : 1;
|
||||
|
||||
/// \brief When the message expression is a send to 'super', this is
|
||||
/// the location of the 'super' keyword.
|
||||
@ -476,7 +483,7 @@ class ObjCMessageExpr : public Expr {
|
||||
|
||||
ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
|
||||
: Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
|
||||
HasMethod(0), SelectorOrMethod(0) { }
|
||||
HasMethod(0), IsDelegateInitCall(0), SelectorOrMethod(0) { }
|
||||
|
||||
ObjCMessageExpr(QualType T, ExprValueKind VK,
|
||||
SourceLocation LBracLoc,
|
||||
@ -807,6 +814,12 @@ class ObjCMessageExpr : public Expr {
|
||||
getArgs()[Arg] = ArgExpr;
|
||||
}
|
||||
|
||||
/// isDelegateInitCall - Answers whether this message send has been
|
||||
/// tagged as a "delegate init call", i.e. a call to a method in the
|
||||
/// -init family on self from within an -init method implementation.
|
||||
bool isDelegateInitCall() const { return IsDelegateInitCall; }
|
||||
void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
|
||||
|
||||
SourceLocation getLeftLoc() const { return LBracLoc; }
|
||||
SourceLocation getRightLoc() const { return RBracLoc; }
|
||||
SourceLocation getSelectorLoc() const { return SelectorLoc; }
|
||||
@ -860,6 +873,7 @@ class ObjCIsaExpr : public Expr {
|
||||
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
|
||||
: Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
|
||||
/*TypeDependent=*/false, base->isValueDependent(),
|
||||
base->isInstantiationDependent(),
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
|
||||
|
||||
@ -892,6 +906,123 @@ class ObjCIsaExpr : public Expr {
|
||||
child_range children() { return child_range(&Base, &Base+1); }
|
||||
};
|
||||
|
||||
|
||||
/// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
|
||||
/// argument by indirect copy-restore in ARC. This is used to support
|
||||
/// passing indirect arguments with the wrong lifetime, e.g. when
|
||||
/// passing the address of a __strong local variable to an 'out'
|
||||
/// parameter. This expression kind is only valid in an "argument"
|
||||
/// position to some sort of call expression.
|
||||
///
|
||||
/// The parameter must have type 'pointer to T', and the argument must
|
||||
/// have type 'pointer to U', where T and U agree except possibly in
|
||||
/// qualification. If the argument value is null, then a null pointer
|
||||
/// is passed; otherwise it points to an object A, and:
|
||||
/// 1. A temporary object B of type T is initialized, either by
|
||||
/// zero-initialization (used when initializing an 'out' parameter)
|
||||
/// or copy-initialization (used when initializing an 'inout'
|
||||
/// parameter).
|
||||
/// 2. The address of the temporary is passed to the function.
|
||||
/// 3. If the call completes normally, A is move-assigned from B.
|
||||
/// 4. Finally, A is destroyed immediately.
|
||||
///
|
||||
/// Currently 'T' must be a retainable object lifetime and must be
|
||||
/// __autoreleasing; this qualifier is ignored when initializing
|
||||
/// the value.
|
||||
class ObjCIndirectCopyRestoreExpr : public Expr {
|
||||
Stmt *Operand;
|
||||
|
||||
// unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
|
||||
void setShouldCopy(bool shouldCopy) {
|
||||
ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
|
||||
}
|
||||
|
||||
explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
|
||||
: Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
|
||||
|
||||
public:
|
||||
ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
|
||||
: Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
|
||||
operand->isTypeDependent(), operand->isValueDependent(),
|
||||
operand->isInstantiationDependent(),
|
||||
operand->containsUnexpandedParameterPack()),
|
||||
Operand(operand) {
|
||||
setShouldCopy(shouldCopy);
|
||||
}
|
||||
|
||||
Expr *getSubExpr() { return cast<Expr>(Operand); }
|
||||
const Expr *getSubExpr() const { return cast<Expr>(Operand); }
|
||||
|
||||
/// shouldCopy - True if we should do the 'copy' part of the
|
||||
/// copy-restore. If false, the temporary will be zero-initialized.
|
||||
bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
|
||||
|
||||
child_range children() { return child_range(&Operand, &Operand+1); }
|
||||
|
||||
// Source locations are determined by the subexpression.
|
||||
SourceRange getSourceRange() const { return Operand->getSourceRange(); }
|
||||
SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); }
|
||||
|
||||
static bool classof(const Stmt *s) {
|
||||
return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
|
||||
}
|
||||
static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// \brief An Objective-C "bridged" cast expression, which casts between
|
||||
/// Objective-C pointers and C pointers, transferring ownership in the process.
|
||||
///
|
||||
/// \code
|
||||
/// NSString *str = (__bridge_transfer NSString *)CFCreateString();
|
||||
/// \endcode
|
||||
class ObjCBridgedCastExpr : public ExplicitCastExpr {
|
||||
SourceLocation LParenLoc;
|
||||
SourceLocation BridgeKeywordLoc;
|
||||
unsigned Kind : 2;
|
||||
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
|
||||
public:
|
||||
ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
|
||||
SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo,
|
||||
Expr *Operand)
|
||||
: ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
|
||||
CK_BitCast, Operand, 0, TSInfo),
|
||||
LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
|
||||
|
||||
/// \brief Construct an empty Objective-C bridged cast.
|
||||
explicit ObjCBridgedCastExpr(EmptyShell Shell)
|
||||
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
|
||||
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
/// \brief Determine which kind of bridge is being performed via this cast.
|
||||
ObjCBridgeCastKind getBridgeKind() const {
|
||||
return static_cast<ObjCBridgeCastKind>(Kind);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the kind of bridge being performed as a string.
|
||||
llvm::StringRef getBridgeKindName() const;
|
||||
|
||||
/// \brief The location of the bridge keyword.
|
||||
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCBridgedCastExprClass;
|
||||
}
|
||||
static bool classof(const ObjCBridgedCastExpr *) { return true; }
|
||||
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,20 @@ class Selector;
|
||||
class Stmt;
|
||||
class TagDecl;
|
||||
|
||||
/// \brief Enumeration describing the result of loading information from
|
||||
/// an external source.
|
||||
enum ExternalLoadResult {
|
||||
/// \brief Loading the external information has succeeded.
|
||||
ELR_Success,
|
||||
|
||||
/// \brief Loading the external information has failed.
|
||||
ELR_Failure,
|
||||
|
||||
/// \brief The external information has already been loaded, and therefore
|
||||
/// no additional processing is required.
|
||||
ELR_AlreadyLoaded
|
||||
};
|
||||
|
||||
/// \brief Abstract interface for external sources of AST nodes.
|
||||
///
|
||||
/// External AST sources provide AST nodes constructed from some
|
||||
@ -132,10 +146,10 @@ class ExternalASTSource {
|
||||
/// declaration kind is one we are looking for. If NULL, all declarations
|
||||
/// are returned.
|
||||
///
|
||||
/// \return true if an error occurred
|
||||
/// \return an indication of whether the load succeeded or failed.
|
||||
///
|
||||
/// The default implementation of this method is a no-op.
|
||||
virtual bool FindExternalLexicalDecls(const DeclContext *DC,
|
||||
virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
bool (*isKindWeWant)(Decl::Kind),
|
||||
llvm::SmallVectorImpl<Decl*> &Result);
|
||||
|
||||
@ -143,14 +157,14 @@ class ExternalASTSource {
|
||||
/// DeclContext.
|
||||
///
|
||||
/// \return true if an error occurred
|
||||
bool FindExternalLexicalDecls(const DeclContext *DC,
|
||||
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
|
||||
llvm::SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, 0, Result);
|
||||
}
|
||||
|
||||
template <typename DeclTy>
|
||||
bool FindExternalLexicalDeclsBy(const DeclContext *DC,
|
||||
llvm::SmallVectorImpl<Decl*> &Result) {
|
||||
ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
|
||||
llvm::SmallVectorImpl<Decl*> &Result) {
|
||||
return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_CODEGEN_GLOBALDECL_H
|
||||
#define CLANG_CODEGEN_GLOBALDECL_H
|
||||
#ifndef LLVM_CLANG_AST_GLOBALDECL_H
|
||||
#define LLVM_CLANG_AST_GLOBALDECL_H
|
||||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
@ -21,8 +21,6 @@
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace CodeGen {
|
||||
|
||||
/// GlobalDecl - represents a global declaration. This can either be a
|
||||
/// CXXConstructorDecl and the constructor type (Base, Complete).
|
||||
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
|
||||
@ -89,28 +87,27 @@ class GlobalDecl {
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace CodeGen
|
||||
} // end namespace clang
|
||||
|
||||
namespace llvm {
|
||||
template<class> struct DenseMapInfo;
|
||||
|
||||
template<> struct DenseMapInfo<clang::CodeGen::GlobalDecl> {
|
||||
static inline clang::CodeGen::GlobalDecl getEmptyKey() {
|
||||
return clang::CodeGen::GlobalDecl();
|
||||
template<> struct DenseMapInfo<clang::GlobalDecl> {
|
||||
static inline clang::GlobalDecl getEmptyKey() {
|
||||
return clang::GlobalDecl();
|
||||
}
|
||||
|
||||
static inline clang::CodeGen::GlobalDecl getTombstoneKey() {
|
||||
return clang::CodeGen::GlobalDecl::
|
||||
static inline clang::GlobalDecl getTombstoneKey() {
|
||||
return clang::GlobalDecl::
|
||||
getFromOpaquePtr(reinterpret_cast<void*>(-1));
|
||||
}
|
||||
|
||||
static unsigned getHashValue(clang::CodeGen::GlobalDecl GD) {
|
||||
static unsigned getHashValue(clang::GlobalDecl GD) {
|
||||
return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
|
||||
}
|
||||
|
||||
static bool isEqual(clang::CodeGen::GlobalDecl LHS,
|
||||
clang::CodeGen::GlobalDecl RHS) {
|
||||
static bool isEqual(clang::GlobalDecl LHS,
|
||||
clang::GlobalDecl RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
|
||||
@ -119,7 +116,7 @@ namespace llvm {
|
||||
// GlobalDecl isn't *technically* a POD type. However, its copy constructor,
|
||||
// copy assignment operator, and destructor are all trivial.
|
||||
template <>
|
||||
struct isPodLike<clang::CodeGen::GlobalDecl> {
|
||||
struct isPodLike<clang::GlobalDecl> {
|
||||
static const bool value = true;
|
||||
};
|
||||
} // end namespace llvm
|
@ -186,6 +186,10 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
|
||||
/// type or not.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Whether this nested name specifier involves a template
|
||||
/// parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Whether this nested-name-specifier contains an unexpanded
|
||||
/// parameter pack (for C++0x variadic templates).
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
@ -435,6 +439,14 @@ class NestedNameSpecifierLocBuilder {
|
||||
/// copied.
|
||||
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
|
||||
|
||||
/// \brief Retrieve a nested-name-specifier with location
|
||||
/// information based on the information in this builder. This loc
|
||||
/// will contain references to the builder's internal data and may
|
||||
/// be invalidated by any change to the builder.
|
||||
NestedNameSpecifierLoc getTemporary() const {
|
||||
return NestedNameSpecifierLoc(Representation, Buffer);
|
||||
}
|
||||
|
||||
/// \brief Clear out this builder, and prepare it to build another
|
||||
/// nested-name-specifier with source-location information.
|
||||
void Clear() {
|
||||
|
@ -245,7 +245,22 @@ enum CastKind {
|
||||
|
||||
/// \brief Converts from an integral complex to a floating complex.
|
||||
/// _Complex unsigned -> _Complex float
|
||||
CK_IntegralComplexToFloatingComplex
|
||||
CK_IntegralComplexToFloatingComplex,
|
||||
|
||||
/// \brief Produces a retainable object pointer so that it may be
|
||||
/// consumed, e.g. by being passed to a consuming parameter. Calls
|
||||
/// objc_retain.
|
||||
CK_ObjCProduceObject,
|
||||
|
||||
/// \brief Consumes a retainable object pointer that has just been
|
||||
/// produced, e.g. as the return value of a retaining call. Enters
|
||||
/// a cleanup to call objc_release at some indefinite time.
|
||||
CK_ObjCConsumeObject,
|
||||
|
||||
/// \brief Reclaim a retainable object pointer object that may have
|
||||
/// been produced and autoreleased as part of a function return
|
||||
/// sequence.
|
||||
CK_ObjCReclaimReturnedObject
|
||||
};
|
||||
|
||||
#define CK_Invalid ((CastKind) -1)
|
||||
@ -284,6 +299,19 @@ enum UnaryOperatorKind {
|
||||
UO_Extension // __extension__ marker.
|
||||
};
|
||||
|
||||
/// \brief The kind of bridging performed by the Objective-C bridge cast.
|
||||
enum ObjCBridgeCastKind {
|
||||
/// \brief Bridging via __bridge, which does nothing but reinterpret
|
||||
/// the bits.
|
||||
OBC_Bridge,
|
||||
/// \brief Bridging via __bridge_transfer, which transfers ownership of an
|
||||
/// Objective-C pointer into ARC.
|
||||
OBC_BridgeTransfer,
|
||||
/// \brief Bridging via __bridge_retain, which makes an ARC object available
|
||||
/// as a +1 C pointer.
|
||||
OBC_BridgeRetained
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,6 +32,7 @@ class ParentMap {
|
||||
Stmt *getParent(Stmt*) const;
|
||||
Stmt *getParentIgnoreParens(Stmt *) const;
|
||||
Stmt *getParentIgnoreParenCasts(Stmt *) const;
|
||||
Stmt *getOuterParenParent(Stmt *) const;
|
||||
|
||||
const Stmt *getParent(const Stmt* S) const {
|
||||
return getParent(const_cast<Stmt*>(S));
|
||||
|
@ -41,7 +41,7 @@ struct PrintingPolicy {
|
||||
SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
|
||||
SuppressInitializers(false),
|
||||
Dump(false), ConstantArraySizeAsWritten(false),
|
||||
AnonymousTagLocations(true) { }
|
||||
AnonymousTagLocations(true), SuppressStrongLifetime(false) { }
|
||||
|
||||
/// \brief The number of spaces to use to indent each line.
|
||||
unsigned Indentation : 8;
|
||||
@ -129,6 +129,10 @@ struct PrintingPolicy {
|
||||
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
|
||||
/// prints "<anonymous>" for the name.
|
||||
bool AnonymousTagLocations : 1;
|
||||
|
||||
/// \brief When true, suppress printing of the __strong lifetime qualifier in
|
||||
/// ARC.
|
||||
unsigned SuppressStrongLifetime : 1;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -1721,6 +1721,7 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
|
||||
DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
|
||||
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
|
||||
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
|
||||
DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
|
||||
DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
|
||||
DEF_TRAVERSE_STMT(ReturnStmt, { })
|
||||
DEF_TRAVERSE_STMT(SwitchStmt, { })
|
||||
@ -1933,6 +1934,10 @@ DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
|
||||
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
|
||||
DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
|
||||
DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
|
||||
DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
|
||||
DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
|
||||
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
|
||||
})
|
||||
DEF_TRAVERSE_STMT(ParenExpr, { })
|
||||
DEF_TRAVERSE_STMT(ParenListExpr, { })
|
||||
DEF_TRAVERSE_STMT(PredefinedExpr, { })
|
||||
@ -1973,6 +1978,8 @@ DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
|
||||
DEF_TRAVERSE_STMT(PackExpansionExpr, { })
|
||||
DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
|
||||
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
|
||||
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
|
||||
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
|
||||
|
||||
// These literals (all of them) do not need any action.
|
||||
DEF_TRAVERSE_STMT(IntegerLiteral, { })
|
||||
|
@ -154,9 +154,10 @@ class Stmt {
|
||||
unsigned ObjectKind : 2;
|
||||
unsigned TypeDependent : 1;
|
||||
unsigned ValueDependent : 1;
|
||||
unsigned InstantiationDependent : 1;
|
||||
unsigned ContainsUnexpandedParameterPack : 1;
|
||||
};
|
||||
enum { NumExprBits = 15 };
|
||||
enum { NumExprBits = 16 };
|
||||
|
||||
class DeclRefExprBitfields {
|
||||
friend class DeclRefExpr;
|
||||
@ -183,6 +184,13 @@ class Stmt {
|
||||
unsigned NumPreArgs : 1;
|
||||
};
|
||||
|
||||
class ObjCIndirectCopyRestoreExprBitfields {
|
||||
friend class ObjCIndirectCopyRestoreExpr;
|
||||
unsigned : NumExprBits;
|
||||
|
||||
unsigned ShouldCopy : 1;
|
||||
};
|
||||
|
||||
union {
|
||||
// FIXME: this is wasteful on 64-bit platforms.
|
||||
void *Aligner;
|
||||
@ -193,6 +201,7 @@ class Stmt {
|
||||
DeclRefExprBitfields DeclRefExprBits;
|
||||
CastExprBitfields CastExprBits;
|
||||
CallExprBitfields CallExprBits;
|
||||
ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
|
||||
};
|
||||
|
||||
friend class ASTStmtReader;
|
||||
@ -284,6 +293,10 @@ class Stmt {
|
||||
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
|
||||
void viewAST() const;
|
||||
|
||||
/// Skip past any implicit AST nodes which might surround this
|
||||
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
|
||||
Stmt *IgnoreImplicit();
|
||||
|
||||
// Implement isa<T> support.
|
||||
static bool classof(const Stmt *) { return true; }
|
||||
|
||||
@ -327,7 +340,7 @@ class Stmt {
|
||||
/// declaration pointers) or the exact representation of the statement as
|
||||
/// written in the source.
|
||||
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
|
||||
bool Canonical);
|
||||
bool Canonical) const;
|
||||
};
|
||||
|
||||
/// DeclStmt - Adaptor class for mixing declarations with statements and
|
||||
@ -1458,6 +1471,10 @@ class SEHExceptStmt : public Stmt {
|
||||
Expr *FilterExpr,
|
||||
Stmt *Block);
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
|
||||
|
||||
public:
|
||||
static SEHExceptStmt* Create(ASTContext &C,
|
||||
SourceLocation ExceptLoc,
|
||||
@ -1492,6 +1509,10 @@ class SEHFinallyStmt : public Stmt {
|
||||
SEHFinallyStmt(SourceLocation Loc,
|
||||
Stmt *Block);
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
|
||||
|
||||
public:
|
||||
static SEHFinallyStmt* Create(ASTContext &C,
|
||||
SourceLocation FinallyLoc,
|
||||
@ -1530,6 +1551,10 @@ class SEHTryStmt : public Stmt {
|
||||
Stmt *TryBlock,
|
||||
Stmt *Handler);
|
||||
|
||||
friend class ASTReader;
|
||||
friend class ASTStmtReader;
|
||||
explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
|
||||
|
||||
public:
|
||||
static SEHTryStmt* Create(ASTContext &C,
|
||||
bool isCXXTry,
|
||||
|
@ -342,6 +342,39 @@ class ObjCAtThrowStmt : public Stmt {
|
||||
child_range children() { return child_range(&Throw, &Throw+1); }
|
||||
};
|
||||
|
||||
/// ObjCAutoreleasePoolStmt - This represent objective-c's
|
||||
/// @autoreleasepool Statement
|
||||
class ObjCAutoreleasePoolStmt : public Stmt {
|
||||
Stmt *SubStmt;
|
||||
SourceLocation AtLoc;
|
||||
public:
|
||||
ObjCAutoreleasePoolStmt(SourceLocation atLoc,
|
||||
Stmt *subStmt)
|
||||
: Stmt(ObjCAutoreleasePoolStmtClass),
|
||||
SubStmt(subStmt), AtLoc(atLoc) {}
|
||||
|
||||
explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) :
|
||||
Stmt(ObjCAutoreleasePoolStmtClass, Empty) { }
|
||||
|
||||
const Stmt *getSubStmt() const { return SubStmt; }
|
||||
Stmt *getSubStmt() { return SubStmt; }
|
||||
void setSubStmt(Stmt *S) { SubStmt = S; }
|
||||
|
||||
SourceRange getSourceRange() const {
|
||||
return SourceRange(AtLoc, SubStmt->getLocEnd());
|
||||
}
|
||||
|
||||
SourceLocation getAtLoc() const { return AtLoc; }
|
||||
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ObjCAutoreleasePoolStmtClass;
|
||||
}
|
||||
static bool classof(const ObjCAutoreleasePoolStmt *) { return true; }
|
||||
|
||||
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -235,9 +235,14 @@ class TemplateArgument {
|
||||
bool isNull() const { return Kind == Null; }
|
||||
|
||||
/// \brief Whether this template argument is dependent on a template
|
||||
/// parameter.
|
||||
/// parameter such that its result can change from one instantiation to
|
||||
/// another.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Whether this template argument is dependent on a template
|
||||
/// parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Whether this template argument contains an unexpanded
|
||||
/// parameter pack.
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
@ -33,6 +33,7 @@ class OverloadedTemplateStorage;
|
||||
struct PrintingPolicy;
|
||||
class QualifiedTemplateName;
|
||||
class NamedDecl;
|
||||
class SubstTemplateTemplateParmStorage;
|
||||
class SubstTemplateTemplateParmPackStorage;
|
||||
class TemplateArgument;
|
||||
class TemplateDecl;
|
||||
@ -42,38 +43,49 @@ class TemplateTemplateParmDecl;
|
||||
/// template names or an already-substituted template template parameter pack.
|
||||
class UncommonTemplateNameStorage {
|
||||
protected:
|
||||
enum Kind {
|
||||
Overloaded,
|
||||
SubstTemplateTemplateParm,
|
||||
SubstTemplateTemplateParmPack
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
/// \brief If true, this is an OverloadedTemplateStorage instance;
|
||||
/// otherwise, it's a SubstTemplateTemplateParmPackStorage instance.
|
||||
unsigned IsOverloadedStorage : 1;
|
||||
/// \brief A Kind.
|
||||
unsigned Kind : 2;
|
||||
|
||||
/// \brief The number of stored templates or template arguments,
|
||||
/// depending on which subclass we have.
|
||||
unsigned Size : 31;
|
||||
unsigned Size : 30;
|
||||
} Bits;
|
||||
|
||||
void *PointerAlignment;
|
||||
};
|
||||
|
||||
UncommonTemplateNameStorage(unsigned Size, bool OverloadedStorage) {
|
||||
Bits.IsOverloadedStorage = OverloadedStorage;
|
||||
Bits.Size = Size;
|
||||
UncommonTemplateNameStorage(Kind kind, unsigned size) {
|
||||
Bits.Kind = kind;
|
||||
Bits.Size = size;
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned size() const { return Bits.Size; }
|
||||
|
||||
OverloadedTemplateStorage *getAsOverloadedStorage() {
|
||||
return Bits.IsOverloadedStorage
|
||||
return Bits.Kind == Overloaded
|
||||
? reinterpret_cast<OverloadedTemplateStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
|
||||
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
|
||||
return Bits.Kind == SubstTemplateTemplateParm
|
||||
? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
|
||||
SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
|
||||
return Bits.IsOverloadedStorage
|
||||
? 0
|
||||
: reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) ;
|
||||
return Bits.Kind == SubstTemplateTemplateParmPack
|
||||
? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
|
||||
: 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -82,8 +94,8 @@ class UncommonTemplateNameStorage {
|
||||
class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
friend class ASTContext;
|
||||
|
||||
OverloadedTemplateStorage(unsigned Size)
|
||||
: UncommonTemplateNameStorage(Size, true) { }
|
||||
OverloadedTemplateStorage(unsigned size)
|
||||
: UncommonTemplateNameStorage(Overloaded, size) { }
|
||||
|
||||
NamedDecl **getStorage() {
|
||||
return reinterpret_cast<NamedDecl **>(this + 1);
|
||||
@ -98,8 +110,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
iterator begin() const { return getStorage(); }
|
||||
iterator end() const { return getStorage() + size(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// \brief A structure for storing an already-substituted template template
|
||||
/// parameter pack.
|
||||
///
|
||||
@ -109,16 +120,14 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
|
||||
class SubstTemplateTemplateParmPackStorage
|
||||
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode
|
||||
{
|
||||
ASTContext &Context;
|
||||
TemplateTemplateParmDecl *Parameter;
|
||||
const TemplateArgument *Arguments;
|
||||
|
||||
public:
|
||||
SubstTemplateTemplateParmPackStorage(ASTContext &Context,
|
||||
TemplateTemplateParmDecl *Parameter,
|
||||
SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
|
||||
unsigned Size,
|
||||
const TemplateArgument *Arguments)
|
||||
: UncommonTemplateNameStorage(Size, false), Context(Context),
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
|
||||
Parameter(Parameter), Arguments(Arguments) { }
|
||||
|
||||
/// \brief Retrieve the template template parameter pack being substituted.
|
||||
@ -130,9 +139,10 @@ class SubstTemplateTemplateParmPackStorage
|
||||
/// parameter was substituted.
|
||||
TemplateArgument getArgumentPack() const;
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
ASTContext &Context,
|
||||
TemplateTemplateParmDecl *Parameter,
|
||||
const TemplateArgument &ArgPack);
|
||||
};
|
||||
@ -189,6 +199,9 @@ class TemplateName {
|
||||
/// \brief A dependent template name that has not been resolved to a
|
||||
/// template (or set of templates).
|
||||
DependentTemplate,
|
||||
/// \brief A template template parameter that has been substituted
|
||||
/// for some other template name.
|
||||
SubstTemplateTemplateParm,
|
||||
/// \brief A template template parameter pack that has been substituted for
|
||||
/// a template template argument pack, but has not yet been expanded into
|
||||
/// individual arguments.
|
||||
@ -199,6 +212,7 @@ class TemplateName {
|
||||
explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
|
||||
explicit TemplateName(OverloadedTemplateStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
|
||||
explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
|
||||
@ -234,6 +248,19 @@ class TemplateName {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the substituted template template parameter, if
|
||||
/// known.
|
||||
///
|
||||
/// \returns The storage for the substituted template template parameter,
|
||||
/// if known. Otherwise, returns NULL.
|
||||
SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
|
||||
if (UncommonTemplateNameStorage *uncommon =
|
||||
Storage.dyn_cast<UncommonTemplateNameStorage *>())
|
||||
return uncommon->getAsSubstTemplateTemplateParm();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the substituted template template parameter pack, if
|
||||
/// known.
|
||||
///
|
||||
@ -260,9 +287,15 @@ class TemplateName {
|
||||
return Storage.dyn_cast<DependentTemplateName *>();
|
||||
}
|
||||
|
||||
TemplateName getUnderlying() const;
|
||||
|
||||
/// \brief Determines whether this is a dependent template name.
|
||||
bool isDependent() const;
|
||||
|
||||
/// \brief Determines whether this is a template name that somehow
|
||||
/// depends on a template parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Determines whether this template name contains an
|
||||
/// unexpanded parameter pack (for C++0x variadic templates).
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
@ -300,6 +333,41 @@ class TemplateName {
|
||||
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
TemplateName N);
|
||||
|
||||
/// \brief A structure for storing the information associated with a
|
||||
/// substituted template template parameter.
|
||||
class SubstTemplateTemplateParmStorage
|
||||
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
|
||||
friend class ASTContext;
|
||||
|
||||
TemplateTemplateParmDecl *Parameter;
|
||||
TemplateName Replacement;
|
||||
|
||||
SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
|
||||
TemplateName replacement)
|
||||
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
|
||||
Parameter(parameter), Replacement(replacement) {}
|
||||
|
||||
public:
|
||||
TemplateTemplateParmDecl *getParameter() const { return Parameter; }
|
||||
TemplateName getReplacement() const { return Replacement; }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID);
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID,
|
||||
TemplateTemplateParmDecl *parameter,
|
||||
TemplateName replacement);
|
||||
};
|
||||
|
||||
inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
|
||||
: Storage(Storage) { }
|
||||
|
||||
inline TemplateName TemplateName::getUnderlying() const {
|
||||
if (SubstTemplateTemplateParmStorage *subst
|
||||
= getAsSubstTemplateTemplateParm())
|
||||
return subst->getReplacement().getUnderlying();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Represents a template name that was expressed as a
|
||||
/// qualified name.
|
||||
///
|
||||
|
@ -126,6 +126,28 @@ class Qualifiers {
|
||||
Strong
|
||||
};
|
||||
|
||||
enum ObjCLifetime {
|
||||
/// There is no lifetime qualification on this type.
|
||||
OCL_None,
|
||||
|
||||
/// This object can be modified without requiring retains or
|
||||
/// releases.
|
||||
OCL_ExplicitNone,
|
||||
|
||||
/// Assigning into this object requires the old value to be
|
||||
/// released and the new value to be retained. The timing of the
|
||||
/// release of the old value is inexact: it may be moved to
|
||||
/// immediately after the last known point where the value is
|
||||
/// live.
|
||||
OCL_Strong,
|
||||
|
||||
/// Reading or writing from this object requires a barrier call.
|
||||
OCL_Weak,
|
||||
|
||||
/// Assigning into this object requires a lifetime extension.
|
||||
OCL_Autoreleasing
|
||||
};
|
||||
|
||||
enum {
|
||||
/// The maximum supported address space number.
|
||||
/// 24 bits should be enough for anyone.
|
||||
@ -218,7 +240,37 @@ class Qualifiers {
|
||||
qs.removeObjCGCAttr();
|
||||
return qs;
|
||||
}
|
||||
Qualifiers withoutObjCGLifetime() const {
|
||||
Qualifiers qs = *this;
|
||||
qs.removeObjCLifetime();
|
||||
return qs;
|
||||
}
|
||||
|
||||
bool hasObjCLifetime() const { return Mask & LifetimeMask; }
|
||||
ObjCLifetime getObjCLifetime() const {
|
||||
return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
|
||||
}
|
||||
void setObjCLifetime(ObjCLifetime type) {
|
||||
Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
|
||||
}
|
||||
void removeObjCLifetime() { setObjCLifetime(OCL_None); }
|
||||
void addObjCLifetime(ObjCLifetime type) {
|
||||
assert(type);
|
||||
setObjCLifetime(type);
|
||||
}
|
||||
|
||||
/// True if the lifetime is neither None or ExplicitNone.
|
||||
bool hasNonTrivialObjCLifetime() const {
|
||||
ObjCLifetime lifetime = getObjCLifetime();
|
||||
return (lifetime > OCL_ExplicitNone);
|
||||
}
|
||||
|
||||
/// True if the lifetime is either strong or weak.
|
||||
bool hasStrongOrWeakObjCLifetime() const {
|
||||
ObjCLifetime lifetime = getObjCLifetime();
|
||||
return (lifetime == OCL_Strong || lifetime == OCL_Weak);
|
||||
}
|
||||
|
||||
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
|
||||
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
|
||||
void setAddressSpace(unsigned space) {
|
||||
@ -277,6 +329,8 @@ class Qualifiers {
|
||||
addAddressSpace(Q.getAddressSpace());
|
||||
if (Q.hasObjCGCAttr())
|
||||
addObjCGCAttr(Q.getObjCGCAttr());
|
||||
if (Q.hasObjCLifetime())
|
||||
addObjCLifetime(Q.getObjCLifetime());
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,6 +341,8 @@ class Qualifiers {
|
||||
!hasAddressSpace() || !qs.hasAddressSpace());
|
||||
assert(getObjCGCAttr() == qs.getObjCGCAttr() ||
|
||||
!hasObjCGCAttr() || !qs.hasObjCGCAttr());
|
||||
assert(getObjCLifetime() == qs.getObjCLifetime() ||
|
||||
!hasObjCLifetime() || !qs.hasObjCLifetime());
|
||||
Mask |= qs.Mask;
|
||||
}
|
||||
|
||||
@ -301,10 +357,30 @@ class Qualifiers {
|
||||
// changed.
|
||||
(getObjCGCAttr() == other.getObjCGCAttr() ||
|
||||
!hasObjCGCAttr() || !other.hasObjCGCAttr()) &&
|
||||
// ObjC lifetime qualifiers must match exactly.
|
||||
getObjCLifetime() == other.getObjCLifetime() &&
|
||||
// CVR qualifiers may subset.
|
||||
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
|
||||
}
|
||||
|
||||
/// \brief Determines if these qualifiers compatibly include another set of
|
||||
/// qualifiers from the narrow perspective of Objective-C ARC lifetime.
|
||||
///
|
||||
/// One set of Objective-C lifetime qualifiers compatibly includes the other
|
||||
/// if the lifetime qualifiers match, or if both are non-__weak and the
|
||||
/// including set also contains the 'const' qualifier.
|
||||
bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
|
||||
if (getObjCLifetime() == other.getObjCLifetime())
|
||||
return true;
|
||||
|
||||
if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
|
||||
return false;
|
||||
|
||||
return hasConst();
|
||||
}
|
||||
|
||||
bool isSupersetOf(Qualifiers Other) const;
|
||||
|
||||
/// \brief Determine whether this set of qualifiers is a strict superset of
|
||||
/// another set of qualifiers, not considering qualifier compatibility.
|
||||
bool isStrictSupersetOf(Qualifiers Other) const;
|
||||
@ -351,14 +427,16 @@ class Qualifiers {
|
||||
|
||||
private:
|
||||
|
||||
// bits: |0 1 2|3 .. 4|5 .. 31|
|
||||
// |C R V|GCAttr|AddrSpace|
|
||||
// bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31|
|
||||
// |C R V|GCAttr|Lifetime|AddressSpace|
|
||||
uint32_t Mask;
|
||||
|
||||
static const uint32_t GCAttrMask = 0x18;
|
||||
static const uint32_t GCAttrShift = 3;
|
||||
static const uint32_t AddressSpaceMask = ~(CVRMask | GCAttrMask);
|
||||
static const uint32_t AddressSpaceShift = 5;
|
||||
static const uint32_t LifetimeMask = 0xE0;
|
||||
static const uint32_t LifetimeShift = 5;
|
||||
static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask);
|
||||
static const uint32_t AddressSpaceShift = 8;
|
||||
};
|
||||
|
||||
/// CallingConv - Specifies the calling convention that a function uses.
|
||||
@ -527,6 +605,23 @@ class QualType {
|
||||
return QualType::isConstant(*this, Ctx);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
|
||||
bool isPODType(ASTContext &Context) const;
|
||||
|
||||
/// isCXX11PODType() - Return true if this is a POD type according to the
|
||||
/// more relaxed rules of the C++11 standard, regardless of the current
|
||||
/// compilation's language.
|
||||
/// (C++0x [basic.types]p9)
|
||||
bool isCXX11PODType(ASTContext &Context) const;
|
||||
|
||||
/// isTrivialType - Return true if this is a trivial type
|
||||
/// (C++0x [basic.types]p9)
|
||||
bool isTrivialType(ASTContext &Context) const;
|
||||
|
||||
/// isTriviallyCopyableType - Return true if this is a trivially
|
||||
/// copyable type (C++0x [basic.types]p9)
|
||||
bool isTriviallyCopyableType(ASTContext &Context) const;
|
||||
|
||||
// Don't promise in the API that anything besides 'const' can be
|
||||
// easily added.
|
||||
|
||||
@ -546,6 +641,10 @@ class QualType {
|
||||
return withFastQualifiers(Qualifiers::Volatile);
|
||||
}
|
||||
|
||||
QualType withCVRQualifiers(unsigned CVR) const {
|
||||
return withFastQualifiers(CVR);
|
||||
}
|
||||
|
||||
void addFastQualifiers(unsigned TQs) {
|
||||
assert(!(TQs & ~Qualifiers::FastMask)
|
||||
&& "non-fast qualifier bits set in mask!");
|
||||
@ -658,6 +757,13 @@ class QualType {
|
||||
return getSplitDesugaredType(*this);
|
||||
}
|
||||
|
||||
/// \brief Return the specified type with one level of "sugar" removed from
|
||||
/// the type.
|
||||
///
|
||||
/// This routine takes off the first typedef, typeof, etc. If the outer level
|
||||
/// of the type is already concrete, it returns it unmodified.
|
||||
QualType getSingleStepDesugaredType(const ASTContext &Context) const;
|
||||
|
||||
/// IgnoreParens - Returns the specified type after dropping any
|
||||
/// outer-level parentheses.
|
||||
QualType IgnoreParens() const {
|
||||
@ -709,7 +815,7 @@ class QualType {
|
||||
/// getAddressSpace - Return the address space of this type.
|
||||
inline unsigned getAddressSpace() const;
|
||||
|
||||
/// GCAttrTypesAttr - Returns gc attribute of this type.
|
||||
/// getObjCGCAttr - Returns gc attribute of this type.
|
||||
inline Qualifiers::GC getObjCGCAttr() const;
|
||||
|
||||
/// isObjCGCWeak true when Type is objc's weak.
|
||||
@ -722,9 +828,24 @@ class QualType {
|
||||
return getObjCGCAttr() == Qualifiers::Strong;
|
||||
}
|
||||
|
||||
/// getObjCLifetime - Returns lifetime attribute of this type.
|
||||
Qualifiers::ObjCLifetime getObjCLifetime() const {
|
||||
return getQualifiers().getObjCLifetime();
|
||||
}
|
||||
|
||||
bool hasNonTrivialObjCLifetime() const {
|
||||
return getQualifiers().hasNonTrivialObjCLifetime();
|
||||
}
|
||||
|
||||
bool hasStrongOrWeakObjCLifetime() const {
|
||||
return getQualifiers().hasStrongOrWeakObjCLifetime();
|
||||
}
|
||||
|
||||
enum DestructionKind {
|
||||
DK_none,
|
||||
DK_cxx_destructor
|
||||
DK_cxx_destructor,
|
||||
DK_objc_strong_lifetime,
|
||||
DK_objc_weak_lifetime
|
||||
};
|
||||
|
||||
/// isDestructedType - nonzero if objects of this type require
|
||||
@ -735,6 +856,21 @@ class QualType {
|
||||
return isDestructedTypeImpl(*this);
|
||||
}
|
||||
|
||||
/// \brief Determine whether expressions of the given type are forbidden
|
||||
/// from being lvalues in C.
|
||||
///
|
||||
/// The expression types that are forbidden to be lvalues are:
|
||||
/// - 'void', but not qualified void
|
||||
/// - function types
|
||||
///
|
||||
/// The exact rule here is C99 6.3.2.1:
|
||||
/// An lvalue is an expression with an object type or an incomplete
|
||||
/// type other than void.
|
||||
bool isCForbiddenLValueType() const;
|
||||
|
||||
/// \brief Determine whether this type has trivial copy-assignment semantics.
|
||||
bool hasTrivialCopyAssignment(ASTContext &Context) const;
|
||||
|
||||
private:
|
||||
// These methods are implemented in a separate translation unit;
|
||||
// "static"-ize them to avoid creating temporary QualTypes in the
|
||||
@ -849,6 +985,11 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
|
||||
bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
|
||||
Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
|
||||
|
||||
bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
|
||||
Qualifiers::ObjCLifetime getObjCLifetime() const {
|
||||
return Quals.getObjCLifetime();
|
||||
}
|
||||
|
||||
bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
|
||||
unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
|
||||
|
||||
@ -931,6 +1072,10 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
/// subclasses can pack their bitfields into the same word.
|
||||
unsigned Dependent : 1;
|
||||
|
||||
/// \brief Whether this type somehow involves a template parameter, even
|
||||
/// if the resolution of the type does not depend on a template parameter.
|
||||
unsigned InstantiationDependent : 1;
|
||||
|
||||
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
||||
unsigned VariablyModified : 1;
|
||||
|
||||
@ -968,7 +1113,7 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
return CachedLocalOrUnnamed;
|
||||
}
|
||||
};
|
||||
enum { NumTypeBits = 17 };
|
||||
enum { NumTypeBits = 18 };
|
||||
|
||||
protected:
|
||||
// These classes allow subclasses to somewhat cleanly pack bitfields
|
||||
@ -1111,12 +1256,14 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
protected:
|
||||
// silence VC++ warning C4355: 'this' : used in base member initializer list
|
||||
Type *this_() { return this; }
|
||||
Type(TypeClass tc, QualType canon, bool Dependent, bool VariablyModified,
|
||||
Type(TypeClass tc, QualType canon, bool Dependent,
|
||||
bool InstantiationDependent, bool VariablyModified,
|
||||
bool ContainsUnexpandedParameterPack)
|
||||
: ExtQualsTypeCommonBase(this,
|
||||
canon.isNull() ? QualType(this_(), 0) : canon) {
|
||||
TypeBits.TC = tc;
|
||||
TypeBits.Dependent = Dependent;
|
||||
TypeBits.InstantiationDependent = Dependent || InstantiationDependent;
|
||||
TypeBits.VariablyModified = VariablyModified;
|
||||
TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
|
||||
TypeBits.CacheValidAndVisibility = 0;
|
||||
@ -1126,8 +1273,15 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
}
|
||||
friend class ASTContext;
|
||||
|
||||
void setDependent(bool D = true) { TypeBits.Dependent = D; }
|
||||
void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; }
|
||||
void setDependent(bool D = true) {
|
||||
TypeBits.Dependent = D;
|
||||
if (D)
|
||||
TypeBits.InstantiationDependent = true;
|
||||
}
|
||||
void setInstantiationDependent(bool D = true) {
|
||||
TypeBits.InstantiationDependent = D; }
|
||||
void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM;
|
||||
}
|
||||
void setContainsUnexpandedParameterPack(bool PP = true) {
|
||||
TypeBits.ContainsUnexpandedParameterPack = PP;
|
||||
}
|
||||
@ -1186,31 +1340,14 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
return !isReferenceType() && !isFunctionType() && !isVoidType();
|
||||
}
|
||||
|
||||
/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
|
||||
bool isPODType() const;
|
||||
|
||||
/// isLiteralType - Return true if this is a literal type
|
||||
/// (C++0x [basic.types]p10)
|
||||
bool isLiteralType() const;
|
||||
|
||||
/// isTrivialType - Return true if this is a trivial type
|
||||
/// (C++0x [basic.types]p9)
|
||||
bool isTrivialType() const;
|
||||
|
||||
/// isTriviallyCopyableType - Return true if this is a trivially copyable type
|
||||
/// (C++0x [basic.types]p9
|
||||
bool isTriviallyCopyableType() const;
|
||||
|
||||
/// \brief Test if this type is a standard-layout type.
|
||||
/// (C++0x [basic.type]p9)
|
||||
bool isStandardLayoutType() const;
|
||||
|
||||
/// isCXX11PODType() - Return true if this is a POD type according to the
|
||||
/// more relaxed rules of the C++11 standard, regardless of the current
|
||||
/// compilation's language.
|
||||
/// (C++0x [basic.types]p9)
|
||||
bool isCXX11PODType() const;
|
||||
|
||||
/// Helper methods to distinguish type categories. All type predicates
|
||||
/// operate on the canonical type, ignoring typedefs and qualifiers.
|
||||
|
||||
@ -1290,7 +1427,11 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
bool isComplexIntegerType() const; // GCC _Complex integer type.
|
||||
bool isVectorType() const; // GCC vector type.
|
||||
bool isExtVectorType() const; // Extended vector type.
|
||||
bool isObjCObjectPointerType() const; // Pointer to *any* ObjC object.
|
||||
bool isObjCObjectPointerType() const; // pointer to ObjC object
|
||||
bool isObjCRetainableType() const; // ObjC object or block pointer
|
||||
bool isObjCLifetimeType() const; // (array of)* retainable type
|
||||
bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type
|
||||
bool isObjCNSObjectType() const; // __attribute__((NSObject))
|
||||
// FIXME: change this to 'raw' interface type, so we can used 'interface' type
|
||||
// for the common case.
|
||||
bool isObjCObjectType() const; // NSString or typeof(*(id)0)
|
||||
@ -1302,9 +1443,19 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
bool isObjCClassType() const; // Class
|
||||
bool isObjCSelType() const; // Class
|
||||
bool isObjCBuiltinType() const; // 'id' or 'Class'
|
||||
bool isObjCARCBridgableType() const;
|
||||
bool isCARCBridgableType() const;
|
||||
bool isTemplateTypeParmType() const; // C++ template type parameter
|
||||
bool isNullPtrType() const; // C++0x nullptr_t
|
||||
|
||||
/// Determines if this type, which must satisfy
|
||||
/// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
|
||||
/// than implicitly __strong.
|
||||
bool isObjCARCImplicitlyUnretainedType() const;
|
||||
|
||||
/// Return the implicit lifetime for this type, which must not be dependent.
|
||||
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
|
||||
|
||||
enum ScalarTypeKind {
|
||||
STK_Pointer,
|
||||
STK_MemberPointer,
|
||||
@ -1322,6 +1473,14 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
/// (C++ [temp.dep.type]).
|
||||
bool isDependentType() const { return TypeBits.Dependent; }
|
||||
|
||||
/// \brief Determine whether this type is an instantiation-dependent type,
|
||||
/// meaning that the type involves a template parameter (even if the
|
||||
/// definition does not actually depend on the type substituted for that
|
||||
/// template parameter).
|
||||
bool isInstantiationDependentType() const {
|
||||
return TypeBits.InstantiationDependent;
|
||||
}
|
||||
|
||||
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
||||
bool isVariablyModifiedType() const { return TypeBits.VariablyModified; }
|
||||
|
||||
@ -1336,6 +1495,8 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
|
||||
/// \brief Determine wither this type is a C++ elaborated-type-specifier.
|
||||
bool isElaboratedTypeSpecifier() const;
|
||||
|
||||
bool canDecayToPointerType() const;
|
||||
|
||||
/// hasPointerRepresentation - Whether this type is represented
|
||||
/// natively as a pointer; this includes pointers, references, block
|
||||
@ -1480,6 +1641,7 @@ class Type : public ExtQualsTypeCommonBase {
|
||||
}
|
||||
CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
|
||||
void dump() const;
|
||||
|
||||
static bool classof(const Type *) { return true; }
|
||||
|
||||
friend class ASTReader;
|
||||
@ -1586,6 +1748,7 @@ class BuiltinType : public Type {
|
||||
public:
|
||||
BuiltinType(Kind K)
|
||||
: Type(Builtin, QualType(), /*Dependent=*/(K == Dependent),
|
||||
/*InstantiationDependent=*/(K == Dependent),
|
||||
/*VariablyModified=*/false,
|
||||
/*Unexpanded paramter pack=*/false) {
|
||||
BuiltinTypeBits.Kind = K;
|
||||
@ -1631,6 +1794,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
|
||||
QualType ElementType;
|
||||
ComplexType(QualType Element, QualType CanonicalPtr) :
|
||||
Type(Complex, CanonicalPtr, Element->isDependentType(),
|
||||
Element->isInstantiationDependentType(),
|
||||
Element->isVariablyModifiedType(),
|
||||
Element->containsUnexpandedParameterPack()),
|
||||
ElementType(Element) {
|
||||
@ -1661,6 +1825,7 @@ class ParenType : public Type, public llvm::FoldingSetNode {
|
||||
|
||||
ParenType(QualType InnerType, QualType CanonType) :
|
||||
Type(Paren, CanonType, InnerType->isDependentType(),
|
||||
InnerType->isInstantiationDependentType(),
|
||||
InnerType->isVariablyModifiedType(),
|
||||
InnerType->containsUnexpandedParameterPack()),
|
||||
Inner(InnerType) {
|
||||
@ -1692,6 +1857,7 @@ class PointerType : public Type, public llvm::FoldingSetNode {
|
||||
|
||||
PointerType(QualType Pointee, QualType CanonicalPtr) :
|
||||
Type(Pointer, CanonicalPtr, Pointee->isDependentType(),
|
||||
Pointee->isInstantiationDependentType(),
|
||||
Pointee->isVariablyModifiedType(),
|
||||
Pointee->containsUnexpandedParameterPack()),
|
||||
PointeeType(Pointee) {
|
||||
@ -1724,6 +1890,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
|
||||
QualType PointeeType; // Block is some kind of pointer type
|
||||
BlockPointerType(QualType Pointee, QualType CanonicalCls) :
|
||||
Type(BlockPointer, CanonicalCls, Pointee->isDependentType(),
|
||||
Pointee->isInstantiationDependentType(),
|
||||
Pointee->isVariablyModifiedType(),
|
||||
Pointee->containsUnexpandedParameterPack()),
|
||||
PointeeType(Pointee) {
|
||||
@ -1760,6 +1927,7 @@ class ReferenceType : public Type, public llvm::FoldingSetNode {
|
||||
ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
|
||||
bool SpelledAsLValue) :
|
||||
Type(tc, CanonicalRef, Referencee->isDependentType(),
|
||||
Referencee->isInstantiationDependentType(),
|
||||
Referencee->isVariablyModifiedType(),
|
||||
Referencee->containsUnexpandedParameterPack()),
|
||||
PointeeType(Referencee)
|
||||
@ -1844,6 +2012,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
|
||||
MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) :
|
||||
Type(MemberPointer, CanonicalPtr,
|
||||
Cls->isDependentType() || Pointee->isDependentType(),
|
||||
(Cls->isInstantiationDependentType() ||
|
||||
Pointee->isInstantiationDependentType()),
|
||||
Pointee->isVariablyModifiedType(),
|
||||
(Cls->containsUnexpandedParameterPack() ||
|
||||
Pointee->containsUnexpandedParameterPack())),
|
||||
@ -1911,6 +2081,7 @@ class ArrayType : public Type, public llvm::FoldingSetNode {
|
||||
ArraySizeModifier sm, unsigned tq,
|
||||
bool ContainsUnexpandedParameterPack)
|
||||
: Type(tc, can, et->isDependentType() || tc == DependentSizedArray,
|
||||
et->isInstantiationDependentType() || tc == DependentSizedArray,
|
||||
(tc == VariableArray || et->isVariablyModifiedType()),
|
||||
ContainsUnexpandedParameterPack),
|
||||
ElementType(et) {
|
||||
@ -2344,28 +2515,32 @@ class FunctionType : public Type {
|
||||
// you'll need to adjust both the Bits field below and
|
||||
// Type::FunctionTypeBitfields.
|
||||
|
||||
// | CC |noreturn|hasregparm|regparm
|
||||
// |0 .. 2| 3 | 4 |5 .. 7
|
||||
// | CC |noreturn|produces|regparm|
|
||||
// |0 .. 2| 3 | 4 | 5 .. 7|
|
||||
//
|
||||
// regparm is either 0 (no regparm attribute) or the regparm value+1.
|
||||
enum { CallConvMask = 0x7 };
|
||||
enum { NoReturnMask = 0x8 };
|
||||
enum { HasRegParmMask = 0x10 };
|
||||
enum { RegParmMask = ~(CallConvMask | NoReturnMask),
|
||||
RegParmOffset = 5 };
|
||||
enum { ProducesResultMask = 0x10 };
|
||||
enum { RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask),
|
||||
RegParmOffset = 5 }; // Assumed to be the last field
|
||||
|
||||
unsigned char Bits;
|
||||
uint16_t Bits;
|
||||
|
||||
ExtInfo(unsigned Bits) : Bits(static_cast<unsigned char>(Bits)) {}
|
||||
ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
|
||||
|
||||
friend class FunctionType;
|
||||
|
||||
public:
|
||||
// Constructor with no defaults. Use this when you know that you
|
||||
// have all the elements (when reading an AST file for example).
|
||||
ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) {
|
||||
ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
|
||||
bool producesResult) {
|
||||
assert((!hasRegParm || regParm < 7) && "Invalid regparm value");
|
||||
Bits = ((unsigned) cc) |
|
||||
(noReturn ? NoReturnMask : 0) |
|
||||
(hasRegParm ? HasRegParmMask : 0) |
|
||||
(regParm << RegParmOffset);
|
||||
(producesResult ? ProducesResultMask : 0) |
|
||||
(hasRegParm ? ((regParm + 1) << RegParmOffset) : 0);
|
||||
}
|
||||
|
||||
// Constructor with all defaults. Use when for example creating a
|
||||
@ -2373,8 +2548,14 @@ class FunctionType : public Type {
|
||||
ExtInfo() : Bits(0) {}
|
||||
|
||||
bool getNoReturn() const { return Bits & NoReturnMask; }
|
||||
bool getHasRegParm() const { return Bits & HasRegParmMask; }
|
||||
unsigned getRegParm() const { return Bits >> RegParmOffset; }
|
||||
bool getProducesResult() const { return Bits & ProducesResultMask; }
|
||||
bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; }
|
||||
unsigned getRegParm() const {
|
||||
unsigned RegParm = Bits >> RegParmOffset;
|
||||
if (RegParm > 0)
|
||||
--RegParm;
|
||||
return RegParm;
|
||||
}
|
||||
CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
|
||||
|
||||
bool operator==(ExtInfo Other) const {
|
||||
@ -2394,8 +2575,17 @@ class FunctionType : public Type {
|
||||
return ExtInfo(Bits & ~NoReturnMask);
|
||||
}
|
||||
|
||||
ExtInfo withProducesResult(bool producesResult) const {
|
||||
if (producesResult)
|
||||
return ExtInfo(Bits | ProducesResultMask);
|
||||
else
|
||||
return ExtInfo(Bits & ~ProducesResultMask);
|
||||
}
|
||||
|
||||
ExtInfo withRegParm(unsigned RegParm) const {
|
||||
return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset));
|
||||
assert(RegParm < 7 && "Invalid regparm value");
|
||||
return ExtInfo((Bits & ~RegParmMask) |
|
||||
((RegParm + 1) << RegParmOffset));
|
||||
}
|
||||
|
||||
ExtInfo withCallingConv(CallingConv cc) const {
|
||||
@ -2411,9 +2601,10 @@ class FunctionType : public Type {
|
||||
FunctionType(TypeClass tc, QualType res, bool variadic,
|
||||
unsigned typeQuals, RefQualifierKind RefQualifier,
|
||||
QualType Canonical, bool Dependent,
|
||||
bool InstantiationDependent,
|
||||
bool VariablyModified, bool ContainsUnexpandedParameterPack,
|
||||
ExtInfo Info)
|
||||
: Type(tc, Canonical, Dependent, VariablyModified,
|
||||
: Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
|
||||
ContainsUnexpandedParameterPack),
|
||||
ResultType(res) {
|
||||
FunctionTypeBits.ExtInfo = Info.Bits;
|
||||
@ -2458,7 +2649,8 @@ class FunctionType : public Type {
|
||||
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
|
||||
: FunctionType(FunctionNoProto, Result, false, 0, RQ_None, Canonical,
|
||||
/*Dependent=*/false, Result->isVariablyModifiedType(),
|
||||
/*Dependent=*/false, /*InstantiationDependent=*/false,
|
||||
Result->isVariablyModifiedType(),
|
||||
/*ContainsUnexpandedParameterPack=*/false, Info) {}
|
||||
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
@ -2495,7 +2687,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
struct ExtProtoInfo {
|
||||
ExtProtoInfo() :
|
||||
Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
|
||||
RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0) {}
|
||||
RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0),
|
||||
ConsumedArguments(0) {}
|
||||
|
||||
FunctionType::ExtInfo ExtInfo;
|
||||
bool Variadic;
|
||||
@ -2505,6 +2698,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
unsigned NumExceptions;
|
||||
const QualType *Exceptions;
|
||||
Expr *NoexceptExpr;
|
||||
const bool *ConsumedArguments;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -2523,7 +2717,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
QualType canonical, const ExtProtoInfo &epi);
|
||||
|
||||
/// NumArgs - The number of arguments this function has, not counting '...'.
|
||||
unsigned NumArgs : 20;
|
||||
unsigned NumArgs : 19;
|
||||
|
||||
/// NumExceptions - The number of types in the exception spec, if any.
|
||||
unsigned NumExceptions : 9;
|
||||
@ -2531,6 +2725,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
/// ExceptionSpecType - The type of exception specification this function has.
|
||||
unsigned ExceptionSpecType : 3;
|
||||
|
||||
/// HasAnyConsumedArgs - Whether this function has any consumed arguments.
|
||||
unsigned HasAnyConsumedArgs : 1;
|
||||
|
||||
/// ArgInfo - There is an variable size array after the class in memory that
|
||||
/// holds the argument types.
|
||||
|
||||
@ -2540,8 +2737,25 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
/// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
|
||||
/// to the expression in the noexcept() specifier.
|
||||
|
||||
/// ConsumedArgs - A variable size array, following Exceptions
|
||||
/// and of length NumArgs, holding flags indicating which arguments
|
||||
/// are consumed. This only appears if HasAnyConsumedArgs is true.
|
||||
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
const bool *getConsumedArgsBuffer() const {
|
||||
assert(hasAnyConsumedArgs());
|
||||
|
||||
// Find the end of the exceptions.
|
||||
Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end());
|
||||
if (getExceptionSpecType() != EST_ComputedNoexcept)
|
||||
eh_end += NumExceptions;
|
||||
else
|
||||
eh_end += 1; // NoexceptExpr
|
||||
|
||||
return reinterpret_cast<const bool*>(eh_end);
|
||||
}
|
||||
|
||||
public:
|
||||
unsigned getNumArgs() const { return NumArgs; }
|
||||
QualType getArgType(unsigned i) const {
|
||||
@ -2562,6 +2776,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
} else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
|
||||
EPI.NoexceptExpr = getNoexceptExpr();
|
||||
}
|
||||
if (hasAnyConsumedArgs())
|
||||
EPI.ConsumedArguments = getConsumedArgsBuffer();
|
||||
return EPI;
|
||||
}
|
||||
|
||||
@ -2647,6 +2863,16 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||
return exception_begin() + NumExceptions;
|
||||
}
|
||||
|
||||
bool hasAnyConsumedArgs() const {
|
||||
return HasAnyConsumedArgs;
|
||||
}
|
||||
bool isArgConsumed(unsigned I) const {
|
||||
assert(I < getNumArgs() && "argument index out of range!");
|
||||
if (hasAnyConsumedArgs())
|
||||
return getConsumedArgsBuffer()[I];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
@ -2670,7 +2896,7 @@ class UnresolvedUsingType : public Type {
|
||||
UnresolvedUsingTypenameDecl *Decl;
|
||||
|
||||
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
|
||||
: Type(UnresolvedUsing, QualType(), true, false,
|
||||
: Type(UnresolvedUsing, QualType(), true, true, false,
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
@ -2700,7 +2926,9 @@ class TypedefType : public Type {
|
||||
TypedefNameDecl *Decl;
|
||||
protected:
|
||||
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
|
||||
: Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(),
|
||||
: Type(tc, can, can->isDependentType(),
|
||||
can->isInstantiationDependentType(),
|
||||
can->isVariablyModifiedType(),
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Decl(const_cast<TypedefNameDecl*>(D)) {
|
||||
assert(!isa<TypedefType>(can) && "Invalid canonical type");
|
||||
@ -2731,7 +2959,7 @@ class TypeOfExprType : public Type {
|
||||
QualType desugar() const;
|
||||
|
||||
/// \brief Returns whether this type directly provides sugar.
|
||||
bool isSugared() const { return true; }
|
||||
bool isSugared() const;
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
|
||||
static bool classof(const TypeOfExprType *) { return true; }
|
||||
@ -2751,9 +2979,6 @@ class DependentTypeOfExprType
|
||||
DependentTypeOfExprType(const ASTContext &Context, Expr *E)
|
||||
: TypeOfExprType(E), Context(Context) { }
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, Context, getUnderlyingExpr());
|
||||
}
|
||||
@ -2766,7 +2991,9 @@ class DependentTypeOfExprType
|
||||
class TypeOfType : public Type {
|
||||
QualType TOType;
|
||||
TypeOfType(QualType T, QualType can)
|
||||
: Type(TypeOf, can, T->isDependentType(), T->isVariablyModifiedType(),
|
||||
: Type(TypeOf, can, T->isDependentType(),
|
||||
T->isInstantiationDependentType(),
|
||||
T->isVariablyModifiedType(),
|
||||
T->containsUnexpandedParameterPack()),
|
||||
TOType(T) {
|
||||
assert(!isa<TypedefType>(can) && "Invalid canonical type");
|
||||
@ -2802,10 +3029,10 @@ class DecltypeType : public Type {
|
||||
QualType getUnderlyingType() const { return UnderlyingType; }
|
||||
|
||||
/// \brief Remove a single level of sugar.
|
||||
QualType desugar() const { return getUnderlyingType(); }
|
||||
QualType desugar() const;
|
||||
|
||||
/// \brief Returns whether this type directly provides sugar.
|
||||
bool isSugared() const { return !isDependentType(); }
|
||||
bool isSugared() const;
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
|
||||
static bool classof(const DecltypeType *) { return true; }
|
||||
@ -2823,9 +3050,6 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
|
||||
public:
|
||||
DependentDecltypeType(const ASTContext &Context, Expr *E);
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) {
|
||||
Profile(ID, Context, getUnderlyingExpr());
|
||||
}
|
||||
@ -2971,6 +3195,7 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
|
||||
|
||||
// Enumerated operand (string or keyword).
|
||||
attr_objc_gc,
|
||||
attr_objc_ownership,
|
||||
attr_pcs,
|
||||
|
||||
FirstEnumOperandKind = attr_objc_gc,
|
||||
@ -2994,6 +3219,7 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
|
||||
AttributedType(QualType canon, Kind attrKind,
|
||||
QualType modified, QualType equivalent)
|
||||
: Type(Attributed, canon, canon->isDependentType(),
|
||||
canon->isInstantiationDependentType(),
|
||||
canon->isVariablyModifiedType(),
|
||||
canon->containsUnexpandedParameterPack()),
|
||||
ModifiedType(modified), EquivalentType(equivalent) {
|
||||
@ -3046,13 +3272,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
|
||||
/// Build a non-canonical type.
|
||||
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
|
||||
: Type(TemplateTypeParm, Canon, /*Dependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*VariablyModified=*/false,
|
||||
Canon->containsUnexpandedParameterPack()),
|
||||
TTPDecl(TTPDecl) { }
|
||||
|
||||
/// Build the canonical type.
|
||||
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
|
||||
: Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true,
|
||||
: Type(TemplateTypeParm, QualType(this, 0),
|
||||
/*Dependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*VariablyModified=*/false, PP) {
|
||||
CanTTPTInfo.Depth = D;
|
||||
CanTTPTInfo.Index = I;
|
||||
@ -3112,6 +3341,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
|
||||
|
||||
SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
|
||||
: Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(),
|
||||
Canon->isInstantiationDependentType(),
|
||||
Canon->isVariablyModifiedType(),
|
||||
Canon->containsUnexpandedParameterPack()),
|
||||
Replaced(Param) { }
|
||||
@ -3211,6 +3441,7 @@ class AutoType : public Type, public llvm::FoldingSetNode {
|
||||
AutoType(QualType DeducedType)
|
||||
: Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType,
|
||||
/*Dependent=*/DeducedType.isNull(),
|
||||
/*InstantiationDependent=*/DeducedType.isNull(),
|
||||
/*VariablyModified=*/false, /*ContainsParameterPack=*/false) {
|
||||
assert((DeducedType.isNull() || !DeducedType->isDependentType()) &&
|
||||
"deduced a dependent type for auto");
|
||||
@ -3244,28 +3475,35 @@ class AutoType : public Type, public llvm::FoldingSetNode {
|
||||
static bool classof(const AutoType *T) { return true; }
|
||||
};
|
||||
|
||||
/// \brief Represents the type of a template specialization as written
|
||||
/// in the source code.
|
||||
/// \brief Represents a type template specialization; the template
|
||||
/// must be a class template, a type alias template, or a template
|
||||
/// template parameter. A template which cannot be resolved to one of
|
||||
/// these, e.g. because it is written with a dependent scope
|
||||
/// specifier, is instead represented as a
|
||||
/// @c DependentTemplateSpecializationType.
|
||||
///
|
||||
/// Template specialization types represent the syntactic form of a
|
||||
/// template-id that refers to a type, e.g., @c vector<int>. Some
|
||||
/// template specialization types are syntactic sugar, whose canonical
|
||||
/// type will point to some other type node that represents the
|
||||
/// instantiation or class template specialization. For example, a
|
||||
/// class template specialization type of @c vector<int> will refer to
|
||||
/// a tag type for the instantiation
|
||||
/// @c std::vector<int, std::allocator<int>>.
|
||||
/// A non-dependent template specialization type is always "sugar",
|
||||
/// typically for a @c RecordType. For example, a class template
|
||||
/// specialization type of @c vector<int> will refer to a tag type for
|
||||
/// the instantiation @c std::vector<int, std::allocator<int>>
|
||||
///
|
||||
/// Other template specialization types, for which the template name
|
||||
/// is dependent, may be canonical types. These types are always
|
||||
/// dependent.
|
||||
/// Template specializations are dependent if either the template or
|
||||
/// any of the template arguments are dependent, in which case the
|
||||
/// type may also be canonical.
|
||||
///
|
||||
/// An instance of this type is followed by an array of TemplateArgument*s,
|
||||
/// then, if the template specialization type is for a type alias template,
|
||||
/// a QualType representing the non-canonical aliased type.
|
||||
/// Instances of this type are allocated with a trailing array of
|
||||
/// TemplateArguments, followed by a QualType representing the
|
||||
/// non-canonical aliased type when the template is a type alias
|
||||
/// template.
|
||||
class TemplateSpecializationType
|
||||
: public Type, public llvm::FoldingSetNode {
|
||||
/// \brief The name of the template being specialized.
|
||||
/// \brief The name of the template being specialized. This is
|
||||
/// either a TemplateName::Template (in which case it is a
|
||||
/// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
|
||||
/// TypeAliasTemplateDecl*), a
|
||||
/// TemplateName::SubstTemplateTemplateParmPack, or a
|
||||
/// TemplateName::SubstTemplateTemplateParm (in which case the
|
||||
/// replacement must, recursively, be one of these).
|
||||
TemplateName Template;
|
||||
|
||||
/// \brief - The number of template arguments named in this class
|
||||
@ -3283,12 +3521,15 @@ class TemplateSpecializationType
|
||||
/// \brief Determine whether any of the given template arguments are
|
||||
/// dependent.
|
||||
static bool anyDependentTemplateArguments(const TemplateArgument *Args,
|
||||
unsigned NumArgs);
|
||||
unsigned NumArgs,
|
||||
bool &InstantiationDependent);
|
||||
|
||||
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
|
||||
unsigned NumArgs);
|
||||
unsigned NumArgs,
|
||||
bool &InstantiationDependent);
|
||||
|
||||
static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
|
||||
static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
|
||||
bool &InstantiationDependent);
|
||||
|
||||
/// \brief Print a template argument list, including the '<' and '>'
|
||||
/// enclosing the template arguments.
|
||||
@ -3399,6 +3640,7 @@ class InjectedClassNameType : public Type {
|
||||
// interdependencies.
|
||||
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
|
||||
: Type(InjectedClassName, QualType(), /*Dependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*VariablyModified=*/false,
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Decl(D), InjectedType(TST) {
|
||||
@ -3461,9 +3703,10 @@ enum ElaboratedTypeKeyword {
|
||||
class TypeWithKeyword : public Type {
|
||||
protected:
|
||||
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
|
||||
QualType Canonical, bool Dependent, bool VariablyModified,
|
||||
QualType Canonical, bool Dependent,
|
||||
bool InstantiationDependent, bool VariablyModified,
|
||||
bool ContainsUnexpandedParameterPack)
|
||||
: Type(tc, Canonical, Dependent, VariablyModified,
|
||||
: Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified,
|
||||
ContainsUnexpandedParameterPack) {
|
||||
TypeWithKeywordBits.Keyword = Keyword;
|
||||
}
|
||||
@ -3523,6 +3766,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
|
||||
QualType NamedType, QualType CanonType)
|
||||
: TypeWithKeyword(Keyword, Elaborated, CanonType,
|
||||
NamedType->isDependentType(),
|
||||
NamedType->isInstantiationDependentType(),
|
||||
NamedType->isVariablyModifiedType(),
|
||||
NamedType->containsUnexpandedParameterPack()),
|
||||
NNS(NNS), NamedType(NamedType) {
|
||||
@ -3585,6 +3829,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
|
||||
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo *Name, QualType CanonType)
|
||||
: TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*VariablyModified=*/false,
|
||||
NNS->containsUnexpandedParameterPack()),
|
||||
NNS(NNS), Name(Name) {
|
||||
@ -3738,6 +3983,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
|
||||
PackExpansionType(QualType Pattern, QualType Canon,
|
||||
llvm::Optional<unsigned> NumExpansions)
|
||||
: Type(PackExpansion, Canon, /*Dependent=*/true,
|
||||
/*InstantiationDependent=*/true,
|
||||
/*VariableModified=*/Pattern->isVariablyModifiedType(),
|
||||
/*ContainsUnexpandedParameterPack=*/false),
|
||||
Pattern(Pattern),
|
||||
@ -3829,7 +4075,7 @@ class ObjCObjectType : public Type {
|
||||
|
||||
enum Nonce_ObjCInterface { Nonce_ObjCInterface };
|
||||
ObjCObjectType(enum Nonce_ObjCInterface)
|
||||
: Type(ObjCInterface, QualType(), false, false, false),
|
||||
: Type(ObjCInterface, QualType(), false, false, false, false),
|
||||
BaseType(QualType(this_(), 0)) {
|
||||
ObjCObjectTypeBits.NumProtocols = 0;
|
||||
}
|
||||
@ -3986,7 +4232,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
|
||||
QualType PointeeType;
|
||||
|
||||
ObjCObjectPointerType(QualType Canonical, QualType Pointee)
|
||||
: Type(ObjCObjectPointer, Canonical, false, false, false),
|
||||
: Type(ObjCObjectPointer, Canonical, false, false, false, false),
|
||||
PointeeType(Pointee) {}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
|
||||
@ -4303,6 +4549,11 @@ inline QualType QualType::getNonReferenceType() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool QualType::isCForbiddenLValueType() const {
|
||||
return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
|
||||
getTypePtr()->isFunctionType());
|
||||
}
|
||||
|
||||
/// \brief Tests whether the type is categorized as a fundamental type.
|
||||
///
|
||||
/// \returns True for types specified in C++0x [basic.fundamental].
|
||||
@ -4480,6 +4731,11 @@ inline bool Type::isOverloadableType() const {
|
||||
return isDependentType() || isRecordType() || isEnumeralType();
|
||||
}
|
||||
|
||||
/// \brief Determines whether this type can decay to a pointer type.
|
||||
inline bool Type::canDecayToPointerType() const {
|
||||
return isFunctionType() || isArrayType();
|
||||
}
|
||||
|
||||
inline bool Type::hasPointerRepresentation() const {
|
||||
return (isPointerType() || isReferenceType() || isBlockPointerType() ||
|
||||
isObjCObjectPointerType() || isNullPtrType());
|
||||
|
@ -32,10 +32,16 @@ class UninitVariablesHandler {
|
||||
const VarDecl *vd,
|
||||
bool isAlwaysUninit) {}
|
||||
};
|
||||
|
||||
|
||||
struct UninitVariablesAnalysisStats {
|
||||
unsigned NumVariablesAnalyzed;
|
||||
unsigned NumBlockVisits;
|
||||
};
|
||||
|
||||
void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
|
||||
AnalysisContext &ac,
|
||||
UninitVariablesHandler &handler);
|
||||
UninitVariablesHandler &handler,
|
||||
UninitVariablesAnalysisStats &stats);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -107,6 +107,11 @@ class AnalysisContext {
|
||||
|
||||
void dumpCFG();
|
||||
|
||||
/// \brief Returns true if we have built a CFG for this analysis context.
|
||||
/// Note that this doesn't correspond to whether or not a valid CFG exists, it
|
||||
/// corresponds to whether we *attempted* to build one.
|
||||
bool isCFGBuilt() const { return builtCFG; }
|
||||
|
||||
ParentMap &getParentMap();
|
||||
PseudoConstantAnalysis *getPseudoConstantAnalysis();
|
||||
LiveVariables *getLiveVariables();
|
||||
|
@ -7,34 +7,45 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines
|
||||
// This file implements cocoa naming convention analysis.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_DS_COCOA
|
||||
#define LLVM_CLANG_ANALYSIS_DS_COCOA
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "clang/AST/Type.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ObjCMethodDecl;
|
||||
|
||||
namespace ento {
|
||||
namespace cocoa {
|
||||
|
||||
enum NamingConvention { NoConvention, CreateRule, InitRule };
|
||||
|
||||
NamingConvention deriveNamingConvention(Selector S);
|
||||
NamingConvention deriveNamingConvention(Selector S, const ObjCMethodDecl *MD);
|
||||
|
||||
static inline bool followsFundamentalRule(Selector S) {
|
||||
return deriveNamingConvention(S) == CreateRule;
|
||||
static inline bool followsFundamentalRule(Selector S,
|
||||
const ObjCMethodDecl *MD) {
|
||||
return deriveNamingConvention(S, MD) == CreateRule;
|
||||
}
|
||||
|
||||
bool isRefType(QualType RetTy, llvm::StringRef Prefix,
|
||||
llvm::StringRef Name = llvm::StringRef());
|
||||
|
||||
bool isCFObjectRef(QualType T);
|
||||
|
||||
|
||||
bool isCocoaObjectRef(QualType T);
|
||||
|
||||
}}}
|
||||
}
|
||||
|
||||
namespace coreFoundation {
|
||||
bool isCFObjectRef(QualType T);
|
||||
|
||||
bool followsCreateRule(llvm::StringRef functionName);
|
||||
}
|
||||
|
||||
}} // end: "clang:ento"
|
||||
|
||||
#endif
|
||||
|
@ -400,6 +400,11 @@ def ObjCNSObject : InheritableAttr {
|
||||
let Spellings = ["NSObject"];
|
||||
}
|
||||
|
||||
def ObjCPreciseLifetime : Attr {
|
||||
let Spellings = ["objc_precise_lifetime"];
|
||||
let Subjects = [Var];
|
||||
}
|
||||
|
||||
def Overloadable : Attr {
|
||||
let Spellings = ["overloadable"];
|
||||
}
|
||||
@ -479,6 +484,10 @@ def Unavailable : InheritableAttr {
|
||||
let Args = [StringArgument<"Message">];
|
||||
}
|
||||
|
||||
def ArcWeakrefUnavailable : InheritableAttr {
|
||||
let Spellings = ["objc_arc_weak_reference_unavailable"];
|
||||
}
|
||||
|
||||
def Unused : InheritableAttr {
|
||||
let Spellings = ["unused"];
|
||||
}
|
||||
|
@ -604,6 +604,8 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
|
||||
// Microsoft builtins.
|
||||
BUILTIN(__assume, "vb", "n")
|
||||
BUILTIN(__noop, "v.", "n")
|
||||
BUILTIN(__debugbreak, "v", "n")
|
||||
|
||||
|
||||
// C99 library functions
|
||||
// C99 stdlib.h
|
||||
@ -727,6 +729,10 @@ LIBBUILTIN(cos, "dd", "fe", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(cosf, "ff", "fe", "math.h", ALL_LANGUAGES)
|
||||
|
||||
LIBBUILTIN(fma, "dddd", "fc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES)
|
||||
|
||||
// Blocks runtime Builtin math library functions
|
||||
LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
|
||||
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
|
||||
|
@ -50,7 +50,6 @@ enum ID {
|
||||
struct Info {
|
||||
const char *Name, *Type, *Attributes, *HeaderName;
|
||||
LanguageID builtin_lang;
|
||||
bool Suppressed;
|
||||
|
||||
bool operator==(const Info &RHS) const {
|
||||
return !strcmp(Name, RHS.Name) &&
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
// 3DNow!
|
||||
//
|
||||
BUILTIN(__builtin_ia32_femms, "v", "")
|
||||
BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc")
|
||||
BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc")
|
||||
BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc")
|
||||
@ -47,7 +48,7 @@ BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc")
|
||||
BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc")
|
||||
BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc")
|
||||
BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc")
|
||||
// 3DNow! Extensions.
|
||||
// 3DNow! Extensions (3dnowa).
|
||||
BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc")
|
||||
BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc")
|
||||
BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc")
|
||||
@ -57,15 +58,13 @@ BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc")
|
||||
|
||||
// MMX
|
||||
//
|
||||
// FIXME: All MMX instructions will be generated via builtins. Any MMX vector
|
||||
// All MMX instructions will be generated via builtins. Any MMX vector
|
||||
// types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
|
||||
// expanded by the back-end.
|
||||
BUILTIN(__builtin_ia32_emms, "v", "")
|
||||
BUILTIN(__builtin_ia32_femms, "v", "")
|
||||
BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "")
|
||||
@ -73,27 +72,17 @@ BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "")
|
||||
@ -113,7 +102,6 @@ BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "")
|
||||
BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "")
|
||||
BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "")
|
||||
@ -127,14 +115,53 @@ BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "")
|
||||
BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
|
||||
BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "")
|
||||
BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "")
|
||||
BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "")
|
||||
BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "")
|
||||
BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "")
|
||||
BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "")
|
||||
|
||||
// MMX2 (MMX+SSE) intrinsics
|
||||
BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
|
||||
BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
|
||||
BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
|
||||
BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "")
|
||||
BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "")
|
||||
|
||||
// MMX+SSE2
|
||||
BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
|
||||
BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
|
||||
BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "")
|
||||
BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "")
|
||||
|
||||
// MMX+SSSE3
|
||||
BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "")
|
||||
BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
|
||||
|
||||
// SSE intrinsics.
|
||||
BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "")
|
||||
BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "")
|
||||
@ -204,42 +231,24 @@ BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "")
|
||||
BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "")
|
||||
BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "")
|
||||
BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "")
|
||||
BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "")
|
||||
BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pmaddubsw128, "V16cV16cV16c", "")
|
||||
BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "")
|
||||
BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "")
|
||||
BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "")
|
||||
BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "")
|
||||
BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "")
|
||||
BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "")
|
||||
BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "")
|
||||
BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "")
|
||||
BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "")
|
||||
BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "")
|
||||
BUILTIN(__builtin_ia32_stmxcsr, "Ui", "")
|
||||
BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "")
|
||||
BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
|
||||
BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
|
||||
BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
|
||||
BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
|
||||
BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
|
||||
BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
|
||||
BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
|
||||
@ -265,11 +274,8 @@ BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "")
|
||||
BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "")
|
||||
BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "")
|
||||
BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "")
|
||||
BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "")
|
||||
|
109
include/clang/Basic/DelayedCleanupPool.h
Normal file
109
include/clang/Basic/DelayedCleanupPool.h
Normal file
@ -0,0 +1,109 @@
|
||||
//=== DelayedCleanupPool.h - Delayed Clean-up Pool Implementation *- C++ -*===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a facility to delay calling cleanup methods until specific
|
||||
// points.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H
|
||||
#define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief Gathers pairs of pointer-to-object/pointer-to-cleanup-function
|
||||
/// allowing the cleanup functions to get called (with the pointer as parameter)
|
||||
/// at specific points.
|
||||
///
|
||||
/// The use case is to simplify clean-up of certain resources that, while their
|
||||
/// lifetime is well-known and restricted, cleaning them up manually is easy to
|
||||
/// miss and cause a leak.
|
||||
///
|
||||
/// The same pointer can be added multiple times; its clean-up function will
|
||||
/// only be called once.
|
||||
class DelayedCleanupPool {
|
||||
public:
|
||||
typedef void (*CleanupFn)(void *ptr);
|
||||
|
||||
/// \brief Adds a pointer and its associated cleanup function to be called
|
||||
/// at a later point.
|
||||
///
|
||||
/// \returns false if the pointer is already added, true otherwise.
|
||||
bool delayCleanup(void *ptr, CleanupFn fn) {
|
||||
assert(ptr && "Expected valid pointer to object");
|
||||
assert(fn && "Expected valid pointer to function");
|
||||
|
||||
CleanupFn &mapFn = Ptrs[ptr];
|
||||
assert((!mapFn || mapFn == fn) &&
|
||||
"Adding a pointer with different cleanup function!");
|
||||
|
||||
if (!mapFn) {
|
||||
mapFn = fn;
|
||||
Cleanups.push_back(std::make_pair(ptr, fn));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool delayDelete(T *ptr) {
|
||||
return delayCleanup(ptr, cleanupWithDelete<T>);
|
||||
}
|
||||
|
||||
template <typename T, void (T::*Fn)()>
|
||||
bool delayMemberFunc(T *ptr) {
|
||||
return delayCleanup(ptr, cleanupWithMemberFunc<T, Fn>);
|
||||
}
|
||||
|
||||
void doCleanup() {
|
||||
for (llvm::SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator
|
||||
I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I)
|
||||
I->second(I->first);
|
||||
Cleanups.clear();
|
||||
Ptrs.clear();
|
||||
}
|
||||
|
||||
~DelayedCleanupPool() {
|
||||
doCleanup();
|
||||
}
|
||||
|
||||
private:
|
||||
llvm::DenseMap<void *, CleanupFn> Ptrs;
|
||||
llvm::SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups;
|
||||
|
||||
template <typename T>
|
||||
static void cleanupWithDelete(void *ptr) {
|
||||
delete static_cast<T *>(ptr);
|
||||
}
|
||||
|
||||
template <typename T, void (T::*Fn)()>
|
||||
static void cleanupWithMemberFunc(void *ptr) {
|
||||
(static_cast<T *>(ptr)->*Fn)();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief RAII object for triggering a cleanup of a DelayedCleanupPool.
|
||||
class DelayedCleanupPoint {
|
||||
DelayedCleanupPool &Pool;
|
||||
|
||||
public:
|
||||
DelayedCleanupPoint(DelayedCleanupPool &pool) : Pool(pool) { }
|
||||
|
||||
~DelayedCleanupPoint() {
|
||||
Pool.doCleanup();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -251,6 +251,14 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
bool ErrorOccurred;
|
||||
bool FatalErrorOccurred;
|
||||
|
||||
/// \brief Indicates that an unrecoverable error has occurred.
|
||||
bool UnrecoverableErrorOccurred;
|
||||
|
||||
/// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred
|
||||
/// during a parsing section, e.g. during parsing a function.
|
||||
bool TrapErrorOccurred;
|
||||
bool TrapUnrecoverableErrorOccurred;
|
||||
|
||||
/// LastDiagLevel - This is the level of the last diagnostic emitted. This is
|
||||
/// used to emit continuation diagnostics with the same level as the
|
||||
/// diagnostic that they follow.
|
||||
@ -269,13 +277,15 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
/// can use this information to avoid redundancy across arguments.
|
||||
///
|
||||
/// This is a hack to avoid a layering violation between libbasic and libsema.
|
||||
typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ModifierLen,
|
||||
const char *Argument, unsigned ArgumentLen,
|
||||
const ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie);
|
||||
typedef void (*ArgToStringFnTy)(
|
||||
ArgumentKind Kind, intptr_t Val,
|
||||
const char *Modifier, unsigned ModifierLen,
|
||||
const char *Argument, unsigned ArgumentLen,
|
||||
const ArgumentValue *PrevArgs,
|
||||
unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
void *Cookie,
|
||||
llvm::SmallVectorImpl<intptr_t> &QualTypeVals);
|
||||
void *ArgToStringCookie;
|
||||
ArgToStringFnTy ArgToStringFn;
|
||||
|
||||
@ -432,7 +442,12 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
|
||||
bool hasErrorOccurred() const { return ErrorOccurred; }
|
||||
bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
|
||||
|
||||
|
||||
/// \brief Determine whether any kind of unrecoverable error has occurred.
|
||||
bool hasUnrecoverableErrorOccurred() const {
|
||||
return FatalErrorOccurred || UnrecoverableErrorOccurred;
|
||||
}
|
||||
|
||||
unsigned getNumWarnings() const { return NumWarnings; }
|
||||
|
||||
void setNumWarnings(unsigned NumWarnings) {
|
||||
@ -452,9 +467,11 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
const char *Modifier, unsigned ModLen,
|
||||
const char *Argument, unsigned ArgLen,
|
||||
const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
|
||||
llvm::SmallVectorImpl<char> &Output) const {
|
||||
llvm::SmallVectorImpl<char> &Output,
|
||||
llvm::SmallVectorImpl<intptr_t> &QualTypeVals) const {
|
||||
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
|
||||
PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
|
||||
PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
|
||||
QualTypeVals);
|
||||
}
|
||||
|
||||
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
|
||||
@ -621,20 +638,28 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
|
||||
/// queried.
|
||||
class DiagnosticErrorTrap {
|
||||
Diagnostic &Diag;
|
||||
unsigned PrevErrors;
|
||||
|
||||
public:
|
||||
explicit DiagnosticErrorTrap(Diagnostic &Diag)
|
||||
: Diag(Diag), PrevErrors(Diag.NumErrors) {}
|
||||
: Diag(Diag) { reset(); }
|
||||
|
||||
/// \brief Determine whether any errors have occurred since this
|
||||
/// object instance was created.
|
||||
bool hasErrorOccurred() const {
|
||||
return Diag.NumErrors > PrevErrors;
|
||||
return Diag.TrapErrorOccurred;
|
||||
}
|
||||
|
||||
/// \brief Determine whether any unrecoverable errors have occurred since this
|
||||
/// object instance was created.
|
||||
bool hasUnrecoverableErrorOccurred() const {
|
||||
return Diag.TrapUnrecoverableErrorOccurred;
|
||||
}
|
||||
|
||||
// Set to initial state of "no errors occurred".
|
||||
void reset() { PrevErrors = Diag.NumErrors; }
|
||||
void reset() {
|
||||
Diag.TrapErrorOccurred = false;
|
||||
Diag.TrapUnrecoverableErrorOccurred = false;
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
26
include/clang/Basic/DiagnosticCategories.h
Normal file
26
include/clang/Basic/DiagnosticCategories.h
Normal file
@ -0,0 +1,26 @@
|
||||
//===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- C++ -*===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H
|
||||
#define LLVM_CLANG_BASIC_DIAGNOSTICCATEGORIES_H
|
||||
|
||||
namespace clang {
|
||||
namespace diag {
|
||||
enum {
|
||||
#define GET_CATEGORY_TABLE
|
||||
#define CATEGORY(X, ENUM) ENUM,
|
||||
#include "clang/Basic/DiagnosticGroups.inc"
|
||||
#undef CATEGORY
|
||||
#undef GET_CATEGORY_TABLE
|
||||
DiagCat_NUM_CATEGORIES
|
||||
};
|
||||
} // end namespace diag
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -32,6 +32,7 @@ def note_type_being_defined : Note<
|
||||
def note_matching : Note<"to match this '%0'">;
|
||||
|
||||
def note_using : Note<"using">;
|
||||
def note_possibility : Note<"one possibility">;
|
||||
def note_also_found : Note<"also found">;
|
||||
|
||||
// Parse && Lex
|
||||
|
@ -82,6 +82,12 @@ def err_drv_conflicting_deployment_targets : Error<
|
||||
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
|
||||
def err_drv_invalid_arch_for_deployment_target : Error<
|
||||
"invalid architecture '%0' for deployment target '%1'">;
|
||||
def err_drv_objc_gc_arr : Error<
|
||||
"cannot specify both '-fobjc-arc' and '%0'">;
|
||||
def err_arc_nonfragile_abi : Error<
|
||||
"-fobjc-arc is not supported with fragile abi">;
|
||||
def err_drv_mg_requires_m_or_mm : Error<
|
||||
"option '-MG' requires '-M' or '-MM'">;
|
||||
|
||||
def warn_c_kext : Warning<
|
||||
"ignoring -fapple-kext which is valid for c++ and objective-c++ only">;
|
||||
|
@ -137,6 +137,9 @@ def warn_pch_nonfragile_abi2 : Error<
|
||||
"PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
|
||||
"Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
|
||||
"Objective-C ABI is selected">;
|
||||
def warn_pch_auto_ref_count : Error<
|
||||
"PCH file was compiled %select{without|with} automated reference counting,"
|
||||
"which is currently %select{disabled|enabled}">;
|
||||
def warn_pch_apple_kext : Error<
|
||||
"PCH file was compiled %select{with|without}0 support for Apple's kernel "
|
||||
"extensions ABI but it is currently %select{disabled|enabled}1">;
|
||||
|
@ -62,6 +62,7 @@ def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
|
||||
def FourByteMultiChar : DiagGroup<"four-char-constants">;
|
||||
def GlobalConstructors : DiagGroup<"global-constructors">;
|
||||
def : DiagGroup<"idiomatic-parentheses">;
|
||||
def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
|
||||
def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
|
||||
def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
|
||||
def : DiagGroup<"import">;
|
||||
@ -115,6 +116,7 @@ def SignCompare : DiagGroup<"sign-compare">;
|
||||
def : DiagGroup<"stack-protector">;
|
||||
def : DiagGroup<"switch-default">;
|
||||
def : DiagGroup<"synth">;
|
||||
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
|
||||
def TautologicalCompare : DiagGroup<"tautological-compare">;
|
||||
def HeaderHygiene : DiagGroup<"header-hygiene">;
|
||||
|
||||
@ -168,6 +170,15 @@ def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
|
||||
def CustomAtomic : DiagGroup<"custom-atomic-properties">;
|
||||
def AtomicProperties : DiagGroup<"atomic-properties",
|
||||
[ImplicitAtomic, CustomAtomic]>;
|
||||
def AutomaticReferenceCountingABI : DiagGroup<"arc-abi">;
|
||||
def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
|
||||
def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
|
||||
def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
|
||||
def AutomaticReferenceCounting : DiagGroup<"arc",
|
||||
[AutomaticReferenceCountingABI,
|
||||
ARCUnsafeRetainedAssign,
|
||||
ARCRetainCycles,
|
||||
ARCNonPodMemAccess]>;
|
||||
def Selector : DiagGroup<"selector">;
|
||||
def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">;
|
||||
def Protocol : DiagGroup<"protocol">;
|
||||
@ -192,7 +203,8 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
|
||||
// in -Wparentheses because most users who use -Wparentheses explicitly
|
||||
// do not want these warnings.
|
||||
def Parentheses : DiagGroup<"parentheses",
|
||||
[LogicalOpParentheses]>;
|
||||
[LogicalOpParentheses,
|
||||
BitwiseOpParentheses]>;
|
||||
|
||||
// -Wconversion has its own warnings, but we split a few out for
|
||||
// legacy reasons:
|
||||
@ -217,12 +229,12 @@ def Unused : DiagGroup<"unused",
|
||||
|
||||
// Format settings.
|
||||
def FormatSecurity : DiagGroup<"format-security">;
|
||||
def FormatY2K : DiagGroup<"format-y2k">;
|
||||
def Format : DiagGroup<"format",
|
||||
[FormatExtraArgs, FormatZeroLength, NonNull,
|
||||
FormatSecurity]>,
|
||||
FormatSecurity, FormatY2K]>,
|
||||
DiagCategory<"Format String Issue">;
|
||||
def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
|
||||
def FormatY2K : DiagGroup<"format-y2k", [Format]>;
|
||||
def Format2 : DiagGroup<"format=2",
|
||||
[FormatNonLiteral, FormatSecurity, FormatY2K]>;
|
||||
|
||||
@ -248,6 +260,7 @@ def Most : DiagGroup<"most", [
|
||||
ReturnType,
|
||||
SelfAssignment,
|
||||
Switch,
|
||||
SizeofArrayArgument,
|
||||
Trigraphs,
|
||||
Uninitialized,
|
||||
UnknownPragmas,
|
||||
@ -283,3 +296,6 @@ def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
|
||||
|
||||
// A warning group for warnings about Microsoft extensions.
|
||||
def Microsoft : DiagGroup<"microsoft">;
|
||||
|
||||
def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
|
||||
|
||||
|
@ -227,6 +227,10 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
|
||||
/// suppressed.
|
||||
bool ProcessDiag(Diagnostic &Diag) const;
|
||||
|
||||
/// \brief Whether the diagnostic may leave the AST in a state where some
|
||||
/// invariants can break.
|
||||
bool isUnrecoverable(unsigned DiagID) const;
|
||||
|
||||
friend class Diagnostic;
|
||||
};
|
||||
|
||||
|
@ -178,7 +178,7 @@ def ext_empty_fnmacro_arg : Extension<
|
||||
|
||||
def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
|
||||
def err_pp_hash_error : Error<"#error%0">;
|
||||
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
|
||||
def warn_pp_file_not_found : Warning<"'%0' file not found">, DefaultFatal;
|
||||
def err_pp_error_opening_file : Error<
|
||||
"error opening file '%0': %1">, DefaultFatal;
|
||||
def err_pp_empty_filename : Error<"empty filename">;
|
||||
|
@ -263,6 +263,11 @@ def warn_objc_protocol_qualifier_missing_id : Warning<
|
||||
def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
|
||||
def err_illegal_super_cast : Error<
|
||||
"cannot cast 'super' (it isn't an expression)">;
|
||||
|
||||
let CategoryName = "Automatic Reference Counting Issue" in {
|
||||
def err_arc_bridge_retain : Error<
|
||||
"unknown cast annotation __bridge_retain; did you mean __bridge_retained?">;
|
||||
}
|
||||
|
||||
def err_objc_illegal_visibility_spec : Error<
|
||||
"illegal visibility specification">;
|
||||
|
@ -48,6 +48,8 @@ def err_vla_decl_has_static_storage : Error<
|
||||
"variable length array declaration can not have 'static' storage duration">;
|
||||
def err_vla_decl_has_extern_linkage : Error<
|
||||
"variable length array declaration can not have 'extern' linkage">;
|
||||
def ext_vla_folded_to_constant : Extension<
|
||||
"variable length array folded to constant array as an extension">;
|
||||
|
||||
// C99 variably modified types
|
||||
def err_variably_modified_template_arg : Error<
|
||||
@ -267,6 +269,15 @@ def warn_dyn_class_memaccess : Warning<
|
||||
InGroup<DiagGroup<"dynamic-class-memaccess">>;
|
||||
def note_bad_memaccess_silence : Note<
|
||||
"explicitly cast the pointer to silence this warning">;
|
||||
def warn_sizeof_pointer_expr_memaccess : Warning<
|
||||
"argument to 'sizeof' in %0 call is the same expression as the "
|
||||
"%select{destination|source}1; did you mean to "
|
||||
"%select{dereference it|remove the addressof|provide an explicit length}2?">,
|
||||
InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
|
||||
def warn_sizeof_pointer_type_memaccess : Warning<
|
||||
"argument to 'sizeof' in %0 call is the same pointer type %1 as the "
|
||||
"%select{destination|source}2; expected %3 or an explicit length">,
|
||||
InGroup<DiagGroup<"sizeof-pointer-memaccess">>;
|
||||
|
||||
/// main()
|
||||
// static/inline main() are not errors in C, just in C++.
|
||||
@ -319,6 +330,8 @@ def err_duplicate_class_def : Error<
|
||||
"duplicate interface definition for class %0">;
|
||||
def err_undef_superclass : Error<
|
||||
"cannot find interface declaration for %0, superclass of %1">;
|
||||
def err_forward_superclass : Error<
|
||||
"attempting to use the forward class %0 as superclass of %1">;
|
||||
def err_no_nsconstant_string_class : Error<
|
||||
"cannot find interface declaration for %0">;
|
||||
def err_recursive_superclass : Error<
|
||||
@ -344,6 +357,8 @@ def err_class_extension_after_impl : Error<
|
||||
"cannot declare class extension for %0 after class implementation">;
|
||||
def note_implementation_declared : Note<
|
||||
"class implementation is declared here">;
|
||||
def note_class_declared : Note<
|
||||
"class is declared here">;
|
||||
def warn_dup_category_def : Warning<
|
||||
"duplicate definition of category %1 on interface %0">;
|
||||
def err_conflicting_super_class : Error<"conflicting super class name %0">;
|
||||
@ -425,6 +440,15 @@ def warn_objc_property_copy_missing_on_block : Warning<
|
||||
def warn_atomic_property_rule : Warning<
|
||||
"writable atomic property %0 cannot pair a synthesized setter/getter "
|
||||
"with a user defined setter/getter">;
|
||||
def warn_ownin_getter_rule : Warning<
|
||||
"property's synthesized getter follows Cocoa naming"
|
||||
" convention for returning 'owned' objects">;
|
||||
def warn_property_getter_owning_mismatch : Warning<
|
||||
"property declared as returning non-retained objects"
|
||||
"; getter returning retained objects">;
|
||||
def err_ownin_getter_rule : Error<
|
||||
"property's synthesized getter follows Cocoa naming"
|
||||
" convention for returning 'owned' objects">;
|
||||
def warn_default_atomic_custom_getter_setter : Warning<
|
||||
"atomic by default property %0 has a user defined %select{getter|setter}1 "
|
||||
"(property should be marked 'atomic' if this is intended)">,
|
||||
@ -460,6 +484,12 @@ def error_bad_property_context : Error<
|
||||
def error_missing_property_ivar_decl : Error<
|
||||
"synthesized property %0 must either be named the same as a compatible"
|
||||
" ivar or must explicitly name an ivar">;
|
||||
def error_synthesize_weak_non_arc_or_gc : Error<
|
||||
"@synthesize of 'weak' property is only allowed in ARC or GC mode">;
|
||||
def err_arc_perform_selector_retains : Error<
|
||||
"performSelector names a selector which retains the object">;
|
||||
def warn_arc_perform_selector_leaks : Warning<
|
||||
"performSelector may cause a leak because its selector is unknown">;
|
||||
|
||||
def error_synthesized_ivar_yet_not_supported : Error<
|
||||
"instance variable synthesis not yet supported"
|
||||
@ -472,7 +502,7 @@ def error_ivar_in_superclass_use : Error<
|
||||
def error_weak_property : Error<
|
||||
"existing ivar %1 for __weak property %0 must be __weak">;
|
||||
def error_strong_property : Error<
|
||||
"property %0 must be declared __weak to match existing ivar %1 with __weak attribute">;
|
||||
"existing ivar %1 for strong property %0 may not be __weak">;
|
||||
def error_dynamic_property_ivar_decl : Error<
|
||||
"dynamic property can not have ivar specification">;
|
||||
def error_duplicate_ivar_use : Error<
|
||||
@ -729,8 +759,6 @@ def err_not_integral_type_bitfield : Error<
|
||||
"bit-field %0 has non-integral type %1">;
|
||||
def err_not_integral_type_anon_bitfield : Error<
|
||||
"anonymous bit-field has non-integral type %0">;
|
||||
def err_member_initialization : Error<
|
||||
"fields can only be initialized in constructors">;
|
||||
def err_member_function_initialization : Error<
|
||||
"initializer on function does not look like a pure-specifier">;
|
||||
def err_non_virtual_pure : Error<
|
||||
@ -1135,6 +1163,8 @@ def err_format_attribute_implicit_this_format_string : Error<
|
||||
"format attribute cannot specify the implicit this argument as the format "
|
||||
"string">;
|
||||
def warn_unknown_method_family : Warning<"unrecognized method family">;
|
||||
def err_init_method_bad_return_type : Error<
|
||||
"init methods must return an object pointer type, not %0">;
|
||||
def err_attribute_invalid_size : Error<
|
||||
"vector size not an integral multiple of component size">;
|
||||
def err_attribute_zero_size : Error<"zero vector size">;
|
||||
@ -1160,6 +1190,10 @@ def err_as_qualified_auto_decl : Error<
|
||||
"automatic variable qualified with an address space">;
|
||||
def err_arg_with_address_space : Error<
|
||||
"parameter may not be qualified with an address space">;
|
||||
def err_attr_objc_ownership_bad_type : Error<
|
||||
"the type %0 cannot be retained">;
|
||||
def err_attr_objc_ownership_redundant : Error<
|
||||
"the type %0 already has retainment attributes set on it">;
|
||||
def err_attribute_not_string : Error<
|
||||
"argument to %0 attribute was not a string literal">;
|
||||
def err_attribute_section_invalid_for_target : Error<
|
||||
@ -1215,6 +1249,8 @@ def warn_function_attribute_wrong_type : Warning<
|
||||
"'%0' only applies to function types; type here is %1">;
|
||||
def warn_pointer_attribute_wrong_type : Warning<
|
||||
"'%0' only applies to pointer types; type here is %1">;
|
||||
def warn_objc_object_attribute_wrong_type : Warning<
|
||||
"'%0' only applies to objective-c object or block pointer types; type here is %1">;
|
||||
def warn_gnu_inline_attribute_requires_inline : Warning<
|
||||
"'gnu_inline' attribute requires function to be marked 'inline',"
|
||||
" attribute ignored">;
|
||||
@ -1232,6 +1268,13 @@ def err_cconv_varargs : Error<
|
||||
def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
|
||||
"attribute was previously declared "
|
||||
"%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
|
||||
def err_objc_precise_lifetime_bad_type : Error<
|
||||
"objc_precise_lifetime only applies to retainable types; type here is %0">;
|
||||
def warn_objc_precise_lifetime_meaningless : Error<
|
||||
"objc_precise_lifetime is not meaningful for "
|
||||
"%select{__unsafe_unretained|__autoreleasing}0 objects">;
|
||||
def warn_label_attribute_not_unused : Warning<
|
||||
"The only valid attribute for labels is 'unused'">;
|
||||
def err_invalid_pcs : Error<"Invalid PCS type">;
|
||||
|
||||
// Availability attribute
|
||||
@ -1505,7 +1548,13 @@ def note_ovl_candidate_arity : Note<"candidate "
|
||||
|
||||
def note_ovl_candidate_deleted : Note<
|
||||
"candidate %select{function|function|constructor|"
|
||||
"function |function |constructor ||||constructor (inherited)}0%1 "
|
||||
"function |function |constructor |"
|
||||
"constructor (the implicit default constructor)|"
|
||||
"constructor (the implicit copy constructor)|"
|
||||
"constructor (the implicit move constructor)|"
|
||||
"function (the implicit copy assignment operator)|"
|
||||
"function (the implicit move assignment operator)|"
|
||||
"constructor (inherited)}0%1 "
|
||||
"has been explicitly %select{made unavailable|deleted}2">;
|
||||
|
||||
// Giving the index of the bad argument really clutters this message, and
|
||||
@ -1565,7 +1614,18 @@ def note_ovl_candidate_bad_gc : Note<"candidate "
|
||||
"function (the implicit move assignment operator)|"
|
||||
"constructor (inherited)}0%1 not viable: "
|
||||
"%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 "
|
||||
"lifetime, but parameter has %select{no|__weak|__strong}4 lifetime">;
|
||||
"ownership, but parameter has %select{no|__weak|__strong}4 ownership">;
|
||||
def note_ovl_candidate_bad_ownership : Note<"candidate "
|
||||
"%select{function|function|constructor|"
|
||||
"function |function |constructor |"
|
||||
"constructor (the implicit default constructor)|"
|
||||
"constructor (the implicit copy constructor)|"
|
||||
"function (the implicit copy assignment operator)|"
|
||||
"constructor (inherited)}0%1 not viable: "
|
||||
"%select{%ordinal6|'this'}5 argument (%2) has "
|
||||
"%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership,"
|
||||
" but parameter has %select{no|__unsafe_unretained|__strong|__weak|"
|
||||
"__autoreleasing}4 ownership">;
|
||||
def note_ovl_candidate_bad_cvr_this : Note<"candidate "
|
||||
"%select{|function|||function||||"
|
||||
"function (the implicit copy assignment operator)|}0 not viable: "
|
||||
@ -1871,8 +1931,11 @@ def err_not_class_template_specialization : Error<
|
||||
"parameter}0">;
|
||||
def err_function_specialization_in_class : Error<
|
||||
"cannot specialize a function %0 within class scope">;
|
||||
def err_explicit_specialization_storage_class : Error<
|
||||
def ext_explicit_specialization_storage_class : ExtWarn<
|
||||
"explicit specialization cannot have a storage class">;
|
||||
def err_explicit_specialization_inconsistent_storage_class : Error<
|
||||
"explicit specialization has extraneous, inconsistent storage class "
|
||||
"'%select{none|extern|static|__private_extern__|auto|register}0'">;
|
||||
|
||||
// C++ class template specializations and out-of-line definitions
|
||||
def err_template_spec_needs_header : Error<
|
||||
@ -2180,7 +2243,7 @@ def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
|
||||
def note_dependent_var_use : Note<"must qualify identifier to find this "
|
||||
"declaration in dependent base class">;
|
||||
def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
|
||||
"visible in the template definition nor found by argument dependent lookup">;
|
||||
"visible in the template definition nor found by argument-dependent lookup">;
|
||||
def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the "
|
||||
"call site%select{| or in %2| or in an associated namespace of one of its arguments}1">;
|
||||
def err_undeclared_use : Error<"use of undeclared %0">;
|
||||
@ -2199,8 +2262,8 @@ def err_unavailable_message : Error<"%0 is unavailable: %1">;
|
||||
def warn_unavailable_fwdclass_message : Warning<
|
||||
"%0 maybe unavailable because receiver type is unknown">;
|
||||
def note_unavailable_here : Note<
|
||||
"function has been explicitly marked "
|
||||
"%select{unavailable|deleted|deprecated}0 here">;
|
||||
"%select{declaration|function}0 has been explicitly marked "
|
||||
"%select{unavailable|deleted|deprecated}1 here">;
|
||||
def warn_not_enough_argument : Warning<
|
||||
"not enough variable arguments in %0 declaration to fit a sentinel">;
|
||||
def warn_missing_sentinel : Warning <
|
||||
@ -2237,6 +2300,8 @@ def err_inline_declaration_block_scope : Error<
|
||||
"inline declaration of %0 not allowed in block scope">;
|
||||
def err_static_non_static : Error<
|
||||
"static declaration of %0 follows non-static declaration">;
|
||||
def warn_weak_import : Warning <
|
||||
"an already-declared variable is made a weak_import declaration %0">;
|
||||
def warn_static_non_static : ExtWarn<
|
||||
"static declaration of %0 follows non-static declaration">;
|
||||
def err_non_static_static : Error<
|
||||
@ -2418,6 +2483,8 @@ def err_indirect_goto_in_protected_scope : Error<
|
||||
def note_indirect_goto_target : Note<"possible target of indirect goto">;
|
||||
def note_protected_by_variable_init : Note<
|
||||
"jump bypasses variable initialization">;
|
||||
def note_protected_by_variable_nontriv_destructor : Note<
|
||||
"jump bypasses variable with a non-trivial destructor">;
|
||||
def note_protected_by_cleanup : Note<
|
||||
"jump bypasses initialization of variable with __attribute__((cleanup))">;
|
||||
def note_protected_by_vla_typedef : Note<
|
||||
@ -2434,12 +2501,22 @@ def note_protected_by_objc_finally : Note<
|
||||
"jump bypasses initialization of @finally block">;
|
||||
def note_protected_by_objc_synchronized : Note<
|
||||
"jump bypasses initialization of @synchronized block">;
|
||||
def note_protected_by_objc_autoreleasepool : Note<
|
||||
"jump bypasses auto release push of @autoreleasepool block">;
|
||||
def note_protected_by_cxx_try : Note<
|
||||
"jump bypasses initialization of try block">;
|
||||
def note_protected_by_cxx_catch : Note<
|
||||
"jump bypasses initialization of catch block">;
|
||||
def note_protected_by___block : Note<
|
||||
"jump bypasses setup of __block variable">;
|
||||
def note_protected_by_objc_ownership : Note<
|
||||
"jump bypasses initialization of retaining variable">;
|
||||
def note_enters_block_captures_cxx_obj : Note<
|
||||
"jump enters lifetime of block which captures a destructible c++ object">;
|
||||
def note_enters_block_captures_strong : Note<
|
||||
"jump enters lifetime of block which strongly captures a variable">;
|
||||
def note_enters_block_captures_weak : Note<
|
||||
"jump enters lifetime of block which weakly captures a variable">;
|
||||
|
||||
def note_exits_cleanup : Note<
|
||||
"jump exits scope of variable with __attribute__((cleanup))">;
|
||||
@ -2459,6 +2536,16 @@ def note_exits_cxx_try : Note<
|
||||
"jump exits try block">;
|
||||
def note_exits_cxx_catch : Note<
|
||||
"jump exits catch block">;
|
||||
def note_exits_objc_autoreleasepool : Note<
|
||||
"jump exits autoreleasepool block">;
|
||||
def note_exits_objc_ownership : Note<
|
||||
"jump exits scope of retaining variable">;
|
||||
def note_exits_block_captures_cxx_obj : Note<
|
||||
"jump exits lifetime of block which captures a destructible c++ object">;
|
||||
def note_exits_block_captures_strong : Note<
|
||||
"jump exits lifetime of block which strongly captures a variable">;
|
||||
def note_exits_block_captures_weak : Note<
|
||||
"jump exits lifetime of block which weakly captures a variable">;
|
||||
|
||||
def err_func_returning_array_function : Error<
|
||||
"function cannot return %select{array|function}0 type %1">;
|
||||
@ -2490,6 +2577,152 @@ def ext_flexible_array_empty_aggregate_gnu : Extension<
|
||||
def ext_flexible_array_union_gnu : Extension<
|
||||
"flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
|
||||
|
||||
let CategoryName = "Automatic Reference Counting Issue" in {
|
||||
|
||||
// ARC-mode diagnostics.
|
||||
def err_arc_weak_no_runtime : Error<
|
||||
"the current deployment target does not support automated __weak references">;
|
||||
def err_arc_unsupported_weak_class : Error<
|
||||
"class is incompatible with __weak references">;
|
||||
def err_arc_weak_unavailable_assign : Error<
|
||||
"assignment of a weak-unavailable object to a __weak object">;
|
||||
def err_arc_convesion_of_weak_unavailable : Error<
|
||||
"%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to"
|
||||
" a __weak object of type %2">;
|
||||
def err_arc_illegal_explicit_message : Error<
|
||||
"ARC forbids explicit message send of %0">;
|
||||
def err_arc_unused_init_message : Error<
|
||||
"the result of a delegate init call must be immediately returned "
|
||||
"or assigned to 'self'">;
|
||||
def err_arc_mismatched_cast : Error<
|
||||
"%select{implicit conversion|cast}0 of "
|
||||
"%select{%2|a non-Objective-C pointer type %2|a block pointer|"
|
||||
"an Objective-C pointer|an indirect pointer to an Objective-C pointer}1"
|
||||
" to %3 is disallowed with ARC">;
|
||||
def err_arc_objc_object_in_struct : Error<
|
||||
"ARC forbids Objective-C objects in structs or unions">;
|
||||
def err_arc_objc_property_default_assign_on_object : Error<
|
||||
"ARC forbids synthesizing a property of an Objective-C object "
|
||||
"with unspecified storage attribute">;
|
||||
def err_arc_illegal_selector : Error<
|
||||
"ARC forbids use of %0 in a @selector">;
|
||||
def err_arc_illegal_method_def : Error<
|
||||
"ARC forbids implementation of %0">;
|
||||
def err_arc_lost_method_convention : Error<
|
||||
"method was declared as %select{an 'alloc'|a 'copy'|an 'init'|a 'new'}0 "
|
||||
"method, but its implementation doesn't match because %select{"
|
||||
"its result type is not an object pointer|"
|
||||
"its result type is unrelated to its receiver type}1">;
|
||||
def note_arc_lost_method_convention : Note<"declaration in interface">;
|
||||
def err_arc_gained_method_convention : Error<
|
||||
"method implementation does not match its declaration">;
|
||||
def note_arc_gained_method_convention : Note<
|
||||
"declaration in interface is not in the '%select{alloc|copy|init|new}0' "
|
||||
"family because %select{its result type is not an object pointer|"
|
||||
"its result type is unrelated to its receiver type}1">;
|
||||
def err_typecheck_arr_assign_self : Error<
|
||||
"cannot assign to 'self' outside of a method in the init family">;
|
||||
def err_typecheck_arr_assign_enumeration : Error<
|
||||
"fast enumeration variables can't be modified in ARC by default; "
|
||||
"declare the variable __strong to allow this">;
|
||||
def warn_arc_non_pod_class_with_object_member : Warning<
|
||||
"%0 cannot be shared between ARC and non-ARC "
|
||||
"code; add a copy constructor, a copy assignment operator, and a destructor "
|
||||
"to make it ABI-compatible">, InGroup<AutomaticReferenceCountingABI>,
|
||||
DefaultIgnore;
|
||||
def warn_arc_retained_assign : Warning<
|
||||
"assigning retained object to %select{weak|unsafe_unretained}0 variable"
|
||||
"; object will be released after assignment">,
|
||||
InGroup<ARCUnsafeRetainedAssign>;
|
||||
def warn_arc_retained_property_assign : Warning<
|
||||
"assigning retained object to unsafe property"
|
||||
"; object will be released after assignment">,
|
||||
InGroup<ARCUnsafeRetainedAssign>;
|
||||
def warn_arc_trivial_member_function_with_object_member : Warning<
|
||||
"%0 cannot be shared between ARC and non-ARC "
|
||||
"code; add a non-trivial %select{copy constructor|copy assignment operator|"
|
||||
"destructor}1 to make it ABI-compatible">,
|
||||
InGroup<AutomaticReferenceCountingABI>, DefaultIgnore;
|
||||
def err_arc_new_array_without_ownership : Error<
|
||||
"'new' cannot allocate an array of %0 with no explicit ownership">;
|
||||
def warn_err_new_delete_object_array : Warning<
|
||||
"%select{allocating|destroying}0 an array of %1; this array must not "
|
||||
"%select{be deleted in|have been allocated from}0 non-ARC code">,
|
||||
InGroup<AutomaticReferenceCountingABI>, DefaultIgnore;
|
||||
def err_arc_autoreleasing_var : Error<
|
||||
"%select{__block variables|global variables|fields|ivars}0 cannot have "
|
||||
"__autoreleasing ownership">;
|
||||
def err_arc_thread_ownership : Error<
|
||||
"thread-local variable has non-trivial ownership: type is %0">;
|
||||
def err_arc_indirect_no_ownership : Error<
|
||||
"%select{pointer|reference}1 to non-const type %0 with no explicit ownership">,
|
||||
InGroup<AutomaticReferenceCounting>;
|
||||
def err_arc_array_param_no_ownership : Error<
|
||||
"must explicitly describe intended ownership of an object array parameter">;
|
||||
def err_arc_pseudo_dtor_inconstant_quals : Error<
|
||||
"pseudo-destructor destroys object of type %0 with inconsistently-qualified "
|
||||
"type %1">;
|
||||
def err_arc_init_method_unrelated_result_type : Error<
|
||||
"init methods must return a type related to the receiver type">;
|
||||
def err_arc_nonlocal_writeback : Error<
|
||||
"passing address of %select{non-local|non-scalar}0 object to "
|
||||
"__autoreleasing parameter for write-back">;
|
||||
def err_arc_method_not_found : Error<
|
||||
"no known %select{instance|class}1 method for selector %0">;
|
||||
def err_arc_receiver_forward_class : Error<
|
||||
"receiver %0 for class message is a forward declaration">;
|
||||
def err_arc_may_not_respond : Error<
|
||||
"receiver type %0 for instance message does not declare a method with "
|
||||
"selector %1">;
|
||||
def err_arc_receiver_forward_instance : Error<
|
||||
"receiver type %0 for instance message is a forward declaration">;
|
||||
def err_arc_multiple_method_decl : Error<
|
||||
"multiple methods named %0 found with mismatched result, "
|
||||
"parameter type or attributes">;
|
||||
def warn_arc_retain_cycle : Warning<
|
||||
"capturing %0 strongly in this block is likely to lead to a retain cycle">,
|
||||
InGroup<ARCRetainCycles>;
|
||||
def note_arc_retain_cycle_owner : Note<
|
||||
"block will be retained by %select{the captured object|an object strongly "
|
||||
"retained by the captured object}0">;
|
||||
def note_nontrivial_objc_ownership : Note<
|
||||
"because type %0 has %select{no|no|__strong|__weak|__autoreleasing}1 "
|
||||
"ownership">;
|
||||
def warn_arc_object_memaccess : Warning<
|
||||
"%select{destination for|source of}0 this %1 call is a pointer to "
|
||||
"ownership-qualified type %2">, InGroup<ARCNonPodMemAccess>;
|
||||
|
||||
def err_arc_strong_property_ownership : Error<
|
||||
"existing ivar %1 for strong property %0 may not be "
|
||||
"%select{|__unsafe_unretained||__weak}2">;
|
||||
def err_arc_assign_property_ownership : Error<
|
||||
"existing ivar %1 for unsafe_unretained property %0 must be __unsafe_unretained">;
|
||||
def err_arc_inconsistent_property_ownership : Error<
|
||||
"%select{strong|weak|unsafe_unretained}1 property %0 may not also be "
|
||||
"declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">;
|
||||
def err_arc_atomic_ownership : Error<
|
||||
"cannot perform atomic operation on a pointer to type %0: type has "
|
||||
"non-trivial ownership">;
|
||||
|
||||
def err_arc_bridge_cast_incompatible : Error<
|
||||
"incompatible types casting %0 to %1 with a %select{__bridge|"
|
||||
"__bridge_transfer|__bridge_retained}2 cast">;
|
||||
def err_arc_bridge_cast_wrong_kind : Error<
|
||||
"cast of %select{Objective-C|block|C}0 pointer type %1 to "
|
||||
"%select{Objective-C|block|C}2 pointer type %3 cannot use %select{__bridge|"
|
||||
"__bridge_transfer|__bridge_retained}4">;
|
||||
def err_arc_cast_requires_bridge : Error<
|
||||
"cast of %select{Objective-C|block|C}0 pointer type %1 to "
|
||||
"%select{Objective-C|block|C}2 pointer type %3 requires a bridged cast">;
|
||||
def note_arc_bridge : Note<
|
||||
"use __bridge to convert directly (no change in ownership)">;
|
||||
def note_arc_bridge_transfer : Note<
|
||||
"use __bridge_transfer to transfer ownership of a +1 %0 into ARC">;
|
||||
def note_arc_bridge_retained : Note<
|
||||
"use __bridge_retained to make an ARC object available as a +1 %0">;
|
||||
|
||||
} // ARC category name
|
||||
|
||||
def err_flexible_array_init_needs_braces : Error<
|
||||
"flexible array requires brace-enclosed initializer">;
|
||||
def err_illegal_decl_array_of_functions : Error<
|
||||
@ -2563,11 +2796,11 @@ def warn_remainder_by_zero : Warning<"remainder by zero is undefined">;
|
||||
def warn_shift_negative : Warning<"shift count is negative">;
|
||||
def warn_shift_gt_typewidth : Warning<"shift count >= width of type">;
|
||||
def warn_shift_result_gt_typewidth : Warning<
|
||||
"shift result (%0) requires %1 bits to represent, but %2 only has %3 bits">,
|
||||
InGroup<DiagGroup<"shift-overflow">>;
|
||||
def warn_shift_result_overrides_sign_bit : Warning<
|
||||
"shift result (%0) overrides the sign bit of the shift expression's type "
|
||||
"(%1) and becomes negative">,
|
||||
"signed shift result (%0) requires %1 bits to represent, but %2 only has "
|
||||
"%3 bits">, InGroup<DiagGroup<"shift-overflow">>;
|
||||
def warn_shift_result_sets_sign_bit : Warning<
|
||||
"signed shift result (%0) sets the sign bit of the shift expression's "
|
||||
"type (%1) and becomes negative">,
|
||||
InGroup<DiagGroup<"shift-sign-overflow">>, DefaultIgnore;
|
||||
|
||||
def warn_precedence_bitwise_rel : Warning<
|
||||
@ -2579,17 +2812,22 @@ def note_precedence_bitwise_silence : Note<
|
||||
"place parentheses around the %0 expression to silence this warning">;
|
||||
|
||||
def warn_precedence_conditional : Warning<
|
||||
"?: has lower precedence than %0; %0 will be evaluated first">,
|
||||
"operator '?:' has lower precedence than '%0'; '%0' will be evaluated first">,
|
||||
InGroup<Parentheses>;
|
||||
def note_precedence_conditional_first : Note<
|
||||
"place parentheses around the ?: expression to evaluate it first">;
|
||||
"place parentheses around the '?:' expression to evaluate it first">;
|
||||
def note_precedence_conditional_silence : Note<
|
||||
"place parentheses around the %0 expression to silence this warning">;
|
||||
"place parentheses around the '%0' expression to silence this warning">;
|
||||
|
||||
def warn_logical_instead_of_bitwise : Warning<
|
||||
"use of logical %0 with constant operand; switch to bitwise %1 or "
|
||||
"remove constant">, InGroup<DiagGroup<"constant-logical-operand">>;
|
||||
|
||||
def warn_bitwise_and_in_bitwise_or : Warning<
|
||||
"'&' within '|'">, InGroup<BitwiseOpParentheses>;
|
||||
def note_bitwise_and_in_bitwise_or_silence : Note<
|
||||
"place parentheses around the '&' expression to silence this warning">;
|
||||
|
||||
def warn_logical_and_in_logical_or : Warning<
|
||||
"'&&' within '||'">, InGroup<LogicalOpParentheses>;
|
||||
def note_logical_and_in_logical_or_silence : Note<
|
||||
@ -2599,6 +2837,10 @@ def warn_self_assignment : Warning<
|
||||
"explicitly assigning a variable of type %0 to itself">,
|
||||
InGroup<SelfAssignment>, DefaultIgnore;
|
||||
|
||||
def warn_sizeof_array_param : Warning<
|
||||
"sizeof on array function parameter will return size of %0 instead of %1">,
|
||||
InGroup<SizeofArrayArgument>;
|
||||
|
||||
def err_sizeof_nonfragile_interface : Error<
|
||||
"invalid application of '%select{alignof|sizeof}1' to interface %0 in "
|
||||
"non-fragile ABI">;
|
||||
@ -2623,10 +2865,15 @@ def err_subscript_function_type : Error<
|
||||
"subscript of pointer to function type %0">;
|
||||
def err_subscript_incomplete_type : Error<
|
||||
"subscript of pointer to incomplete type %0">;
|
||||
def ext_gnu_subscript_void_type : Extension<
|
||||
"subscript of a pointer to void is a GNU extension">, InGroup<PointerArith>;
|
||||
def err_typecheck_member_reference_struct_union : Error<
|
||||
"member reference base type %0 is not a structure or union">;
|
||||
def err_typecheck_member_reference_ivar : Error<
|
||||
"%0 does not have a member named %1">;
|
||||
def error_arc_weak_ivar_access : Error<
|
||||
"dereferencing a __weak pointer is not allowed due to possible "
|
||||
"null value caused by race condition, assign it to strong variable first">;
|
||||
def err_typecheck_member_reference_arrow : Error<
|
||||
"member reference type %0 is not a pointer">;
|
||||
def err_typecheck_member_reference_suggestion : Error<
|
||||
@ -2658,7 +2905,7 @@ def err_member_def_undefined_record : Error<
|
||||
def err_member_def_does_not_match : Error<
|
||||
"out-of-line definition of %0 does not match any declaration in %1">;
|
||||
def err_member_def_does_not_match_ret_type : Error<
|
||||
"out-of-line definition of %q0 differ from the declaration in the return type">;
|
||||
"out-of-line definition of %q0 differs from the declaration in the return type">;
|
||||
def err_nonstatic_member_out_of_line : Error<
|
||||
"non-static data member defined out-of-line">;
|
||||
def err_nonstatic_flexible_variable : Error<
|
||||
@ -2682,11 +2929,12 @@ def err_ivar_reference_type : Error<
|
||||
def err_typecheck_illegal_increment_decrement : Error<
|
||||
"cannot %select{decrement|increment}1 value of type %0">;
|
||||
def err_typecheck_arithmetic_incomplete_type : Error<
|
||||
"arithmetic on pointer to incomplete type %0">;
|
||||
"arithmetic on a pointer to an incomplete type %0">;
|
||||
def err_typecheck_pointer_arith_function_type : Error<
|
||||
"arithmetic on pointer to function type %0">;
|
||||
"arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 "
|
||||
"function type%select{|s}2 %1%select{| and %3}2">;
|
||||
def err_typecheck_pointer_arith_void_type : Error<
|
||||
"arithmetic on pointer to void type">;
|
||||
"arithmetic on%select{ a|}0 pointer%select{|s}0 to void">;
|
||||
def err_typecheck_decl_incomplete_type : Error<
|
||||
"variable has incomplete type %0">;
|
||||
def ext_typecheck_decl_incomplete_type : ExtWarn<
|
||||
@ -2803,6 +3051,9 @@ def warn_runsigned_always_true_comparison : Warning<
|
||||
def warn_comparison_of_mixed_enum_types : Warning<
|
||||
"comparison of two values with different enumeration types (%0 and %1)">,
|
||||
InGroup<DiagGroup<"enum-compare">>;
|
||||
def warn_null_in_arithmetic_operation : Warning<
|
||||
"use of NULL in arithmetic operation">,
|
||||
InGroup<DiagGroup<"null-arithmetic">>;
|
||||
|
||||
def err_invalid_this_use : Error<
|
||||
"invalid use of 'this' outside of a nonstatic member function">;
|
||||
@ -2871,9 +3122,11 @@ def note_forward_class : Note<
|
||||
def err_duplicate_property : Error<
|
||||
"property has a previous declaration">;
|
||||
def ext_gnu_void_ptr : Extension<
|
||||
"use of GNU void* extension">, InGroup<PointerArith>;
|
||||
"arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension">,
|
||||
InGroup<PointerArith>;
|
||||
def ext_gnu_ptr_func_arith : Extension<
|
||||
"arithmetic on pointer to function type %0 is a GNU extension">,
|
||||
"arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function "
|
||||
"type%select{|s}2 %1%select{| and %3}2 is a GNU extension">,
|
||||
InGroup<PointerArith>;
|
||||
def error_readonly_property_assignment : Error<
|
||||
"assigning to property with 'readonly' attribute not allowed">;
|
||||
@ -2942,9 +3195,9 @@ def err_qualified_objc_catch_parm : Error<
|
||||
"@catch parameter declarator cannot be qualified">;
|
||||
def err_objc_pointer_cxx_catch_gnu : Error<
|
||||
"can't catch Objective C exceptions in C++ in the GNU runtime">;
|
||||
def err_objc_pointer_cxx_catch_fragile : Error<
|
||||
"can't catch Objective C exceptions in C++ in the non-unified "
|
||||
"exception model">;
|
||||
def warn_objc_pointer_cxx_catch_fragile : Warning<
|
||||
"can not catch an exception thrown with @throw in C++ in the non-unified "
|
||||
"exception model">, InGroup<ObjCNonUnifiedException>;
|
||||
def err_objc_object_catch : Error<
|
||||
"can't catch an Objective C object by value">;
|
||||
def err_incomplete_type_objc_at_encode : Error<
|
||||
@ -3328,6 +3581,15 @@ def err_typecheck_incompatible_address_space : Error<
|
||||
"|sending %0 to parameter of type %1"
|
||||
"|casting %0 to type %1}2"
|
||||
" changes address space of pointer">;
|
||||
def err_typecheck_incompatible_ownership : Error<
|
||||
"%select{assigning %1 to %0"
|
||||
"|passing %0 to parameter of type %1"
|
||||
"|returning %0 from a function with result type %1"
|
||||
"|converting %0 to type %1"
|
||||
"|initializing %0 with an expression of type %1"
|
||||
"|sending %0 to parameter of type %1"
|
||||
"|casting %0 to type %1}2"
|
||||
" changes retain/release properties of pointer">;
|
||||
def err_typecheck_convert_ambiguous : Error<
|
||||
"ambiguity in initializing value of type %0 with initializer of type %1">;
|
||||
def err_typecheck_comparison_of_distinct_blocks : Error<
|
||||
@ -3544,6 +3806,9 @@ def ext_in_class_initializer_float_type : ExtWarn<
|
||||
def err_in_class_initializer_non_constant : Error<
|
||||
"in-class initializer is not a constant expression">;
|
||||
|
||||
def ext_in_class_initializer_non_constant : Extension<
|
||||
"in-class initializer is not a constant expression, accepted as an extension">;
|
||||
|
||||
// C++ anonymous unions and GNU anonymous structs/unions
|
||||
def ext_anonymous_union : Extension<
|
||||
"anonymous unions are a GNU extension in C">, InGroup<GNU>;
|
||||
@ -3929,12 +4194,23 @@ def err_switch_incomplete_class_type : Error<
|
||||
"switch condition has incomplete class type %0">;
|
||||
def warn_empty_if_body : Warning<
|
||||
"if statement has empty body">, InGroup<EmptyBody>;
|
||||
|
||||
def err_va_start_used_in_non_variadic_function : Error<
|
||||
"'va_start' used in function with fixed args">;
|
||||
def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
|
||||
"second parameter of 'va_start' not last named argument">;
|
||||
def err_first_argument_to_va_arg_not_of_type_va_list : Error<
|
||||
"first argument to 'va_arg' is of type %0 and not 'va_list'">;
|
||||
def err_second_parameter_to_va_arg_incomplete: Error<
|
||||
"second argument to 'va_arg' is of incomplete type %0">;
|
||||
def err_second_parameter_to_va_arg_abstract: Error<
|
||||
"second argument to 'va_arg' is of abstract type %0">;
|
||||
def warn_second_parameter_to_va_arg_not_pod : Warning<
|
||||
"second argument to 'va_arg' is of non-POD type %0">,
|
||||
InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
|
||||
def warn_second_parameter_to_va_arg_never_compatible : Warning<
|
||||
"second argument to 'va_arg' is of promotable type %0; this va_arg has "
|
||||
"undefined behavior because arguments will be promoted to %1">;
|
||||
|
||||
def warn_return_missing_expr : Warning<
|
||||
"non-void %select{function|method}1 %0 should return a value">, DefaultError,
|
||||
@ -3943,8 +4219,9 @@ def ext_return_missing_expr : ExtWarn<
|
||||
"non-void %select{function|method}1 %0 should return a value">, DefaultError,
|
||||
InGroup<ReturnType>;
|
||||
def ext_return_has_expr : ExtWarn<
|
||||
"void %select{function|method}1 %0 should not return a value">, DefaultError,
|
||||
InGroup<ReturnType>;
|
||||
"%select{void function|void method|constructor|destructor}1 %0 "
|
||||
"should not return a value">,
|
||||
DefaultError, InGroup<ReturnType>;
|
||||
def ext_return_has_void_expr : Extension<
|
||||
"void %select{function|method}1 %0 should not return void expression">;
|
||||
def warn_noreturn_function_has_return_expr : Warning<
|
||||
@ -4074,6 +4351,11 @@ def err_typecheck_member_reference_ivar_suggest : Error<
|
||||
"%0 does not have a member named %1; did you mean %2?">;
|
||||
def err_property_not_found_suggest : Error<
|
||||
"property %0 not found on object of type %1; did you mean %2?">;
|
||||
def err_ivar_access_using_property_syntax_suggest : Error<
|
||||
"property %0 not found on object of type %1; did you mean to access ivar %2?">;
|
||||
def err_property_found_suggest : Error<
|
||||
"property %0 found on object of type %1; did you mean to access "
|
||||
"it with the \".\" operator?">;
|
||||
def err_undef_interface_suggest : Error<
|
||||
"cannot find interface declaration for %0; did you mean %1?">;
|
||||
def warn_undef_interface_suggest : Warning<
|
||||
|
@ -21,10 +21,13 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Config/config.h" // for mode_t
|
||||
// FIXME: Enhance libsystem to support inode and other fields in stat.
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
struct stat;
|
||||
|
||||
namespace llvm {
|
||||
|
@ -411,23 +411,15 @@ class IdentifierTable {
|
||||
return II;
|
||||
}
|
||||
|
||||
IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
|
||||
return get(llvm::StringRef(NameStart, NameEnd-NameStart));
|
||||
}
|
||||
|
||||
IdentifierInfo &get(const char *Name, size_t NameLen) {
|
||||
return get(llvm::StringRef(Name, NameLen));
|
||||
}
|
||||
|
||||
/// \brief Gets an IdentifierInfo for the given name without consulting
|
||||
/// external sources.
|
||||
///
|
||||
/// This is a version of get() meant for external sources that want to
|
||||
/// introduce or modify an identifier. If they called get(), they would
|
||||
/// likely end up in a recursion.
|
||||
IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) {
|
||||
IdentifierInfo &getOwn(llvm::StringRef Name) {
|
||||
llvm::StringMapEntry<IdentifierInfo*> &Entry =
|
||||
HashTable.GetOrCreateValue(NameStart, NameEnd);
|
||||
HashTable.GetOrCreateValue(Name);
|
||||
|
||||
IdentifierInfo *II = Entry.getValue();
|
||||
if (!II) {
|
||||
@ -444,9 +436,6 @@ class IdentifierTable {
|
||||
|
||||
return *II;
|
||||
}
|
||||
IdentifierInfo &getOwn(llvm::StringRef Name) {
|
||||
return getOwn(Name.begin(), Name.end());
|
||||
}
|
||||
|
||||
typedef HashTableTy::const_iterator iterator;
|
||||
typedef HashTableTy::const_iterator const_iterator;
|
||||
@ -499,7 +488,10 @@ enum ObjCMethodFamily {
|
||||
OMF_release,
|
||||
OMF_retain,
|
||||
OMF_retainCount,
|
||||
OMF_self
|
||||
OMF_self,
|
||||
|
||||
// performSelector families
|
||||
OMF_performSelector
|
||||
};
|
||||
|
||||
/// Enough bits to store any enumerator in ObjCMethodFamily or
|
||||
|
@ -119,6 +119,8 @@ class LangOptions {
|
||||
unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have
|
||||
// hidden visibility by default.
|
||||
unsigned ParseUnknownAnytype: 1; /// Let the user write __unknown_anytype.
|
||||
unsigned DebuggerSupport : 1; /// Do things that only make sense when
|
||||
/// supporting a debugger
|
||||
|
||||
unsigned SpellChecking : 1; // Whether to perform spell-checking for error
|
||||
// recovery.
|
||||
@ -130,6 +132,10 @@ class LangOptions {
|
||||
unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT
|
||||
// FIXME: This is just a temporary option, for testing purposes.
|
||||
unsigned NoBitFieldTypeAlign : 1;
|
||||
unsigned ObjCAutoRefCount : 1; // Objective C automated reference counting
|
||||
unsigned ObjCRuntimeHasWeak : 1; // The ARC runtime supports __weak
|
||||
unsigned ObjCInferRelatedReturnType : 1; // Infer Objective-C related return
|
||||
// types
|
||||
unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for
|
||||
// testing languages such as OpenCL.
|
||||
|
||||
@ -172,10 +178,13 @@ class LangOptions {
|
||||
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
|
||||
GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
|
||||
HexFloats = 0;
|
||||
ObjCAutoRefCount = 0;
|
||||
ObjCRuntimeHasWeak = 0;
|
||||
ObjCInferRelatedReturnType = 0;
|
||||
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
|
||||
AppleKext = 0;
|
||||
ObjCDefaultSynthProperties = 0;
|
||||
ObjCInferRelatedResultType = 0;
|
||||
ObjCInferRelatedResultType = 1;
|
||||
NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
|
||||
C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
|
||||
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
|
||||
@ -234,7 +243,7 @@ class LangOptions {
|
||||
FakeAddressSpaceMap = 0;
|
||||
MRTD = 0;
|
||||
DelayedTemplateParsing = 0;
|
||||
ParseUnknownAnytype = 0;
|
||||
ParseUnknownAnytype = DebuggerSupport = 0;
|
||||
}
|
||||
|
||||
GCMode getGCMode() const { return (GCMode) GC; }
|
||||
|
@ -36,6 +36,7 @@ class SourceManager;
|
||||
class FileManager;
|
||||
class FileEntry;
|
||||
class LineTableInfo;
|
||||
class LangOptions;
|
||||
|
||||
/// SrcMgr - Public enums and private classes that are part of the
|
||||
/// SourceManager implementation.
|
||||
@ -89,7 +90,7 @@ namespace SrcMgr {
|
||||
|
||||
/// getBuffer - Returns the memory buffer for the associated content.
|
||||
///
|
||||
/// \param Diag Object through which diagnostics will be emitted it the
|
||||
/// \param Diag Object through which diagnostics will be emitted if the
|
||||
/// buffer cannot be retrieved.
|
||||
///
|
||||
/// \param Loc If specified, is the location that invalid file diagnostics
|
||||
@ -238,8 +239,11 @@ namespace SrcMgr {
|
||||
/// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
|
||||
/// indicate the start and end of the instantiation. In object-like macros,
|
||||
/// these will be the same. In a function-like macro instantiation, the
|
||||
/// start will be the identifier and the end will be the ')'.
|
||||
/// start will be the identifier and the end will be the ')'. Finally, in
|
||||
/// macro-argument instantitions, the end will be 'SourceLocation()', an
|
||||
/// invalid location.
|
||||
unsigned InstantiationLocStart, InstantiationLocEnd;
|
||||
|
||||
public:
|
||||
SourceLocation getSpellingLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(SpellingLoc);
|
||||
@ -248,7 +252,9 @@ namespace SrcMgr {
|
||||
return SourceLocation::getFromRawEncoding(InstantiationLocStart);
|
||||
}
|
||||
SourceLocation getInstantiationLocEnd() const {
|
||||
return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
|
||||
SourceLocation EndLoc =
|
||||
SourceLocation::getFromRawEncoding(InstantiationLocEnd);
|
||||
return EndLoc.isInvalid() ? getInstantiationLocStart() : EndLoc;
|
||||
}
|
||||
|
||||
std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
|
||||
@ -256,19 +262,52 @@ namespace SrcMgr {
|
||||
getInstantiationLocEnd());
|
||||
}
|
||||
|
||||
/// get - Return a InstantiationInfo for an expansion. IL specifies
|
||||
/// the instantiation location (where the macro is expanded), and SL
|
||||
/// specifies the spelling location (where the characters from the token
|
||||
/// come from). IL and PL can both refer to normal File SLocs or
|
||||
bool isMacroArgInstantiation() const {
|
||||
// Note that this needs to return false for default constructed objects.
|
||||
return getInstantiationLocStart().isValid() &&
|
||||
SourceLocation::getFromRawEncoding(InstantiationLocEnd).isInvalid();
|
||||
}
|
||||
|
||||
/// create - Return a InstantiationInfo for an expansion. ILStart and
|
||||
/// ILEnd specify the instantiation range (where the macro is expanded),
|
||||
/// and SL specifies the spelling location (where the characters from the
|
||||
/// token come from). All three can refer to normal File SLocs or
|
||||
/// instantiation locations.
|
||||
static InstantiationInfo get(SourceLocation ILStart, SourceLocation ILEnd,
|
||||
SourceLocation SL) {
|
||||
static InstantiationInfo create(SourceLocation SL,
|
||||
SourceLocation ILStart,
|
||||
SourceLocation ILEnd) {
|
||||
InstantiationInfo X;
|
||||
X.SpellingLoc = SL.getRawEncoding();
|
||||
X.InstantiationLocStart = ILStart.getRawEncoding();
|
||||
X.InstantiationLocEnd = ILEnd.getRawEncoding();
|
||||
return X;
|
||||
}
|
||||
|
||||
/// createForMacroArg - Return a special InstantiationInfo for the
|
||||
/// expansion of a macro argument into a function-like macro's body. IL
|
||||
/// specifies the instantiation location (where the macro is expanded).
|
||||
/// This doesn't need to be a range because a macro is always instantiated
|
||||
/// at a macro parameter reference, and macro parameters are always exactly
|
||||
/// one token. SL specifies the spelling location (where the characters
|
||||
/// from the token come from). IL and SL can both refer to normal File
|
||||
/// SLocs or instantiation locations.
|
||||
///
|
||||
/// Given the code:
|
||||
/// \code
|
||||
/// #define F(x) f(x)
|
||||
/// F(42);
|
||||
/// \endcode
|
||||
///
|
||||
/// When expanding '\c F(42)', the '\c x' would call this with an SL
|
||||
/// pointing at '\c 42' anad an IL pointing at its location in the
|
||||
/// definition of '\c F'.
|
||||
static InstantiationInfo createForMacroArg(SourceLocation SL,
|
||||
SourceLocation IL) {
|
||||
// We store an intentionally invalid source location for the end of the
|
||||
// instantiation range to mark that this is a macro argument instantation
|
||||
// rather than a normal one.
|
||||
return create(SL, IL, SourceLocation());
|
||||
}
|
||||
};
|
||||
|
||||
/// SLocEntry - This is a discriminated union of FileInfo and
|
||||
@ -500,8 +539,8 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// createFileID - Create a new FileID that represents the specified file
|
||||
/// being #included from the specified IncludePosition. This returns 0 on
|
||||
/// error and translates NULL into standard input.
|
||||
/// being #included from the specified IncludePosition. This translates NULL
|
||||
/// into standard input.
|
||||
/// PreallocateID should be non-zero to specify which pre-allocated,
|
||||
/// lazily computed source location is being filled in by this operation.
|
||||
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
|
||||
@ -532,9 +571,17 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
return MainFileID;
|
||||
}
|
||||
|
||||
/// createMacroArgInstantiationLoc - Return a new SourceLocation that encodes
|
||||
/// the fact that a token from SpellingLoc should actually be referenced from
|
||||
/// InstantiationLoc, and that it represents the instantiation of a macro
|
||||
/// argument into the function-like macro body.
|
||||
SourceLocation createMacroArgInstantiationLoc(SourceLocation Loc,
|
||||
SourceLocation InstantiationLoc,
|
||||
unsigned TokLength);
|
||||
|
||||
/// createInstantiationLoc - Return a new SourceLocation that encodes the fact
|
||||
/// that a token at Loc should actually be referenced from InstantiationLoc.
|
||||
/// TokLength is the length of the token being instantiated.
|
||||
/// that a token from SpellingLoc should actually be referenced from
|
||||
/// InstantiationLoc.
|
||||
SourceLocation createInstantiationLoc(SourceLocation Loc,
|
||||
SourceLocation InstantiationLocStart,
|
||||
SourceLocation InstantiationLocEnd,
|
||||
@ -721,7 +768,7 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
if (Loc.isFileID())
|
||||
return std::make_pair(FID, Offset);
|
||||
|
||||
return getDecomposedInstantiationLocSlowCase(E, Offset);
|
||||
return getDecomposedInstantiationLocSlowCase(E);
|
||||
}
|
||||
|
||||
/// getDecomposedSpellingLoc - Decompose the specified location into a raw
|
||||
@ -745,6 +792,12 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
return getDecomposedLoc(SpellingLoc).second;
|
||||
}
|
||||
|
||||
/// isMacroArgInstantiation - This method tests whether the given source
|
||||
/// location represents a macro argument's instantiation into the
|
||||
/// function-like macro definition. Such source locations only appear inside
|
||||
/// of the instantiation locations representing where a particular
|
||||
/// function-like macro was expanded.
|
||||
bool isMacroArgInstantiation(SourceLocation Loc) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Queries about the code at a SourceLocation.
|
||||
@ -831,13 +884,38 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the first
|
||||
/// token of the macro instantiation.
|
||||
bool isAtStartOfMacroInstantiation(SourceLocation Loc) const;
|
||||
/// \brief Given a specific chunk of a FileID (FileID with offset+length),
|
||||
/// returns true if \arg Loc is inside that chunk and sets relative offset
|
||||
/// (offset of \arg Loc from beginning of chunk) to \arg relativeOffset.
|
||||
bool isInFileID(SourceLocation Loc,
|
||||
FileID FID, unsigned offset, unsigned length,
|
||||
unsigned *relativeOffset = 0) const {
|
||||
assert(!FID.isInvalid());
|
||||
if (Loc.isInvalid())
|
||||
return false;
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the last
|
||||
/// token of the macro instantiation.
|
||||
bool isAtEndOfMacroInstantiation(SourceLocation Loc) const;
|
||||
unsigned start = getSLocEntry(FID).getOffset() + offset;
|
||||
unsigned end = start + length;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Make sure offset/length describe a chunk inside the given FileID.
|
||||
unsigned NextOffset;
|
||||
if (FID.ID+1 == SLocEntryTable.size())
|
||||
NextOffset = getNextOffset();
|
||||
else
|
||||
NextOffset = getSLocEntry(FID.ID+1).getOffset();
|
||||
assert(start < NextOffset);
|
||||
assert(end < NextOffset);
|
||||
#endif
|
||||
|
||||
if (Loc.getOffset() >= start && Loc.getOffset() < end) {
|
||||
if (relativeOffset)
|
||||
*relativeOffset = Loc.getOffset() - start;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Line Table Manipulation Routines
|
||||
@ -845,7 +923,7 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
|
||||
/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
|
||||
///
|
||||
unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
|
||||
unsigned getLineTableFilenameID(llvm::StringRef Str);
|
||||
|
||||
/// AddLineNote - Add a line note to the line table for the FileID and offset
|
||||
/// specified by Loc. If FilenameID is -1, it is considered to be
|
||||
@ -899,6 +977,19 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
/// \returns true if LHS source location comes before RHS, false otherwise.
|
||||
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
|
||||
|
||||
/// \brief Determines the order of 2 source locations in the "source location
|
||||
/// address space".
|
||||
static bool isBeforeInSourceLocationOffset(SourceLocation LHS,
|
||||
SourceLocation RHS) {
|
||||
return isBeforeInSourceLocationOffset(LHS, RHS.getOffset());
|
||||
}
|
||||
|
||||
/// \brief Determines the order of a source location and a source location
|
||||
/// offset in the "source location address space".
|
||||
static bool isBeforeInSourceLocationOffset(SourceLocation LHS, unsigned RHS) {
|
||||
return LHS.getOffset() < RHS;
|
||||
}
|
||||
|
||||
// Iterators over FileInfos.
|
||||
typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
|
||||
::const_iterator fileinfo_iterator;
|
||||
@ -952,6 +1043,14 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
private:
|
||||
const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
|
||||
|
||||
/// createInstantiationLoc - Implements the common elements of storing an
|
||||
/// instantiation info struct into the SLocEntry table and producing a source
|
||||
/// location that refers to it.
|
||||
SourceLocation createInstantiationLocImpl(const SrcMgr::InstantiationInfo &II,
|
||||
unsigned TokLength,
|
||||
unsigned PreallocatedID = 0,
|
||||
unsigned Offset = 0);
|
||||
|
||||
/// isOffsetInFileID - Return true if the specified FileID contains the
|
||||
/// specified SourceLocation offset. This is a very hot method.
|
||||
inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {
|
||||
@ -989,8 +1088,7 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> {
|
||||
SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const;
|
||||
|
||||
std::pair<FileID, unsigned>
|
||||
getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
|
||||
unsigned Offset) const;
|
||||
getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E) const;
|
||||
std::pair<FileID, unsigned>
|
||||
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
|
||||
unsigned Offset) const;
|
||||
|
@ -97,7 +97,7 @@ class LineTableInfo {
|
||||
|
||||
~LineTableInfo() {}
|
||||
|
||||
unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
|
||||
unsigned getLineTableFilenameID(llvm::StringRef Str);
|
||||
const char *getFilename(unsigned ID) const {
|
||||
assert(ID < FilenamesByID.size() && "Invalid FilenameID");
|
||||
return FilenamesByID[ID]->getKeyData();
|
||||
|
@ -83,7 +83,7 @@ namespace clang {
|
||||
/// ExprValueKind - The categorization of expression values,
|
||||
/// currently following the C++0x scheme.
|
||||
enum ExprValueKind {
|
||||
/// An r-value expression (a gr-value in the C++0x taxonomy)
|
||||
/// An r-value expression (a pr-value in the C++0x taxonomy)
|
||||
/// produces a temporary value.
|
||||
VK_RValue,
|
||||
|
||||
|
@ -37,6 +37,7 @@ def ObjCAtFinallyStmt : Stmt;
|
||||
def ObjCAtThrowStmt : Stmt;
|
||||
def ObjCAtSynchronizedStmt : Stmt;
|
||||
def ObjCForCollectionStmt : Stmt;
|
||||
def ObjCAutoreleasePoolStmt : Stmt;
|
||||
|
||||
// C++ statments
|
||||
def CXXCatchStmt : Stmt;
|
||||
@ -119,7 +120,9 @@ def UnresolvedMemberExpr : DStmt<OverloadExpr>;
|
||||
def CXXNoexceptExpr : DStmt<Expr>;
|
||||
def PackExpansionExpr : DStmt<Expr>;
|
||||
def SizeOfPackExpr : DStmt<Expr>;
|
||||
def SubstNonTypeTemplateParmExpr : DStmt<Expr>;
|
||||
def SubstNonTypeTemplateParmPackExpr : DStmt<Expr>;
|
||||
def MaterializeTemporaryExpr : DStmt<Expr>;
|
||||
|
||||
// Obj-C Expressions.
|
||||
def ObjCStringLiteral : DStmt<Expr>;
|
||||
@ -130,6 +133,10 @@ def ObjCProtocolExpr : DStmt<Expr>;
|
||||
def ObjCIvarRefExpr : DStmt<Expr>;
|
||||
def ObjCPropertyRefExpr : DStmt<Expr>;
|
||||
def ObjCIsaExpr : DStmt<Expr>;
|
||||
def ObjCIndirectCopyRestoreExpr : DStmt<Expr>;
|
||||
|
||||
// Obj-C ARC Expressions.
|
||||
def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>;
|
||||
|
||||
// CUDA Expressions.
|
||||
def CUDAKernelCallExpr : DStmt<CallExpr>;
|
||||
|
@ -240,6 +240,14 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
|
||||
return getTypeWidth(IntMaxType);
|
||||
}
|
||||
|
||||
/// getRegisterWidth - Return the "preferred" register width on this target.
|
||||
uint64_t getRegisterWidth() const {
|
||||
// Currently we assume the register width on the target matches the pointer
|
||||
// width, we can introduce a new variable for this if/when some target wants
|
||||
// it.
|
||||
return LongWidth;
|
||||
}
|
||||
|
||||
/// getUserLabelPrefix - This returns the default value of the
|
||||
/// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by
|
||||
/// default. On most platforms this is "_", but it is "" on some, and "." on
|
||||
@ -295,6 +303,11 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
|
||||
/// __builtin_va_list, which is target-specific.
|
||||
virtual const char *getVAListDeclaration() const = 0;
|
||||
|
||||
/// isValidClobber - Returns whether the passed in string is
|
||||
/// a valid clobber in an inline asm statement. This is used by
|
||||
/// Sema.
|
||||
bool isValidClobber(llvm::StringRef Name) const;
|
||||
|
||||
/// isValidGCCRegisterName - Returns whether the passed in string
|
||||
/// is a valid register name according to GCC. This is used by Sema for
|
||||
/// inline asm statements.
|
||||
@ -396,6 +409,11 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
|
||||
const char * const Register;
|
||||
};
|
||||
|
||||
struct AddlRegName {
|
||||
const char * const Names[5];
|
||||
const unsigned RegNum;
|
||||
};
|
||||
|
||||
virtual bool useGlobalsForAutomaticVariables() const { return false; }
|
||||
|
||||
/// getCFStringSection - Return the section to use for CFString
|
||||
@ -511,6 +529,7 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
|
||||
|
||||
// getRegParmMax - Returns maximal number of args passed in registers.
|
||||
unsigned getRegParmMax() const {
|
||||
assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
|
||||
return RegParmMax;
|
||||
}
|
||||
|
||||
@ -566,6 +585,11 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
|
||||
unsigned &NumNames) const = 0;
|
||||
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
||||
unsigned &NumAliases) const = 0;
|
||||
virtual void getGCCAddlRegNames(const AddlRegName *&Addl,
|
||||
unsigned &NumAddl) const {
|
||||
Addl = 0;
|
||||
NumAddl = 0;
|
||||
}
|
||||
virtual bool validateAsmConstraint(const char *&Name,
|
||||
TargetInfo::ConstraintInfo &info) const= 0;
|
||||
};
|
||||
|
@ -422,6 +422,12 @@ KEYWORD(__pascal , KEYALL)
|
||||
KEYWORD(__vector , KEYALTIVEC)
|
||||
KEYWORD(__pixel , KEYALTIVEC)
|
||||
|
||||
// Objective-C ARC keywords.
|
||||
KEYWORD(__bridge , KEYARC)
|
||||
KEYWORD(__bridge_transfer , KEYARC)
|
||||
KEYWORD(__bridge_retained , KEYARC)
|
||||
KEYWORD(__bridge_retain , KEYARC)
|
||||
|
||||
// Alternate spelling for various tokens. There are GCC extensions in all
|
||||
// languages, but should not be disabled in strict conformance mode.
|
||||
ALIAS("__alignof__" , __alignof , KEYALL)
|
||||
@ -507,6 +513,7 @@ OBJC1_AT_KEYWORD(try)
|
||||
OBJC1_AT_KEYWORD(catch)
|
||||
OBJC1_AT_KEYWORD(finally)
|
||||
OBJC1_AT_KEYWORD(synchronized)
|
||||
OBJC1_AT_KEYWORD(autoreleasepool)
|
||||
|
||||
OBJC2_AT_KEYWORD(property)
|
||||
OBJC2_AT_KEYWORD(package)
|
||||
|
@ -182,7 +182,7 @@ def VMAX : SInst<"vmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
|
||||
def VMIN : SInst<"vmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// E.3.7 Pairdise Addition
|
||||
// E.3.7 Pairwise Addition
|
||||
def VPADD : IInst<"vpadd", "ddd", "csiUcUsUif">;
|
||||
def VPADDL : SInst<"vpaddl", "nd", "csiUcUsUiQcQsQiQUcQUsQUi">;
|
||||
def VPADAL : SInst<"vpadal", "nnd", "csiUcUsUiQcQsQiQUcQUsQUi">;
|
||||
@ -352,7 +352,7 @@ def VEXT : WInst<"vext", "dddi",
|
||||
"cUcPcsUsPsiUilUlfQcQUcQPcQsQUsQPsQiQUiQlQUlQf">;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// E.3.27 Reverse vector elements (sdap endianness)
|
||||
// E.3.27 Reverse vector elements
|
||||
def VREV64 : Inst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf",
|
||||
OP_REV64>;
|
||||
def VREV32 : Inst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>;
|
||||
|
@ -19,6 +19,7 @@ namespace clang {
|
||||
class Diagnostic;
|
||||
class CodeGenOptions;
|
||||
class TargetOptions;
|
||||
class LangOptions;
|
||||
|
||||
enum BackendAction {
|
||||
Backend_EmitAssembly, ///< Emit native assembly files
|
||||
@ -30,7 +31,8 @@ namespace clang {
|
||||
};
|
||||
|
||||
void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
|
||||
const TargetOptions &TOpts, llvm::Module *M,
|
||||
const TargetOptions &TOpts, const LangOptions &LOpts,
|
||||
llvm::Module *M,
|
||||
BackendAction Action, llvm::raw_ostream *OS);
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,8 @@ def femit_coverage_data: Flag<"-femit-coverage-data">,
|
||||
def coverage_file : Separate<"-coverage-file">,
|
||||
HelpText<"Emit coverage data to this filename. The extension will be replaced.">;
|
||||
def coverage_file_EQ : Joined<"-coverage-file=">, Alias<coverage_file>;
|
||||
def fuse_register_sized_bitfield_access: Flag<"-fuse-register-sized-bitfield-access">,
|
||||
HelpText<"Use register sized accesses to bit-fields, when possible.">;
|
||||
def relaxed_aliasing : Flag<"-relaxed-aliasing">,
|
||||
HelpText<"Turn off Type Based Alias Analysis">;
|
||||
def masm_verbose : Flag<"-masm-verbose">,
|
||||
@ -157,6 +159,8 @@ def mfloat_abi : Separate<"-mfloat-abi">,
|
||||
HelpText<"The float ABI to use">;
|
||||
def mlimit_float_precision : Separate<"-mlimit-float-precision">,
|
||||
HelpText<"Limit float precision to the given value">;
|
||||
def mno_exec_stack : Flag<"-mnoexecstack">,
|
||||
HelpText<"Mark the file as not needing an executable stack">;
|
||||
def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
|
||||
HelpText<"Do not put zero initialized data in the BSS">;
|
||||
def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">,
|
||||
@ -204,6 +208,7 @@ def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">;
|
||||
def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
|
||||
def MP : Flag<"-MP">,
|
||||
HelpText<"Create phony target for each dependency (other than main file)">;
|
||||
def MG : Flag<"-MG">, HelpText<"Add missing headers to dependency list">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Diagnostic Options
|
||||
@ -259,7 +264,7 @@ def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
|
||||
def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
|
||||
def fmacro_backtrace_limit : Separate<"-fmacro-backtrace-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of entries to print in a macro instantiation backtrace (0 = no limit).">;
|
||||
HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">;
|
||||
def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
|
||||
HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
|
||||
def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
|
||||
@ -352,8 +357,6 @@ def ast_dump_xml : Flag<"-ast-dump-xml">,
|
||||
HelpText<"Build ASTs and then debug dump them in a verbose XML format">;
|
||||
def ast_view : Flag<"-ast-view">,
|
||||
HelpText<"Build ASTs and view them with GraphViz">;
|
||||
def boostcon : Flag<"-boostcon">,
|
||||
HelpText<"BoostCon workshop mode">;
|
||||
def print_decl_contexts : Flag<"-print-decl-contexts">,
|
||||
HelpText<"Print DeclContexts and their Decls">;
|
||||
def emit_pth : Flag<"-emit-pth">,
|
||||
@ -383,6 +386,15 @@ def create_module : Flag<"-create-module">,
|
||||
HelpText<"Create a module definition file">;
|
||||
}
|
||||
|
||||
def arcmt_check : Flag<"-arcmt-check">,
|
||||
HelpText<"Check for ARC migration issues that need manual handling">;
|
||||
def arcmt_modify : Flag<"-arcmt-modify">,
|
||||
HelpText<"Apply modifications to files to conform to ARC">;
|
||||
def arcmt_migrate : Flag<"-arcmt-migrate">,
|
||||
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
|
||||
def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">,
|
||||
HelpText<"Directory for temporary files produced during ARC migration">;
|
||||
|
||||
def import_module : Separate<"-import-module">,
|
||||
HelpText<"Import a module definition file">;
|
||||
|
||||
@ -452,6 +464,8 @@ def fhidden_weak_vtables : Flag<"-fhidden-weak-vtables">,
|
||||
HelpText<"Generate weak vtables and RTTI with hidden visibility">;
|
||||
def std_EQ : Joined<"-std=">,
|
||||
HelpText<"Language standard to compile for">;
|
||||
def stdlib_EQ : Joined<"-stdlib=">,
|
||||
HelpText<"C++ standard library to use">;
|
||||
def fmath_errno : Flag<"-fmath-errno">,
|
||||
HelpText<"Require math functions to indicate errors by setting errno">;
|
||||
def fms_extensions : Flag<"-fms-extensions">,
|
||||
@ -479,6 +493,18 @@ def fconstant_string_class : Separate<"-fconstant-string-class">,
|
||||
HelpText<"Specify the class to use for constant Objective-C string objects.">;
|
||||
def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">,
|
||||
HelpText<"Enable creation of CodeFoundation-type constant strings">;
|
||||
def fobjc_arc : Flag<"-fobjc-arc">,
|
||||
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
|
||||
def fobjc_arc_cxxlib_EQ : Joined<"-fobjc-arc-cxxlib=">,
|
||||
HelpText<"Objective-C++ Automatic Reference Counting standard library kind">;
|
||||
def fobjc_arc_exceptions : Flag<"-fobjc-arc-exceptions">,
|
||||
HelpText<"Use EH-safe code when synthesizing retains and releases in -fobjc-arc">;
|
||||
def fobjc_runtime_has_arc : Flag<"-fobjc-runtime-has-arc">,
|
||||
HelpText<"The target Objective-C runtime provides ARC entrypoints">;
|
||||
def fobjc_runtime_has_weak : Flag<"-fobjc-runtime-has-weak">,
|
||||
HelpText<"The target Objective-C runtime supports ARC weak operations">;
|
||||
def fobjc_runtime_has_terminate : Flag<"-fobjc-runtime-has-terminate">,
|
||||
HelpText<"The target Objective-C runtime provides an objc_terminate entrypoint">;
|
||||
def fobjc_gc : Flag<"-fobjc-gc">,
|
||||
HelpText<"Enable Objective-C garbage collection">;
|
||||
def fobjc_gc_only : Flag<"-fobjc-gc-only">,
|
||||
@ -493,8 +519,10 @@ def print_ivar_layout : Flag<"-print-ivar-layout">,
|
||||
HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
|
||||
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
|
||||
HelpText<"enable objective-c's nonfragile abi">;
|
||||
def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">,
|
||||
HelpText<"infer Objective-C related result type based on method family">;
|
||||
def fno_objc_infer_related_result_type : Flag<
|
||||
"-fno-objc-infer-related-result-type">,
|
||||
HelpText<
|
||||
"do not infer Objective-C related result type based on method family">;
|
||||
def ftrapv : Flag<"-ftrapv">,
|
||||
HelpText<"Trap on integer overflow">;
|
||||
def ftrapv_handler : Separate<"-ftrapv-handler">,
|
||||
@ -554,6 +582,8 @@ def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">,
|
||||
"translation unit ">;
|
||||
def funknown_anytype : Flag<"-funknown-anytype">,
|
||||
HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">;
|
||||
def fdebugger_support : Flag<"-fdebugger-support">,
|
||||
HelpText<"Enable special debugger support behavior">;
|
||||
def fdeprecated_macro : Flag<"-fdeprecated-macro">,
|
||||
HelpText<"Defines the __DEPRECATED macro">;
|
||||
def fno_deprecated_macro : Flag<"-fno-deprecated-macro">,
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "clang/Driver/Util.h"
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
|
@ -357,6 +357,8 @@ class Driver {
|
||||
bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
|
||||
const llvm::Triple &ArchName) const;
|
||||
|
||||
bool IsUsingLTO(const ArgList &Args) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
|
||||
|
46
include/clang/Driver/ObjCRuntime.h
Normal file
46
include/clang/Driver/ObjCRuntime.h
Normal file
@ -0,0 +1,46 @@
|
||||
//===--- ObjCRuntime.h - Objective C runtime features -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_DRIVER_OBJCRUNTIME_H_
|
||||
#define CLANG_DRIVER_OBJCRUNTIME_H_
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
|
||||
class ObjCRuntime {
|
||||
public:
|
||||
enum Kind { GNU, NeXT };
|
||||
private:
|
||||
unsigned RuntimeKind : 1;
|
||||
public:
|
||||
void setKind(Kind k) { RuntimeKind = k; }
|
||||
Kind getKind() const { return static_cast<Kind>(RuntimeKind); }
|
||||
|
||||
/// True if the runtime provides native ARC entrypoints. ARC may
|
||||
/// still be usable without this if the tool-chain provides a
|
||||
/// statically-linked runtime support library.
|
||||
unsigned HasARC : 1;
|
||||
|
||||
/// True if the runtime supports ARC zeroing __weak.
|
||||
unsigned HasWeak : 1;
|
||||
|
||||
/// True if the runtime provides the following entrypoint:
|
||||
/// void objc_terminate(void);
|
||||
/// If available, this will be called instead of abort() when an
|
||||
/// exception is thrown out of an EH cleanup.
|
||||
unsigned HasTerminate : 1;
|
||||
|
||||
ObjCRuntime() : RuntimeKind(NeXT), HasARC(false), HasWeak(false),
|
||||
HasTerminate(false) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#define CLANG_DRIVER_OPTION_H_
|
||||
|
||||
#include "clang/Driver/OptSpecifier.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
using llvm::isa;
|
||||
using llvm::cast;
|
||||
@ -64,7 +65,7 @@ namespace driver {
|
||||
OptSpecifier ID;
|
||||
|
||||
/// The option name.
|
||||
const char *Name;
|
||||
llvm::StringRef Name;
|
||||
|
||||
/// Group this option is a member of, if any.
|
||||
const OptionGroup *Group;
|
||||
@ -103,7 +104,7 @@ namespace driver {
|
||||
|
||||
unsigned getID() const { return ID.getID(); }
|
||||
OptionClass getKind() const { return Kind; }
|
||||
const char *getName() const { return Name; }
|
||||
llvm::StringRef getName() const { return Name; }
|
||||
const OptionGroup *getGroup() const { return Group; }
|
||||
const Option *getAlias() const { return Alias; }
|
||||
|
||||
@ -143,7 +144,7 @@ namespace driver {
|
||||
|
||||
/// getRenderName - Return the name to use when rendering this
|
||||
/// option.
|
||||
const char *getRenderName() const {
|
||||
llvm::StringRef getRenderName() const {
|
||||
return getUnaliasedOption()->getName();
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,17 @@ def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt,
|
||||
def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt,
|
||||
HelpText<"Show bindings of tools to actions">;
|
||||
|
||||
def ccc_arcmt_check : Flag<"-ccc-arcmt-check">, CCCDriverOpt,
|
||||
HelpText<"Check for ARC migration issues that need manual handling">;
|
||||
def ccc_arcmt_modify : Flag<"-ccc-arcmt-modify">, CCCDriverOpt,
|
||||
HelpText<"Apply modifications to files to conform to ARC">;
|
||||
def ccc_arrmt_check : Flag<"-ccc-arrmt-check">, Alias<ccc_arcmt_check>;
|
||||
def ccc_arrmt_modify : Flag<"-ccc-arrmt-modify">, Alias<ccc_arcmt_modify>;
|
||||
def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt,
|
||||
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
|
||||
def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt,
|
||||
Alias<ccc_arcmt_migrate>;
|
||||
|
||||
// Make sure all other -ccc- options are rejected.
|
||||
def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
|
||||
|
||||
@ -382,6 +393,10 @@ def fno_verbose_asm : Flag<"-fno-verbose-asm">, Group<f_Group>;
|
||||
def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
|
||||
def fno_wrapv : Flag<"-fno-wrapv">, Group<f_Group>;
|
||||
def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
|
||||
def fobjc_arc : Flag<"-fobjc-arc">, Group<f_Group>;
|
||||
def fno_objc_arc : Flag<"-fno-objc-arc">, Group<f_Group>;
|
||||
def fobjc_arc_exceptions : Flag<"-fobjc-arc-exceptions">, Group<f_Group>;
|
||||
def fno_objc_arc_exceptions : Flag<"-fno-objc-arc-exceptions">, Group<f_Group>;
|
||||
def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_default_synthesize_properties :
|
||||
@ -409,6 +424,7 @@ def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
|
||||
def fopenmp : Flag<"-fopenmp">, Group<f_Group>;
|
||||
def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
|
||||
def force__flat__namespace : Flag<"-force_flat_namespace">;
|
||||
def force__load : Separate<"-force_load">;
|
||||
def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
|
||||
def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
|
||||
def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
|
||||
@ -803,8 +819,8 @@ def _specs : Separate<"--specs">, Alias<specs_EQ>;
|
||||
def _static : Flag<"--static">, Alias<static>;
|
||||
def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
|
||||
def _std : Separate<"--std">, Alias<std_EQ>;
|
||||
def _stdlib_EQ : Joined<"--stdlib=">, Alias<std_EQ>;
|
||||
def _stdlib : Separate<"--stdlib">, Alias<std_EQ>;
|
||||
def _stdlib_EQ : Joined<"--stdlib=">, Alias<stdlib_EQ>;
|
||||
def _stdlib : Separate<"--stdlib">, Alias<stdlib_EQ>;
|
||||
def _sysroot_EQ : Joined<"--sysroot=">;
|
||||
def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>;
|
||||
def _target_help : Flag<"--target-help">;
|
||||
|
@ -26,6 +26,7 @@ namespace driver {
|
||||
class HostInfo;
|
||||
class InputArgList;
|
||||
class JobAction;
|
||||
class ObjCRuntime;
|
||||
class Tool;
|
||||
|
||||
/// ToolChain - Access to tools for a single platform.
|
||||
@ -177,6 +178,12 @@ class ToolChain {
|
||||
/// Clang.
|
||||
virtual std::string ComputeEffectiveClangTriple(const ArgList &Args) const;
|
||||
|
||||
/// configureObjCRuntime - Configure the known properties of the
|
||||
/// Objective-C runtime for this platform.
|
||||
///
|
||||
/// FIXME: this doesn't really belong here.
|
||||
virtual void configureObjCRuntime(ObjCRuntime &runtime) const;
|
||||
|
||||
// GetCXXStdlibType - Determine the C++ standard library type to use with the
|
||||
// given compilation arguments.
|
||||
virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const;
|
||||
@ -184,7 +191,8 @@ class ToolChain {
|
||||
/// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
|
||||
/// the include paths to use for the given C++ standard library type.
|
||||
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const;
|
||||
ArgStringList &CmdArgs,
|
||||
bool ObjCXXAutoRefCount) const;
|
||||
|
||||
/// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
|
||||
/// for the given C++ standard library type.
|
||||
|
@ -249,9 +249,9 @@ class ASTUnit {
|
||||
/// \brief Whether we should be caching code-completion results.
|
||||
bool ShouldCacheCodeCompletionResults;
|
||||
|
||||
/// \brief Whether we want to include nested macro instantiations in the
|
||||
/// \brief Whether we want to include nested macro expansions in the
|
||||
/// detailed preprocessing record.
|
||||
bool NestedMacroInstantiations;
|
||||
bool NestedMacroExpansions;
|
||||
|
||||
static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags,
|
||||
const char **ArgBegin, const char **ArgEnd,
|
||||
@ -363,7 +363,7 @@ class ASTUnit {
|
||||
unsigned MaxLines, bool &CreatedBuffer);
|
||||
|
||||
llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble(
|
||||
CompilerInvocation PreambleInvocation,
|
||||
const CompilerInvocation &PreambleInvocationIn,
|
||||
bool AllowRebuild = true,
|
||||
unsigned MaxLines = 0);
|
||||
void RealizeTopLevelDeclsFromPreamble();
|
||||
@ -612,7 +612,7 @@ class ASTUnit {
|
||||
bool PrecompilePreamble = false,
|
||||
bool CompleteTranslationUnit = true,
|
||||
bool CacheCodeCompletionResults = false,
|
||||
bool NestedMacroInstantiations = true);
|
||||
bool NestedMacroExpansions = true);
|
||||
|
||||
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
|
||||
/// arguments, which must specify exactly one source file.
|
||||
@ -642,7 +642,7 @@ class ASTUnit {
|
||||
bool CacheCodeCompletionResults = false,
|
||||
bool CXXPrecompilePreamble = false,
|
||||
bool CXXChainedPCH = false,
|
||||
bool NestedMacroInstantiations = true);
|
||||
bool NestedMacroExpansions = true);
|
||||
|
||||
/// \brief Reparse the source files using the same command-line options that
|
||||
/// were originally used to produce this translation unit.
|
||||
@ -680,8 +680,8 @@ class ASTUnit {
|
||||
|
||||
/// \brief Save this translation unit to a file with the given name.
|
||||
///
|
||||
/// \returns True if an error occurred, false otherwise.
|
||||
bool Save(llvm::StringRef File);
|
||||
/// \returns An indication of whether the save was successful or not.
|
||||
CXSaveError Save(llvm::StringRef File);
|
||||
|
||||
/// \brief Serialize this translation unit with the given output stream.
|
||||
///
|
||||
|
@ -36,6 +36,7 @@ class CodeGenOptions {
|
||||
};
|
||||
|
||||
unsigned AsmVerbose : 1; /// -dA, -fverbose-asm.
|
||||
unsigned ObjCAutoRefCountExceptions : 1; /// Whether ARC should be EH-safe.
|
||||
unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors.
|
||||
unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
|
||||
/// aliases to base ctors when possible.
|
||||
@ -69,11 +70,14 @@ class CodeGenOptions {
|
||||
unsigned MergeAllConstants : 1; /// Merge identical constants.
|
||||
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
|
||||
unsigned NoDwarf2CFIAsm : 1; /// Set when -fno-dwarf2-cfi-asm is enabled.
|
||||
unsigned NoExecStack : 1; /// Set when -Wa,--noexecstack is enabled.
|
||||
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
|
||||
unsigned NoInfsFPMath : 1; /// Assume FP arguments, results not +-Inf.
|
||||
unsigned NoNaNsFPMath : 1; /// Assume FP arguments, results not NaN.
|
||||
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
|
||||
unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
|
||||
unsigned ObjCRuntimeHasARC : 1; /// The target runtime supports ARC natively
|
||||
unsigned ObjCRuntimeHasTerminate : 1; /// The ObjC runtime has objc_terminate
|
||||
unsigned OmitLeafFramePointer : 1; /// Set when -momit-leaf-frame-pointer is
|
||||
/// enabled.
|
||||
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
|
||||
@ -89,6 +93,11 @@ class CodeGenOptions {
|
||||
unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
|
||||
unsigned UnsafeFPMath : 1; /// Allow unsafe floating point optzns.
|
||||
unsigned UnwindTables : 1; /// Emit unwind tables.
|
||||
|
||||
/// Attempt to use register sized accesses to bit-fields in structures, when
|
||||
/// possible.
|
||||
unsigned UseRegisterSizedBitfieldAccess : 1;
|
||||
|
||||
unsigned VerifyModule : 1; /// Control whether the module should be run
|
||||
/// through the LLVM Verifier.
|
||||
|
||||
@ -159,7 +168,10 @@ class CodeGenOptions {
|
||||
NoNaNsFPMath = 0;
|
||||
NoZeroInitializedInBSS = 0;
|
||||
NumRegisterParameters = 0;
|
||||
ObjCAutoRefCountExceptions = 0;
|
||||
ObjCDispatchMethod = Legacy;
|
||||
ObjCRuntimeHasARC = 0;
|
||||
ObjCRuntimeHasTerminate = 0;
|
||||
OmitLeafFramePointer = 0;
|
||||
OptimizationLevel = 0;
|
||||
OptimizeSize = 0;
|
||||
@ -173,6 +185,7 @@ class CodeGenOptions {
|
||||
UnrollLoops = 0;
|
||||
UnsafeFPMath = 0;
|
||||
UnwindTables = 0;
|
||||
UseRegisterSizedBitfieldAccess = 0;
|
||||
VerifyModule = 1;
|
||||
|
||||
Inlining = NoInlining;
|
||||
|
@ -24,6 +24,7 @@ class DependencyOutputOptions {
|
||||
unsigned UsePhonyTargets : 1; ///< Include phony targets for each
|
||||
/// dependency, which can avoid some 'make'
|
||||
/// problems.
|
||||
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
|
||||
|
||||
/// The file to write dependency output to.
|
||||
std::string OutputFile;
|
||||
@ -43,6 +44,7 @@ class DependencyOutputOptions {
|
||||
IncludeSystemHeaders = 0;
|
||||
ShowHeaderIncludes = 0;
|
||||
UsePhonyTargets = 0;
|
||||
AddMissingHeaderDeps = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -49,8 +49,7 @@ class DiagnosticOptions {
|
||||
/// input source file.
|
||||
|
||||
unsigned ErrorLimit; /// Limit # errors emitted.
|
||||
unsigned MacroBacktraceLimit; /// Limit depth of macro instantiation
|
||||
/// backtrace.
|
||||
unsigned MacroBacktraceLimit; /// Limit depth of macro expansion backtrace.
|
||||
unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
|
||||
|
||||
/// The distance between tab stops.
|
||||
|
@ -51,6 +51,7 @@ class FrontendAction {
|
||||
llvm::OwningPtr<ASTUnit> CurrentASTUnit;
|
||||
CompilerInstance *Instance;
|
||||
friend class ASTMergeAction;
|
||||
friend class WrapperFrontendAction;
|
||||
|
||||
private:
|
||||
ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI,
|
||||
@ -77,6 +78,14 @@ class FrontendAction {
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
|
||||
llvm::StringRef InFile) = 0;
|
||||
|
||||
/// \brief Callback before starting processing a single input, giving the
|
||||
/// opportunity to modify the CompilerInvocation or do some other action
|
||||
/// before BeginSourceFileAction is called.
|
||||
///
|
||||
/// \return True on success; on failure \see BeginSourceFileAction() and
|
||||
/// ExecutionAction() and EndSourceFileAction() will not be called.
|
||||
virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
|
||||
|
||||
/// BeginSourceFileAction - Callback at the start of processing a single
|
||||
/// input.
|
||||
///
|
||||
@ -253,6 +262,36 @@ class PreprocessorFrontendAction : public FrontendAction {
|
||||
virtual bool usesPreprocessorOnly() const { return true; }
|
||||
};
|
||||
|
||||
/// WrapperFrontendAction - A frontend action which simply wraps some other
|
||||
/// runtime specified frontend action. Deriving from this class allows an
|
||||
/// action to inject custom logic around some existing action's behavior. It
|
||||
/// implements every virtual method in the FrontendAction interface by
|
||||
/// forwarding to the wrapped action.
|
||||
class WrapperFrontendAction : public FrontendAction {
|
||||
llvm::OwningPtr<FrontendAction> WrappedAction;
|
||||
|
||||
protected:
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
|
||||
llvm::StringRef InFile);
|
||||
virtual bool BeginInvocation(CompilerInstance &CI);
|
||||
virtual bool BeginSourceFileAction(CompilerInstance &CI,
|
||||
llvm::StringRef Filename);
|
||||
virtual void ExecuteAction();
|
||||
virtual void EndSourceFileAction();
|
||||
|
||||
public:
|
||||
/// Construct a WrapperFrontendAction from an existing action, taking
|
||||
/// ownership of it.
|
||||
WrapperFrontendAction(FrontendAction *WrappedAction);
|
||||
|
||||
virtual bool usesPreprocessorOnly() const;
|
||||
virtual bool usesCompleteTranslationUnit();
|
||||
virtual bool hasPCHSupport() const;
|
||||
virtual bool hasASTFileSupport() const;
|
||||
virtual bool hasIRSupport() const;
|
||||
virtual bool hasCodeCompletionSupport() const;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -97,12 +97,6 @@ class SyntaxOnlyAction : public ASTFrontendAction {
|
||||
virtual bool hasCodeCompletionSupport() const { return true; }
|
||||
};
|
||||
|
||||
class BoostConAction : public SyntaxOnlyAction {
|
||||
protected:
|
||||
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
|
||||
llvm::StringRef InFile);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Frontend action adaptor that merges ASTs together.
|
||||
*
|
||||
|
@ -24,7 +24,6 @@ namespace frontend {
|
||||
ASTDumpXML, ///< Parse ASTs and dump them in XML.
|
||||
ASTPrint, ///< Parse ASTs and print them.
|
||||
ASTView, ///< Parse ASTs and view them in Graphviz.
|
||||
BoostCon, ///< BoostCon mode.
|
||||
CreateModule, ///< Create module definition
|
||||
DumpRawTokens, ///< Dump out raw tokens.
|
||||
DumpTokens, ///< Dump out preprocessed tokens.
|
||||
@ -77,6 +76,15 @@ class FrontendOptions {
|
||||
unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are
|
||||
/// unfixable errors.
|
||||
|
||||
enum {
|
||||
ARCMT_None,
|
||||
ARCMT_Check,
|
||||
ARCMT_Modify,
|
||||
ARCMT_Migrate
|
||||
} ARCMTAction;
|
||||
|
||||
std::string ARCMTMigrateDir;
|
||||
|
||||
/// The input files and their types.
|
||||
std::vector<std::pair<InputKind, std::string> > Inputs;
|
||||
|
||||
@ -131,6 +139,7 @@ class FrontendOptions {
|
||||
ShowStats = 0;
|
||||
ShowTimers = 0;
|
||||
ShowVersion = 0;
|
||||
ARCMTAction = ARCMT_None;
|
||||
}
|
||||
|
||||
/// getInputKindForExtension - Return the appropriate input kind for a file
|
||||
|
@ -17,10 +17,12 @@ namespace clang {
|
||||
|
||||
namespace frontend {
|
||||
/// IncludeDirGroup - Identifiers the group a include entry belongs to, which
|
||||
/// represents its relative positive in the search list.
|
||||
/// represents its relative positive in the search list. A #include of a ""
|
||||
/// path starts at the -iquote group, then searches the Angled group, then
|
||||
/// searches the system group, etc.
|
||||
enum IncludeDirGroup {
|
||||
Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`.
|
||||
Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`)
|
||||
Quoted = 0, ///< '#include ""' paths, added by'gcc -iquote'.
|
||||
Angled, ///< Paths for '#include <>' added by '-I'.
|
||||
System, ///< Like Angled, but marks system directories.
|
||||
CXXSystem, ///< Like System, but only used for C++.
|
||||
After ///< Like System, but searched after the system directories.
|
||||
@ -37,15 +39,15 @@ class HeaderSearchOptions {
|
||||
unsigned IsUserSupplied : 1;
|
||||
unsigned IsFramework : 1;
|
||||
|
||||
/// IsSysRootRelative - This is true if an absolute path should be treated
|
||||
/// relative to the sysroot, or false if it should always be the absolute
|
||||
/// IgnoreSysRoot - This is false if an absolute path should be treated
|
||||
/// relative to the sysroot, or true if it should always be the absolute
|
||||
/// path.
|
||||
unsigned IsSysRootRelative : 1;
|
||||
unsigned IgnoreSysRoot : 1;
|
||||
|
||||
Entry(llvm::StringRef path, frontend::IncludeDirGroup group,
|
||||
bool isUserSupplied, bool isFramework, bool isSysRootRelative)
|
||||
bool isUserSupplied, bool isFramework, bool ignoreSysRoot)
|
||||
: Path(path), Group(group), IsUserSupplied(isUserSupplied),
|
||||
IsFramework(isFramework), IsSysRootRelative(isSysRootRelative) {}
|
||||
IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot) {}
|
||||
};
|
||||
|
||||
/// If non-empty, the directory to use as a "virtual system root" for include
|
||||
@ -80,20 +82,23 @@ class HeaderSearchOptions {
|
||||
/// Include the system standard C++ library include search directories.
|
||||
unsigned UseStandardCXXIncludes : 1;
|
||||
|
||||
/// Use libc++ instead of the default libstdc++.
|
||||
unsigned UseLibcxx : 1;
|
||||
|
||||
/// Whether header search information should be output as for -v.
|
||||
unsigned Verbose : 1;
|
||||
|
||||
public:
|
||||
HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
|
||||
: Sysroot(_Sysroot), UseBuiltinIncludes(true),
|
||||
UseStandardIncludes(true), UseStandardCXXIncludes(true),
|
||||
UseStandardIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false),
|
||||
Verbose(false) {}
|
||||
|
||||
/// AddPath - Add the \arg Path path to the specified \arg Group list.
|
||||
void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
|
||||
bool IsUserSupplied, bool IsFramework, bool IsSysRootRelative) {
|
||||
bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot) {
|
||||
UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
|
||||
IsSysRootRelative));
|
||||
IgnoreSysRoot));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- PreprocessorOptionms.h ---------------------------------*- C++ -*-===//
|
||||
//===--- PreprocessorOptions.h ----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -26,6 +26,15 @@ namespace clang {
|
||||
class Preprocessor;
|
||||
class LangOptions;
|
||||
|
||||
/// \brief Enumerate the kinds of standard library that
|
||||
enum ObjCXXARCStandardLibraryKind {
|
||||
ARCXX_nolib,
|
||||
/// \brief libc++
|
||||
ARCXX_libcxx,
|
||||
/// \brief libstdc++
|
||||
ARCXX_libstdcxx
|
||||
};
|
||||
|
||||
/// PreprocessorOptions - This class is used for passing the various options
|
||||
/// used in preprocessor initialization to InitializePreprocessor().
|
||||
class PreprocessorOptions {
|
||||
@ -39,11 +48,11 @@ class PreprocessorOptions {
|
||||
|
||||
unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
|
||||
/// record of all macro definitions and
|
||||
/// instantiations.
|
||||
/// expansions.
|
||||
|
||||
/// \brief Whether the detailed preprocessing record includes nested macro
|
||||
/// instantiations.
|
||||
unsigned DetailedRecordIncludesNestedMacroInstantiations : 1;
|
||||
/// expansions.
|
||||
unsigned DetailedRecordIncludesNestedMacroExpansions : 1;
|
||||
|
||||
/// The implicit PCH included at the start of the translation unit, or empty.
|
||||
std::string ImplicitPCHInclude;
|
||||
@ -104,6 +113,11 @@ class PreprocessorOptions {
|
||||
/// compiler invocation and its buffers will be reused.
|
||||
bool RetainRemappedFileBuffers;
|
||||
|
||||
/// \brief The Objective-C++ ARC standard library that we should support,
|
||||
/// by providing appropriate definitions to retrofit the standard library
|
||||
/// with support for lifetime-qualified pointers.
|
||||
ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary;
|
||||
|
||||
typedef std::vector<std::pair<std::string, std::string> >::iterator
|
||||
remapped_file_iterator;
|
||||
typedef std::vector<std::pair<std::string, std::string> >::const_iterator
|
||||
@ -140,12 +154,13 @@ class PreprocessorOptions {
|
||||
|
||||
public:
|
||||
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
|
||||
DetailedRecordIncludesNestedMacroInstantiations(true),
|
||||
DetailedRecordIncludesNestedMacroExpansions(true),
|
||||
DisablePCHValidation(false), DisableStatCache(false),
|
||||
DumpDeserializedPCHDecls(false),
|
||||
PrecompiledPreambleBytes(0, true),
|
||||
RemappedFilesKeepOriginalName(true),
|
||||
RetainRemappedFileBuffers(false) { }
|
||||
RetainRemappedFileBuffers(false),
|
||||
ObjCXXARCStandardLibrary(ARCXX_nolib) { }
|
||||
|
||||
void addMacroDef(llvm::StringRef Name) {
|
||||
Macros.push_back(std::make_pair(Name, false));
|
||||
|
@ -62,18 +62,17 @@ class TextDiagnosticPrinter : public DiagnosticClient {
|
||||
std::string &CaretLine,
|
||||
const std::string &SourceLine);
|
||||
|
||||
void EmitCaretDiagnostic(Diagnostic::Level Level, SourceLocation Loc,
|
||||
CharSourceRange *Ranges, unsigned NumRanges,
|
||||
const SourceManager &SM,
|
||||
const FixItHint *Hints,
|
||||
unsigned NumHints,
|
||||
unsigned Columns,
|
||||
unsigned OnMacroInst,
|
||||
unsigned MacroSkipStart,
|
||||
unsigned MacroSkipEnd);
|
||||
|
||||
virtual void HandleDiagnostic(Diagnostic::Level Level,
|
||||
const DiagnosticInfo &Info);
|
||||
|
||||
private:
|
||||
void EmitCaretDiagnostic(SourceLocation Loc, CharSourceRange *Ranges,
|
||||
unsigned NumRanges, const SourceManager &SM,
|
||||
const FixItHint *Hints,
|
||||
unsigned NumHints, unsigned Columns,
|
||||
unsigned OnMacroInst, unsigned MacroSkipStart,
|
||||
unsigned MacroSkipEnd);
|
||||
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace llvm {
|
||||
class Triple;
|
||||
|
@ -95,8 +95,8 @@ class Lexer : public PreprocessorLexer {
|
||||
/// _Pragma expansion. This has a variety of magic semantics that this method
|
||||
/// sets up. It returns a new'd Lexer that must be delete'd when done.
|
||||
static Lexer *Create_PragmaLexer(SourceLocation SpellingLoc,
|
||||
SourceLocation InstantiationLocStart,
|
||||
SourceLocation InstantiationLocEnd,
|
||||
SourceLocation ExpansionLocStart,
|
||||
SourceLocation ExpansionLocEnd,
|
||||
unsigned TokLen, Preprocessor &PP);
|
||||
|
||||
|
||||
@ -241,8 +241,8 @@ class Lexer : public PreprocessorLexer {
|
||||
/// is not necessary to copy any data, then the returned string may
|
||||
/// not point into the provided buffer.
|
||||
///
|
||||
/// This method lexes at the instantiation depth of the given
|
||||
/// location and does not jump to the instantiation or spelling
|
||||
/// This method lexes at the expansion depth of the given
|
||||
/// location and does not jump to the expansion or spelling
|
||||
/// location.
|
||||
static llvm::StringRef getSpelling(SourceLocation loc,
|
||||
llvm::SmallVectorImpl<char> &buffer,
|
||||
@ -293,7 +293,19 @@ class Lexer : public PreprocessorLexer {
|
||||
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &Features);
|
||||
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the first
|
||||
/// token of the macro expansion.
|
||||
static bool isAtStartOfMacroExpansion(SourceLocation loc,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts);
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the last
|
||||
/// token of the macro expansion.
|
||||
static bool isAtEndOfMacroExpansion(SourceLocation loc,
|
||||
const SourceManager &SM,
|
||||
const LangOptions &LangOpts);
|
||||
|
||||
/// \brief Compute the preamble of the given file.
|
||||
///
|
||||
/// The preamble of a file contains the initial comments, include directives,
|
||||
|
@ -167,7 +167,9 @@ class StringLiteralParser {
|
||||
bool AnyWide;
|
||||
bool Pascal;
|
||||
|
||||
const char *GetString() { return ResultBuf.data(); }
|
||||
llvm::StringRef GetString() const {
|
||||
return llvm::StringRef(ResultBuf.data(), GetStringLength());
|
||||
}
|
||||
unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); }
|
||||
|
||||
unsigned GetNumStringChars() const {
|
||||
|
@ -43,6 +43,10 @@ class MacroInfo {
|
||||
/// to.
|
||||
llvm::SmallVector<Token, 8> ReplacementTokens;
|
||||
|
||||
/// \brief Length in characters of the macro definition.
|
||||
mutable unsigned DefinitionLength;
|
||||
mutable bool IsDefinitionLengthCached : 1;
|
||||
|
||||
/// IsFunctionLike - True if this macro is a function-like macro, false if it
|
||||
/// is an object-like macro.
|
||||
bool IsFunctionLike : 1;
|
||||
@ -116,6 +120,13 @@ class MacroInfo {
|
||||
/// getDefinitionEndLoc - Return the location of the last token in the macro.
|
||||
///
|
||||
SourceLocation getDefinitionEndLoc() const { return EndLocation; }
|
||||
|
||||
/// \brief Get length in characters of the macro definition.
|
||||
unsigned getDefinitionLength(SourceManager &SM) const {
|
||||
if (IsDefinitionLengthCached)
|
||||
return DefinitionLength;
|
||||
return getDefinitionLengthSlow(SM);
|
||||
}
|
||||
|
||||
/// isIdenticalTo - Return true if the specified macro definition is equal to
|
||||
/// this macro in spelling, arguments, and whitespace. This is used to emit
|
||||
@ -232,6 +243,8 @@ class MacroInfo {
|
||||
/// AddTokenToBody - Add the specified token to the replacement text for the
|
||||
/// macro.
|
||||
void AddTokenToBody(const Token &Tok) {
|
||||
assert(!IsDefinitionLengthCached &&
|
||||
"Changing replacement tokens after definition length got calculated");
|
||||
ReplacementTokens.push_back(Tok);
|
||||
}
|
||||
|
||||
@ -248,6 +261,9 @@ class MacroInfo {
|
||||
assert(!IsDisabled && "Cannot disable an already-disabled macro!");
|
||||
IsDisabled = true;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned getDefinitionLengthSlow(SourceManager &SM) const;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "clang/Lex/DirectoryLookup.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/DiagnosticIDs.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <string>
|
||||
|
||||
@ -124,6 +125,24 @@ class PPCallbacks {
|
||||
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
|
||||
}
|
||||
|
||||
/// PragmaDiagnosticPush - This callback is invoked when a
|
||||
/// #pragma gcc dianostic push directive is read.
|
||||
virtual void PragmaDiagnosticPush(SourceLocation Loc,
|
||||
llvm::StringRef Namespace) {
|
||||
}
|
||||
|
||||
/// PragmaDiagnosticPop - This callback is invoked when a
|
||||
/// #pragma gcc dianostic pop directive is read.
|
||||
virtual void PragmaDiagnosticPop(SourceLocation Loc,
|
||||
llvm::StringRef Namespace) {
|
||||
}
|
||||
|
||||
/// PragmaDiagnostic - This callback is invoked when a
|
||||
/// #pragma gcc dianostic directive is read.
|
||||
virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
|
||||
diag::Mapping mapping, llvm::StringRef Str) {
|
||||
}
|
||||
|
||||
/// MacroExpands - This is called by
|
||||
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
|
||||
/// found.
|
||||
@ -232,6 +251,24 @@ class PPChainedCallbacks : public PPCallbacks {
|
||||
Second->PragmaMessage(Loc, Str);
|
||||
}
|
||||
|
||||
virtual void PragmaDiagnosticPush(SourceLocation Loc,
|
||||
llvm::StringRef Namespace) {
|
||||
First->PragmaDiagnosticPush(Loc, Namespace);
|
||||
Second->PragmaDiagnosticPush(Loc, Namespace);
|
||||
}
|
||||
|
||||
virtual void PragmaDiagnosticPop(SourceLocation Loc,
|
||||
llvm::StringRef Namespace) {
|
||||
First->PragmaDiagnosticPop(Loc, Namespace);
|
||||
Second->PragmaDiagnosticPop(Loc, Namespace);
|
||||
}
|
||||
|
||||
virtual void PragmaDiagnostic(SourceLocation Loc, llvm::StringRef Namespace,
|
||||
diag::Mapping mapping, llvm::StringRef Str) {
|
||||
First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
|
||||
Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
|
||||
}
|
||||
|
||||
virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
|
||||
First->MacroExpands(MacroNameTok, MI);
|
||||
Second->MacroExpands(MacroNameTok, MI);
|
||||
|
@ -38,13 +38,13 @@ namespace clang {
|
||||
class FileEntry;
|
||||
|
||||
/// \brief Base class that describes a preprocessed entity, which may be a
|
||||
/// preprocessor directive or macro instantiation.
|
||||
/// preprocessor directive or macro expansion.
|
||||
class PreprocessedEntity {
|
||||
public:
|
||||
/// \brief The kind of preprocessed entity an object describes.
|
||||
enum EntityKind {
|
||||
/// \brief A macro instantiation.
|
||||
MacroInstantiationKind,
|
||||
/// \brief A macro expansion.
|
||||
MacroExpansionKind,
|
||||
|
||||
/// \brief A preprocessing directive whose kind is not specified.
|
||||
///
|
||||
@ -110,31 +110,31 @@ namespace clang {
|
||||
void operator delete(void* data) throw();
|
||||
};
|
||||
|
||||
/// \brief Records the location of a macro instantiation.
|
||||
class MacroInstantiation : public PreprocessedEntity {
|
||||
/// \brief The name of the macro being instantiation.
|
||||
/// \brief Records the location of a macro expansion.
|
||||
class MacroExpansion : public PreprocessedEntity {
|
||||
/// \brief The name of the macro being expanded.
|
||||
IdentifierInfo *Name;
|
||||
|
||||
/// \brief The definition of this macro.
|
||||
MacroDefinition *Definition;
|
||||
|
||||
public:
|
||||
MacroInstantiation(IdentifierInfo *Name, SourceRange Range,
|
||||
MacroDefinition *Definition)
|
||||
: PreprocessedEntity(MacroInstantiationKind, Range), Name(Name),
|
||||
MacroExpansion(IdentifierInfo *Name, SourceRange Range,
|
||||
MacroDefinition *Definition)
|
||||
: PreprocessedEntity(MacroExpansionKind, Range), Name(Name),
|
||||
Definition(Definition) { }
|
||||
|
||||
/// \brief The name of the macro being instantiated.
|
||||
/// \brief The name of the macro being expanded.
|
||||
IdentifierInfo *getName() const { return Name; }
|
||||
|
||||
/// \brief The definition of the macro being instantiated.
|
||||
/// \brief The definition of the macro being expanded.
|
||||
MacroDefinition *getDefinition() const { return Definition; }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const PreprocessedEntity *PE) {
|
||||
return PE->getKind() == MacroInstantiationKind;
|
||||
return PE->getKind() == MacroExpansionKind;
|
||||
}
|
||||
static bool classof(const MacroInstantiation *) { return true; }
|
||||
static bool classof(const MacroExpansion *) { return true; }
|
||||
|
||||
};
|
||||
|
||||
@ -256,11 +256,11 @@ namespace clang {
|
||||
|
||||
/// \brief A record of the steps taken while preprocessing a source file,
|
||||
/// including the various preprocessing directives processed, macros
|
||||
/// instantiated, etc.
|
||||
/// expanded, etc.
|
||||
class PreprocessingRecord : public PPCallbacks {
|
||||
/// \brief Whether we should include nested macro instantiations in
|
||||
/// \brief Whether we should include nested macro expansions in
|
||||
/// the preprocessing record.
|
||||
bool IncludeNestedMacroInstantiations;
|
||||
bool IncludeNestedMacroExpansions;
|
||||
|
||||
/// \brief Allocator used to store preprocessing objects.
|
||||
llvm::BumpPtrAllocator BumpAlloc;
|
||||
@ -286,7 +286,7 @@ namespace clang {
|
||||
|
||||
public:
|
||||
/// \brief Construct
|
||||
explicit PreprocessingRecord(bool IncludeNestedMacroInstantiations);
|
||||
explicit PreprocessingRecord(bool IncludeNestedMacroExpansions);
|
||||
|
||||
/// \brief Allocate memory in the preprocessing record.
|
||||
void *Allocate(unsigned Size, unsigned Align = 8) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include <vector>
|
||||
|
||||
@ -120,7 +121,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
|
||||
/// Selectors - This table contains all the selectors in the program. Unlike
|
||||
/// IdentifierTable above, this table *isn't* populated by the preprocessor.
|
||||
/// It is declared/instantiated here because it's role/lifetime is
|
||||
/// It is declared/expanded here because it's role/lifetime is
|
||||
/// conceptually similar the IdentifierTable. In addition, the current control
|
||||
/// flow (in clang::ParseAST()), make it convenient to put here.
|
||||
/// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
|
||||
@ -219,9 +220,9 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
/// previous macro value.
|
||||
llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
|
||||
|
||||
/// \brief Instantiation source location for the last macro that expanded
|
||||
/// \brief Expansion source location for the last macro that expanded
|
||||
/// to no tokens.
|
||||
SourceLocation LastEmptyMacroInstantiationLoc;
|
||||
SourceLocation LastEmptyMacroExpansionLoc;
|
||||
|
||||
// Various statistics we track for performance analysis.
|
||||
unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
|
||||
@ -240,7 +241,15 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
unsigned NumCachedTokenLexers;
|
||||
TokenLexer *TokenLexerCache[TokenLexerCacheSize];
|
||||
|
||||
/// \brief A record of the macro definitions and instantiations that
|
||||
/// \brief Keeps macro expanded tokens for TokenLexers.
|
||||
//
|
||||
/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
|
||||
/// going to lex in the cache and when it finishes the tokens are removed
|
||||
/// from the end of the cache.
|
||||
llvm::SmallVector<Token, 16> MacroExpandedTokens;
|
||||
std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
|
||||
|
||||
/// \brief A record of the macro definitions and expansions that
|
||||
/// occurred during preprocessing.
|
||||
///
|
||||
/// This is an optional side structure that can be enabled with
|
||||
@ -371,10 +380,10 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
|
||||
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
|
||||
|
||||
/// \brief Instantiation source location for the last macro that expanded
|
||||
/// \brief Expansion source location for the last macro that expanded
|
||||
/// to no tokens.
|
||||
SourceLocation getLastEmptyMacroInstantiationLoc() const {
|
||||
return LastEmptyMacroInstantiationLoc;
|
||||
SourceLocation getLastEmptyMacroExpansionLoc() const {
|
||||
return LastEmptyMacroExpansionLoc;
|
||||
}
|
||||
|
||||
const std::string &getPredefines() const { return Predefines; }
|
||||
@ -442,7 +451,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
|
||||
/// \brief Create a new preprocessing record, which will keep track of
|
||||
/// all macro expansions, macro definitions, etc.
|
||||
void createPreprocessingRecord(bool IncludeNestedMacroInstantiations);
|
||||
void createPreprocessingRecord(bool IncludeNestedMacroExpansions);
|
||||
|
||||
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
|
||||
/// which implicitly adds the builtin defines etc.
|
||||
@ -658,7 +667,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
|
||||
/// getSpelling() - Return the 'spelling' of the token at the given
|
||||
/// location; does not go up to the spelling location or down to the
|
||||
/// instantiation location.
|
||||
/// expansion location.
|
||||
///
|
||||
/// \param buffer A buffer which will be used only if the token requires
|
||||
/// "cleaning", e.g. if it contains trigraphs or escaped newlines
|
||||
@ -721,7 +730,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
|
||||
/// CreateString - Plop the specified string into a scratch buffer and set the
|
||||
/// specified token's location and length to it. If specified, the source
|
||||
/// location provides a location of the instantiation point of the token.
|
||||
/// location provides a location of the expansion point of the token.
|
||||
void CreateString(const char *Buf, unsigned Len,
|
||||
Token &Tok, SourceLocation SourceLoc = SourceLocation());
|
||||
|
||||
@ -744,6 +753,18 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, Features);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the first
|
||||
/// token of the macro expansion.
|
||||
bool isAtStartOfMacroExpansion(SourceLocation loc) const {
|
||||
return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the given MacroID location points at the last
|
||||
/// token of the macro expansion.
|
||||
bool isAtEndOfMacroExpansion(SourceLocation loc) const {
|
||||
return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features);
|
||||
}
|
||||
|
||||
/// DumpToken - Print the token to stderr, used for debugging.
|
||||
///
|
||||
void DumpToken(const Token &Tok, bool DumpFlags = false) const;
|
||||
@ -770,6 +791,8 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
|
||||
void PrintStats();
|
||||
|
||||
size_t getTotalMemory() const;
|
||||
|
||||
/// HandleMicrosoftCommentPaste - When the macro expander pastes together a
|
||||
/// comment (/##/) in microsoft mode, this method handles updating the current
|
||||
/// state, returning the token on the next source line.
|
||||
@ -977,6 +1000,16 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
/// the macro should not be expanded return true, otherwise return false.
|
||||
bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI);
|
||||
|
||||
/// \brief Cache macro expanded tokens for TokenLexers.
|
||||
//
|
||||
/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
|
||||
/// going to lex in the cache and when it finishes the tokens are removed
|
||||
/// from the end of the cache.
|
||||
Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
|
||||
llvm::ArrayRef<Token> tokens);
|
||||
void removeCachedMacroExpandedTokensOfLastLexer();
|
||||
friend void TokenLexer::ExpandFunctionArguments();
|
||||
|
||||
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
|
||||
/// lexed is a '('. If so, consume the token and return true, if not, this
|
||||
/// method should have no observable side-effect on the lexed tokens.
|
||||
@ -986,7 +1019,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||
/// invoked to read all of the formal arguments specified for the macro
|
||||
/// invocation. This returns null on error.
|
||||
MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
|
||||
SourceLocation &InstantiationEnd);
|
||||
SourceLocation &ExpansionEnd);
|
||||
|
||||
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
|
||||
/// as a builtin macro, handle it and return the next token as 'Tok'.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user