Vendor import of clang trunk r132879:

http://llvm.org/svn/llvm-project/cfe/trunk@132879
This commit is contained in:
Dimitry Andric 2011-06-12 15:46:16 +00:00
parent 01af97d3b2
commit 29cafa66ad
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=223015
svn path=/vendor/clang/clang-r132879/; revision=223016; tag=vendor/clang/clang-r132879
603 changed files with 21534 additions and 8383 deletions

View File

@ -57,6 +57,13 @@ set(CLANG_RESOURCE_DIR "" CACHE STRING
set(C_INCLUDE_DIRS "" CACHE STRING
"Colon separated list of directories clang will search for headers.")
set(CLANG_VENDOR "" CACHE STRING
"Vendor-specific text for showing with version information.")
if( CLANG_VENDOR )
add_definitions( -DCLANG_VENDOR="${CLANG_VENDOR} " )
endif()
set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
@ -103,7 +110,7 @@ configure_file(
${CMAKE_CURRENT_BINARY_DIR}/include/clang/Basic/Version.inc)
# Add appropriate flags for GCC
if (CMAKE_COMPILER_IS_GNUCXX)
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings")
endif ()

View File

@ -6,6 +6,12 @@
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
BD6B0EDF13A1824C00B8E3FE /* Mangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD6B0EDE13A1824C00B8E3FE /* Mangle.cpp */; };
BD6B0EE213A182A600B8E3FE /* ItaniumMangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD6B0EE113A182A600B8E3FE /* ItaniumMangle.cpp */; };
BD6B0EE413A182DA00B8E3FE /* MicrosoftMangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BD6B0EE313A182DA00B8E3FE /* MicrosoftMangle.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@ -472,6 +478,9 @@
BD59A952121496B9003A5A02 /* SemaConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaConsumer.h; path = clang/Sema/SemaConsumer.h; sourceTree = "<group>"; };
BD59A953121496B9003A5A02 /* SemaDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaDiagnostic.h; path = clang/Sema/SemaDiagnostic.h; sourceTree = "<group>"; };
BD59A954121496B9003A5A02 /* Template.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Template.h; path = clang/Sema/Template.h; sourceTree = "<group>"; };
BD6B0EDE13A1824C00B8E3FE /* Mangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mangle.cpp; sourceTree = "<group>"; };
BD6B0EE113A182A600B8E3FE /* ItaniumMangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ItaniumMangle.cpp; sourceTree = "<group>"; };
BD6B0EE313A182DA00B8E3FE /* MicrosoftMangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MicrosoftMangle.cpp; sourceTree = "<group>"; };
BDF87CF60FD746F300BBF872 /* SemaTemplateDeduction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateDeduction.cpp; path = lib/Sema/SemaTemplateDeduction.cpp; sourceTree = "<group>"; tabWidth = 2; };
BF89C3E111595818001C2D68 /* AnalysisBasedWarnings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisBasedWarnings.cpp; path = lib/Sema/AnalysisBasedWarnings.cpp; sourceTree = "<group>"; };
BF89C3E5115958A1001C2D68 /* TargetAttributesSema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TargetAttributesSema.h; path = lib/Sema/TargetAttributesSema.h; sourceTree = "<group>"; };
@ -1514,6 +1523,9 @@
DEC8D9920A9433F400353FCA /* AST */ = {
isa = PBXGroup;
children = (
BD6B0EDE13A1824C00B8E3FE /* Mangle.cpp */,
BD6B0EE313A182DA00B8E3FE /* MicrosoftMangle.cpp */,
BD6B0EE113A182A600B8E3FE /* ItaniumMangle.cpp */,
BF9FEE051225E770003A8B71 /* MicrosoftCXXABI.cpp */,
BF9FEE031225E759003A8B71 /* ItaniumCXXABI.cpp */,
BF9FEE011225E73F003A8B71 /* ExprClassification.cpp */,
@ -1900,6 +1912,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BD6B0EDF13A1824C00B8E3FE /* Mangle.cpp in Sources */,
BD6B0EE213A182A600B8E3FE /* ItaniumMangle.cpp in Sources */,
BD6B0EE413A182DA00B8E3FE /* MicrosoftMangle.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -32,28 +32,42 @@ td {
</ul>
<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a></li>
<ul>
<li><a href="#cxx_attributes">C++0x attributes</a></li>
<li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
<li><a href="#cxx_default_function_template_args">C++0x default template arguments in function templates</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>
<li><a href="#cxx_override_control">C++0x override control</a></li>
<li><a href="#cxx_range_for">C++0x range-based for loop</a></li>
<li><a href="#cxx_rvalue_references">C++0x rvalue references</a></li>
<li><a href="#cxx_reference_qualified_functions">C++0x reference-qualified functions</a></li>
<li><a href="#cxx_static_assert">C++0x <tt>static_assert()</tt></a></li>
<li><a href="#cxx_auto_type">C++0x type inference</a></li>
<li><a href="#cxx_variadic_templates">C++0x variadic templates</a></li>
<li><a href="#cxx_inline_namespaces">C++0x inline namespaces</a></li>
<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>
<li><a href="#cxx0x">C++0x</a>
<ul>
<li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
<li><a href="#cxx_access_control_sfinae">C++0x SFINAE includes access control</a></li>
<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_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>
<li><a href="#cxx_override_control">C++0x override control</a></li>
<li><a href="#cxx_range_for">C++0x range-based for loop</a></li>
<li><a href="#cxx_rvalue_references">C++0x rvalue references</a></li>
<li><a href="#cxx_reference_qualified_functions">C++0x reference-qualified functions</a></li>
<li><a href="#cxx_static_assert">C++0x <tt>static_assert()</tt></a></li>
<li><a href="#cxx_auto_type">C++0x type inference</a></li>
<li><a href="#cxx_variadic_templates">C++0x variadic templates</a></li>
<li><a href="#cxx_inline_namespaces">C++0x inline namespaces</a></li>
<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>
<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>
<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>
</ul>
</li>
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
<li><a href="#generic-selections">Generic Selections</a></li>
<li><a href="#builtins">Builtin Functions</a>
<ul>
<li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
@ -115,28 +129,48 @@ not. It can be used like this:</p>
<!-- ======================================================================= -->
<h3 id="__has_feature">__has_feature</h3>
<h3 id="__has_feature_extension">__has_feature and __has_extension</h3>
<!-- ======================================================================= -->
<p>This function-like macro takes a single identifier argument that is the name
of a feature. It evaluates to 1 if the feature is supported or 0 if not. It
can be used like this:</p>
<p>These function-like macros take a single identifier argument that is the
name of a feature. <code>__has_feature</code> evaluates to 1 if the feature
is both supported by Clang and standardized in the current language standard
or 0 if not (but see <a href="#has_feature_back_compat">below</a>), while
<code>__has_extension</code> evaluates to 1 if the feature is supported by
Clang in the current language (either as a language extension or a standard
language feature) or 0 if not. They can be used like this:</p>
<blockquote>
<pre>
#ifndef __has_feature // Optional of course.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
...
#if __has_feature(attribute_overloadable) || \
__has_feature(blocks)
...
#if __has_feature(cxx_rvalue_references)
// This code will only be compiled with the -std=c++0x and -std=gnu++0x
// options, because rvalue references are only standardized in C++0x.
#endif
#if __has_extension(cxx_rvalue_references)
// This code will be compiled with the -std=c++0x, -std=gnu++0x, -std=c++98
// and -std=gnu++98 options, because rvalue references are supported as a
// language extension in C++98.
#endif
...
</pre>
</blockquote>
<p id="has_feature_back_compat">For backwards compatibility reasons,
<code>__has_feature</code> can also be used to test for support for
non-standardized features, i.e. features not prefixed <code>c_</code>,
<code>cxx_</code> or <code>objc_</code>.</p>
<p>If the <code>-pedantic-errors</code> option is given,
<code>__has_extension</code> is equivalent to <code>__has_feature</code>.</p>
<p>The feature tag is described along with the language feature below.</p>
<!-- ======================================================================= -->
@ -293,7 +327,7 @@ float4 foo(float2 a, float2 b) {
</pre>
</blockquote>
<p>Query for this feature with __has_feature(attribute_ext_vector_type).</p>
<p>Query for this feature with __has_extension(attribute_ext_vector_type).</p>
<p>See also <a href="#__builtin_shufflevector">__builtin_shufflevector</a>.</p>
@ -318,8 +352,8 @@ will be incorporated into the appropriate diagnostic:</p>
</blockquote>
<p>Query for this feature
with <tt>__has_feature(attribute_deprecated_with_message)</tt>
and <tt>__has_feature(attribute_unavailable_with_message)</tt>.</p>
with <tt>__has_extension(attribute_deprecated_with_message)</tt>
and <tt>__has_extension(attribute_unavailable_with_message)</tt>.</p>
<!-- ======================================================================= -->
<h2 id="attributes-on-enumerators">Attributes on Enumerators</h2>
@ -342,7 +376,7 @@ initializer, like so:</p>
<p>Attributes on the <tt>enum</tt> declaration do not apply to
individual enumerators.</p>
<p>Query for this feature with <tt>__has_feature(enumerator_attributes)</tt>.</p>
<p>Query for this feature with <tt>__has_extension(enumerator_attributes)</tt>.</p>
<!-- ======================================================================= -->
<h2 id="checking_language_features">Checks for Standard Language Features</h2>
@ -365,106 +399,165 @@ compiling code with <tt>-fno-rtti</tt> disables the use of RTTI.</p>
<h2 id="checking_upcoming_features">Checks for Upcoming Standard Language Features</h2>
<!-- ======================================================================= -->
<p>The <tt>__has_feature</tt> macro can be used to query if certain upcoming
standard language features are enabled. Those features are listed here.</p>
<p>The <tt>__has_feature</tt> or <tt>__has_extension</tt> macros can be used
to query if certain upcoming standard language features are enabled. Those
features are listed here. Features that are not yet implemented will be
noted.</p>
<p>Currently, all features listed here are slated for inclusion in the upcoming
C++0x standard. As a result, all the features that clang supports are enabled
with the <tt>-std=c++0x</tt> option when compiling C++ code. Features that are
not yet implemented will be noted.</p>
<h3 id="cxx0x">C++0x</h3>
<h3 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
<p>The features listed below are slated for inclusion in the upcoming
C++0x standard. As a result, all these features are enabled
with the <tt>-std=c++0x</tt> option when compiling C++ code.</p>
<p>Use <tt>__has_feature(cxx_decltype)</tt> to determine if support for the
<h4 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
<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>
<h3 id="cxx_attributes">C++0x attributes</h3>
<h4 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h3>
<p>Use <tt>__has_feature(cxx_attributes)</tt> to determine if support for
attribute parsing with C++0x's square bracket notation is enabled.</p>
<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>
<h3 id="cxx_default_function_template_args">C++0x default template arguments in function templates</h3>
<h4 id="cxx_alias_templates">C++0x alias templates</h3>
<p>Use <tt>__has_feature(cxx_default_function_template_args)</tt> to determine if support for default template arguments in function templates is enabled.</p>
<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>
<h3 id="cxx_deleted_functions">C++0x deleted functions</tt></h3>
<h4 id="cxx_attributes">C++0x attributes</h3>
<p>Use <tt>__has_feature(cxx_deleted_functions)</tt> to determine if support for
<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>
<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>
<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>
<h3 id="cxx_lambdas">C++0x lambdas</h3>
<h4 id="cxx_lambdas">C++0x lambdas</h3>
<p>Use <tt>__has_feature(cxx_lambdas)</tt> to determine if support for
lambdas is enabled. clang does not currently implement this feature.</p>
<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>
<h3 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
<h4 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
<p>Use <tt>__has_feature(cxx_nullptr)</tt> to determine if support for
<tt>nullptr</tt> is enabled. clang does not yet fully implement this
feature.</p>
<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>
<h3 id="cxx_override_control">C++0x <tt>override control</tt></h3>
<h4 id="cxx_override_control">C++0x <tt>override control</tt></h3>
<p>Use <tt>__has_feature(cxx_override_control)</tt> to determine if support for
<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>
<h3 id="cxx_reference_qualified_functions">C++0x reference-qualified functions</h3>
<p>Use <tt>__has_feature(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_reference_qualified_functions">C++0x reference-qualified functions</h3>
<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>
<h3 id="cxx_range_for">C++0x range-based for loop</tt></h3>
<h4 id="cxx_range_for">C++0x range-based for loop</tt></h3>
<p>Use <tt>__has_feature(cxx_range_for)</tt> to determine if support for
the range-based for loop is enabled. </p>
<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>
<h3 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
<h4 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> to determine if support for
<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>
<h3 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
<h4 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
<p>Use <tt>__has_feature(cxx_static_assert)</tt> to determine if support for
<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>
<h3 id="cxx_auto_type">C++0x type inference</h3>
<h4 id="cxx_auto_type">C++0x type inference</h3>
<p>Use <tt>__has_feature(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>
<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>
<h3 id="cxx_variadic_templates">C++0x variadic templates</h3>
<h4 id="cxx_variadic_templates">C++0x variadic templates</h3>
<p>Use <tt>__has_feature(cxx_variadic_templates)</tt> to determine if support
<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>
<h3 id="cxx_inline_namespaces">C++0x inline namespaces</h3>
<h4 id="cxx_inline_namespaces">C++0x inline namespaces</h3>
<p>Use <tt>__has_feature(cxx_inline_namespaces)</tt> to determine if support for
<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>
<h3 id="cxx_trailing_return">C++0x trailing return type</h3>
<h4 id="cxx_trailing_return">C++0x trailing return type</h3>
<p>Use <tt>__has_feature(cxx_trailing_return)</tt> to determine if support for
the alternate function declaration syntax with trailing return type is enabled.</p>
<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>
<h3 id="cxx_noexcept">C++0x noexcept</h3>
<h4 id="cxx_noexcept">C++0x noexcept</h3>
<p>Use <tt>__has_feature(cxx_noexcept)</tt> to determine if support for
noexcept exception specifications is enabled.</p>
<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>
<h3 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
<h4 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
<p>Use <tt>__has_feature(cxx_strong_enums)</tt> to determine if support for
<p>Use <tt>__has_feature(cxx_strong_enums)</tt> or
<tt>__has_extension(cxx_strong_enums)</tt> to determine if support for
strongly typed, scoped enumerations is enabled.</p>
<h3 id="c1x">C1X</h3>
<p>The features listed below are slated for inclusion in the upcoming
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>
<p>Use <tt>__has_feature(c_generic_selections)</tt> or
<tt>__has_extension(c_generic_selections)</tt> to determine if support for
generic selections is enabled.</p>
<p>As an extension, the C1X generic selection expression is available in all
languages supported by Clang. The syntax is the same as that given in the
C1X draft standard.</p>
<p>In C, type compatibility is decided according to the rules given in the
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>
<p>Use <tt>__has_feature(c_static_assert)</tt> or
<tt>__has_extension(c_static_assert)</tt> to determine if support for
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_feature(X)</code> indicates the presence of the type trait. For example:
<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:
<blockquote>
<pre>
#if __has_feature(is_convertible_to)
#if __has_extension(is_convertible_to)
template&lt;typename From, typename To&gt;
struct is_convertible_to {
static const bool value = __is_convertible_to(From, To);
@ -507,7 +600,74 @@ details for the clang implementation are in <a
href="Block-ABI-Apple.txt">Block-ABI-Apple.txt</a>.</p>
<p>Query for this feature with __has_feature(blocks).</p>
<p>Query for this feature with __has_extension(blocks).</p>
<!-- ======================================================================= -->
<h2 id="objc_features">Objective-C Features</h2>
<!-- ======================================================================= -->
<h3 id="objc_instancetype">Related result types</h3>
<p>According to Cocoa conventions, Objective-C methods with certain names ("init", "alloc", etc.) always return objects that are an instance of the receiving class's type. Such methods are said to have a "related result type", meaning that a message send to one of these methods will have the same static type as an instance of the receiver class. For example, given the following classes:</p>
<blockquote>
<pre>
@interface NSObject
+ (id)alloc;
- (id)init;
@end
@interface NSArray : NSObject
@end
</pre>
</blockquote>
<p>and this common initialization pattern</p>
<blockquote>
<pre>
NSArray *array = [[NSArray alloc] init];
</pre>
</blockquote>
<p>the type of the expression <code>[NSArray alloc]</code> is
<code>NSArray*</code> because <code>alloc</code> implicitly has a
related result type. Similarly, the type of the expression
<code>[[NSArray alloc] init]</code> is <code>NSArray*</code>, since
<code>init</code> has a related result type and its receiver is known
to have the type <code>NSArray *</code>. If neither <code>alloc</code> nor <code>init</code> had a related result type, the expressions would have had type <code>id</code>, as declared in the method signature.</p>
<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
<ul>
<li>the first word is "alloc" or "new", and the method is a class
method, or</li>
<li>the first word is "autorelease", "init", "retain", or "self",
and the method is an instance method.</li>
</ul></p>
<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
with the subclass type. For example:</p>
<blockquote>
<pre>
@interface NSString : NSObject
- (NSUnrelated *)init; // incorrect usage: NSUnrelated is not NSString or a superclass of NSString
@end
</pre>
</blockquote>
<p>Related result types only affect the type of a message send or
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="overloading-in-c">Function Overloading in C</h2>
@ -607,23 +767,9 @@ caveats to this use of name mangling:</p>
C.</li>
</ul>
<p>Query for this feature with __has_feature(attribute_overloadable).</p>
<p>Query for this feature with __has_extension(attribute_overloadable).</p>
<!-- ======================================================================= -->
<h2 id="generic-selections">Generic Selections</h2>
<!-- ======================================================================= -->
<p>The C1X generic selection expression is available in all languages
supported by Clang. The syntax is the same as that given in the C1X draft
standard.</p>
<p>In C, type compatibility is decided according to the rules given in the
appropriate standard, but in C++, which lacks the type compatibility rules
used in C, types are considered compatible only if they are equivalent.</p>
<p>Query for this feature with __has_feature(generic_selections).</p>
<!-- ======================================================================= -->
<h2 id="builtins">Builtin Functions</h2>
<!-- ======================================================================= -->

View File

@ -16,10 +16,10 @@ DOXYGEN = doxygen
$(PROJ_OBJ_DIR)/doxygen.cfg: doxygen.cfg.in
cat $< | sed \
-e 's/@abs_top_srcdir@/../g' \
-e 's/@abs_srcdir@/./g' \
-e 's/@DOT@/dot/g' \
-e 's/@PACKAGE_VERSION@/mainline/' \
-e 's/@abs_top_builddir@/../g' > $@
-e 's/@abs_builddir@/./g' > $@
endif
include $(CLANG_LEVEL)/Makefile

View File

@ -273,6 +273,35 @@ when this is enabled, Clang will print something like:
</pre>
</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-format"><b>-fdiagnostics-format=clang/msvc/vi</b>:
Changes diagnostic output format to better match IDEs and command line tools.</dt>
<dd>This option controls the output format of the filename, line number, and column printed in diagnostic messages. The options, and their affect on formatting a simple conversion diagnostic, follow:
<dl>
<dt><b>clang</b> (default)</dt>
<dd>
<pre>t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
<dt><b>msvc</b></dt>
<dd>
<pre>t.c(3,11) : warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
<dt><b>vi</b></dt>
<dd>
<pre>t.c +3:11: warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
</dl>
</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-show-name"><b>-f[no-]diagnostics-show-name</b>:
Enable the display of the diagnostic name.</dt>
<dd>This option, which defaults to off, controls whether or not
Clang prints the associated name.</dd>
<br>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-show-option"><b>-f[no-]diagnostics-show-option</b>:
Enable <tt>[-Woption]</tt> information in diagnostic line.</dt>
<dd>This option, which defaults to on,
@ -499,6 +528,8 @@ it:</p>
<li>A categorization of the diagnostic as a note, warning, error, or fatal
error.</li>
<li>A text string that describes what the problem is.</li>
<li>An option that indicates whether to print the diagnostic name [<a
href="#opt_fdiagnostics-show-name">-fdiagnostics-show-name</a>].</li>
<li>An option that indicates how to control the diagnostic (for diagnostics that
support it) [<a
href="#opt_fdiagnostics-show-option">-fdiagnostics-show-option</a>].</li>

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ PROJECT_NUMBER = @PACKAGE_VERSION@
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = @abs_top_builddir@/docs/doxygen
OUTPUT_DIRECTORY = @abs_builddir@/doxygen
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@ -450,9 +450,9 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @abs_top_srcdir@/include \
@abs_top_srcdir@/lib \
@abs_top_srcdir@/docs/doxygen.intro
INPUT = @abs_srcdir@/../include \
@abs_srcdir@/../lib \
@abs_srcdir@/doxygen.intro
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -493,7 +493,7 @@ EXCLUDE_PATTERNS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = @abs_top_srcdir@/examples
EXAMPLE_PATH = @abs_srcdir@/../examples
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -513,7 +513,7 @@ EXAMPLE_RECURSIVE = YES
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = @abs_top_srcdir@/docs/img
IMAGE_PATH = @abs_srcdir@/img
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -636,13 +636,13 @@ HTML_FILE_EXTENSION = .html
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER = @abs_top_srcdir@/docs/doxygen.header
HTML_HEADER = @abs_srcdir@/doxygen.header
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER = @abs_top_srcdir@/docs/doxygen.footer
HTML_FOOTER = @abs_srcdir@/doxygen.footer
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
@ -651,7 +651,7 @@ HTML_FOOTER = @abs_top_srcdir@/docs/doxygen.footer
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET = @abs_top_srcdir@/docs/doxygen.css
HTML_STYLESHEET = @abs_srcdir@/doxygen.css
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to

View File

@ -1,267 +0,0 @@
<html>
<head>
<title>The Index Library</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>
<!--#include virtual="../menu.html.incl"-->
<div id="content">
<h1>The Index Library</h1>
<p><b>Table of Contents</b></p>
<ul>
<li><a href="#philosophy">Design Philosophy</a></li>
<li><a href="#classes">Classes</a>
<ul>
<li><a href="#entity">Entity</a></li>
<li><a href="#astlocation">ASTLocation</a></li>
<li><a href="#declreferencemap">DeclReferenceMap</a></li>
</ul>
</li>
<li><a href="#functions">Functions</a>
<ul>
<li><a href="#resolveloc">ResolveLocationInAST</a></li>
</ul>
</li>
<li><a href="#astfiles">AST Files</a></li>
<li><a href="#indextest">index-test tool</a>
<ul>
<li><a href="#indextestusage">Usage</a></li>
<li><a href="#indextestexamples">Examples</a></li>
</ul>
</li>
</ul>
<h2 id="philosophy">Design Philosophy</h2>
<p> The Index library is meant to provide the basic infrastructure for
cross-translation-unit analysis and is primarily focused on indexing
related functionality. It provides an API for clients that need to
accurately map the AST nodes of the ASTContext to the locations in the source files.
It also allows them to analyze information across multiple translation units.</p>
<p>As a "general rule", ASTContexts are considered the primary source of
information that a client wants about a translation unit. There will be no such class as an
"indexing database" that stores, for example, source locations of identifiers separately from ASTContext.
All the information that a client needs from a translation unit will be extracted from the ASTContext.</p>
<h2 id="classes">Classes</h2>
<h3 id="entity">Entity</h3>
<p>To be able to reason about semantically the same Decls that are contained in multiple ASTContexts, the 'Entity' class was introduced.
An Entity is an ASTContext-independent "token" that can be created from a Decl (and a typename in the future) with
the purpose to "resolve" it into a Decl belonging to another ASTContext. Some examples to make the concept of Entities more clear:</p>
<p>
t1.c:
<pre class="code_example">
void foo(void);
void bar(void);
</pre>
</p>
<p>
t2.c:
<pre class="code_example">
void foo(void) {
}
</pre>
</p>
<p>
Translation unit <code>t1.c</code> contains 2 Entities <code>foo</code> and <code>bar</code>, while <code>t2.c</code> contains 1 Entity <code>foo</code>.
Entities are uniqued in such a way that the Entity* pointer for <code>t1.c/foo</code> is the same as the Entity* pointer for <code>t2.c/foo</code>.
An Entity doesn't convey any information about the declaration, it is more like an opaque pointer used only to get the
associated Decl out of an ASTContext so that the actual information for the declaration can be accessed.
Another important aspect of Entities is that they can only be created/associated for declarations that are visible outside the
translation unit. This means that for:
</p>
<p>
t3.c:
<pre class="code_example">
static void foo(void);
</pre>
</p>
<p>
there can be no Entity (if you ask for the Entity* of the static function <code>foo</code> you'll get a null pointer).
This is for 2 reasons:
<ul>
<li>To preserve the invariant that the same Entity* pointers refer to the same semantic Decls.
In the above example <code>t1.c/foo</code> and <code>t2.c/foo</code> are the same, while <code>t3.c/foo</code> is different.</li>
<li>The purpose of Entity is to get the same semantic Decl from multiple ASTContexts. For a Decl that is not visible
outside of its own translation unit, you don't need an Entity since it won't appear in another ASTContext.</li>
</ul>
</p>
<h3 id="astlocation">ASTLocation</h3>
Encapsulates a "point" in the AST tree of the ASTContext.
It represents either a Decl*, or a Stmt* along with its immediate Decl* parent.
An example for its usage is that libIndex will provide the references of <code>foo</code> in the form of ASTLocations,
"pointing" at the expressions that reference <code>foo</code>.
<h3 id="declreferencemap">DeclReferenceMap</h3>
Accepts an ASTContext and creates a mapping from NamedDecls to the ASTLocations that reference them (in the same ASTContext).
<h2 id="functions">Functions</h2>
<h3 id="resolveloc">ResolveLocationInAST</h3>
A function that accepts an ASTContext and a SourceLocation which it resolves into an ASTLocation.
<h2 id="astfiles">AST Files</h2>
The precompiled headers implementation of clang (<a href="http://clang.llvm.org/docs/PCHInternals.html">PCH</a>) is ideal for storing an ASTContext in a compact form that
will be loaded later for AST analysis. An "AST file" refers to a translation unit that was "compiled" into a precompiled header file.
<h2 id="indextest">index-test tool</h2>
<h3 id="indextestusage">Usage</h3>
A command-line tool that exercises the libIndex API, useful for testing its features.
As input it accepts multiple AST files (representing multiple translation units) and a few options:
<p>
<pre class="code_example">
-point-at [file:line:column]
</pre>
Resolves a [file:line:column] triplet into a ASTLocation from the first AST file. If no other option is specified, it prints the ASTLocation.
It also prints a declaration's associated doxygen comment, if one is available.
</p>
<p>
<pre class="code_example">
-print-refs
</pre>
Prints the ASTLocations that reference the declaration that was resolved out of the [file:line:column] triplet
</p>
<p>
<pre class="code_example">
-print-defs
</pre>
Prints the ASTLocations that define the resolved declaration
</p>
<p>
<pre class="code_example">
-print-decls
</pre>
Prints the ASTLocations that declare the resolved declaration
</p>
<h3 id="indextestexamples">Examples</h3>
<p>
Here's an example of using index-test:
</p>
<p>
We have 3 files,
</p>
<p>
foo.h:
<pre class="code_example">
extern int global_var;
void foo_func(int param1);
void bar_func(void);
</pre>
t1.c:
<pre class="code_example">
#include "foo.h"
void foo_func(int param1) {
int local_var = global_var;
for (int for_var = 100; for_var < 500; ++for_var) {
local_var = param1 + for_var;
}
bar_func();
}
</pre>
t2.c:
<pre class="code_example">
#include "foo.h"
int global_var = 10;
void bar_func(void) {
global_var += 100;
foo_func(global_var);
}
</pre>
</p>
<p>
You first get AST files out of <code>t1.c</code> and <code>t2.c</code>:
<pre class="code_example">
$ clang -emit-ast t1.c -o t1.ast
$ clang -emit-ast t2.c -o t2.ast
</pre>
</p>
<p>
Find the ASTLocation under this position of <code>t1.c</code>:
<pre class="code_example">
[...]
void foo_func(int param1) {
int local_var = global_var;
^
[...]
</pre>
<pre class="code_example">
$ index-test t1.ast -point-at t1.c:4:23
> [Decl: Var local_var | Stmt: DeclRefExpr global_var] &lt;t1.c:4:19, t1.c:4:19>
</pre>
</p>
<p>
Find the declaration:
<pre class="code_example">
$ index-test t1.ast -point-at t1.c:4:23 -print-decls
> [Decl: Var global_var] &lt;foo.h:1:12, foo.h:1:12>
</pre>
</p>
<p>
Find the references:
<pre class="code_example">
$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-refs
> [Decl: Var local_var | Stmt: DeclRefExpr global_var] &lt;t1.c:4:19, t1.c:4:19>
> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] &lt;t2.c:6:3, t2.c:6:3>
> [Decl: Function bar_func | Stmt: DeclRefExpr global_var] &lt;t2.c:7:12, t2.c:7:12>
</pre>
</p>
<p>
Find definitions:
<pre class="code_example">
$ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-defs
> [Decl: Var global_var] &lt;t2.c:3:5, t2.c:3:18>
</pre>
</p>
</div>
</body>
</html>

View File

@ -1,3 +1,2 @@
add_subdirectory(clang-interpreter)
add_subdirectory(PrintFunctionNames)
add_subdirectory(Tooling)

View File

@ -1,6 +0,0 @@
set(LLVM_USED_LIBS clangTooling clangBasic)
add_clang_executable(clang-check
ClangCheck.cpp
)

View File

@ -1,108 +0,0 @@
//===- examples/Tooling/ClangCheck.cpp - Clang check tool -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a clang-check tool that runs the
// clang::SyntaxOnlyAction over a number of translation units.
//
// Usage:
// clang-check <cmake-output-dir> <file1> <file2> ...
//
// Where <cmake-output-dir> is a CMake build directory in which a file named
// compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
// CMake to get this output).
//
// <file1> ... specify the paths of files in the CMake source tree. This path
// is looked up in the compile command database. If the path of a file is
// absolute, it needs to point into CMake's source tree. If the path is
// relative, the current working directory needs to be in the CMake source
// tree and the file must be in a subdirectory of the current working
// directory. "./" prefixes in the relative files will be automatically
// removed, but the rest of a relative path must be a suffix of a path in
// the compile command line database.
//
// For example, to use clang-check on all files in a subtree of the source
// tree, use:
//
// /path/in/subtree $ find . -name '*.cpp'| xargs clang-check /path/to/source
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
/// \brief Returns the absolute path of 'File', by prepending it with
/// 'BaseDirectory' if 'File' is not absolute. Otherwise returns 'File'.
/// If 'File' starts with "./", the returned path will not contain the "./".
/// Otherwise, the returned path will contain the literal path-concatenation of
/// 'BaseDirectory' and 'File'.
///
/// \param File Either an absolute or relative path.
/// \param BaseDirectory An absolute path.
///
/// FIXME: Put this somewhere where it is more generally available.
static std::string GetAbsolutePath(
llvm::StringRef File, llvm::StringRef BaseDirectory) {
assert(llvm::sys::path::is_absolute(BaseDirectory));
if (llvm::sys::path::is_absolute(File)) {
return File;
}
llvm::StringRef RelativePath(File);
if (RelativePath.startswith("./")) {
RelativePath = RelativePath.substr(strlen("./"));
}
llvm::SmallString<1024> AbsolutePath(BaseDirectory);
llvm::sys::path::append(AbsolutePath, RelativePath);
return AbsolutePath.str();
}
int main(int argc, char **argv) {
if (argc < 3) {
llvm::outs() << "Usage: " << argv[0] << " <cmake-output-dir> "
<< "<file1> <file2> ...\n";
return 1;
}
// FIXME: We should pull how to find the database into the Tooling package.
llvm::OwningPtr<llvm::MemoryBuffer> JsonDatabase;
llvm::SmallString<1024> JsonDatabasePath(argv[1]);
llvm::sys::path::append(JsonDatabasePath, "compile_commands.json");
llvm::error_code Result =
llvm::MemoryBuffer::getFile(JsonDatabasePath, JsonDatabase);
if (Result != 0) {
llvm::outs() << "Error while opening JSON database: " << Result.message()
<< "\n";
return 1;
}
llvm::StringRef BaseDirectory(::getenv("PWD"));
for (int I = 2; I < argc; ++I) {
llvm::SmallString<1024> File(GetAbsolutePath(argv[I], BaseDirectory));
llvm::outs() << "Processing " << File << ".\n";
std::string ErrorMessage;
clang::tooling::CompileCommand LookupResult =
clang::tooling::FindCompileArgsInJsonDatabase(
File.str(), JsonDatabase->getBuffer(), ErrorMessage);
if (!LookupResult.CommandLine.empty()) {
if (!clang::tooling::RunToolWithFlags(
new clang::SyntaxOnlyAction,
LookupResult.CommandLine.size(),
clang::tooling::CommandLineToArgv(
&LookupResult.CommandLine).data())) {
llvm::outs() << "Error while processing " << File << ".\n";
}
} else {
llvm::outs() << "Skipping " << File << ". Command line not found.\n";
}
}
return 0;
}

View File

@ -1,24 +0,0 @@
##===- examples/Tooling/Makefile ---------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ../..
TOOLNAME = clang-check
NO_INSTALL = 1
# No plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
LINK_COMPONENTS := support mc
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangSema.a clangAnalysis.a \
clangAST.a clangParse.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@ -18,7 +18,8 @@ TOOL_NO_EXPORTS = 1
LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter ipo \
selectiondag asmparser instrumentation
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a clangCodeGen.a \
clangSema.a clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a clangAnalysis.a clangRewrite.a \
clangAST.a clangParse.a clangLex.a clangBasic.a
clangParse.a clangSema.a clangStaticAnalyzerFrontend.a \
clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
clangAnalysis.a clangRewrite.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@ -94,7 +94,7 @@ int main(int argc, const char **argv, char * const *envp) {
// We expect to get back exactly one command job, if we didn't something
// failed. Extract that job from the compilation.
const driver::JobList &Jobs = C->getJobs();
if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) {
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
llvm::SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
C->PrintJob(OS, C->getJobs(), "; ", true);

View File

@ -16,8 +16,11 @@ NO_INSTALL = 1
TOOL_NO_EXPORTS = 1
LINK_COMPONENTS := asmparser bitreader mc core
USEDLIBS = clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a clangIndex.a clangFrontend.a clangDriver.a \
clangSema.a clangAnalysis.a clangSerialization.a \
clangAST.a clangParse.a clangLex.a clangBasic.a
USEDLIBS = clangStaticAnalyzerFrontend.a \
clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a \
clangIndex.a clangFrontend.a clangDriver.a \
clangParse.a clangSema.a clangAnalysis.a clangSerialization.a \
clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@ -221,6 +221,14 @@ CINDEX_LINKAGE CXString clang_getFileName(CXFile SFile);
*/
CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile);
/**
* \brief Determine whether the given header is guarded against
* multiple inclusions, either with the conventional
* #ifndef/#define/#endif macro guards or with #pragma once.
*/
CINDEX_LINKAGE unsigned
clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);
/**
* \brief Retrieve a file handle within the given translation unit.
*
@ -821,7 +829,18 @@ enum CXTranslationUnit_Flags {
* Note: this is a *temporary* option that is available only while
* we are testing C++ precompiled preamble support.
*/
CXTranslationUnit_CXXChainedPCH = 0x20
CXTranslationUnit_CXXChainedPCH = 0x20,
/**
* \brief Used to indicate that the "detailed" preprocessing record,
* if requested, should also contain nested macro instantiations.
*
* Nested macro instantiations (i.e., macro instantiations that occur
* inside another macro instantiation) 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
};
/**
@ -1027,12 +1046,14 @@ enum CXTUResourceUsageKind {
CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,
CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9,
CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10,
CXTUResourceUsage_Preprocessor = 11,
CXTUResourceUsage_PreprocessingRecord = 12,
CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST,
CXTUResourceUsage_MEMORY_IN_BYTES_END =
CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
CXTUResourceUsage_PreprocessingRecord,
CXTUResourceUsage_First = CXTUResourceUsage_AST,
CXTUResourceUsage_Last = CXTUResourceUsage_ExternalASTSource_Membuffer_MMap
CXTUResourceUsage_Last = CXTUResourceUsage_PreprocessingRecord
};
/**
@ -1166,8 +1187,12 @@ enum CXCursorKind {
CXCursor_UsingDeclaration = 35,
/** \brief A C++ alias declaration */
CXCursor_TypeAliasDecl = 36,
/** \brief An Objective-C @synthesize definition. */
CXCursor_ObjCSynthesizeDecl = 37,
/** \brief An Objective-C @dynamic definition. */
CXCursor_ObjCDynamicDecl = 38,
CXCursor_FirstDecl = CXCursor_UnexposedDecl,
CXCursor_LastDecl = CXCursor_TypeAliasDecl,
CXCursor_LastDecl = CXCursor_ObjCDynamicDecl,
/* References */
CXCursor_FirstRef = 40, /* Decl references */
@ -2245,6 +2270,13 @@ CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor);
*/
CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
/**
* \brief Determine if a C++ member function or member function template is
* explicitly declared 'virtual' or if it overrides a virtual method from
* one of the base classes.
*/
CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
/**
* \brief Given a cursor that represents a template, determine
* the cursor kind of the specializations would be generated by instantiating

View File

@ -85,10 +85,10 @@ class APValue {
APValue(const APValue &RHS) : Kind(Uninitialized) {
*this = RHS;
}
APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) {
APValue(const Expr* B, const CharUnits &O) : Kind(Uninitialized) {
MakeLValue(); setLValue(B, O);
}
APValue(Expr* B);
APValue(const Expr* B);
~APValue() {
MakeUninit();
@ -167,7 +167,7 @@ class APValue {
return const_cast<APValue*>(this)->getComplexFloatImag();
}
Expr* getLValueBase() const;
const Expr* getLValueBase() const;
CharUnits getLValueOffset() const;
void setInt(const APSInt &I) {
@ -199,7 +199,7 @@ class APValue {
((ComplexAPFloat*)(char*)Data)->Real = R;
((ComplexAPFloat*)(char*)Data)->Imag = I;
}
void setLValue(Expr *B, const CharUnits &O);
void setLValue(const Expr *B, const CharUnits &O);
const APValue &operator=(const APValue &RHS);

View File

@ -406,6 +406,21 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
/// bitfield which follows the bitfield 'LastFD'.
bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
/// BitfieldFollowsBitfield - return 'true" if 'FD' is a
/// bitfield which follows the bitfield 'LastFD'.
bool BitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
/// NoneBitfieldFollowsBitfield - return 'true" if 'FD' is not a
/// bitfield which follows the bitfield 'LastFD'.
bool NoneBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
/// BitfieldFollowsNoneBitfield - return 'true" if 'FD' is a
/// bitfield which follows the none bitfield 'LastFD'.
bool BitfieldFollowsNoneBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
// Access to the set of methods overridden by the given C++ method.
typedef CXXMethodVector::iterator overridden_cxx_method_iterator;
@ -764,6 +779,10 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
/// getDecltypeType - C++0x decltype.
QualType getDecltypeType(Expr *e) const;
/// getUnaryTransformType - unary type transforms
QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType,
UnaryTransformType::UTTKind UKind) const;
/// getAutoType - C++0x deduced auto type.
QualType getAutoType(QualType DeducedType) const;
@ -895,12 +914,18 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
std::string &S) const;
/// getObjCEncodingForFunctionDecl - Returns the encoded type for this
//function. This is in the same format as Objective-C method encodings.
void getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
/// function. This is in the same format as Objective-C method encodings.
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S);
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
/// declaration.
void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S)
///
/// \returns true if an error occurred (e.g., because one of the parameter
/// types is incomplete), false otherwise.
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S)
const;
/// getObjCEncodingForBlock - Return the encoded type for this block
@ -1438,7 +1463,8 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
/// MakeIntValue - Make an APSInt of the appropriate width and
/// signedness for the given \arg Value and integer \arg Type.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const {
llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerType());
llvm::APSInt Res(getIntWidth(Type),
!Type->isSignedIntegerOrEnumerationType());
Res = Value;
return Res;
}
@ -1526,6 +1552,13 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
/// which declarations were built.
static unsigned NumImplicitCopyConstructorsDeclared;
/// \brief The number of implicitly-declared move constructors.
static unsigned NumImplicitMoveConstructors;
/// \brief The number of implicitly-declared move constructors for
/// which declarations were built.
static unsigned NumImplicitMoveConstructorsDeclared;
/// \brief The number of implicitly-declared copy assignment operators.
static unsigned NumImplicitCopyAssignmentOperators;
@ -1533,6 +1566,13 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
/// which declarations were built.
static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
/// \brief The number of implicitly-declared move assignment operators.
static unsigned NumImplicitMoveAssignmentOperators;
/// \brief The number of implicitly-declared move assignment operators for
/// which declarations were built.
static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
/// \brief The number of implicitly-declared destructors.
static unsigned NumImplicitDestructors;
@ -1553,7 +1593,13 @@ class ASTContext : public llvm::RefCountedBase<ASTContext> {
bool ExpandStructures,
const FieldDecl *Field,
bool OutermostType = false,
bool EncodingProperty = false) const;
bool EncodingProperty = false,
bool StructField = false) const;
// Adds the encoding of the structure's members.
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
const FieldDecl *Field,
bool includeVBases = true) const;
const ASTRecordLayout &
getObjCLayout(const ObjCInterfaceDecl *D,

View File

@ -291,6 +291,8 @@ class CanProxyBase {
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
@ -630,6 +632,14 @@ struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
};
template <>
struct CanProxyAdaptor<UnaryTransformType>
: public CanProxyBase<UnaryTransformType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind)
};
template<>
struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)

View File

@ -1365,6 +1365,8 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool HasWrittenPrototype : 1;
bool IsDeleted : 1;
bool IsTrivial : 1; // sunk from CXXMethodDecl
bool IsDefaulted : 1; // sunk from CXXMethoDecl
bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl
bool HasImplicitReturnZero : 1;
bool IsLateTemplateParsed : 1;
@ -1448,6 +1450,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsDefaulted(false), IsExplicitlyDefaulted(false),
HasImplicitReturnZero(false), IsLateTemplateParsed(false),
EndRangeLoc(NameInfo.getEndLoc()),
TemplateOrSpecialization(),
@ -1512,6 +1515,20 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
return hasBody(Definition);
}
/// hasTrivialBody - Returns whether the function has a trivial body that does
/// not require any specific codegen.
bool hasTrivialBody() const;
/// isDefined - Returns true if the function is defined at all, including
/// a deleted definition. Except for the behavior when the function is
/// deleted, behaves like hasBody.
bool isDefined(const FunctionDecl *&Definition) const;
virtual bool isDefined() const {
const FunctionDecl* Definition;
return isDefined(Definition);
}
/// getBody - Retrieve the body (definition) of the function. The
/// function body might be in any of the (re-)declarations of this
/// function. The variant that accepts a FunctionDecl pointer will
@ -1529,10 +1546,17 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// isThisDeclarationADefinition - Returns whether this specific
/// declaration of the function is also a definition. This does not
/// determine whether the function has been defined (e.g., in a
/// previous definition); for that information, use getBody.
/// FIXME: Should return true if function is deleted or defaulted. However,
/// CodeGenModule.cpp uses it, and I don't know if this would break it.
/// previous definition); for that information, use isDefined. Note
/// that this returns false for a defaulted function unless that function
/// has been implicitly defined (possibly as deleted).
bool isThisDeclarationADefinition() const {
return IsDeleted || Body || IsLateTemplateParsed;
}
/// doesThisDeclarationHaveABody - Returns whether this specific
/// declaration of the function has a body - that is, if it is a non-
/// deleted definition.
bool doesThisDeclarationHaveABody() const {
return Body || IsLateTemplateParsed;
}
@ -1566,6 +1590,16 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool isTrivial() const { return IsTrivial; }
void setTrivial(bool IT) { IsTrivial = IT; }
/// Whether this function is defaulted per C++0x. Only valid for
/// special member functions.
bool isDefaulted() const { return IsDefaulted; }
void setDefaulted(bool D = true) { IsDefaulted = D; }
/// Whether this function is explicitly defaulted per C++0x. Only valid
/// for special member functions.
bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; }
void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; }
/// Whether falling off this function implicitly returns null/zero.
/// If a more specific implicit return value is required, front-ends
/// should synthesize the appropriate return statements.
@ -1605,13 +1639,30 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// Integer(long double) = delete; // no construction from long double
/// };
/// @endcode
bool isDeleted() const { return IsDeleted; }
void setDeleted(bool D = true) { IsDeleted = D; }
// If a function is deleted, its first declaration must be.
bool isDeleted() const { return getCanonicalDecl()->IsDeleted; }
bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; }
void setDeletedAsWritten(bool D = true) { IsDeleted = D; }
/// \brief Determines whether this is a function "main", which is
/// the entry point into an executable program.
/// \brief Determines whether this function is "main", which is the
/// entry point into an executable program.
bool isMain() const;
/// \brief Determines whether this operator new or delete is one
/// of the reserved global placement operators:
/// void *operator new(size_t, void *);
/// void *operator new[](size_t, void *);
/// void operator delete(void *, void *);
/// void operator delete[](void *, void *);
/// These functions have special behavior under [new.delete.placement]:
/// These functions are reserved, a C++ program may not define
/// functions that displace the versions in the Standard C++ library.
/// The provisions of [basic.stc.dynamic] do not apply to these
/// reserved placement forms of operator new and operator delete.
///
/// This function must be an allocation or deallocation function.
bool isReservedGlobalPlacementOperator() const;
/// \brief Determines whether this function is a function with
/// external, C linkage.
bool isExternC() const;
@ -1902,20 +1953,33 @@ class FieldDecl : public DeclaratorDecl {
bool Mutable : 1;
mutable unsigned CachedFieldIndex : 31;
Expr *BitWidth;
/// \brief A pointer to either the in-class initializer for this field (if
/// the boolean value is false), or the bit width expression for this bit
/// field (if the boolean value is true).
///
/// We can safely combine these two because in-class initializers are not
/// permitted for bit-fields.
///
/// If the boolean is false and the initializer is null, then this field has
/// an in-class initializer which has not yet been parsed and attached.
llvm::PointerIntPair<Expr *, 1, bool> InitializerOrBitWidth;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable)
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
bool HasInit)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0), BitWidth(BW) {
Mutable(Mutable), CachedFieldIndex(0),
InitializerOrBitWidth(BW, !HasInit) {
assert(!(BW && HasInit) && "got initializer for bitfield");
}
public:
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
bool HasInit);
/// getFieldIndex - Returns the index of this field within its record,
/// as appropriate for passing to ASTRecordLayout::getFieldOffset.
@ -1928,10 +1992,12 @@ class FieldDecl : public DeclaratorDecl {
void setMutable(bool M) { Mutable = M; }
/// isBitfield - Determines whether this field is a bitfield.
bool isBitField() const { return BitWidth != NULL; }
bool isBitField() const {
return InitializerOrBitWidth.getInt() && InitializerOrBitWidth.getPointer();
}
/// @brief Determines whether this is an unnamed bitfield.
bool isUnnamedBitfield() const { return BitWidth != NULL && !getDeclName(); }
bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); }
/// isAnonymousStructOrUnion - Determines whether this field is a
/// representative for an anonymous struct or union. Such fields are
@ -1939,8 +2005,37 @@ class FieldDecl : public DeclaratorDecl {
/// store the data for the anonymous union or struct.
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const { return BitWidth; }
void setBitWidth(Expr *BW) { BitWidth = BW; }
Expr *getBitWidth() const {
return isBitField() ? InitializerOrBitWidth.getPointer() : 0;
}
void setBitWidth(Expr *BW) {
assert(!InitializerOrBitWidth.getPointer() &&
"bit width or initializer already set");
InitializerOrBitWidth.setPointer(BW);
InitializerOrBitWidth.setInt(1);
}
/// hasInClassInitializer - Determine whether this member has a C++0x in-class
/// initializer.
bool hasInClassInitializer() const {
return !InitializerOrBitWidth.getInt();
}
/// getInClassInitializer - Get the C++0x in-class initializer for this
/// member, or null if one has not been set. If a valid declaration has an
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
}
/// setInClassInitializer - Set the C++0x in-class initializer for this member.
void setInClassInitializer(Expr *Init);
/// removeInClassInitializer - Remove the C++0x in-class initializer from this
/// member.
void removeInClassInitializer() {
assert(!InitializerOrBitWidth.getInt() && "no initializer to remove");
InitializerOrBitWidth.setPointer(0);
InitializerOrBitWidth.setInt(1);
}
/// getParent - Returns the parent of this field declaration, which
/// is the struct in which this method is defined.

View File

@ -1355,17 +1355,12 @@ struct cast_convert_decl_context<ToTy, true> {
namespace llvm {
/// isa<T>(DeclContext*)
template<class ToTy>
struct isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
template <typename To>
struct isa_impl<To, ::clang::DeclContext> {
static bool doit(const ::clang::DeclContext &Val) {
return ToTy::classofKind(Val.getDeclKind());
return To::classofKind(Val.getDeclKind());
}
};
template<class ToTy>
struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
: public isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {};
/// cast<T>(DeclContext*)
template<class ToTy>

View File

@ -278,10 +278,18 @@ class CXXRecordDecl : public RecordDecl {
/// user-declared copy constructor.
bool UserDeclaredCopyConstructor : 1;
/// UserDeclareMoveConstructor - True when this class has a
/// user-declared move constructor.
bool UserDeclaredMoveConstructor : 1;
/// UserDeclaredCopyAssignment - True when this class has a
/// user-declared copy assignment operator.
bool UserDeclaredCopyAssignment : 1;
/// UserDeclareMoveAssignment - True when this class has a
/// user-declared move assignment.
bool UserDeclaredMoveAssignment : 1;
/// UserDeclaredDestructor - True when this class has a
/// user-declared destructor.
bool UserDeclaredDestructor : 1;
@ -337,15 +345,24 @@ class CXXRecordDecl : public RecordDecl {
/// HasPublicFields - True when there are private non-static data members.
bool HasPublicFields : 1;
/// HasTrivialConstructor - True when this class has a trivial constructor.
/// \brief True if this class (or any subobject) has mutable fields.
bool HasMutableFields : 1;
/// HasTrivialDefaultConstructor - True when, if this class has a default
/// constructor, this default constructor is trivial.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
/// implicitly-declared default constructor and if:
/// * its class has no virtual functions and no virtual base classes, and
/// * all the direct base classes of its class have trivial constructors, and
/// * for all the nonstatic data members of its class that are of class type
/// (or array thereof), each such class has a trivial constructor.
bool HasTrivialConstructor : 1;
/// C++0x [class.ctor]p5
/// A default constructor is trivial if it is not user-provided and if
/// -- its class has no virtual functions and no virtual base classes,
/// and
/// -- no non-static data member of its class has a
/// brace-or-equal-initializer, and
/// -- all the direct base classes of its class have trivial
/// default constructors, and
/// -- for all the nonstatic data members of its class that are of class
/// type (or array thereof), each such class has a trivial
/// default constructor.
bool HasTrivialDefaultConstructor : 1;
/// HasConstExprNonCopyMoveConstructor - True when this class has at least
/// one constexpr constructor which is neither the copy nor move
@ -357,7 +374,7 @@ class CXXRecordDecl : public RecordDecl {
///
/// C++0x [class.copy]p13:
/// A copy/move constructor for class X is trivial if it is neither
/// user-provided nor deleted and if
/// user-provided and if
/// -- class X has no virtual functions and no virtual base classes, and
/// -- the constructor selected to copy/move each direct base class
/// subobject is trivial, and
@ -372,7 +389,7 @@ class CXXRecordDecl : public RecordDecl {
///
/// C++0x [class.copy]p13:
/// A copy/move constructor for class X is trivial if it is neither
/// user-provided nor deleted and if
/// user-provided and if
/// -- class X has no virtual functions and no virtual base classes, and
/// -- the constructor selected to copy/move each direct base class
/// subobject is trivial, and
@ -430,15 +447,24 @@ class CXXRecordDecl : public RecordDecl {
/// already computed and are available.
bool ComputedVisibleConversions : 1;
/// \brief Whether we have already declared the default constructor or
/// do not need to have one declared.
/// \brief Whether we have a C++0x user-provided default constructor (not
/// explicitly deleted or defaulted).
bool UserProvidedDefaultConstructor : 1;
/// \brief Whether we have already declared the default constructor.
bool DeclaredDefaultConstructor : 1;
/// \brief Whether we have already declared the copy constructor.
bool DeclaredCopyConstructor : 1;
/// \brief Whether we have already declared the move constructor.
bool DeclaredMoveConstructor : 1;
/// \brief Whether we have already declared the copy-assignment operator.
bool DeclaredCopyAssignment : 1;
/// \brief Whether we have already declared the move-assignment operator.
bool DeclaredMoveAssignment : 1;
/// \brief Whether we have already declared a destructor within the class.
bool DeclaredDestructor : 1;
@ -666,21 +692,30 @@ class CXXRecordDecl : public RecordDecl {
return data().FirstFriend != 0;
}
/// \brief Determine whether this class has had its default constructor
/// declared implicitly or does not need one declared implicitly.
/// \brief Determine if we need to declare a default constructor for
/// this class.
///
/// This value is used for lazy creation of default constructors.
bool needsImplicitDefaultConstructor() const {
return !data().UserDeclaredConstructor &&
!data().DeclaredDefaultConstructor;
}
/// hasDeclaredDefaultConstructor - Whether this class's default constructor
/// has been declared (either explicitly or implicitly).
bool hasDeclaredDefaultConstructor() const {
return data().DeclaredDefaultConstructor;
}
/// hasConstCopyConstructor - Determines whether this class has a
/// copy constructor that accepts a const-qualified argument.
bool hasConstCopyConstructor(const ASTContext &Context) const;
bool hasConstCopyConstructor() const;
/// getCopyConstructor - Returns the copy constructor for this class
CXXConstructorDecl *getCopyConstructor(const ASTContext &Context,
unsigned TypeQuals) const;
CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const;
/// getMoveConstructor - Returns the move constructor for this class
CXXConstructorDecl *getMoveConstructor() const;
/// \brief Retrieve the copy-assignment operator for this class, if available.
///
@ -693,6 +728,10 @@ class CXXRecordDecl : public RecordDecl {
/// \returns The copy-assignment operator that can be invoked, or NULL if
/// a unique copy-assignment operator could not be found.
CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
/// getMoveAssignmentOperator - Returns the move assignment operator for this
/// class
CXXMethodDecl *getMoveAssignmentOperator() const;
/// hasUserDeclaredConstructor - Whether this class has any
/// user-declared constructors. When true, a default constructor
@ -701,6 +740,12 @@ class CXXRecordDecl : public RecordDecl {
return data().UserDeclaredConstructor;
}
/// hasUserProvidedDefaultconstructor - Whether this class has a
/// user-provided default constructor per C++0x.
bool hasUserProvidedDefaultConstructor() const {
return data().UserProvidedDefaultConstructor;
}
/// hasUserDeclaredCopyConstructor - Whether this class has a
/// user-declared copy constructor. When false, a copy constructor
/// will be implicitly declared.
@ -715,7 +760,27 @@ class CXXRecordDecl : public RecordDecl {
bool hasDeclaredCopyConstructor() const {
return data().DeclaredCopyConstructor;
}
/// hasUserDeclaredMoveOperation - Whether this class has a user-
/// declared move constructor or assignment operator. When false, a
/// move constructor and assignment operator may be implicitly declared.
bool hasUserDeclaredMoveOperation() const {
return data().UserDeclaredMoveConstructor ||
data().UserDeclaredMoveAssignment;
}
/// \brief Determine whether this class has had a move constructor
/// declared by the user.
bool hasUserDeclaredMoveConstructor() const {
return data().UserDeclaredMoveConstructor;
}
/// \brief Determine whether this class has had a move constructor
/// declared.
bool hasDeclaredMoveConstructor() const {
return data().DeclaredMoveConstructor;
}
/// hasUserDeclaredCopyAssignment - Whether this class has a
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
@ -730,7 +795,19 @@ class CXXRecordDecl : public RecordDecl {
bool hasDeclaredCopyAssignment() const {
return data().DeclaredCopyAssignment;
}
/// \brief Determine whether this class has had a move assignment
/// declared by the user.
bool hasUserDeclaredMoveAssignment() const {
return data().UserDeclaredMoveAssignment;
}
/// hasDeclaredMoveAssignment - Whether this class has a
/// declared move assignment operator.
bool hasDeclaredMoveAssignment() const {
return data().DeclaredMoveAssignment;
}
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
@ -800,9 +877,18 @@ class CXXRecordDecl : public RecordDecl {
/// (C++ [class]p7)
bool isStandardLayout() const { return data().IsStandardLayout; }
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
/// \brief Whether this class, or any of its class subobjects, contains a
/// mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
// hasTrivialDefaultConstructor - Whether this class has a trivial default
// constructor
// (C++0x [class.ctor]p5)
bool hasTrivialDefaultConstructor() const {
return data().HasTrivialDefaultConstructor &&
(!data().UserDeclaredConstructor ||
data().DeclaredDefaultConstructor);
}
// hasConstExprNonCopyMoveConstructor - Whether this class has at least one
// constexpr constructor other than the copy or move constructors
@ -845,9 +931,18 @@ class CXXRecordDecl : public RecordDecl {
}
// isTriviallyCopyable - Whether this class is considered trivially copyable
// (C++0x [class]p5).
// (C++0x [class]p6).
bool isTriviallyCopyable() const;
// isTrivial - Whether this class is considered trivial
//
// C++0x [class]p6
// A trivial class is a class that has a trivial default constructor and
// is trivially copiable.
bool isTrivial() const {
return isTriviallyCopyable() && hasTrivialDefaultConstructor();
}
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@ -1182,6 +1277,9 @@ class CXXMethodDecl : public FunctionDecl {
/// \brief Determine whether this is a copy-assignment operator, regardless
/// of whether it was declared implicitly or explicitly.
bool isCopyAssignmentOperator() const;
/// \brief Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
const CXXMethodDecl *getCanonicalDecl() const {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
@ -1189,6 +1287,12 @@ class CXXMethodDecl : public FunctionDecl {
CXXMethodDecl *getCanonicalDecl() {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
/// isUserProvided - True if it is either an implicit constructor or
/// if it was defaulted or deleted on first declaration.
bool isUserProvided() const {
return !(isDeleted() || getCanonicalDecl()->isDefaulted());
}
///
void addOverriddenMethod(const CXXMethodDecl *MD);
@ -1274,6 +1378,8 @@ class CXXCtorInitializer {
/// \brief The argument used to initialize the base or member, which may
/// end up constructing an object (when multiple arguments are involved).
/// If 0, this is a field initializer, and the in-class member initializer
/// will be used.
Stmt *Init;
/// LParenLoc - Location of the left paren of the ctor-initializer.
@ -1348,6 +1454,13 @@ class CXXCtorInitializer {
return Initializee.is<IndirectFieldDecl*>();
}
/// isInClassMemberInitializer - Returns true when this initializer is an
/// implicit ctor initializer generated for a field with an initializer
/// defined on the member declaration.
bool isInClassMemberInitializer() const {
return !Init;
}
/// isDelegatingInitializer - Returns true when this initializer is creating
/// a delegating constructor.
bool isDelegatingInitializer() const {
@ -1476,7 +1589,14 @@ class CXXCtorInitializer {
reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
}
Expr *getInit() const { return static_cast<Expr *>(Init); }
/// \brief Get the initializer. This is 0 if this is an in-class initializer
/// for a non-static data member which has not yet been parsed.
Expr *getInit() const {
if (!Init)
return getAnyMember()->getInClassInitializer();
return static_cast<Expr*>(Init);
}
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@ -1619,10 +1739,9 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// getTargetConstructor - When this constructor delegates to
/// another, retrieve the target
CXXConstructorDecl *getTargetConstructor() const {
if (isDelegatingConstructor())
return CtorInitializers[0]->getTargetConstructor();
else
return 0;
assert(isDelegatingConstructor() &&
"A non-delegating constructor has no target");
return CtorInitializers[0]->getTargetConstructor();
}
/// isDefaultConstructor - Whether this constructor is a default
@ -1693,6 +1812,13 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// \brief Set the constructor that this inheriting constructor is based on.
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
const CXXConstructorDecl *getCanonicalDecl() const {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
CXXConstructorDecl *getCanonicalDecl() {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }

View File

@ -135,6 +135,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
/// in, inout, etc.
unsigned objcDeclQualifier : 6;
/// \brief Indicates whether this method has a related result type.
unsigned RelatedResultType : 1;
// Number of args separated by ':' in a method declaration.
unsigned NumSelectorArgs;
@ -171,6 +174,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
bool isSynthesized = false,
bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false,
unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
@ -178,8 +182,8 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
IsSynthesized(isSynthesized),
IsDefined(isDefined),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
NumSelectorArgs(numSelectorArgs), MethodDeclType(T),
ResultTInfo(ResultTInfo),
RelatedResultType(HasRelatedResultType), NumSelectorArgs(numSelectorArgs),
MethodDeclType(T), ResultTInfo(ResultTInfo),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
/// \brief A definition will return its interface declaration.
@ -199,6 +203,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
bool isSynthesized = false,
bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false,
unsigned numSelectorArgs = 0);
virtual ObjCMethodDecl *getCanonicalDecl();
@ -211,6 +216,13 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
}
void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
/// \brief Determine whether this method has a result type that is related
/// to the message receiver's type.
bool hasRelatedResultType() const { return RelatedResultType; }
/// \brief Note whether this method has a related result type.
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
unsigned getNumSelectorArgs() const { return NumSelectorArgs; }
void setNumSelectorArgs(unsigned numSelectorArgs) {
NumSelectorArgs = numSelectorArgs;
@ -712,7 +724,7 @@ class ObjCIvarDecl : public FieldDecl {
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false),
/*Mutable=*/false, /*HasInit=*/false),
NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
@ -767,7 +779,7 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
/*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false) {}
BW, /*Mutable=*/false, /*HasInit=*/false) {}
public:
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,

