Vendor import of clang trunk r135360:

http://llvm.org/svn/llvm-project/cfe/trunk@135360
This commit is contained in:
Dimitry Andric 2011-07-17 15:40:56 +00:00
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
788 changed files with 45145 additions and 11225 deletions

View File

@ -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
View 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
View 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
View 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
View 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;
}

View 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;
}

View File

@ -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:

View File

@ -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]

View 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

View File

@ -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])

View File

@ -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 */,

File diff suppressed because it is too large Load Diff

View File

@ -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) {

View File

@ -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.

View File

@ -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 &amp; Pipelining</h4>

View File

@ -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

View File

@ -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(&lt;stdint.h&gt;)
#if __has_include("myinclude.h") &amp;&amp; __has_include(&lt;stdint.h&gt;)
# 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) &amp;&amp; __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(&lt;stdint.h&gt;)
#if __has_include_next("myinclude.h") &amp;&amp; __has_include_next(&lt;stdint.h&gt;)
# 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) &amp;&amp; __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>&amp;</code> or <code>&amp;&amp;</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(&amp;value, new_value);
</pre>
<p><b>Description:</b></p>

View File

@ -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

View File

@ -1,4 +0,0 @@
<title>'clang' C frontend documentation</title>
None yet, sorry :(

View File

@ -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);
/**
* @}
*/

View 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

View 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

View 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

View File

@ -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 {

View File

@ -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

View File

@ -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.
///

View File

@ -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,

View File

@ -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());

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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, { })

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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.
///

View File

@ -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());

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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"];
}

View File

@ -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)

View File

@ -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) &&

View File

@ -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", "")

View 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

View File

@ -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;
}
};
//===----------------------------------------------------------------------===//

View 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

View File

@ -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

View File

@ -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">;

View File

@ -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">;

View File

@ -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">;

View File

@ -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;
};

View File

@ -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">;

View File

@ -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">;

View File

@ -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<

View File

@ -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 {

View File

@ -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

View File

@ -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; }

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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>;

View File

@ -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;
};

View File

@ -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)

View File

@ -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>;

View File

@ -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);
}

View File

@ -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">,

View File

@ -14,7 +14,6 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class raw_ostream;

View File

@ -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

View 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

View File

@ -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();
}

View File

@ -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">;

View File

@ -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.

View File

@ -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.
///

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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.

View File

@ -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

View File

@ -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.
*

View File

@ -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

View 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));
}
};

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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