View File

@ -30,6 +30,7 @@ class ClassTemplatePartialSpecializationDecl;
class TemplateTypeParmDecl;
class NonTypeTemplateParmDecl;
class TemplateTemplateParmDecl;
class TypeAliasTemplateDecl;
/// \brief Stores a template parameter of any kind.
typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
@ -230,6 +231,7 @@ class TemplateDecl : public NamedDecl {
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstTemplate && K <= lastTemplate;
}
@ -672,6 +674,7 @@ class RedeclarableTemplateDecl : public TemplateDecl {
static bool classof(const RedeclarableTemplateDecl *D) { return true; }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
}
@ -2014,6 +2017,78 @@ class FriendTemplateDecl : public Decl {
friend class ASTDeclReader;
};
/// Declaration of an alias template. For example:
///
/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
class TypeAliasTemplateDecl : public RedeclarableTemplateDecl,
public RedeclarableTemplate<TypeAliasTemplateDecl> {
static void DeallocateCommon(void *Ptr);
protected:
typedef RedeclarableTemplate<TypeAliasTemplateDecl> redeclarable_base;
typedef CommonBase Common;
TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
public:
/// Get the underlying function declaration of the template.
TypeAliasDecl *getTemplatedDecl() const {
return static_cast<TypeAliasDecl*>(TemplatedDecl);
}
TypeAliasTemplateDecl *getCanonicalDecl() {
return redeclarable_base::getCanonicalDecl();
}
const TypeAliasTemplateDecl *getCanonicalDecl() const {
return redeclarable_base::getCanonicalDecl();
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
TypeAliasTemplateDecl *getPreviousDeclaration() {
return redeclarable_base::getPreviousDeclaration();
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
const TypeAliasTemplateDecl *getPreviousDeclaration() const {
return redeclarable_base::getPreviousDeclaration();
}
TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
return redeclarable_base::getInstantiatedFromMemberTemplate();
}
/// \brief Create a function template node.
static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
/// \brief Create an empty alias template node.
static TypeAliasTemplateDecl *Create(ASTContext &C, EmptyShell);
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeAliasTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
/// Implementation of inline functions that require the template declarations
inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
: Function(FTD) { }

View File

@ -515,6 +515,14 @@ class Expr : public Stmt {
/// ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts();
/// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
/// call to a conversion operator, return the argument.
Expr *IgnoreConversionOperator();
const Expr *IgnoreConversionOperator() const {
return const_cast<Expr*>(this)->IgnoreConversionOperator();
}
const Expr *IgnoreParenImpCasts() const {
return const_cast<Expr*>(this)->IgnoreParenImpCasts();
}
@ -1018,13 +1026,18 @@ class IntegerLiteral : public Expr {
false),
Loc(l) {
assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
assert(V.getBitWidth() == C.getIntWidth(type) &&
"Integer type is not the correct size for constant.");
setValue(C, V);
}
// type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
// or UnsignedLongLongTy
/// \brief Returns a new integer literal with value 'V' and type 'type'.
/// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy,
/// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V
/// \param V - the value that the returned integer literal contains.
static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V,
QualType type, SourceLocation l);
/// \brief Returns a new empty integer literal.
static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
llvm::APInt getValue() const { return Num.getValue(); }
@ -1555,9 +1568,9 @@ class OffsetOfExpr : public Expr {
TSInfo = tsi;
}
const OffsetOfNode &getComponent(unsigned Idx) {
const OffsetOfNode &getComponent(unsigned Idx) const {
assert(Idx < NumComps && "Subscript out of range");
return reinterpret_cast<OffsetOfNode *> (this + 1)[Idx];
return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx];
}
void setComponent(unsigned Idx, OffsetOfNode ON) {
@ -1574,6 +1587,9 @@ class OffsetOfExpr : public Expr {
return reinterpret_cast<Expr **>(
reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
}
const Expr *getIndexExpr(unsigned Idx) const {
return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx);
}
void setIndexExpr(unsigned Idx, Expr* E) {
assert(Idx < NumComps && "Subscript out of range");
@ -3299,6 +3315,9 @@ class InitListExpr : public Expr {
Expr *getArrayFiller() {
return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
}
const Expr *getArrayFiller() const {
return const_cast<InitListExpr *>(this)->getArrayFiller();
}
void setArrayFiller(Expr *filler);
/// \brief If this initializes a union, specifies which field in the
@ -3310,6 +3329,9 @@ class InitListExpr : public Expr {
FieldDecl *getInitializedFieldInUnion() {
return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
}
const FieldDecl *getInitializedFieldInUnion() const {
return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
}
void setInitializedFieldInUnion(FieldDecl *FD) {
ArrayFillerOrUnionFieldInit = FD;
}
@ -4012,6 +4034,42 @@ class BlockDeclRefExpr : public Expr {
child_range children() { return child_range(); }
};
/// 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 {
private:
Expr* SrcExpr;
QualType DstType;
SourceLocation BuiltinLoc, RParenLoc;
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) {}
/// getSrcExpr - Return the Expr to be converted.
Expr *getSrcExpr() const { return SrcExpr; }
QualType getDstType() const { return DstType; }
SourceRange getSourceRange() const {
return SourceRange(BuiltinLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == AsTypeExprClass;
}
static bool classof(const AsTypeExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
};
} // end namespace clang
#endif

View File

@ -211,7 +211,7 @@ class ExternalASTSource {
return sizes;
}
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const = 0;
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
protected:
static DeclContextLookupResult

View File

@ -750,6 +750,11 @@ DEF_TRAVERSE_TYPE(DecltypeType, {
TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
})
DEF_TRAVERSE_TYPE(UnaryTransformType, {
TRY_TO(TraverseType(T->getBaseType()));
TRY_TO(TraverseType(T->getUnderlyingType()));
})
DEF_TRAVERSE_TYPE(AutoType, {
TRY_TO(TraverseType(T->getDeducedType()));
})
@ -966,6 +971,10 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, {
TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
})
DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
})
DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
})
@ -1368,6 +1377,11 @@ DEF_TRAVERSE_DECL(TypeAliasDecl, {
// source.
})
DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
TRY_TO(TraverseDecl(D->getTemplatedDecl()));
TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
})
DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
// A dependent using declaration which was marked with 'typename'.
// template<class T> class A : public B<T> { using typename B<T>::foo; };
@ -1967,6 +1981,9 @@ DEF_TRAVERSE_STMT(FloatingLiteral, { })
DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
DEF_TRAVERSE_STMT(StringLiteral, { })
DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
// Traverse OpenCL: AsType, Convert.
DEF_TRAVERSE_STMT(AsTypeExpr, { })
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file defines the StmtVisitor interface.
// This file defines the StmtVisitor and ConstStmtVisitor interfaces.
//
//===----------------------------------------------------------------------===//
@ -21,20 +21,26 @@
namespace clang {
#define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S))
template <typename T> struct make_ptr { typedef T *type; };
template <typename T> struct make_const_ptr { typedef const T *type; };
/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
template<typename ImplClass, typename RetTy=void>
class StmtVisitor {
/// StmtVisitorBase - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs.
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
class StmtVisitorBase {
public:
RetTy Visit(Stmt *S) {
#define PTR(CLASS) typename Ptr<CLASS>::type
#define DISPATCH(NAME, CLASS) \
return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
RetTy Visit(PTR(Stmt) S) {
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
default: assert(0 && "Unknown binary operator!");
case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator);
@ -72,7 +78,7 @@ class StmtVisitor {
case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator);
case BO_Comma: DISPATCH(BinComma, BinaryOperator);
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
} else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
default: assert(0 && "Unknown unary operator!");
case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator);
@ -104,13 +110,13 @@ class StmtVisitor {
// If the implementation chooses not to implement a certain visit method, fall
// back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \
RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
#include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.
#define BINOP_FALLBACK(NAME) \
RetTy VisitBin ## NAME(BinaryOperator *S) { \
RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
DISPATCH(BinaryOperator, BinaryOperator); \
}
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
@ -130,7 +136,7 @@ class StmtVisitor {
// If the implementation doesn't implement compound assignment operator
// methods, fall back on VisitCompoundAssignOperator.
#define CAO_FALLBACK(NAME) \
RetTy VisitBin ## NAME(CompoundAssignOperator *S) { \
RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
}
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
@ -142,7 +148,7 @@ class StmtVisitor {
// If the implementation doesn't implement unary operator methods, fall back
// on VisitUnaryOperator.
#define UNARYOP_FALLBACK(NAME) \
RetTy VisitUnary ## NAME(UnaryOperator *S) { \
RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
DISPATCH(UnaryOperator, UnaryOperator); \
}
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
@ -156,10 +162,29 @@ class StmtVisitor {
#undef UNARYOP_FALLBACK
// Base case, ignore it. :)
RetTy VisitStmt(Stmt *Node) { return RetTy(); }
RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
#undef PTR
#undef DISPATCH
};
#undef DISPATCH
/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
///
/// This class does not preserve constness of Stmt pointers (see also
/// ConstStmtVisitor).
template<typename ImplClass, typename RetTy=void>
class StmtVisitor
: public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
/// ConstStmtVisitor - This class implements a simple visitor for Stmt
/// subclasses. Since Expr derives from Stmt, this also includes support for
/// visiting Exprs.
///
/// This class preserves constness of Stmt pointers (see also StmtVisitor).
template<typename ImplClass, typename RetTy=void>
class ConstStmtVisitor
: public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
} // end namespace clang

View File

@ -294,9 +294,15 @@ class Qualifiers {
/// Generally this answers the question of whether an object with the other
/// qualifiers can be safely used as an object with these qualifiers.
bool compatiblyIncludes(Qualifiers other) const {
// Non-CVR qualifiers must match exactly. CVR qualifiers may subset.
return ((Mask & ~CVRMask) == (other.Mask & ~CVRMask)) &&
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
return
// Address spaces must match exactly.
getAddressSpace() == other.getAddressSpace() &&
// ObjC GC qualifiers can match, be added, or be removed, but can't be
// changed.
(getObjCGCAttr() == other.getObjCGCAttr() ||
!hasObjCGCAttr() || !other.hasObjCGCAttr()) &&
// CVR qualifiers may subset.
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
}
/// \brief Determine whether this set of qualifiers is a strict superset of
@ -532,6 +538,14 @@ class QualType {
return withFastQualifiers(Qualifiers::Const);
}
/// addVolatile - add the specified type qualifier to this QualType.
void addVolatile() {
addFastQualifiers(Qualifiers::Volatile);
}
QualType withVolatile() const {
return withFastQualifiers(Qualifiers::Volatile);
}
void addFastQualifiers(unsigned TQs) {
assert(!(TQs & ~Qualifiers::FastMask)
&& "non-fast qualifier bits set in mask!");
@ -1183,6 +1197,10 @@ class Type : public ExtQualsTypeCommonBase {
/// (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;
@ -1418,16 +1436,22 @@ class Type : public ExtQualsTypeCommonBase {
/// isSignedIntegerType - Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// an enum decl which has a signed representation, or a vector of signed
/// integer element type.
/// or an enum decl which has a signed representation.
bool isSignedIntegerType() const;
/// isUnsignedIntegerType - Return true if this is an integer type that is
/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
/// decl which has an unsigned representation, or a vector of unsigned integer
/// element type.
/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
/// or an enum decl which has an unsigned representation.
bool isUnsignedIntegerType() const;
/// Determines whether this is an integer type that is signed or an
/// enumeration types whose underlying type is a signed integer type.
bool isSignedIntegerOrEnumerationType() const;
/// Determines whether this is an integer type that is unsigned or an
/// enumeration types whose underlying type is a unsigned integer type.
bool isUnsignedIntegerOrEnumerationType() const;
/// isConstantSizeType - Return true if this is not a variable sized type,
/// according to the rules of C99 6.7.5p3. It is not legal to call this on
/// incomplete types.
@ -2580,6 +2604,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
}
bool isNothrow(ASTContext &Ctx) const {
ExceptionSpecificationType EST = getExceptionSpecType();
assert(EST != EST_Delayed);
if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
return true;
if (EST != EST_ComputedNoexcept)
@ -2809,6 +2834,39 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
Expr *E);
};
/// \brief A unary type transform, which is a type constructed from another
class UnaryTransformType : public Type {
public:
enum UTTKind {
EnumUnderlyingType
};
private:
/// The untransformed type.
QualType BaseType;
/// The transformed type if not dependent, otherwise the same as BaseType.
QualType UnderlyingType;
UTTKind UKind;
protected:
UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
QualType CanonicalTy);
friend class ASTContext;
public:
bool isSugared() const { return !isDependentType(); }
QualType desugar() const { return UnderlyingType; }
QualType getUnderlyingType() const { return UnderlyingType; }
QualType getBaseType() const { return BaseType; }
UTTKind getUTTKind() const { return UKind; }
static bool classof(const Type *T) {
return T->getTypeClass() == UnaryTransform;
}
static bool classof(const UnaryTransformType *) { return true; }
};
class TagType : public Type {
/// Stores the TagDecl associated with this type. The decl may point to any
/// TagDecl that declares the entity.
@ -3201,6 +3259,10 @@ class AutoType : public Type, public llvm::FoldingSetNode {
/// Other template specialization types, for which the template name
/// is dependent, may be canonical types. These types are always
/// dependent.
///
/// 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.
class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
/// \brief The name of the template being specialized.
@ -3212,7 +3274,8 @@ class TemplateSpecializationType
TemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs, QualType Canon);
unsigned NumArgs, QualType Canon,
QualType Aliased);
friend class ASTContext; // ASTContext creates these
@ -3247,6 +3310,16 @@ class TemplateSpecializationType
return isa<InjectedClassNameType>(getCanonicalTypeInternal());
}
/// True if this template specialization type is for a type alias
/// template.
bool isTypeAlias() const;
/// Get the aliased type, if this is a specialization of a type alias
/// template.
QualType getAliasedType() const {
assert(isTypeAlias() && "not a type alias template specialization");
return *reinterpret_cast<const QualType*>(end());
}
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
@ -3268,12 +3341,14 @@ class TemplateSpecializationType
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
bool isSugared() const {
return !isDependentType() || isCurrentInstantiation();
return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
}
QualType desugar() const { return getCanonicalTypeInternal(); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
Profile(ID, Template, getArgs(), NumArgs, Ctx);
if (isTypeAlias())
getAliasedType().Profile(ID);
}
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,

View File

@ -1410,6 +1410,53 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeType> {
};
struct UnaryTransformTypeLocInfo {
// FIXME: While there's only one unary transform right now, future ones may
// need different representations
SourceLocation KWLoc, LParenLoc, RParenLoc;
TypeSourceInfo *UnderlyingTInfo;
};
class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
UnaryTransformTypeLoc,
UnaryTransformType,
UnaryTransformTypeLocInfo> {
public:
SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
TypeSourceInfo* getUnderlyingTInfo() const {
return getLocalData()->UnderlyingTInfo;
}
void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
getLocalData()->UnderlyingTInfo = TInfo;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getKWLoc(), getRParenLoc());
}
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKWLoc(Loc);
setRParenLoc(Loc);
setLParenLoc(Loc);
}
};
class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
AutoTypeLoc,
AutoType> {

View File

@ -84,6 +84,7 @@ NON_CANONICAL_TYPE(Typedef, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type)
ABSTRACT_TYPE(Tag, Type)
TYPE(Record, TagType)
TYPE(Enum, TagType)

View File

@ -24,12 +24,26 @@ BUILTIN(__builtin_arm_qsub, "iii", "nc")
BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
// Store and load exclusive doubleword
BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
BUILTIN(__builtin_arm_strexd, "iLLUiv*", "")
// VFP
BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc")
BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc")
BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc")
BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc")
// Coprocessor
BUILTIN(__builtin_arm_mcr, "vUiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_mcr2, "vUiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_mrc, "UiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_mrc2, "UiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_cdp, "vUiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "")
BUILTIN(__builtin_arm_mcrr, "vUiUiUiUiUi", "")
BUILTIN(__builtin_arm_mcrr2, "vUiUiUiUiUi", "")
// NEON
#define GET_NEON_BUILTINS
#include "clang/Basic/arm_neon.inc"

View File

@ -278,7 +278,6 @@ BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "")
BUILTIN(__builtin_ia32_clflush, "vvC*", "")
BUILTIN(__builtin_ia32_lfence, "v", "")
BUILTIN(__builtin_ia32_mfence, "v", "")
BUILTIN(__builtin_ia32_loaddqu, "V16ccC*", "")
BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "")
BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "")
BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "")

View File

@ -50,6 +50,7 @@ def Named : Decl<1>;
def RedeclarableTemplate : DDecl<Template, 1>;
def FunctionTemplate : DDecl<RedeclarableTemplate>;
def ClassTemplate : DDecl<RedeclarableTemplate>;
def TypeAliasTemplate : DDecl<RedeclarableTemplate>;
def TemplateTemplateParm : DDecl<Template>;
def Using : DDecl<Named>;
def UsingShadow : DDecl<Named>;

View File

@ -32,6 +32,7 @@ namespace clang {
class LangOptions;
class Preprocessor;
class DiagnosticErrorTrap;
class StoredDiagnostic;
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
@ -400,6 +401,7 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
void setExtensionHandlingBehavior(ExtensionHandling H) {
ExtBehavior = H;
}
ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
/// AllExtensionsSilenced - This is a counter bumped when an __extension__
/// block is encountered. When non-zero, all extension diagnostics are
@ -423,7 +425,7 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
///
/// 'Loc' is the source location that this change of diagnostic state should
/// take affect. It can be null if we are setting the state from command-line.
bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map,
bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map,
SourceLocation Loc = SourceLocation()) {
return Diags->setDiagnosticGroupMapping(Group, Map, Loc, *this);
}
@ -487,6 +489,8 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID);
inline DiagnosticBuilder Report(unsigned DiagID);
void Report(const StoredDiagnostic &storedDiag);
/// \brief Determine whethere there is already a diagnostic in flight.
bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
@ -839,8 +843,11 @@ inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) {
/// about the currently in-flight diagnostic.
class DiagnosticInfo {
const Diagnostic *DiagObj;
llvm::StringRef StoredDiagMessage;
public:
explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {}
DiagnosticInfo(const Diagnostic *DO, llvm::StringRef storedDiagMessage)
: DiagObj(DO), StoredDiagMessage(storedDiagMessage) {}
const Diagnostic *getDiags() const { return DiagObj; }
unsigned getID() const { return DiagObj->CurDiagID; }

View File

@ -52,6 +52,12 @@ def err_invalid_storage_class_in_func_decl : Error<
def err_expected_namespace_name : Error<"expected namespace name">;
def ext_variadic_templates : ExtWarn<
"variadic templates are a C++0x extension">, InGroup<CXX0x>;
def err_default_special_members : Error<
"only special member functions may be defaulted">;
def err_friends_define_only_namespace_scope : Error<
"cannot define a function with non-namespace scope in a friend declaration">;
def err_deleted_non_function : Error<
"only functions can have deleted definitions">;
// Sema && Lex
def ext_longlong : Extension<

View File

@ -281,6 +281,9 @@ def err_not_a_pch_file : Error<
def warn_unknown_warning_option : Warning<
"unknown warning option '%0'">,
InGroup<DiagGroup<"unknown-warning-option"> >;
def warn_unknown_negative_warning_option : Warning<
"unknown warning option '%0'">,
InGroup<DiagGroup<"unknown-warning-option"> >, DefaultIgnore;
def warn_unknown_warning_specifier : Warning<
"unknown %0 warning specifier: '%1'">,
InGroup<DiagGroup<"unknown-warning-option"> >;

View File

@ -33,8 +33,11 @@ def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"ctor-dtor-privacy">;
def : DiagGroup<"declaration-after-statement">;
def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">;
def GNUDesignator : DiagGroup<"gnu-designator">;
def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">;
def Deprecated : DiagGroup<"deprecated", [ DeprecatedDeclarations] >,
@ -144,7 +147,7 @@ def : DiagGroup<"type-limits">;
def Uninitialized : DiagGroup<"uninitialized">;
def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def UnknownAttributes : DiagGroup<"unknown-attributes">;
def UnknownAttributes : DiagGroup<"attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">;
def UnusedArgument : DiagGroup<"unused-argument">;
def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
@ -235,6 +238,7 @@ def Extra : DiagGroup<"extra", [
def Most : DiagGroup<"most", [
CharSubscript,
Comment,
DeleteNonVirtualDtor,
Format,
Implicit,
MismatchedTags,
@ -271,6 +275,8 @@ def NonGCC : DiagGroup<"non-gcc",
def CXX0xStaticNonIntegralInitializer :
DiagGroup<"c++0x-static-nonintegral-init">;
def CXX0x : DiagGroup<"c++0x-extensions", [CXX0xStaticNonIntegralInitializer]>;
def DelegatingCtorCycles :
DiagGroup<"delegating-ctor-cycles">;
// A warning group for warnings about GCC extensions.
def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;

View File

@ -101,7 +101,7 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
const char *getDescription(unsigned DiagID) const;
llvm::StringRef getDescription(unsigned DiagID) const;
/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
/// level of the specified diagnostic ID is a Warning or Extension.
@ -132,15 +132,18 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
/// the diagnostic, this returns null.
static const char *getWarningOptionForDiag(unsigned DiagID);
static llvm::StringRef getWarningOptionForDiag(unsigned DiagID);
/// getCategoryNumberForDiag - Return the category number that a specified
/// DiagID belongs to, or 0 if no category.
static unsigned getCategoryNumberForDiag(unsigned DiagID);
/// getNumberOfCategories - Return the number of categories
static unsigned getNumberOfCategories();
/// getCategoryNameFromID - Given a category ID, return the name of the
/// category.
static const char *getCategoryNameFromID(unsigned CategoryID);
static llvm::StringRef getCategoryNameFromID(unsigned CategoryID);
/// \brief Enumeration describing how the the emission of a diagnostic should
/// be treated when it occurs during C++ template argument deduction.
@ -179,24 +182,24 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
/// getName - Given a diagnostic ID, return its name
static const char *getName(unsigned DiagID);
static llvm::StringRef getName(unsigned DiagID);
/// getIdFromName - Given a diagnostic name, return its ID, or 0
static unsigned getIdFromName(char const *Name);
static unsigned getIdFromName(llvm::StringRef Name);
/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
/// of the issue
static const char *getBriefExplanation(unsigned DiagID);
static llvm::StringRef getBriefExplanation(unsigned DiagID);
/// getFullExplanation - Given a diagnostic ID, return a full explanation
/// of the issue
static const char *getFullExplanation(unsigned DiagID);
static llvm::StringRef getFullExplanation(unsigned DiagID);
private:
/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
/// "unknown-pragmas" to have the specified mapping. This returns true and
/// ignores the request if "Group" was unknown, false otherwise.
bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map,
bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map,
SourceLocation Loc, Diagnostic &Diag) const;
/// \brief Based on the way the client configured the Diagnostic

View File

@ -108,6 +108,7 @@ def err_expected_ident_lparen : Error<"expected identifier or '('">;
def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
def err_expected_lbrace : Error<"expected '{'">;
def err_expected_lparen : Error<"expected '('">;
def err_expected_lparen_or_lbrace : Error<"expected '('or '{'">;
def err_expected_rparen : Error<"expected ')'">;
def err_expected_lsquare : Error<"expected '['">;
def err_expected_rsquare : Error<"expected ']'">;
@ -161,6 +162,8 @@ def err_unexpected_namespace_attributes_alias : Error<
def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
def err_namespace_nonnamespace_scope : Error<
"namespaces can only be defined in global or namespace scope">;
def err_nested_namespaces_with_double_colon : Error<
"nested namespace definition must define each namespace separately">;
def err_expected_semi_after_attribute_list : Error<
"expected ';' after attribute list">;
def err_expected_semi_after_static_assert : Error<
@ -190,6 +193,8 @@ def ext_ref_qualifier : ExtWarn<
"reference qualifiers on functions are a C++0x extension">, InGroup<CXX0x>;
def ext_inline_namespace : ExtWarn<
"inline namespaces are a C++0x feature">, InGroup<CXX0x>;
def err_generalized_initializer_lists : Error<
"generalized initializer lists are a C++0x extension unsupported in Clang">;
def ext_generalized_initializer_lists : ExtWarn<
"generalized initializer lists are a C++0x extension unsupported in Clang">,
InGroup<CXX0x>;
@ -343,6 +348,9 @@ def err_operator_string_not_empty : Error<
// Classes.
def err_anon_type_definition : Error<
"declaration of anonymous %0 must be a definition">;
def err_default_delete_in_multiple_declaration : Error<
"'= %select{default|delete}0' is a function definition and must occur in a "
"standalone declaration">;
def err_cxx0x_attribute_forbids_arguments : Error<
"C++0x attribute '%0' cannot have an argument list">;
@ -434,12 +442,26 @@ def err_missing_whitespace_digraph : Error<
def warn_deleted_function_accepted_as_extension: ExtWarn<
"deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>;
def warn_defaulted_function_accepted_as_extension: ExtWarn<
"defaulted function definition accepted as a C++0x extension">,
InGroup<CXX0x>;
// C++0x in-class member initialization
def warn_nonstatic_member_init_accepted_as_extension: ExtWarn<
"in-class initialization of non-static data member accepted as a C++0x extension">,
InGroup<CXX0x>;
def err_bitfield_member_init: Error<
"bitfield member cannot have an in-class initializer">;
def err_incomplete_array_member_init: Error<
"array bound cannot be deduced from an in-class initializer">;
// C++0x alias-declaration
def ext_alias_declaration : ExtWarn<
"alias declarations accepted as a C++0x extension">, InGroup<CXX0x>;
def err_alias_declaration_not_identifier : Error<
"name defined in alias declaration must be an identifier">;
def err_alias_declaration_specialization : Error<
"%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;
// C++0x override control
def ext_override_control_keyword : Extension<

View File

@ -261,10 +261,11 @@ def err_builtin_definition : Error<"definition of builtin function %0">;
def err_types_compatible_p_in_cplusplus : Error<
"__builtin_types_compatible_p is not valid in C++">;
def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
def warn_non_pod_memset : Warning<
"destination for this memset call is a pointer to a non-POD type %0">,
InGroup<DiagGroup<"non-pod-memset">>, DefaultIgnore;
def note_non_pod_memset_silence : Note<
def warn_dyn_class_memaccess : Warning<
"%select{destination for|source of}0 this %1 call is a pointer to dynamic "
"class %2; vtable pointer will be overwritten">,
InGroup<DiagGroup<"dynamic-class-memaccess">>;
def note_bad_memaccess_silence : Note<
"explicitly cast the pointer to silence this warning">;
/// main()
@ -371,7 +372,8 @@ def warn_conflicting_ret_types : Warning<
"conflicting return type in implementation of %0: %1 vs %2">;
def warn_conflicting_ret_type_modifiers : Warning<
"conflicting distributed object modifiers on return type "
"in implementation of %0">;
"in implementation of %0">,
InGroup<DiagGroup<"distributed-object-modifiers">>;
def warn_non_covariant_ret_types : Warning<
"conflicting return type in implementation of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
@ -380,7 +382,8 @@ def warn_conflicting_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">;
def warn_conflicting_param_modifiers : Warning<
"conflicting distributed object modifiers on parameter type "
"in implementation of %0">;
"in implementation of %0">,
InGroup<DiagGroup<"distributed-object-modifiers">>;
def warn_non_contravariant_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
@ -495,6 +498,8 @@ def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
def err_static_assert_failed : Error<"static_assert failed \"%0\"">;
def warn_inline_namespace_reopened_noninline : Warning<
"inline namespace cannot be re-opened as a non-inline namespace">;
def err_inline_namespace_mismatch : Error<
"%select{|non-}0inline namespace "
"cannot be reopened as %select{non-|}0inline">;
@ -504,11 +509,12 @@ def err_unexpected_friend : Error<
def ext_enum_friend : ExtWarn<
"enumeration type %0 cannot be a friend">;
def ext_nonclass_type_friend : ExtWarn<
"non-class type %0 cannot be a friend">;
"non-class friend type %0 is a C++0x extension">, InGroup<CXX0x>;
def err_friend_is_member : Error<
"friends cannot be members of the declaring class">;
def ext_unelaborated_friend_type : ExtWarn<
"must specify '%select{struct|union|class|enum}0' to befriend %1">;
"specify '%select{struct|union|class|enum}0' to befriend %1; accepted "
"as a C++0x extension">, InGroup<CXX0x>;
def err_qualified_friend_not_found : Error<
"no function named %0 with type %1 was found in the specified scope">;
def err_introducing_special_friend : Error<
@ -539,12 +545,12 @@ def err_type_defined_in_result_type : Error<
"%0 can not be defined in the result type of a function">;
def err_type_defined_in_param_type : Error<
"%0 can not be defined in a parameter type">;
def err_type_defined_in_alias_template : Error<
"%0 can not be defined in a type alias template">;
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
def err_deleted_non_function : Error<
"only functions can have deleted definitions">;
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
@ -572,6 +578,9 @@ def warn_mismatched_exception_spec : ExtWarn<
def err_override_exception_spec : Error<
"exception specification of overriding function is more lax than "
"base version">;
def warn_override_exception_spec : ExtWarn<
"exception specification of overriding function is more lax than "
"base version">, InGroup<Microsoft>;
def err_incompatible_exception_specs : Error<
"target exception specification is not superset of source">;
def err_deep_exception_specs_differ : Error<
@ -580,12 +589,18 @@ def warn_missing_exception_specification : Warning<
"%0 is missing exception specification '%1'">;
def err_noexcept_needs_constant_expression : Error<
"argument to noexcept specifier must be a constant expression">;
def err_exception_spec_unknown : Error<
"exception specification is not available until end of class definition">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
def err_access : Error<
"%1 is a %select{private|protected}0 member of %3">, AccessControl;
def war_ms_using_declaration_inaccessible : ExtWarn<
"using declaration refers to inaccessible member '%0', which refers "
"to accessible member '%1', accepted for Microsoft compatibility">,
AccessControl, InGroup<Microsoft>;
def err_access_ctor : Error<
"calling a %select{private|protected}0 constructor of class %2">,
AccessControl;
@ -593,13 +608,18 @@ def ext_rvalue_to_reference_access_ctor : ExtWarn<
"C++98 requires an accessible copy constructor for class %2 when binding "
"a reference to a temporary; was %select{private|protected}0">,
AccessControl, InGroup<BindToTemporaryCopy>;
def err_access_base : Error<
def err_access_base_ctor : Error<
// The ERRORs represent other special members that aren't constructors, in
// hopes that someone will bother noticing and reporting if they appear
"%select{base class|inherited virtual base class}0 %1 has %select{private|"
"protected}3 %select{constructor|copy constructor|copy assignment operator|"
"destructor}2">, AccessControl;
def err_access_field: Error<
"field of type %0 has %select{private|protected}2 %select{constructor|copy "
"constructor|copy assignment operator|destructor}1">, AccessControl;
"protected}3 %select{default |copy |move |*ERROR* |*ERROR* "
"|*ERROR*|}2constructor">, AccessControl;
def err_access_field_ctor : Error<
// The ERRORs represent other special members that aren't constructors, in
// hopes that someone will bother noticing and reporting if they appear
"field of type %0 has %select{private|protected}2 "
"%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">,
AccessControl;
def err_access_ctor_field :
Error<"field of type %1 has %select{private|protected}2 constructor">,
@ -715,39 +735,52 @@ def err_member_function_initialization : Error<
"initializer on function does not look like a pure-specifier">;
def err_non_virtual_pure : Error<
"%0 is not virtual and cannot be declared pure">;
def warn_pure_function_definition : ExtWarn<
"function definition with pure-specifier is a Microsoft extension">,
InGroup<Microsoft>;
def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
def err_qualified_member_of_unrelated : Error<
"%q0 is not a member of class %1">;
def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning<
"call to pure virtual member function %0; overrides of %0 in subclasses are "
"not available in the %select{constructor|destructor}1 of %2">;
def note_field_decl : Note<"member is declared here">;
def note_ivar_decl : Note<"ivar is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
def note_previous_decl : Note<"%0 declared here">;
def note_member_synthesized_at : Note<
"implicit default %select{constructor|copy constructor|"
"copy assignment operator|destructor}0 for %1 first required here">;
"implicit default %select{constructor|copy constructor|move constructor|copy "
"assignment operator|move assignment operator|destructor}0 for %1 first "
"required here">;
def err_missing_default_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{base class|member}2 %3 which does not have a default "
"constructor">;
def err_illegal_union_or_anon_struct_member : Error<
"%select{anonymous struct|union}0 member %1 has a non-trivial "
"%select{constructor|copy constructor|copy assignment operator|destructor}2">;
"%select{constructor|copy constructor|move constructor|copy assignment "
"operator|move assignment operator|destructor}2">;
def note_nontrivial_has_virtual : Note<
"because type %0 has a virtual %select{member function|base class}1">;
def note_nontrivial_has_nontrivial : Note<
"because type %0 has a %select{member|base class}1 with a non-trivial "
"%select{constructor|copy constructor|copy assignment operator|destructor}2">;
"%select{constructor|copy constructor|move constructor|copy assignment "
"operator|move assignment operator|destructor}2">;
def note_nontrivial_user_defined : Note<
"because type %0 has a user-declared %select{constructor|copy constructor|"
"copy assignment operator|destructor}1">;
"move constructor|copy assignment operator|move assignment operator|"
"destructor}1">;
def err_static_data_member_not_allowed_in_union_or_anon_struct : Error<
"static data member %0 not allowed in %select{anonymous struct|union}1">;
def err_union_member_of_reference_type : Error<
"union member %0 has reference type %1">;
def ext_anonymous_struct_union_qualified : Extension<
"anonymous %select{struct|union}0 cannot be '%select{const|volatile|"
"restrict}1'">;
def err_different_return_type_for_overriding_virtual_function : Error<
"virtual function %0 has a different return type (%1) than the "
"function it overrides (which has return type %2)">;
@ -942,8 +975,8 @@ def err_illegal_decl_array_of_auto : Error<
def err_new_array_of_auto : Error<
"cannot allocate array of 'auto'">;
def err_auto_not_allowed : Error<
"'auto' not allowed %select{in function prototype|in struct member"
"|in union member|in class member|in exception declaration"
"'auto' not allowed %select{in function prototype|in non-static struct member"
"|in non-static union member|in non-static class member|in exception declaration"
"|in template parameter|in block literal|in template argument"
"|in typedef|in type alias|in function return type|here}0">;
def err_auto_var_requires_init : Error<
@ -1000,16 +1033,23 @@ def err_enum_redeclare_fixed_mismatch : Error<
"enumeration previously declared with %select{non|}0fixed underlying type">;
def err_enum_redeclare_scoped_mismatch : Error<
"enumeration previously declared as %select{un|}0scoped">;
def err_only_enums_have_underlying_types : Error<
"only enumeration types have underlying types">;
def err_incomplete_type_no_underlying_type : Error<
"an incomplete enumeration type has no underlying type yet">;
// C++0x delegating constructors
def err_delegation_0x_only : Error<
"delegating constructors are permitted only in C++0x">;
def err_delegation_unimplemented : Error<
"delegating constructors are not fully implemented">;
def err_delegating_initializer_alone : Error<
"an initializer for a delegating constructor must appear alone">;
def err_delegating_ctor_loop : Error<
"constructor %0 delegates to itself (possibly indirectly)">;
def warn_delegating_ctor_cycle : Warning<
"constructor for %0 creates a delegation cycle">, DefaultError,
InGroup<DelegatingCtorCycles>;
def note_it_delegates_to : Note<
"it delegates to">, InGroup<DelegatingCtorCycles>;
def note_which_delegates_to : Note<
"which delegates to">, InGroup<DelegatingCtorCycles>;
def err_delegating_codegen_not_implemented : Error<
"code generation for delegating constructors not implemented">;
@ -1140,6 +1180,8 @@ def warn_attribute_void_function_method : Warning<
"%select{functions|Objective-C method}1 without return value">;
def warn_attribute_weak_on_field : Warning<
"__weak attribute cannot be specified on a field declaration">;
def warn_gc_attribute_weak_on_local : Warning<
"Objective-C GC does not allow weak variables on the stack">;
def warn_attribute_weak_on_local : Warning<
"__weak attribute cannot be specified on an automatic variable">;
def warn_weak_identifier_undeclared : Warning<
@ -1242,7 +1284,9 @@ def warn_impcast_different_enum_types : Warning<
def warn_impcast_bool_to_null_pointer : Warning<
"initialization of pointer of type %0 to NULL from a constant boolean "
"expression">, InGroup<BoolConversions>;
def warn_impcast_null_pointer_to_integer : Warning<
"implicit conversion of NULL constant to integer">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_cast_align : Warning<
"cast from %0 to %1 increases required alignment from %2 to %3">,
@ -1374,6 +1418,13 @@ def note_first_required_here : Note<
def err_uninitialized_member_in_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{reference|const}2 member %3">;
def warn_default_arg_makes_ctor_special : Warning<
"addition of default argument on redeclaration makes this constructor a "
"%select{default|copy|move}0 constructor">, InGroup<DefaultArgSpecialMember>;
def note_previous_declaration_special : Note<
// The ERRORs are in hopes that if they occur, they'll get reported.
"previous declaration was %select{*ERROR*|a copy constructor|a move "
"constructor|*ERROR*|*ERROR*|*ERROR*|not a special member function}0">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@ -1412,7 +1463,9 @@ def note_ovl_candidate : Note<"candidate "
"function |function |constructor |"
"is the implicit default constructor|"
"is the implicit copy constructor|"
"is the implicit move constructor|"
"is the implicit copy assignment operator|"
"is the implicit move assignment operator|"
"is an inherited constructor}0%1">;
def note_ovl_candidate_inherited_constructor : Note<"inherited from here">;
@ -1443,7 +1496,9 @@ def note_ovl_candidate_arity : Note<"candidate "
"%select{function|function|constructor|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 %select{|template }1"
"not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 "
"%plural{1:was|:were}4 provided">;
@ -1463,7 +1518,9 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
"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 "
"not viable: cannot convert argument of incomplete type %2 to %3">;
def note_ovl_candidate_bad_overload : Note<"candidate "
@ -1471,7 +1528,9 @@ def note_ovl_candidate_bad_overload : Note<"candidate "
"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"
" not viable: no overload of %3 matching %2 for %ordinal4 argument">;
def note_ovl_candidate_bad_conv : Note<"candidate "
@ -1479,7 +1538,9 @@ def note_ovl_candidate_bad_conv : Note<"candidate "
"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"
" not viable: no known conversion from %2 to %3 for "
"%select{%ordinal5 argument|object argument}4">;
@ -1488,7 +1549,9 @@ def note_ovl_candidate_bad_addrspace : Note<"candidate "
"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 not viable: "
"%select{%ordinal6|'this'}5 argument (%2) is in "
"address space %3, but parameter must be in address space %4">;
@ -1497,7 +1560,9 @@ def note_ovl_candidate_bad_gc : Note<"candidate "
"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 not viable: "
"%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 "
"lifetime, but parameter has %select{no|__weak|__strong}4 lifetime">;
@ -1512,7 +1577,9 @@ def note_ovl_candidate_bad_cvr : Note<"candidate "
"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 not viable: "
"%ordinal4 argument (%2) would lose "
"%select{const|restrict|const and restrict|volatile|const and volatile|"
@ -1523,7 +1590,9 @@ def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate "
"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"
" not viable: cannot %select{convert from|convert from|bind}2 "
"%select{base class pointer|superclass|base class object of type}2 %3 to "
@ -1666,7 +1735,7 @@ def err_template_arg_must_be_expr : Error<
def err_template_arg_nontype_ambig : Error<
"template argument for non-type template parameter is treated as type %0">;
def err_template_arg_must_be_template : Error<
"template argument for template template parameter must be a class template">;
"template argument for template template parameter must be a class template%select{| or type alias template}0">;
def ext_template_arg_local_type : ExtWarn<
"template argument uses local type %0">, InGroup<LocalTypeTemplateArgs>;
def ext_template_arg_unnamed_type : ExtWarn<
@ -1802,6 +1871,8 @@ 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<
"explicit specialization cannot have a storage class">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@ -1812,6 +1883,8 @@ def err_template_spec_needs_template_parameters : Error<
def err_template_param_list_matches_nontemplate : Error<
"template parameter list matching the non-templated nested type %0 should "
"be empty ('template<>')">;
def err_alias_template_extra_headers : Error<
"extraneous template parameter list in alias template declaration">;
def err_template_spec_extra_headers : Error<
"extraneous template parameter list in template specialization or "
"out-of-line template definition">;
@ -1823,6 +1896,9 @@ def note_explicit_template_spec_does_not_need_header : Note<
def err_template_qualified_declarator_no_match : Error<
"nested name specifier '%0' for declaration does not refer into a class, "
"class template or class template partial specialization">;
def err_specialize_member_of_template : Error<
"cannot specialize (with 'template<>') a member of an unspecialized "
"template">;
// C++ Class Template Partial Specialization
def err_default_arg_in_partial_spec : Error<
@ -1889,6 +1965,8 @@ def note_function_template_spec_here : Note<
"in instantiation of function template specialization %q0 requested here">;
def note_template_static_data_member_def_here : Note<
"in instantiation of static data member %q0 requested here">;
def note_template_type_alias_instantiation_here : Note<
"in instantiation of template type alias %0 requested here">;
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
@ -1954,6 +2032,8 @@ def err_explicit_instantiation_requires_name : Error<
"explicit instantiation declaration requires a name">;
def err_explicit_instantiation_of_typedef : Error<
"explicit instantiation of typedef %0">;
def err_explicit_instantiation_storage_class : Error<
"explicit instantiation cannot have a storage class">;
def err_explicit_instantiation_not_known : Error<
"explicit instantiation of %0 does not refer to a function template, member "
"function, member class, or static data member">;
@ -1971,7 +2051,7 @@ def note_explicit_instantiation_candidate : Note<
"explicit instantiation candidate function template here %0">;
def err_explicit_instantiation_inline : Error<
"explicit instantiation cannot be 'inline'">;
def ext_explicit_instantiation_without_qualified_id : ExtWarn<
def ext_explicit_instantiation_without_qualified_id : Extension<
"qualifier in explicit instantiation of %q0 requires a template-id "
"(a typedef is not permitted)">;
def err_explicit_instantiation_unqualified_wrong_namespace : Error<
@ -2026,7 +2106,7 @@ def err_non_type_template_in_nested_name_specifier : Error<
def err_template_id_not_a_type : Error<
"template name refers to non-type template '%0'">;
def note_template_declared_here : Note<
"%select{function template|class template|template template parameter}0 "
"%select{function template|class template|type alias template|template template parameter}0 "
"%1 declared here">;
// C++0x Variadic Templates
@ -2099,6 +2179,10 @@ def err_unexpected_namespace : Error<
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">;
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">;
def warn_deprecated : Warning<"%0 is deprecated">,
InGroup<DeprecatedDeclarations>;
@ -2115,7 +2199,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">;
"function has been explicitly marked "
"%select{unavailable|deleted|deprecated}0 here">;
def warn_not_enough_argument : Warning<
"not enough variable arguments in %0 declaration to fit a sentinel">;
def warn_missing_sentinel : Warning <
@ -2127,8 +2212,13 @@ def warn_missing_prototype : Warning<
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
def err_redefinition : Error<"redefinition of %0">;
def err_definition_of_implicitly_declared_member : Error<
"definition of implicitly declared %select{constructor|copy constructor|"
"copy assignment operator|destructor}1">;
"definition of implicitly declared %select{default constructor|copy "
"constructor|move constructor|copy assignment operator|move assignment "
"operator|destructor}1">;
def err_definition_of_explicitly_defaulted_member : Error<
"definition of explicitly defaulted %select{default constructor|copy "
"constructor|move constructor|copy assignment operator|move assignment "
"operator|destructor}0">;
def err_redefinition_extern_inline : Error<
"redefinition of a 'extern inline' function %0 is not supported in "
"%select{C99 mode|C++}1">;
@ -2164,9 +2254,9 @@ def err_redefinition_different_type : Error<
def err_redefinition_different_kind : Error<
"redefinition of %0 as different kind of symbol">;
def err_redefinition_different_typedef : Error<
"%select{typedef|type alias}0 redefinition with different types (%1 vs %2)">;
"%select{typedef|type alias|type alias template}0 redefinition with different types (%1 vs %2)">;
def err_tag_reference_non_tag : Error<
"elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template}0">;
"elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">;
def err_tag_reference_conflict : Error<
"implicit declaration introduced by elaborated type conflicts with "
"%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
@ -2180,9 +2270,15 @@ def err_nested_redefinition : Error<"nested redefinition of %0">;
def err_use_with_wrong_tag : Error<
"use of %0 with tag type that does not match previous declaration">;
def warn_struct_class_tag_mismatch : Warning<
"%select{struct|class}0 %select{|template}1 %2 was previously declared "
"as a %select{class|struct}0 %select{|template}1">,
"%select{struct|class}0%select{| template}1 %2 was previously declared "
"as a %select{class|struct}0%select{| template}1">,
InGroup<MismatchedTags>, DefaultIgnore;
def warn_struct_class_previous_tag_mismatch : Warning<
"%2 defined as a %select{struct|class}0%select{| template}1 here but "
"previously declared as a %select{class|struct}0%select{| template}1">,
InGroup<MismatchedTags>, DefaultIgnore;
def note_struct_class_suggestion : Note<
"did you mean %select{struct|class}0 here?">;
def ext_forward_ref_enum : Extension<
"ISO C forbids forward references to 'enum' types">;
def err_forward_ref_enum : Error<
@ -2482,6 +2578,14 @@ def note_precedence_bitwise_first : Note<
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">,
InGroup<Parentheses>;
def note_precedence_conditional_first : Note<
"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">;
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">>;
@ -2641,6 +2745,10 @@ def warn_indirection_through_null : Warning<
"indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>;
def note_indirection_through_null : Note<
"consider using __builtin_trap() or qualifying pointer with 'volatile'">;
def warn_pointer_indirection_from_incompatible_type : Warning<
"dereference of type %1 that was reinterpret_cast from type %0 has undefined "
"behavior.">,
InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore;
def err_assignment_requires_nonfragile_object : Error<
"cannot assign to class object in non-fragile ABI (%0 invalid)">;
@ -2839,6 +2947,8 @@ def err_objc_pointer_cxx_catch_fragile : Error<
"exception model">;
def err_objc_object_catch : Error<
"can't catch an Objective C object by value">;
def err_incomplete_type_objc_at_encode : Error<
"'@encode' of incomplete type %0">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
@ -2904,6 +3014,9 @@ def err_bad_cxx_cast_member_pointer_size : Error<
def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">;
def err_bad_reinterpret_cast_reference : Error<
"reinterpret_cast of a %0 to %1 needs its address which is not allowed">;
def warn_undefined_reinterpret_cast : Warning<
"reinterpret_cast from %0 to %1 has undefined behavior.">,
InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore;
// These messages don't adhere to the pattern.
// FIXME: Display the path somehow better.
@ -3016,6 +3129,9 @@ def err_objc_exceptions_disabled : Error<
def warn_non_virtual_dtor : Warning<
"%0 has virtual functions but non-virtual destructor">,
InGroup<NonVirtualDtor>, DefaultIgnore;
def warn_delete_non_virtual_dtor : Warning<
"delete called on %0 that has virtual functions but non-virtual destructor">,
InGroup<DeleteNonVirtualDtor>, DefaultIgnore;
def warn_overloaded_virtual : Warning<
"%q0 hides overloaded virtual %select{function|functions}1">,
InGroup<OverloadedVirtual>, DefaultIgnore;
@ -3170,7 +3286,8 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
" %0 "
"%select{from|to parameter of type|from a function with result type|to type|"
"with an expression of type|to parameter of type|to type}2 %1">;
"with an expression of type|to parameter of type|to type}2 %1">,
InGroup<DiagGroup<"incompatible-pointer-types">>;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
" %0 "
@ -3281,8 +3398,8 @@ def err_cannot_pass_objc_interface_to_vararg : Error<
"%select{function|block|method}1">;
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of non-POD type %0 through variadic "
"%select{function|block|method|constructor}1; call will abort at runtime">,
"cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic"
" %select{function|block|method|constructor}2; call will abort at runtime">,
InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
def err_typecheck_call_invalid_ordered_compare : Error<
@ -3591,6 +3708,47 @@ def warn_not_compound_assign : Warning<
def warn_explicit_conversion_functions : Warning<
"explicit conversion functions are a C++0x extension">, InGroup<CXX0x>;
// C++0x defaulted functions
def err_defaulted_default_ctor_params : Error<
"an explicitly-defaulted default constructor must have no parameters">;
def err_defaulted_copy_ctor_params : Error<
"an explicitly-defaulted copy constructor must have exactly one parameter">;
def err_defaulted_copy_ctor_volatile_param : Error<
"the parameter for an explicitly-defaulted copy constructor may not be "
"volatile">;
def err_defaulted_copy_ctor_const_param : Error<
"the parameter for this explicitly-defaulted copy constructor is const, but "
"a member or base requires it to be non-const">;
def err_defaulted_copy_assign_params : Error<
"an explicitly-defaulted copy assignment operator must have exactly one "
"parameter">;
def err_defaulted_copy_assign_return_type : Error<
"an explicitly-defaulted copy assignment operator must return an unqualified "
"lvalue reference to its class type">;
def err_defaulted_copy_assign_not_ref : Error<
"the parameter for an explicitly-defaulted copy assignment operator must be an "
"lvalue reference type">;
def err_defaulted_copy_assign_volatile_param : Error<
"the parameter for an explicitly-defaulted copy assignment operator may not "
"be volatile">;
def err_defaulted_copy_assign_const_param : Error<
"the parameter for this explicitly-defaulted copy assignment operator is "
"const, but a member or base requires it to be non-const">;
def err_defaulted_copy_assign_quals : Error<
"an explicitly-defaulted copy assignment operator may not have 'const' "
"or 'volatile' qualifiers">;
def err_incorrect_defaulted_exception_spec : Error<
"exception specification of explicitly defaulted %select{default constructor|"
"copy constructor|move constructor|copy assignment operator|move assignment "
"operator|destructor}0 does not match the "
"calculated one">;
def err_out_of_line_default_deletes : Error<
"defaulting this %select{default constructor|copy constructor|move "
"constructor|copy assignment operator|move assignment operator|destructor}0 "
"would delete it after its first declaration">;
def err_defaulted_move_unsupported : Error<
"defaulting move functions not yet supported">;
def warn_array_index_precedes_bounds : Warning<
"array index of '%0' indexes before the beginning of the array">,
InGroup<DiagGroup<"array-bounds">>;
@ -3955,7 +4113,28 @@ def err_unknown_any_var_function_type : Error<
def err_filter_expression_integral : Error<
"filter expression type should be an integral value not %0">;
// OpenCL warnings and errors.
def err_invalid_astype_of_different_size : Error<
"invalid reinterpretation: sizes of %0 and %1 must match">;
} // end of sema category
let CategoryName = "Related Result Type Issue" in {
// Objective-C related result type compatibility
def warn_related_result_type_compatibility_class : Warning<
"method is expected to return an instance of its class type %0, but "
"is declared to return %1">;
def warn_related_result_type_compatibility_protocol : Warning<
"protocol method is expected to return an instance of the implementing "
"class, but is declared to return %0">;
def note_related_result_type_overridden : Note<
"overridden method is part of the '%select{|alloc|copy|init|mutableCopy|"
"new|autorelease|dealloc|release|retain|retainCount|self}0' method family">;
def note_related_result_type_inferred : Note<
"%select{class|instance}0 method %1 is assumed to return an instance of "
"its receiver type (%2)">;
}
} // end of sema component.

View File

@ -18,12 +18,13 @@ namespace clang {
/// \brief The various types of exception specifications that exist in C++0x.
enum ExceptionSpecificationType {
EST_None, ///< no exception specification
EST_DynamicNone, ///< throw()
EST_Dynamic, ///< throw(T1, T2)
EST_MSAny, ///< Microsoft throw(...) extension
EST_BasicNoexcept, ///< noexcept
EST_ComputedNoexcept ///< noexcept(expression)
EST_None, ///< no exception specification
EST_DynamicNone, ///< throw()
EST_Dynamic, ///< throw(T1, T2)
EST_MSAny, ///< Microsoft throw(...) extension
EST_BasicNoexcept, ///< noexcept
EST_ComputedNoexcept, ///< noexcept(expression)
EST_Delayed ///< not known yet
};
inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {

View File

@ -498,7 +498,8 @@ enum ObjCMethodFamily {
OMF_dealloc,
OMF_release,
OMF_retain,
OMF_retainCount
OMF_retainCount,
OMF_self
};
/// Enough bits to store any enumerator in ObjCMethodFamily or

View File

@ -46,6 +46,8 @@ class LangOptions {
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled
unsigned ObjCDefaultSynthProperties : 1; // Objective-C auto-synthesized properties.
unsigned ObjCInferRelatedResultType : 1; // Infer Objective-C related return
// types
unsigned AppleKext : 1; // Allow apple kext features.
unsigned PascalStrings : 1; // Allow Pascal strings
@ -173,6 +175,7 @@ class LangOptions {
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
AppleKext = 0;
ObjCDefaultSynthProperties = 0;
ObjCInferRelatedResultType = 0;
NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;

View File

@ -54,6 +54,9 @@ class FileID {
private:
friend class SourceManager;
friend class ASTWriter;
friend class ASTReader;
static FileID get(unsigned V) {
FileID F;
F.ID = V;

View File

@ -831,6 +831,14 @@ 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 Returns true if the given MacroID location points at the last
/// token of the macro instantiation.
bool isAtEndOfMacroInstantiation(SourceLocation Loc) const;
//===--------------------------------------------------------------------===//
// Line Table Manipulation Routines
//===--------------------------------------------------------------------===//

View File

@ -54,6 +54,7 @@ namespace clang {
TST_typeofType,
TST_typeofExpr,
TST_decltype, // C++0x decltype
TST_underlyingType, // __underlying_type for C++0x
TST_auto, // C++0x auto
TST_unknown_anytype, // __unknown_anytype extension
TST_error // erroneous type

View File

@ -146,3 +146,5 @@ def SEHTryStmt : Stmt;
def SEHExceptStmt : Stmt;
def SEHFinallyStmt : Stmt;
// OpenCL Extensions.
def AsTypeExpr : DStmt<Expr>;

View File

@ -368,11 +368,14 @@ class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
ConstraintInfo *OutputConstraints,
unsigned NumOutputs, unsigned &Index) const;
virtual std::string convertConstraint(const char Constraint) const {
// Constraint parm will be left pointing at the last character of
// the constraint. In practice, it won't be changed unless the
// constraint is longer than one character.
virtual std::string convertConstraint(const char *&Constraint) const {
// 'p' defaults to 'r', but can be overridden by targets.
if (Constraint == 'p')
if (*Constraint == 'p')
return std::string("r");
return std::string(1, Constraint);
return std::string(1, *Constraint);
}
// Returns a string of target-specific clobbers, in LLVM format.

View File

@ -346,6 +346,10 @@ KEYWORD(__is_polymorphic , KEYCXX)
KEYWORD(__is_trivial , KEYCXX)
KEYWORD(__is_union , KEYCXX)
// Clang-only C++ Type Traits
KEYWORD(__is_trivially_copyable , KEYCXX)
KEYWORD(__underlying_type , KEYCXX)
// Embarcadero Expression Traits
KEYWORD(__is_lvalue_expr , KEYCXX)
KEYWORD(__is_rvalue_expr , KEYCXX)
@ -409,6 +413,7 @@ KEYWORD(__read_write , KEYOPENCL)
ALIAS("read_only", __read_only , KEYOPENCL)
ALIAS("write_only", __write_only , KEYOPENCL)
ALIAS("read_write", __read_write , KEYOPENCL)
KEYWORD(__builtin_astype , KEYOPENCL)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
@ -451,6 +456,8 @@ KEYWORD(__except , KEYMS | KEYBORLAND)
KEYWORD(__finally , KEYMS | KEYBORLAND)
KEYWORD(__leave , KEYMS | KEYBORLAND)
KEYWORD(__int64 , KEYMS)
KEYWORD(__if_exists , KEYMS)
KEYWORD(__if_not_exists , KEYMS)
ALIAS("__int8" , char , KEYMS)
ALIAS("__int16" , short , KEYMS)
ALIAS("__int32" , int , KEYMS)

View File

@ -23,7 +23,7 @@ namespace clang {
UTT_HasNothrowConstructor,
UTT_HasTrivialAssign,
UTT_HasTrivialCopy,
UTT_HasTrivialConstructor,
UTT_HasTrivialDefaultConstructor,
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
@ -54,6 +54,7 @@ namespace clang {
UTT_IsSigned,
UTT_IsStandardLayout,
UTT_IsTrivial,
UTT_IsTriviallyCopyable,
UTT_IsUnion,
UTT_IsUnsigned,
UTT_IsVoid,

View File

@ -75,6 +75,7 @@ class Inst <string n, string p, string t, Op o> {
string Types = t;
Op Operand = o;
bit isShift = 0;
bit isVCVT_N = 0;
}
// Used to generate Builtins.def:
@ -297,11 +298,13 @@ def VGET_LOW : Inst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>;
def VCVT_S32 : SInst<"vcvt_s32", "xd", "fQf">;
def VCVT_U32 : SInst<"vcvt_u32", "ud", "fQf">;
def VCVT_F16 : SInst<"vcvt_f16", "hk", "f">;
def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">;
def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">;
def VCVT_F32 : SInst<"vcvt_f32", "fd", "iUiQiQUi">;
def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "fd", "h">;
let isVCVT_N = 1 in {
def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">;
def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">;
def VCVT_N_F32 : SInst<"vcvt_n_f32", "fdi", "iUiQiQUi">;
}
def VMOVN : IInst<"vmovn", "hk", "silUsUiUl">;
def VMOVL : SInst<"vmovl", "wd", "csiUcUsUi">;
def VQMOVN : SInst<"vqmovn", "hk", "silUsUiUl">;

View File

@ -77,3 +77,6 @@ def relax_all : Flag<"-relax-all">,
def no_exec_stack : Flag<"--noexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
def fatal_warnings : Flag<"--fatal-warnings">,
HelpText<"Consider warnings as errors">;

View File

@ -140,6 +140,9 @@ def femit_coverage_notes : Flag<"-femit-coverage-notes">,
HelpText<"Emit a gcov coverage notes file when compiling.">;
def femit_coverage_data: Flag<"-femit-coverage-data">,
HelpText<"Instrument the program to emit gcov coverage data when run.">;
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 relaxed_aliasing : Flag<"-relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
def masm_verbose : Flag<"-masm-verbose">,
@ -178,6 +181,8 @@ def mconstructor_aliases : Flag<"-mconstructor-aliases">,
HelpText<"Emit complete constructors and destructors as aliases when possible">;
def mms_bitfields : Flag<"-mms-bitfields">,
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard.">;
def mstackrealign : Flag<"-mstackrealign">,
HelpText<"Force realign the stack at entry to every function.">;
def O : Joined<"-O">, HelpText<"Optimization level">;
def Os : Flag<"-Os">, HelpText<"Optimize for size">;
def Oz : Flag<"-Oz">, HelpText<"Optimize for size, regardless of performance">;
@ -211,6 +216,8 @@ def diagnostic_log_file : Separate<"-diagnostic-log-file">,
HelpText<"Filename (or -) to log diagnostics to">;
def fno_show_column : Flag<"-fno-show-column">,
HelpText<"Do not include column number on diagnostics">;
def fshow_column : Flag<"-fshow-column">,
HelpText<"Include column number on diagnostics">;
def fno_show_source_location : Flag<"-fno-show-source-location">,
HelpText<"Do not include source location information with diagnostics">;
def fshow_overloads_EQ : Joined<"-fshow-overloads=">,
@ -240,6 +247,8 @@ def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">,
HelpText<"Print diagnostic name">;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print option name with mappable diagnostics">;
def fdiagnostics_format : Separate<"-fdiagnostics-format">,
HelpText<"Change diagnostic formatting to match IDE and command line tools">;
def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
def fdiagnostics_show_note_include_stack :
@ -414,6 +423,8 @@ def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">,
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">;
def fgnu_keywords : Flag<"-fgnu-keywords">,
HelpText<"Allow GNU-extension keywords regardless of language standard">;
def fgnu89_inline : Flag<"-fgnu89-inline">,
HelpText<"Use the gnu89 inline semantics">;
def fno_gnu_keywords : Flag<"-fno-gnu-keywords">,
HelpText<"Disallow GNU-extension keywords regardless of language standard">;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
@ -482,6 +493,8 @@ 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 ftrapv : Flag<"-ftrapv">,
HelpText<"Trap on integer overflow">;
def ftrapv_handler : Separate<"-ftrapv-handler">,

View File

@ -238,8 +238,8 @@ def emit_llvm : Flag<"-emit-llvm">,
def exported__symbols__list : Separate<"-exported_symbols_list">;
def e : JoinedOrSeparate<"-e">;
def fPIC : Flag<"-fPIC">, Group<f_Group>;
def fPIE : Flag<"-fPIE">, Group<f_Group>;
def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>;
def fPIE : Flag<"-fPIE">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
def fallow_unsupported : Flag<"-fallow-unsupported">, Group<f_Group>;
def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
@ -278,6 +278,7 @@ def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Grou
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, Group<f_Group>;
def fdiagnostics_show_note_include_stack : Flag<"-fdiagnostics-show-note-include-stack">, Group<f_Group>;
def fdiagnostics_format_EQ : Joined<"-fdiagnostics-format=">, Group<f_clang_Group>;
def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_clang_Group>;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
def fdwarf2_cfi_asm : Flag<"-fdwarf2-cfi-asm">, Group<f_Group>;
@ -298,6 +299,8 @@ def fno_for_scope : Flag<"-fno-for-scope">, Group<f_Group>;
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
def fgnu89_inline : Flag<"-fgnu89-inline">, Group<f_Group>;
def fno_gnu89_inline : Flag<"-fno-gnu89-inline">, Group<f_Group>;
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
@ -389,6 +392,10 @@ def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>;
def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">,
Group<f_Group>;
def fno_objc_infer_related_result_type : Flag<
"-fno-objc-infer-related-result-type">, Group<f_Group>;
// Objective-C ABI options.
def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>;
@ -406,8 +413,8 @@ 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>;
def fpic : Flag<"-fpic">, Group<f_Group>;
def fpie : Flag<"-fpie">, Group<f_Group>;
def fno_pie : Flag<"-fno-pie">, Group<f_Group>;
def fpie : Flag<"-fpie">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fno_pie : Flag<"-fno-pie">, Group<f_Group>, Flags<[NoArgumentUnused]>;
def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
def framework : Separate<"-framework">, Flags<[LinkerInput]>;
@ -418,6 +425,7 @@ def fshort_enums : Flag<"-fshort-enums">, Group<f_Group>;
def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>;
def fshow_column : Flag<"-fshow-column">, Group<f_Group>;
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
def fspell_checking : Flag<"-fspell-checking">, Group<f_Group>;
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
@ -513,6 +521,7 @@ def mlinker_version_EQ : Joined<"-mlinker-version=">, Flags<[NoForward]>;
def mllvm : Separate<"-mllvm">;
def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>;
def mms_bitfields : Flag<"-mms-bitfields">, Group<m_Group>;
def mstackrealign : Flag<"-mstackrealign">, Group<m_Group>;
def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>;
def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>;
def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>;

View File

@ -157,7 +157,7 @@ class ToolChain {
virtual bool SupportsProfiling() const { return true; }
/// Does this tool chain support Objective-C garbage collection.
virtual bool SupportsObjCGC() const { return false; }
virtual bool SupportsObjCGC() const { return true; }
/// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
/// compile unit information.

View File

@ -51,6 +51,7 @@ class HeaderSearch;
class Preprocessor;
class SourceManager;
class TargetInfo;
class ASTFrontendAction;
using namespace idx;
@ -248,6 +249,10 @@ class ASTUnit {
/// \brief Whether we should be caching code-completion results.
bool ShouldCacheCodeCompletionResults;
/// \brief Whether we want to include nested macro instantiations in the
/// detailed preprocessing record.
bool NestedMacroInstantiations;
static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags,
const char **ArgBegin, const char **ArgEnd,
ASTUnit &AST, bool CaptureDiagnostics);
@ -574,6 +579,21 @@ class ASTUnit {
public:
/// \brief Create an ASTUnit from a source file, via a CompilerInvocation
/// object, by invoking the optionally provided ASTFrontendAction.
///
/// \param CI - The compiler invocation to use; it must have exactly one input
/// source file. The ASTUnit takes ownership of the CompilerInvocation object.
///
/// \param Diags - The diagnostics engine to use for reporting errors; its
/// lifetime is expected to extend past that of the returned ASTUnit.
///
/// \param Action - The ASTFrontendAction to invoke. Its ownership is not
/// transfered.
static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags,
ASTFrontendAction *Action = 0);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.
///
@ -591,7 +611,8 @@ class ASTUnit {
bool CaptureDiagnostics = false,
bool PrecompilePreamble = false,
bool CompleteTranslationUnit = true,
bool CacheCodeCompletionResults = false);
bool CacheCodeCompletionResults = false,
bool NestedMacroInstantiations = true);
/// LoadFromCommandLine - Create an ASTUnit from a vector of command line
/// arguments, which must specify exactly one source file.
@ -620,7 +641,8 @@ class ASTUnit {
bool CompleteTranslationUnit = true,
bool CacheCodeCompletionResults = false,
bool CXXPrecompilePreamble = false,
bool CXXChainedPCH = false);
bool CXXChainedPCH = false,
bool NestedMacroInstantiations = true);
/// \brief Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.

View File

@ -95,6 +95,10 @@ class CodeGenOptions {
/// The code model to use (-mcmodel).
std::string CodeModel;
/// The filename with path we use for coverage files. The extension will be
/// replaced.
std::string CoverageFile;
/// Enable additional debugging information.
std::string DebugPass;

View File

@ -37,6 +37,10 @@ class DiagnosticOptions {
unsigned ShowNoteIncludeStack : 1; /// Show include stacks for notes.
unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
/// 2 -> Full Name.
unsigned Format : 2; /// Format for diagnostics:
enum TextDiagnosticFormat { Clang, Msvc, Vi };
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
unsigned ShowOverloads : 1; /// Overload candidates to show. Values from
/// Diagnostic::OverloadsShown
@ -86,6 +90,7 @@ class DiagnosticOptions {
ShowNames = 0;
ShowOptionNames = 0;
ShowCategories = 0;
Format = Clang;
ShowSourceRanges = 0;
ShowParseableFixits = 0;
VerifyDiagnostics = 0;

View File

@ -18,14 +18,15 @@ namespace frontend {
enum LangFeatures {
BCPLComment = (1 << 0),
C99 = (1 << 1),
C1X = (1 << 2),
CPlusPlus = (1 << 3),
CPlusPlus0x = (1 << 4),
Digraphs = (1 << 5),
GNUMode = (1 << 6),
HexFloat = (1 << 7),
ImplicitInt = (1 << 8)
C89 = (1 << 1),
C99 = (1 << 2),
C1X = (1 << 3),
CPlusPlus = (1 << 4),
CPlusPlus0x = (1 << 5),
Digraphs = (1 << 6),
GNUMode = (1 << 7),
HexFloat = (1 << 8),
ImplicitInt = (1 << 9)
};
}
@ -54,6 +55,9 @@ struct LangStandard {
/// hasBCPLComments - Language supports '//' comments.
bool hasBCPLComments() const { return Flags & frontend::BCPLComment; }
/// isC89 - Language is a superset of C89.
bool isC89() const { return Flags & frontend::C89; }
/// isC99 - Language is a superset of C99.
bool isC99() const { return Flags & frontend::C99; }

View File

@ -22,21 +22,21 @@
// C89-ish modes.
LANGSTANDARD(c89, "c89",
"ISO C 1990",
ImplicitInt)
C89 | ImplicitInt)
LANGSTANDARD(c90, "c90",
"ISO C 1990",
ImplicitInt)
C89 | ImplicitInt)
LANGSTANDARD(iso9899_1990, "iso9899:1990",
"ISO C 1990",
ImplicitInt)
C89 | ImplicitInt)
LANGSTANDARD(c94, "iso9899:199409",
"ISO C 1990 with amendment 1",
Digraphs | ImplicitInt)
C89 | Digraphs | ImplicitInt)
LANGSTANDARD(gnu89, "gnu89",
"ISO C 1990 with GNU extensions",
BCPLComment | Digraphs | GNUMode | ImplicitInt)
BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt)
// C99-ish modes
LANGSTANDARD(c99, "c99",
@ -87,7 +87,6 @@ LANGSTANDARD(gnucxx0x, "gnu++0x",
BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode)
// OpenCL
LANGSTANDARD(opencl, "cl",
"OpenCL 1.0",
BCPLComment | C99 | Digraphs | HexFloat)

View File

@ -41,6 +41,10 @@ class PreprocessorOptions {
/// record of all macro definitions and
/// instantiations.
/// \brief Whether the detailed preprocessing record includes nested macro
/// instantiations.
unsigned DetailedRecordIncludesNestedMacroInstantiations : 1;
/// The implicit PCH included at the start of the translation unit, or empty.
std::string ImplicitPCHInclude;
@ -136,6 +140,7 @@ class PreprocessorOptions {
public:
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
DetailedRecordIncludesNestedMacroInstantiations(true),
DisablePCHValidation(false), DisableStatCache(false),
DumpDeserializedPCHDecls(false),
PrecompiledPreambleBytes(0, true),

View File

@ -71,9 +71,6 @@ void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts);
void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS,
const PreprocessorOutputOptions &Opts);
/// CheckDiagnostics - Gather the expected diagnostics and check them.
bool CheckDiagnostics(Preprocessor &PP);
/// AttachDependencyFileGen - Create a dependency file generator, and attach
/// it to the given preprocessor. This takes ownership of the output stream.
void AttachDependencyFileGen(Preprocessor &PP,

View File

@ -31,6 +31,9 @@ struct HeaderFileInfo {
/// isImport - True if this is a #import'd or #pragma once file.
unsigned isImport : 1;
/// isPragmaOnce - True if this is #pragma once file.
unsigned isPragmaOnce : 1;
/// DirInfo - Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
/// by #pragma gcc system_header. This is an instance of
@ -66,8 +69,8 @@ struct HeaderFileInfo {
const IdentifierInfo *ControllingMacro;
HeaderFileInfo()
: isImport(false), DirInfo(SrcMgr::C_User), External(false),
Resolved(false), NumIncludes(0), ControllingMacroID(0),
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0),
ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
@ -77,7 +80,8 @@ struct HeaderFileInfo {
/// \brief Determine whether this is a non-default header file info, e.g.,
/// it corresponds to an actual header we've included or tried to include.
bool isNonDefault() const {
return isImport || NumIncludes || ControllingMacro || ControllingMacroID;
return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
ControllingMacroID;
}
};
@ -101,11 +105,12 @@ class HeaderSearch {
FileManager &FileMgr;
/// #include search path information. Requests for #include "x" search the
/// directory of the #including file first, then each directory in SearchDirs
/// consequtively. Requests for <x> search the current dir first, then each
/// directory in SearchDirs, starting at SystemDirIdx, consequtively. If
/// consecutively. Requests for <x> search the current dir first, then each
/// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
/// NoCurDirSearch is true, then the check for the file in the current
/// directory is suppressed.
std::vector<DirectoryLookup> SearchDirs;
unsigned AngledDirIdx;
unsigned SystemDirIdx;
bool NoCurDirSearch;
@ -156,8 +161,12 @@ class HeaderSearch {
/// SetSearchPaths - Interface for setting the file search paths.
///
void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
unsigned systemDirIdx, bool noCurDirSearch) {
unsigned angledDirIdx, unsigned systemDirIdx,
bool noCurDirSearch) {
assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
"Directory indicies are unordered");
SearchDirs = dirs;
AngledDirIdx = angledDirIdx;
SystemDirIdx = systemDirIdx;
NoCurDirSearch = noCurDirSearch;
//LookupFileCache.clear();
@ -242,7 +251,9 @@ class HeaderSearch {
/// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
/// due to #pragma once.
void MarkFileIncludeOnce(const FileEntry *File) {
getFileInfo(File).isImport = true;
HeaderFileInfo &FI = getFileInfo(File);
FI.isImport = true;
FI.isPragmaOnce = true;
}
/// MarkFileSystemHeader - Mark the specified file as a system header, e.g.
@ -265,6 +276,13 @@ class HeaderSearch {
getFileInfo(File).ControllingMacro = ControllingMacro;
}
/// \brief Determine whether this file is intended to be safe from
/// multiple inclusions, e.g., it has #pragma once or a controlling
/// macro.
///
/// This routine does not consider the effect of #import
bool isFileMultipleIncludeGuarded(const FileEntry *File);
/// CreateHeaderMap - This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE);
@ -285,6 +303,20 @@ class HeaderSearch {
search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
unsigned search_dir_size() const { return SearchDirs.size(); }
search_dir_iterator quoted_dir_begin() const {
return SearchDirs.begin();
}
search_dir_iterator quoted_dir_end() const {
return SearchDirs.begin() + AngledDirIdx;
}
search_dir_iterator angled_dir_begin() const {
return SearchDirs.begin() + AngledDirIdx;
}
search_dir_iterator angled_dir_end() const {
return SearchDirs.begin() + SystemDirIdx;
}
search_dir_iterator system_dir_begin() const {
return SearchDirs.begin() + SystemDirIdx;
}

View File

@ -156,7 +156,9 @@ class StringLiteralParser {
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
const SourceManager &sm, const LangOptions &features,
const TargetInfo &target, Diagnostic *diags = 0)
: SM(sm), Features(features), Target(target), Diags(diags) {
: SM(sm), Features(features), Target(target), Diags(diags),
MaxTokenLength(0), SizeBound(0), wchar_tByteWidth(0),
ResultPtr(ResultBuf.data()), hadError(false), AnyWide(false), Pascal(false) {
init(StringToks, NumStringToks);
}
@ -165,8 +167,8 @@ class StringLiteralParser {
bool AnyWide;
bool Pascal;
const char *GetString() { return &ResultBuf[0]; }
unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; }
const char *GetString() { return ResultBuf.data(); }
unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); }
unsigned GetNumStringChars() const {
if (AnyWide)

View File

@ -258,6 +258,10 @@ namespace clang {
/// including the various preprocessing directives processed, macros
/// instantiated, etc.
class PreprocessingRecord : public PPCallbacks {
/// \brief Whether we should include nested macro instantiations in
/// the preprocessing record.
bool IncludeNestedMacroInstantiations;
/// \brief Allocator used to store preprocessing objects.
llvm::BumpPtrAllocator BumpAlloc;
@ -281,7 +285,8 @@ namespace clang {
void MaybeLoadPreallocatedEntities() const ;
public:
PreprocessingRecord();
/// \brief Construct
explicit PreprocessingRecord(bool IncludeNestedMacroInstantiations);
/// \brief Allocate memory in the preprocessing record.
void *Allocate(unsigned Size, unsigned Align = 8) {
@ -291,6 +296,10 @@ namespace clang {
/// \brief Deallocate memory in the preprocessing record.
void Deallocate(void *Ptr) { }
size_t getTotalMemory() const {
return BumpAlloc.getTotalMemory();
}
// Iteration over the preprocessed entities.
typedef std::vector<PreprocessedEntity *>::iterator iterator;
typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator;

View File

@ -84,6 +84,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_extension; // __has_extension
IdentifierInfo *Ident__has_builtin; // __has_builtin
IdentifierInfo *Ident__has_attribute; // __has_attribute
IdentifierInfo *Ident__has_include; // __has_include
@ -441,7 +442,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();
void createPreprocessingRecord(bool IncludeNestedMacroInstantiations);
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.

View File

@ -580,6 +580,18 @@ class Parser : public CodeCompletionHandler {
/// ExitScope - Pop a scope off the scope stack.
void ExitScope();
/// \brief RAII object used to modify the scope flags for the current scope.
class ParseScopeFlags {
Scope *CurScope;
unsigned OldFlags;
ParseScopeFlags(const ParseScopeFlags &); // do not implement
void operator=(const ParseScopeFlags &); // do not implement
public:
ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
~ParseScopeFlags();
};
//===--------------------------------------------------------------------===//
// Diagnostic Emission and Error recovery.
@ -621,8 +633,8 @@ class Parser : public CodeCompletionHandler {
/// - function bodies
/// - default arguments
/// - exception-specifications (TODO: C++0x)
/// - and brace-or-equal-initializers (TODO: C++0x)
/// for non-static data members (including such things in nested classes)."
/// - and brace-or-equal-initializers for non-static data members
/// (including such things in nested classes)."
/// LateParsedDeclarations build the tree of those elements so they can
/// be parsed after parsing the top-level class.
class LateParsedDeclaration {
@ -630,6 +642,7 @@ class Parser : public CodeCompletionHandler {
virtual ~LateParsedDeclaration();
virtual void ParseLexedMethodDeclarations();
virtual void ParseLexedMemberInitializers();
virtual void ParseLexedMethodDefs();
};
@ -641,6 +654,7 @@ class Parser : public CodeCompletionHandler {
virtual ~LateParsedClass();
virtual void ParseLexedMethodDeclarations();
virtual void ParseLexedMemberInitializers();
virtual void ParseLexedMethodDefs();
private:
@ -714,6 +728,25 @@ class Parser : public CodeCompletionHandler {
llvm::SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
};
/// LateParsedMemberInitializer - An initializer for a non-static class data
/// member whose parsing must to be delayed until the class is completely
/// defined (C++11 [class.mem]p2).
struct LateParsedMemberInitializer : public LateParsedDeclaration {
LateParsedMemberInitializer(Parser *P, Decl *FD)
: Self(P), Field(FD) { }
virtual void ParseLexedMemberInitializers();
Parser *Self;
/// Field - The field declaration.
Decl *Field;
/// CachedTokens - The sequence of tokens that comprises the initializer,
/// including any leading '='.
CachedTokens Toks;
};
/// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
/// C++ class, its method declarations that contain parts that won't be
/// parsed until after the definition is completed (C++ [class.mem]p2),
@ -973,11 +1006,14 @@ class Parser : public CodeCompletionHandler {
Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo,
const VirtSpecifiers& VS);
const VirtSpecifiers& VS, ExprResult& Init);
void ParseCXXNonStaticMemberInitializer(Decl *VarD);
void ParseLexedMethodDeclarations(ParsingClass &Class);
void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
void ParseLexedMethodDefs(ParsingClass &Class);
void ParseLexedMethodDef(LexedMethod &LM);
void ParseLexedMemberInitializers(ParsingClass &Class);
void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
bool ConsumeAndStoreUntil(tok::TokenKind T1,
CachedTokens &Toks,
bool StopAtSemi = true,
@ -1000,7 +1036,7 @@ class Parser : public CodeCompletionHandler {
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
ParsingDeclSpec *DS = 0);
bool isDeclarationAfterDeclarator() const;
bool isDeclarationAfterDeclarator();
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
AccessSpecifier AS = AS_none);
@ -1308,7 +1344,12 @@ class Parser : public CodeCompletionHandler {
StmtResult ParseReturnStatement(ParsedAttributes &Attr);
StmtResult ParseAsmStatement(bool &msAsm);
StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
bool ParseMicrosoftIfExistsCondition(bool& Result);
void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
void ParseMicrosoftIfExistsExternalDeclaration();
void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
AccessSpecifier& CurAS);
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
llvm::SmallVectorImpl<ExprTy *> &Constraints,
llvm::SmallVectorImpl<ExprTy *> &Exprs);
@ -1645,6 +1686,7 @@ class Parser : public CodeCompletionHandler {
void ParseTypeofSpecifier(DeclSpec &DS);
void ParseDecltypeSpecifier(DeclSpec &DS);
void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
ExprResult ParseCXX0XAlignArgument(SourceLocation Start);
@ -1714,6 +1756,12 @@ class Parser : public CodeCompletionHandler {
Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd,
SourceLocation InlineLoc = SourceLocation());
void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
std::vector<IdentifierInfo*>& Ident,
std::vector<SourceLocation>& NamespaceLoc,
unsigned int index, SourceLocation& InlineLoc,
SourceLocation& LBrace, ParsedAttributes& attrs,
SourceLocation& RBraceLoc);
Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context);
Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
const ParsedTemplateInfo &TemplateInfo,
@ -1743,6 +1791,8 @@ class Parser : public CodeCompletionHandler {
bool SuppressDeclarations = false);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(bool IsFunction,
SourceLocation &EqualLoc);
void ParseCXXClassMemberDeclaration(AccessSpecifier AS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
ParsingDeclRAIIObject *DiagsFromTParams = 0);

View File

@ -88,7 +88,10 @@ enum {
/// \brief Adjustment for KVC code pattern priorities when it doesn't look
/// like the
CCD_ProbablyNotObjCCollection = 15
CCD_ProbablyNotObjCCollection = 15,
/// \brief An Objective-C method being used as a property.
CCD_MethodAsProperty = 2
};
/// \brief Priority value factors by which we will divide or multiply the

View File

@ -249,6 +249,7 @@ class DeclSpec {
static const TST TST_typeofType = clang::TST_typeofType;
static const TST TST_typeofExpr = clang::TST_typeofExpr;
static const TST TST_decltype = clang::TST_decltype;
static const TST TST_underlyingType = clang::TST_underlyingType;
static const TST TST_auto = clang::TST_auto;
static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
static const TST TST_error = clang::TST_error;
@ -344,7 +345,8 @@ class DeclSpec {
void SaveStorageSpecifierAsWritten();
static bool isTypeRep(TST T) {
return (T == TST_typename || T == TST_typeofType);
return (T == TST_typename || T == TST_typeofType ||
T == TST_underlyingType);
}
static bool isExprRep(TST T) {
return (T == TST_typeofExpr || T == TST_decltype);
@ -462,6 +464,14 @@ class DeclSpec {
SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
/// \brief Clear out all of the type qualifiers.
void ClearTypeQualifiers() {
TypeQualifiers = 0;
TQ_constLoc = SourceLocation();
TQ_restrictLoc = SourceLocation();
TQ_volatileLoc = SourceLocation();
}
// function-specifier
bool isInlineSpecified() const { return FS_inline_specified; }
SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
@ -1068,8 +1078,8 @@ struct DeclaratorChunk {
/// If this is an invalid location, there is no ref-qualifier.
unsigned RefQualifierLoc;
/// \brief When ExceptionSpecType isn't EST_None, the location of the
/// keyword introducing the spec.
/// \brief When ExceptionSpecType isn't EST_None or EST_Delayed, the
/// location of the keyword introducing the spec.
unsigned ExceptionSpecLoc;
/// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
@ -1332,7 +1342,8 @@ class Declarator {
CXXCatchContext, // C++ catch exception-declaration
BlockLiteralContext, // Block literal declarator.
TemplateTypeArgContext, // Template type argument.
AliasDeclContext // C++0x alias-declaration.
AliasDeclContext, // C++0x alias-declaration.
AliasTemplateContext // C++0x alias-declaration template.
};
private:
@ -1474,6 +1485,7 @@ class Declarator {
case TypeNameContext:
case AliasDeclContext:
case AliasTemplateContext:
case PrototypeContext:
case ObjCPrototypeContext:
case TemplateParamContext:
@ -1503,6 +1515,7 @@ class Declarator {
case TypeNameContext:
case AliasDeclContext:
case AliasTemplateContext:
case ObjCPrototypeContext:
case BlockLiteralContext:
case TemplateTypeArgContext:
@ -1531,6 +1544,7 @@ class Declarator {
case CXXCatchContext:
case TypeNameContext:
case AliasDeclContext:
case AliasTemplateContext:
case BlockLiteralContext:
case TemplateTypeArgContext:
return false;
@ -1602,6 +1616,29 @@ class Declarator {
DeclTypeInfo.erase(DeclTypeInfo.begin());
}
/// isArrayOfUnknownBound - This method returns true if the declarator
/// is a declarator for an array of unknown bound (looking through
/// parentheses).
bool isArrayOfUnknownBound() const {
for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
switch (DeclTypeInfo[i].Kind) {
case DeclaratorChunk::Paren:
continue;
case DeclaratorChunk::Function:
case DeclaratorChunk::Pointer:
case DeclaratorChunk::Reference:
case DeclaratorChunk::BlockPointer:
case DeclaratorChunk::MemberPointer:
return false;
case DeclaratorChunk::Array:
return !DeclTypeInfo[i].Arr.NumElts;
}
llvm_unreachable("Invalid type chunk");
return false;
}
return false;
}
/// isFunctionDeclarator - This method returns true if the declarator
/// is a function declarator (looking through parentheses).
/// If true is returned, then the reference type parameter idx is

View File

@ -101,7 +101,8 @@ class InitializedEntity {
/// the temporary is being created.
unsigned Location;
/// \brief Whether the
/// \brief Whether the entity being initialized may end up using the
/// named return value optimization (NRVO).
bool NRVO;
} LocAndNRVO;
@ -436,48 +437,21 @@ class InitializationKind {
class InitializationSequence {
public:
/// \brief Describes the kind of initialization sequence computed.
///
/// FIXME: Much of this information is in the initialization steps... why is
/// it duplicated here?
enum SequenceKind {
/// \brief A failed initialization sequence. The failure kind tells what
/// happened.
FailedSequence = 0,
/// \brief A dependent initialization, which could not be
/// type-checked due to the presence of dependent types or
/// dependently-type expressions.
/// dependently-typed expressions.
DependentSequence,
/// \brief A user-defined conversion sequence.
UserDefinedConversion,
/// \brief A constructor call.
ConstructorInitialization,
/// \brief A normal sequence.
NormalSequence,
/// \brief A reference binding.
ReferenceBinding,
/// \brief List initialization
ListInitialization,
/// \brief Zero-initialization.
ZeroInitialization,
/// \brief No initialization required.
NoInitialization,
/// \brief Standard conversion sequence.
StandardConversion,
/// \brief C conversion sequence.
CAssignment,
/// \brief String initialization
StringInit,
/// \brief Array initialization from another array (GNU C extension).
ArrayInit
ReferenceBinding // FIXME: Still looks redundant, but complicated.
};
/// \brief Describes the kind of a particular step in an initialization
@ -697,7 +671,10 @@ class InitializationSequence {
void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
/// \brief Determine whether the initialization sequence is valid.
operator bool() const { return SequenceKind != FailedSequence; }
operator bool() const { return !Failed(); }
/// \brief Determine whether the initialization sequence is invalid.
bool Failed() const { return SequenceKind == FailedSequence; }
typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator;
step_iterator step_begin() const { return Steps.begin(); }
@ -821,7 +798,7 @@ class InitializationSequence {
/// \brief Determine why initialization failed.
FailureKind getFailureKind() const {
assert(getKind() == FailedSequence && "Not an initialization failure!");
assert(Failed() && "Not an initialization failure!");
return Failure;
}

View File

@ -282,6 +282,18 @@ class LookupResult {
return NamingClass != 0;
}
/// \brief Set whether the name lookup is triggered by a
/// using declaration.
void setUsingDeclaration(bool U) {
UsingDeclaration = U;
}
/// \brief Returns whether the name lookup is triggered by a
/// using declaration.
bool isUsingDeclaration() const {
return UsingDeclaration;
}
/// \brief Returns the 'naming class' for this lookup, i.e. the
/// class which was looked into to find these results.
///
@ -603,6 +615,10 @@ class LookupResult {
bool HideTags;
bool Diagnose;
/// \brief True if the lookup is triggered by a using declaration.
/// Necessary to handle a MSVC bug.
bool UsingDeclaration;
};
/// \brief Consumes visible declarations found when searching for

View File

@ -202,8 +202,7 @@ namespace clang {
void setAsIdentityConversion();
bool isIdentityConversion() const {
return First == ICK_Identity && Second == ICK_Identity &&
Third == ICK_Identity;
return Second == ICK_Identity && Third == ICK_Identity;
}
ImplicitConversionRank getRank() const;

View File

@ -79,7 +79,12 @@ class Scope {
ObjCMethodScope = 0x400,
/// SwitchScope - This is a scope that corresponds to a switch statement.
SwitchScope = 0x800
SwitchScope = 0x800,
/// ThisScope - This is the scope of a struct/union/class definition,
/// outside of any member function definition, where 'this' is nonetheless
/// usable.
ThisScope = 0x1000
};
private:
/// The parent scope for this scope. This is null for the translation-unit

View File

@ -312,6 +312,17 @@ class Sema {
/// and must warn if not used. Only contains the first declaration.
llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls;
/// \brief All the delegating constructors seen so far in the file, used for
/// cycle detection at the end of the TU.
llvm::SmallVector<CXXConstructorDecl*, 4> DelegatingCtorDecls;
/// \brief All the overriding destructors seen during a class definition
/// (there could be multiple due to nested classes) that had their exception
/// spec checks delayed, plus the overridden destructor.
llvm::SmallVector<std::pair<const CXXDestructorDecl*,
const CXXDestructorDecl*>, 2>
DelayedDestructorExceptionSpecChecks;
/// \brief Callback to the parser to parse templated functions when needed.
typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD);
LateTemplateParserCB *LateTemplateParser;
@ -589,6 +600,44 @@ class Sema {
/// A stack of expression evaluation contexts.
llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
/// SpecialMemberOverloadResult - The overloading result for a special member
/// function.
///
/// This is basically a wrapper around PointerIntPair. The lowest bit of the
/// integer is used to determine whether we have a parameter qualification
/// match, the second-lowest is whether we had success in resolving the
/// overload to a unique non-deleted function.
///
/// The ConstParamMatch bit represents whether, when looking up a copy
/// constructor or assignment operator, we found a potential copy
/// constructor/assignment operator whose first parameter is const-qualified.
/// This is used for determining parameter types of other objects and is
/// utterly meaningless on other types of special members.
class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
public:
SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
: FastFoldingSetNode(ID)
{}
CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
bool hasSuccess() const { return Pair.getInt() & 0x1; }
void setSuccess(bool B) {
Pair.setInt(unsigned(B) | hasConstParamMatch() << 1);
}
bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
void setConstParamMatch(bool B) {
Pair.setInt(B << 1 | unsigned(hasSuccess()));
}
};
/// \brief A cache of special member function overload resolution results
/// for C++ records.
llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache;
/// \brief Whether the code handled by Sema should be considered a
/// complete translation unit or not.
///
@ -704,6 +753,8 @@ class Sema {
void ActOnEndOfTranslationUnit();
void CheckDelegatingCtorCycles();
Scope *getScopeForContext(DeclContext *Ctx);
void PushFunctionScope();
@ -795,12 +846,19 @@ class Sema {
const PartialDiagnostic &PD);
bool RequireCompleteType(SourceLocation Loc, QualType T,
unsigned DiagID);
bool RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
std::pair<SourceLocation,
PartialDiagnostic> Note);
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
const CXXScopeSpec &SS, QualType T);
QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
QualType BuildDecltypeType(Expr *E, SourceLocation Loc);
QualType BuildUnaryTransformType(QualType BaseType,
UnaryTransformType::UTTKind UKind,
SourceLocation Loc);
//===--------------------------------------------------------------------===//
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
@ -925,7 +983,8 @@ class Sema {
SourceLocation NameLoc,
const Token &NextToken);
Decl *ActOnDeclarator(Scope *S, Declarator &D);
Decl *ActOnDeclarator(Scope *S, Declarator &D,
bool IsFunctionDefintion = false);
Decl *HandleDeclarator(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
@ -938,6 +997,7 @@ class Sema {
void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
void CheckShadow(Scope *S, VarDecl *D);
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange);
void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, TypeSourceInfo *TInfo,
LookupResult &Previous, bool &Redeclaration);
@ -988,6 +1048,7 @@ class Sema {
void ActOnInitializerError(Decl *Dcl);
void ActOnCXXForRangeDecl(Decl *D);
void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
void FinalizeDeclaration(Decl *D);
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
Decl **Group,
@ -1026,10 +1087,11 @@ class Sema {
void ActOnPopScope(SourceLocation Loc, Scope *S);
void ActOnTranslationUnitScope(Scope *S);
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DeclSpec &DS);
Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DeclSpec &DS,
MultiTemplateParamsArg TemplateParams);
StmtResult ActOnVlaStmt(const DeclSpec &DS);
@ -1041,7 +1103,7 @@ class Sema {
RecordDecl *Record);
bool isAcceptableTagRedeclaration(const TagDecl *Previous,
TagTypeKind NewTag,
TagTypeKind NewTag, bool isDefinition,
SourceLocation NewTagLoc,
const IdentifierInfo &Name);
@ -1082,23 +1144,25 @@ class Sema {
Declarator &D, Expr *BitfieldWidth);
FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
Declarator &D, Expr *BitfieldWidth,
Declarator &D, Expr *BitfieldWidth, bool HasInit,
AccessSpecifier AS);
FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
TypeSourceInfo *TInfo,
RecordDecl *Record, SourceLocation Loc,
bool Mutable, Expr *BitfieldWidth,
bool Mutable, Expr *BitfieldWidth, bool HasInit,
SourceLocation TSSL,
AccessSpecifier AS, NamedDecl *PrevDecl,
Declarator *D = 0);
enum CXXSpecialMember {
CXXInvalid = -1,
CXXConstructor = 0,
CXXCopyConstructor = 1,
CXXCopyAssignment = 2,
CXXDestructor = 3
CXXDefaultConstructor,
CXXCopyConstructor,
CXXMoveConstructor,
CXXCopyAssignment,
CXXMoveAssignment,
CXXDestructor,
CXXInvalid
};
bool CheckNontrivialField(FieldDecl *FD);
void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
@ -1283,6 +1347,8 @@ class Sema {
QualType ResultType,
Expr *Value);
bool CanPerformCopyInitialization(const InitializedEntity &Entity,
ExprResult Init);
ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
SourceLocation EqualLoc,
ExprResult Init);
@ -1566,6 +1632,14 @@ class Sema {
private:
bool CppLookupName(LookupResult &R, Scope *S);
SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
CXXSpecialMember SM,
bool ConstArg,
bool VolatileArg,
bool RValueThis,
bool ConstThis,
bool VolatileThis);
public:
/// \brief Look up a name, looking for a single declaration. Return
/// null if the results were absent, ambiguous, or overloaded.
@ -1594,6 +1668,10 @@ class Sema {
SourceLocation GnuLabelLoc = SourceLocation());
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
CXXConstructorDecl *LookupCopyConstructor(CXXRecordDecl *Class,
unsigned Quals,
bool *ConstParam = 0);
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
@ -1645,6 +1723,10 @@ class Sema {
AssociatedNamespaceSet &AssociatedNamespaces,
AssociatedClassSet &AssociatedClasses);
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
bool ConsiderLinkage,
bool ExplicitInstantiationOrSpecialization);
bool DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
@ -2067,7 +2149,14 @@ class Sema {
void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
void MarkDeclarationsReferencedInExpr(Expr *E);
/// \brief Figure out if an expression could be turned into a call.
bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy,
UnresolvedSetImpl &NonTemplateOverloads);
/// \brief Give notes for a set of overloads.
void NoteOverloads(const UnresolvedSetImpl &Overloads,
const SourceLocation FinalNoteLoc);
/// \brief Conditionally issue a diagnostic based on the current
/// evaluation context.
///
@ -2177,8 +2266,7 @@ class Sema {
UnaryExprOrTypeTrait ExprKind,
SourceRange R);
ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
UnaryExprOrTypeTrait ExprKind,
SourceRange R);
UnaryExprOrTypeTrait ExprKind);
ExprResult
ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc,
UnaryExprOrTypeTrait ExprKind,
@ -2186,8 +2274,9 @@ class Sema {
const SourceRange &ArgRange);
ExprResult CheckPlaceholderExpr(Expr *E);
bool CheckVecStepExpr(Expr *E, SourceLocation OpLoc, SourceRange R);
bool CheckVecStepExpr(Expr *E);
bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind);
bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc,
SourceRange R,
UnaryExprOrTypeTrait ExprKind);
@ -2364,6 +2453,8 @@ class Sema {
bool CheckCaseExpression(Expr *expr);
bool CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, UnqualifiedId &Name);
//===------------------------- "Block" Extension ------------------------===//
/// ActOnBlockStart - This callback is invoked when a block literal is
@ -2383,6 +2474,13 @@ class Sema {
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
Stmt *Body, Scope *CurScope);
//===---------------------------- OpenCL Features -----------------------===//
/// __builtin_astype(...)
ExprResult ActOnAsTypeExpr(Expr *expr, ParsedType DestTy,
SourceLocation BuiltinLoc,
SourceLocation RParenLoc);
//===---------------------------- C++ Features --------------------------===//
// Act on C++ namespaces
@ -2454,6 +2552,7 @@ class Sema {
SourceLocation TypenameLoc);
Decl *ActOnAliasDeclaration(Scope *CurScope,
AccessSpecifier AS,
MultiTemplateParamsArg TemplateParams,
SourceLocation UsingLoc,
UnqualifiedId &Name,
TypeResult Type);
@ -2502,6 +2601,111 @@ class Sema {
/// constructed variable.
void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
/// \brief Helper class that collects exception specifications for
/// implicitly-declared special member functions.
class ImplicitExceptionSpecification {
// Pointer to allow copying
ASTContext *Context;
// We order exception specifications thus:
// noexcept is the most restrictive, but is only used in C++0x.
// throw() comes next.
// Then a throw(collected exceptions)
// Finally no specification.
// throw(...) is used instead if any called function uses it.
//
// If this exception specification cannot be known yet (for instance,
// because this is the exception specification for a defaulted default
// constructor and we haven't finished parsing the deferred parts of the
// class yet), the C++0x standard does not specify how to behave. We
// record this as an 'unknown' exception specification, which overrules
// any other specification (even 'none', to keep this rule simple).
ExceptionSpecificationType ComputedEST;
llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
llvm::SmallVector<QualType, 4> Exceptions;
void ClearExceptions() {
ExceptionsSeen.clear();
Exceptions.clear();
}
public:
explicit ImplicitExceptionSpecification(ASTContext &Context)
: Context(&Context), ComputedEST(EST_BasicNoexcept) {
if (!Context.getLangOptions().CPlusPlus0x)
ComputedEST = EST_DynamicNone;
}
/// \brief Get the computed exception specification type.
ExceptionSpecificationType getExceptionSpecType() const {
assert(ComputedEST != EST_ComputedNoexcept &&
"noexcept(expr) should not be a possible result");
return ComputedEST;
}
/// \brief The number of exceptions in the exception specification.
unsigned size() const { return Exceptions.size(); }
/// \brief The set of exceptions in the exception specification.
const QualType *data() const { return Exceptions.data(); }
/// \brief Integrate another called method into the collected data.
void CalledDecl(CXXMethodDecl *Method);
/// \brief Integrate an invoked expression into the collected data.
void CalledExpr(Expr *E);
/// \brief Specify that the exception specification can't be detemined yet.
void SetDelayed() {
ClearExceptions();
ComputedEST = EST_Delayed;
}
FunctionProtoType::ExtProtoInfo getEPI() const {
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExceptionSpecType = getExceptionSpecType();
EPI.NumExceptions = size();
EPI.Exceptions = data();
return EPI;
}
};
/// \brief Determine what sort of exception specification a defaulted
/// copy constructor of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl);
/// \brief Determine what sort of exception specification a defaulted
/// default constructor of a class will have, and whether the parameter
/// will be const.
std::pair<ImplicitExceptionSpecification, bool>
ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl);
/// \brief Determine what sort of exception specification a defautled
/// copy assignment operator of a class will have, and whether the
/// parameter will be const.
std::pair<ImplicitExceptionSpecification, bool>
ComputeDefaultedCopyAssignmentExceptionSpecAndConst(CXXRecordDecl *ClassDecl);
/// \brief Determine what sort of exception specification a defaulted
/// destructor of a class will have.
ImplicitExceptionSpecification
ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl);
/// \brief Determine if a defaulted default constructor ought to be
/// deleted.
bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD);
/// \brief Determine if a defaulted copy constructor ought to be
/// deleted.
bool ShouldDeleteCopyConstructor(CXXConstructorDecl *CD);
/// \brief Determine if a defaulted copy assignment operator ought to be
/// deleted.
bool ShouldDeleteCopyAssignmentOperator(CXXMethodDecl *MD);
/// \brief Determine if a defaulted destructor ought to be deleted.
bool ShouldDeleteDestructor(CXXDestructorDecl *DD);
/// \brief Declare the implicit default constructor for the given class.
///
/// \param ClassDecl The class declaration into which the implicit
@ -2529,6 +2733,13 @@ class Sema {
void DefineImplicitDestructor(SourceLocation CurrentLocation,
CXXDestructorDecl *Destructor);
/// \brief Build an exception spec for destructors that don't have one.
///
/// C++11 says that user-defined destructors with no exception spec get one
/// that looks as if the destructor was implicitly declared.
void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
CXXDestructorDecl *Destructor);
/// \brief Declare all inherited constructors for the given class.
///
/// \param ClassDecl The class declaration into which the inherited
@ -2549,8 +2760,7 @@ class Sema {
/// DefineImplicitCopyConstructor - Checks for feasibility of
/// defining this constructor as the copy constructor.
void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
CXXConstructorDecl *Constructor,
unsigned TypeQuals);
CXXConstructorDecl *Constructor);
/// \brief Declare the implicit copy assignment operator for the given class.
///
@ -2587,6 +2797,10 @@ class Sema {
ParsedType ObjectType,
bool EnteringContext);
// Checks that reinterpret casts don't have undefined behavior.
void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
bool IsDereference, SourceRange Range);
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
tok::TokenKind Kind,
@ -2638,10 +2852,9 @@ class Sema {
//// ActOnCXXThis - Parse 'this' pointer.
ExprResult ActOnCXXThis(SourceLocation loc);
/// tryCaptureCXXThis - Try to capture a 'this' pointer. Returns a
/// pointer to an instance method whose 'this' pointer is
/// capturable, or null if this is not possible.
CXXMethodDecl *tryCaptureCXXThis();
/// getAndCaptureCurrentThisType - Try to capture a 'this' pointer. Returns
/// the type of the 'this' pointer, or a null type if this is not possible.
QualType getAndCaptureCurrentThisType();
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
@ -2699,14 +2912,16 @@ class Sema {
bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
DeclarationName Name, Expr** Args,
unsigned NumArgs, DeclContext *Ctx,
bool AllowMissing, FunctionDecl *&Operator);
bool AllowMissing, FunctionDecl *&Operator,
bool Diagnose = true);
void DeclareGlobalNewDelete();
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
QualType Argument,
bool addMallocAttr = false);
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name, FunctionDecl* &Operator);
DeclarationName Name, FunctionDecl* &Operator,
bool Diagnose = true);
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
ExprResult ActOnCXXDelete(SourceLocation StartLoc,
@ -2985,7 +3200,7 @@ class Sema {
Expr **Strings,
unsigned NumStrings);
Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
TypeSourceInfo *EncodedTypeInfo,
SourceLocation RParenLoc);
ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
@ -3038,8 +3253,10 @@ class Sema {
Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
Expr *BitfieldWidth, const VirtSpecifiers &VS,
Expr *Init, bool IsDefinition,
bool Deleted = false);
Expr *Init, bool HasDeferredInit,
bool IsDefinition);
void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc,
Expr *Init);
MemInitResult ActOnMemInitializer(Decl *ConstructorD,
Scope *S,
@ -3143,8 +3360,9 @@ class Sema {
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record);
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnFinishDelayedMemberInitializers(Decl *Record);
void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true);
bool IsInsideALocalClassWithinATemplateFunction();
@ -3170,6 +3388,12 @@ class Sema {
StorageClass& SC);
Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record);
void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor);
void CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *Ctor);
void CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *Method);
void CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *Dtor);
//===--------------------------------------------------------------------===//
// C++ Derived Classes
//
@ -3257,12 +3481,17 @@ class Sema {
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
SourceRange PlacementRange,
CXXRecordDecl *NamingClass,
DeclAccessPair FoundDecl);
DeclAccessPair FoundDecl,
bool Diagnose = true);
AccessResult CheckConstructorAccess(SourceLocation Loc,
CXXConstructorDecl *D,
const InitializedEntity &Entity,
AccessSpecifier Access,
bool IsCopyBindingRefToTemp = false);
AccessResult CheckConstructorAccess(SourceLocation Loc,
CXXConstructorDecl *D,
AccessSpecifier Access,
PartialDiagnostic PD);
AccessResult CheckDestructorAccess(SourceLocation Loc,
CXXDestructorDecl *Dtor,
const PartialDiagnostic &PDiag);
@ -3394,7 +3623,8 @@ class Sema {
TPC_FunctionTemplate,
TPC_ClassTemplateMember,
TPC_FriendFunctionTemplate,
TPC_FriendFunctionTemplateDefinition
TPC_FriendFunctionTemplateDefinition,
TPC_TypeAliasTemplate
};
bool CheckTemplateParameterList(TemplateParameterList *NewParams,
@ -3402,6 +3632,7 @@ class Sema {
TemplateParamListContext TPC);
TemplateParameterList *
MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
SourceLocation DeclLoc,
const CXXScopeSpec &SS,
TemplateParameterList **ParamLists,
unsigned NumParamLists,
@ -4507,7 +4738,7 @@ class Sema {
/// types, static variables, enumerators, etc.
std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
bool PerformPendingInstantiations(bool LocalOnly = false);
void PerformPendingInstantiations(bool LocalOnly = false);
TypeSourceInfo *SubstType(TypeSourceInfo *T,
const MultiLevelTemplateArgumentList &TemplateArgs,
@ -4644,7 +4875,7 @@ class Sema {
IdentifierInfo *AliasName, SourceLocation AliasLocation,
IdentifierInfo *ClassName, SourceLocation ClassLocation);
void CheckForwardProtocolDeclarationForCircularDependency(
bool CheckForwardProtocolDeclarationForCircularDependency(
IdentifierInfo *PName,
SourceLocation &PLoc, SourceLocation PrevLoc,
const ObjCList<ObjCProtocolDecl> &PList);
@ -4769,7 +5000,7 @@ class Sema {
SourceLocation EndLoc, // location of the ; or {.
tok::TokenKind MethodType,
Decl *ClassDecl, ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
Selector Sel,
SourceLocation SelectorStartLoc, Selector Sel,
// optional arguments. The number of types/arguments is obtained
// from the Sel.getNumArgs().
ObjCArgInfo *ArgInfo,
@ -4867,7 +5098,18 @@ class Sema {
SourceLocation RBracLoc,
MultiExprArg Args);
/// \brief Check whether the given new method is a valid override of the
/// given overridden method, and set any properties that should be inherited.
///
/// \returns True if an error occurred.
bool CheckObjCMethodOverride(ObjCMethodDecl *NewMethod,
const ObjCMethodDecl *Overridden,
bool IsImplementation);
/// \brief Check whether the given method overrides any methods in its class,
/// calling \c CheckObjCMethodOverride for each overridden method.
bool CheckObjCMethodOverrides(ObjCMethodDecl *NewMethod, DeclContext *DC);
enum PragmaOptionsAlignKind {
POAK_Native, // #pragma options align=native
POAK_Natural, // #pragma options align=natural
@ -5289,11 +5531,24 @@ class Sema {
/// \param Method - May be null.
/// \param [out] ReturnType - The return type of the send.
/// \return true iff there were any incompatible types.
bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
bool CheckMessageArgumentTypes(QualType ReceiverType,
Expr **Args, unsigned NumArgs, Selector Sel,
ObjCMethodDecl *Method, bool isClassMessage,
bool isSuperMessage,
SourceLocation lbrac, SourceLocation rbrac,
QualType &ReturnType, ExprValueKind &VK);
/// \brief Determine the result of a message send expression based on
/// the type of the receiver, the method expected to receive the message,
/// and the form of the message send.
QualType getMessageSendResultType(QualType ReceiverType,
ObjCMethodDecl *Method,
bool isClassMessage, bool isSuperMessage);
/// \brief If the given expression involves a message send to a method
/// with a related result type, emit a note describing what happened.
void EmitRelatedResultTypeNote(const Expr *E);
/// CheckBooleanCondition - Diagnose problems involving the use of
/// the given expression as a boolean condition (e.g. in an if
/// statement). Also performs the standard function and array
@ -5547,7 +5802,8 @@ class Sema {
unsigned format_idx, unsigned firstDataArg,
bool isPrintf);
void CheckMemsetArguments(const CallExpr *Call);
void CheckMemsetcpymoveArguments(const CallExpr *Call,
const IdentifierInfo *FnName);
void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
SourceLocation ReturnLoc);

View File

@ -335,9 +335,9 @@ namespace clang {
Decl *VisitLabelDecl(LabelDecl *D);
Decl *VisitNamespaceDecl(NamespaceDecl *D);
Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
Decl *VisitTypedefDecl(TypedefDecl *D);
Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
Decl *VisitVarDecl(VarDecl *D);
Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
Decl *VisitFieldDecl(FieldDecl *D);
@ -415,6 +415,7 @@ namespace clang {
bool SubstQualifier(const TagDecl *OldDecl,
TagDecl *NewDecl);
Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
ClassTemplatePartialSpecializationDecl *
InstantiateClassTemplatePartialSpecialization(
ClassTemplateDecl *ClassTemplate,

View File

@ -279,7 +279,9 @@ namespace clang {
/// generate the AST file.
ORIGINAL_FILE_NAME = 19,
/// Record #20 intentionally left blank.
/// \brief Record code for the file ID of the original file used to
/// generate the AST file.
ORIGINAL_FILE_ID = 20,
/// \brief Record code for the version control branch and revision
/// information of the compiler used to build this AST file.
@ -362,7 +364,15 @@ namespace clang {
FP_PRAGMA_OPTIONS = 42,
/// \brief Record code for enabled OpenCL extensions.
OPENCL_EXTENSIONS = 43
OPENCL_EXTENSIONS = 43,
/// \brief The list of delegating constructor declarations.
DELEGATING_CTORS = 44,
/// \brief Record code for the table of offsets into the block
/// of file source-location information.
FILE_SOURCE_LOCATION_OFFSETS = 45
};
/// \brief Record types used within a source manager block.
@ -504,6 +514,9 @@ namespace clang {
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 100;
/// \brief The number of allowed abbreviations in bits
const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4;
/// \brief Record codes for each kind of type.
///
/// These constants describe the type records that can occur within a
@ -584,7 +597,9 @@ namespace clang {
/// \brief A SubstTemplateTypeParmPackType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37,
/// \brief A AutoType record.
TYPE_AUTO = 38
TYPE_AUTO = 38,
/// \brief A UnaryTransformType record.
TYPE_UNARY_TRANSFORM = 39
};
/// \brief The type IDs for special types constructed by semantic
@ -758,6 +773,8 @@ namespace clang {
DECL_NON_TYPE_TEMPLATE_PARM,
/// \brief A TemplateTemplateParmDecl record.
DECL_TEMPLATE_TEMPLATE_PARM,
/// \brief A TypeAliasTemplateDecl record.
DECL_TYPE_ALIAS_TEMPLATE,
/// \brief A StaticAssertDecl record.
DECL_STATIC_ASSERT,
/// \brief A record containing CXXBaseSpecifiers.
@ -986,7 +1003,10 @@ namespace clang {
// CUDA
EXPR_CUDA_KERNEL_CALL // CUDAKernelCallExpr
EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr
// OpenCL
EXPR_ASTYPE // An AsTypeExpr record.
};
/// \brief The kinds of designators that can occur in a
@ -1003,6 +1023,15 @@ namespace clang {
DESIG_ARRAY_RANGE = 3
};
/// \brief The different kinds of data that can occur in a
/// CtorInitializer.
enum CtorInitializerType {
CTOR_INITIALIZER_BASE,
CTOR_INITIALIZER_DELEGATING,
CTOR_INITIALIZER_MEMBER,
CTOR_INITIALIZER_INDIRECT_MEMBER
};
/// @}
}
} // end namespace clang

View File

@ -54,6 +54,7 @@ class Decl;
class DeclContext;
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXConstructorDecl;
class CXXCtorInitializer;
class GotoStmt;
class MacroDefinition;
@ -256,6 +257,13 @@ class ASTReader
/// AST file.
const uint32_t *SLocOffsets;
/// \brief The number of source location file entries in this AST file.
unsigned LocalNumSLocFileEntries;
/// \brief Offsets for all of the source location file entries in the
/// AST file.
const uint32_t *SLocFileOffsets;
/// \brief The entire size of this module's source location offset range.
unsigned LocalSLocSize;
@ -564,6 +572,10 @@ class ASTReader
/// generating warnings.
llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls;
/// \brief A list of all the delegating constructors we've seen, to diagnose
/// cycles.
llvm::SmallVector<uint64_t, 4> DelegatingCtorDecls;
/// \brief A snapshot of Sema's weak undeclared identifier tracking, for
/// generating warnings.
llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers;
@ -626,6 +638,10 @@ class ASTReader
/// AST file.
std::string ActualOriginalFileName;
/// \brief The file ID for the original file that was used to build the
/// primary AST file.
FileID OriginalFileID;
/// \brief The directory that the PCH was originally created in. Used to
/// allow resolving headers even after headers+PCH was moved to a new path.
std::string OriginalDir;
@ -780,6 +796,10 @@ class ASTReader
/// \brief Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(PerFileData &F);
/// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take
/// into account all the necessary relocations.
const FileEntry *getFileEntry(llvm::StringRef filename);
void MaybeAddSystemRootToFilename(std::string &Filename);
ASTReadResult ReadASTCore(llvm::StringRef FileName, ASTFileType Type);
@ -879,6 +899,10 @@ class ASTReader
/// name.
ASTReadResult ReadAST(const std::string &FileName, ASTFileType Type);
/// \brief Checks that no file that is stored in PCH is out-of-sync with
/// the actual file in the file system.
ASTReadResult validateFileEntries();
/// \brief Set the AST callbacks listener.
void setListener(ASTReaderListener *listener) {
Listener.reset(listener);

View File

@ -338,10 +338,20 @@ class ASTWriter : public ASTDeserializationListener,
void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
unsigned ParmVarDeclAbbrev;
unsigned DeclParmVarAbbrev;
unsigned DeclContextLexicalAbbrev;
unsigned DeclContextVisibleLookupAbbrev;
unsigned UpdateVisibleAbbrev;
unsigned DeclRefExprAbbrev;
unsigned CharacterLiteralAbbrev;
unsigned DeclRecordAbbrev;
unsigned IntegerLiteralAbbrev;
unsigned DeclTypedefAbbrev;
unsigned DeclVarAbbrev;
unsigned DeclFieldAbbrev;
unsigned DeclEnumAbbrev;
unsigned DeclObjCIvarAbbrev;
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
@ -568,7 +578,16 @@ class ASTWriter : public ASTDeserializationListener,
/// \brief Retrieve the ID for the given opaque value expression.
unsigned getOpaqueValueID(OpaqueValueExpr *e);
unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
bool hasChain() const { return Chain; }

View File

@ -63,6 +63,24 @@ class ASTCodeBody {
}
};
class EndOfTranslationUnit {
template <typename CHECKER>
static void _checkEndOfTranslationUnit(void *checker,
const TranslationUnitDecl *TU,
AnalysisManager& mgr,
BugReporter &BR) {
((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
}
public:
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr){
mgr._registerForEndOfTranslationUnit(
CheckerManager::CheckEndOfTranslationUnit(checker,
_checkEndOfTranslationUnit<CHECKER>));
}
};
template <typename STMT>
class PreStmt {
template <typename CHECKER>
@ -240,9 +258,11 @@ class DeadSymbols {
class RegionChanges {
template <typename CHECKER>
static const GRState *_checkRegionChanges(void *checker, const GRState *state,
const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion * const *Begin,
const MemRegion * const *End) {
return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End);
return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
Begin, End);
}
template <typename CHECKER>
static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) {

View File

@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include <vector>
namespace clang {
@ -49,6 +50,18 @@ class GraphExpander {
template <typename T> class CheckerFn;
template <typename RET, typename P1, typename P2, typename P3, typename P4>
class CheckerFn<RET(P1, P2, P3, P4)> {
typedef RET (*Func)(void *, P1, P2, P3, P4);
Func Fn;
public:
void *Checker;
CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
return Fn(Checker, p1, p2, p3, p4);
}
};
template <typename RET, typename P1, typename P2, typename P3>
class CheckerFn<RET(P1, P2, P3)> {
typedef RET (*Func)(void *, P1, P2, P3);
@ -224,9 +237,11 @@ class CheckerManager {
bool wantsRegionChangeUpdate(const GRState *state);
/// \brief Run checkers for region changes.
const GRState *runCheckersForRegionChanges(const GRState *state,
const MemRegion * const *Begin,
const MemRegion * const *End);
const GRState *
runCheckersForRegionChanges(const GRState *state,
const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion * const *Begin,
const MemRegion * const *End);
/// \brief Run checkers for handling assumptions on symbolic values.
const GRState *runCheckersForEvalAssume(const GRState *state,
@ -237,6 +252,11 @@ class CheckerManager {
const ExplodedNodeSet &Src,
const CallExpr *CE, ExprEngine &Eng,
GraphExpander *defaultEval = 0);
/// \brief Run checkers for the entire Translation Unit.
void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl* TU,
AnalysisManager &mgr,
BugReporter &BR);
//===----------------------------------------------------------------------===//
// Internal registration functions for AST traversing.
@ -283,6 +303,7 @@ class CheckerManager {
typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc;
typedef CheckerFn<const GRState * (const GRState *,
const StoreManager::InvalidatedSymbols *symbols,
const MemRegion * const *begin,
const MemRegion * const *end)>
CheckRegionChangesFunc;
@ -296,6 +317,10 @@ class CheckerManager {
typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
EvalCallFunc;
typedef CheckerFn<void (const TranslationUnitDecl *,
AnalysisManager&, BugReporter &)>
CheckEndOfTranslationUnit;
typedef bool (*HandlesStmtFunc)(const Stmt *D);
void _registerForPreStmt(CheckStmtFunc checkfn,
HandlesStmtFunc isForStmtFn);
@ -326,6 +351,8 @@ class CheckerManager {
void _registerForEvalCall(EvalCallFunc checkfn);
void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
//===----------------------------------------------------------------------===//
// Internal registration functions for events.
//===----------------------------------------------------------------------===//
@ -446,6 +473,8 @@ class CheckerManager {
std::vector<EvalCallFunc> EvalCallCheckers;
std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
struct EventInfo {
llvm::SmallVector<CheckEventFunc, 4> Checkers;
bool HasDispatcher;

View File

@ -108,7 +108,8 @@ class BasicValueFactory {
const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
assert(T->isIntegerType() || Loc::isLocType(T));
unsigned bitwidth = Ctx.getTypeSize(T);
bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T);
bool isUnsigned
= T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T);
if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth())
return From;
@ -131,13 +132,15 @@ class BasicValueFactory {
inline const llvm::APSInt& getMaxValue(QualType T) {
assert(T->isIntegerType() || Loc::isLocType(T));
bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T);
bool isUnsigned
= T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T);
return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned));
}
inline const llvm::APSInt& getMinValue(QualType T) {
assert(T->isIntegerType() || Loc::isLocType(T));
bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T);
bool isUnsigned
= T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T);
return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned));
}

View File

@ -21,6 +21,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/AST/Type.h"
#include "clang/AST/ExprObjC.h"
@ -188,9 +189,11 @@ class ExprEngine : public SubEngine {
/// processRegionChanges - Called by GRStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
const GRState* processRegionChanges(const GRState *state,
const MemRegion * const *Begin,
const MemRegion * const *End);
const GRState *
processRegionChanges(const GRState *state,
const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion * const *Begin,
const MemRegion * const *End);
virtual GRStateManager& getStateManager() { return StateMgr; }
@ -458,6 +461,13 @@ class ExprEngine : public SubEngine {
const void *tag, bool isLoad);
bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
public:
/// Returns true if calling the specific function or method would possibly
/// cause global variables to be invalidated.
bool doesInvalidateGlobals(const CallOrObjCMessage &callOrMessage) const;
};
} // end ento namespace

View File

@ -368,6 +368,12 @@ class GRState : public llvm::FoldingSetNode {
assert(refCount > 0);
--refCount;
}
const GRState *invalidateRegionsImpl(const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned BlockCount,
StoreManager::InvalidatedSymbols &IS,
bool invalidateGlobals) const;
};
class GRStateSet {

View File

@ -187,6 +187,7 @@ class CallOrObjCMessage {
return CallE && isa<CXXMemberCallExpr>(CallE);
}
SVal getFunctionCallee() const;
SVal getCXXCallee() const;
unsigned getNumArgs() const {

View File

@ -172,7 +172,7 @@ class SValBuilder {
nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) {
return nonloc::ConcreteInt(
BasicVals.getValue(integer->getValue(),
integer->getType()->isUnsignedIntegerType()));
integer->getType()->isUnsignedIntegerOrEnumerationType()));
}
nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean) {

View File

@ -188,7 +188,7 @@ class StoreManager {
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
InvalidatedSymbols *IS,
InvalidatedSymbols &IS,
bool invalidateGlobals,
InvalidatedRegions *Regions) = 0;

View File

@ -15,6 +15,7 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
namespace clang {
@ -95,13 +96,17 @@ class SubEngine {
/// processRegionChanges - Called by GRStateManager whenever a change is made
/// to the store. Used to update checkers that track region values.
virtual const GRState* processRegionChanges(const GRState* state,
const MemRegion* const *Begin,
const MemRegion* const *End) = 0;
virtual const GRState *
processRegionChanges(const GRState *state,
const StoreManager::InvalidatedSymbols *invalidated,
const MemRegion* const *Begin,
const MemRegion* const *End) = 0;
inline const GRState* processRegionChange(const GRState* state,
const MemRegion* MR) {
return processRegionChanges(state, &MR, &MR+1);
inline const GRState *
processRegionChange(const GRState* state,
const MemRegion* MR) {
return processRegionChanges(state, 0, &MR, &MR+1);
}
/// Called by CoreEngine when the analysis worklist is either empty or the

View File

@ -1,81 +0,0 @@
//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements functions to run clang tools standalone instead
// of running them as a plugin.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLING_TOOLING_H
#define LLVM_CLANG_TOOLING_TOOLING_H
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
namespace clang {
class FrontendAction;
namespace tooling {
/// \brief Runs (and deletes) the tool on 'Code' with the -fsynatx-only flag.
///
/// \param ToolAction The action to run over the code.
/// \param Code C++ code.
///
/// \return - True if 'ToolAction' was successfully executed.
bool RunSyntaxOnlyToolOnCode(
clang::FrontendAction *ToolAction, llvm::StringRef Code);
/// \brief Runs (and deletes) the tool with the given Clang flags.
///
/// \param ToolAction The action to run over the code.
/// \param Argc The number of elements in Argv.
/// \param Argv The command line arguments, including the path the binary
/// was started with (Argv[0]).
bool RunToolWithFlags(
clang::FrontendAction* ToolAction, int Argc, char *Argv[]);
/// \brief Converts a vector<string> into a vector<char*> suitable to pass
/// to main-style functions taking (int Argc, char *Argv[]).
std::vector<char*> CommandLineToArgv(const std::vector<std::string>* Command);
/// \brief Specifies the working directory and command of a compilation.
struct CompileCommand {
/// \brief The working directory the command was executed from.
std::string Directory;
/// \brief The command line that was executed.
std::vector<std::string> CommandLine;
};
/// \brief Looks up the compile command for 'FileName' in 'JsonDatabase'.
///
/// \param FileName The path to an input file for which we want the compile
/// command line. If the 'JsonDatabase' was created by CMake, this must be
/// an absolute path inside the CMake source directory which does not have
/// symlinks resolved.
///
/// \param JsonDatabase A JSON formatted list of compile commands. This lookup
/// command supports only a subset of the JSON standard as written by CMake.
///
/// \param ErrorMessage If non-empty, an error occurred and 'ErrorMessage' will
/// be set to contain the error message. In this case CompileCommand will
/// contain an empty directory and command line.
///
/// \see JsonCompileCommandLineDatabase
CompileCommand FindCompileArgsInJsonDatabase(
llvm::StringRef FileName, llvm::StringRef JsonDatabase,
std::string &ErrorMessage);
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_TOOLING_H

View File

@ -18,12 +18,12 @@ using namespace clang;
namespace {
struct LV {
Expr* Base;
const Expr* Base;
CharUnits Offset;
};
}
APValue::APValue(Expr* B) : Kind(Uninitialized) {
APValue::APValue(const Expr* B) : Kind(Uninitialized) {
MakeLValue(); setLValue(B, CharUnits::Zero());
}
@ -118,7 +118,7 @@ void APValue::print(llvm::raw_ostream &OS) const {
}
}
Expr* APValue::getLValueBase() const {
const Expr* APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
return ((const LV*)(const void*)Data)->Base;
}
@ -128,7 +128,7 @@ CharUnits APValue::getLValueOffset() const {
return ((const LV*)(const void*)Data)->Offset;
}
void APValue::setLValue(Expr *B, const CharUnits &O) {
void APValue::setLValue(const Expr *B, const CharUnits &O) {
assert(isLValue() && "Invalid accessor");
((LV*)(char*)Data)->Base = B;
((LV*)(char*)Data)->Offset = O;

View File

@ -31,6 +31,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "CXXABI.h"
#include <map>
using namespace clang;
@ -38,8 +39,12 @@ unsigned ASTContext::NumImplicitDefaultConstructors;
unsigned ASTContext::NumImplicitDefaultConstructorsDeclared;
unsigned ASTContext::NumImplicitCopyConstructors;
unsigned ASTContext::NumImplicitCopyConstructorsDeclared;
unsigned ASTContext::NumImplicitMoveConstructors;
unsigned ASTContext::NumImplicitMoveConstructorsDeclared;
unsigned ASTContext::NumImplicitCopyAssignmentOperators;
unsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
unsigned ASTContext::NumImplicitMoveAssignmentOperators;
unsigned ASTContext::NumImplicitMoveAssignmentOperatorsDeclared;
unsigned ASTContext::NumImplicitDestructors;
unsigned ASTContext::NumImplicitDestructorsDeclared;
@ -317,9 +322,17 @@ void ASTContext::PrintStats() const {
fprintf(stderr, " %u/%u implicit copy constructors created\n",
NumImplicitCopyConstructorsDeclared,
NumImplicitCopyConstructors);
if (getLangOptions().CPlusPlus)
fprintf(stderr, " %u/%u implicit move constructors created\n",
NumImplicitMoveConstructorsDeclared,
NumImplicitMoveConstructors);
fprintf(stderr, " %u/%u implicit copy assignment operators created\n",
NumImplicitCopyAssignmentOperatorsDeclared,
NumImplicitCopyAssignmentOperators);
if (getLangOptions().CPlusPlus)
fprintf(stderr, " %u/%u implicit move assignment operators created\n",
NumImplicitMoveAssignmentOperatorsDeclared,
NumImplicitMoveAssignmentOperators);
fprintf(stderr, " %u/%u implicit destructors created\n",
NumImplicitDestructorsDeclared, NumImplicitDestructors);
@ -546,10 +559,30 @@ bool ASTContext::ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
bool ASTContext::ZeroBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const {
return (FD->isBitField() && LastFD && LastFD->isBitField() &&
FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue() == 0);
FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue() == 0 &&
LastFD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue() != 0);
}
bool ASTContext::BitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const {
return (FD->isBitField() && LastFD && LastFD->isBitField() &&
FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue() &&
LastFD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue());
}
bool ASTContext::NoneBitfieldFollowsBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const {
return (!FD->isBitField() && LastFD && LastFD->isBitField() &&
LastFD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue());
}
bool ASTContext::BitfieldFollowsNoneBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const {
return (FD->isBitField() && LastFD && !LastFD->isBitField() &&
FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue());
}
ASTContext::overridden_cxx_method_iterator
ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
@ -627,6 +660,10 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
UseAlignAttrOnly = true;
}
}
else if (isa<FieldDecl>(D))
UseAlignAttrOnly =
D->hasAttr<PackedAttr>() ||
cast<FieldDecl>(D)->getParent()->hasAttr<PackedAttr>();
// If we're using the align attribute only, just ignore everything
// else about the declaration and its type.
@ -950,6 +987,9 @@ ASTContext::getTypeInfo(const Type *T) const {
return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
.getTypePtr());
case Type::UnaryTransform:
return getTypeInfo(cast<UnaryTransformType>(T)->getUnderlyingType());
case Type::Elaborated:
return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
@ -957,13 +997,18 @@ ASTContext::getTypeInfo(const Type *T) const {
return getTypeInfo(
cast<AttributedType>(T)->getEquivalentType().getTypePtr());
case Type::TemplateSpecialization:
case Type::TemplateSpecialization: {
assert(getCanonicalType(T) != T &&
"Cannot request the size of a dependent type");
// FIXME: this is likely to be wrong once we support template
// aliases, since a template alias could refer to a typedef that
// has an __aligned__ attribute on it.
return getTypeInfo(getCanonicalType(T));
const TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T);
// A type alias template specialization may refer to a typedef with the
// aligned attribute on it.
if (TST->isTypeAlias())
return getTypeInfo(TST->getAliasedType().getTypePtr());
else
return getTypeInfo(getCanonicalType(T));
}
}
assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
@ -1393,6 +1438,9 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
/// lvalue reference to the specified type.
QualType
ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
assert(getCanonicalType(T) != OverloadTy &&
"Unresolved overloaded function type");
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
llvm::FoldingSetNodeID ID;
@ -1572,6 +1620,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::TypeOfExpr:
case Type::TypeOf:
case Type::Decltype:
case Type::UnaryTransform:
case Type::DependentName:
case Type::InjectedClassName:
case Type::TemplateSpecialization:
@ -2235,10 +2284,10 @@ TypeSourceInfo *
ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
SourceLocation NameLoc,
const TemplateArgumentListInfo &Args,
QualType CanonType) const {
QualType Underlying) const {
assert(!Name.getAsDependentTemplateName() &&
"No dependent template names here!");
QualType TST = getTemplateSpecializationType(Name, Args, CanonType);
QualType TST = getTemplateSpecializationType(Name, Args, Underlying);
TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
TemplateSpecializationTypeLoc TL
@ -2254,7 +2303,7 @@ ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgumentListInfo &Args,
QualType Canon) const {
QualType Underlying) const {
assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
@ -2266,35 +2315,46 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
ArgVec.push_back(Args[i].getArgument());
return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs,
Canon);
Underlying);
}
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgument *Args,
unsigned NumArgs,
QualType Canon) const {
QualType Underlying) const {
assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
// Look through qualified template names.
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
Template = TemplateName(QTN->getTemplateDecl());
if (!Canon.isNull())
Canon = getCanonicalType(Canon);
else
Canon = getCanonicalTemplateSpecializationType(Template, Args, NumArgs);
bool isTypeAlias =
Template.getAsTemplateDecl() &&
isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
QualType CanonType;
if (!Underlying.isNull())
CanonType = getCanonicalType(Underlying);
else {
assert(!isTypeAlias &&
"Underlying type for template alias must be computed by caller");
CanonType = getCanonicalTemplateSpecializationType(Template, Args,
NumArgs);
}
// Allocate the (non-canonical) template specialization type, but don't
// try to unique it: these types typically have location information that
// we don't unique and don't want to lose.
void *Mem = Allocate((sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs),
void *Mem = Allocate(sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs +
(isTypeAlias ? sizeof(QualType) : 0),
TypeAlignment);
TemplateSpecializationType *Spec
= new (Mem) TemplateSpecializationType(Template,
Args, NumArgs,
Canon);
CanonType,
isTypeAlias ? Underlying : QualType());
Types.push_back(Spec);
return QualType(Spec, 0);
@ -2306,6 +2366,10 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
unsigned NumArgs) const {
assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
assert((!Template.getAsTemplateDecl() ||
!isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) &&
"Underlying type for template alias must be computed by caller");
// Look through qualified template names.
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
Template = TemplateName(QTN->getTemplateDecl());
@ -2334,7 +2398,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
TypeAlignment);
Spec = new (Mem) TemplateSpecializationType(CanonTemplate,
CanonArgs.data(), NumArgs,
QualType());
QualType(), QualType());
Types.push_back(Spec);
TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
}
@ -2754,6 +2818,21 @@ QualType ASTContext::getDecltypeType(Expr *e) const {
return QualType(dt, 0);
}
/// getUnaryTransformationType - We don't unique these, since the memory
/// savings are minimal and these are rare.
QualType ASTContext::getUnaryTransformType(QualType BaseType,
QualType UnderlyingType,
UnaryTransformType::UTTKind Kind)
const {
UnaryTransformType *Ty =
new (*this, TypeAlignment) UnaryTransformType (BaseType, UnderlyingType,
Kind,
UnderlyingType->isDependentType() ?
QualType() : UnderlyingType);
Types.push_back(Ty);
return QualType(Ty, 0);
}
/// getAutoType - We only unique auto types after they've been deduced.
QualType ASTContext::getAutoType(QualType DeducedType) const {
void *InsertPos = 0;
@ -3457,7 +3536,8 @@ QualType ASTContext::getCFConstantStringType() const {
SourceLocation(), 0,
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
/*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
CFConstantStringTypeDecl->addDecl(Field);
}
@ -3498,7 +3578,8 @@ QualType ASTContext::getNSConstantStringType() const {
SourceLocation(), 0,
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
/*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
NSConstantStringTypeDecl->addDecl(Field);
}
@ -3537,7 +3618,8 @@ QualType ASTContext::getObjCFastEnumerationStateType() const {
SourceLocation(), 0,
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
/*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
ObjCFastEnumerationStateTypeDecl->addDecl(Field);
}
@ -3574,7 +3656,8 @@ QualType ASTContext::getBlockDescriptorType() const {
&Idents.get(FieldNames[i]),
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
/*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
T->addDecl(Field);
}
@ -3622,7 +3705,8 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
&Idents.get(FieldNames[i]),
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0,
/*Mutable=*/false);
/*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
T->addDecl(Field);
}
@ -3650,7 +3734,7 @@ bool ASTContext::BlockRequiresCopying(QualType Ty) const {
if (getLangOptions().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
return RD->hasConstCopyConstructor(*this);
return RD->hasConstCopyConstructor();
}
}
@ -3707,7 +3791,8 @@ ASTContext::BuildByRefType(llvm::StringRef DeclName, QualType Ty) const {
SourceLocation(),
&Idents.get(FieldNames[i]),
FieldTypes[i], /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
/*BitWidth=*/0, /*Mutable=*/false,
/*HasInit=*/false);
Field->setAccess(AS_public);
T->addDecl(Field);
}
@ -3736,6 +3821,9 @@ static bool isTypeTypedefedAsBOOL(QualType T) {
/// getObjCEncodingTypeSize returns size of type for objective-c encoding
/// purpose.
CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {
if (!type->isIncompleteArrayType() && type->isIncompleteType())
return CharUnits::Zero();
CharUnits sz = getTypeSizeInChars(type);
// Make all integer and enum types at least as large as an int
@ -3803,7 +3891,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
return S;
}
void ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
std::string& S) {
// Encode result type.
getObjCEncodingForType(Decl->getResultType(), S);
@ -3813,8 +3901,11 @@ void ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
E = Decl->param_end(); PI != E; ++PI) {
QualType PType = (*PI)->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
return true;
assert (sz.isPositive() &&
"getObjCEncodingForMethodDecl - Incomplete param type");
"getObjCEncodingForFunctionDecl - Incomplete param type");
ParmOffset += sz;
}
S += charUnitsToString(ParmOffset);
@ -3837,11 +3928,13 @@ void ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
S += charUnitsToString(ParmOffset);
ParmOffset += getObjCEncodingTypeSize(PType);
}
return false;
}
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
/// declaration.
void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
std::string& S) const {
// FIXME: This is not very efficient.
// Encode type qualifer, 'in', 'inout', etc. for the return type.
@ -3860,6 +3953,9 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
E = Decl->sel_param_end(); PI != E; ++PI) {
QualType PType = (*PI)->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
return true;
assert (sz.isPositive() &&
"getObjCEncodingForMethodDecl - Incomplete param type");
ParmOffset += sz;
@ -3889,6 +3985,8 @@ void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
S += charUnitsToString(ParmOffset);
ParmOffset += getObjCEncodingTypeSize(PType);
}
return false;
}
/// getObjCEncodingForPropertyDecl - Return the encoded type for this
@ -4108,7 +4206,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
bool ExpandStructures,
const FieldDecl *FD,
bool OutermostType,
bool EncodingProperty) const {
bool EncodingProperty,
bool StructField) const {
if (T->getAs<BuiltinType>()) {
if (FD && FD->isBitField())
return EncodeBitField(this, S, T, FD);
@ -4193,7 +4292,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (const ArrayType *AT =
// Ignore type qualifiers etc.
dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
if (isa<IncompleteArrayType>(AT)) {
if (isa<IncompleteArrayType>(AT) && !StructField) {
// Incomplete arrays are encoded as a pointer to the array element.
S += '^';
@ -4202,11 +4301,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
} else {
S += '[';
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
S += llvm::utostr(CAT->getSize().getZExtValue());
else {
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
if (getTypeSize(CAT->getElementType()) == 0)
S += '0';
else
S += llvm::utostr(CAT->getSize().getZExtValue());
} else {
//Variable length arrays are encoded as a regular array with 0 elements.
assert(isa<VariableArrayType>(AT) && "Unknown array type!");
assert((isa<VariableArrayType>(AT) || isa<IncompleteArrayType>(AT)) &&
"Unknown array type!");
S += '0';
}
@ -4244,24 +4347,30 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
if (ExpandStructures) {
S += '=';
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
if (FD) {
S += '"';
S += Field->getNameAsString();
S += '"';
}
if (!RDecl->isUnion()) {
getObjCEncodingForStructureImpl(RDecl, S, FD);
} else {
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
if (FD) {
S += '"';
S += Field->getNameAsString();
S += '"';
}
// Special case bit-fields.
if (Field->isBitField()) {
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
(*Field));
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
getObjCEncodingForTypeImpl(qt, S, false, true,
FD);
// Special case bit-fields.
if (Field->isBitField()) {
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
(*Field));
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
getObjCEncodingForTypeImpl(qt, S, false, true,
FD, /*OutermostType*/false,
/*EncodingProperty*/false,
/*StructField*/true);
}
}
}
}
@ -4382,6 +4491,135 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
assert(0 && "@encode for type not implemented!");
}
void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
std::string &S,
const FieldDecl *FD,
bool includeVBases) const {
assert(RDecl && "Expected non-null RecordDecl");
assert(!RDecl->isUnion() && "Should not be called for unions");
if (!RDecl->getDefinition())
return;
CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
if (CXXRec) {
for (CXXRecordDecl::base_class_iterator
BI = CXXRec->bases_begin(),
BE = CXXRec->bases_end(); BI != BE; ++BI) {
if (!BI->isVirtual()) {
CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
uint64_t offs = layout.getBaseClassOffsetInBits(base);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
std::make_pair(offs, base));
}
}
}
unsigned i = 0;
for (RecordDecl::field_iterator Field = RDecl->field_begin(),
FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field, ++i) {
uint64_t offs = layout.getFieldOffset(i);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
std::make_pair(offs, *Field));
}
if (CXXRec && includeVBases) {
for (CXXRecordDecl::base_class_iterator
BI = CXXRec->vbases_begin(),
BE = CXXRec->vbases_end(); BI != BE; ++BI) {
CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
uint64_t offs = layout.getVBaseClassOffsetInBits(base);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
std::make_pair(offs, base));
}
}
CharUnits size;
if (CXXRec) {
size = includeVBases ? layout.getSize() : layout.getNonVirtualSize();
} else {
size = layout.getSize();
}
uint64_t CurOffs = 0;
std::multimap<uint64_t, NamedDecl *>::iterator
CurLayObj = FieldOrBaseOffsets.begin();
if (CurLayObj != FieldOrBaseOffsets.end() && CurLayObj->first != 0) {
assert(CXXRec && CXXRec->isDynamicClass() &&
"Offset 0 was empty but no VTable ?");
if (FD) {
S += "\"_vptr$";
std::string recname = CXXRec->getNameAsString();
if (recname.empty()) recname = "?";
S += recname;
S += '"';
}
S += "^^?";
CurOffs += getTypeSize(VoidPtrTy);
}
if (!RDecl->hasFlexibleArrayMember()) {
// Mark the end of the structure.
uint64_t offs = toBits(size);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
std::make_pair(offs, (NamedDecl*)0));
}
for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {
assert(CurOffs <= CurLayObj->first);
if (CurOffs < CurLayObj->first) {
uint64_t padding = CurLayObj->first - CurOffs;
// FIXME: There doesn't seem to be a way to indicate in the encoding that
// packing/alignment of members is different that normal, in which case
// the encoding will be out-of-sync with the real layout.
// If the runtime switches to just consider the size of types without
// taking into account alignment, we could make padding explicit in the
// encoding (e.g. using arrays of chars). The encoding strings would be
// longer then though.
CurOffs += padding;
}
NamedDecl *dcl = CurLayObj->second;
if (dcl == 0)
break; // reached end of structure.
if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
// We expand the bases without their virtual bases since those are going
// in the initial structure. Note that this differs from gcc which
// expands virtual bases each time one is encountered in the hierarchy,
// making the encoding type bigger than it really is.
getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
if (!base->isEmpty())
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
} else {
FieldDecl *field = cast<FieldDecl>(dcl);
if (FD) {
S += '"';
S += field->getNameAsString();
S += '"';
}
if (field->isBitField()) {
EncodeBitField(this, S, field->getType(), field);
CurOffs += field->getBitWidth()->EvaluateAsInt(*this).getZExtValue();
} else {
QualType qt = field->getType();
getLegacyIntegralTypeEncoding(qt);
getObjCEncodingForTypeImpl(qt, S, false, true, FD,
/*OutermostType*/false,
/*EncodingProperty*/false,
/*StructField*/true);
CurOffs += getTypeSize(field->getType());
}
}
}
}
void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
std::string& S) const {
if (QT & Decl::OBJC_TQ_In)
@ -6068,7 +6306,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// Forward declarations aren't required.
if (!FD->isThisDeclarationADefinition())
if (!FD->doesThisDeclarationHaveABody())
return false;
// Constructors and destructors are required.
@ -6105,10 +6343,13 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Structs that have non-trivial constructors or destructors are required.
// FIXME: Handle references.
// FIXME: Be more selective about which constructors we care about.
if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
if (RD->hasDefinition() &&
(!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor()))
if (RD->hasDefinition() && !(RD->hasTrivialDefaultConstructor() &&
RD->hasTrivialCopyConstructor() &&
RD->hasTrivialMoveConstructor() &&
RD->hasTrivialDestructor()))
return true;
}
}

View File

@ -56,9 +56,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
continue;
}
// Don't desugar template specializations.
if (isa<TemplateSpecializationType>(Ty))
break;
// Don't desugar template specializations, unless it's an alias template.
if (const TemplateSpecializationType *TST
= dyn_cast<TemplateSpecializationType>(Ty))
if (!TST->isTypeAlias())
break;
// Don't desugar magic Objective-C types.
if (QualType(Ty,0) == Context.getObjCIdType() ||

View File

@ -64,6 +64,7 @@ namespace {
// FIXME: DependentTypeOfExprType
QualType VisitTypeOfType(const TypeOfType *T);
QualType VisitDecltypeType(const DecltypeType *T);
QualType VisitUnaryTransformType(const UnaryTransformType *T);
QualType VisitAutoType(const AutoType *T);
// FIXME: DependentDecltypeType
QualType VisitRecordType(const RecordType *T);
@ -604,7 +605,14 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
cast<TypeOfType>(T2)->getUnderlyingType()))
return false;
break;
case Type::UnaryTransform:
if (!IsStructurallyEquivalent(Context,
cast<UnaryTransformType>(T1)->getUnderlyingType(),
cast<UnaryTransformType>(T1)->getUnderlyingType()))
return false;
break;
case Type::Decltype:
if (!IsStructurallyEquivalent(Context,
cast<DecltypeType>(T1)->getUnderlyingExpr(),
@ -1572,6 +1580,17 @@ QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
return Importer.getToContext().getDecltypeType(ToExpr);
}
QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
QualType ToBaseType = Importer.Import(T->getBaseType());
QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
if (ToBaseType.isNull() || ToUnderlyingType.isNull())
return QualType();
return Importer.getToContext().getUnaryTransformType(ToBaseType,
ToUnderlyingType,
T->getUTTKind());
}
QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
// FIXME: Make sure that the "to" context supports C++0x!
QualType FromDeduced = T->getDeducedType();
@ -2493,9 +2512,12 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, BitWidth, D->isMutable());
T, TInfo, BitWidth, D->isMutable(),
D->hasInClassInitializer());
ToField->setAccess(D->getAccess());
ToField->setLexicalDeclContext(LexicalDC);
if (ToField->hasInClassInitializer())
ToField->setInClassInitializer(D->getInClassInitializer());
Importer.Imported(D, ToField);
LexicalDC->addDecl(ToField);
return ToField;
@ -2851,7 +2873,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
D->isVariadic(),
D->isSynthesized(),
D->isDefined(),
D->getImplementationControl());
D->getImplementationControl(),
D->hasRelatedResultType());
// FIXME: When we decide to merge method definitions, we'll need to
// deal with implicit parameters.

View File

@ -1422,6 +1422,31 @@ bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
return false;
}
bool FunctionDecl::hasTrivialBody() const
{
Stmt *S = getBody();
if (!S) {
// Since we don't have a body for this function, we don't know if it's
// trivial or not.
return false;
}
if (isa<CompoundStmt>(S) && cast<CompoundStmt>(S)->body_empty())
return true;
return false;
}
bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed) {
Definition = I->IsDeleted ? I->getCanonicalDecl() : *I;
return true;
}
}
return false;
}
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
if (I->Body) {
@ -1450,10 +1475,34 @@ void FunctionDecl::setPure(bool P) {
}
bool FunctionDecl::isMain() const {
ASTContext &Context = getASTContext();
return !Context.getLangOptions().Freestanding &&
getDeclContext()->getRedeclContext()->isTranslationUnit() &&
getIdentifier() && getIdentifier()->isStr("main");
const TranslationUnitDecl *tunit =
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
return tunit &&
!tunit->getASTContext().getLangOptions().Freestanding &&
getIdentifier() &&
getIdentifier()->isStr("main");
}
bool FunctionDecl::isReservedGlobalPlacementOperator() const {
assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName);
assert(getDeclName().getCXXOverloadedOperator() == OO_New ||
getDeclName().getCXXOverloadedOperator() == OO_Delete ||
getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
if (isa<CXXRecordDecl>(getDeclContext())) return false;
assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
if (proto->getNumArgs() != 2 || proto->isVariadic()) return false;
ASTContext &Context =
cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
->getASTContext();
// The result type and first argument type are constant across all
// these operators. The second argument must be exactly void*.
return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
}
bool FunctionDecl::isExternC() const {
@ -1690,11 +1739,11 @@ bool FunctionDecl::isInlined() const {
/// an externally visible symbol, but "extern inline" will not create an
/// externally visible symbol.
bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
assert(isThisDeclarationADefinition() && "Must have the function definition");
assert(doesThisDeclarationHaveABody() && "Must have the function definition");
assert(isInlined() && "Function must be inline");
ASTContext &Context = getASTContext();
if (!Context.getLangOptions().C99 || hasAttr<GNUInlineAttr>()) {
if (Context.getLangOptions().GNUInline || hasAttr<GNUInlineAttr>()) {
// If it's not the case that both 'inline' and 'extern' are
// specified on the definition, then this inline definition is
// externally visible.
@ -2028,9 +2077,10 @@ SourceRange FunctionDecl::getSourceRange() const {
FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable) {
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
bool HasInit) {
return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
BW, Mutable);
BW, Mutable, HasInit);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@ -2059,8 +2109,7 @@ unsigned FieldDecl::getFieldIndex() const {
if (IsMsStruct) {
// Zero-length bitfields following non-bitfield members are ignored.
if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD) ||
getASTContext().ZeroBitfieldFollowsBitfield((*i), LastFD)) {
if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD)) {
++i;
continue;
}
@ -2076,10 +2125,17 @@ unsigned FieldDecl::getFieldIndex() const {
SourceRange FieldDecl::getSourceRange() const {
if (isBitField())
return SourceRange(getInnerLocStart(), BitWidth->getLocEnd());
return SourceRange(getInnerLocStart(), getBitWidth()->getLocEnd());
return DeclaratorDecl::getSourceRange();
}
void FieldDecl::setInClassInitializer(Expr *Init) {
assert(!InitializerOrBitWidth.getPointer() &&
"bit width or initializer already set");
InitializerOrBitWidth.setPointer(Init);
InitializerOrBitWidth.setInt(0);
}
//===----------------------------------------------------------------------===//
// TagDecl Implementation
//===----------------------------------------------------------------------===//

View File

@ -439,6 +439,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case Typedef:
case TypeAlias:
case TypeAliasTemplate:
case UnresolvedUsingTypename:
case TemplateTypeParm:
return IDNS_Ordinary | IDNS_Type;
@ -1165,10 +1166,10 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
if (!D->getDeclName())
return;
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
if (isa<ClassTemplateSpecializationDecl>(D) || D->isTemplateParameter())
// Skip entities that can't be found by name lookup into a particular
// context.
if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
D->isTemplateParameter())
return;
ASTContext *C = 0;

View File

@ -29,19 +29,21 @@ using namespace clang;
CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
: UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false),
UserDeclaredMoveConstructor(false), UserDeclaredCopyAssignment(false),
UserDeclaredMoveAssignment(false), UserDeclaredDestructor(false),
Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
HasTrivialConstructor(true), HasConstExprNonCopyMoveConstructor(false),
HasTrivialCopyConstructor(true), HasTrivialMoveConstructor(true),
HasTrivialCopyAssignment(true), HasTrivialMoveAssignment(true),
HasTrivialDestructor(true), HasNonLiteralTypeFieldsOrBases(false),
ComputedVisibleConversions(false),
DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false),
DeclaredCopyAssignment(false), DeclaredDestructor(false),
NumBases(0), NumVBases(0), Bases(), VBases(),
Definition(D), FirstFriend(0) {
HasMutableFields(false), HasTrivialDefaultConstructor(true),
HasConstExprNonCopyMoveConstructor(false), HasTrivialCopyConstructor(true),
HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true),
HasTrivialMoveAssignment(true), HasTrivialDestructor(true),
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
UserProvidedDefaultConstructor(false), DeclaredDefaultConstructor(false),
DeclaredCopyConstructor(false), DeclaredMoveConstructor(false),
DeclaredCopyAssignment(false), DeclaredMoveAssignment(false),
DeclaredDestructor(false), NumBases(0), NumVBases(0), Bases(), VBases(),
Definition(D), FirstFriend(0) {
}
CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@ -165,8 +167,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().Empty = false;
// C++ [class.ctor]p5:
// A constructor is trivial if its class has no virtual base classes.
data().HasTrivialConstructor = false;
// A default constructor is trivial [...] if:
// -- its class has [...] no virtual bases
data().HasTrivialDefaultConstructor = false;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if it is neither
@ -188,10 +191,11 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().IsStandardLayout = false;
} else {
// C++ [class.ctor]p5:
// A constructor is trivial if all the direct base classes of its
// class have trivial constructors.
if (!BaseClassDecl->hasTrivialConstructor())
data().HasTrivialConstructor = false;
// A default constructor is trivial [...] if:
// -- all the direct base classes of its class have trivial default
// constructors.
if (!BaseClassDecl->hasTrivialDefaultConstructor())
data().HasTrivialDefaultConstructor = false;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if [...]
@ -223,6 +227,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
// have trivial destructors.
if (!BaseClassDecl->hasTrivialDestructor())
data().HasTrivialDestructor = false;
// Keep track of the presence of mutable fields.
if (BaseClassDecl->hasMutableFields())
data().HasMutableFields = true;
}
if (VBases.empty())
@ -262,8 +270,8 @@ bool CXXRecordDecl::hasAnyDependentBases() const {
return !forallBases(SawBase, 0);
}
bool CXXRecordDecl::hasConstCopyConstructor(const ASTContext &Context) const {
return getCopyConstructor(Context, Qualifiers::Const) != 0;
bool CXXRecordDecl::hasConstCopyConstructor() const {
return getCopyConstructor(Qualifiers::Const) != 0;
}
bool CXXRecordDecl::isTriviallyCopyable() const {
@ -306,8 +314,8 @@ GetBestOverloadCandidateSimple(
return Cands[Best].first;
}
CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(const ASTContext &Context,
unsigned TypeQuals) const{
CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(unsigned TypeQuals) const{
ASTContext &Context = getASTContext();
QualType ClassType
= Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this));
DeclarationName ConstructorName
@ -337,6 +345,14 @@ CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(const ASTContext &Context,
GetBestOverloadCandidateSimple(Found));
}
CXXConstructorDecl *CXXRecordDecl::getMoveConstructor() const {
for (ctor_iterator I = ctor_begin(), E = ctor_end(); I != E; ++I)
if (I->isMoveConstructor())
return *I;
return 0;
}
CXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const {
ASTContext &Context = getASTContext();
QualType Class = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this));
@ -387,6 +403,14 @@ CXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const {
return GetBestOverloadCandidateSimple(Found);
}
CXXMethodDecl *CXXRecordDecl::getMoveAssignmentOperator() const {
for (method_iterator I = method_begin(), E = method_end(); I != E; ++I)
if (I->isMoveAssignmentOperator())
return *I;
return 0;
}
void CXXRecordDecl::markedVirtualFunctionPure() {
// C++ [class.abstract]p2:
// A class is abstract if it has at least one pure virtual function.
@ -421,8 +445,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
// polymorphic class.
data().Polymorphic = true;
// None of the special member functions are trivial.
data().HasTrivialConstructor = false;
// C++0x [class.ctor]p5
// A default constructor is trivial [...] if:
// -- its class has no virtual functions [...]
data().HasTrivialDefaultConstructor = false;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if [...]
@ -451,32 +477,32 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (ASTMutationListener *L = getASTMutationListener())
L->AddedCXXImplicitMember(data().Definition, D);
// If this is a special member function, note that it was added and then
// return early.
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
// If this is the implicit default constructor, note that we have now
// declared it.
if (Constructor->isDefaultConstructor())
data().DeclaredDefaultConstructor = true;
// If this is the implicit copy constructor, note that we have now
// declared it.
else if (Constructor->isCopyConstructor())
data().DeclaredCopyConstructor = true;
else if (Constructor->isMoveConstructor())
data().DeclaredMoveConstructor = true;
else
goto NotASpecialMember;
return;
}
if (isa<CXXDestructorDecl>(D)) {
} else if (isa<CXXDestructorDecl>(D)) {
data().DeclaredDestructor = true;
return;
}
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
// If this is the implicit copy constructor, note that we have now
// declared it.
// FIXME: Move constructors
if (Method->getOverloadedOperator() == OO_Equal)
} else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
if (Method->isCopyAssignmentOperator())
data().DeclaredCopyAssignment = true;
else if (Method->isMoveAssignmentOperator())
data().DeclaredMoveAssignment = true;
else
goto NotASpecialMember;
return;
}
NotASpecialMember:;
// Any other implicit declarations are handled like normal declarations.
}
@ -485,23 +511,20 @@ void CXXRecordDecl::addedMember(Decl *D) {
// Note that we have a user-declared constructor.
data().UserDeclaredConstructor = true;
// Note that we have no need of an implicitly-declared default constructor.
data().DeclaredDefaultConstructor = true;
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with no
// user-declared constructors (12.1) [...].
data().Aggregate = false;
// FIXME: Under C++0x, /only/ special member functions may be user-provided.
// This is probably a defect.
bool UserProvided = false;
// C++ [class]p4:
// A POD-struct is an aggregate class [...]
data().PlainOldData = false;
// C++ [class.ctor]p5:
// A constructor is trivial if it is an implicitly-declared default
// constructor.
// FIXME: C++0x: don't do this for "= default" default constructors.
data().HasTrivialConstructor = false;
// C++0x [class.ctor]p5:
// A default constructor is trivial if it is not user-provided [...]
if (Constructor->isDefaultConstructor()) {
data().DeclaredDefaultConstructor = true;
if (Constructor->isUserProvided()) {
data().HasTrivialDefaultConstructor = false;
data().UserProvidedDefaultConstructor = true;
UserProvided = true;
}
}
// Note when we have a user-declared copy or move constructor, which will
// suppress the implicit declaration of those constructors.
@ -511,16 +534,23 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().DeclaredCopyConstructor = true;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if it is neither
// user-provided nor deleted
// FIXME: C++0x: don't do this for "= default" copy constructors.
data().HasTrivialCopyConstructor = false;
// A copy/move constructor for class X is trivial if it is not
// user-provided [...]
if (Constructor->isUserProvided()) {
data().HasTrivialCopyConstructor = false;
UserProvided = true;
}
} else if (Constructor->isMoveConstructor()) {
data().UserDeclaredMoveConstructor = true;
data().DeclaredMoveConstructor = true;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if it is neither
// user-provided nor deleted
// FIXME: C++0x: don't do this for "= default" move constructors.
data().HasTrivialMoveConstructor = false;
// A copy/move constructor for class X is trivial if it is not
// user-provided [...]
if (Constructor->isUserProvided()) {
data().HasTrivialMoveConstructor = false;
UserProvided = true;
}
}
}
if (Constructor->isConstExpr() &&
@ -530,88 +560,81 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().HasConstExprNonCopyMoveConstructor = true;
}
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class with no user-declared
// constructors [...].
// C++0x [dcl.init.aggr]p1:
// An aggregate is an array or a class with no user-provided
// constructors [...].
if (!getASTContext().getLangOptions().CPlusPlus0x || UserProvided)
data().Aggregate = false;
// C++ [class]p4:
// A POD-struct is an aggregate class [...]
// Since the POD bit is meant to be C++03 POD-ness, clear it even if the
// type is technically an aggregate in C++0x since it wouldn't be in 03.
data().PlainOldData = false;
return;
}
// Handle (user-declared) destructors.
if (isa<CXXDestructorDecl>(D)) {
if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
data().DeclaredDestructor = true;
data().UserDeclaredDestructor = true;
// C++ [class]p4:
// A POD-struct is an aggregate class that has [...] no user-defined
// destructor.
// This bit is the C++03 POD bit, not the 0x one.
data().PlainOldData = false;
// C++ [class.dtor]p3:
// A destructor is trivial if it is an implicitly-declared destructor and
// [...].
//
// FIXME: C++0x: don't do this for "= default" destructors
data().HasTrivialDestructor = false;
// C++0x [class.dtor]p5:
// A destructor is trivial if it is not user-provided and [...]
if (DD->isUserProvided())
data().HasTrivialDestructor = false;
return;
}
// Handle (user-declared) member functions.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
if (Method->getOverloadedOperator() == OO_Equal) {
// We're interested specifically in copy assignment operators.
const FunctionProtoType *FnType
= Method->getType()->getAs<FunctionProtoType>();
assert(FnType && "Overloaded operator has no proto function type.");
assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
// Copy assignment operators must be non-templates.
if (Method->getPrimaryTemplate() || FunTmpl)
return;
ASTContext &Context = getASTContext();
QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
const_cast<CXXRecordDecl*>(this)));
bool isRValueRefArg = false;
QualType ArgType = FnType->getArgType(0);
if (const LValueReferenceType *Ref =
ArgType->getAs<LValueReferenceType>()) {
ArgType = Ref->getPointeeType();
} else if (const RValueReferenceType *Ref =
ArgType->getAs<RValueReferenceType>()) {
ArgType = Ref->getPointeeType();
isRValueRefArg = true;
}
if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
return;
if (Method->isCopyAssignmentOperator()) {
// C++ [class]p4:
// A POD-struct is an aggregate class that [...] has no user-defined
// copy assignment operator [...].
// FIXME: This should be probably determined dynamically in terms of
// other more precise attributes to correctly model how it is specified
// in C++0x. Setting it here happens to do the right thing.
// This is the C++03 bit only.
data().PlainOldData = false;
if (!isRValueRefArg) {
// This is a copy assignment operator.
// This is a copy assignment operator.
// Suppress the implicit declaration of a copy constructor.
data().UserDeclaredCopyAssignment = true;
data().DeclaredCopyAssignment = true;
// Suppress the implicit declaration of a copy constructor.
data().UserDeclaredCopyAssignment = true;
data().DeclaredCopyAssignment = true;
// C++0x [class.copy]p27:
// A copy/move assignment operator for class X is trivial if it is
// neither user-provided nor deleted [...]
// FIXME: C++0x: don't do this for "= default" copy operators.
// C++0x [class.copy]p27:
// A copy/move assignment operator for class X is trivial if it is
// neither user-provided nor deleted [...]
if (Method->isUserProvided())
data().HasTrivialCopyAssignment = false;
} else {
// This is a move assignment operator.
// C++0x [class.copy]p27:
// A copy/move assignment operator for class X is trivial if it is
// neither user-provided nor deleted [...]
// FIXME: C++0x: don't do this for "= default" copy operators.
return;
}
if (Method->isMoveAssignmentOperator()) {
// This is an extension in C++03 mode, but we'll keep consistency by
// taking a move assignment operator to induce non-POD-ness
data().PlainOldData = false;
// This is a move assignment operator.
data().UserDeclaredMoveAssignment = true;
data().DeclaredMoveAssignment = true;
// C++0x [class.copy]p27:
// A copy/move assignment operator for class X is trivial if it is
// neither user-provided nor deleted [...]
if (Method->isUserProvided())
data().HasTrivialMoveAssignment = false;
}
}
// Keep the list of conversion functions up-to-date.
@ -667,6 +690,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().HasPublicFields) > 1)
data().IsStandardLayout = false;
// Keep track of the presence of mutable fields.
if (Field->isMutable())
data().HasMutableFields = true;
// C++0x [class]p9:
// A POD struct is a class that is both a trivial class and a
// standard-layout class, and has no non-static data members of type
@ -676,7 +703,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (!T->isPODType())
data().PlainOldData = false;
if (T->isReferenceType()) {
data().HasTrivialConstructor = false;
data().HasTrivialDefaultConstructor = false;
// C++0x [class]p7:
// A standard-layout class is a class that:
@ -688,11 +715,32 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (!hasNonLiteralTypeFieldsOrBases() && !T->isLiteralType())
data().HasNonLiteralTypeFieldsOrBases = true;
if (Field->hasInClassInitializer()) {
// C++0x [class]p5:
// A default constructor is trivial if [...] no non-static data member
// of its class has a brace-or-equal-initializer.
data().HasTrivialDefaultConstructor = false;
// C++0x [dcl.init.aggr]p1:
// An aggregate is a [...] class with [...] no
// brace-or-equal-initializers for non-static data members.
data().Aggregate = false;
// C++0x [class]p10:
// A POD struct is [...] a trivial class.
data().PlainOldData = false;
}
if (const RecordType *RecordTy = T->getAs<RecordType>()) {
CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
if (FieldRec->getDefinition()) {
if (!FieldRec->hasTrivialConstructor())
data().HasTrivialConstructor = false;
// C++0x [class.ctor]p5:
// A defulat constructor is trivial [...] if:
// -- for all the non-static data members of its class that are of
// class type (or array thereof), each such class has a trivial
// default constructor.
if (!FieldRec->hasTrivialDefaultConstructor())
data().HasTrivialDefaultConstructor = false;
// C++0x [class.copy]p13:
// A copy/move constructor for class X is trivial if [...]
@ -753,6 +801,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
}
}
}
// Keep track of the presence of mutable fields.
if (FieldRec->hasMutableFields())
data().HasMutableFields = true;
}
}
@ -1135,14 +1187,13 @@ bool CXXMethodDecl::isUsualDeallocationFunction() const {
}
bool CXXMethodDecl::isCopyAssignmentOperator() const {
// C++0x [class.copy]p19:
// C++0x [class.copy]p17:
// A user-declared copy assignment operator X::operator= is a non-static
// non-template member function of class X with exactly one parameter of
// type X, X&, const X&, volatile X& or const volatile X&.
if (/*operator=*/getOverloadedOperator() != OO_Equal ||
/*non-static*/ isStatic() ||
/*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() ||
/*exactly one parameter*/getNumParams() != 1)
/*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate())
return false;
QualType ParamType = getParamDecl(0)->getType();
@ -1155,6 +1206,26 @@ bool CXXMethodDecl::isCopyAssignmentOperator() const {
return Context.hasSameUnqualifiedType(ClassType, ParamType);
}
bool CXXMethodDecl::isMoveAssignmentOperator() const {
// C++0x [class.copy]p19:
// A user-declared move assignment operator X::operator= is a non-static
// non-template member function of class X with exactly one parameter of type
// X&&, const X&&, volatile X&&, or const volatile X&&.
if (getOverloadedOperator() != OO_Equal || isStatic() ||
getPrimaryTemplate() || getDescribedFunctionTemplate())
return false;
QualType ParamType = getParamDecl(0)->getType();
if (!isa<RValueReferenceType>(ParamType))
return false;
ParamType = ParamType->getPointeeType();
ASTContext &Context = getASTContext();
QualType ClassType
= Context.getCanonicalType(Context.getTypeDeclType(getParent()));
return Context.hasSameUnqualifiedType(ClassType, ParamType);
}
void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
assert(MD->isCanonicalDecl() && "Method is not canonical!");
assert(!MD->getParent()->isDependentContext() &&
@ -1290,11 +1361,21 @@ const Type *CXXCtorInitializer::getBaseClass() const {
SourceLocation CXXCtorInitializer::getSourceLocation() const {
if (isAnyMemberInitializer() || isDelegatingInitializer())
return getMemberLocation();
if (isInClassMemberInitializer())
return getAnyMember()->getLocation();
return getBaseClassLoc().getLocalSourceRange().getBegin();
}
SourceRange CXXCtorInitializer::getSourceRange() const {
if (isInClassMemberInitializer()) {
FieldDecl *D = getAnyMember();
if (Expr *I = D->getInClassInitializer())
return I->getSourceRange();
return SourceRange();
}
return SourceRange(getSourceLocation(), getRParenLoc());
}

View File

@ -339,12 +339,14 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
bool isSynthesized,
bool isDefined,
ImplementationControl impControl,
bool HasRelatedResultType,
unsigned numSelectorArgs) {
return new (C) ObjCMethodDecl(beginLoc, endLoc,
SelInfo, T, ResultTInfo, contextDecl,
isInstance,
isVariadic, isSynthesized, isDefined,
impControl,
HasRelatedResultType,
numSelectorArgs);
}
@ -446,6 +448,7 @@ ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
case OMF_release:
case OMF_autorelease:
case OMF_retainCount:
case OMF_self:
if (!isInstanceMethod())
family = OMF_None;
break;

View File

@ -400,7 +400,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->getNumParams()) POut << ", ";
POut << "...";
}
} else if (D->isThisDeclarationADefinition() && !D->hasPrototype()) {
} else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
if (i)
Proto += ", ";
@ -450,62 +450,67 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->hasAttr<NoReturnAttr>())
Proto += " __attribute((noreturn))";
if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) {
if (CDecl->getNumCtorInitializers() > 0) {
Proto += " : ";
Out << Proto;
Proto.clear();
for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
E = CDecl->init_end();
B != E; ++B) {
CXXCtorInitializer * BMInitializer = (*B);
if (B != CDecl->init_begin())
Out << ", ";
if (BMInitializer->isAnyMemberInitializer()) {
FieldDecl *FD = BMInitializer->getAnyMember();
Out << FD;
} else {
Out << QualType(BMInitializer->getBaseClass(),
0).getAsString(Policy);
}
bool HasInitializerList = false;
for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
E = CDecl->init_end();
B != E; ++B) {
CXXCtorInitializer * BMInitializer = (*B);
if (BMInitializer->isInClassMemberInitializer())
continue;
if (!HasInitializerList) {
Proto += " : ";
Out << Proto;
Proto.clear();
HasInitializerList = true;
} else
Out << ", ";
if (BMInitializer->isAnyMemberInitializer()) {
FieldDecl *FD = BMInitializer->getAnyMember();
Out << FD;
} else {
Out << QualType(BMInitializer->getBaseClass(),
0).getAsString(Policy);
}
Out << "(";
if (!BMInitializer->getInit()) {
// Nothing to print
} else {
Expr *Init = BMInitializer->getInit();
if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
Init = Tmp->getSubExpr();
Out << "(";
if (!BMInitializer->getInit()) {
// Nothing to print
} else {
Expr *Init = BMInitializer->getInit();
if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
Init = Tmp->getSubExpr();
Init = Init->IgnoreParens();
Expr *SimpleInit = 0;
Expr **Args = 0;
unsigned NumArgs = 0;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
Args = ParenList->getExprs();
NumArgs = ParenList->getNumExprs();
} else if (CXXConstructExpr *Construct
= dyn_cast<CXXConstructExpr>(Init)) {
Args = Construct->getArgs();
NumArgs = Construct->getNumArgs();
} else
SimpleInit = Init;
if (SimpleInit)
SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
else {
for (unsigned I = 0; I != NumArgs; ++I) {
if (isa<CXXDefaultArgExpr>(Args[I]))
break;
if (I)
Out << ", ";
Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
}
Init = Init->IgnoreParens();
Expr *SimpleInit = 0;
Expr **Args = 0;
unsigned NumArgs = 0;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
Args = ParenList->getExprs();
NumArgs = ParenList->getNumExprs();
} else if (CXXConstructExpr *Construct
= dyn_cast<CXXConstructExpr>(Init)) {
Args = Construct->getArgs();
NumArgs = Construct->getNumArgs();
} else
SimpleInit = Init;
if (SimpleInit)
SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
else {
for (unsigned I = 0; I != NumArgs; ++I) {
if (isa<CXXDefaultArgExpr>(Args[I]))
break;
if (I)
Out << ", ";
Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
}
}
Out << ")";
}
Out << ")";
}
}
else
@ -518,9 +523,9 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->isPure())
Out << " = 0";
else if (D->isDeleted())
else if (D->isDeletedAsWritten())
Out << " = delete";
else if (D->isThisDeclarationADefinition()) {
else if (D->doesThisDeclarationHaveABody()) {
if (!D->hasPrototype() && D->getNumParams()) {
// This is a K&R function definition, so we need to print the
// parameters.
@ -553,6 +558,12 @@ void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
Out << " : ";
D->getBitWidth()->printPretty(Out, Context, 0, Policy, Indentation);
}
Expr *Init = D->getInClassInitializer();
if (!Policy.SuppressInitializers && Init) {
Out << " = ";
Init->printPretty(Out, Context, 0, Policy, Indentation);
}
}
void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
@ -932,6 +943,11 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
Out << (first ? ' ' : ',') << "nonatomic";
first = false;
}
if (PDecl->getPropertyAttributes() &
ObjCPropertyDecl::OBJC_PR_atomic) {
Out << (first ? ' ' : ',') << "atomic";
first = false;
}
Out << " )";
}
Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << PDecl;

View File

@ -735,3 +735,34 @@ FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
EmptyShell Empty) {
return new (Context) FriendTemplateDecl(Empty);
}
//===----------------------------------------------------------------------===//
// TypeAliasTemplateDecl Implementation
//===----------------------------------------------------------------------===//
TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl) {
AdoptTemplateParameterList(Params, DC);
return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
}
TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
EmptyShell) {
return new (C) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
0, 0);
}
void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
static_cast<Common *>(Ptr)->~Common();
}
RedeclarableTemplateDecl::CommonBase *
TypeAliasTemplateDecl::newCommon(ASTContext &C) {
Common *CommonPtr = new (C) Common;
C.AddDeallocation(DeallocateCommon, CommonPtr);
return CommonPtr;
}

View File

@ -482,18 +482,20 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
setFlag("trivial", D->isTrivial());
setFlag("returnzero", D->hasImplicitReturnZero());
setFlag("prototype", D->hasWrittenPrototype());
setFlag("deleted", D->isDeleted());
setFlag("deleted", D->isDeletedAsWritten());
if (D->getStorageClass() != SC_None)
set("storage",
VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
setFlag("inline", D->isInlineSpecified());
if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
set("asmlabel", ALA->getLabel());
// TODO: instantiation, etc.
}
void visitFunctionDeclChildren(FunctionDecl *D) {
for (FunctionDecl::param_iterator
I = D->param_begin(), E = D->param_end(); I != E; ++I)
dispatch(*I);
if (D->isThisDeclarationADefinition())
if (D->doesThisDeclarationHaveABody())
dispatch(D->getBody());
}
@ -619,7 +621,8 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
// TemplateDecl
void visitTemplateDeclChildren(TemplateDecl *D) {
visitTemplateParameters(D->getTemplateParameters());
dispatch(D->getTemplatedDecl());
if (D->getTemplatedDecl())
dispatch(D->getTemplatedDecl());
}
// FunctionTemplateDecl
@ -845,6 +848,7 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
setFlag("variadic", D->isVariadic());
setFlag("synthesized", D->isSynthesized());
setFlag("defined", D->isDefined());
setFlag("related_result_type", D->hasRelatedResultType());
}
void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
dispatch(D->getResultType());

Some files were not shown because too many files have changed in this diff Show More