Vendor import of clang trunk r130700:

http://llvm.org/svn/llvm-project/cfe/trunk@130700
This commit is contained in:
Dimitry Andric 2011-05-02 19:39:53 +00:00
parent c3b054d250
commit 01af97d3b2
1142 changed files with 52414 additions and 22512 deletions

View File

@ -30,7 +30,7 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
include(AddLLVM)
include(TableGen)
include("${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVM.cmake")
include("${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
include(HandleLLVMOptions)
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
@ -40,9 +40,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories("${PATH_TO_LLVM_BUILD}/include" "${LLVM_MAIN_INCLUDE_DIR}")
if( NOT PATH_TO_LLVM_BUILD STREQUAL LLVM_MAIN_SRC_DIR )
include_directories("${LLVM_MAIN_INCLUDE_DIR}")
endif()
link_directories("${PATH_TO_LLVM_BUILD}/lib")
set(LLVM_TABLEGEN_EXE "${PATH_TO_LLVM_BUILD}/bin/tblgen")
@ -174,23 +171,12 @@ macro(add_clang_library name)
if( LLVM_COMMON_DEPENDS )
add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
endif( LLVM_COMMON_DEPENDS )
if( LLVM_USED_LIBS )
foreach(lib ${LLVM_USED_LIBS})
target_link_libraries( ${name} ${lib} )
endforeach(lib)
endif( LLVM_USED_LIBS )
if( LLVM_LINK_COMPONENTS )
llvm_config(${name} ${LLVM_LINK_COMPONENTS})
endif( LLVM_LINK_COMPONENTS )
if (LLVM_COMMON_LIBS)
target_link_libraries(${name} ${LLVM_COMMON_LIBS})
endif()
if( NOT MINGW )
get_system_libs(llvm_system_libs)
if( llvm_system_libs )
target_link_libraries(${name} ${llvm_system_libs})
endif()
endif()
target_link_libraries( ${name} ${LLVM_USED_LIBS} )
llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
target_link_libraries( ${name} ${LLVM_COMMON_LIBS} )
link_system_libs( ${name} )
add_dependencies(${name} ClangDiagnosticCommon)
if(MSVC)
get_target_property(cflag ${name} COMPILE_FLAGS)
@ -211,9 +197,9 @@ macro(add_clang_executable name)
set_target_properties(${name} PROPERTIES FOLDER "Clang executables")
endmacro(add_clang_executable)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
include_directories(BEFORE
${CMAKE_CURRENT_BINARY_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/include
)
install(DIRECTORY include/
@ -221,7 +207,6 @@ install(DIRECTORY include/
FILES_MATCHING
PATTERN "*.def"
PATTERN "*.h"
PATTERN "*.td"
PATTERN ".svn" EXCLUDE
)

View File

@ -46,6 +46,9 @@ CPP.Flags += -I$(PROJ_SRC_DIR)/$(CLANG_LEVEL)/include -I$(PROJ_OBJ_DIR)/$(CLANG_
ifdef CLANG_VENDOR
CPP.Flags += -DCLANG_VENDOR='"$(CLANG_VENDOR) "'
endif
ifdef CLANG_REPOSITORY_STRING
CPP.Flags += -DCLANG_REPOSITORY_STRING='"$(CLANG_REPOSITORY_STRING)"'
endif
# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't
# work with it enabled with GCC), Clang/llvm-gcc don't support it yet, and newer

View File

@ -88,7 +88,7 @@
<h3 id="components">Flexible</h3>
<!--=======================================================================-->
<p>The driver was designed to be flexible and easily accomodate
<p>The driver was designed to be flexible and easily accommodate
new uses as we grow the clang and LLVM infrastructure. As one
example, the driver can easily support the introduction of
tools which have an integrated assembler; something we hope to
@ -218,7 +218,7 @@
<p>The clang driver can dump the results of this
stage using the <tt>-ccc-print-options</tt> flag (which
must preceed any actual command line arguments). For
must precede any actual command line arguments). For
example:</p>
<pre>
$ <b>clang -ccc-print-options -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c</b>
@ -490,7 +490,7 @@
<li>
<b>Specs</b>
<p>The clang driver has no direct correspondant for
<p>The clang driver has no direct correspondent for
"specs". The majority of the functionality that is
embedded in specs is in the Tool specific argument
translation routines. The parts of specs which control the

View File

@ -412,7 +412,7 @@ it is rendered.
</p>
<!-- ==================================================== -->
<h4 id="code-modification-hints">Code Modification Hints</h4>
<h4 id="fix-it-hints">Fix-It Hints</h4>
<!-- ==================================================== -->
<p>In some cases, the front end emits diagnostics when it is clear
@ -422,14 +422,14 @@ deprecated syntax that is easily rewritten into a more modern form.
Clang tries very hard to emit the diagnostic and recover gracefully
in these and other cases.</p>
<p>However, for these cases where the fix is obvious, the diagnostic
can be annotated with a code
modification "hint" that describes how to change the code referenced
by the diagnostic to fix the problem. For example, it might add the
missing semicolon at the end of the statement or rewrite the use of a
deprecated construct into something more palatable. Here is one such
example C++ front end, where we warn about the right-shift operator
changing meaning from C++98 to C++0x:</p>
<p>However, for these cases where the fix is obvious, the diagnostic
can be annotated with a hint (referred to as a "fix-it hint") that
describes how to change the code referenced by the diagnostic to fix
the problem. For example, it might add the missing semicolon at the
end of the statement or rewrite the use of a deprecated construct
into something more palatable. Here is one such example from the C++
front end, where we warn about the right-shift operator changing
meaning from C++98 to C++0x:</p>
<pre>
test.cpp:3:7: warning: use of right-shift operator ('&gt;&gt;') in template argument will require parentheses in C++0x
@ -438,33 +438,31 @@ A&lt;100 &gt;&gt; 2&gt; *a;
( )
</pre>
<p>Here, the code modification hint is suggesting that parentheses be
added, and showing exactly where those parentheses would be inserted
into the source code. The code modification hints themselves describe
what changes to make to the source code in an abstract manner, which
the text diagnostic printer renders as a line of "insertions" below
the caret line. <a href="#DiagnosticClient">Other diagnostic
clients</a> might choose to render the code differently (e.g., as
markup inline) or even give the user the ability to automatically fix
the problem.</p>
<p>Here, the fix-it hint is suggesting that parentheses be added,
and showing exactly where those parentheses would be inserted into the
source code. The fix-it hints themselves describe what changes to make
to the source code in an abstract manner, which the text diagnostic
printer renders as a line of "insertions" below the caret line. <a
href="#DiagnosticClient">Other diagnostic clients</a> might choose
to render the code differently (e.g., as markup inline) or even give
the user the ability to automatically fix the problem.</p>
<p>All code modification hints are described by the
<code>CodeModificationHint</code> class, instances of which should be
attached to the diagnostic using the &lt;&lt; operator in the same way
that highlighted source ranges and arguments are passed to the
diagnostic. Code modification hints can be created with one of three
constructors:</p>
<p>All fix-it hints are described by the <code>FixItHint</code> class,
instances of which should be attached to the diagnostic using the
&lt;&lt; operator in the same way that highlighted source ranges and
arguments are passed to the diagnostic. Fix-it hints can be created
with one of three constructors:</p>
<dl>
<dt><code>CodeModificationHint::CreateInsertion(Loc, Code)</code></dt>
<dt><code>FixItHint::CreateInsertion(Loc, Code)</code></dt>
<dd>Specifies that the given <code>Code</code> (a string) should be inserted
before the source location <code>Loc</code>.</dd>
<dt><code>CodeModificationHint::CreateRemoval(Range)</code></dt>
<dt><code>FixItHint::CreateRemoval(Range)</code></dt>
<dd>Specifies that the code in the given source <code>Range</code>
should be removed.</dd>
<dt><code>CodeModificationHint::CreateReplacement(Range, Code)</code></dt>
<dt><code>FixItHint::CreateReplacement(Range, Code)</code></dt>
<dd>Specifies that the code in the given source <code>Range</code>
should be removed, and replaced with the given <code>Code</code> string.</dd>
</dl>
@ -821,7 +819,7 @@ code is vectorized on X86 and PowerPC hosts).</p>
within the filename.</li>
<li>When parsing a preprocessor directive (after "<tt>#</tt>") the
ParsingPreprocessorDirective mode is entered. This changes the parser to
return EOM at a newline.</li>
return EOD at a newline.</li>
<li>The Lexer uses a LangOptions object to know whether trigraphs are enabled,
whether C++ or ObjC keywords are recognized, etc.</li>
</ul>

View File

@ -38,6 +38,8 @@ td {
<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>
@ -46,14 +48,17 @@ td {
<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="#checking_type_traits">Checks for Type Traits</a></li>
<li><a href="#blocks">Blocks</a></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>
<li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
<li><a href="#__sync_swap">__sync_swap</a></li>
</ul>
</li>
<li><a href="#targetspecific">Target-Specific Extensions</a>
@ -61,11 +66,7 @@ td {
<li><a href="#x86-specific">X86/X86-64 Language Extensions</a></li>
</ul>
</li>
<li><a href="#analyzerspecific">Static Analysis-Specific Extensions</a>
<ul>
<li><a href="#analyzerattributes">Analyzer Attributes</a></li>
</ul>
</li>
<li><a href="#analyzerspecific">Static Analysis-Specific Extensions</a></li>
</ul>
<!-- ======================================================================= -->
@ -83,7 +84,7 @@ more information on these extensions.</p>
<!-- ======================================================================= -->
<p>Language extensions can be very useful, but only if you know you can depend
on them. In order to allow fine-grain features checks, we support two builtin
on them. In order to allow fine-grain features checks, we support three builtin
function-like macros. This allows you to directly test for a feature in your
code without having to resort to something like autoconf or fragile "compiler
version checks".</p>
@ -402,9 +403,19 @@ lambdas is enabled. clang does not currently implement this feature.</p>
<tt>nullptr</tt> is enabled. clang does not yet fully implement this
feature.</p>
<h3 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
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>
<h3 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>
<h3 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> to determine if support for
@ -436,6 +447,11 @@ inline namespaces is enabled.</p>
<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>
<h3 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>
<h3 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
<p>Use <tt>__has_feature(cxx_strong_enums)</tt> to determine if support for
@ -594,6 +610,20 @@ caveats to this use of name mangling:</p>
<p>Query for this feature with __has_feature(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>
<!-- ======================================================================= -->
@ -703,6 +733,36 @@ no arguments and produces a void result.
<p>Query for this feature with __has_builtin(__builtin_unreachable).</p>
<!-- ======================================================================= -->
<h3 id="__sync_swap">__sync_swap</h3>
<!-- ======================================================================= -->
<p><tt>__sync_swap</tt> is used to atomically swap integers or pointers in
memory.
</p>
<p><b>Syntax:</b></p>
<pre>
<i>type</i> __sync_swap(<i>type</i> *ptr, <i>type</i> value, ...)
</pre>
<p><b>Example of Use:</b></p>
<pre>
int old_value = __sync_swap(&value, new_value);
</pre>
<p><b>Description:</b></p>
<p>The __sync_swap() builtin extends the existing __sync_*() family of atomic
intrinsics to allow code to atomically swap the current value with the new
value. More importantly, it helps developers write more efficient and correct
code by avoiding expensive loops around __sync_bool_compare_and_swap() or
relying on the platform specific implementation details of
__sync_lock_test_and_set(). The __sync_swap() builtin is a full barrier.
</p>
<!-- ======================================================================= -->
<h2 id="targetspecific">Target-Specific Extensions</h2>
@ -754,11 +814,7 @@ are used by the <a
href="http://clang.llvm.org/StaticAnalysis.html">path-sensitive static analyzer
engine</a> that is part of Clang's Analysis library.</p>
<!-- ======================================================================= -->
<h3 id="analyzerattributes">Analyzer Attributes</h3>
<!-- ======================================================================= -->
<h4 id="attr_analyzer_noreturn"><tt>analyzer_noreturn</tt></h4>
<h3 id="attr_analyzer_noreturn">The <tt>analyzer_noreturn</tt> attribute</h3>
<p>Clang's static analysis engine understands the standard <tt>noreturn</tt>
attribute. This attribute, which is typically affixed to a function prototype,
@ -786,16 +842,47 @@ placed at the end of function prototypes:</p>
void foo() <b>__attribute__((analyzer_noreturn))</b>;
</pre>
<p>Query for this feature with __has_feature(attribute_analyzer_noreturn).</p>
<p>Query for this feature with
<tt>__has_attribute(analyzer_noreturn)</tt>.</p>
<h4 id="attr_retain_release">Objective-C retaining behavior attributes</h4>
<h3 id="attr_method_family">The <tt>objc_method_family</tt> attribute</h3>
<p>Many methods in Objective-C have conventional meanings determined
by their selectors. For the purposes of static analysis, it is
sometimes useful to be able to mark a method as having a particular
conventional meaning despite not having the right selector, or as not
having the conventional meaning that its selector would suggest.
For these use cases, we provide an attribute to specifically describe
the <q>method family</q> that a method belongs to.</p>
<p><b>Usage</b>: <tt>__attribute__((objc_method_family(X)))</tt>,
where <tt>X</tt> is one of <tt>none</tt>, <tt>alloc</tt>, <tt>copy</tt>,
<tt>init</tt>, <tt>mutableCopy</tt>, or <tt>new</tt>. This attribute
can only be placed at the end of a method declaration:</p>
<pre>
- (NSString*) initMyStringValue <b>__attribute__((objc_method_family(none)))</b>;
</pre>
<p>Users who do not wish to change the conventional meaning of a
method, and who merely want to document its non-standard retain and
release semantics, should use the
<a href="#attr_retain_release">retaining behavior attributes</a>
described below.</p>
<p>Query for this feature with
<tt>__has_attribute(objc_method_family)</tt>.</p>
<h3 id="attr_retain_release">Objective-C retaining behavior attributes</h3>
<p>In Objective-C, functions and methods are generally assumed to take
and return objects with +0 retain counts, with some exceptions for
special methods like <tt>+alloc</tt> and <tt>init</tt>. However,
there are exceptions, and so Clang provides attributes to allow these
exceptions to be documented, which helps the analyzer find leaks (and
ignore non-leaks).</p>
ignore non-leaks). Some exceptions may be better described using
the <a href="#attr_method_family"><tt>objc_method_family</tt></a>
attribute instead.</p>
<p><b>Usage</b>: The <tt>ns_returns_retained</tt>, <tt>ns_returns_not_retained</tt>,
<tt>ns_returns_autoreleased</tt>, <tt>cf_returns_retained</tt>,
@ -834,6 +921,9 @@ balance in some way.</p>
- (void) baz: (id) <b>__attribute__((ns_consumed))</b> x;
</pre>
<p>Query for these features with <tt>__has_attribute(ns_consumed)</tt>,
<tt>__has_attribute(ns_returns_retained)</tt>, etc.</p>
</div>
</body>
</html>

View File

@ -32,7 +32,7 @@ td {
</li>
<li><a href="#general_features">Language and Target-Independent Features</a>
<ul>
<li><a href="#diagnostics">Controlling Errors and Warnings</a></li>
<li><a href="#diagnostics">Controlling Errors and Warnings</a>
<ul>
<li><a href="#diagnostics_display">Controlling How Clang Displays Diagnostics</a></li>
<li><a href="#diagnostics_mappings">Diagnostic Mappings</a></li>
@ -41,9 +41,10 @@ td {
<li><a href="#diagnostics_pragmas">Controlling Diagnostics via Pragmas</a></li>
<li><a href="#analyzer_diagnositics">Controlling Static Analyzer Diagnostics</a></li>
</ul>
</li>
<li><a href="#precompiledheaders">Precompiled Headers</a></li>
<li><a href="#codegen">Controlling Code Generation</a></li>
</ul>
</ul>
</li>
<li><a href="#c">C Language Features</a>
<ul>
@ -67,8 +68,8 @@ td {
<ul>
<li><a href="#target_os_darwin">Darwin (Mac OS/X)</a></li>
<li>Linux, etc.</li>
<li><a href="#target_os_win32">Windows</a></li>
</ul>
</li>
</ul>
</li>
@ -205,7 +206,7 @@ diagnostics that it generates.</p>
diagnostic.</dt>
<dd>This option, which defaults to on, controls whether or not Clang prints the
column number of a diagnostic. For example, when this is enabled, Clang will
print something like:</p>
print something like:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -223,7 +224,7 @@ column number.</p>
source file/line/column information in diagnostic.</dt>
<dd>This option, which defaults to on, controls whether or not Clang prints the
filename, line number and column number of a diagnostic. For example,
when this is enabled, Clang will print something like:</p>
when this is enabled, Clang will print something like:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -240,7 +241,7 @@ when this is enabled, Clang will print something like:</p>
line and ranges from source code in diagnostic.</dt>
<dd>This option, which defaults to on, controls whether or not Clang prints the
source line, source ranges, and caret when emitting a diagnostic. For example,
when this is enabled, Clang will print something like:</p>
when this is enabled, Clang will print something like:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -277,7 +278,7 @@ Enable <tt>[-Woption]</tt> information in diagnostic line.</dt>
<dd>This option, which defaults to on,
controls whether or not Clang prints the associated <A
href="#cl_diag_warning_groups">warning group</a> option name when outputting
a warning diagnostic. For example, in this output:</p>
a warning diagnostic. For example, in this output:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -299,7 +300,7 @@ Enable printing category information in diagnostic line.</dt>
controls whether or not Clang prints the category associated with a diagnostic
when emitting it. Each diagnostic may or many not have an associated category,
if it has one, it is listed in the diagnostic categorization field of the
diagnostic line (in the []'s).</p>
diagnostic line (in the []'s).
<p>For example, a format string warning will produce these three renditions
based on the setting of this option:</p>
@ -322,7 +323,7 @@ hundreds or thousands of them.</p>
Enable "FixIt" information in the diagnostics output.</dt>
<dd>This option, which defaults to on, controls whether or not Clang prints the
information on how to fix a specific diagnostic underneath it when it knows.
For example, in this output:</p>
For example, in this output:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -345,7 +346,7 @@ Print machine parsable information about source ranges.</dt>
information about source ranges in a machine parsable format after the
file/line/column number information. The information is a simple sequence of
brace enclosed ranges, where each range lists the start and end line/column
locations. For example, in this output:</p>
locations. For example, in this output:
<pre>
exprs.c:47:15:{47:8-47:14}{47:17-47:24}: error: invalid operands to binary expression ('int *' and '_Complex float')
@ -366,7 +367,14 @@ Print Fix-Its in a machine parseable form.</dt>
fix-it:"t.cpp":{7:25-7:29}:"Gamma"
</pre>
<p>The range printed is a half-open range, so in this example the characters at column 25 up to but not including column 29 on line 7 in t.cpp should be replaced with the string "Gamma". Either the range or the replacement string may be empty (representing strict insertions and strict erasures, respectively). Both the file name and the insertion string escape backslash (as "\\"), tabs (as "\t"), newlines (as "\n"), double quotes(as "\"") and non-printable characters (as octal "\xxx").</p>
<p>The range printed is a half-open range, so in this example the characters at
column 25 up to but not including column 29 on line 7 in t.cpp should be
replaced with the string &quot;Gamma&quot;. Either the range or the replacement
string may be empty (representing strict insertions and strict erasures,
respectively). Both the file name and the insertion string escape backslash (as
&quot;\\&quot;), tabs (as &quot;\t&quot;), newlines (as &quot;\n&quot;), double
quotes(as &quot;\&quot;&quot;) and non-printable characters (as octal
&quot;\xxx&quot;).</p>
</dd>
</dl>
@ -388,7 +396,7 @@ Print Fix-Its in a machine parseable form.</dt>
<dt id="opt_Wextra-tokens"><b>-Wextra-tokens</b>: Warn about excess tokens at
the end of a preprocessor directive.</dt>
<dd>This option, which defaults to on, enables warnings about extra tokens at
the end of preprocessor directives. For example:</p>
the end of preprocessor directives. For example:
<pre>
test.c:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
@ -408,7 +416,7 @@ by commenting them out.</p>
Warn about unqualified uses of a member template whose name resolves
to another template at the location of the use.</dt>
<dd>This option, which defaults to on, enables a warning in the
following code:</p>
following code:
<pre>
template&lt;typename T> struct set{};
@ -432,7 +440,7 @@ an extension.</p>
an unusable copy constructor when binding a reference to a temporary.</dt>
<dd>This option, which defaults to on, enables warnings about binding a
reference to a temporary when the temporary doesn't have a usable copy
constructor. For example:</p>
constructor. For example:
<pre>
struct NonCopyable {
@ -484,7 +492,6 @@ and gives you fine-grain control over which information is printed. Clang has
the ability to print this information, and these are the options that control
it:</p>
<p>
<ol>
<li>A file/line/column indicator that shows exactly where the diagnostic occurs
in your code [<a href="#opt_fshow-column">-fshow-column</a>, <a
@ -508,7 +515,7 @@ it:</p>
<li>A machine-parsable representation of the ranges involved (off by
default) [<a
href="opt_fdiagnostics-print-source-range-info">-fdiagnostics-print-source-range-info</a>].</li>
</ol></p>
</ol>
<p>For more information please see <a href="#cl_diag_formatting">Formatting of
Diagnostics</a>.</p>
@ -518,14 +525,13 @@ Diagnostics</a>.</p>
<p>All diagnostics are mapped into one of these 5 classes:</p>
<p>
<ul>
<li>Ignored</li>
<li>Note</li>
<li>Warning</li>
<li>Error</li>
<li>Fatal</li>
</ul></p>
</ul>
<h4 id="diagnostics_categories">Diagnostic Categories</h4>
@ -735,6 +741,7 @@ likely to affect PCH files that reference a large number of headers.</p>
<p>Clang provides a number of ways to control code generation. The options are listed below.</p>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dl>
<dt id="opt_fcatch-undefined-behavior"><b>-fcatch-undefined-behavior</b>: Turn
on runtime code generation to check for undefined behavior.</dt>
@ -742,7 +749,7 @@ on runtime code generation to check for undefined behavior.</dt>
adds runtime checks for undefined runtime behavior. If a check fails,
<tt>__builtin_trap()</tt> is used to indicate failure.
The checks are:
<p>
<ul>
<li>Subscripting where the static type of one operand is a variable
which is decayed from an array type and the other operand is
greater than the size of the array or less than zero.</li>
@ -752,7 +759,7 @@ The checks are:
<li>When llvm implements more __builtin_object_size support, reads and
writes for objects that __builtin_object_size indicates we aren't
accessing valid memory. Bit-fields and vectors are not yet checked.
</p>
</ul>
</dd>
<dt id="opt_fno-assume-sane-operator-new"><b>-fno-assume-sane-operator-new</b>:
@ -761,6 +768,19 @@ Don't assume that the C++'s new operator is sane.</dt>
operator will always return a pointer that does not
alias any other pointer when the function returns.</dd>
<dt id="opt_ftrap-function"><b>-ftrap-function=[name]</b>: Instruct code
generator to emit a function call to the specified function name for
<tt>__builtin_trap()</tt>.</dt>
<dd>LLVM code generator translates <tt>__builtin_trap()</tt> to a trap
instruction if it is supported by the target ISA. Otherwise, the builtin is
translated into a call to <tt>abort</tt>. If this option is set, then the code
generator will always lower the builtin to a call to the specified function
regardless of whether the target ISA has a trap instruction. This option is
useful for environments (e.g. deeply embedded) where a trap cannot be properly
handled, or when some custom behavior is desired.</dd>
</dl>
<!-- ======================================================================= -->
<h2 id="c">C Language Features</h2>
<!-- ======================================================================= -->
@ -917,6 +937,7 @@ support is incomplete; enabling Microsoft extensions will silently drop
certain constructs (including __declspec and Microsoft-style asm statements).
</p>
<ul>
<li>clang allows setting _MSC_VER with -fmsc-version=. It defaults to 1300 which
is the same as Visual C/C++ 2003. Any number is supported and can greatly affect
what Windows SDK and c++stdlib headers clang can compile. This option will be
@ -930,6 +951,7 @@ record members can be declared using user defined typedefs.</li>
controlling record layout. GCC also contains support for this feature,
however where MSVC and GCC are incompatible clang follows the MSVC
definition.</li>
</ul>
<!-- ======================================================================= -->
<h2 id="target_features">Target-Specific Features and Limitations</h2>
@ -948,6 +970,10 @@ definition.</li>
(Mac OS/X), Linux, FreeBSD, and Dragonfly BSD: it has been tested to correctly
compile many large C, C++, Objective-C, and Objective-C++ codebases.</p>
<p>On x86_64-mingw32, passing i128(by value) is incompatible to Microsoft x64
calling conversion. You might need to tweak WinX86_64ABIInfo::classify()
in lib/CodeGen/TargetInfo.cpp.</p>
<!-- ======================== -->
<h4 id="target_arch_arm">ARM</h4>
<!-- ======================== -->
@ -985,6 +1011,44 @@ Generating assembly requires a suitable LLVM backend.
<p>No __thread support, 64-bit ObjC support requires SL tools.</p>
<!-- ======================================= -->
<h4 id="target_os_win32">Windows</h4>
<!-- ======================================= -->
<p>Experimental supports are on Cygming.</p>
<h5>Cygwin</h5>
<p>Clang works on Cygwin-1.7.</p>
<h5>MinGW32</h5>
<p>Clang works on some mingw32 distributions.
Clang assumes directories as below;</p>
<ul>
<li><tt>C:/mingw/include</tt></li>
<li><tt>C:/mingw/lib</tt></li>
<li><tt>C:/mingw/lib/gcc/mingw32/4.[3-5].0/include/c++</tt></li>
</ul>
<p>On MSYS, a few tests might fail. It is due to <a href="http://llvm.org/bugs/show_bug.cgi?id=8520">Bug 8520</a> and is fixed in <a href="http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110314/118106.html">LLVM's r127724</a>.</p>
<h5>MinGW-w64</h5>
<p>For x32(i686-w64-mingw32), it is not supported yet.</p>
<p>For x64(x86_64-w64-mingw32), <a href="http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110321/118499.html">an essential patch(LLVM's r128206)</a> would be needed. It is incompatible to <a href="http://tdm-gcc.tdragon.net/development">TDM-GCC</a> due to the definition of symbol &quot;<code>___chkstk</code>&quot;. Clang assumes as below;<p>
<ul>
<li><tt>C:/mingw/x86_64-w64-mingw32/include</tt></li>
<li><tt>C:/mingw/x86_64-w64-mingw32/include/c++/4.5.[23]</tt></li>
<li>GCC driver &quot;gcc.exe&quot; to build x86_64-w64-mingw32 binary.</li>
</ul>
<p><a href="http://llvm.org/bugs/show_bug.cgi?id=8833">Some tests might fail</a>
on x64.</p>
</div>
</body>
</html>

View File

@ -7,7 +7,7 @@ clang - the Clang C, C++, and Objective-C compiler
=head1 SYNOPSIS
B<clang> [B<-c>|B<-S>|B<-E>] B<-std=>I<standard> B<-g>
[B<-O0>|B<-O1>|B<-O2>|B<-Os>|B<-O3>|B<-O4>]
[B<-O0>|B<-O1>|B<-O2>|B<-Os>|B<-Oz>|B<-O3>|B<-O4>]
B<-W>I<warnings...> B<-pedantic>
B<-I>I<dir...> B<-L>I<dir...>
B<-D>I<macro[=defn]>
@ -53,7 +53,7 @@ parse errors. The output of this stage is an "Abstract Syntax Tree" (AST).
This stage translates an AST into low-level intermediate code (known as "LLVM
IR") and ultimately to machine code. This phase is responsible for optimizing
the generated code and handling target-specfic code generation. The output of
the generated code and handling target-specific code generation. The output of
this stage is typically called a ".s" file or "assembly" file.
Clang also supports the use of an integrated assembler, in which the code
@ -263,12 +263,13 @@ may not exist on earlier ones.
=over
=item B<-O0> B<-O1> B<-O2> B<-Os> B<-O3> B<-O4>
=item B<-O0> B<-O1> B<-O2> B<-Os> B<-Oz> B<-O3> B<-O4>
Specify which optimization level to use. B<-O0> means "no optimization": this
level compiles the fastest and generates the most debuggable code. B<-O2> is a
moderate level of optimization which enables most optimizations. B<-Os> is like
B<-O2> with extra optimizations to reduce code size. B<-O3> is like B<-O2>,
B<-O2> with extra optimizations to reduce code size. B<-Oz> is like B<-Os>
(and thus B<-O2>), but reduces code size further. B<-O3> is like B<-O2>,
except that it enables optimizations that take longer to perform or that may
generate larger code (in an attempt to make the program run faster). On
supported platforms, B<-O4> enables link-time optimization; object files are
@ -356,18 +357,10 @@ Pass I<arg> to the static analyzer.
Pass I<arg> to the assembler.
=item B<-Xclang> I<arg>
Pass I<arg> to the clang compiler frontend.
=item B<-Xlinker> I<arg>
Pass I<arg> to the linker.
=item B<-mllvm> I<arg>
Pass I<arg> to the LLVM backend.
=item B<-Xpreprocessor> I<arg>
Pass I<arg> to the preprocessor.

View File

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

View File

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

View File

@ -0,0 +1,108 @@
//===- 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;
}

24
examples/Tooling/Makefile Normal file
View File

@ -0,0 +1,24 @@
##===- 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

@ -16,7 +16,7 @@ NO_INSTALL = 1
TOOL_NO_EXPORTS = 1
LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter ipo \
selectiondag asmparser
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

View File

@ -85,8 +85,7 @@ int main(int argc, const char **argv, char * const *envp) {
// (basically, exactly one input, and the operation mode is hard wired).
llvm::SmallVector<const char *, 16> Args(argv, argv + argc);
Args.push_back("-fsyntax-only");
llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args.size(),
Args.data()));
llvm::OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args));
if (!C)
return 0;

View File

@ -1012,7 +1012,68 @@ CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
unsigned num_unsaved_files,
struct CXUnsavedFile *unsaved_files,
unsigned options);
/**
* \brief Categorizes how memory is being used by a translation unit.
*/
enum CXTUResourceUsageKind {
CXTUResourceUsage_AST = 1,
CXTUResourceUsage_Identifiers = 2,
CXTUResourceUsage_Selectors = 3,
CXTUResourceUsage_GlobalCompletionResults = 4,
CXTUResourceUsage_SourceManagerContentCache = 5,
CXTUResourceUsage_AST_SideTables = 6,
CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7,
CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,
CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9,
CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10,
CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST,
CXTUResourceUsage_MEMORY_IN_BYTES_END =
CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
CXTUResourceUsage_First = CXTUResourceUsage_AST,
CXTUResourceUsage_Last = CXTUResourceUsage_ExternalASTSource_Membuffer_MMap
};
/**
* \brief Returns the human-readable null-terminated C string that represents
* the name of the memory category. This string should never be freed.
*/
CINDEX_LINKAGE
const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind);
typedef struct CXTUResourceUsageEntry {
/* \brief The memory usage category. */
enum CXTUResourceUsageKind kind;
/* \brief Amount of resources used.
The units will depend on the resource kind. */
unsigned long amount;
} CXTUResourceUsageEntry;
/**
* \brief The memory usage of a CXTranslationUnit, broken into categories.
*/
typedef struct CXTUResourceUsage {
/* \brief Private data member, used for queries. */
void *data;
/* \brief The number of entries in the 'entries' array. */
unsigned numEntries;
/* \brief An array of key-value pairs, representing the breakdown of memory
usage. */
CXTUResourceUsageEntry *entries;
} CXTUResourceUsage;
/**
* \brief Return the memory usage of a translation unit. This object
* should be released with clang_disposeCXTUResourceUsage().
*/
CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU);
CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage);
/**
* @}
*/
@ -1101,10 +1162,12 @@ enum CXCursorKind {
CXCursor_NamespaceAlias = 33,
/** \brief A C++ using directive. */
CXCursor_UsingDirective = 34,
/** \brief A using declaration. */
/** \brief A C++ using declaration. */
CXCursor_UsingDeclaration = 35,
/** \brief A C++ alias declaration */
CXCursor_TypeAliasDecl = 36,
CXCursor_FirstDecl = CXCursor_UnexposedDecl,
CXCursor_LastDecl = CXCursor_UsingDeclaration,
CXCursor_LastDecl = CXCursor_TypeAliasDecl,
/* References */
CXCursor_FirstRef = 40, /* Decl references */
@ -2871,6 +2934,15 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,
*/
CINDEX_LINKAGE CXString clang_getClangVersion();
/**
* \brief Enable/disable crash recovery.
*
* \param Flag to indicate if crash recovery is enabled. A non-zero value
* enables crash recovery, while 0 disables it.
*/
CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled);
/**
* \brief Visitor invoked for each file in a translation unit
* (used with clang_getInclusions()).

View File

@ -89,7 +89,7 @@ class ASTConsumer {
/// \brief If the consumer is interested in entities getting modified after
/// their initial creation, it should return a pointer to
/// a GetASTMutationListener here.
/// an ASTMutationListener here.
virtual ASTMutationListener *GetASTMutationListener() { return 0; }
/// \brief If the consumer is interested in entities being deserialized from

View File

@ -14,10 +14,12 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/VersionTuple.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@ -27,6 +29,7 @@
#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
@ -68,7 +71,7 @@ namespace clang {
class TemplateTypeParmDecl;
class TranslationUnitDecl;
class TypeDecl;
class TypedefDecl;
class TypedefNameDecl;
class UsingDecl;
class UsingShadowDecl;
class UnresolvedSetIterator;
@ -77,7 +80,7 @@ namespace clang {
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
class ASTContext : public llvm::RefCountedBase<ASTContext> {
ASTContext &this_() { return *this; }
mutable std::vector<Type*> Types;
@ -96,7 +99,8 @@ class ASTContext {
DependentSizedExtVectorTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
@ -310,6 +314,9 @@ class ASTContext {
llvm::OwningPtr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
/// \brief The logical -> physical address space map.
const LangAS::Map &AddrSpaceMap;
friend class ASTDeclReader;
public:
@ -335,6 +342,14 @@ class ASTContext {
}
void Deallocate(void *Ptr) const { }
/// Return the total amount of physical memory allocated for representing
/// AST nodes and type information.
size_t getASTAllocatedMemory() const {
return BumpAlloc.getTotalMemory();
}
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
return DiagAllocator;
}
@ -381,6 +396,16 @@ class ASTContext {
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
/// ZeroBitfieldFollowsNonBitfield - return 'true" if 'FD' is a zero-length
/// bitfield which follows the non-bitfield 'LastFD'.
bool ZeroBitfieldFollowsNonBitfield(const FieldDecl *FD,
const FieldDecl *LastFD) const;
/// ZeroBitfieldFollowsBitfield - return 'true" if 'FD' is a zero-length
/// bitfield which follows the bitfield 'LastFD'.
bool ZeroBitfieldFollowsBitfield(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;
@ -413,10 +438,13 @@ class ASTContext {
CanQualType FloatTy, DoubleTy, LongDoubleTy;
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType OverloadTy;
CanQualType DependentTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,
IdentifierTable &idents, SelectorTable &sels,
Builtin::Context &builtins,
@ -654,9 +682,9 @@ class ASTContext {
}
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType getTypedefType(const TypedefDecl *Decl, QualType Canon = QualType())
const;
/// specified typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
QualType Canon = QualType()) const;
QualType getRecordType(const RecordDecl *Decl) const;
@ -676,7 +704,7 @@ class ASTContext {
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
IdentifierInfo *Name = 0) const;
TemplateTypeParmDecl *ParmDecl = 0) const;
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
@ -739,6 +767,12 @@ class ASTContext {
/// getAutoType - C++0x deduced auto type.
QualType getAutoType(QualType DeducedType) const;
/// getAutoDeductType - C++0x deduction pattern for 'auto' type.
QualType getAutoDeductType() const;
/// getAutoRRefDeductType - C++0x deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
/// getTagDeclType - Return the unique reference to the type for the
/// specified TagDecl (struct/union/class/enum) decl.
QualType getTagDeclType(const TagDecl *Decl) const;
@ -1294,6 +1328,21 @@ class ASTContext {
QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
QualType typeDomain) const;
unsigned getTargetAddressSpace(QualType T) const {
return getTargetAddressSpace(T.getQualifiers());
}
unsigned getTargetAddressSpace(Qualifiers Q) const {
return getTargetAddressSpace(Q.getAddressSpace());
}
unsigned getTargetAddressSpace(unsigned AS) const {
if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
return AS;
else
return AddrSpaceMap[AS - LangAS::Offset];
}
private:
// Helper for integer ordering
unsigned getIntegerRank(const Type *T) const;
@ -1332,7 +1381,8 @@ class ASTContext {
const ObjCObjectType *RHS);
bool canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
const ObjCObjectPointerType *RHSOPT,
bool BlockReturnType);
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@ -1340,7 +1390,7 @@ class ASTContext {
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
QualType mergeFunctionArgumentTypes(QualType, QualType,
@ -1528,13 +1578,13 @@ class ASTContext {
};
/// @brief Utility function for constructing a nullary selector.
static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
static inline Selector GetNullarySelector(llvm::StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(0, &II);
}
/// @brief Utility function for constructing an unary selector.
static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) {
static inline Selector GetUnarySelector(llvm::StringRef name, ASTContext& Ctx) {
IdentifierInfo* II = &Ctx.Idents.get(name);
return Ctx.Selectors.getSelector(1, &II);
}

View File

@ -15,7 +15,8 @@
namespace clang {
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"
#undef DIAG

View File

@ -20,6 +20,8 @@ namespace clang {
class CXXRecordDecl;
class ClassTemplateDecl;
class ClassTemplateSpecializationDecl;
class FunctionDecl;
class FunctionTemplateDecl;
/// \brief An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
@ -41,6 +43,17 @@ class ASTMutationListener {
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {}
/// \brief A template specialization (or partial one) was added to the
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {}
/// \brief An implicit member got a definition.
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
/// \brief A static data member was implicitly instantiated.
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
};
} // end namespace clang

View File

@ -17,9 +17,11 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/VersionTuple.h"
#include <cassert>
#include <cstring>
#include <algorithm>
@ -120,6 +122,19 @@ class InheritableAttr : public Attr {
static bool classof(const InheritableAttr *) { return true; }
};
class InheritableParamAttr : public InheritableAttr {
protected:
InheritableParamAttr(attr::Kind AK, SourceLocation L)
: InheritableAttr(AK, L) {}
public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
}
static bool classof(const InheritableParamAttr *) { return true; }
};
#include "clang/AST/Attrs.inc"
/// AttrVec - A vector of Attr, which is how they are stored on the AST.

View File

@ -87,7 +87,7 @@ class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
/// BasePaths - Represents the set of paths from a derived class to
/// one of its (direct or indirect) bases. For example, given the
/// following class hierachy:
/// following class hierarchy:
///
/// @code
/// class A { };

View File

@ -655,7 +655,8 @@ struct CanProxyAdaptor<TemplateTypeParmType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getDepth)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getIndex)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isParameterPack)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TemplateTypeParmDecl *, getDecl)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getIdentifier)
};
template<>

View File

@ -34,7 +34,7 @@ namespace clang {
/// architectures where the two are the same size.
///
/// For portability, never assume that a target character is 8 bits wide. Use
/// CharUnit values whereever you calculate sizes, offsets, or alignments
/// CharUnit values wherever you calculate sizes, offsets, or alignments
/// in character units.
class CharUnits {
public:
@ -70,10 +70,24 @@ namespace clang {
Quantity += Other.Quantity;
return *this;
}
CharUnits& operator++ () {
++Quantity;
return *this;
}
CharUnits operator++ (int) {
return CharUnits(Quantity++);
}
CharUnits& operator-= (const CharUnits &Other) {
Quantity -= Other.Quantity;
return *this;
}
CharUnits& operator-- () {
--Quantity;
return *this;
}
CharUnits operator-- (int) {
return CharUnits(Quantity--);
}
// Comparison operators.
bool operator== (const CharUnits &Other) const {

View File

@ -20,6 +20,7 @@
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/Linkage.h"
#include "llvm/ADT/Optional.h"
namespace clang {
class CXXTemporary;
@ -119,14 +120,6 @@ class NamedDecl : public Decl {
return getIdentifier() ? getIdentifier()->getName() : "";
}
llvm::StringRef getMessageUnavailableAttr(bool unavailable) const {
if (!unavailable)
return "";
if (const UnavailableAttr *UA = getAttr<UnavailableAttr>())
return UA->getMessage();
return "";
}
/// getNameAsString - Get a human-readable name for the declaration, even if
/// it is one of the special kinds of names (C++ constructor, Objective-C
/// selector, etc). Creating this name requires expensive string
@ -281,6 +274,10 @@ class NamedDecl : public Decl {
/// \brief Determines the linkage and visibility of this entity.
LinkageInfo getLinkageAndVisibility() const;
/// \brief If visibility was explicitly specified for this
/// declaration, return that visibility.
llvm::Optional<Visibility> getExplicitVisibility() const;
/// \brief Clear the linkage cache in response to a change
/// to the declaration.
void ClearLinkageCache();
@ -310,16 +307,32 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
LabelStmt *TheStmt;
LabelDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *II, LabelStmt *S)
: NamedDecl(Label, DC, L, II), TheStmt(S) {}
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
/// this is the location of the __label__ keyword.
SourceLocation LocStart;
LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II,
LabelStmt *S, SourceLocation StartL)
: NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {}
public:
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *II);
SourceLocation IdentL, IdentifierInfo *II);
static LabelDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II,
SourceLocation GnuLabelL);
LabelStmt *getStmt() const { return TheStmt; }
void setStmt(LabelStmt *T) { TheStmt = T; }
bool isGnuLocal() const { return LocStart != getLocation(); }
void setLocStart(SourceLocation L) { LocStart = L; }
SourceRange getSourceRange() const {
return SourceRange(LocStart, getLocation());
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LabelDecl *D) { return true; }
@ -330,7 +343,11 @@ class LabelDecl : public NamedDecl {
class NamespaceDecl : public NamedDecl, public DeclContext {
bool IsInline : 1;
SourceLocation LBracLoc, RBracLoc;
/// LocStart - The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
/// RBraceLoc - The ending location of the source range.
SourceLocation RBraceLoc;
// For extended namespace definitions:
//
@ -357,13 +374,16 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
/// namespace declaration (which the boolean indicates).
llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
: NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
IsInline(false), NextNamespace(), OrigOrAnonNamespace(0, true) { }
NamespaceDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id)
: NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
IsInline(false), LocStart(StartLoc), RBraceLoc(),
NextNamespace(), OrigOrAnonNamespace(0, true) { }
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id);
/// \brief Returns true if this is an anonymous namespace declaration.
///
@ -427,7 +447,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
void setAnonymousNamespace(NamespaceDecl *D) {
assert(!D || D->isAnonymousNamespace());
assert(!D || D->getParent() == this);
assert(!D || D->getParent()->getRedeclContext() == this);
getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
}
@ -437,14 +457,14 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
}
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
return SourceRange(LocStart, RBraceLoc);
}
SourceLocation getLBracLoc() const { return LBracLoc; }
SourceLocation getRBracLoc() const { return RBracLoc; }
void setLBracLoc(SourceLocation L) { LBracLoc = L; }
void setRBracLoc(SourceLocation R) { RBracLoc = R; }
SourceLocation getLocStart() const { return LocStart; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setLocStart(SourceLocation L) { LocStart = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceDecl *D) { return true; }
@ -484,16 +504,24 @@ class ValueDecl : public NamedDecl {
/// name qualifier, to be used for the case of out-of-line declarations.
struct QualifierInfo {
NestedNameSpecifierLoc QualifierLoc;
/// NumTemplParamLists - The number of template parameter lists
/// that were matched against the template-ids occurring into the NNS.
/// NumTemplParamLists - The number of "outer" template parameter lists.
/// The count includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
unsigned NumTemplParamLists;
/// TemplParamLists - A new-allocated array of size NumTemplParamLists,
/// containing pointers to the matched template parameter lists.
/// containing pointers to the "outer" template parameter lists.
/// It includes all of the template parameter lists that were matched
/// against the template-ids occurring into the NNS and possibly (in the
/// case of an explicit specialization) a final "template <>".
TemplateParameterList** TemplParamLists;
/// Default constructor.
QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
/// setTemplateParameterListsInfo - Sets info about matched template
/// setTemplateParameterListsInfo - Sets info about "outer" template
/// parameter lists.
void setTemplateParameterListsInfo(ASTContext &Context,
unsigned NumTPLists,
@ -516,14 +544,20 @@ class DeclaratorDecl : public ValueDecl {
llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo;
/// InnerLocStart - The start of the source range for this declaration,
/// ignoring outer template declarations.
SourceLocation InnerLocStart;
bool hasExtInfo() const { return DeclInfo.is<ExtInfo*>(); }
ExtInfo *getExtInfo() { return DeclInfo.get<ExtInfo*>(); }
const ExtInfo *getExtInfo() const { return DeclInfo.get<ExtInfo*>(); }
protected:
DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo)
: ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo) {}
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
SourceLocation StartL)
: ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {
}
public:
TypeSourceInfo *getTypeSourceInfo() const {
@ -540,14 +574,14 @@ class DeclaratorDecl : public ValueDecl {
/// getInnerLocStart - Return SourceLocation representing start of source
/// range ignoring outer template declarations.
virtual SourceLocation getInnerLocStart() const { return getLocation(); }
SourceLocation getInnerLocStart() const { return InnerLocStart; }
void setInnerLocStart(SourceLocation L) { InnerLocStart = L; }
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
SourceRange getSourceRange() const {
return SourceRange(getOuterLocStart(), getLocation());
}
virtual SourceRange getSourceRange() const;
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@ -574,9 +608,7 @@ class DeclaratorDecl : public ValueDecl {
return getExtInfo()->TemplParamLists[index];
}
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
TemplateParameterList **TPLists) {
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
}
TemplateParameterList **TPLists);
SourceLocation getTypeSpecStartLoc() const;
@ -650,32 +682,77 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
mutable InitType Init;
private:
// FIXME: This can be packed into the bitfields in Decl.
unsigned SClass : 3;
unsigned SClassAsWritten : 3;
bool ThreadSpecified : 1;
bool HasCXXDirectInit : 1;
class VarDeclBitfields {
friend class VarDecl;
friend class ASTDeclReader;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
bool ExceptionVar : 1;
unsigned SClass : 3;
unsigned SClassAsWritten : 3;
unsigned ThreadSpecified : 1;
unsigned HasCXXDirectInit : 1;
/// \brief Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
unsigned ExceptionVar : 1;
/// \brief Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization (NRVO).
bool NRVOVariable : 1;
/// \brief Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization (NRVO).
unsigned NRVOVariable : 1;
/// \brief Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
unsigned CXXForRangeDecl : 1;
};
enum { NumVarDeclBits = 13 }; // two reserved bits for now
friend class StmtIteratorBase;
friend class ASTDeclReader;
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
class ParmVarDeclBitfields {
friend class ParmVarDecl;
friend class ASTDeclReader;
unsigned : NumVarDeclBits;
/// Whether this parameter inherits a default argument from a
/// prior declaration.
unsigned HasInheritedDefaultArg : 1;
/// Whether this parameter undergoes K&R argument promotion.
unsigned IsKNRPromoted : 1;
/// Whether this parameter is an ObjC method parameter or not.
unsigned IsObjCMethodParam : 1;
/// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
/// Otherwise, the number of function parameter scopes enclosing
/// the function parameter scope in which this parameter was
/// declared.
unsigned ScopeDepthOrObjCQuals : 8;
/// The number of parameters preceding this parameter in the
/// function parameter scope in which it was declared.
unsigned ParameterIndex : 8;
};
union {
unsigned AllBits;
VarDeclBitfields VarDeclBits;
ParmVarDeclBitfields ParmVarDeclBits;
};
VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
ExceptionVar(false), NRVOVariable(false) {
SClass = SC;
SClassAsWritten = SCAsWritten;
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
AllBits = 0;
VarDeclBits.SClass = SC;
VarDeclBits.SClassAsWritten = SCAsWritten;
// Everything else is implicitly initialized to false.
}
typedef Redeclarable<VarDecl> redeclarable_base;
@ -691,26 +768,27 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
}
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass S,
StorageClass SCAsWritten);
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten);
virtual SourceLocation getInnerLocStart() const;
virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
}
StorageClass getStorageClassAsWritten() const {
return (StorageClass) SClassAsWritten;
return (StorageClass) VarDeclBits.SClassAsWritten;
}
void setStorageClass(StorageClass SC);
void setStorageClassAsWritten(StorageClass SC) {
assert(isLegalForVariable(SC));
SClassAsWritten = SC;
VarDeclBits.SClassAsWritten = SC;
}
void setThreadSpecified(bool T) { ThreadSpecified = T; }
void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; }
bool isThreadSpecified() const {
return ThreadSpecified;
return VarDeclBits.ThreadSpecified;
}
/// hasLocalStorage - Returns true if a variable with function scope
@ -988,7 +1066,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
Eval->IsICE = IsICE;
}
void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
void setCXXDirectInitializer(bool T) { VarDeclBits.HasCXXDirectInit = T; }
/// hasCXXDirectInitializer - If true, the initializer was a direct
/// initializer, e.g: "int x(1);". The Init expression will be the expression
@ -997,15 +1075,15 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// by checking hasCXXDirectInitializer.
///
bool hasCXXDirectInitializer() const {
return HasCXXDirectInit;
return VarDeclBits.HasCXXDirectInit;
}
/// \brief Determine whether this variable is the exception variable in a
/// C++ catch statememt or an Objective-C @catch statement.
bool isExceptionVariable() const {
return ExceptionVar;
return VarDeclBits.ExceptionVar;
}
void setExceptionVariable(bool EV) { ExceptionVar = EV; }
void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; }
/// \brief Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
@ -1017,8 +1095,13 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// return slot when returning from the function. Within the function body,
/// each return that returns the NRVO object will have this variable as its
/// NRVO candidate.
bool isNRVOVariable() const { return NRVOVariable; }
void setNRVOVariable(bool NRVO) { NRVOVariable = NRVO; }
bool isNRVOVariable() const { return VarDeclBits.NRVOVariable; }
void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; }
/// \brief Determine whether this variable is the for-range-declaration in
/// a C++0x for-range statement.
bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; }
void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; }
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@ -1048,12 +1131,12 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
class ImplicitParamDecl : public VarDecl {
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T);
ImplicitParamDecl(DeclContext *DC, SourceLocation loc,
IdentifierInfo *name, QualType type)
: VarDecl(ImplicitParam, DC, loc, name, type,
ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type)
: VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
/*tinfo*/ 0, SC_None, SC_None) {
setImplicit();
}
@ -1064,35 +1147,85 @@ class ImplicitParamDecl : public VarDecl {
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
/// ParmVarDecl - Represent a parameter to a function.
/// ParmVarDecl - Represents a parameter to a function.
class ParmVarDecl : public VarDecl {
// NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
/// FIXME: Also can be paced into the bitfields in Decl.
/// in, inout, etc.
unsigned objcDeclQualifier : 6;
bool HasInheritedDefaultArg : 1;
public:
enum { MaxFunctionScopeDepth = 255 };
enum { MaxFunctionScopeIndex = 255 };
protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
: VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
: VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) {
assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
assert(ParmVarDeclBits.IsKNRPromoted == false);
assert(ParmVarDeclBits.IsObjCMethodParam == false);
setDefaultArg(DefArg);
}
public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten,
Expr *DefArg);
void setObjCMethodScopeInfo(unsigned parameterIndex) {
ParmVarDeclBits.IsObjCMethodParam = true;
ParmVarDeclBits.ParameterIndex = parameterIndex;
assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
}
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex) {
assert(!ParmVarDeclBits.IsObjCMethodParam);
ParmVarDeclBits.ScopeDepthOrObjCQuals = scopeDepth;
assert(ParmVarDeclBits.ScopeDepthOrObjCQuals == scopeDepth && "truncation!");
ParmVarDeclBits.ParameterIndex = parameterIndex;
assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");
}
bool isObjCMethodParameter() const {
return ParmVarDeclBits.IsObjCMethodParam;
}
unsigned getFunctionScopeDepth() const {
if (ParmVarDeclBits.IsObjCMethodParam) return 0;
return ParmVarDeclBits.ScopeDepthOrObjCQuals;
}
/// Returns the index of this parameter in its prototype or method scope.
unsigned getFunctionScopeIndex() const {
return ParmVarDeclBits.ParameterIndex;
}
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
if (!ParmVarDeclBits.IsObjCMethodParam) return OBJC_TQ_None;
return ObjCDeclQualifier(ParmVarDeclBits.ScopeDepthOrObjCQuals);
}
void setObjCDeclQualifier(ObjCDeclQualifier QTVal) {
objcDeclQualifier = QTVal;
assert(ParmVarDeclBits.IsObjCMethodParam);
ParmVarDeclBits.ScopeDepthOrObjCQuals = QTVal;
}
/// True if the value passed to this parameter must undergo
/// K&R-style default argument promotion:
///
/// C99 6.5.2.2.
/// If the expression that denotes the called function has a type
/// that does not include a prototype, the integer promotions are
/// performed on each argument, and arguments that have type float
/// are promoted to double.
bool isKNRPromoted() const {
return ParmVarDeclBits.IsKNRPromoted;
}
void setKNRPromoted(bool promoted) {
ParmVarDeclBits.IsKNRPromoted = promoted;
}
Expr *getDefaultArg();
@ -1158,11 +1291,11 @@ class ParmVarDecl : public VarDecl {
}
bool hasInheritedDefaultArg() const {
return HasInheritedDefaultArg;
return ParmVarDeclBits.HasInheritedDefaultArg;
}
void setHasInheritedDefaultArg(bool I = true) {
HasInheritedDefaultArg = I;
ParmVarDeclBits.HasInheritedDefaultArg = I;
}
QualType getOriginalType() const {
@ -1233,6 +1366,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool IsDeleted : 1;
bool IsTrivial : 1; // sunk from CXXMethodDecl
bool HasImplicitReturnZero : 1;
bool IsLateTemplateParsed : 1;
/// \brief End part of this FunctionDecl's source range.
///
@ -1302,17 +1436,20 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams);
protected:
FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo),
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK),
ParamInfo(0), Body(),
SClass(S), SClassAsWritten(SCAsWritten),
SClass(S), SClassAsWritten(SCAsWritten),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
HasImplicitReturnZero(false), EndRangeLoc(NameInfo.getEndLoc()),
HasImplicitReturnZero(false), IsLateTemplateParsed(false),
EndRangeLoc(NameInfo.getEndLoc()),
TemplateOrSpecialization(),
DNLoc(NameInfo.getInfo()) {}
@ -1328,22 +1465,25 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
return redeclarable_base::redecls_end();
}
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation NLoc,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
StorageClass S = SC_None,
StorageClass SC = SC_None,
StorageClass SCAsWritten = SC_None,
bool isInlineSpecified = false,
bool hasWrittenPrototype = true) {
DeclarationNameInfo NameInfo(N, L);
return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten,
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
SC, SCAsWritten,
isInlineSpecified, hasWrittenPrototype);
}
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S = SC_None,
StorageClass SC = SC_None,
StorageClass SCAsWritten = SC_None,
bool isInlineSpecified = false,
bool hasWrittenPrototype = true);
@ -1356,12 +1496,9 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
const PrintingPolicy &Policy,
bool Qualified) const;
virtual SourceRange getSourceRange() const {
return SourceRange(getOuterLocStart(), EndRangeLoc);
}
void setLocEnd(SourceLocation E) {
EndRangeLoc = E;
}
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
virtual SourceRange getSourceRange() const;
/// \brief Returns true if the function has a body (definition). The
/// function body might be in any of the (re-)declarations of this
@ -1395,7 +1532,9 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// 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.
bool isThisDeclarationADefinition() const { return Body; }
bool isThisDeclarationADefinition() const {
return Body || IsLateTemplateParsed;
}
void setBody(Stmt *B);
void setLazyBody(uint64_t Offset) { Body = Offset; }
@ -1412,6 +1551,14 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool isPure() const { return IsPure; }
void setPure(bool P = true);
/// Whether this is a constexpr function or constexpr constructor.
// FIXME: C++0x: Implement tracking of the constexpr specifier.
bool isConstExpr() const { return false; }
/// Whether this templated function will be late parsed.
bool isLateTemplateParsed() const { return IsLateTemplateParsed; }
void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; }
/// Whether this function is "trivial" in some specialized C++ senses.
/// Can only be true for default constructors, copy constructors,
/// copy assignment operators, and destructors. Not meaningful until
@ -1757,16 +1904,17 @@ class FieldDecl : public DeclaratorDecl {
Expr *BitWidth;
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
Expr *BW, bool Mutable)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo),
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
Mutable(Mutable), CachedFieldIndex(0), BitWidth(BW) {
}
public:
static FieldDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, QualType T,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable);
/// getFieldIndex - Returns the index of this field within its record,
@ -1803,7 +1951,9 @@ class FieldDecl : public DeclaratorDecl {
RecordDecl *getParent() {
return cast<RecordDecl>(getDeclContext());
}
SourceRange getSourceRange() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
@ -1895,6 +2045,8 @@ class TypeDecl : public NamedDecl {
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
/// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl.
mutable const Type *TypeForDecl;
/// LocStart - The start of the source range for this declaration.
SourceLocation LocStart;
friend class ASTContext;
friend class DeclContext;
friend class TagDecl;
@ -1902,15 +2054,24 @@ class TypeDecl : public NamedDecl {
friend class TagType;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id)
: NamedDecl(DK, DC, L, Id), TypeForDecl(0) {}
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation StartL = SourceLocation())
: NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {}
public:
// Low-level accessor
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
SourceLocation getLocStart() const { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
virtual SourceRange getSourceRange() const {
if (LocStart.isValid())
return SourceRange(LocStart, getLocation());
else
return SourceRange(getLocation());
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
@ -1918,17 +2079,21 @@ class TypeDecl : public NamedDecl {
};
class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
/// UnderlyingType - This is the type the typedef is set to.
TypeSourceInfo *TInfo;
TypedefDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
protected:
typedef Redeclarable<TypedefDecl> redeclarable_base;
virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
TypeSourceInfo *TInfo)
: TypeDecl(DK, DC, IdLoc, Id, StartLoc), TInfo(TInfo) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
virtual TypedefNameDecl *getNextRedeclaration() {
return RedeclLink.getNext();
}
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
@ -1939,19 +2104,15 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
return redeclarable_base::redecls_end();
}
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
TypeSourceInfo *TInfo);
TypeSourceInfo *getTypeSourceInfo() const {
return TInfo;
}
/// Retrieves the canonical declaration of this typedef.
TypedefDecl *getCanonicalDecl() {
/// Retrieves the canonical declaration of this typedef-name.
TypedefNameDecl *getCanonicalDecl() {
return getFirstDeclaration();
}
const TypedefDecl *getCanonicalDecl() const {
const TypedefNameDecl *getCanonicalDecl() const {
return getFirstDeclaration();
}
@ -1962,13 +2123,53 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
TInfo = newType;
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefNameDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= firstTypedefName && K <= lastTypedefName;
}
};
/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
SourceRange getSourceRange() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Typedef; }
};
class TypedefDecl;
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo)
: TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
SourceRange getSourceRange() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TypeAlias; }
};
/// TagDecl - Represents the declaration of a struct/union/class/enum.
class TagDecl
@ -2013,32 +2214,31 @@ class TagDecl
bool IsFixed : 1;
private:
SourceLocation TagKeywordLoc;
SourceLocation RBraceLoc;
// A struct representing syntactic qualifier info,
// to be used for the (uncommon) case of out-of-line declarations.
typedef QualifierInfo ExtInfo;
/// TypedefDeclOrQualifier - If the (out-of-line) tag declaration name
/// TypedefNameDeclOrQualifier - If the (out-of-line) tag declaration name
/// is qualified, it points to the qualifier info (nns and range);
/// otherwise, if the tag declaration is anonymous and it is part of
/// a typedef, it points to the TypedefDecl (used for mangling);
/// otherwise, it is a null (TypedefDecl) pointer.
llvm::PointerUnion<TypedefDecl*, ExtInfo*> TypedefDeclOrQualifier;
/// a typedef or alias, it points to the TypedefNameDecl (used for mangling);
/// otherwise, it is a null (TypedefNameDecl) pointer.
llvm::PointerUnion<TypedefNameDecl*, ExtInfo*> TypedefNameDeclOrQualifier;
bool hasExtInfo() const { return TypedefDeclOrQualifier.is<ExtInfo*>(); }
ExtInfo *getExtInfo() { return TypedefDeclOrQualifier.get<ExtInfo*>(); }
bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo*>(); }
ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo*>(); }
const ExtInfo *getExtInfo() const {
return TypedefDeclOrQualifier.get<ExtInfo*>();
return TypedefNameDeclOrQualifier.get<ExtInfo*>();
}
protected:
TagDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
: TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
TypedefDeclOrQualifier((TypedefDecl*) 0) {
TagDecl *PrevDecl, SourceLocation StartL)
: TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK),
TypedefNameDeclOrQualifier((TypedefNameDecl*) 0) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
@ -2068,12 +2268,9 @@ class TagDecl
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
SourceLocation getTagKeywordLoc() const { return TagKeywordLoc; }
void setTagKeywordLoc(SourceLocation TKL) { TagKeywordLoc = TKL; }
/// getInnerLocStart - Return SourceLocation representing start of source
/// range ignoring outer template declarations.
virtual SourceLocation getInnerLocStart() const { return TagKeywordLoc; }
SourceLocation getInnerLocStart() const { return getLocStart(); }
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
@ -2146,11 +2343,11 @@ class TagDecl
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
TypedefNameDecl *getTypedefNameForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefNameDeclOrQualifier.get<TypedefNameDecl*>();
}
void setTypedefForAnonDecl(TypedefDecl *TDD);
void setTypedefNameForAnonDecl(TypedefNameDecl *TDD);
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@ -2177,9 +2374,7 @@ class TagDecl
return getExtInfo()->TemplParamLists[i];
}
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
TemplateParameterList **TPLists) {
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
}
TemplateParameterList **TPLists);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -2235,18 +2430,19 @@ class EnumDecl : public TagDecl {
NumBitsMask = (1 << NumBitsWidth) - 1
};
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL,
EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
: TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = (const Type*)0;
NumNegativeBits = 0;
NumPositiveBits = 0;
IsScoped = Scoped;
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
}
: TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
InstantiatedFrom(0) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = (const Type*)0;
NumNegativeBits = 0;
NumPositiveBits = 0;
IsScoped = Scoped;
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
}
public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
@ -2263,8 +2459,8 @@ class EnumDecl : public TagDecl {
}
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL, EnumDecl *PrevDecl,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool IsScoped, bool IsScopedUsingClassTag,
bool IsFixed);
static EnumDecl *Create(ASTContext &C, EmptyShell Empty);
@ -2326,7 +2522,7 @@ class EnumDecl : public TagDecl {
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
/// \brief Returns the width in bits requred to store all the
/// \brief Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
return NumPositiveBits;
@ -2336,7 +2532,7 @@ class EnumDecl : public TagDecl {
assert(NumPositiveBits == Num && "can't store this bitcount");
}
/// \brief Returns the width in bits requred to store all the
/// \brief Returns the width in bits required to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
///
@ -2419,14 +2615,13 @@ class RecordDecl : public TagDecl {
protected:
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
RecordDecl *PrevDecl, SourceLocation TKL);
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl *PrevDecl);
public:
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
RecordDecl* PrevDecl = 0);
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
static RecordDecl *Create(const ASTContext &C, EmptyShell Empty);
const RecordDecl *getPreviousDeclaration() const {
@ -2519,11 +2714,21 @@ class RecordDecl : public TagDecl {
class FileScopeAsmDecl : public Decl {
StringLiteral *AsmString;
FileScopeAsmDecl(DeclContext *DC, SourceLocation L, StringLiteral *asmstring)
: Decl(FileScopeAsm, DC, L), AsmString(asmstring) {}
SourceLocation RParenLoc;
FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring,
SourceLocation StartL, SourceLocation EndL)
: Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {}
public:
static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, StringLiteral *Str);
StringLiteral *Str, SourceLocation AsmLoc,
SourceLocation RParenLoc);
SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
SourceRange getSourceRange() const {
return SourceRange(getAsmLoc(), getRParenLoc());
}
const StringLiteral *getAsmString() const { return AsmString; }
StringLiteral *getAsmString() { return AsmString; }

View File

@ -62,6 +62,15 @@ template<>
namespace clang {
/// \brief Captures the result of checking the availability of a
/// declaration.
enum AvailabilityResult {
AR_Available = 0,
AR_NotYetIntroduced,
AR_Deprecated,
AR_Unavailable
};
/// Decl - This represents one declaration (or definition), e.g. a variable,
/// typedef, function, struct, etc.
///
@ -147,9 +156,20 @@ class Decl {
IDNS_NonMemberOperator = 0x0400
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
/// for remote messaging. They are meant for the arguments though and
/// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
/// parameter types in method declarations. Other than remembering
/// them and mangling them into the method's signature string, these
/// are ignored by the compiler; they are consumed by certain
/// remote-messaging frameworks.
///
/// in, inout, and out are mutually exclusive and apply only to
/// method parameters. bycopy and byref are mutually exclusive and
/// apply only to method parameters (?). oneway applies only to
/// results. All of these expect their corresponding parameter to
/// have a particular type. None of this is currently enforced by
/// clang.
///
/// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
enum ObjCDeclQualifier {
OBJC_TQ_None = 0x0,
OBJC_TQ_In = 0x1,
@ -218,6 +238,12 @@ class Decl {
/// required.
unsigned Used : 1;
/// \brief Whether this declaration was "referenced".
/// The difference with 'Used' is whether the reference appears in a
/// evaluated context or not, e.g. functions used in uninstantiated templates
/// are regarded as "referenced" but not "used".
unsigned Referenced : 1;
protected:
/// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
@ -252,7 +278,7 @@ class Decl {
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
HasCachedLinkage(0)
@ -262,7 +288,7 @@ class Decl {
Decl(Kind DK, EmptyShell Empty)
: NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
HasAttrs(false), Implicit(false), Used(false), Referenced(false),
Access(AS_none), PCHLevel(0), ChangedAfterLoad(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
HasCachedLinkage(0)
@ -399,6 +425,57 @@ class Decl {
void setUsed(bool U = true) { Used = U; }
/// \brief Whether this declaration was referenced.
bool isReferenced() const;
void setReferenced(bool R = true) { Referenced = R; }
/// \brief Determine the availability of the given declaration.
///
/// This routine will determine the most restrictive availability of
/// the given declaration (e.g., preferring 'unavailable' to
/// 'deprecated').
///
/// \param Message If non-NULL and the result is not \c
/// AR_Available, will be set to a (possibly empty) message
/// describing why the declaration has not been introduced, is
/// deprecated, or is unavailable.
AvailabilityResult getAvailability(std::string *Message = 0) const;
/// \brief Determine whether this declaration is marked 'deprecated'.
///
/// \param Message If non-NULL and the declaration is deprecated,
/// this will be set to the message describing why the declaration
/// was deprecated (which may be empty).
bool isDeprecated(std::string *Message = 0) const {
return getAvailability(Message) == AR_Deprecated;
}
/// \brief Determine whether this declaration is marked 'unavailable'.
///
/// \param Message If non-NULL and the declaration is unavailable,
/// this will be set to the message describing why the declaration
/// was made unavailable (which may be empty).
bool isUnavailable(std::string *Message = 0) const {
return getAvailability(Message) == AR_Unavailable;
}
/// \brief Determine whether this is a weak-imported symbol.
///
/// Weak-imported symbols are typically marked with the
/// 'weak_import' attribute, but may also be marked with an
/// 'availability' attribute where we're targing a platform prior to
/// the introduction of this feature.
bool isWeakImported() const;
/// \brief Determines whether this symbol can be weak-imported,
/// e.g., whether it would be well-formed to add the weak_import
/// attribute.
///
/// \param IsDefinition Set to \c true to indicate that this
/// declaration cannot be weak-imported because it has a definition.
bool canBeWeakImported(bool &IsDefinition) const;
/// \brief Retrieve the level of precompiled header from which this
/// declaration was generated.
///

View File

@ -306,6 +306,37 @@ class CXXRecordDecl : public RecordDecl {
/// one pure virtual function, (that can come from a base class).
bool Abstract : 1;
/// IsStandardLayout - True when this class has standard layout.
///
/// C++0x [class]p7. A standard-layout class is a class that:
/// * has no non-static data members of type non-standard-layout class (or
/// array of such types) or reference,
/// * has no virtual functions (10.3) and no virtual base classes (10.1),
/// * has the same access control (Clause 11) for all non-static data members
/// * has no non-standard-layout base classes,
/// * either has no non-static data members in the most derived class and at
/// most one base class with non-static data members, or has no base
/// classes with non-static data members, and
/// * has no base classes of the same type as the first non-static data
/// member.
bool IsStandardLayout : 1;
/// HasNoNonEmptyBases - True when there are no non-empty base classes.
///
/// This is a helper bit of state used to implement IsStandardLayout more
/// efficiently.
bool HasNoNonEmptyBases : 1;
/// HasPrivateFields - True when there are private non-static data members.
bool HasPrivateFields : 1;
/// HasProtectedFields - True when there are protected non-static data
/// members.
bool HasProtectedFields : 1;
/// HasPublicFields - True when there are private non-static data members.
bool HasPublicFields : 1;
/// HasTrivialConstructor - True when this class has a trivial constructor.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
@ -316,31 +347,71 @@ class CXXRecordDecl : public RecordDecl {
/// (or array thereof), each such class has a trivial constructor.
bool HasTrivialConstructor : 1;
/// HasConstExprNonCopyMoveConstructor - True when this class has at least
/// one constexpr constructor which is neither the copy nor move
/// constructor.
bool HasConstExprNonCopyMoveConstructor : 1;
/// HasTrivialCopyConstructor - True when this class has a trivial copy
/// constructor.
///
/// C++ [class.copy]p6. A copy constructor for class X is trivial
/// if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy constructor, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy constructor;
/// otherwise the copy constructor is non-trivial.
/// C++0x [class.copy]p13:
/// A copy/move constructor for class X is trivial if it is neither
/// user-provided nor deleted 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
/// -- for each non-static data member of X that is of class type (or an
/// array thereof), the constructor selected to copy/move that member
/// is trivial;
/// otherwise the copy/move constructor is non-trivial.
bool HasTrivialCopyConstructor : 1;
/// HasTrivialMoveConstructor - True when this class has a trivial move
/// constructor.
///
/// C++0x [class.copy]p13:
/// A copy/move constructor for class X is trivial if it is neither
/// user-provided nor deleted 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
/// -- for each non-static data member of X that is of class type (or an
/// array thereof), the constructor selected to copy/move that member
/// is trivial;
/// otherwise the copy/move constructor is non-trivial.
bool HasTrivialMoveConstructor : 1;
/// HasTrivialCopyAssignment - True when this class has a trivial copy
/// assignment operator.
///
/// C++ [class.copy]p11. A copy assignment operator for class X is
/// trivial if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy assignment operator, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy assignment
/// operator;
/// otherwise the copy assignment operator is non-trivial.
/// C++0x [class.copy]p27:
/// A copy/move assignment operator for class X is trivial if it is
/// neither user-provided nor deleted and if
/// -- class X has no virtual functions and no virtual base classes, and
/// -- the assignment operator selected to copy/move each direct base
/// class subobject is trivial, and
/// -- for each non-static data member of X that is of class type (or an
/// array thereof), the assignment operator selected to copy/move
/// that member is trivial;
/// otherwise the copy/move assignment operator is non-trivial.
bool HasTrivialCopyAssignment : 1;
/// HasTrivialMoveAssignment - True when this class has a trivial 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 and if
/// -- class X has no virtual functions and no virtual base classes, and
/// -- the assignment operator selected to copy/move each direct base
/// class subobject is trivial, and
/// -- for each non-static data member of X that is of class type (or an
/// array thereof), the assignment operator selected to copy/move
/// that member is trivial;
/// otherwise the copy/move assignment operator is non-trivial.
bool HasTrivialMoveAssignment : 1;
/// HasTrivialDestructor - True when this class has a trivial destructor.
///
/// C++ [class.dtor]p3. A destructor is trivial if it is an
@ -351,6 +422,10 @@ class CXXRecordDecl : public RecordDecl {
/// type (or array thereof), each such class has a trivial destructor.
bool HasTrivialDestructor : 1;
/// HasNonLiteralTypeFieldsOrBases - True when this class contains at least
/// one non-static data member or base class of non literal type.
bool HasNonLiteralTypeFieldsOrBases : 1;
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
@ -449,9 +524,8 @@ class CXXRecordDecl : public RecordDecl {
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
CXXRecordDecl *PrevDecl,
SourceLocation TKL = SourceLocation());
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
public:
/// base_class_iterator - Iterator that traverses the base classes
@ -494,9 +568,8 @@ class CXXRecordDecl : public RecordDecl {
bool hasDefinition() const { return DefinitionData != 0; }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
CXXRecordDecl* PrevDecl=0,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty);
@ -723,26 +796,58 @@ class CXXRecordDecl : public RecordDecl {
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return data().Abstract; }
/// isStandardLayout - Whether this class has standard layout
/// (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; }
// hasConstExprNonCopyMoveConstructor - Whether this class has at least one
// constexpr constructor other than the copy or move constructors
bool hasConstExprNonCopyMoveConstructor() const {
return data().HasConstExprNonCopyMoveConstructor;
}
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
// constructor (C++ [class.copy]p6, C++0x [class.copy]p13)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
// hasTrivialMoveConstructor - Whether this class has a trivial move
// constructor (C++0x [class.copy]p13)
bool hasTrivialMoveConstructor() const {
return data().HasTrivialMoveConstructor;
}
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
// assignment operator (C++ [class.copy]p11, C++0x [class.copy]p27)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
// hasTrivialMoveAssignment - Whether this class has a trivial move
// assignment operator (C++0x [class.copy]p27)
bool hasTrivialMoveAssignment() const {
return data().HasTrivialMoveAssignment;
}
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
// hasNonLiteralTypeFieldsOrBases - Whether this class has a non-literal type
// non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const {
return data().HasNonLiteralTypeFieldsOrBases;
}
// isTriviallyCopyable - Whether this class is considered trivially copyable
// (C++0x [class]p5).
bool isTriviallyCopyable() const;
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@ -1034,20 +1139,27 @@ class CXXRecordDecl : public RecordDecl {
/// struct/union/class.
class CXXMethodDecl : public FunctionDecl {
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD,
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isStatic, StorageClass SCAsWritten, bool isInline)
: FunctionDecl(DK, RD, NameInfo, T, TInfo, (isStatic ? SC_Static : SC_None),
SCAsWritten, isInline) {}
bool isStatic, StorageClass SCAsWritten, bool isInline,
SourceLocation EndLocation)
: FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
(isStatic ? SC_Static : SC_None),
SCAsWritten, isInline) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
}
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isStatic = false,
StorageClass SCAsWritten = SC_None,
bool isInline = false);
bool isStatic,
StorageClass SCAsWritten,
bool isInline,
SourceLocation EndLocation);
bool isStatic() const { return getStorageClass() == SC_Static; }
bool isInstance() const { return !isStatic(); }
@ -1148,13 +1260,16 @@ class CXXMethodDecl : public FunctionDecl {
/// @endcode
class CXXCtorInitializer {
/// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
/// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being
/// initialized.
llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
/// field (FieldDecl), anonymous field (IndirectFieldDecl*), or target
/// constructor (CXXConstructorDecl*) being initialized.
llvm::PointerUnion4<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *,
CXXConstructorDecl *>
Initializee;
/// \brief The source location for the field name or, for a base initializer
/// pack expansion, the location of the ellipsis.
/// pack expansion, the location of the ellipsis. In the case of a delegating
/// constructor, it will still include the type's source location as the
/// Initializee points to the CXXConstructorDecl (to allow loop detection).
SourceLocation MemberOrEllipsisLocation;
/// \brief The argument used to initialize the base or member, which may
@ -1199,11 +1314,17 @@ class CXXCtorInitializer {
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
/// CXXCtorInitializer - Creates a new anonymous field initializer.
explicit
CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
SourceLocation MemberLoc, SourceLocation L, Expr *Init,
SourceLocation R);
/// CXXCtorInitializer - Creates a new delegating Initializer.
explicit
CXXCtorInitializer(ASTContext &Context, SourceLocation D, SourceLocation L,
CXXConstructorDecl *Target, Expr *Init, SourceLocation R);
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
@ -1227,6 +1348,12 @@ class CXXCtorInitializer {
return Initializee.is<IndirectFieldDecl*>();
}
/// isDelegatingInitializer - Returns true when this initializer is creating
/// a delegating constructor.
bool isDelegatingInitializer() const {
return Initializee.is<CXXConstructorDecl *>();
}
/// \brief Determine whether this initializer is a pack expansion.
bool isPackExpansion() const {
return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
@ -1284,6 +1411,13 @@ class CXXCtorInitializer {
return 0;
}
CXXConstructorDecl *getTargetConstructor() const {
if (isDelegatingInitializer())
return Initializee.get<CXXConstructorDecl*>();
else
return 0;
}
SourceLocation getMemberLocation() const {
return MemberOrEllipsisLocation;
}
@ -1373,12 +1507,13 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXCtorInitializer **CtorInitializers;
unsigned NumCtorInitializers;
CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false,
SC_None, isInline),
: CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false,
SC_None, isInline, SourceLocation()),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
CtorInitializers(0), NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
@ -1387,6 +1522,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
public:
static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicit,
@ -1472,6 +1608,23 @@ class CXXConstructorDecl : public CXXMethodDecl {
void setCtorInitializers(CXXCtorInitializer ** initializers) {
CtorInitializers = initializers;
}
/// isDelegatingConstructor - Whether this constructor is a
/// delegating constructor
bool isDelegatingConstructor() const {
return (getNumCtorInitializers() == 1) &&
CtorInitializers[0]->isDelegatingInitializer();
}
/// getTargetConstructor - When this constructor delegates to
/// another, retrieve the target
CXXConstructorDecl *getTargetConstructor() const {
if (isDelegatingConstructor())
return CtorInitializers[0]->getTargetConstructor();
else
return 0;
}
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
/// default-initialize a class of this type.
@ -1508,8 +1661,11 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// \brief Determine whether this constructor is a move constructor
/// (C++0x [class.copy]p3), which can be used to move values of the class.
bool isMoveConstructor() const;
bool isMoveConstructor() const {
unsigned TypeQuals = 0;
return isMoveConstructor(TypeQuals);
}
/// \brief Determine whether this is a copy or move constructor.
///
/// \param TypeQuals Will be set to the type qualifiers on the reference
@ -1567,11 +1723,12 @@ class CXXDestructorDecl : public CXXMethodDecl {
FunctionDecl *OperatorDelete;
CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
: CXXMethodDecl(CXXDestructor, RD, NameInfo, T, TInfo, false,
SC_None, isInline),
: CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false,
SC_None, isInline, SourceLocation()),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@ -1579,6 +1736,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo* TInfo,
bool isInline,
@ -1629,19 +1787,23 @@ class CXXConversionDecl : public CXXMethodDecl {
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
CXXConversionDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified)
: CXXMethodDecl(CXXConversion, RD, NameInfo, T, TInfo, false,
SC_None, isInline),
bool isInline, bool isExplicitSpecified,
SourceLocation EndLocation)
: CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false,
SC_None, isInline, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
bool isInline, bool isExplicit,
SourceLocation EndLocation);
/// IsExplicitSpecified - Whether this conversion function declaration is
/// marked "explicit", meaning that it can only be applied when the user
@ -1688,33 +1850,48 @@ class LinkageSpecDecl : public Decl, public DeclContext {
private:
/// Language - The language for this linkage specification.
LanguageIDs Language;
/// ExternLoc - The source location for the extern keyword.
SourceLocation ExternLoc;
/// RBraceLoc - The source location for the right brace (if valid).
SourceLocation RBraceLoc;
/// HadBraces - Whether this linkage specification had curly braces or not.
bool HadBraces : 1;
LinkageSpecDecl(DeclContext *DC, SourceLocation L, LanguageIDs lang,
bool Braces)
: Decl(LinkageSpec, DC, L),
DeclContext(LinkageSpec), Language(lang), HadBraces(Braces) { }
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
SourceLocation LangLoc, LanguageIDs lang,
SourceLocation RBLoc)
: Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { }
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, LanguageIDs Lang,
bool Braces);
SourceLocation ExternLoc,
SourceLocation LangLoc, LanguageIDs Lang,
SourceLocation RBraceLoc = SourceLocation());
/// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return Language; }
/// \brief Set the language specified by this linkage specification.
void setLanguage(LanguageIDs L) { Language = L; }
/// \brief Determines whether this linkage specification had braces in
/// its syntactic form.
bool hasBraces() const { return HadBraces; }
bool hasBraces() const { return RBraceLoc.isValid(); }
/// \brief Set whether this linkage specification has braces in its
/// syntactic form.
void setHasBraces(bool B) { HadBraces = B; }
SourceLocation getExternLoc() const { return ExternLoc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setExternLoc(SourceLocation L) { ExternLoc = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
SourceLocation getLocEnd() const {
if (hasBraces())
return getRBraceLoc();
// No braces: get the end location of the (only) declaration in context
// (if present).
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
SourceRange getSourceRange() const {
return SourceRange(ExternLoc, getLocEnd());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
@ -2023,12 +2200,6 @@ class UsingDecl : public NamedDecl {
return QualifierLoc.getNestedNameSpecifier();
}
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifies the name.
SourceRange getQualifierRange() const {
return QualifierLoc.getSourceRange();
}
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
@ -2154,12 +2325,6 @@ class UnresolvedUsingValueDecl : public ValueDecl {
return QualifierLoc.getNestedNameSpecifier();
}
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifies the name.
SourceRange getQualifierRange() const {
return QualifierLoc.getSourceRange();
}
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
@ -2205,15 +2370,15 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc,
IdentifierInfo *TargetName)
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
UsingLocation(UsingLoc), TypenameLocation(TypenameLoc),
QualifierLoc(QualifierLoc) { }
: TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,
UsingLoc),
TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }
friend class ASTDeclReader;
public:
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
SourceLocation getUsingLoc() const { return getLocStart(); }
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
@ -2227,22 +2392,11 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
return QualifierLoc.getNestedNameSpecifier();
}
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifies the name.
SourceRange getQualifierRange() const {
return QualifierLoc.getSourceRange();
}
// FIXME: DeclarationNameInfo
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TargetNameLoc, DeclarationName TargetName);
SourceRange getSourceRange() const {
return SourceRange(UsingLocation, getLocation());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UnresolvedUsingTypename; }
@ -2252,15 +2406,19 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
class StaticAssertDecl : public Decl {
Expr *AssertExpr;
StringLiteral *Message;
SourceLocation RParenLoc;
StaticAssertDecl(DeclContext *DC, SourceLocation L,
Expr *assertexpr, StringLiteral *message)
: Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
Expr *assertexpr, StringLiteral *message,
SourceLocation RParenLoc)
: Decl(StaticAssert, DC, StaticAssertLoc), AssertExpr(assertexpr),
Message(message), RParenLoc(RParenLoc) { }
public:
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, Expr *AssertExpr,
StringLiteral *Message);
SourceLocation StaticAssertLoc,
Expr *AssertExpr, StringLiteral *Message,
SourceLocation RParenLoc);
Expr *getAssertExpr() { return AssertExpr; }
const Expr *getAssertExpr() const { return AssertExpr; }
@ -2268,6 +2426,13 @@ class StaticAssertDecl : public Decl {
StringLiteral *getMessage() { return Message; }
const StringLiteral *getMessage() const { return Message; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
SourceRange getSourceRange() const {
return SourceRange(getLocation(), getRParenLoc());
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
static bool classofKind(Kind K) { return K == StaticAssert; }

View File

@ -98,6 +98,17 @@ class FriendDecl : public Decl {
return FriendLoc;
}
/// Retrieves the source range for the friend declaration.
SourceRange getSourceRange() const {
/* FIXME: consider the case of templates wrt start of range. */
if (NamedDecl *ND = getFriendDecl())
return SourceRange(getFriendLoc(), ND->getLocEnd());
else if (TypeSourceInfo *TInfo = getFriendType())
return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc());
else
return SourceRange(getFriendLoc(), getLocation());
}
/// Determines if this friend kind is unsupported.
bool isUnsupportedFriend() const {
return UnsupportedFriend;

View File

@ -112,17 +112,20 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
public:
enum ImplementationControl { None, Required, Optional };
private:
/// Bitfields must be first fields in this class so they pack with those
/// declared in class Decl.
// The conventional meaning of this method; an ObjCMethodFamily.
// This is not serialized; instead, it is computed on demand and
// cached.
mutable unsigned Family : ObjCMethodFamilyBitWidth;
/// instance (true) or class (false) method.
bool IsInstance : 1;
bool IsVariadic : 1;
unsigned IsInstance : 1;
unsigned IsVariadic : 1;
// Synthesized declaration method for a property setter/getter
bool IsSynthesized : 1;
unsigned IsSynthesized : 1;
// Method has a definition.
bool IsDefined : 1;
unsigned IsDefined : 1;
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
/// @required/@optional
@ -170,7 +173,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ImplementationControl impControl = None,
unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod),
DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
IsDefined(isDefined),
@ -279,6 +282,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
/// Determines the family of this method.
ObjCMethodFamily getMethodFamily() const;
bool isInstanceMethod() const { return IsInstance; }
void setInstanceMethod(bool isInst) { IsInstance = isInst; }
bool isVariadic() const { return IsVariadic; }
@ -453,7 +459,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
///
/// Categories are stored as a linked list in the AST, since the categories
/// and class extensions come long after the initial interface declaration,
/// and we avoid dynamically-resized arrays in the AST whereever possible.
/// and we avoid dynamically-resized arrays in the AST wherever possible.
ObjCCategoryDecl *CategoryList;
/// IvarList - List of all ivars defined by this class; including class
@ -701,15 +707,18 @@ class ObjCIvarDecl : public FieldDecl {
};
private:
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
bool synthesized)
: FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false),
NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation L, IdentifierInfo *Id, QualType T,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
AccessControl ac, Expr *BW = NULL,
bool synthesized=false);
@ -753,17 +762,18 @@ class ObjCIvarDecl : public FieldDecl {
/// @defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
private:
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, L, Id, T,
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
/*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false) {}
public:
static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id, QualType T,
Expr *BW);
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -773,7 +783,7 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
/// declare a pure abstract type (i.e no instance variables are permitted).
/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
/// Protocols originally drew inspiration from C++ pure virtual functions (a C++
/// feature with nice semantics and lousy syntax:-). Here is an example:
///
/// @protocol NSDraggingInfo <refproto1, refproto2>

View File

@ -771,9 +771,20 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl,
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
Common() : InjectedArgs(0) { }
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
/// \brief The set of "injected" template arguments used within this
/// function template.
///
/// This pointer refers to the template arguments (there are as
/// many template arguments as template parameaters) for the function
/// template, and is allocated lazily, since most function templates do not
/// require the use of this information.
TemplateArgument *InjectedArgs;
};
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@ -793,6 +804,13 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl,
llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
return getCommonPtr()->Specializations;
}
/// \brief Add a specialization of this function template.
///
/// \param InsertPos Insert position in the FoldingSet, must have been
/// retrieved by an earlier call to findSpecialization().
void addSpecialization(FunctionTemplateSpecializationInfo* Info,
void *InsertPos);
public:
/// Get the underlying function declaration of the template.
@ -844,13 +862,25 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl,
return makeSpecIterator(getSpecializations(), true);
}
/// Create a template function node.
/// \brief Retrieve the "injected" template arguments that correspond to the
/// template parameters of this function template.
///
/// Although the C++ standard has no notion of the "injected" template
/// arguments for a function template, the notion is convenient when
/// we need to perform substitutions inside the definition of a function
/// template.
std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs();
/// \brief Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
NamedDecl *Decl);
/// \brief Create an empty function template node.
static FunctionTemplateDecl *Create(ASTContext &C, EmptyShell);
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionTemplateDecl *D) { return true; }
@ -915,25 +945,23 @@ class TemplateTypeParmDecl : public TypeDecl {
/// default argument.
bool InheritedDefault : 1;
/// \brief Whether this is a parameter pack.
bool ParameterPack : 1;
/// \brief The default template argument, if any.
TypeSourceInfo *DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
bool Typename, QualType Type, bool ParameterPack)
: TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
TypeForDecl = Type.getTypePtrOrNull();
}
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
bool Typename)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
InheritedDefault(false), DefaultArgument() { }
/// Sema creates these on the stack during auto type deduction.
friend class Sema;
public:
static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
SourceLocation KeyLoc,
SourceLocation NameLoc,
unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty);
@ -978,9 +1006,6 @@ class TemplateTypeParmDecl : public TypeDecl {
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
/// \brief Set whether this is a parameter pack.
void setParameterPack(bool isParamPack) { ParameterPack = isParamPack; }
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
@ -988,7 +1013,9 @@ class TemplateTypeParmDecl : public TypeDecl {
unsigned getIndex() const;
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const { return ParameterPack; }
bool isParameterPack() const;
SourceRange getSourceRange() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -1021,17 +1048,19 @@ class NonTypeTemplateParmDecl
/// \brief The number of types in an expanded parameter pack.
unsigned NumExpandedTypes;
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo),
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
ParameterPack(ParameterPack), ExpandedParameterPack(false),
NumExpandedTypes(0)
{ }
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
const QualType *ExpandedTypes,
unsigned NumExpandedTypes,
@ -1041,13 +1070,14 @@ class NonTypeTemplateParmDecl
public:
static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack,
TypeSourceInfo *TInfo);
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
const QualType *ExpandedTypes, unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos);
@ -1057,7 +1087,6 @@ class NonTypeTemplateParmDecl
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
SourceLocation getInnerLocStart() const;
SourceRange getSourceRange() const;
/// \brief Determine whether this template parameter has a default
@ -1316,7 +1345,8 @@ class ClassTemplateSpecializationDecl
protected:
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
unsigned NumArgs,
@ -1326,7 +1356,8 @@ class ClassTemplateSpecializationDecl
public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
unsigned NumArgs,
@ -1488,7 +1519,7 @@ class ClassTemplateSpecializationDecl
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
SourceRange getSourceRange() const;
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
@ -1544,7 +1575,9 @@ class ClassTemplatePartialSpecializationDecl
InstantiatedFromMember;
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
@ -1552,14 +1585,7 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
TK, DC, L, SpecializedTemplate,
Args, NumArgs, PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
InstantiatedFromMember(0, false) { }
unsigned SequenceNumber);
ClassTemplatePartialSpecializationDecl()
: ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
@ -1569,7 +1595,8 @@ class ClassTemplatePartialSpecializationDecl
public:
static ClassTemplatePartialSpecializationDecl *
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
Create(ASTContext &Context, TagKind TK,DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
const TemplateArgument *Args,
@ -1742,6 +1769,10 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl,
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
ClassTemplateDecl(EmptyShell Empty)
: RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
DeclarationName(), 0, 0) { }
CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
@ -1768,6 +1799,9 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl,
NamedDecl *Decl,
ClassTemplateDecl *PrevDecl);
/// Create an empty class template node.
static ClassTemplateDecl *Create(ASTContext &C, EmptyShell);
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
ClassTemplateSpecializationDecl *

View File

@ -37,7 +37,8 @@ class EvaluatedExprVisitor : public StmtVisitor<ImplClass> {
// other sub-expressions).
void VisitDeclRefExpr(DeclRefExpr *E) { }
void VisitOffsetOfExpr(OffsetOfExpr *E) { }
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { }
void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) { }
void VisitExpressionTraitExpr(ExpressionTraitExpr *E) { }
void VisitBlockExpr(BlockExpr *E) { }
void VisitCXXUuidofExpr(CXXUuidofExpr *E) { }
void VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { }

View File

@ -21,12 +21,12 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/UsuallyTinyPtrVector.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cctype>
#include <vector>
namespace clang {
class ASTContext;
@ -172,6 +172,7 @@ class Expr : public Stmt {
LV_IncompleteVoidType,
LV_DuplicateVectorComponents,
LV_InvalidExpression,
LV_InvalidMessageExpression,
LV_MemberFunction,
LV_SubObjCPropertySetting,
LV_ClassTemporary
@ -203,6 +204,7 @@ class Expr : public Stmt {
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting,
MLV_InvalidMessageExpression,
MLV_ClassTemporary
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
@ -218,10 +220,12 @@ class Expr : public Stmt {
CL_XValue,
CL_Function, // Functions cannot be lvalues in C.
CL_Void, // Void cannot be an lvalue in C.
CL_AddressableVoid, // Void expression whose address can be taken in C.
CL_DuplicateVectorComponents, // A vector shuffle with dupes.
CL_MemberFunction, // An expression referring to a member function
CL_SubObjCPropertySetting,
CL_ClassTemporary, // A prvalue of class type
CL_ObjCMessageRValue, // ObjC message is an rvalue
CL_PRValue // A prvalue for any other reason, of any other type
};
/// \brief The results of modification testing.
@ -482,6 +486,11 @@ class Expr : public Stmt {
/// \brief Returns true if this expression is a bound member function.
bool isBoundMemberFunction(ASTContext &Ctx) const;
/// \brief Given an expression of bound-member type, find the type
/// of the member. Returns null if this is an *overloaded* bound
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
/// \brief Result type of CanThrow().
enum CanThrowResult {
CT_Cannot,
@ -536,6 +545,9 @@ class Expr : public Stmt {
/// temporary object of the given class type.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const;
/// \brief Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
const Expr *IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
@ -618,16 +630,6 @@ class OpaqueValueExpr : public Expr {
static bool classof(const OpaqueValueExpr *) { return true; }
};
/// \brief Represents the qualifier that may precede a C++ name, e.g., the
/// "std::" in "std::sort".
struct NameQualifier {
/// \brief The nested name specifier.
NestedNameSpecifier *NNS;
/// \brief The source range covered by the nested name specifier.
SourceRange Range;
};
/// \brief Represents an explicit template argument list in C++, e.g.,
/// the "<int>" in "sort<int>".
struct ExplicitTemplateArgumentList {
@ -659,95 +661,118 @@ struct ExplicitTemplateArgumentList {
static std::size_t sizeFor(unsigned NumTemplateArgs);
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
};
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
/// enum, etc.
class DeclRefExpr : public Expr {
enum {
// Flag on DecoratedD that specifies when this declaration reference
// expression has a C++ nested-name-specifier.
HasQualifierFlag = 0x01,
// Flag on DecoratedD that specifies when this declaration reference
// expression has an explicit C++ template argument list.
HasExplicitTemplateArgumentListFlag = 0x02
};
// DecoratedD - The declaration that we are referencing, plus two bits to
// indicate whether (1) the declaration's name was explicitly qualified and
// (2) the declaration's name was followed by an explicit template
// argument list.
llvm::PointerIntPair<ValueDecl *, 2> DecoratedD;
// Loc - The location of the declaration name itself.
/// \brief A reference to a declared variable, function, enum, etc.
/// [C99 6.5.1p2]
///
/// This encodes all the information about how a declaration is referenced
/// within an expression.
///
/// There are several optional constructs attached to DeclRefExprs only when
/// they apply in order to conserve memory. These are laid out past the end of
/// the object, and flags in the DeclRefExprBitfield track whether they exist:
///
/// DeclRefExprBits.HasQualifier:
/// Specifies when this declaration reference expression has a C++
/// nested-name-specifier.
/// DeclRefExprBits.HasFoundDecl:
/// Specifies when this declaration reference expression has a record of
/// a NamedDecl (different from the referenced ValueDecl) which was found
/// during name lookup and/or overload resolution.
/// DeclRefExprBits.HasExplicitTemplateArgs:
/// Specifies when this declaration reference expression has an explicit
/// C++ template argument list.
class DeclRefExpr : public Expr {
/// \brief The declaration that we are referencing.
ValueDecl *D;
/// \brief The location of the declaration name itself.
SourceLocation Loc;
/// DNLoc - Provides source/type location info for the
/// declaration name embedded in DecoratedD.
/// \brief Provides source/type location info for the declaration name
/// embedded in D.
DeclarationNameLoc DNLoc;
/// \brief Retrieve the qualifier that preceded the declaration name, if any.
NameQualifier *getNameQualifier() {
if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
return 0;
return reinterpret_cast<NameQualifier *> (this + 1);
}
/// \brief Retrieve the qualifier that preceded the member name, if any.
const NameQualifier *getNameQualifier() const {
return const_cast<DeclRefExpr *>(this)->getNameQualifier();
/// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
NestedNameSpecifierLoc &getInternalQualifierLoc() {
assert(hasQualifier());
return *reinterpret_cast<NestedNameSpecifierLoc *>(this + 1);
}
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
/// \brief Helper to retrieve the optional NestedNameSpecifierLoc.
const NestedNameSpecifierLoc &getInternalQualifierLoc() const {
return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc();
}
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
/// \brief Test whether there is a distinct FoundDecl attached to the end of
/// this DRE.
bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; }
/// \brief Helper to retrieve the optional NamedDecl through which this
/// reference occured.
NamedDecl *&getInternalFoundDecl() {
assert(hasFoundDecl());
if (hasQualifier())
return *reinterpret_cast<NamedDecl **>(&getInternalQualifierLoc() + 1);
return *reinterpret_cast<NamedDecl **>(this + 1);
}
/// \brief Helper to retrieve the optional NamedDecl through which this
/// reference occured.
NamedDecl *getInternalFoundDecl() const {
return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
}
DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D, const DeclarationNameInfo &NameInfo,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
void computeDependence();
public:
DeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, SourceLocation l) :
Expr(DeclRefExprClass, t, VK, OK_Ordinary, false, false, false),
DecoratedD(d, 0), Loc(l) {
DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L)
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
D(D), Loc(L) {
DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasExplicitTemplateArgs = 0;
DeclRefExprBits.HasFoundDecl = 0;
computeDependence();
}
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D,
SourceLocation NameLoc,
QualType T, ExprValueKind VK,
NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
ValueDecl *D,
const DeclarationNameInfo &NameInfo,
QualType T, ExprValueKind VK,
NamedDecl *FoundD = 0,
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
bool HasQualifier,
bool HasQualifier,
bool HasFoundDecl,
bool HasExplicitTemplateArgs,
unsigned NumTemplateArgs);
ValueDecl *getDecl() { return DecoratedD.getPointer(); }
const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
void setDecl(ValueDecl *NewD) { DecoratedD.setPointer(NewD); }
ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; }
void setDecl(ValueDecl *NewD) { D = NewD; }
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), Loc, DNLoc);
@ -759,43 +784,62 @@ class DeclRefExpr : public Expr {
/// \brief Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; }
/// \brief If the name was qualified, retrieves the source range of
/// the nested-name-specifier that precedes the name. Otherwise,
/// returns an empty source range.
SourceRange getQualifierRange() const {
if (!hasQualifier())
return SourceRange();
return getNameQualifier()->Range;
}
/// \brief If the name was qualified, retrieves the nested-name-specifier
bool hasQualifier() const { return DeclRefExprBits.HasQualifier; }
/// \brief If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
if (!hasQualifier())
return 0;
return getNameQualifier()->NNS;
return getInternalQualifierLoc().getNestedNameSpecifier();
}
/// \brief If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name, with source-location information.
NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier())
return NestedNameSpecifierLoc();
return getInternalQualifierLoc();
}
/// \brief Get the NamedDecl through which this reference occured.
///
/// This Decl may be different from the ValueDecl actually referred to in the
/// presence of using declarations, etc. It always returns non-NULL, and may
/// simple return the ValueDecl when appropriate.
NamedDecl *getFoundDecl() {
return hasFoundDecl() ? getInternalFoundDecl() : D;
}
/// \brief Get the NamedDecl through which this reference occurred.
/// See non-const variant.
const NamedDecl *getFoundDecl() const {
return hasFoundDecl() ? getInternalFoundDecl() : D;
}
/// \brief Determines whether this declaration reference was followed by an
/// explict template argument list.
bool hasExplicitTemplateArgs() const {
return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag);
return DeclRefExprBits.HasExplicitTemplateArgs;
}
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(hasExplicitTemplateArgs());
if (hasFoundDecl())
return *reinterpret_cast<ExplicitTemplateArgumentList *>(
&getInternalFoundDecl() + 1);
if ((DecoratedD.getInt() & HasQualifierFlag) == 0)
return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
return *reinterpret_cast<ExplicitTemplateArgumentList *>(
getNameQualifier() + 1);
if (hasQualifier())
return *reinterpret_cast<ExplicitTemplateArgumentList *>(
&getInternalQualifierLoc() + 1);
return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
@ -809,50 +853,50 @@ class DeclRefExpr : public Expr {
if (!hasExplicitTemplateArgs()) return 0;
return &getExplicitTemplateArgs();
}
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgs())
getExplicitTemplateArgs().copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any.
SourceLocation getLAngleLoc() const {
if (!hasExplicitTemplateArgs())
return SourceLocation();
return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as part of this
/// template-id.
unsigned getNumTemplateArgs() const {
if (!hasExplicitTemplateArgs())
return 0;
return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>').
SourceLocation getRAngleLoc() const {
if (!hasExplicitTemplateArgs())
return SourceLocation();
return getExplicitTemplateArgs().RAngleLoc;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
}
@ -860,7 +904,7 @@ class DeclRefExpr : public Expr {
// Iterators
child_range children() { return child_range(); }
friend class ASTStmtReader;
friend class ASTStmtWriter;
};
@ -1133,9 +1177,12 @@ class ImaginaryLiteral : public Expr {
/// In this case, getByteLength() will return 6, but the string literal will
/// have type "char[2]".
class StringLiteral : public Expr {
friend class ASTStmtReader;
const char *StrData;
unsigned ByteLength;
bool IsWide;
bool IsPascal;
unsigned NumConcatenated;
SourceLocation TokLocs[1];
@ -1146,14 +1193,15 @@ class StringLiteral : public Expr {
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
static StringLiteral *Create(ASTContext &C, const char *StrData,
unsigned ByteLength, bool Wide, QualType Ty,
unsigned ByteLength, bool Wide, bool Pascal,
QualType Ty,
const SourceLocation *Loc, unsigned NumStrs);
/// Simple constructor for string literals made from one token.
static StringLiteral *Create(ASTContext &C, const char *StrData,
unsigned ByteLength,
bool Wide, QualType Ty, SourceLocation Loc) {
return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1);
unsigned ByteLength, bool Wide,
bool Pascal, QualType Ty, SourceLocation Loc) {
return Create(C, StrData, ByteLength, Wide, Pascal, Ty, &Loc, 1);
}
/// \brief Construct an empty string literal.
@ -1169,8 +1217,8 @@ class StringLiteral : public Expr {
void setString(ASTContext &C, llvm::StringRef Str);
bool isWide() const { return IsWide; }
void setWide(bool W) { IsWide = W; }
bool isPascal() const { return IsPascal; }
bool containsNonAsciiOrNull() const {
llvm::StringRef Str = getString();
for (unsigned i = 0, e = Str.size(); i != e; ++i)
@ -1458,7 +1506,7 @@ class OffsetOfExpr : public Expr {
/// the square brackets. For a field or identifier node, the source range
/// contains the location of the period (if there is one) and the
/// identifier.
SourceRange getRange() const { return Range; }
SourceRange getSourceRange() const { return Range; }
};
private:
@ -1556,10 +1604,11 @@ class OffsetOfExpr : public Expr {
}
};
/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
/// types and expressions.
class SizeOfAlignOfExpr : public Expr {
bool isSizeof : 1; // true if sizeof, false if alignof.
/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
/// expression operand. Used for sizeof/alignof (C99 6.5.3.4) and
/// vec_step (OpenCL 1.1 6.11.12).
class UnaryExprOrTypeTraitExpr : public Expr {
unsigned Kind : 2;
bool isType : 1; // true if operand is a type, false if an expression
union {
TypeSourceInfo *Ty;
@ -1568,36 +1617,38 @@ class SizeOfAlignOfExpr : public Expr {
SourceLocation OpLoc, RParenLoc;
public:
SizeOfAlignOfExpr(bool issizeof, TypeSourceInfo *TInfo,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
TInfo->getType()->isDependentType(),
TInfo->getType()->containsUnexpandedParameterPack()),
isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
Kind(ExprKind), isType(true), OpLoc(op), RParenLoc(rp) {
Argument.Ty = TInfo;
}
SizeOfAlignOfExpr(bool issizeof, Expr *E,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(SizeOfAlignOfExprClass, resultType, VK_RValue, OK_Ordinary,
UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
E->isTypeDependent(),
E->containsUnexpandedParameterPack()),
isSizeof(issizeof), isType(false), OpLoc(op), RParenLoc(rp) {
Kind(ExprKind), isType(false), OpLoc(op), RParenLoc(rp) {
Argument.Ex = E;
}
/// \brief Construct an empty sizeof/alignof expression.
explicit SizeOfAlignOfExpr(EmptyShell Empty)
: Expr(SizeOfAlignOfExprClass, Empty) { }
explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty)
: Expr(UnaryExprOrTypeTraitExprClass, Empty) { }
bool isSizeOf() const { return isSizeof; }
void setSizeof(bool S) { isSizeof = S; }
UnaryExprOrTypeTrait getKind() const {
return static_cast<UnaryExprOrTypeTrait>(Kind);
}
void setKind(UnaryExprOrTypeTrait K) { Kind = K; }
bool isArgumentType() const { return isType; }
QualType getArgumentType() const {
@ -1612,7 +1663,7 @@ class SizeOfAlignOfExpr : public Expr {
return static_cast<Expr*>(Argument.Ex);
}
const Expr *getArgumentExpr() const {
return const_cast<SizeOfAlignOfExpr*>(this)->getArgumentExpr();
return const_cast<UnaryExprOrTypeTraitExpr*>(this)->getArgumentExpr();
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
@ -1638,9 +1689,9 @@ class SizeOfAlignOfExpr : public Expr {
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == SizeOfAlignOfExprClass;
return T->getStmtClass() == UnaryExprOrTypeTraitExprClass;
}
static bool classof(const SizeOfAlignOfExpr *) { return true; }
static bool classof(const UnaryExprOrTypeTraitExpr *) { return true; }
// Iterators
child_range children();
@ -1862,7 +1913,13 @@ class CallExpr : public Expr {
///
class MemberExpr : public Expr {
/// Extra data stored in some member expressions.
struct MemberNameQualifier : public NameQualifier {
struct MemberNameQualifier {
/// \brief The nested-name-specifier that qualifies the name, including
/// source-location information.
NestedNameSpecifierLoc QualifierLoc;
/// \brief The DeclAccessPair through which the MemberDecl was found due to
/// name qualifiers.
DeclAccessPair FoundDecl;
};
@ -1936,7 +1993,7 @@ class MemberExpr : public Expr {
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
NestedNameSpecifierLoc QualifierLoc,
ValueDecl *memberdecl, DeclAccessPair founddecl,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *targs,
@ -1965,16 +2022,6 @@ class MemberExpr : public Expr {
/// x->Base::foo.
bool hasQualifier() const { return getQualifier() != 0; }
/// \brief If the member name was qualified, retrieves the source range of
/// the nested-name-specifier that precedes the member name. Otherwise,
/// returns an empty source range.
SourceRange getQualifierRange() const {
if (!HasQualifierOrFoundDecl)
return SourceRange();
return getMemberQualifier()->Range;
}
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
@ -1982,7 +2029,17 @@ class MemberExpr : public Expr {
if (!HasQualifierOrFoundDecl)
return 0;
return getMemberQualifier()->NNS;
return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
}
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name, with source-location
/// information.
NestedNameSpecifierLoc getQualifierLoc() const {
if (!hasQualifier())
return NestedNameSpecifierLoc();
return getMemberQualifier()->QualifierLoc;
}
/// \brief Determines whether this member expression actually had a C++
@ -2075,20 +2132,15 @@ class MemberExpr : public Expr {
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
SourceRange getSourceRange() const {
// If we have an implicit base (like a C++ implicit this),
// make sure not to return its location
SourceLocation EndLoc = (HasExplicitTemplateArgumentList)
? getRAngleLoc() : getMemberNameInfo().getEndLoc();
SourceLocation BaseLoc = getBase()->getLocStart();
if (BaseLoc.isInvalid())
return SourceRange(MemberLoc, EndLoc);
return SourceRange(BaseLoc, EndLoc);
}
SourceRange getSourceRange() const;
SourceLocation getExprLoc() const { return MemberLoc; }
/// \brief Determine whether the base of this explicit is implicit.
bool isImplicitAccess() const {
return getBase() && getBase()->isImplicitCXXThis();
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
}
@ -2234,6 +2286,12 @@ class CastExpr : public Expr {
}
CXXBaseSpecifier **path_buffer();
void setBasePathSize(unsigned basePathSize) {
CastExprBits.BasePathSize = basePathSize;
assert(CastExprBits.BasePathSize == basePathSize &&
"basePathSize doesn't fit in bits of CastExprBits.BasePathSize!");
}
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
const CastKind kind, Expr *op, unsigned BasePathSize) :
@ -2249,14 +2307,14 @@ class CastExpr : public Expr {
Op(op) {
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
CastExprBits.BasePathSize = BasePathSize;
setBasePathSize(BasePathSize);
CheckCastConsistency();
}
/// \brief Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
CastExprBits.BasePathSize = BasePathSize;
setBasePathSize(BasePathSize);
}
public:
@ -3173,9 +3231,14 @@ class InitListExpr : public Expr {
/// written in the source code.
InitListExpr *SyntacticForm;
/// If this initializer list initializes a union, specifies which
/// field within the union will be initialized.
FieldDecl *UnionFieldInit;
/// \brief Either:
/// If this initializer list initializes an array with more elements than
/// there are initializers in the list, specifies an expression to be used
/// for value initialization of the rest of the elements.
/// Or
/// If this initializer list initializes a union, specifies which
/// field within the union will be initialized.
llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
/// Whether this initializer list originally had a GNU array-range
/// designator in it. This is a temporary marker used by CodeGen.
@ -3227,17 +3290,29 @@ class InitListExpr : public Expr {
///
/// When @p Init is out of range for this initializer list, the
/// initializer list will be extended with NULL expressions to
/// accomodate the new entry.
/// accommodate the new entry.
Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr);
/// \brief If this initializer list initializes an array with more elements
/// than there are initializers in the list, specifies an expression to be
/// used for value initialization of the rest of the elements.
Expr *getArrayFiller() {
return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
}
void setArrayFiller(Expr *filler);
/// \brief If this initializes a union, specifies which field in the
/// union to initialize.
///
/// Typically, this field is the first named field within the
/// union. However, a designated initializer can specify the
/// initialization of a different field within the union.
FieldDecl *getInitializedFieldInUnion() { return UnionFieldInit; }
void setInitializedFieldInUnion(FieldDecl *FD) { UnionFieldInit = FD; }
FieldDecl *getInitializedFieldInUnion() {
return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
}
void setInitializedFieldInUnion(FieldDecl *FD) {
ArrayFillerOrUnionFieldInit = FD;
}
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
@ -3288,6 +3363,9 @@ class InitListExpr : public Expr {
const_reverse_iterator rbegin() const { return InitExprs.rbegin(); }
reverse_iterator rend() { return InitExprs.rend(); }
const_reverse_iterator rend() const { return InitExprs.rend(); }
friend class ASTStmtReader;
friend class ASTStmtWriter;
};
/// @brief Represents a C99 designated initializer expression.
@ -3492,6 +3570,12 @@ class DesignatedInitExpr : public Expr {
else
return getLBracketLoc();
}
SourceLocation getEndLocation() const {
return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
}
SourceRange getSourceRange() const {
return SourceRange(getStartLocation(), getEndLocation());
}
};
static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators,
@ -3574,6 +3658,8 @@ class DesignatedInitExpr : public Expr {
void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First,
const Designator *Last);
SourceRange getDesignatorsSourceRange() const;
SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {
@ -3667,6 +3753,118 @@ class ParenListExpr : public Expr {
};
/// \brief Represents a C1X generic selection.
///
/// A generic selection (C1X 6.5.1.1) contains an unevaluated controlling
/// expression, followed by one or more generic associations. Each generic
/// association specifies a type name and an expression, or "default" and an
/// expression (in which case it is known as a default generic association).
/// The type and value of the generic selection are identical to those of its
/// result expression, which is defined as the expression in the generic
/// association with a type name that is compatible with the type of the
/// controlling expression, or the expression in the default generic association
/// if no types are compatible. For example:
///
/// @code
/// _Generic(X, double: 1, float: 2, default: 3)
/// @endcode
///
/// The above expression evaluates to 1 if 1.0 is substituted for X, 2 if 1.0f
/// or 3 if "hello".
///
/// As an extension, generic selections are allowed in C++, where the following
/// additional semantics apply:
///
/// Any generic selection whose controlling expression is type-dependent or
/// which names a dependent type in its association list is result-dependent,
/// which means that the choice of result expression is dependent.
/// Result-dependent generic associations are both type- and value-dependent.
class GenericSelectionExpr : public Expr {
enum { CONTROLLING, END_EXPR };
TypeSourceInfo **AssocTypes;
Stmt **SubExprs;
unsigned NumAssocs, ResultIndex;
SourceLocation GenericLoc, DefaultLoc, RParenLoc;
public:
GenericSelectionExpr(ASTContext &Context,
SourceLocation GenericLoc, Expr *ControllingExpr,
TypeSourceInfo **AssocTypes, Expr **AssocExprs,
unsigned NumAssocs, SourceLocation DefaultLoc,
SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
/// This constructor is used in the result-dependent case.
GenericSelectionExpr(ASTContext &Context,
SourceLocation GenericLoc, Expr *ControllingExpr,
TypeSourceInfo **AssocTypes, Expr **AssocExprs,
unsigned NumAssocs, SourceLocation DefaultLoc,
SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
explicit GenericSelectionExpr(EmptyShell Empty)
: Expr(GenericSelectionExprClass, Empty) { }
unsigned getNumAssocs() const { return NumAssocs; }
SourceLocation getGenericLoc() const { return GenericLoc; }
SourceLocation getDefaultLoc() const { return DefaultLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
const Expr *getAssocExpr(unsigned i) const {
return cast<Expr>(SubExprs[END_EXPR+i]);
}
Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
return AssocTypes[i];
}
TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
QualType getAssocType(unsigned i) const {
if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
return TS->getType();
else
return QualType();
}
const Expr *getControllingExpr() const {
return cast<Expr>(SubExprs[CONTROLLING]);
}
Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
/// Whether this generic selection is result-dependent.
bool isResultDependent() const { return ResultIndex == -1U; }
/// The zero-based index of the result expression's generic association in
/// the generic selection's association list. Defined only if the
/// generic selection is not result-dependent.
unsigned getResultIndex() const {
assert(!isResultDependent() && "Generic selection is result-dependent");
return ResultIndex;
}
/// The generic selection's result expression. Defined only if the
/// generic selection is not result-dependent.
const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
SourceRange getSourceRange() const {
return SourceRange(GenericLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
}
static bool classof(const GenericSelectionExpr *) { return true; }
child_range children() {
return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
}
friend class ASTStmtReader;
};
//===----------------------------------------------------------------------===//
// Clang Extensions
//===----------------------------------------------------------------------===//

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_EXPRCXX_H
#include "clang/Basic/TypeTraits.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/AST/Expr.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/AST/TemplateBase.h"
@ -99,7 +100,10 @@ class CXXMemberCallExpr : public CallExpr {
/// getImplicitObjectArgument - Retrieves the implicit object
/// argument for the member call. For example, in "x.f(5)", this
/// operation would return "x".
Expr *getImplicitObjectArgument();
Expr *getImplicitObjectArgument() const;
/// Retrieves the declaration of the called method.
CXXMethodDecl *getMethodDecl() const;
/// getRecordDecl - Retrieves the CXXRecordDecl for the underlying type of
/// the implicit object argument. Note that this is may not be the same
@ -250,6 +254,8 @@ class CXXDynamicCastExpr : public CXXNamedCastExpr {
static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
bool isAlwaysNull() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXDynamicCastExprClass;
}
@ -774,7 +780,8 @@ class CXXConstructExpr : public Expr {
enum ConstructionKind {
CK_Complete,
CK_NonVirtualBase,
CK_VirtualBase
CK_VirtualBase,
CK_Delegating
};
private:
@ -1080,6 +1087,17 @@ class CXXNewExpr : public Expr {
TypeSourceInfo *getAllocatedTypeSourceInfo() const {
return AllocatedTypeInfo;
}
/// \brief True if the allocation result needs to be null-checked.
/// C++0x [expr.new]p13:
/// If the allocation function returns null, initialization shall
/// not be done, the deallocation function shall not be called,
/// and the value of the new-expression shall be null.
/// An allocation function is not allowed to return null unless it
/// has a non-throwing exception-specification. The '03 rule is
/// identical except that the definition of a non-throwing
/// exception specification is just "is it throw()?".
bool shouldNullCheckAllocation(ASTContext &Ctx) const;
FunctionDecl *getOperatorNew() const { return OperatorNew; }
void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
@ -1577,6 +1595,122 @@ class BinaryTypeTraitExpr : public Expr {
friend class ASTStmtReader;
};
/// ArrayTypeTraitExpr - An Embarcadero array type trait, as used in the
/// implementation of __array_rank and __array_extent.
/// Example:
/// __array_rank(int[10][20]) == 2
/// __array_extent(int, 1) == 20
class ArrayTypeTraitExpr : public Expr {
/// ATT - The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
unsigned ATT : 2;
/// The value of the type trait. Unspecified if dependent.
uint64_t Value;
/// The array dimension being queried, or -1 if not used
Expr *Dimension;
/// Loc - The location of the type trait keyword.
SourceLocation Loc;
/// RParen - The location of the closing paren.
SourceLocation RParen;
/// The type being queried.
TypeSourceInfo *QueriedType;
public:
ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
TypeSourceInfo *queried, uint64_t value,
Expr *dimension, SourceLocation rparen, QualType ty)
: Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
false, queried->getType()->isDependentType(),
queried->getType()->containsUnexpandedParameterPack()),
ATT(att), Value(value), Dimension(dimension),
Loc(loc), RParen(rparen), QueriedType(queried) { }
explicit ArrayTypeTraitExpr(EmptyShell Empty)
: Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
QueriedType() { }
virtual ~ArrayTypeTraitExpr() { }
virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen); }
ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
QualType getQueriedType() const { return QueriedType->getType(); }
TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
Expr *getDimensionExpression() const { return Dimension; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArrayTypeTraitExprClass;
}
static bool classof(const ArrayTypeTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
friend class ASTStmtReader;
};
/// ExpressionTraitExpr - An expression trait intrinsic
/// Example:
/// __is_lvalue_expr(std::cout) == true
/// __is_lvalue_expr(1) == false
class ExpressionTraitExpr : public Expr {
/// ET - The trait. A ExpressionTrait enum in MSVC compat unsigned.
unsigned ET : 31;
/// The value of the type trait. Unspecified if dependent.
bool Value : 1;
/// Loc - The location of the type trait keyword.
SourceLocation Loc;
/// RParen - The location of the closing paren.
SourceLocation RParen;
Expr* QueriedExpression;
public:
ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et,
Expr *queried, bool value,
SourceLocation rparen, QualType resultType)
: Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary,
false, // Not type-dependent
// Value-dependent if the argument is type-dependent.
queried->isTypeDependent(),
queried->containsUnexpandedParameterPack()),
ET(et), Value(value), Loc(loc), RParen(rparen), QueriedExpression(queried) { }
explicit ExpressionTraitExpr(EmptyShell Empty)
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
QueriedExpression() { }
SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
Expr *getQueriedExpression() const { return QueriedExpression; }
bool getValue() const { return Value; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ExpressionTraitExprClass;
}
static bool classof(const ExpressionTraitExpr *) { return true; }
// Iterators
child_range children() { return child_range(); }
friend class ASTStmtReader;
};
/// \brief A reference to an overloaded function set, either an
/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
class OverloadExpr : public Expr {
@ -1590,18 +1724,15 @@ class OverloadExpr : public Expr {
/// The common name of these declarations.
DeclarationNameInfo NameInfo;
/// The scope specifier, if any.
NestedNameSpecifier *Qualifier;
/// The source range of the scope specifier.
SourceRange QualifierRange;
/// \brief The nested-name-specifier that qualifies the name, if any.
NestedNameSpecifierLoc QualifierLoc;
protected:
/// True if the name was a template-id.
bool HasExplicitTemplateArgs;
OverloadExpr(StmtClass K, ASTContext &C,
NestedNameSpecifier *Qualifier, SourceRange QRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
@ -1610,7 +1741,7 @@ class OverloadExpr : public Expr {
OverloadExpr(StmtClass K, EmptyShell Empty)
: Expr(K, Empty), Results(0), NumResults(0),
Qualifier(0), HasExplicitTemplateArgs(false) { }
QualifierLoc(), HasExplicitTemplateArgs(false) { }
void initializeResults(ASTContext &C,
UnresolvedSetIterator Begin,
@ -1665,23 +1796,21 @@ class OverloadExpr : public Expr {
/// Gets the full name info.
const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; }
/// Gets the name looked up.
DeclarationName getName() const { return NameInfo.getName(); }
void setName(DeclarationName N) { NameInfo.setName(N); }
/// Gets the location of the name.
SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
void setNameLoc(SourceLocation Loc) { NameInfo.setLoc(Loc); }
/// Fetches the nested-name qualifier, if one was given.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
/// Fetches the range of the nested-name qualifier.
SourceRange getQualifierRange() const { return QualifierRange; }
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// Fetches the nested-name qualifier with source-location information, if
/// one was given.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// \brief Determines whether this expression had an explicit
/// template argument list, e.g. f<int>.
@ -1727,6 +1856,10 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// call.
bool RequiresADL;
/// True if namespace ::std should be considered an associated namespace
/// for the purposes of argument-dependent lookup. See C++0x [stmt.ranged]p1.
bool StdIsAssociatedNamespace;
/// True if these lookup results are overloaded. This is pretty
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
@ -1740,39 +1873,46 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedLookupExpr(ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool RequiresADL, bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, C, Qualifier, QRange, NameInfo,
UnresolvedSetIterator Begin, UnresolvedSetIterator End,
bool StdIsAssociatedNamespace)
: OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo,
TemplateArgs, Begin, End),
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
RequiresADL(RequiresADL),
StdIsAssociatedNamespace(StdIsAssociatedNamespace),
Overloaded(Overloaded), NamingClass(NamingClass)
{}
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
RequiresADL(false), Overloaded(false), NamingClass(0)
RequiresADL(false), StdIsAssociatedNamespace(false), Overloaded(false),
NamingClass(0)
{}
friend class ASTStmtReader;
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, Qualifier,
QualifierRange, NameInfo, ADL,
Overloaded, 0, Begin, End);
UnresolvedSetIterator End,
bool StdIsAssociatedNamespace = false) {
assert((ADL || !StdIsAssociatedNamespace) &&
"std considered associated namespace when not performing ADL");
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo,
ADL, Overloaded, 0, Begin, End,
StdIsAssociatedNamespace);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &NameInfo,
bool ADL,
const TemplateArgumentListInfo &Args,
@ -1786,17 +1926,18 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
void setRequiresADL(bool V) { RequiresADL = V; }
/// True if namespace ::std should be artificially added to the set of
/// associated namespaecs for argument-dependent lookup purposes.
bool isStdAssociatedNamespace() const { return StdIsAssociatedNamespace; }
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
void setOverloaded(bool V) { Overloaded = V; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
void setNamingClass(CXXRecordDecl *D) { NamingClass = D; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
@ -1845,8 +1986,10 @@ class UnresolvedLookupExpr : public OverloadExpr {
SourceRange getSourceRange() const {
SourceRange Range(getNameInfo().getSourceRange());
if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
if (getQualifierLoc())
Range.setBegin(getQualifierLoc().getBeginLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
return Range;
}
@ -2186,16 +2329,13 @@ class CXXDependentScopeMemberExpr : public Expr {
SourceLocation OperatorLoc;
/// \brief The nested-name-specifier that precedes the member name, if any.
NestedNameSpecifier *Qualifier;
/// \brief The source range covering the nested name specifier.
SourceRange QualifierRange;
NestedNameSpecifierLoc QualifierLoc;
/// \brief In a qualified member access expression such as t->Base::f, this
/// member stores the resolves of name lookup in the context of the member
/// access expression, to be used at instantiation time.
///
/// FIXME: This member, along with the Qualifier and QualifierRange, could
/// FIXME: This member, along with the QualifierLoc, could
/// be stuck into a structure that is optionally allocated at the end of
/// the CXXDependentScopeMemberExpr, to save space in the common case.
NamedDecl *FirstQualifierFoundInScope;
@ -2208,8 +2348,7 @@ class CXXDependentScopeMemberExpr : public Expr {
CXXDependentScopeMemberExpr(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
@ -2219,8 +2358,7 @@ class CXXDependentScopeMemberExpr : public Expr {
Expr *Base, QualType BaseType,
bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo);
@ -2228,8 +2366,7 @@ class CXXDependentScopeMemberExpr : public Expr {
Create(ASTContext &C,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
NamedDecl *FirstQualifierFoundInScope,
DeclarationNameInfo MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs);
@ -2241,7 +2378,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
bool isImplicitAccess() const { return Base == 0; }
bool isImplicitAccess() const;
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@ -2249,30 +2386,27 @@ class CXXDependentScopeMemberExpr : public Expr {
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
void setArrow(bool A) { IsArrow = A; }
/// \brief Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Retrieve the source range covering the nested-name-specifier
/// that qualifies the member name.
SourceRange getQualifierRange() const { return QualifierRange; }
void setQualifierRange(SourceRange R) { QualifierRange = R; }
NestedNameSpecifier *getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name, with source location information.
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// \brief Retrieve the first part of the nested-name-specifier that was
/// found in the scope of the member access expression when the member access
/// was initially parsed.
@ -2287,26 +2421,20 @@ class CXXDependentScopeMemberExpr : public Expr {
NamedDecl *getFirstQualifierFoundInScope() const {
return FirstQualifierFoundInScope;
}
void setFirstQualifierFoundInScope(NamedDecl *D) {
FirstQualifierFoundInScope = D;
}
/// \brief Retrieve the name of the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const {
return MemberNameInfo;
}
void setMemberNameInfo(const DeclarationNameInfo &N) { MemberNameInfo = N; }
/// \brief Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMember() const { return MemberNameInfo.getName(); }
void setMember(DeclarationName N) { MemberNameInfo.setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
void setMemberLoc(SourceLocation L) { MemberNameInfo.setLoc(L); }
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
@ -2376,7 +2504,7 @@ class CXXDependentScopeMemberExpr : public Expr {
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
Range.setBegin(getQualifierLoc().getBeginLoc());
else
Range.setBegin(MemberNameInfo.getBeginLoc());
@ -2438,8 +2566,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@ -2448,13 +2575,14 @@ class UnresolvedMemberExpr : public OverloadExpr {
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
HasUnresolvedUsing(false), Base(0) { }
friend class ASTStmtReader;
public:
static UnresolvedMemberExpr *
Create(ASTContext &C, bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
const DeclarationNameInfo &MemberNameInfo,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
@ -2466,7 +2594,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
bool isImplicitAccess() const { return Base == 0; }
bool isImplicitAccess() const;
/// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m.
@ -2478,24 +2606,19 @@ class UnresolvedMemberExpr : public OverloadExpr {
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
void setBaseType(QualType T) { BaseType = T; }
/// \brief Determine whether the lookup results contain an unresolved using
/// declaration.
bool hasUnresolvedUsing() const { return HasUnresolvedUsing; }
void setHasUnresolvedUsing(bool V) { HasUnresolvedUsing = V; }
/// \brief Determine whether this member expression used the '->'
/// operator; otherwise, it used the '.' operator.
bool isArrow() const { return IsArrow; }
void setArrow(bool A) { IsArrow = A; }
/// \brief Retrieve the location of the '->' or '.' operator.
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieves the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
@ -2503,17 +2626,14 @@ class UnresolvedMemberExpr : public OverloadExpr {
/// \brief Retrieve the full name info for the member that this expression
/// refers to.
const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
void setMemberNameInfo(const DeclarationNameInfo &N) { setNameInfo(N); }
/// \brief Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMemberName() const { return getName(); }
void setMemberName(DeclarationName N) { setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
void setMemberLoc(SourceLocation L) { setNameLoc(L); }
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
@ -2570,8 +2690,8 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceRange Range = getMemberNameInfo().getSourceRange();
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
else if (getQualifierLoc())
Range.setBegin(getQualifierLoc().getBeginLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());

View File

@ -337,6 +337,39 @@ class ObjCPropertyRefExpr : public Expr {
QualType getSuperReceiverType() const {
return QualType(Receiver.get<const Type*>(), 0);
}
QualType getGetterResultType() const {
QualType ResultType;
if (isExplicitProperty()) {
const ObjCPropertyDecl *PDecl = getExplicitProperty();
if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
ResultType = Getter->getResultType();
else
ResultType = getType();
} else {
const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
ResultType = Getter->getResultType(); // with reference!
}
return ResultType;
}
QualType getSetterArgType() const {
QualType ArgType;
if (isImplicitProperty()) {
const ObjCMethodDecl *Setter = getImplicitPropertySetter();
ObjCMethodDecl::param_iterator P = Setter->param_begin();
ArgType = (*P)->getType();
} else {
if (ObjCPropertyDecl *PDecl = getExplicitProperty())
if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
ObjCMethodDecl::param_iterator P = Setter->param_begin();
ArgType = (*P)->getType();
}
if (ArgType.isNull())
ArgType = getType();
}
return ArgType;
}
ObjCInterfaceDecl *getClassReceiver() const {
return Receiver.get<ObjCInterfaceDecl*>();
}
@ -741,6 +774,11 @@ class ObjCMessageExpr : public Expr {
SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
}
ObjCMethodFamily getMethodFamily() const {
if (HasMethod) return getMethodDecl()->getMethodFamily();
return getSelector().getMethodFamily();
}
/// \brief Return the number of actual arguments in this message,
/// not counting the receiver.
unsigned getNumArgs() const { return NumArgs; }
@ -808,7 +846,7 @@ class ObjCMessageExpr : public Expr {
};
/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
/// (similiar in spirit to MemberExpr).
/// (similar in spirit to MemberExpr).
class ObjCIsaExpr : public Expr {
/// Base - the expression for the base object pointer.
Stmt *Base;

View File

@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines the ExternalASTSource interface, which enables
// construction of AST nodes from some external source.x
// construction of AST nodes from some external source.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
@ -16,7 +16,6 @@
#include "clang/AST/DeclBase.h"
#include <cassert>
#include <vector>
namespace llvm {
template <class T> class SmallVectorImpl;
@ -26,9 +25,6 @@ namespace clang {
class ASTConsumer;
class CXXBaseSpecifier;
class Decl;
class DeclContext;
class DeclContextLookupResult;
class DeclarationName;
class ExternalSemaSource; // layering violation required for downcasting
class NamedDecl;
@ -74,17 +70,23 @@ class ExternalASTSource {
///
/// This method only needs to be implemented if the AST source ever
/// passes back decl sets as VisibleDeclaration objects.
virtual Decl *GetExternalDecl(uint32_t ID) = 0;
///
/// The default implementation of this method is a no-op.
virtual Decl *GetExternalDecl(uint32_t ID);
/// \brief Resolve a selector ID into a selector.
///
/// This operation only needs to be implemented if the AST source
/// returns non-zero for GetNumKnownSelectors().
virtual Selector GetExternalSelector(uint32_t ID) = 0;
///
/// The default implementation of this method is a no-op.
virtual Selector GetExternalSelector(uint32_t ID);
/// \brief Returns the number of selectors known to the external AST
/// source.
virtual uint32_t GetNumExternalSelectors() = 0;
///
/// The default implementation of this method is a no-op.
virtual uint32_t GetNumExternalSelectors();
/// \brief Resolve the offset of a statement in the decl stream into
/// a statement.
@ -92,21 +94,26 @@ class ExternalASTSource {
/// This operation is meant to be used via a LazyOffsetPtr. It only
/// needs to be implemented if the AST source uses methods like
/// FunctionDecl::setLazyBody when building decls.
virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
///
/// The default implementation of this method is a no-op.
virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
/// \brief Resolve the offset of a set of C++ base specifiers in the decl
/// stream into an array of specifiers.
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) = 0;
///
/// The default implementation of this method is a no-op.
virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
/// \brief Finds all declarations with the given name in the
/// given context.
///
/// Generally the final step of this method is either to call
/// SetExternalVisibleDeclsForName or to recursively call lookup on
/// the DeclContext after calling SetExternalVisibleDecls.
///
/// The default implementation of this method is a no-op.
virtual DeclContextLookupResult
FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) = 0;
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
/// \brief Deserialize all the visible declarations from external storage.
///
@ -114,7 +121,9 @@ class ExternalASTSource {
/// may not have a complete name lookup table. This function deserializes
/// the rest of visible declarations from the external storage and completes
/// the name lookup table of the DeclContext.
virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
///
/// The default implementation of this method is a no-op.
virtual void MaterializeVisibleDecls(const DeclContext *DC);
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
@ -124,9 +133,11 @@ class ExternalASTSource {
/// are returned.
///
/// \return true if an error occurred
///
/// The default implementation of this method is a no-op.
virtual bool FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
llvm::SmallVectorImpl<Decl*> &Result) = 0;
llvm::SmallVectorImpl<Decl*> &Result);
/// \brief Finds all declarations lexically contained within the given
/// DeclContext.
@ -154,7 +165,7 @@ class ExternalASTSource {
/// set on the ObjCInterfaceDecl via the function
/// \c ObjCInterfaceDecl::setExternallyCompleted().
virtual void CompleteType(ObjCInterfaceDecl *Class) { }
/// \brief Notify ExternalASTSource that we started deserialization of
/// a decl or type so until FinishedDeserializing is called there may be
/// decls that are initializing. Must be paired with FinishedDeserializing.
@ -179,6 +190,28 @@ class ExternalASTSource {
///
/// The default implementation of this method is a no-op.
virtual void PrintStats();
//===--------------------------------------------------------------------===//
// Queries for performance analysis.
//===--------------------------------------------------------------------===//
struct MemoryBufferSizes {
size_t malloc_bytes;
size_t mmap_bytes;
MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
};
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
MemoryBufferSizes getMemoryBufferSizes() const {
MemoryBufferSizes sizes(0, 0);
getMemoryBufferSizes(sizes);
return sizes;
}
virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const = 0;
protected:
static DeclContextLookupResult
@ -270,7 +303,7 @@ typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
&ExternalASTSource::GetExternalCXXBaseSpecifiers>
LazyCXXBaseSpecifiersPtr;
} // end namespace clang
#endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H

View File

@ -312,6 +312,146 @@ class NestedNameSpecifierLoc {
}
};
/// \brief Class that aids in the construction of nested-name-specifiers along
/// with source-location information for all of the components of the
/// nested-name-specifier.
class NestedNameSpecifierLocBuilder {
/// \brief The current representation of the nested-name-specifier we're
/// building.
NestedNameSpecifier *Representation;
/// \brief Buffer used to store source-location information for the
/// nested-name-specifier.
///
/// Note that we explicitly manage the buffer (rather than using a
/// SmallVector) because \c Declarator expects it to be possible to memcpy()
/// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
char *Buffer;
/// \brief The size of the buffer used to store source-location information
/// for the nested-name-specifier.
unsigned BufferSize;
/// \brief The capacity of the buffer used to store source-location
/// information for the nested-name-specifier.
unsigned BufferCapacity;
public:
NestedNameSpecifierLocBuilder();
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
NestedNameSpecifierLocBuilder &
operator=(const NestedNameSpecifierLocBuilder &Other);
~NestedNameSpecifierLocBuilder();
/// \brief Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getRepresentation() const { return Representation; }
/// \brief Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'type::'.
///
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
/// \param TemplateKWLoc The location of the 'template' keyword, if present.
///
/// \param TL The TypeLoc that describes the type preceding the '::'.
///
/// \param ColonColonLoc The location of the trailing '::'.
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
SourceLocation ColonColonLoc);
/// \brief Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'identifier::'.
///
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
/// \param Identifier The identifier.
///
/// \param IdentifierLoc The location of the identifier.
///
/// \param ColonColonLoc The location of the trailing '::'.
void Extend(ASTContext &Context, IdentifierInfo *Identifier,
SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
/// \brief Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace::'.
///
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
/// \param Namespace The namespace.
///
/// \param NamespaceLoc The location of the namespace name.
///
/// \param ColonColonLoc The location of the trailing '::'.
void Extend(ASTContext &Context, NamespaceDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
/// \brief Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace-alias::'.
///
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
/// \param Alias The namespace alias.
///
/// \param AliasLoc The location of the namespace alias
/// name.
///
/// \param ColonColonLoc The location of the trailing '::'.
void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
SourceLocation AliasLoc, SourceLocation ColonColonLoc);
/// \brief Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
/// \brief Make a new nested-name-specifier from incomplete source-location
/// information.
///
/// This routine should be used very, very rarely, in cases where we
/// need to synthesize a nested-name-specifier. Most code should instead use
/// \c Adopt() with a proper \c NestedNameSpecifierLoc.
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
SourceRange R);
/// \brief Adopt an existing nested-name-specifier (with source-range
/// information).
void Adopt(NestedNameSpecifierLoc Other);
/// \brief Retrieve the source range covered by this nested-name-specifier.
SourceRange getSourceRange() const {
return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
}
/// \brief Retrieve a nested-name-specifier with location information,
/// copied into the given AST context.
///
/// \param Context The context into which this nested-name-specifier will be
/// copied.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
/// \brief Clear out this builder, and prepare it to build another
/// nested-name-specifier with source-location information.
void Clear() {
Representation = 0;
BufferSize = 0;
}
/// \brief Retrieve the underlying buffer.
///
/// \returns A pair containing a pointer to the buffer of source-location
/// data and the size of the source-location data that resides in that
/// buffer.
std::pair<char *, unsigned> getBuffer() const {
return std::make_pair(Buffer, BufferSize);
}
};
/// Insertion operator for diagnostics. This allows sending NestedNameSpecifiers
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,

View File

@ -38,7 +38,8 @@ struct PrintingPolicy {
/// \brief Create a default printing policy for C.
PrintingPolicy(const LangOptions &LO)
: Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
SuppressTag(false), SuppressScope(false),
SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
SuppressInitializers(false),
Dump(false), ConstantArraySizeAsWritten(false),
AnonymousTagLocations(true) { }
@ -64,6 +65,16 @@ struct PrintingPolicy {
/// "const int" type specifier and instead only print the "*y".
bool SuppressSpecifiers : 1;
/// \brief Whether type printing should skip printing the tag keyword.
///
/// This is used when printing the inner type of elaborated types,
/// (as the tag keyword is part of the elaborated type):
///
/// \code
/// struct Geometry::Point;
/// \endcode
bool SuppressTagKeyword : 1;
/// \brief Whether type printing should skip printing the actual tag type.
///
/// This is used when the caller needs to print a tag definition in front
@ -77,6 +88,19 @@ struct PrintingPolicy {
/// \brief Suppresses printing of scope specifiers.
bool SuppressScope : 1;
/// \brief Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
/// statement. For example, given:
///
/// \code
/// for (auto x : coll)
/// \endcode
///
/// SuppressInitializers will be true when printing "auto x", so that the
/// internal initializer constructed for x will not be printed.
bool SuppressInitializers : 1;
/// \brief True when we are "dumping" rather than "pretty-printing",
/// where dumping involves printing the internal details of the AST
/// and pretty-printing involves printing something similar to

View File

@ -600,12 +600,15 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
// FIXME: how can TSI ever be NULL?
if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
else
return true;
else
return getDerived().TraverseType(Arg.getAsType());
}
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
if (ArgLoc.getTemplateQualifierLoc())
TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
ArgLoc.getTemplateQualifierLoc()));
return getDerived().TraverseTemplateName(
Arg.getAsTemplateOrTemplatePattern());
@ -933,7 +936,11 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
const FunctionProtoType *T = TL.getTypePtr();
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
TRY_TO(TraverseDecl(TL.getArg(I)));
if (TL.getArg(I)) {
TRY_TO(TraverseDecl(TL.getArg(I)));
} else if (I < T->getNumArgs()) {
TRY_TO(TraverseType(T->getArgType(I)));
}
}
for (FunctionProtoType::exception_iterator E = T->exception_begin(),
@ -987,21 +994,22 @@ DEF_TRAVERSE_TYPELOC(AttributedType, {
TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
})
// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getTypePtr()->getQualifier()) {
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
}
TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
})
// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(DependentNameType, {
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
}
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}
@ -1041,7 +1049,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
for (DeclContext::decl_iterator Child = DC->decls_begin(),
ChildEnd = DC->decls_end();
Child != ChildEnd; ++Child) {
TRY_TO(TraverseDecl(*Child));
// BlockDecls are traversed through BlockExprs.
if (!isa<BlockDecl>(*Child))
TRY_TO(TraverseDecl(*Child));
}
return true;
@ -1060,10 +1070,12 @@ bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \
DEF_TRAVERSE_DECL(AccessSpecDecl, { })
DEF_TRAVERSE_DECL(BlockDecl, {
// We don't traverse nodes in param_begin()/param_end(), as they
// appear in decls_begin()/decls_end() and thus are handled by the
// DEF_TRAVERSE_DECL macro already.
TRY_TO(TraverseTypeLoc(D->getSignatureAsWritten()->getTypeLoc()));
TRY_TO(TraverseStmt(D->getBody()));
// This return statement makes sure the traversal of nodes in
// decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
// is skipped - don't remove it.
return true;
})
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
@ -1164,9 +1176,17 @@ DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
})
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
// We don't traverse nodes in param_begin()/param_end(), as they
// appear in decls_begin()/decls_end() and thus are handled.
TRY_TO(TraverseStmt(D->getBody()));
if (D->getResultTypeSourceInfo()) {
TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
}
for (ObjCMethodDecl::param_iterator
I = D->param_begin(), E = D->param_end(); I != E; ++I) {
TRY_TO(TraverseDecl(*I));
}
if (D->isThisDeclarationADefinition()) {
TRY_TO(TraverseStmt(D->getBody()));
}
return true;
})
DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
@ -1341,6 +1361,13 @@ DEF_TRAVERSE_DECL(TypedefDecl, {
// source.
})
DEF_TRAVERSE_DECL(TypeAliasDecl, {
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type alias, not something that was written in the
// source.
})
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; };
@ -1354,7 +1381,7 @@ DEF_TRAVERSE_DECL(EnumDecl, {
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
// The enumerators are already traversed by
// decls_begin()/decls_end().
})
@ -1367,7 +1394,7 @@ bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
// We shouldn't traverse D->getTypeForDecl(); it's a result of
// declaring the type, not something that was written in the source.
TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
return true;
}
@ -1464,9 +1491,11 @@ DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
if (D->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
else
TRY_TO(TraverseType(D->getType()));
return true;
}
@ -1492,7 +1521,7 @@ DEF_TRAVERSE_DECL(ObjCIvarDecl, {
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TRY_TO(TraverseNestedNameSpecifier(D->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
// If we're an explicit template specialization, iterate over the
// template args that were explicitly specified. If we were doing
@ -1678,13 +1707,14 @@ DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
DEF_TRAVERSE_STMT(ReturnStmt, { })
DEF_TRAVERSE_STMT(SwitchStmt, { })
DEF_TRAVERSE_STMT(WhileStmt, { })
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
@ -1692,7 +1722,7 @@ DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
})
DEF_TRAVERSE_STMT(DeclRefExpr, {
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
})
@ -1707,10 +1737,9 @@ DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
})
DEF_TRAVERSE_STMT(MemberExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseTemplateArgumentLocsHelper(
S->getTemplateArgs(), S->getNumTemplateArgs()));
// FIXME: Should we be recursing on the qualifier?
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
})
DEF_TRAVERSE_STMT(ImplicitCastExpr, {
@ -1759,6 +1788,22 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
return true;
}
// GenericSelectionExpr is a special case because the types and expressions
// are interleaved. We also need to watch out for null types (default
// generic associations).
template<typename Derived>
bool RecursiveASTVisitor<Derived>::
TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
TRY_TO(WalkUpFromGenericSelectionExpr(S));
TRY_TO(TraverseStmt(S->getControllingExpr()));
for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
TRY_TO(TraverseStmt(S->getAssocExpr(i)));
}
return true;
}
DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
// This is called for code like 'return T()' where T is a built-in
// (i.e. non-class) type.
@ -1778,7 +1823,7 @@ DEF_TRAVERSE_STMT(OffsetOfExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(SizeOfAlignOfExpr, {
DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
// The child-iterator will pick up the arg if it's an expression,
// but not if it's a type.
if (S->isArgumentType())
@ -1808,6 +1853,14 @@ DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
TRY_TO(TraverseStmt(S->getQueriedExpression()));
})
DEF_TRAVERSE_STMT(VAArgExpr, {
// The child-iterator will pick up the expression argument.
TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
@ -1834,7 +1887,10 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
DEF_TRAVERSE_STMT(AddrLabelExpr, { })
DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
DEF_TRAVERSE_STMT(BlockExpr, { })
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
})
DEF_TRAVERSE_STMT(ChooseExpr, { })
DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
@ -1869,7 +1925,7 @@ DEF_TRAVERSE_STMT(PredefinedExpr, { })
DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
DEF_TRAVERSE_STMT(StmtExpr, { })
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
S->getNumTemplateArgs()));
@ -1877,13 +1933,17 @@ DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
})
DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
TRY_TO(TraverseNestedNameSpecifier(S->getQualifier()));
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (S->hasExplicitTemplateArgs()) {
TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
S->getNumTemplateArgs()));
}
})
DEF_TRAVERSE_STMT(SEHTryStmt, {})
DEF_TRAVERSE_STMT(SEHExceptStmt, {})
DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
@ -1921,7 +1981,7 @@ DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
// Candidates:
//
// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
// http://clang.llvm.org/doxygen/classclang_1_1SizeOfAlignOfExpr.html
// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
// Every class that has getQualifier.

View File

@ -158,6 +158,16 @@ class Stmt {
};
enum { NumExprBits = 15 };
class DeclRefExprBitfields {
friend class DeclRefExpr;
friend class ASTStmtReader; // deserialization
unsigned : NumExprBits;
unsigned HasQualifier : 1;
unsigned HasExplicitTemplateArgs : 1;
unsigned HasFoundDecl : 1;
};
class CastExprBitfields {
friend class CastExpr;
unsigned : NumExprBits;
@ -180,6 +190,7 @@ class Stmt {
StmtBitfields StmtBits;
CompoundStmtBitfields CompoundStmtBits;
ExprBitfields ExprBits;
DeclRefExprBitfields DeclRefExprBits;
CastExprBitfields CastExprBits;
CallExprBitfields CallExprBits;
};
@ -383,14 +394,15 @@ class DeclStmt : public Stmt {
class NullStmt : public Stmt {
SourceLocation SemiLoc;
/// \brief Whether the null statement was preceded by an empty macro, e.g:
/// \brief If the null statement was preceded by an empty macro this is
/// its instantiation source location, e.g:
/// @code
/// #define CALL(x)
/// CALL(0);
/// @endcode
bool LeadingEmptyMacro;
SourceLocation LeadingEmptyMacro;
public:
NullStmt(SourceLocation L, bool LeadingEmptyMacro = false)
NullStmt(SourceLocation L, SourceLocation LeadingEmptyMacro =SourceLocation())
: Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {}
/// \brief Build an empty null statement.
@ -399,7 +411,8 @@ class NullStmt : public Stmt {
SourceLocation getSemiLoc() const { return SemiLoc; }
void setSemiLoc(SourceLocation L) { SemiLoc = L; }
bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro; }
bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro.isValid(); }
SourceLocation getLeadingEmptyMacroLoc() const { return LeadingEmptyMacro; }
SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
@ -424,6 +437,8 @@ class CompoundStmt : public Stmt {
SourceLocation LB, SourceLocation RB)
: Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) {
CompoundStmtBits.NumStmts = NumStmts;
assert(CompoundStmtBits.NumStmts == NumStmts &&
"NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
if (NumStmts == 0) {
Body = 0;
@ -516,6 +531,9 @@ class SwitchCase : public Stmt {
void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
Stmt *getSubStmt();
const Stmt *getSubStmt() const {
return const_cast<SwitchCase*>(this)->getSubStmt();
}
SourceRange getSourceRange() const { return SourceRange(); }
@ -527,7 +545,7 @@ class SwitchCase : public Stmt {
};
class CaseStmt : public SwitchCase {
enum { SUBSTMT, LHS, RHS, END_EXPR };
enum { LHS, RHS, SUBSTMT, END_EXPR };
Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
// GNU "case 1 ... 4" extension
SourceLocation CaseLoc;
@ -688,6 +706,12 @@ class IfStmt : public Stmt {
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
/// If this IfStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
}
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
const Stmt *getThen() const { return SubExprs[THEN]; }
@ -754,6 +778,12 @@ class SwitchStmt : public Stmt {
/// \endcode
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
/// If this SwitchStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
}
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
const Stmt *getBody() const { return SubExprs[BODY]; }
@ -835,6 +865,12 @@ class WhileStmt : public Stmt {
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
/// If this WhileStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
}
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
@ -939,6 +975,12 @@ class ForStmt : public Stmt {
VarDecl *getConditionVariable() const;
void setConditionVariable(ASTContext &C, VarDecl *V);
/// If this ForStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
}
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
@ -1406,6 +1448,122 @@ class AsmStmt : public Stmt {
}
};
class SEHExceptStmt : public Stmt {
SourceLocation Loc;
Stmt *Children[2];
enum { FILTER_EXPR, BLOCK };
SEHExceptStmt(SourceLocation Loc,
Expr *FilterExpr,
Stmt *Block);
public:
static SEHExceptStmt* Create(ASTContext &C,
SourceLocation ExceptLoc,
Expr *FilterExpr,
Stmt *Block);
SourceRange getSourceRange() const {
return SourceRange(getExceptLoc(), getEndLoc());
}
SourceLocation getExceptLoc() const { return Loc; }
SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
Expr *getFilterExpr() const { return reinterpret_cast<Expr*>(Children[FILTER_EXPR]); }
CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Children[BLOCK]); }
child_range children() {
return child_range(Children,Children+2);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHExceptStmtClass;
}
static bool classof(SEHExceptStmt *) { return true; }
};
class SEHFinallyStmt : public Stmt {
SourceLocation Loc;
Stmt *Block;
SEHFinallyStmt(SourceLocation Loc,
Stmt *Block);
public:
static SEHFinallyStmt* Create(ASTContext &C,
SourceLocation FinallyLoc,
Stmt *Block);
SourceRange getSourceRange() const {
return SourceRange(getFinallyLoc(), getEndLoc());
}
SourceLocation getFinallyLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Block->getLocEnd(); }
CompoundStmt *getBlock() const { return llvm::cast<CompoundStmt>(Block); }
child_range children() {
return child_range(&Block,&Block+1);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHFinallyStmtClass;
}
static bool classof(SEHFinallyStmt *) { return true; }
};
class SEHTryStmt : public Stmt {
bool IsCXXTry;
SourceLocation TryLoc;
Stmt *Children[2];
enum { TRY = 0, HANDLER = 1 };
SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
SourceLocation TryLoc,
Stmt *TryBlock,
Stmt *Handler);
public:
static SEHTryStmt* Create(ASTContext &C,
bool isCXXTry,
SourceLocation TryLoc,
Stmt *TryBlock,
Stmt *Handler);
SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
bool getIsCXXTry() const { return IsCXXTry; }
CompoundStmt* getTryBlock() const { return llvm::cast<CompoundStmt>(Children[TRY]); }
Stmt *getHandler() const { return Children[HANDLER]; }
/// Returns 0 if not defined
SEHExceptStmt *getExceptHandler() const;
SEHFinallyStmt *getFinallyHandler() const;
child_range children() {
return child_range(Children,Children+2);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHTryStmtClass;
}
static bool classof(SEHTryStmt *) { return true; }
};
} // end namespace clang
#endif

View File

@ -119,6 +119,88 @@ class CXXTryStmt : public Stmt {
friend class ASTStmtReader;
};
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
/// statement, represented as 'for (range-declarator : range-expression)'.
///
/// This is stored in a partially-desugared form to allow full semantic
/// analysis of the constituent components. The original syntactic components
/// can be extracted using getLoopVariable and getRangeInit.
class CXXForRangeStmt : public Stmt {
enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
// SubExprs[RANGE] is an expression or declstmt.
// SubExprs[COND] and SubExprs[INC] are expressions.
Stmt *SubExprs[END];
SourceLocation ForLoc;
SourceLocation ColonLoc;
SourceLocation RParenLoc;
public:
CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
SourceLocation FL, SourceLocation CL, SourceLocation RPL);
CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
VarDecl *getLoopVariable();
Expr *getRangeInit();
const VarDecl *getLoopVariable() const;
const Expr *getRangeInit() const;
DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
DeclStmt *getBeginEndStmt() { return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); }
Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
Stmt *getBody() { return SubExprs[BODY]; }
const DeclStmt *getRangeStmt() const {
return cast<DeclStmt>(SubExprs[RANGE]);
}
const DeclStmt *getBeginEndStmt() const {
return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
}
const Expr *getCond() const {
return cast_or_null<Expr>(SubExprs[COND]);
}
const Expr *getInc() const {
return cast_or_null<Expr>(SubExprs[INC]);
}
const DeclStmt *getLoopVarStmt() const {
return cast<DeclStmt>(SubExprs[LOOPVAR]);
}
const Stmt *getBody() const { return SubExprs[BODY]; }
void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
void setBody(Stmt *S) { SubExprs[BODY] = S; }
SourceLocation getForLoc() const { return ForLoc; }
void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
SourceLocation getColonLoc() const { return ColonLoc; }
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
SourceRange getSourceRange() const {
return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXForRangeStmtClass;
}
static bool classof(const CXXForRangeStmt *) { return true; }
// Iterators
child_range children() {
return child_range(&SubExprs[0], &SubExprs[END]);
}
};
} // end namespace clang

View File

@ -18,6 +18,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
#include <utility>
namespace clang {

View File

@ -362,7 +362,10 @@ struct TemplateArgumentLocInfo {
Expr *Expression;
TypeSourceInfo *Declarator;
struct {
unsigned QualifierRange[2];
// FIXME: We'd like to just use the qualifier in the TemplateName,
// but template arguments get canonicalized too quickly.
NestedNameSpecifier *Qualifier;
void *QualifierLocData;
unsigned TemplateNameLoc;
unsigned EllipsisLoc;
} Template;
@ -375,12 +378,12 @@ struct TemplateArgumentLocInfo {
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
TemplateArgumentLocInfo(SourceRange QualifierRange,
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc)
{
Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
Template.QualifierLocData = QualifierLoc.getOpaqueData();
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
}
@ -393,10 +396,9 @@ struct TemplateArgumentLocInfo {
return Expression;
}
SourceRange getTemplateQualifierRange() const {
return SourceRange(
SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
return NestedNameSpecifierLoc(Template.Qualifier,
Template.QualifierLocData);
}
SourceLocation getTemplateNameLoc() const {
@ -433,11 +435,10 @@ class TemplateArgumentLoc {
}
TemplateArgumentLoc(const TemplateArgument &Argument,
SourceRange QualifierRange,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation())
: Argument(Argument),
LocInfo(QualifierRange, TemplateNameLoc, EllipsisLoc) {
: Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
@ -477,10 +478,10 @@ class TemplateArgumentLoc {
return LocInfo.getAsExpr();
}
SourceRange getTemplateQualifierRange() const {
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
return LocInfo.getTemplateQualifierRange();
return LocInfo.getTemplateQualifierLoc();
}
SourceLocation getTemplateNameLoc() const {

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPE_H
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
#include "clang/Basic/PartialDiagnostic.h"
@ -72,7 +73,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class TypedefDecl;
class TypedefNameDecl;
class TemplateDecl;
class TemplateTypeParmDecl;
class NonTypeTemplateParmDecl;
@ -212,6 +213,11 @@ class Qualifiers {
assert(type);
setObjCGCAttr(type);
}
Qualifiers withoutObjCGCAttr() const {
Qualifiers qs = *this;
qs.removeObjCGCAttr();
return qs;
}
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
@ -293,8 +299,10 @@ class Qualifiers {
(((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask));
}
bool isSupersetOf(Qualifiers Other) const;
/// \brief Determine whether this set of qualifiers is a strict superset of
/// another set of qualifiers, not considering qualifier compatibility.
bool isStrictSupersetOf(Qualifiers Other) const;
bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
@ -354,7 +362,9 @@ enum CallingConv {
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86Pascal // __attribute__((pascal))
CC_X86Pascal, // __attribute__((pascal))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp")))
};
typedef std::pair<const Type*, Qualifiers> SplitQualType;
@ -598,8 +608,14 @@ class QualType {
/// ASTContext::getUnqualifiedArrayType.
inline SplitQualType getSplitUnqualifiedType() const;
/// \brief Determine whether this type is more qualified than the other
/// given type, requiring exact equality for non-CVR qualifiers.
bool isMoreQualifiedThan(QualType Other) const;
/// \brief Determine whether this type is at least as qualified as the other
/// given type, requiring exact equality for non-CVR qualifiers.
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
/// \brief Determine the type of a (typically non-lvalue) expression with the
@ -1163,6 +1179,20 @@ class Type : public ExtQualsTypeCommonBase {
/// (C++0x [basic.types]p10)
bool isLiteralType() const;
/// isTrivialType - Return true if this is a trivial type
/// (C++0x [basic.types]p9)
bool isTrivialType() const;
/// \brief Test if this type is a standard-layout type.
/// (C++0x [basic.type]p9)
bool isStandardLayoutType() const;
/// isCXX11PODType() - Return true if this is a POD type according to the
/// more relaxed rules of the C++11 standard, regardless of the current
/// compilation's language.
/// (C++0x [basic.types]p9)
bool isCXX11PODType() const;
/// Helper methods to distinguish type categories. All type predicates
/// operate on the canonical type, ignoring typedefs and qualifiers.
@ -1178,6 +1208,9 @@ class Type : public ExtQualsTypeCommonBase {
/// BuiltinTypes.
bool isPlaceholderType() const;
/// isSpecificPlaceholderType - Test for a specific placeholder type.
bool isSpecificPlaceholderType(unsigned K) const;
/// isIntegerType() does *not* include complex integers (a GCC extension).
/// isComplexIntegerType() can be used to test for complex integers.
bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
@ -1207,6 +1240,8 @@ class Type : public ExtQualsTypeCommonBase {
bool isDerivedType() const; // C99 6.2.5p20
bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
bool isAggregateType() const;
bool isFundamentalType() const;
bool isCompoundType() const;
// Type Predicates: Check to see if this type is structurally the specified
// type, ignoring typedefs and qualifiers.
@ -1321,6 +1356,7 @@ class Type : public ExtQualsTypeCommonBase {
// for object declared using an interface.
const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
@ -1475,25 +1511,52 @@ class BuiltinType : public Type {
NullPtr, // This is the type of C++0x 'nullptr'.
/// The primitive Objective C 'id' type. The user-visible 'id'
/// type is a typedef of an ObjCObjectPointerType to an
/// ObjCObjectType with this as its base. In fact, this only ever
/// shows up in an AST as the base type of an ObjCObjectType.
ObjCId,
/// The primitive Objective C 'Class' type. The user-visible
/// 'Class' type is a typedef of an ObjCObjectPointerType to an
/// ObjCObjectType with this as its base. In fact, this only ever
/// shows up in an AST as the base type of an ObjCObjectType.
ObjCClass,
/// The primitive Objective C 'SEL' type. The user-visible 'SEL'
/// type is a typedef of a PointerType to this.
ObjCSel,
/// This represents the type of an expression whose type is
/// totally unknown, e.g. 'T::foo'. It is permitted for this to
/// appear in situations where the structure of the type is
/// theoretically deducible.
Dependent,
Overload, // This represents the type of an overloaded function declaration.
/// The type of an unresolved overload set. A placeholder type.
/// Expressions with this type have one of the following basic
/// forms, with parentheses generally permitted:
/// foo # possibly qualified, not if an implicit access
/// foo # possibly qualified, not if an implicit access
/// &foo # possibly qualified, not if an implicit access
/// x->foo # only if might be a static member function
/// &x->foo # only if might be a static member function
/// &Class::foo # when a pointer-to-member; sub-expr also has this type
/// OverloadExpr::find can be used to analyze the expression.
Overload,
/// The primitive Objective C 'id' type. The type pointed to by the
/// user-visible 'id' type. Only ever shows up in an AST as the base
/// type of an ObjCObjectType.
ObjCId,
/// The type of a bound C++ non-static member function.
/// A placeholder type. Expressions with this type have one of the
/// following basic forms:
/// foo # if an implicit access
/// x->foo # if only contains non-static members
BoundMember,
/// The primitive Objective C 'Class' type. The type pointed to by the
/// user-visible 'Class' type. Only ever shows up in an AST as the
/// base type of an ObjCObjectType.
ObjCClass,
ObjCSel // This represents the ObjC 'SEL' type.
/// __builtin_any_type. A placeholder type. Useful for clients
/// like debuggers that don't know what type to give something.
/// Only a small number of operations are valid on expressions of
/// unknown type, most notably explicit casts.
UnknownAny
};
public:
@ -1526,11 +1589,11 @@ class BuiltinType : public Type {
return getKind() >= Float && getKind() <= LongDouble;
}
/// Determines whether this type is a "forbidden" placeholder type,
/// i.e. a type which cannot appear in arbitrary positions in a
/// fully-formed expression.
/// Determines whether this type is a placeholder type, i.e. a type
/// which cannot appear in arbitrary positions in a fully-formed
/// expression.
bool isPlaceholderType() const {
return getKind() == Overload;
return getKind() >= Overload;
}
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
@ -1991,7 +2054,7 @@ class VariableArrayType : public ArrayType {
friend class StmtIteratorBase;
void Profile(llvm::FoldingSetNodeID &ID) {
assert(0 && "Cannnot unique VariableArrayTypes.");
assert(0 && "Cannot unique VariableArrayTypes.");
}
};
@ -2257,12 +2320,13 @@ class FunctionType : public Type {
// you'll need to adjust both the Bits field below and
// Type::FunctionTypeBitfields.
// | CC |noreturn|regparm
// |0 .. 2| 3 |4 .. 6
// | CC |noreturn|hasregparm|regparm
// |0 .. 2| 3 | 4 |5 .. 7
enum { CallConvMask = 0x7 };
enum { NoReturnMask = 0x8 };
enum { HasRegParmMask = 0x10 };
enum { RegParmMask = ~(CallConvMask | NoReturnMask),
RegParmOffset = 4 };
RegParmOffset = 5 };
unsigned char Bits;
@ -2273,9 +2337,10 @@ class FunctionType : public Type {
public:
// Constructor with no defaults. Use this when you know that you
// have all the elements (when reading an AST file for example).
ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) {
ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc) {
Bits = ((unsigned) cc) |
(noReturn ? NoReturnMask : 0) |
(hasRegParm ? HasRegParmMask : 0) |
(regParm << RegParmOffset);
}
@ -2284,6 +2349,7 @@ class FunctionType : public Type {
ExtInfo() : Bits(0) {}
bool getNoReturn() const { return Bits & NoReturnMask; }
bool getHasRegParm() const { return Bits & HasRegParmMask; }
unsigned getRegParm() const { return Bits >> RegParmOffset; }
CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
@ -2305,7 +2371,7 @@ class FunctionType : public Type {
}
ExtInfo withRegParm(unsigned RegParm) const {
return ExtInfo((Bits & ~RegParmMask) | (RegParm << RegParmOffset));
return ExtInfo(HasRegParmMask | (Bits & ~RegParmMask) | (RegParm << RegParmOffset));
}
ExtInfo withCallingConv(CallingConv cc) const {
@ -2341,7 +2407,8 @@ class FunctionType : public Type {
public:
QualType getResultType() const { return ResultType; }
bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
CallingConv getCallConv() const { return getExtInfo().getCC(); }
@ -2403,17 +2470,17 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
/// ExtProtoInfo - Extra information about a function prototype.
struct ExtProtoInfo {
ExtProtoInfo() :
Variadic(false), HasExceptionSpec(false), HasAnyExceptionSpec(false),
TypeQuals(0), RefQualifier(RQ_None), NumExceptions(0), Exceptions(0) {}
Variadic(false), ExceptionSpecType(EST_None), TypeQuals(0),
RefQualifier(RQ_None), NumExceptions(0), Exceptions(0), NoexceptExpr(0) {}
FunctionType::ExtInfo ExtInfo;
bool Variadic;
bool HasExceptionSpec;
bool HasAnyExceptionSpec;
ExceptionSpecificationType ExceptionSpecType;
unsigned char TypeQuals;
RefQualifierKind RefQualifier;
unsigned NumExceptions;
const QualType *Exceptions;
Expr *NoexceptExpr;
};
private:
@ -2435,13 +2502,10 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
unsigned NumArgs : 20;
/// NumExceptions - The number of types in the exception spec, if any.
unsigned NumExceptions : 10;
unsigned NumExceptions : 9;
/// HasExceptionSpec - Whether this function has an exception spec at all.
unsigned HasExceptionSpec : 1;
/// HasAnyExceptionSpec - Whether this function has a throw(...) spec.
unsigned HasAnyExceptionSpec : 1;
/// ExceptionSpecType - The type of exception specification this function has.
unsigned ExceptionSpecType : 3;
/// ArgInfo - There is an variable size array after the class in memory that
/// holds the argument types.
@ -2449,6 +2513,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
/// Exceptions - There is another variable size array after ArgInfo that
/// holds the exception types.
/// NoexceptExpr - Instead of Exceptions, there may be a single Expr* pointing
/// to the expression in the noexcept() specifier.
friend class ASTContext; // ASTContext creates these.
public:
@ -2462,29 +2529,66 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
ExtProtoInfo EPI;
EPI.ExtInfo = getExtInfo();
EPI.Variadic = isVariadic();
EPI.HasExceptionSpec = hasExceptionSpec();
EPI.HasAnyExceptionSpec = hasAnyExceptionSpec();
EPI.ExceptionSpecType = getExceptionSpecType();
EPI.TypeQuals = static_cast<unsigned char>(getTypeQuals());
EPI.RefQualifier = getRefQualifier();
EPI.NumExceptions = NumExceptions;
EPI.Exceptions = exception_begin();
if (EPI.ExceptionSpecType == EST_Dynamic) {
EPI.NumExceptions = NumExceptions;
EPI.Exceptions = exception_begin();
} else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
EPI.NoexceptExpr = getNoexceptExpr();
}
return EPI;
}
bool hasExceptionSpec() const { return HasExceptionSpec; }
bool hasAnyExceptionSpec() const { return HasAnyExceptionSpec; }
/// \brief Get the kind of exception specification on this function.
ExceptionSpecificationType getExceptionSpecType() const {
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
}
/// \brief Return whether this function has any kind of exception spec.
bool hasExceptionSpec() const {
return getExceptionSpecType() != EST_None;
}
/// \brief Return whether this function has a dynamic (throw) exception spec.
bool hasDynamicExceptionSpec() const {
return isDynamicExceptionSpec(getExceptionSpecType());
}
/// \brief Return whether this function has a noexcept exception spec.
bool hasNoexceptExceptionSpec() const {
return isNoexceptExceptionSpec(getExceptionSpecType());
}
/// \brief Result type of getNoexceptSpec().
enum NoexceptResult {
NR_NoNoexcept, ///< There is no noexcept specifier.
NR_BadNoexcept, ///< The noexcept specifier has a bad expression.
NR_Dependent, ///< The noexcept specifier is dependent.
NR_Throw, ///< The noexcept specifier evaluates to false.
NR_Nothrow ///< The noexcept specifier evaluates to true.
};
/// \brief Get the meaning of the noexcept spec on this function, if any.
NoexceptResult getNoexceptSpec(ASTContext &Ctx) const;
unsigned getNumExceptions() const { return NumExceptions; }
QualType getExceptionType(unsigned i) const {
assert(i < NumExceptions && "Invalid exception number!");
return exception_begin()[i];
}
bool hasEmptyExceptionSpec() const {
return hasExceptionSpec() && !hasAnyExceptionSpec() &&
getNumExceptions() == 0;
Expr *getNoexceptExpr() const {
if (getExceptionSpecType() != EST_ComputedNoexcept)
return 0;
// NoexceptExpr sits where the arguments end.
return *reinterpret_cast<Expr *const *>(arg_type_end());
}
bool isNothrow(ASTContext &Ctx) const {
ExceptionSpecificationType EST = getExceptionSpecType();
if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
return true;
if (EST != EST_ComputedNoexcept)
return false;
return getNoexceptSpec(Ctx) == NR_Nothrow;
}
using FunctionType::isVariadic;
/// \brief Determines whether this function prototype contains a
/// parameter pack at the end.
///
@ -2513,6 +2617,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
return arg_type_end();
}
exception_iterator exception_end() const {
if (getExceptionSpecType() != EST_Dynamic)
return exception_begin();
return exception_begin() + NumExceptions;
}
@ -2524,10 +2630,10 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
}
static bool classof(const FunctionProtoType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID);
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
arg_type_iterator ArgTys, unsigned NumArgs,
const ExtProtoInfo &EPI);
const ExtProtoInfo &EPI, const ASTContext &Context);
};
@ -2566,18 +2672,18 @@ class UnresolvedUsingType : public Type {
class TypedefType : public Type {
TypedefDecl *Decl;
TypedefNameDecl *Decl;
protected:
TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can)
: Type(tc, can, can->isDependentType(), can->isVariablyModifiedType(),
/*ContainsUnexpandedParameterPack=*/false),
Decl(const_cast<TypedefDecl*>(D)) {
Decl(const_cast<TypedefNameDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
public:
TypedefDecl *getDecl() const { return Decl; }
TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
QualType desugar() const;
@ -2807,9 +2913,10 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
// Enumerated operand (string or keyword).
attr_objc_gc,
attr_pcs,
FirstEnumOperandKind = attr_objc_gc,
LastEnumOperandKind = attr_objc_gc,
LastEnumOperandKind = attr_pcs,
// No operand.
attr_noreturn,
@ -2864,44 +2971,68 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
};
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
unsigned Depth : 15;
unsigned ParameterPack : 1;
unsigned Index : 16;
IdentifierInfo *Name;
// Helper data collector for canonical types.
struct CanonicalTTPTInfo {
unsigned Depth : 15;
unsigned ParameterPack : 1;
unsigned Index : 16;
};
TemplateTypeParmType(unsigned D, unsigned I, bool PP, IdentifierInfo *N,
QualType Canon)
union {
// Info for the canonical type.
CanonicalTTPTInfo CanTTPTInfo;
// Info for the non-canonical type.
TemplateTypeParmDecl *TTPDecl;
};
/// Build a non-canonical type.
TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
: Type(TemplateTypeParm, Canon, /*Dependent=*/true,
/*VariablyModified=*/false, PP),
Depth(D), ParameterPack(PP), Index(I), Name(N) { }
/*VariablyModified=*/false,
Canon->containsUnexpandedParameterPack()),
TTPDecl(TTPDecl) { }
/// Build the canonical type.
TemplateTypeParmType(unsigned D, unsigned I, bool PP)
: Type(TemplateTypeParm, QualType(this, 0), /*Dependent=*/true,
/*VariablyModified=*/false, PP),
Depth(D), ParameterPack(PP), Index(I), Name(0) { }
/*VariablyModified=*/false, PP) {
CanTTPTInfo.Depth = D;
CanTTPTInfo.Index = I;
CanTTPTInfo.ParameterPack = PP;
}
friend class ASTContext; // ASTContext creates these
const CanonicalTTPTInfo& getCanTTPTInfo() const {
QualType Can = getCanonicalTypeInternal();
return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
}
public:
unsigned getDepth() const { return Depth; }
unsigned getIndex() const { return Index; }
bool isParameterPack() const { return ParameterPack; }
IdentifierInfo *getName() const { return Name; }
unsigned getDepth() const { return getCanTTPTInfo().Depth; }
unsigned getIndex() const { return getCanTTPTInfo().Index; }
bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
TemplateTypeParmDecl *getDecl() const {
return isCanonicalUnqualified() ? 0 : TTPDecl;
}
IdentifierInfo *getIdentifier() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, Depth, Index, ParameterPack, Name);
Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
}
static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
unsigned Index, bool ParameterPack,
IdentifierInfo *Name) {
TemplateTypeParmDecl *TTPDecl) {
ID.AddInteger(Depth);
ID.AddInteger(Index);
ID.AddBoolean(ParameterPack);
ID.AddPointer(Name);
ID.AddPointer(TTPDecl);
}
static bool classof(const Type *T) {
@ -2930,8 +3061,6 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
public:
IdentifierInfo *getName() const { return Replaced->getName(); }
/// Gets the template parameter that was substituted for.
const TemplateTypeParmType *getReplacedParameter() const {
return Replaced;
@ -2992,7 +3121,7 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
public:
IdentifierInfo *getName() const { return Replaced->getName(); }
IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
/// Gets the template parameter that was substituted for.
const TemplateTypeParmType *getReplacedParameter() const {
@ -4064,12 +4193,6 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
return getFunctionExtInfo(*t);
}
/// \brief Determine whether this set of qualifiers is a superset of the given
/// set of qualifiers.
inline bool Qualifiers::isSupersetOf(Qualifiers Other) const {
return Mask != Other.Mask && (Mask | Other.Mask) == Mask;
}
/// isMoreQualifiedThan - Determine whether this type is more
/// qualified than the Other type. For example, "const volatile int"
/// is more qualified than "const int", "volatile int", and
@ -4105,6 +4228,40 @@ inline QualType QualType::getNonReferenceType() const {
return *this;
}
/// \brief Tests whether the type is categorized as a fundamental type.
///
/// \returns True for types specified in C++0x [basic.fundamental].
inline bool Type::isFundamentalType() const {
return isVoidType() ||
// FIXME: It's really annoying that we don't have an
// 'isArithmeticType()' which agrees with the standard definition.
(isArithmeticType() && !isEnumeralType());
}
/// \brief Tests whether the type is categorized as a compound type.
///
/// \returns True for types specified in C++0x [basic.compound].
inline bool Type::isCompoundType() const {
// C++0x [basic.compound]p1:
// Compound types can be constructed in the following ways:
// -- arrays of objects of a given type [...];
return isArrayType() ||
// -- functions, which have parameters of given types [...];
isFunctionType() ||
// -- pointers to void or objects or functions [...];
isPointerType() ||
// -- references to objects or functions of a given type. [...]
isReferenceType() ||
// -- classes containing a sequence of objects of various types, [...];
isRecordType() ||
// -- unions, which ar classes capable of containing objects of different types at different times;
isUnionType() ||
// -- enumerations, which comprise a set of named constant values. [...];
isEnumeralType() ||
// -- pointers to non-static class members, [...].
isMemberPointerType();
}
inline bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType);
}
@ -4236,6 +4393,12 @@ inline bool Type::isPlaceholderType() const {
return false;
}
inline bool Type::isSpecificPlaceholderType(unsigned K) const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
return (BT->getKind() == (BuiltinType::Kind) K);
return false;
}
/// \brief Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {

View File

@ -527,7 +527,7 @@ class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
TypedefType> {
public:
TypedefDecl *getTypedefDecl() const {
TypedefNameDecl *getTypedefNameDecl() const {
return getTypePtr()->getDecl();
}
};
@ -584,6 +584,8 @@ class TemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TemplateTypeParmTypeLoc,
TemplateTypeParmType> {
public:
TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// \brief Wrapper for substituted template type parameters.
@ -943,10 +945,14 @@ class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
}
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
TypeSourceInfo *ClassTInfo;
};
/// \brief Wrapper for source info for member pointers.
class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
MemberPointerType> {
MemberPointerType,
MemberPointerLocInfo> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
@ -954,6 +960,28 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
const Type *getClass() const {
return getTypePtr()->getClass();
}
TypeSourceInfo *getClassTInfo() const {
return getLocalData()->ClassTInfo;
}
void setClassTInfo(TypeSourceInfo* TI) {
getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
setClassTInfo(0);
}
SourceRange getLocalSourceRange() const {
if (TypeSourceInfo *TI = getClassTInfo())
return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
else
return SourceRange(getStarLoc());
}
};
/// Wraps an ObjCPointerType with source location information.
@ -1007,7 +1035,8 @@ class RValueReferenceTypeLoc :
struct FunctionLocInfo {
SourceLocation LParenLoc, RParenLoc;
SourceLocation LocalRangeBegin;
SourceLocation LocalRangeEnd;
bool TrailingReturn;
};
@ -1017,18 +1046,18 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
FunctionType,
FunctionLocInfo> {
public:
SourceLocation getLParenLoc() const {
return getLocalData()->LParenLoc;
SourceLocation getLocalRangeBegin() const {
return getLocalData()->LocalRangeBegin;
}
void setLParenLoc(SourceLocation Loc) {
getLocalData()->LParenLoc = Loc;
void setLocalRangeBegin(SourceLocation L) {
getLocalData()->LocalRangeBegin = L;
}
SourceLocation getRParenLoc() const {
return getLocalData()->RParenLoc;
SourceLocation getLocalRangeEnd() const {
return getLocalData()->LocalRangeEnd;
}
void setRParenLoc(SourceLocation Loc) {
getLocalData()->RParenLoc = Loc;
void setLocalRangeEnd(SourceLocation L) {
getLocalData()->LocalRangeEnd = L;
}
bool getTrailingReturn() const {
@ -1056,12 +1085,12 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLParenLoc(Loc);
setRParenLoc(Loc);
setLocalRangeBegin(Loc);
setLocalRangeEnd(Loc);
setTrailingReturn(false);
for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
setArg(i, NULL);
@ -1388,7 +1417,10 @@ class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
struct ElaboratedLocInfo {
SourceLocation KeywordLoc;
SourceRange QualifierRange;
/// \brief Opaque data pointer used to reconstruct a nested-name-specifier
/// from
void *QualifierData;
};
class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@ -1403,27 +1435,29 @@ class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
NestedNameSpecifierLoc getQualifierLoc() const {
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
if (getQualifierRange().getEnd().isValid())
return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
if (getQualifierLoc())
return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc());
else
return SourceRange(getKeywordLoc());
else
return getQualifierRange();
return getQualifierLoc().getSourceRange();
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
@ -1444,6 +1478,9 @@ class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
// type is some sort of TypeDeclTypeLoc.
struct DependentNameLocInfo : ElaboratedLocInfo {
SourceLocation NameLoc;
/// \brief Data associated with the nested-name-specifier location.
void *QualifierData;
};
class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@ -1458,13 +1495,18 @@ class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
NestedNameSpecifierLoc getQualifierLoc() const {
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
@ -1476,7 +1518,7 @@ class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getNameLoc());
else
return SourceRange(getQualifierRange().getBegin(), getNameLoc());
return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
}
void copy(DependentNameTypeLoc Loc) {
@ -1485,16 +1527,11 @@ class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
memcpy(Data, Loc.Data, size);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
// This is exactly the structure of an ElaboratedTypeLoc whose inner
// type is some sort of TemplateSpecializationTypeLoc.
struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
SourceLocation KeywordLoc;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// followed by a TemplateArgumentLocInfo[]
@ -1513,11 +1550,28 @@ class DependentTemplateSpecializationTypeLoc :
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
NestedNameSpecifierLoc getQualifierLoc() const {
if (!getLocalData()->QualifierData)
return NestedNameSpecifierLoc();
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
if (!QualifierLoc) {
// Even if we have a nested-name-specifier in the dependent
// template specialization type, we won't record the nested-name-specifier
// location information when this type-source location information is
// part of a nested-name-specifier.
getLocalData()->QualifierData = 0;
return;
}
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getNameLoc() const {
@ -1559,8 +1613,10 @@ class DependentTemplateSpecializationTypeLoc :
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getRAngleLoc());
else if (getQualifierLoc())
return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
else
return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
return SourceRange(getNameLoc(), getRAngleLoc());
}
void copy(DependentTemplateSpecializationTypeLoc Loc) {
@ -1569,16 +1625,7 @@ class DependentTemplateSpecializationTypeLoc :
memcpy(Data, Loc.Data, size);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);

View File

@ -29,13 +29,13 @@ class CFGBlock;
// tend to have a common destination, so we lazily do a predecessor search
// from the destination node and cache the results to prevent work
// duplication.
class CFGReachabilityAnalysis {
class CFGReverseBlockReachabilityAnalysis {
typedef llvm::BitVector ReachableSet;
typedef llvm::DenseMap<unsigned, ReachableSet> ReachableMap;
ReachableSet analyzed;
ReachableMap reachable;
public:
CFGReachabilityAnalysis(const CFG &cfg);
CFGReverseBlockReachabilityAnalysis(const CFG &cfg);
/// Returns true if the block 'Dst' can be reached from block 'Src'.
bool isReachable(const CFGBlock *Src, const CFGBlock *Dst);

View File

@ -1,4 +1,4 @@
//===- UninitializedValues.h - unintialized values analysis ----*- C++ --*-===//
//= UninitializedValues.h - Finding uses of uninitialized values --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@ -7,71 +7,35 @@
//
//===----------------------------------------------------------------------===//
//
// This file provides the interface for the Unintialized Values analysis,
// a flow-sensitive analysis that detects when variable values are unintialized.
// This file defines APIs for invoking and reported uninitialized values
// warnings.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_UNITVALS_H
#define LLVM_CLANG_UNITVALS_H
#include "clang/Analysis/Support/BlkExprDeclBitVector.h"
#include "clang/Analysis/FlowSensitive/DataflowValues.h"
#ifndef LLVM_CLANG_UNINIT_VALS_H
#define LLVM_CLANG_UNINIT_VALS_H
namespace clang {
class BlockVarDecl;
class Expr;
class DeclRefExpr;
class VarDecl;
/// UninitializedValues_ValueTypes - Utility class to wrap type declarations
/// for dataflow values and dataflow analysis state for the
/// Unitialized Values analysis.
class UninitializedValues_ValueTypes {
class AnalysisContext;
class CFG;
class DeclContext;
class Expr;
class VarDecl;
class UninitVariablesHandler {
public:
struct ObserverTy;
struct AnalysisDataTy : public StmtDeclBitVector_Types::AnalysisDataTy {
AnalysisDataTy() : Observer(NULL), FullUninitTaint(true) {}
virtual ~AnalysisDataTy() {}
ObserverTy* Observer;
bool FullUninitTaint;
};
typedef StmtDeclBitVector_Types::ValTy ValTy;
//===--------------------------------------------------------------------===//
// ObserverTy - Observer for querying DeclRefExprs that use an uninitalized
// value.
//===--------------------------------------------------------------------===//
struct ObserverTy {
virtual ~ObserverTy();
virtual void ObserveDeclRefExpr(ValTy& Val, AnalysisDataTy& AD,
DeclRefExpr* DR, VarDecl* VD) = 0;
};
UninitVariablesHandler() {}
virtual ~UninitVariablesHandler();
virtual void handleUseOfUninitVariable(const Expr *ex,
const VarDecl *vd,
bool isAlwaysUninit) {}
};
void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
AnalysisContext &ac,
UninitVariablesHandler &handler);
/// UninitializedValues - Objects of this class encapsulate dataflow analysis
/// information regarding what variable declarations in a function are
/// potentially unintialized.
class UninitializedValues :
public DataflowValues<UninitializedValues_ValueTypes> {
public:
typedef UninitializedValues_ValueTypes::ObserverTy ObserverTy;
UninitializedValues(CFG &cfg) { getAnalysisData().setCFG(cfg); }
/// IntializeValues - Create initial dataflow values and meta data for
/// a given CFG. This is intended to be called by the dataflow solver.
void InitializeValues(const CFG& cfg);
};
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false);
} // end namespace clang
}
#endif

View File

@ -1,40 +0,0 @@
//= UninitializedValuesV2.h - Finding uses of uninitialized values --*- C++ -*-=
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines APIs for invoking and reported uninitialized values
// warnings.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_UNINIT_VALS_H
#define LLVM_CLANG_UNINIT_VALS_H
namespace clang {
class AnalysisContext;
class CFG;
class DeclContext;
class Expr;
class VarDecl;
class UninitVariablesHandler {
public:
UninitVariablesHandler() {}
virtual ~UninitVariablesHandler();
virtual void handleUseOfUninitVariable(const Expr *ex,
const VarDecl *vd) {}
};
void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
AnalysisContext &ac,
UninitVariablesHandler &handler);
}
#endif

View File

@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
@ -27,9 +28,7 @@ namespace clang {
class Decl;
class Stmt;
class CFG;
class CFGBlock;
class CFGReachabilityAnalysis;
class CFGReverseBlockReachabilityAnalysis;
class CFGStmtMap;
class LiveVariables;
class ParentMap;
@ -48,33 +47,32 @@ class AnalysisContext {
// TranslationUnit is NULL if we don't have multiple translation units.
idx::TranslationUnit *TU;
// AnalysisContext owns the following data.
CFG *cfg, *completeCFG;
CFGStmtMap *cfgStmtMap;
llvm::OwningPtr<CFG> cfg, completeCFG;
llvm::OwningPtr<CFGStmtMap> cfgStmtMap;
CFG::BuildOptions cfgBuildOptions;
CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
bool builtCFG, builtCompleteCFG;
LiveVariables *liveness;
LiveVariables *relaxedLiveness;
ParentMap *PM;
PseudoConstantAnalysis *PCA;
CFGReachabilityAnalysis *CFA;
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
const bool useUnoptimizedCFG;
llvm::OwningPtr<LiveVariables> liveness;
llvm::OwningPtr<LiveVariables> relaxedLiveness;
llvm::OwningPtr<ParentMap> PM;
llvm::OwningPtr<PseudoConstantAnalysis> PCA;
llvm::OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
llvm::BumpPtrAllocator A;
bool UseUnoptimizedCFG;
bool AddEHEdges;
bool AddImplicitDtors;
bool AddInitializers;
// FIXME: remove.
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
public:
AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
bool useUnoptimizedCFG = false,
bool addehedges = false,
bool addImplicitDtors = false,
bool addInitializers = false)
: D(d), TU(tu), cfg(0), completeCFG(0), cfgStmtMap(0),
builtCFG(false), builtCompleteCFG(false),
liveness(0), relaxedLiveness(0), PM(0), PCA(0), CFA(0),
ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
AddEHEdges(addehedges), AddImplicitDtors(addImplicitDtors),
AddInitializers(addInitializers) {}
bool addInitializers = false);
~AnalysisContext();
@ -87,18 +85,22 @@ class AnalysisContext {
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must
/// cope with that.
bool getAddEHEdges() const { return AddEHEdges; }
bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
bool getAddImplicitDtors() const { return AddImplicitDtors; }
bool getAddInitializers() const { return AddInitializers; }
bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
bool getUseUnoptimizedCFG() const {
return cfgBuildOptions.PruneTriviallyFalseEdges;
}
bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
void registerForcedBlockExpression(const Stmt *stmt);
const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
Stmt *getBody();
CFG *getCFG();
CFGStmtMap *getCFGStmtMap();
CFGReachabilityAnalysis *getCFGReachablityAnalysis();
CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
/// Return a version of the CFG without any edges pruned.
CFG *getUnoptimizedCFG();

View File

@ -15,7 +15,8 @@
namespace clang {
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM,
#define ANALYSISSTART
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
#undef DIAG

View File

@ -19,6 +19,8 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseMap.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/SourceLocation.h"
#include <cassert>
@ -29,6 +31,7 @@ namespace llvm {
}
namespace clang {
class CXXDestructorDecl;
class Decl;
class Stmt;
class Expr;
@ -47,45 +50,45 @@ class CFGElement {
public:
enum Kind {
// main kind
Invalid,
Statement,
Initializer,
ImplicitDtor,
// dtor kind
AutomaticObjectDtor,
BaseDtor,
MemberDtor,
TemporaryDtor,
DTOR_BEGIN = AutomaticObjectDtor
DTOR_BEGIN = AutomaticObjectDtor,
DTOR_END = TemporaryDtor
};
protected:
// The int bits are used to mark the main kind.
// The int bits are used to mark the kind.
llvm::PointerIntPair<void *, 2> Data1;
// The int bits are used to mark the dtor kind.
llvm::PointerIntPair<void *, 2> Data2;
CFGElement(void *Ptr, unsigned Int) : Data1(Ptr, Int) {}
CFGElement(void *Ptr1, unsigned Int1, void *Ptr2, unsigned Int2)
: Data1(Ptr1, Int1), Data2(Ptr2, Int2) {}
CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0)
: Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
public:
CFGElement() {}
Kind getKind() const { return static_cast<Kind>(Data1.getInt()); }
Kind getDtorKind() const {
assert(getKind() == ImplicitDtor);
return static_cast<Kind>(Data2.getInt() + DTOR_BEGIN);
Kind getKind() const {
unsigned x = Data2.getInt();
x <<= 2;
x |= Data1.getInt();
return (Kind) x;
}
bool isValid() const { return Data1.getPointer(); }
bool isValid() const { return getKind() != Invalid; }
operator bool() const { return isValid(); }
template<class ElemTy> ElemTy getAs() const {
template<class ElemTy> const ElemTy *getAs() const {
if (llvm::isa<ElemTy>(this))
return *static_cast<const ElemTy*>(this);
return ElemTy();
return static_cast<const ElemTy*>(this);
return 0;
}
static bool classof(const CFGElement *E) { return true; }
@ -93,13 +96,10 @@ class CFGElement {
class CFGStmt : public CFGElement {
public:
CFGStmt() {}
CFGStmt(Stmt *S) : CFGElement(S, 0) {}
CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
Stmt *getStmt() const { return static_cast<Stmt *>(Data1.getPointer()); }
operator Stmt*() const { return getStmt(); }
static bool classof(const CFGElement *E) {
return E->getKind() == Statement;
}
@ -109,14 +109,12 @@ class CFGStmt : public CFGElement {
/// constructor's initialization list.
class CFGInitializer : public CFGElement {
public:
CFGInitializer() {}
CFGInitializer(CXXCtorInitializer* I)
: CFGElement(I, Initializer) {}
CFGInitializer(CXXCtorInitializer *initializer)
: CFGElement(Initializer, initializer) {}
CXXCtorInitializer* getInitializer() const {
return static_cast<CXXCtorInitializer*>(Data1.getPointer());
}
operator CXXCtorInitializer*() const { return getInitializer(); }
static bool classof(const CFGElement *E) {
return E->getKind() == Initializer;
@ -127,14 +125,18 @@ class CFGInitializer : public CFGElement {
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
protected:
CFGImplicitDtor(unsigned K, void* P, void* S)
: CFGElement(P, ImplicitDtor, S, K - DTOR_BEGIN) {}
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
: CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
}
public:
CFGImplicitDtor() {}
const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
bool isNoReturn(ASTContext &astContext) const;
static bool classof(const CFGElement *E) {
return E->getKind() == ImplicitDtor;
Kind kind = E->getKind();
return kind >= DTOR_BEGIN && kind <= DTOR_END;
}
};
@ -143,22 +145,20 @@ class CFGImplicitDtor : public CFGElement {
/// of leaving its local scope.
class CFGAutomaticObjDtor: public CFGImplicitDtor {
public:
CFGAutomaticObjDtor() {}
CFGAutomaticObjDtor(VarDecl* VD, Stmt* S)
: CFGImplicitDtor(AutomaticObjectDtor, VD, S) {}
CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
: CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {}
VarDecl* getVarDecl() const {
const VarDecl *getVarDecl() const {
return static_cast<VarDecl*>(Data1.getPointer());
}
// Get statement end of which triggered the destructor call.
Stmt* getTriggerStmt() const {
const Stmt *getTriggerStmt() const {
return static_cast<Stmt*>(Data2.getPointer());
}
static bool classof(const CFGElement *E) {
return E->getKind() == ImplicitDtor &&
E->getDtorKind() == AutomaticObjectDtor;
static bool classof(const CFGElement *elem) {
return elem->getKind() == AutomaticObjectDtor;
}
};
@ -166,16 +166,15 @@ class CFGAutomaticObjDtor: public CFGImplicitDtor {
/// base object in destructor.
class CFGBaseDtor : public CFGImplicitDtor {
public:
CFGBaseDtor() {}
CFGBaseDtor(const CXXBaseSpecifier *BS)
: CFGImplicitDtor(BaseDtor, const_cast<CXXBaseSpecifier*>(BS), NULL) {}
CFGBaseDtor(const CXXBaseSpecifier *base)
: CFGImplicitDtor(BaseDtor, base) {}
const CXXBaseSpecifier *getBaseSpecifier() const {
return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
return E->getKind() == ImplicitDtor && E->getDtorKind() == BaseDtor;
return E->getKind() == BaseDtor;
}
};
@ -183,16 +182,15 @@ class CFGBaseDtor : public CFGImplicitDtor {
/// member object in destructor.
class CFGMemberDtor : public CFGImplicitDtor {
public:
CFGMemberDtor() {}
CFGMemberDtor(FieldDecl *FD)
: CFGImplicitDtor(MemberDtor, FD, NULL) {}
CFGMemberDtor(const FieldDecl *field)
: CFGImplicitDtor(MemberDtor, field, 0) {}
FieldDecl *getFieldDecl() const {
return static_cast<FieldDecl*>(Data1.getPointer());
const FieldDecl *getFieldDecl() const {
return static_cast<const FieldDecl*>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
return E->getKind() == ImplicitDtor && E->getDtorKind() == MemberDtor;
return E->getKind() == MemberDtor;
}
};
@ -200,16 +198,15 @@ class CFGMemberDtor : public CFGImplicitDtor {
/// at the end of full expression for temporary object.
class CFGTemporaryDtor : public CFGImplicitDtor {
public:
CFGTemporaryDtor() {}
CFGTemporaryDtor(CXXBindTemporaryExpr *E)
: CFGImplicitDtor(TemporaryDtor, E, NULL) {}
CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
: CFGImplicitDtor(TemporaryDtor, expr, 0) {}
CXXBindTemporaryExpr *getBindTemporaryExpr() const {
return static_cast<CXXBindTemporaryExpr *>(Data1.getPointer());
const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
return E->getKind() == ImplicitDtor && E->getDtorKind() == TemporaryDtor;
return E->getKind() == TemporaryDtor;
}
};
@ -267,6 +264,8 @@ class CFGTerminator {
/// ? operator LHS expression; RHS expression
/// &&, || expression that uses result of && or ||, RHS
///
/// But note that any of that may be NULL in case of optimized-out edges.
///
class CFGBlock {
class ElementList {
typedef BumpVector<CFGElement> ImplTy;
@ -471,8 +470,6 @@ class CFGBlock {
const Stmt *getLoopTarget() const { return LoopTarget; }
bool hasBinaryBranchTerminator() const;
Stmt* getLabel() { return Label; }
const Stmt* getLabel() const { return Label; }
@ -537,13 +534,16 @@ class CFG {
class BuildOptions {
public:
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
ForcedBlkExprs **forcedBlkExprs;
bool PruneTriviallyFalseEdges:1;
bool AddEHEdges:1;
bool AddInitializers:1;
bool AddImplicitDtors:1;
BuildOptions()
: PruneTriviallyFalseEdges(true)
: forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
, AddEHEdges(false)
, AddInitializers(false)
, AddImplicitDtors(false) {}
@ -552,7 +552,7 @@ class CFG {
/// buildCFG - Builds a CFG from an AST. The responsibility to free the
/// constructed CFG belongs to the caller.
static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
BuildOptions BO = BuildOptions());
const BuildOptions &BO);
/// createBlock - Create a new block in the CFG. The CFG owns the block;
/// the caller should not directly free it.
@ -607,8 +607,8 @@ class CFG {
for (const_iterator I=begin(), E=end(); I != E; ++I)
for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
BI != BE; ++BI) {
if (CFGStmt S = BI->getAs<CFGStmt>())
O(S);
if (const CFGStmt *stmt = BI->getAs<CFGStmt>())
O(stmt->getStmt());
}
}

View File

@ -22,7 +22,7 @@ namespace cocoa {
enum NamingConvention { NoConvention, CreateRule, InitRule };
NamingConvention deriveNamingConvention(Selector S, bool ignorePrefix = true);
NamingConvention deriveNamingConvention(Selector S);
static inline bool followsFundamentalRule(Selector S) {
return deriveNamingConvention(S) == CreateRule;

View File

@ -277,8 +277,8 @@ class DataflowSolver {
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
CFGElement El = *I;
if (CFGStmt S = El.getAs<CFGStmt>())
ProcessStmt(S, recordStmtValues, AnalysisDirTag());
if (const CFGStmt *S = El.getAs<CFGStmt>())
ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
}
TF.VisitTerminator(const_cast<CFGBlock*>(B));
@ -293,8 +293,8 @@ class DataflowSolver {
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
CFGElement El = *I;
if (CFGStmt S = El.getAs<CFGStmt>())
ProcessStmt(S, recordStmtValues, AnalysisDirTag());
if (const CFGStmt *S = El.getAs<CFGStmt>())
ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
}
}

View File

@ -43,6 +43,7 @@ class ProgramPoint {
PostStoreKind,
PostPurgeDeadSymbolsKind,
PostStmtCustomKind,
PostConditionKind,
PostLValueKind,
PostInitializerKind,
CallEnterKind,
@ -221,7 +222,17 @@ class PostStmtCustom : public PostStmt {
}
};
// PostCondition represents the post program point of a branch condition.
class PostCondition : public PostStmt {
public:
PostCondition(const Stmt* S, const LocationContext *L, const void *tag = 0)
: PostStmt(S, PostConditionKind, L, tag) {}
static bool classof(const ProgramPoint* Location) {
return Location->getKind() == PostConditionKind;
}
};
class LocationCheck : public StmtPoint {
protected:
LocationCheck(const Stmt *S, const LocationContext *L,

View File

@ -82,6 +82,7 @@ class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
DISPATCH_CASE(ConditionalOperator)
DISPATCH_CASE(BinaryConditionalOperator)
DISPATCH_CASE(ObjCForCollectionStmt)
DISPATCH_CASE(CXXForRangeStmt)
case Stmt::BinaryOperatorClass: {
BinaryOperator* B = cast<BinaryOperator>(S);
@ -109,6 +110,10 @@ class CFGStmtVisitor : public StmtVisitor<ImplClass,RetTy> {
return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
}
RetTy BlockStmt_VisitCXXForRangeStmt(CXXForRangeStmt* S) {
return static_cast<ImplClass*>(this)->BlockStmt_VisitStmt(S);
}
RetTy BlockStmt_VisitImplicitControlFlowExpr(Expr* E) {
return static_cast<ImplClass*>(this)->BlockStmt_VisitExpr(E);
}

View File

@ -0,0 +1,44 @@
//===--- AddressSpaces.h - Language-specific address spaces -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides definitions for the various language-specific address
// spaces.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_ADDRESSSPACES_H
#define LLVM_CLANG_BASIC_ADDRESSSPACES_H
namespace clang {
namespace LangAS {
/// This enum defines the set of possible language-specific address spaces.
/// It uses a high starting offset so as not to conflict with any address
/// space used by a target.
enum ID {
Offset = 0xFFFF00,
opencl_global = Offset,
opencl_local,
opencl_constant,
Last,
Count = Last-Offset
};
/// The type of a lookup table which maps from language-specific address spaces
/// to target-specific ones.
typedef unsigned Map[Count];
}
}
#endif

View File

@ -46,6 +46,7 @@ class Argument<string name> {
string Name = name;
}
class BoolArgument<string name> : Argument<name>;
class IdentifierArgument<string name> : Argument<name>;
class IntArgument<string name> : Argument<name>;
class StringArgument<string name> : Argument<name>;
@ -55,6 +56,9 @@ class TypeArgument<string name> : Argument<name>;
class UnsignedArgument<string name> : Argument<name>;
class VariadicUnsignedArgument<string name> : Argument<name>;
// A version of the form major.minor[.subminor].
class VersionArgument<string name> : Argument<name>;
// This one's a doozy, so it gets its own special type
// It can be an unsigned integer, or a type. Either can
// be dependent.
@ -89,8 +93,13 @@ class Attr {
code AdditionalMembers = [{}];
}
/// An inheritable attribute is inherited by later redeclarations.
class InheritableAttr : Attr;
/// An inheritable parameter attribute is inherited by later
/// redeclarations, even when it's written on a parameter.
class InheritableParamAttr : InheritableAttr;
//
// Attributes begin here
//
@ -129,12 +138,26 @@ def AsmLabel : InheritableAttr {
let Args = [StringArgument<"Label">];
}
def Availability : InheritableAttr {
let Spellings = ["availability"];
let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
BoolArgument<"unavailable">];
let AdditionalMembers =
[{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
return llvm::StringSwitch<llvm::StringRef>(Platform)
.Case("ios", "iOS")
.Case("macosx", "Mac OS X")
.Default(llvm::StringRef());
} }];
}
def Blocks : InheritableAttr {
let Spellings = ["blocks"];
let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
}
def CarriesDependency : InheritableAttr {
def CarriesDependency : InheritableParamAttr {
let Spellings = ["carries_dependency"];
let Subjects = [ParmVar, Function];
let Namespaces = ["", "std"];
@ -154,7 +177,7 @@ def CFReturnsNotRetained : InheritableAttr {
let Subjects = [ObjCMethod, Function];
}
def CFConsumed : InheritableAttr {
def CFConsumed : InheritableParamAttr {
let Spellings = ["cf_consumed"];
let Subjects = [ParmVar];
}
@ -224,10 +247,6 @@ def DLLImport : InheritableAttr {
let Spellings = ["dllimport"];
}
def Explicit : InheritableAttr {
let Spellings = [];
}
def FastCall : InheritableAttr {
let Spellings = ["fastcall", "__fastcall"];
}
@ -236,6 +255,10 @@ def Final : InheritableAttr {
let Spellings = [];
}
def MsStruct : InheritableAttr {
let Spellings = ["__ms_struct__"];
}
def Format : InheritableAttr {
let Spellings = ["format"];
let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
@ -261,7 +284,7 @@ def IBOutlet : InheritableAttr {
def IBOutletCollection : InheritableAttr {
let Spellings = ["iboutletcollection"];
let Args = [TypeArgument<"Interface">];
let Args = [TypeArgument<"InterFace">];
}
def Malloc : InheritableAttr {
@ -355,7 +378,7 @@ def NSConsumesSelf : InheritableAttr {
let Subjects = [ObjCMethod];
}
def NSConsumed : InheritableAttr {
def NSConsumed : InheritableParamAttr {
let Spellings = ["ns_consumed"];
let Subjects = [ParmVar];
}
@ -364,6 +387,15 @@ def ObjCException : InheritableAttr {
let Spellings = ["objc_exception"];
}
def ObjCMethodFamily : InheritableAttr {
let Spellings = ["objc_method_family"];
let Subjects = [ObjCMethod];
let Args = [EnumArgument<"Family", "FamilyKind",
["none", "alloc", "copy", "init", "mutableCopy", "new"],
["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
"OMF_mutableCopy", "OMF_new"]>];
}
def ObjCNSObject : InheritableAttr {
let Spellings = ["NSObject"];
}
@ -388,6 +420,13 @@ def Packed : InheritableAttr {
let Spellings = ["packed"];
}
def Pcs : InheritableAttr {
let Spellings = ["pcs"];
let Args = [EnumArgument<"PCS", "PCSType",
["aapcs", "aapcs-vfp"],
["AAPCS", "AAPCS_VFP"]>];
}
def Pure : InheritableAttr {
let Spellings = ["pure"];
}

View File

@ -22,6 +22,7 @@ namespace attr {
enum Kind {
#define ATTR(X) X,
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
#include "clang/Basic/AttrList.inc"
NUM_ATTRS
};

View File

@ -443,7 +443,7 @@ BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
BUILTIN(__builtin_object_size, "zvC*i", "n")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
@ -577,6 +577,13 @@ BUILTIN(__sync_lock_release_4, "viD*.", "n")
BUILTIN(__sync_lock_release_8, "vLLiD*.", "n")
BUILTIN(__sync_lock_release_16, "vLLLiD*.", "n")
BUILTIN(__sync_swap, "v.", "")
BUILTIN(__sync_swap_1, "ccD*c.", "n")
BUILTIN(__sync_swap_2, "ssD*s.", "n")
BUILTIN(__sync_swap_4, "iiD*i.", "n")
BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "n")
BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "n")
// Non-overloaded atomic builtins.

View File

@ -0,0 +1,62 @@
//===--- BuiltinsPTX.def - PTX Builtin function database ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the PTX-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//
// The format of this database matches clang/Basic/Builtins.def.
BUILTIN(__builtin_ptx_read_tid_x, "i", "nc")
BUILTIN(__builtin_ptx_read_tid_y, "i", "nc")
BUILTIN(__builtin_ptx_read_tid_z, "i", "nc")
BUILTIN(__builtin_ptx_read_tid_w, "i", "nc")
BUILTIN(__builtin_ptx_read_ntid_x, "i", "nc")
BUILTIN(__builtin_ptx_read_ntid_y, "i", "nc")
BUILTIN(__builtin_ptx_read_ntid_z, "i", "nc")
BUILTIN(__builtin_ptx_read_ntid_w, "i", "nc")
BUILTIN(__builtin_ptx_read_ctaid_x, "i", "nc")
BUILTIN(__builtin_ptx_read_ctaid_y, "i", "nc")
BUILTIN(__builtin_ptx_read_ctaid_z, "i", "nc")
BUILTIN(__builtin_ptx_read_ctaid_w, "i", "nc")
BUILTIN(__builtin_ptx_read_nctaid_x, "i", "nc")
BUILTIN(__builtin_ptx_read_nctaid_y, "i", "nc")
BUILTIN(__builtin_ptx_read_nctaid_z, "i", "nc")
BUILTIN(__builtin_ptx_read_nctaid_w, "i", "nc")
BUILTIN(__builtin_ptx_read_laneid, "i", "nc")
BUILTIN(__builtin_ptx_read_warpid, "i", "nc")
BUILTIN(__builtin_ptx_read_nwarpid, "i", "nc")
BUILTIN(__builtin_ptx_read_smid, "i", "nc")
BUILTIN(__builtin_ptx_read_nsmid, "i", "nc")
BUILTIN(__builtin_ptx_read_gridid, "i", "nc")
BUILTIN(__builtin_ptx_read_lanemask_eq, "i", "nc")
BUILTIN(__builtin_ptx_read_lanemask_le, "i", "nc")
BUILTIN(__builtin_ptx_read_lanemask_lt, "i", "nc")
BUILTIN(__builtin_ptx_read_lanemask_ge, "i", "nc")
BUILTIN(__builtin_ptx_read_lanemask_gt, "i", "nc")
BUILTIN(__builtin_ptx_read_clock, "i", "n")
BUILTIN(__builtin_ptx_read_clock64, "Li", "n")
BUILTIN(__builtin_ptx_read_pm0, "i", "n")
BUILTIN(__builtin_ptx_read_pm1, "i", "n")
BUILTIN(__builtin_ptx_read_pm2, "i", "n")
BUILTIN(__builtin_ptx_read_pm3, "i", "n")
BUILTIN(__builtin_ptx_bar_sync, "vi", "n")
#undef BUILTIN

View File

@ -24,6 +24,37 @@
// FIXME: Are these nothrow/const?
// 3DNow!
//
BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc")
BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc")
BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "nc")
BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "nc")
BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "nc")
// GCC has pfrsqrtit1, even though this is not the name of the instruction.
BUILTIN(__builtin_ia32_pfrsqrtit1, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc")
BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc")
// 3DNow! Extensions.
BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc")
BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc")
BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "nc")
BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "nc")
BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc")
// MMX
//
// FIXME: All MMX instructions will be generated via builtins. Any MMX vector
@ -209,7 +240,6 @@ BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "")
BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "")
BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "")
BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "")
BUILTIN(__builtin_ia32_loadups, "V4ffC*", "")
BUILTIN(__builtin_ia32_storeups, "vf*V4f", "")
BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "")
BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "")
@ -223,7 +253,6 @@ BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "")
BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "")
BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "")
BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "")
BUILTIN(__builtin_ia32_loadupd, "V2ddC*", "")
BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "")
BUILTIN(__builtin_ia32_movmskpd, "iV2d", "")
BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "")
@ -342,10 +371,10 @@ BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16cic","")
BUILTIN(__builtin_ia32_pcmpgtq, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_ia32_crc32qi, "iic", "")
BUILTIN(__builtin_ia32_crc32hi, "iis", "")
BUILTIN(__builtin_ia32_crc32si, "iii", "")
BUILTIN(__builtin_ia32_crc32di, "LLiLLiLLi", "")
BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "")
BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "")
BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "")
BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "")
// AES
BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "")

View File

@ -17,6 +17,10 @@ clang_tablegen(DiagnosticGroups.inc -gen-clang-diag-groups
SOURCE Diagnostic.td
TARGET ClangDiagnosticGroups)
clang_tablegen(DiagnosticIndexName.inc -gen-clang-diags-index-name
SOURCE Diagnostic.td
TARGET ClangDiagnosticIndexName)
clang_tablegen(AttrList.inc -gen-clang-attr-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE Attr.td

View File

@ -87,6 +87,9 @@
------------------------------------------------------------------------ */
#ifndef CLANG_BASIC_CONVERTUTF_H
#define CLANG_BASIC_CONVERTUTF_H
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
@ -156,4 +159,6 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
}
#endif
#endif
/* --------------------------------------------------------------------- */

View File

@ -17,7 +17,9 @@ def Named : Decl<1>;
def NamespaceAlias : DDecl<Named>;
def Label : DDecl<Named>;
def Type : DDecl<Named, 1>;
def Typedef : DDecl<Type>;
def TypedefName : DDecl<Type, 1>;
def Typedef : DDecl<TypedefName>;
def TypeAlias : DDecl<TypedefName>;
def UnresolvedUsingTypename : DDecl<Type>;
def Tag : DDecl<Type, 1>, DeclContext;
def Enum : DDecl<Tag>;

View File

@ -585,7 +585,7 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
/// DiagArgumentsVal - The values for the various substitution positions. This
/// is used when the argument is not an std::string. The specific value is
/// mangled into an intptr_t and the intepretation depends on exactly what
/// mangled into an intptr_t and the interpretation depends on exactly what
/// sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
@ -741,9 +741,6 @@ class DiagnosticBuilder {
}
void AddFixItHint(const FixItHint &Hint) const {
if (Hint.isNull())
return;
assert(NumFixItHints < Diagnostic::MaxFixItHints &&
"Too many fix-it hints!");
if (DiagObj)

View File

@ -18,6 +18,8 @@ def MAP_IGNORE : DiagMapping;
def MAP_WARNING : DiagMapping;
def MAP_ERROR : DiagMapping;
def MAP_FATAL : DiagMapping;
def MAP_WARNING_NO_WERROR : DiagMapping;
def MAP_WARNING_SHOW_IN_SYSTEM_HEADER : DiagMapping;
// Define the diagnostic classes.
class DiagClass;
@ -60,6 +62,8 @@ class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> {
DiagMapping DefaultMapping = defaultmapping;
DiagGroup Group;
string CategoryName = "";
string Brief = "";
string Explanation = "";
}
class Error<string str> : Diagnostic<str, CLASS_ERROR, MAP_ERROR>;
@ -73,10 +77,20 @@ class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; }
class DefaultWarn { DiagMapping DefaultMapping = MAP_WARNING; }
class DefaultError { DiagMapping DefaultMapping = MAP_ERROR; }
class DefaultFatal { DiagMapping DefaultMapping = MAP_FATAL; }
class DefaultWarnNoWerror { DiagMapping DefaultMapping= MAP_WARNING_NO_WERROR; }
class DefaultWarnShowInSystemHeader {
DiagMapping DefaultMapping = MAP_WARNING_SHOW_IN_SYSTEM_HEADER;
}
class NoSFINAE { bit SFINAE = 0; }
class AccessControl { bit AccessControl = 1; }
class Brief<string str> { string Brief = str; }
class FullExplanation<string brief, string full> {
string Brief = brief;
string Explanation = full;
}
// Definitions for Diagnostics.
include "DiagnosticASTKinds.td"
include "DiagnosticAnalysisKinds.td"

View File

@ -45,6 +45,8 @@ def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
InGroup<MissingDeclarations>;
def err_param_redefinition : Error<"redefinition of parameter %0">;
def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
InGroup<DuplicateArgDecl>, DefaultIgnore;
def err_invalid_storage_class_in_func_decl : Error<
"invalid storage class specifier in function declarator">;
def err_expected_namespace_name : Error<"expected namespace name">;

View File

@ -39,8 +39,10 @@ def err_drv_invalid_darwin_version : Error<
"invalid Darwin version number: %0">;
def err_drv_missing_argument : Error<
"argument to '%0' is missing (expected %1 %plural{1:value|:values}1)">;
def err_drv_invalid_Xarch_argument : Error<
"invalid Xarch argument: '%0'">;
def err_drv_invalid_Xarch_argument_with_args : Error<
"invalid Xarch argument: '%0', options requiring arguments are unsupported">;
def err_drv_invalid_Xarch_argument_isdriver : Error<
"invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">;
def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">;
def err_drv_argument_not_allowed_with : Error<
@ -76,6 +78,10 @@ def err_drv_cc_print_options_failure : Error<
"unable to open CC_PRINT_OPTIONS file: %0">;
def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
def err_drv_invalid_arch_for_deployment_target : Error<
"invalid architecture '%0' for deployment target '%1'">;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for c++ and objective-c++ only">;

View File

@ -79,6 +79,8 @@ def warn_fe_macro_contains_embedded_newline : Warning<
"macro '%0' contains embedded newline, text after the newline is ignored.">;
def warn_fe_cc_print_header_failure : Warning<
"unable to open CC_PRINT_HEADERS file: %0 (using stderr)">;
def warn_fe_cc_log_diagnostics_failure : Warning<
"unable to open CC_LOG_DIAGNOSTICS file: %0 (using stderr)">;
def err_verify_missing_start : Error<
"cannot find start ('{{') of expected %0">;
@ -113,6 +115,9 @@ def warn_pch_target_triple : Error<
def warn_pch_c99 : Error<
"C99 support was %select{disabled|enabled}0 in PCH file but is "
"currently %select{disabled|enabled}1">;
def warn_pch_c1x : Error<
"C1X support was %select{disabled|enabled}0 in PCH file but is "
"currently %select{disabled|enabled}1">;
def warn_pch_cplusplus : Error<
"C++ support was %select{disabled|enabled}0 in PCH file but is "
"currently %select{disabled|enabled}1">;
@ -230,6 +235,9 @@ def warn_pch_gnu_inline : Error<
def warn_pch_no_inline : Error<
"the macro '__NO_INLINE__' was %select{not defined|defined}0 in "
"the PCH file but is currently %select{undefined|defined}1">;
def warn_pch_deprecated : Error<
"the macro '__DEPRECATED' was %select{not defined|defined}0 in "
"the PCH file but is currently %select{undefined|defined}1">;
def warn_pch_gc_mode : Error<
"the PCH file was built with %select{no||hybrid}0 garbage collection but "
"the current translation unit will compiled with %select{no||hybrid}1 "

View File

@ -24,6 +24,7 @@ def : DiagGroup<"aggregate-return">;
def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
def Availability : DiagGroup<"availability">;
def BoolConversions : DiagGroup<"bool-conversions">;
def CXXCompat: DiagGroup<"c++-compat">;
def CastAlign : DiagGroup<"cast-align">;
@ -54,6 +55,7 @@ def CXXHexFloats : DiagGroup<"c++-hex-floats">;
def : DiagGroup<"c++0x-compat", [CXXHexFloats]>;
def : DiagGroup<"effc++">;
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
def GlobalConstructors : DiagGroup<"global-constructors">;
def : DiagGroup<"idiomatic-parentheses">;
@ -94,6 +96,8 @@ def Padded : DiagGroup<"padded">;
def PointerArith : DiagGroup<"pointer-arith">;
def PoundWarning : DiagGroup<"#warnings">,
DiagCategory<"#warning Directive">;
def PoundPragmaMessage : DiagGroup<"#pragma messages">,
DiagCategory<"#pragma message Directive">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def ReturnType : DiagGroup<"return-type">;
@ -109,6 +113,7 @@ def : DiagGroup<"stack-protector">;
def : DiagGroup<"switch-default">;
def : DiagGroup<"synth">;
def TautologicalCompare : DiagGroup<"tautological-compare">;
def HeaderHygiene : DiagGroup<"header-hygiene">;
// Preprocessor warnings.
def : DiagGroup<"builtin-macro-redefined">;
@ -137,13 +142,17 @@ def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
def Uninitialized : DiagGroup<"uninitialized">;
def UninitializedMaybe : DiagGroup<"conditional-uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def UnknownAttributes : DiagGroup<"unknown-attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">;
def UnusedArgument : DiagGroup<"unused-argument">;
def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
def UnusedFunction : DiagGroup<"unused-function">;
def UnusedMemberFunction : DiagGroup<"unused-member-function">;
def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">;
def UnneededMemberFunction : DiagGroup<"unneeded-member-function">;
def UnusedFunction : DiagGroup<"unused-function", [UnneededInternalDecl]>;
def UnusedMemberFunction : DiagGroup<"unused-member-function",
[UnneededMemberFunction]>;
def UnusedLabel : DiagGroup<"unused-label">;
def UnusedParameter : DiagGroup<"unused-parameter">;
def UnusedValue : DiagGroup<"unused-value">;
@ -165,17 +174,22 @@ def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VLA : DiagGroup<"vla">;
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
// GCC calls -Wdeprecated-writable-strings -Wwrite-strings.
def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>;
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
// Aggregation warning settings.
// -Widiomatic-parentheses contains warnings about 'idiomatic'
// missing parentheses; it is off by default.
// missing parentheses; it is off by default. We do not include it
// in -Wparentheses because most users who use -Wparentheses explicitly
// do not want these warnings.
def Parentheses : DiagGroup<"parentheses",
[LogicalOpParentheses,
DiagGroup<"idiomatic-parentheses">]>;
[LogicalOpParentheses]>;
// -Wconversion has its own warnings, but we split a few out for
// legacy reasons:
@ -187,6 +201,7 @@ def Conversion : DiagGroup<"conversion",
[DiagGroup<"shorten-64-to-32">,
DiagGroup<"constant-conversion">,
DiagGroup<"literal-conversion">,
DiagGroup<"sign-conversion">,
BoolConversions]>,
DiagCategory<"Value Conversion Issue">;
@ -253,7 +268,9 @@ def NonGCC : DiagGroup<"non-gcc",
// A warning group for warnings about using C++0x features as extensions in
// earlier C++ versions.
def CXX0x : DiagGroup<"c++0x-extensions">;
def CXX0xStaticNonIntegralInitializer :
DiagGroup<"c++0x-static-nonintegral-init">;
def CXX0x : DiagGroup<"c++0x-extensions", [CXX0xStaticNonIntegralInitializer]>;
// A warning group for warnings about GCC extensions.
def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;

View File

@ -42,7 +42,8 @@ namespace clang {
// Get typedefs for common diagnostics.
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM,
#include "clang/Basic/DiagnosticCommonKinds.inc"
NUM_BUILTIN_COMMON_DIAGNOSTICS
#undef DIAG
@ -63,9 +64,12 @@ namespace clang {
/// Map this diagnostic to "warning", but make it immune to -Werror. This
/// happens when you specify -Wno-error=foo.
MAP_WARNING_NO_WERROR = 5,
/// Map this diagnostic to "warning", but make it immune to
/// -Wno-system-headers.
MAP_WARNING_SHOW_IN_SYSTEM_HEADER = 6,
/// Map this diagnostic to "error", but make it immune to -Wfatal-errors.
/// This happens for -Wno-fatal-errors=foo.
MAP_ERROR_NO_WFATAL = 6
MAP_ERROR_NO_WFATAL = 7
};
}
@ -99,7 +103,7 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
/// issue.
const char *getDescription(unsigned DiagID) const;
/// isNoteWarningOrExtension - Return true if the unmapped diagnostic
/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
/// level of the specified diagnostic ID is a Warning or Extension.
/// This only works on builtin diagnostics, not custom ones, and is not legal to
/// call on NOTEs.
@ -130,7 +134,7 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
/// the diagnostic, this returns null.
static const char *getWarningOptionForDiag(unsigned DiagID);
/// getWarningOptionForDiag - Return the category number that a specified
/// getCategoryNumberForDiag - Return the category number that a specified
/// DiagID belongs to, or 0 if no category.
static unsigned getCategoryNumberForDiag(unsigned DiagID);
@ -174,6 +178,20 @@ class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> {
/// are not SFINAE errors.
static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
/// getName - Given a diagnostic ID, return its name
static const char *getName(unsigned DiagID);
/// getIdFromName - Given a diagnostic name, return its ID, or 0
static unsigned getIdFromName(char const *Name);
/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
/// of the issue
static const char *getBriefExplanation(unsigned DiagID);
/// getFullExplanation - Given a diagnostic ID, return a full explanation
/// of the issue
static const char *getFullExplanation(unsigned DiagID);
private:
/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
/// "unknown-pragmas" to have the specified mapping. This returns true and

View File

@ -114,7 +114,8 @@ def err_invalid_pth_file : Error<
//===----------------------------------------------------------------------===//
// Preprocessor Diagnostics
//===----------------------------------------------------------------------===//
def pp_hash_warning : Warning<"#warning%0">, InGroup<PoundWarning>;
def pp_hash_warning : Warning<"#warning%0">,
InGroup<PoundWarning>, DefaultWarnShowInSystemHeader;
def pp_include_next_in_primary : Warning<
"#include_next in primary source file">;
def pp_include_macros_out_of_predefines : Error<
@ -239,7 +240,8 @@ def err_pragma_push_pop_macro_malformed : Error<
"pragma %0 requires a parenthesized string">;
def warn_pragma_pop_macro_no_push : Warning<
"pragma pop_macro could not pop '%0', no matching push_macro">;
def warn_pragma_message : Warning<"%0">;
def warn_pragma_message : Warning<"%0">,
InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
def warn_pragma_ignored : Warning<"unknown pragma ignored">,
InGroup<UnknownPragmas>, DefaultIgnore;
def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
@ -247,8 +249,8 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
def ext_on_off_switch_syntax :
ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">,
InGroup<UnknownPragmas>;
def ext_pragma_syntax_eom :
ExtWarn<"expected end of macro in pragma">,
def ext_pragma_syntax_eod :
ExtWarn<"expected end of directive in pragma">,
InGroup<UnknownPragmas>;
def warn_stdc_fenv_access_not_supported :
Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,

View File

@ -67,6 +67,13 @@ def ext_ms_enum_fixed_underlying_type : Extension<
"enumeration types with a fixed underlying type are a Microsoft extension">,
InGroup<Microsoft>;
def ext_c1x_generic_selection : Extension<
"generic selections are a C1X-specific feature">;
def err_duplicate_default_assoc : Error<
"duplicate default generic association">;
def note_previous_default_assoc : Note<
"previous default generic association is here">;
def ext_gnu_indirect_goto : Extension<
"use of GNU indirect-goto extension">, InGroup<GNU>;
def ext_gnu_address_of_label : Extension<
@ -111,7 +118,7 @@ def err_expected_semi_declaration : Error<
"expected ';' at end of declaration">;
def err_expected_semi_decl_list : Error<
"expected ';' at end of declaration list">;
def ext_expected_semi_decl_list : Extension<
def ext_expected_semi_decl_list : ExtWarn<
"expected ';' at end of declaration list">;
def err_expected_member_name_or_semi : Error<
"expected member name or ';' after declaration specifiers">;
@ -119,6 +126,10 @@ def err_function_declared_typedef : Error<
"function definition declared 'typedef'">;
def err_iboutletcollection_builtintype : Error<
"type argument of iboutletcollection attribute cannot be a builtin type">;
def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">;
def err_at_in_class : Error<"unexpected '@' in member specification">;
def err_expected_fn_body : Error<
"expected function body after function declarator">;
def err_expected_method_body : Error<"expected method body">;
@ -130,6 +141,7 @@ def err_expected_statement : Error<"expected statement">;
def err_expected_lparen_after : Error<"expected '(' after '%0'">;
def err_expected_lparen_after_id : Error<"expected '(' after %0">;
def err_expected_less_after : Error<"expected '<' after '%0'">;
def err_expected_equal_after : Error<"expected '=' after %0">;
def err_expected_comma : Error<"expected ','">;
def err_expected_lbrace_in_compound_literal : Error<
"expected '{' in compound literal">;
@ -178,6 +190,9 @@ 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 ext_generalized_initializer_lists : ExtWarn<
"generalized initializer lists are a C++0x extension unsupported in Clang">,
InGroup<CXX0x>;
def err_argument_required_after_attribute : Error<
"argument required after attribute">;
def err_missing_param : Error<"expected parameter declarator">;
@ -189,6 +204,9 @@ def err_expected_class_name : Error<"expected class name">;
def err_unspecified_vla_size_with_static : Error<
"'static' may not be used with an unspecified variable length array size">;
def err_expected_case_before_expression: Error<
"expected 'case' keyword before expression">;
// Declarations.
def err_typename_requires_specqual : Error<
"type name requires a specifier or qualifier">;
@ -226,6 +244,8 @@ def err_unexected_colon_in_nested_name_spec : Error<
"unexpected ':' in nested name specifier">;
def err_bool_redeclaration : Error<
"redeclaration of C++ built-in type 'bool'">;
def ext_c1x_static_assert : Extension<
"_Static_assert is a C1X-specific feature">;
/// Objective-C parser diagnostics
def err_expected_minus_or_plus : Error<
@ -266,7 +286,7 @@ def err_missing_id_definition : Error<"cannot find definition of 'id'">;
def err_missing_proto_definition : Error<
"cannot find definition of 'Protocol'">;
def err_missing_class_definition : Error<"cannot find definition of 'Class'">;
def warn_expected_implementation : Warning<
def err_expected_implementation : Error<
"@end must appear in an @implementation context">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
@ -300,6 +320,8 @@ def err_expected_lbrace_after_base_specifiers : Error<
"expected '{' after base class list">;
def ext_ellipsis_exception_spec : Extension<
"exception specification of '...' is a Microsoft extension">;
def err_dynamic_and_noexcept_specification : Error<
"cannot have both throw() and noexcept() clause on the same function">;
def err_expected_catch : Error<"expected catch">;
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_using_namespace_in_class : Error<
@ -363,6 +385,8 @@ def err_enum_template : Error<"enumeration cannot be a template">;
def err_missing_dependent_template_keyword : Error<
"use 'template' keyword to treat '%0' as a dependent template name">;
def warn_missing_dependent_template_keyword : ExtWarn<
"use 'template' keyword to treat '%0' as a dependent template name">;
def warn_static_inline_explicit_inst_ignored : Warning<
"ignoring '%select{static|inline}0' keyword on explicit template "
@ -380,6 +404,8 @@ def err_out_of_line_type_names_constructor : Error<
def err_expected_qualified_after_typename : Error<
"expected a qualified name after 'typename'">;
def warn_expected_qualified_after_typename : ExtWarn<
"expected a qualified name after 'typename'">;
def err_expected_semi_after_tagdecl : Error<
"expected ';' after %0">;
@ -401,15 +427,23 @@ def err_ctor_init_missing_comma : Error<
// C++ declarations
def err_friend_decl_defines_class : Error<
"cannot define a type in a friend declaration">;
def err_missing_whitespace_digraph : Error<
"found '<::' after a "
"%select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0"
" which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">;
def warn_deleted_function_accepted_as_extension: ExtWarn<
"deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>;
// 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">;
// C++0x override control
def ext_override_control_keyword : Extension<
"'%0' keyword accepted as a C++0x extension">, InGroup<CXX0x>;
def ext_override_inline: Extension<
"'%0' keyword only allowed in declarations, allowed as an extension">;
def err_duplicate_virt_specifier : Error<
"class member already marked '%0'">;
@ -426,6 +460,23 @@ def err_paren_sizeof_parameter_pack : Error<
def err_sizeof_parameter_pack : Error<
"expected parenthesized parameter pack name in 'sizeof...' expression">;
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
def err_zero_version : Error<
"version number must have non-zero major, minor, or sub-minor version">;
def err_availability_expected_platform : Error<
"expected a platform name, e.g., 'macosx'">;
def err_availability_expected_change : Error<
"expected 'introduced', 'deprecated', or 'obsoleted'">;
def err_availability_unknown_change : Error<
"%0 is not an availability stage; use 'introduced', 'deprecated', or "
"'obsoleted'">;
def err_availability_redundant : Error<
"redundant %0 availability change; only the last specified change will " "be used">;
def warn_availability_and_unavailable : Warning<
"'unavailable' availability overrides all other availability information">;
// Language specific pragmas
// - Generic warnings
def warn_pragma_expected_lparen : Warning<
@ -434,6 +485,8 @@ def warn_pragma_expected_rparen : Warning<
"missing ')' after '#pragma %0' - ignoring">;
def warn_pragma_expected_identifier : Warning<
"expected identifier in '#pragma %0' - ignored">;
def warn_pragma_ms_struct : Warning<
"incorrect use of '#pragma ms_struct on|off' - ignored">;
def warn_pragma_extra_tokens_at_eol : Warning<
"extra tokens at end of '#pragma %0' - ignored">;
// - #pragma options
@ -468,5 +521,17 @@ def warn_pragma_expected_enable_disable : Warning<
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">;
def err_seh_expected_handler : Error<
"expected '__except' or '__finally' block">;
def err_seh___except_block : Error<
"%0 only allowed in __except block">;
def err_seh___except_filter : Error<
"%0 only allowed in __except filter expression">;
def err_seh___finally_block : Error<
"%0 only allowed in __finally block">;
} // end of Parse Issue category.
} // end of Parser diagnostics

View File

@ -30,6 +30,8 @@ def warn_float_overflow : Warning<
def warn_float_underflow : Warning<
"magnitude of floating-point constant too small for type %0; minimum is %1">,
InGroup<LiteralRange>;
def warn_double_const_requires_fp64 : Warning<
"double precision constant requires cl_khr_fp64, casting to single precision">;
// C99 variable-length arrays
def ext_vla : Extension<
@ -57,6 +59,8 @@ def err_variably_modified_new_type : Error<
// C99 Designated Initializers
def ext_designated_init : Extension<
"designated initializers are a C99 feature">;
def ext_designated_init_cxx : Extension<
"designated initializers are a C99 feature, accepted in C++ as an extension">;
def err_array_designator_negative : Error<
"array designator value '%0' is negative">;
@ -114,6 +118,12 @@ def warn_unused_member_function : Warning<"unused member function %0">,
InGroup<UnusedMemberFunction>, DefaultIgnore;
def warn_used_but_marked_unused: Warning<"%0 was marked unused but was used">,
InGroup<UsedButMarkedUnused>, DefaultIgnore;
def warn_unneeded_internal_decl : Warning<
"%select{function|variable}0 %1 is not needed and will not be emitted">,
InGroup<UnneededInternalDecl>, DefaultIgnore;
def warn_unneeded_member_function : Warning<
"member function %0 is not needed and will not be emitted">,
InGroup<UnneededMemberFunction>, DefaultIgnore;
def warn_parameter_size: Warning<
"%0 is a large (%1 bytes) pass-by-value argument; "
@ -202,6 +212,9 @@ def warn_global_constructor : Warning<
def warn_global_destructor : Warning<
"declaration requires a global destructor">,
InGroup<GlobalConstructors>, DefaultIgnore;
def warn_exit_time_destructor : Warning<
"declaration requires an exit-time destructor">,
InGroup<ExitTimeDestructors>, DefaultIgnore;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@ -248,6 +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<
"explicitly cast the pointer to silence this warning">;
/// main()
// static/inline main() are not errors in C, just in C++.
@ -382,7 +400,7 @@ def note_declared_at : Note<"declared here">;
def note_method_declared_at : Note<"method declared here">;
def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
def err_missing_atend : Error<"'@end' is missing in implementation context">;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside @interface or @protocol">;
def error_missing_method_context : Error<
@ -540,7 +558,7 @@ def ext_using_undefined_std : ExtWarn<
// C++ exception specifications
def err_exception_spec_in_typedef : Error<
"exception specifications are not allowed in typedefs">;
"exception specifications are not allowed in %select{typedefs|type aliases}0">;
def err_distant_exception_spec : Error<
"exception specifications are not allowed beyond a single level "
"of indirection">;
@ -549,6 +567,8 @@ def err_incomplete_in_exception_spec : Error<
"in exception specification">;
def err_mismatched_exception_spec : Error<
"exception specification in declaration does not match previous declaration">;
def warn_mismatched_exception_spec : ExtWarn<
"exception specification in declaration does not match previous declaration">;
def err_override_exception_spec : Error<
"exception specification of overriding function is more lax than "
"base version">;
@ -558,6 +578,8 @@ def err_deep_exception_specs_differ : Error<
"exception specifications of %select{return|argument}0 types differ">;
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">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@ -786,20 +808,28 @@ def err_destructor_redeclared : Error<"destructor cannot be redeclared">;
def err_destructor_with_params : Error<"destructor cannot have any parameters">;
def err_destructor_variadic : Error<"destructor cannot be variadic">;
def err_destructor_typedef_name : Error<
"destructor cannot be declared using a typedef %0 of the class name">;
"destructor cannot be declared using a %select{typedef|type alias}1 %0 of the class name">;
def err_destructor_name : Error<
"expected the class name after '~' to name the enclosing class">;
def err_destructor_class_name : Error<
"expected the class name after '~' to name a destructor">;
def err_ident_in_pseudo_dtor_not_a_type : Error<
"identifier %0 in pseudo-destructor expression does not name a type">;
def err_ident_in_dtor_not_a_type : Error<
"identifier %0 in object destruction expression does not name a type">;
def err_destructor_expr_type_mismatch : Error<
"destructor type %0 in object destruction expression does not match the "
"type %1 of the object being destroyed">;
def note_destructor_type_here : Note<
"type %0 is declared here">;
def err_destructor_template : Error<
"destructor cannot be declared as a template">;
// C++ initialization
def err_init_conversion_failed : Error<
"cannot initialize %select{a variable|a parameter|return object|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a vector element}0 of type %1 with an %select{rvalue|lvalue}2 of "
"type %3">;
"base class|a constructor delegation|a vector element}0 of type %1 with an "
"%select{rvalue|lvalue}2 of type %3">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference to type %0 cannot bind "
"to lvalue of type %1">;
@ -854,13 +884,23 @@ def note_uninit_reference_member : Note<
"uninitialized reference member is here">;
def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
InGroup<Uninitialized>;
def warn_uninit_var : Warning<"variable %0 is possibly uninitialized when used here">,
InGroup<DiagGroup<"uninitialized-experimental">>, DefaultIgnore;
def warn_uninit_self_reference_in_init : Warning<
"variable %0 is uninitialized when used within its own initialization">,
InGroup<Uninitialized>;
def warn_uninit_var : Warning<
"variable %0 is uninitialized when used here">,
InGroup<Uninitialized>, DefaultIgnore;
def warn_maybe_uninit_var :
Warning<"variable %0 may be uninitialized when used here">,
InGroup<UninitializedMaybe>, DefaultIgnore;
def note_uninit_var_def : Note<
"variable %0 is declared here">;
def warn_uninit_var_captured_by_block : Warning<
"variable %0 is possibly uninitialized when captured by block">,
InGroup<DiagGroup<"uninitialized-experimental">>, DefaultIgnore;
"variable %0 is uninitialized when captured by block">,
InGroup<Uninitialized>, DefaultIgnore;
def warn_maybe_uninit_var_captured_by_block : Warning<
"variable %0 may be uninitialized when captured by block">,
InGroup<UninitializedMaybe>, DefaultIgnore;
def note_var_fixit_add_initialization : Note<
"add initialization to silence this warning">;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
@ -905,7 +945,7 @@ 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"
"|in template parameter|in block literal|in template argument"
"|in typedef|in function return type|here}0">;
"|in typedef|in type alias|in function return type|here}0">;
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
def err_auto_new_requires_ctor_arg : Error<
@ -944,9 +984,6 @@ def err_final_function_overridden : Error<
def err_final_base : Error<
"derivation from 'final' %0">;
def err_function_overriding_without_override : Error<
"%0 overrides function%s1 without being marked 'override'">;
// C++0x scoped enumerations
def err_enum_invalid_underlying : Error<
"non-integral type %0 is an invalid underlying type">;
@ -969,6 +1006,34 @@ 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 err_delegating_codegen_not_implemented : Error<
"code generation for delegating constructors not implemented">;
// C++0x range-based for loop
def err_for_range_decl_must_be_var : Error<
"for range declaration must declare a variable">;
def err_for_range_storage_class : Error<
"loop variable %0 may not be declared %select{'extern'|'static'|"
"'__private_extern__'|'auto'|'register'|'constexpr'}1">;
def err_type_defined_in_for_range : Error<
"types may not be defined in a for range declaration">;
def err_for_range_deduction_failure : Error<
"cannot use type %0 as a range">;
def err_for_range_incomplete_type : Error<
"cannot use incomplete type %0 as a range">;
def err_for_range_iter_deduction_failure : Error<
"cannot use type %0 as an iterator">;
def err_for_range_member_begin_end_mismatch : Error<
"range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">;
def err_for_range_begin_end_types_differ : Error<
"'begin' and 'end' must return the same type (got %0 and %1)">;
def note_for_range_type : Note<"range has type %0">;
def note_for_range_begin_end : Note<
"selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">;
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<
@ -982,7 +1047,10 @@ def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
def err_attributes_are_not_compatible : Error<
"%0 and %1 attributes are not compatible">;
def err_attribute_wrong_number_arguments : Error<
"attribute requires %0 argument(s)">;
"attribute %plural{0:takes no arguments|1:takes one argument|"
":requires exactly %0 arguments}0">;
def err_attribute_too_many_arguments : Error<
"attribute takes no more than %0 argument%s0">;
def err_iboutletcollection_type : Error<
"invalid type %0 as argument of iboutletcollection attribute">;
def err_iboutletcollection_object_type : Error<
@ -1026,6 +1094,7 @@ def err_format_attribute_result_not : Error<"function does not return %0">;
def err_format_attribute_implicit_this_format_string : Error<
"format attribute cannot specify the implicit this argument as the format "
"string">;
def warn_unknown_method_family : Warning<"unrecognized method family">;
def err_attribute_invalid_size : Error<
"vector size not an integral multiple of component size">;
def err_attribute_zero_size : Error<"zero vector size">;
@ -1101,7 +1170,9 @@ def err_attribute_wrong_decl_type : Error<
"classes and virtual methods|functions, methods, and parameters|"
"classes|virtual methods|class members|variables|methods}1">;
def warn_function_attribute_wrong_type : Warning<
"%0 only applies to function types; type here is %1">;
"'%0' only applies to function types; type here is %1">;
def warn_pointer_attribute_wrong_type : Warning<
"'%0' only applies to pointer types; type here is %1">;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
@ -1119,6 +1190,15 @@ def err_cconv_varargs : Error<
def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
"attribute was previously declared "
"%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
def err_invalid_pcs : Error<"Invalid PCS type">;
// Availability attribute
def warn_availability_unknown_platform : Warning<
"unknown platform %0 in availability macro">;
def warn_availability_version_ordering : Warning<
"feature cannot be %select{introduced|deprecated|obsoleted}0 in %1 version "
"%2 before it was %select{introduced|deprecated|obsoleted}3 in version %4; "
"attribute ignored">;
def warn_impcast_vector_scalar : Warning<
"implicit conversion turns vector to scalar: %0 to %1">,
@ -1134,10 +1214,10 @@ def warn_impcast_float_integer : Warning<
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
"implicit conversion changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
InGroup<DiagGroup<"sign-conversion">>, DefaultIgnore;
def warn_impcast_integer_sign_conditional : Warning<
"operand of ? changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
InGroup<DiagGroup<"sign-conversion">>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
"implicit conversion loses integer precision: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
@ -1154,9 +1234,15 @@ def warn_impcast_literal_float_to_integer : Warning<
"implicit conversion turns literal floating-point number into integer: "
"%0 to %1">,
InGroup<DiagGroup<"literal-conversion">>, DefaultIgnore;
def note_fix_integral_float_as_integer : Note<
"this can be rewritten as an integer literal with the exact same value">;
def warn_impcast_different_enum_types : Warning<
"implicit conversion from enumeration type %0 to different enumeration type "
"%1">, InGroup<DiagGroup<"conversion">>;
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_cast_align : Warning<
"cast from %0 to %1 increases required alignment from %2 to %3">,
@ -1252,11 +1338,13 @@ def err_ident_list_in_fn_declaration : Error<
def ext_param_not_declared : Extension<
"parameter %0 was not declared, defaulting to type 'int'">;
def err_param_typedef_of_void : Error<
"empty parameter list defined with a typedef of 'void' not allowed in C++">;
"empty parameter list defined with a %select{typedef|type alias}0 of 'void' not allowed%select{ in C++|}0">;
def err_param_default_argument : Error<
"C does not support default arguments">;
def err_param_default_argument_redefinition : Error<
"redefinition of default argument">;
def warn_param_default_argument_redefinition : ExtWarn<
"redefinition of default argument">;
def err_param_default_argument_missing : Error<
"missing default argument on parameter">;
def err_param_default_argument_missing_name : Error<
@ -1311,11 +1399,11 @@ def err_ovl_no_viable_member_function_in_call : Error<
def err_ovl_ambiguous_call : Error<
"call to %0 is ambiguous">;
def err_ovl_deleted_call : Error<
"call to %select{unavailable|deleted}0 function %1 %2">;
"call to %select{unavailable|deleted}0 function %1%2">;
def err_ovl_ambiguous_member_call : Error<
"call to member function %0 is ambiguous">;
def err_ovl_deleted_member_call : Error<
"call to %select{unavailable|deleted}0 member function %1 %2">;
"call to %select{unavailable|deleted}0 member function %1%2">;
def note_ovl_too_many_candidates : Note<
"remaining %0 candidate%s0 omitted; "
"pass -fshow-overloads=all to show them">;
@ -1327,10 +1415,6 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit copy assignment operator|"
"is an inherited constructor}0%1">;
def warn_init_pointer_from_false : Warning<
"initialization of pointer of type %0 from literal 'false'">,
InGroup<BoolConversions>;
def note_ovl_candidate_inherited_constructor : Note<"inherited from here">;
def note_ovl_candidate_bad_deduction : Note<
"candidate template ignored: failed template argument deduction">;
@ -1408,6 +1492,15 @@ def note_ovl_candidate_bad_addrspace : Note<"candidate "
"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">;
def note_ovl_candidate_bad_gc : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
"constructor (the implicit default constructor)|"
"constructor (the implicit copy constructor)|"
"function (the implicit copy assignment operator)|"
"constructor (inherited)}0%1 not viable: "
"%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 "
"lifetime, but parameter has %select{no|__weak|__strong}4 lifetime">;
def note_ovl_candidate_bad_cvr_this : Note<"candidate "
"%select{|function|||function||||"
"function (the implicit copy assignment operator)|}0 not viable: "
@ -1467,13 +1560,13 @@ def err_ovl_ambiguous_oper_binary : Error<
"use of overloaded operator '%0' is ambiguous (with operand types %1 and %2)">;
def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
def err_ovl_deleted_oper : Error<
"overload resolution selected %select{unavailable|deleted}0 operator '%1' %2">;
"overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
def err_ovl_no_viable_subscript :
Error<"no viable overloaded operator[] for type %0">;
def err_ovl_no_oper :
Error<"type %0 does not provide a %select{subscript|call}1 operator">;
def err_ovl_unresolvable :
Error<"cannot resolve overloaded function from context">;
Error<"cannot resolve overloaded function %0 from context">;
def err_ovl_no_viable_object_call : Error<
@ -1481,7 +1574,7 @@ def err_ovl_no_viable_object_call : Error<
def err_ovl_ambiguous_object_call : Error<
"call to object of type %0 is ambiguous">;
def err_ovl_deleted_object_call : Error<
"call to %select{unavailable|deleted}0 function call operator in type %1 %2">;
"call to %select{unavailable|deleted}0 function call operator in type %1%2">;
def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
def err_member_call_without_object : Error<
"call to non-static member function without an object argument">;
@ -1707,6 +1800,8 @@ def err_template_spec_default_arg : Error<
def err_not_class_template_specialization : Error<
"cannot specialize a %select{dependent template|template template "
"parameter}0">;
def err_function_specialization_in_class : Error<
"cannot specialize a function %0 within class scope">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@ -1777,6 +1872,9 @@ def err_template_recursion_depth_exceeded : Error<
def note_template_recursion_depth : Note<
"use -ftemplate-depth-N to increase recursive template instantiation depth">;
def err_template_instantiate_within_definition : Error<
"%select{implicit|explicit}0 instantiation of template %1 within its"
" own definition">;
def err_template_instantiate_undefined : Error<
"%select{implicit|explicit}0 instantiation of undefined template %1">;
def err_implicit_instantiate_member_undefined : Error<
@ -1900,6 +1998,8 @@ def note_typename_refers_here : Note<
"referenced member %0 is declared here">;
def err_typename_missing : Error<
"missing 'typename' prior to dependent type name '%0%1'">;
def warn_typename_missing : ExtWarn<
"missing 'typename' prior to dependent type name '%0%1'">;
def ext_typename_outside_of_template : ExtWarn<
"'typename' occurs outside of a template">, InGroup<CXX0x>;
def err_typename_refers_to_using_value_decl : Error<
@ -1921,6 +2021,14 @@ def err_template_kw_missing : Error<
def ext_template_outside_of_template : ExtWarn<
"'template' keyword outside of a template">, InGroup<CXX0x>;
def err_non_type_template_in_nested_name_specifier : Error<
"qualified name refers into a specialization of function template '%0'">;
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 "
"%1 declared here">;
// C++0x Variadic Templates
def err_template_param_pack_default_arg : Error<
"template parameter pack cannot have a default argument">;
@ -2039,6 +2147,8 @@ def err_inline_declaration_block_scope : Error<
"inline declaration of %0 not allowed in block scope">;
def err_static_non_static : Error<
"static declaration of %0 follows non-static declaration">;
def warn_static_non_static : ExtWarn<
"static declaration of %0 follows non-static declaration">;
def err_non_static_static : Error<
"non-static declaration of %0 follows static declaration">;
def err_extern_non_extern : Error<
@ -2054,17 +2164,17 @@ 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<
"typedef redefinition with different types (%0 vs %1)">;
"%select{typedef|type alias}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 template}0">;
"elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template}0">;
def err_tag_reference_conflict : Error<
"implicit declaration introduced by elaborated type conflicts with "
"%select{a declaration|a typedef|a template}0 of the same name">;
"%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
def err_dependent_tag_decl : Error<
"%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
"in a dependent scope">;
def err_tag_definition_of_typedef : Error<
"definition of type %0 conflicts with typedef of the same name">;
"definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">;
def err_conflicting_types : Error<"conflicting types for %0">;
def err_nested_redefinition : Error<"nested redefinition of %0">;
def err_use_with_wrong_tag : Error<
@ -2154,6 +2264,8 @@ def err_excess_initializers_in_char_array_initializer : Error<
"excess elements in char array initializer">;
def warn_excess_initializers_in_char_array_initializer : ExtWarn<
"excess elements in char array initializer">;
def err_initializer_string_for_char_array_too_long : Error<
"initializer-string for char array is too long">;
def warn_initializer_string_for_char_array_too_long : ExtWarn<
"initializer-string for char array is too long">;
def warn_missing_field_initializers : Warning<
@ -2180,6 +2292,8 @@ def err_bitfield_width_exceeds_type_size : Error<
"size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">;
def err_anon_bitfield_width_exceeds_type_size : Error<
"size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
def err_incorrect_number_of_vector_initializers : Error<
"number of elements must be either one or match the size of the vector">;
// Used by C++ which allows bit-fields that are wider than the type.
def warn_bitfield_width_exceeds_type_size: Warning<
@ -2212,6 +2326,8 @@ def note_protected_by_cleanup : Note<
"jump bypasses initialization of variable with __attribute__((cleanup))">;
def note_protected_by_vla_typedef : Note<
"jump bypasses initialization of VLA typedef">;
def note_protected_by_vla_type_alias : Note<
"jump bypasses initialization of VLA type alias">;
def note_protected_by_vla : Note<
"jump bypasses initialization of variable length array">;
def note_protected_by_objc_try : Note<
@ -2266,12 +2382,17 @@ def ext_flexible_array_in_array : Extension<
"%0 may not be used as an array element due to flexible array member">;
def err_flexible_array_init_nonempty : Error<
"non-empty initialization of flexible array member inside subobject">;
def ext_flexible_array_empty_aggregate : Extension<
def ext_flexible_array_empty_aggregate_ms : Extension<
"flexible array member %0 in otherwise empty %select{struct|class}1 "
"is a Microsoft extension">, InGroup<Microsoft>;
def ext_flexible_array_union : Extension<
def ext_flexible_array_union_ms : Extension<
"flexible array member %0 in a union is a Microsoft extension">,
InGroup<Microsoft>;
def ext_flexible_array_empty_aggregate_gnu : Extension<
"flexible array member %0 in otherwise empty %select{struct|class}1 "
"is a GNU extension">, InGroup<GNU>;
def ext_flexible_array_union_gnu : Extension<
"flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
def err_flexible_array_init_needs_braces : Error<
"flexible array requires brace-enclosed initializer">;
@ -2314,14 +2435,18 @@ def err_func_def_incomplete_result : Error<
def ext_sizeof_function_type : Extension<
"invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
def err_sizeof_alignof_overloaded_function_type : Error<
"invalid application of '%select{sizeof|__alignof}0' to an overloaded "
"function">;
"invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
"overloaded function">;
def ext_sizeof_void_type : Extension<
"invalid application of '%0' to a void type">, InGroup<PointerArith>;
"invalid application of '%select{sizeof|__alignof|vec_step}0' to a void "
"type">, InGroup<PointerArith>;
def err_sizeof_alignof_incomplete_type : Error<
"invalid application of '%select{sizeof|__alignof}0' to an incomplete type %1">;
"invalid application of '%select{sizeof|__alignof|vec_step}0' to an "
"incomplete type %1">;
def err_sizeof_alignof_bitfield : Error<
"invalid application of '%select{sizeof|__alignof}0' to bit-field">;
def err_vecstep_non_scalar_vector_type : Error<
"'vec_step' requires built-in scalar or vector type, %0 invalid">;
def err_offsetof_incomplete_type : Error<
"offsetof of incomplete type %0">;
def err_offsetof_record_type : Error<
@ -2417,6 +2542,11 @@ def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
def err_no_member : Error<"no member named %0 in %1">;
def err_member_not_yet_instantiated : Error<
"no member %0 in %1; it has not yet been instantiated">;
def note_non_instantiated_member_here : Note<
"not-yet-instantiated member is declared here">;
def err_member_redeclared : Error<"class member cannot be redeclared">;
def err_member_name_of_class : Error<"member %0 has the same name as its class">;
def err_member_def_undefined_record : Error<
@ -2483,6 +2613,7 @@ def err_typecheck_sclass_fscope : Error<
"illegal storage class on file-scoped variable">;
def err_unsupported_global_register : Error<
"global register variables are not supported">;
def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">;
def err_typecheck_sclass_func : Error<"illegal storage class on function">;
def err_static_block_func : Error<
"function declared in block scope cannot have 'static' storage class">;
@ -2618,6 +2749,8 @@ def err_ref_array_type : Error<
"cannot refer to declaration with an array type inside block">;
def err_property_not_found : Error<
"property %0 not found on object of type %1">;
def err_invalid_property_name : Error<
"%0 is not a valid property name (accessing an object of type %1)">;
def err_getter_not_found : Error<
"expected getter method not found on object of type %0">;
def err_property_not_found_forward_class : Error<
@ -2636,6 +2769,8 @@ def ext_gnu_ptr_func_arith : Extension<
InGroup<PointerArith>;
def error_readonly_property_assignment : Error<
"assigning to property with 'readonly' attribute not allowed">;
def error_readonly_message_assignment : Error<
"assigning to 'readonly' return result of an objective-c message not allowed">;
def ext_integer_increment_complex : Extension<
"ISO C does not support '++'/'--' on complex integer type %0">;
def ext_integer_complement_complex : Extension<
@ -2655,9 +2790,11 @@ def err_imaginary_not_supported : Error<"imaginary types are not supported">;
def warn_root_inst_method_not_found : Warning<
"instance method %0 is being used on 'Class' which is not in the root class">;
def warn_class_method_not_found : Warning<
"method %objcclass0 not found (return type defaults to 'id')">;
"class method %objcclass0 not found (return type defaults to 'id')">;
def warn_instance_method_on_class_found : Warning<
"instance method %0 found instead of class method %1">;
def warn_inst_method_not_found : Warning<
"method %objcinstance0 not found (return type defaults to 'id')">;
"instance method %objcinstance0 not found (return type defaults to 'id')">;
def error_no_super_class_message : Error<
"no @interface declaration found in class messaging of %0">;
def error_root_class_cannot_use_super : Error<
@ -2735,9 +2872,9 @@ def err_bad_cxx_cast_generic : Error<
def err_bad_cxx_cast_rvalue : Error<
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
"functional-style cast}0 from rvalue to reference type %2">;
def err_bad_cxx_cast_const_away : Error<
def err_bad_cxx_cast_qualifiers_away : Error<
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
"functional-style cast}0 from %1 to %2 casts away constness">;
"functional-style cast}0 from %1 to %2 casts away qualifiers">;
def err_bad_const_cast_dest : Error<
"%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
@ -2765,6 +2902,8 @@ def err_bad_cxx_cast_member_pointer_size : Error<
"cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer "
"type %1 to member pointer type %2 of different size">;
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">;
// These messages don't adhere to the pattern.
// FIXME: Display the path somehow better.
@ -2823,7 +2962,11 @@ def ext_array_size_conversion : Extension<
"implicit conversion from array size expression of type %0 to "
"%select{integral|enumeration}1 type %2 is a C++0x extension">,
InGroup<CXX0x>;
def err_address_space_qualified_new : Error<
"'new' cannot allocate objects of type %0 in address space '%1'">;
def err_address_space_qualified_delete : Error<
"'delete' cannot delete objects of type %0 in address space '%1'">;
def err_default_init_const : Error<
"default initialization of an object of const type %0"
"%select{| requires a user-provided default constructor}1">;
@ -2878,6 +3021,9 @@ def warn_overloaded_virtual : Warning<
InGroup<OverloadedVirtual>, DefaultIgnore;
def note_hidden_overloaded_virtual_declared_here : Note<
"hidden overloaded virtual function %q0 declared here">;
def warn_using_directive_in_header : Warning<
"using namespace directive in global context in header">,
InGroup<HeaderHygiene>, DefaultIgnore;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
@ -3067,11 +3213,6 @@ def err_typecheck_incompatible_address_space : Error<
" changes address space of pointer">;
def err_typecheck_convert_ambiguous : Error<
"ambiguity in initializing value of type %0 with initializer of type %1">;
def err_cannot_initialize_decl_noname : Error<
"cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
"of type %2">;
def err_cannot_initialize_decl : Error<
"cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
def err_typecheck_comparison_of_distinct_blocks : Error<
"comparison of distinct block types (%0 and %1)">;
@ -3109,6 +3250,8 @@ def err_typecheck_call_too_few_args_at_least : Error<
def err_typecheck_call_too_many_args : Error<
"too many arguments to %select{function|block|method}0 call, "
"expected %1, have %2">;
def note_typecheck_call_too_many_args : Note<
"%0 declared here">;
def err_typecheck_call_too_many_args_at_most : Error<
"too many arguments to %select{function|block|method}0 call, "
"expected at most %1, have %2">;
@ -3196,6 +3339,8 @@ def warn_unused_call : Warning<
def err_incomplete_type_used_in_type_trait_expr : Error<
"incomplete type %0 used in type trait expression">;
def err_dimension_expr_not_constant_integer : Error<
"dimension expression does not evaluate to a constant unsigned int">;
def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
def err_typecheck_cond_incompatible_operands_null : Error<
@ -3278,7 +3423,7 @@ def err_in_class_initializer_bad_type : Error<
"static data member of type %0 must be initialized out of line">;
def ext_in_class_initializer_float_type : ExtWarn<
"in-class initializer for static data member of type %0 "
"is a C++0x extension">, InGroup<CXX0x>;
"is a C++0x extension">, InGroup<CXX0xStaticNonIntegralInitializer>;
def err_in_class_initializer_non_constant : Error<
"in-class initializer is not a constant expression">;
@ -3544,6 +3689,21 @@ def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use strncmp instead)">;
// Generic selections.
def err_assoc_type_incomplete : Error<
"type %0 in generic association incomplete">;
def err_assoc_type_nonobject : Error<
"type %0 in generic association not an object type">;
def err_assoc_type_variably_modified : Error<
"type %0 in generic association is a variably modified type">;
def err_assoc_compatible_types : Error<
"type %0 in generic association compatible with previously specified type %1">;
def note_compat_assoc : Note<
"compatible type %0 specified here">;
def err_generic_sel_no_match : Error<
"controlling expression type %0 not compatible with any generic association type">;
def err_generic_sel_multi_match : Error<
"controlling expression type %0 compatible with %1 generic association types">;
// Blocks
@ -3559,8 +3719,6 @@ def err_block_returning_array_function : Error<
// CFString checking
def err_cfstring_literal_not_string_constant : Error<
"CFString literal is not a string constant">;
def warn_cfstring_literal_contains_nul_character : Warning<
"CFString literal contains NUL character">;
def warn_cfstring_truncated : Warning<
"input conversion stopped due to an input byte that does not "
"belong to the input codeset UTF-8">;
@ -3722,6 +3880,8 @@ def warn_ivar_use_hidden : Warning<
"local declaration of %0 hides instance variable">;
def error_ivar_use_in_class_method : Error<
"instance variable %0 accessed in class method">;
def error_implicit_ivar_access : Error<
"instance variable %0 cannot be accessed because 'self' has been redeclared">;
def error_private_ivar_access : Error<"instance variable %0 is private">,
AccessControl;
def error_protected_ivar_access : Error<"instance variable %0 is protected">,
@ -3776,6 +3936,26 @@ def err_sizeof_pack_no_pack_name_suggest : Error<
"%0 does not refer to the name of a parameter pack; did you mean %1?">;
def note_parameter_pack_here : Note<"parameter pack %0 declared here">;
def err_uncasted_use_of_unknown_any : Error<
"%0 has unknown type; cast it to its declared type to use it">;
def err_uncasted_call_of_unknown_any : Error<
"%0 has unknown return type; cast the call to its declared return type">;
def err_unsupported_unknown_any_decl : Error<
"%0 has unknown type, which is unsupported for this kind of declaration">;
def err_unsupported_unknown_any_expr : Error<
"unsupported expression with unknown type">;
def err_unsupported_unknown_any_call : Error<
"call to unsupported expression with unknown type">;
def err_unknown_any_addrof : Error<
"the address of a declaration with unknown type "
"can only be cast to a pointer type">;
def err_unknown_any_var_function_type : Error<
"variable %0 with unknown type cannot be given a function type">;
def err_filter_expression_integral : Error<
"filter expression type should be an integral value not %0">;
} // end of sema category
} // end of sema component.

View File

@ -0,0 +1,39 @@
//===--- ExceptionSpecificationType.h ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the ExceptionSpecificationType enumeration and various
// utility functions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
#define LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H
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)
};
inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) {
return ESpecType >= EST_DynamicNone && ESpecType <= EST_MSAny;
}
inline bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType) {
return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept;
}
} // end namespace clang
#endif // LLVM_CLANG_BASIC_EXCEPTIONSPECIFICATIONTYPE_H

View File

@ -0,0 +1,25 @@
//===--- ExpressionTraits.h - C++ Expression Traits Support Enumerations ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines enumerations for expression traits intrinsics.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_EXPRESSIONTRAITS_H
#define LLVM_CLANG_EXPRESSIONTRAITS_H
namespace clang {
enum ExpressionTrait {
ET_IsLValueExpr,
ET_IsRValueExpr
};
}
#endif

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_FILEMANAGER_H
#include "clang/Basic/FileSystemOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@ -105,7 +106,7 @@ class FileEntry {
/// properties, such as uniquing files based on "inode", so that a file with two
/// names (e.g. symlinked) will be treated as a single file.
///
class FileManager {
class FileManager : public llvm::RefCountedBase<FileManager> {
FileSystemOptions FileSystemOpts;
class UniqueDirContainer;
@ -176,10 +177,11 @@ class FileManager {
///
const DirectoryEntry *getDirectory(llvm::StringRef DirName);
/// getFile - Lookup, cache, and verify the specified file (real or
/// \brief Lookup, cache, and verify the specified file (real or
/// virtual). This returns NULL if the file doesn't exist.
///
const FileEntry *getFile(llvm::StringRef Filename);
/// \param openFile if true and the file exists, it will be opened.
const FileEntry *getFile(llvm::StringRef Filename, bool openFile = false);
/// \brief Retrieve a file entry for a "virtual" file that acts as
/// if there were a file with the given name on disk. The file
@ -194,13 +196,16 @@ class FileManager {
llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename,
std::string *ErrorStr = 0);
// getNoncachedStatValue - Will get the 'stat' information for the given path.
// If the path is relative, it will be resolved against the WorkingDir of the
// FileManager's FileSystemOptions.
bool getNoncachedStatValue(llvm::StringRef Path, struct stat &StatBuf);
/// \brief If path is not absolute and FileSystemOptions set the working
/// directory, the path is modified to be relative to the given
/// working directory.
static void FixupRelativePath(llvm::sys::Path &path,
const FileSystemOptions &FSOpts);
void FixupRelativePath(llvm::SmallVectorImpl<char> &path) const;
/// \brief Produce an array mapping from the unique IDs assigned to each
/// file to the corresponding FileEntry pointer.
void GetUniqueIDMapping(

View File

@ -255,6 +255,25 @@ class IdentifierInfo {
}
};
/// \brief an RAII object for [un]poisoning an identifier
/// within a certain scope. II is allowed to be null, in
/// which case, objects of this type have no effect.
class PoisonIdentifierRAIIObject {
IdentifierInfo *const II;
const bool OldValue;
public:
PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
: II(II), OldValue(II ? II->isPoisoned() : false) {
if(II)
II->setIsPoisoned(NewValue);
}
~PoisonIdentifierRAIIObject() {
if(II)
II->setIsPoisoned(OldValue);
}
};
/// \brief An iterator that walks over all of the known identifiers
/// in the lookup table.
///
@ -325,7 +344,7 @@ class ExternalIdentifierLookup {
/// IdentifierTable - This table implements an efficient mapping from strings to
/// IdentifierInfo nodes. It has no other purpose, but this is an
/// extremely performance-critical piece of the code, as each occurrance of
/// extremely performance-critical piece of the code, as each occurrence of
/// every identifier goes through here when lexed.
class IdentifierTable {
// Shark shows that using MallocAllocator is *much* slower than using this
@ -443,6 +462,52 @@ class IdentifierTable {
void AddKeywords(const LangOptions &LangOpts);
};
/// ObjCMethodFamily - A family of Objective-C methods. These
/// families have no inherent meaning in the language, but are
/// nonetheless central enough in the existing implementations to
/// merit direct AST support. While, in theory, arbitrary methods can
/// be considered to form families, we focus here on the methods
/// involving allocation and retain-count management, as these are the
/// most "core" and the most likely to be useful to diverse clients
/// without extra information.
///
/// Both selectors and actual method declarations may be classified
/// into families. Method families may impose additional restrictions
/// beyond their selector name; for example, a method called '_init'
/// that returns void is not considered to be in the 'init' family
/// (but would be if it returned 'id'). It is also possible to
/// explicitly change or remove a method's family. Therefore the
/// method's family should be considered the single source of truth.
enum ObjCMethodFamily {
/// \brief No particular method family.
OMF_None,
// Selectors in these families may have arbitrary arity, may be
// written with arbitrary leading underscores, and may have
// additional CamelCase "words" in their first selector chunk
// following the family name.
OMF_alloc,
OMF_copy,
OMF_init,
OMF_mutableCopy,
OMF_new,
// These families are singletons consisting only of the nullary
// selector with the given name.
OMF_autorelease,
OMF_dealloc,
OMF_release,
OMF_retain,
OMF_retainCount
};
/// Enough bits to store any enumerator in ObjCMethodFamily or
/// InvalidObjCMethodFamily.
enum { ObjCMethodFamilyBitWidth = 4 };
/// An invalid value of ObjCMethodFamily.
enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 };
/// Selector - This smart pointer class efficiently represents Objective-C
/// method names. This class will either point to an IdentifierInfo or a
/// MultiKeywordSelector (which is private). This enables us to optimize
@ -479,6 +544,8 @@ class Selector {
return InfoPtr & ArgFlags;
}
static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
public:
friend class SelectorTable; // only the SelectorTable can create these
friend class DeclarationName; // and the AST's DeclarationName.
@ -541,6 +608,11 @@ class Selector {
/// it as an std::string.
std::string getAsString() const;
/// getMethodFamily - Derive the conventional family of this method.
ObjCMethodFamily getMethodFamily() const {
return getMethodFamilyImpl(*this);
}
static Selector getEmptyMarker() {
return Selector(uintptr_t(-1));
}
@ -571,6 +643,9 @@ class SelectorTable {
return Selector(ID, 0);
}
/// Return the total amount of memory allocated for managing selectors.
size_t getTotalMemory() const;
/// constructSetterName - Return the setter name for the given
/// identifier, i.e. "set" + Name where the initial character of Name
/// has been capitalized.

View File

@ -34,6 +34,7 @@ class LangOptions {
unsigned Digraphs : 1; // C94, C99 and C++
unsigned HexFloats : 1; // C99 Hexadecimal float constants.
unsigned C99 : 1; // C99 Support
unsigned C1X : 1; // C1X Support
unsigned Microsoft : 1; // Microsoft extensions.
unsigned Borland : 1; // Borland extensions.
unsigned CPlusPlus : 1; // C++ Support
@ -56,6 +57,7 @@ class LangOptions {
unsigned ObjCExceptions : 1; // Support Objective-C exceptions.
unsigned CXXExceptions : 1; // Support C++ exceptions.
unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling.
unsigned TraditionalCPP : 1; /// Enable some traditional CPP emulation.
unsigned RTTI : 1; // Support RTTI information.
unsigned MSBitfields : 1; // MS-compatible structure layout
@ -87,6 +89,8 @@ class LangOptions {
// used (instead of C99 semantics).
unsigned NoInline : 1; // Should __NO_INLINE__ be defined.
unsigned Deprecated : 1; // Should __DEPRECATED be defined.
unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout
// for __weak/__strong ivars.
@ -112,6 +116,7 @@ class LangOptions {
unsigned NoConstantCFStrings : 1; // Do not do CF strings
unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have
// hidden visibility by default.
unsigned ParseUnknownAnytype: 1; /// Let the user write __unknown_anytype.
unsigned SpellChecking : 1; // Whether to perform spell-checking for error
// recovery.
@ -123,6 +128,11 @@ class LangOptions {
unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT
// FIXME: This is just a temporary option, for testing purposes.
unsigned NoBitFieldTypeAlign : 1;
unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for
// testing languages such as OpenCL.
unsigned MRTD : 1; // -mrtd calling convention
unsigned DelayedTemplateParsing : 1; // Delayed template parsing
private:
// We declare multibit enums as unsigned because MSVC insists on making enums
@ -164,10 +174,10 @@ class LangOptions {
AppleKext = 0;
ObjCDefaultSynthProperties = 0;
NoConstantCFStrings = 0; InlineVisibilityHidden = 0;
C99 = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
Exceptions = ObjCExceptions = CXXExceptions = SjLjExceptions = 0;
Freestanding = NoBuiltin = 0;
TraditionalCPP = Freestanding = NoBuiltin = 0;
MSBitfields = 0;
NeXTRuntime = 1;
RTTI = 1;
@ -205,6 +215,8 @@ class LangOptions {
GNUInline = 0;
NoInline = 0;
Deprecated = 0;
CharIsSigned = 1;
ShortWChar = 0;
ShortEnums = 0;
@ -216,6 +228,10 @@ class LangOptions {
FastRelaxedMath = 0;
DefaultFPContract = 0;
NoBitFieldTypeAlign = 0;
FakeAddressSpaceMap = 0;
MRTD = 0;
DelayedTemplateParsing = 0;
ParseUnknownAnytype = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }
@ -240,8 +256,8 @@ class LangOptions {
SignedOverflowBehavior = (unsigned)V;
}
bool areExceptionsEnabled() const {
return Exceptions;
bool isSignedOverflowDefined() const {
return getSignedOverflowBehavior() == SOB_Defined;
}
};

View File

@ -4,7 +4,7 @@ BUILT_SOURCES = \
DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \
DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
DiagnosticGroups.inc AttrList.inc arm_neon.inc \
DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \
Version.inc
TABLEGEN_INC_FILES_COMMON = 1
@ -33,6 +33,10 @@ $(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN)
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
$(ObjDir)/DiagnosticIndexName.inc.tmp : Diagnostic.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang diagnostic name index with tblgen"
$(Verb) $(TableGen) -gen-clang-diags-index-name -o $(call SYSPATH, $@) $<
$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang diagnostic groups with tblgen"
$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<

View File

@ -0,0 +1,28 @@
//===--- OpenCL.h - OpenCL enums --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some OpenCL-specific enums.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_OPENCL_H
#define LLVM_CLANG_BASIC_OPENCL_H
namespace clang {
/// Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
enum OpenCLImageAccess {
CLIA_read_only = 1,
CLIA_write_only = 2,
CLIA_read_write = 3
};
}
#endif

View File

@ -53,7 +53,7 @@ class PartialDiagnostic {
/// DiagArgumentsVal - The values for the various substitution positions.
/// This is used when the argument is not an std::string. The specific value
/// is mangled into an intptr_t and the intepretation depends on exactly
/// is mangled into an intptr_t and the interpretation depends on exactly
/// what sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];

View File

@ -16,6 +16,7 @@
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <utility>
#include <functional>
#include <cassert>
namespace llvm {
@ -295,6 +296,14 @@ class FullSourceLoc : public SourceLocation {
return isBeforeInTranslationUnitThan((SourceLocation)Loc);
}
/// \brief Comparison function class, useful for sorting FullSourceLocs.
struct BeforeThanCompare : public std::binary_function<FullSourceLoc,
FullSourceLoc, bool> {
bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
return lhs.isBeforeInTranslationUnitThan(rhs);
}
};
/// Prints information about this FullSourceLoc to stderr. Useful for
/// debugging.
void dump() const { SourceLocation::dump(*SrcMgr); }

View File

@ -19,12 +19,13 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
#include <cassert>
namespace llvm {
class MemoryBuffer;
class StringRef;
}
@ -66,10 +67,16 @@ namespace SrcMgr {
mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
public:
/// Reference to the file entry. This reference does not own
/// the FileEntry object. It is possible for this to be NULL if
/// Reference to the file entry representing this ContentCache.
/// This reference does not own the FileEntry object.
/// It is possible for this to be NULL if
/// the ContentCache encapsulates an imaginary text buffer.
const FileEntry *Entry;
const FileEntry *OrigEntry;
/// \brief References the file which the contents were actually loaded from.
/// Can be different from 'Entry' if we overridden the contents of one file
/// with the contents of another file.
const FileEntry *ContentsEntry;
/// SourceLineCache - A bump pointer allocated array of offsets for each
/// source line. This is lazily computed. This is owned by the
@ -104,6 +111,10 @@ namespace SrcMgr {
/// this ContentCache. This can be 0 if the MemBuffer was not actually
/// instantiated.
unsigned getSizeBytesMapped() const;
/// Returns the kind of memory used to back the memory buffer for
/// this content cache. This is used for performance analysis.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
void setBuffer(const llvm::MemoryBuffer *B) {
assert(!Buffer.getPointer() && "MemoryBuffer already set.");
@ -132,17 +143,23 @@ namespace SrcMgr {
}
ContentCache(const FileEntry *Ent = 0)
: Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {}
: Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
SourceLineCache(0), NumLines(0) {}
ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
: Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
SourceLineCache(0), NumLines(0) {}
~ContentCache();
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transfered, so this is a logical error.
/// is not transferred, so this is a logical error.
ContentCache(const ContentCache &RHS)
: Buffer(0, false), SourceLineCache(0)
{
Entry = RHS.Entry;
OrigEntry = RHS.OrigEntry;
ContentsEntry = RHS.ContentsEntry;
assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0
&& "Passed ContentCache object cannot own a buffer.");
@ -301,7 +318,10 @@ class ExternalSLocEntrySource {
virtual ~ExternalSLocEntrySource();
/// \brief Read the source location entry with index ID.
virtual void ReadSLocEntry(unsigned ID) = 0;
///
/// \returns true if an error occurred that prevented the source-location
/// entry from being loaded.
virtual bool ReadSLocEntry(unsigned ID) = 0;
};
@ -364,9 +384,9 @@ class IsBeforeInTranslationUnitCache {
/// Spelling locations represent where the bytes corresponding to a token came
/// from and instantiation locations represent where the location is in the
/// user's view. In the case of a macro expansion, for example, the spelling
/// location indicates where the expanded token came from and the instantiation
/// location indicates where the expanded token came from and the instantiation
/// location specifies where it was expanded.
class SourceManager {
class SourceManager : public llvm::RefCountedBase<SourceManager> {
/// \brief Diagnostic object.
Diagnostic &Diag;
@ -380,6 +400,13 @@ class SourceManager {
/// non-null, FileEntry pointers.
llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
/// \brief True if the ContentCache for files that are overriden by other
/// files, should report the original file name. Defaults to true.
bool OverridenFilesKeepOriginalName;
/// \brief Files that have been overriden with the contents from another file.
llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
/// MemBufferInfos - Information about various memory buffers that we have
/// read in. All FileEntry* within the stored ContentCache objects are NULL,
/// as they do not refer to a file.
@ -425,6 +452,9 @@ class SourceManager {
// Cache results for the isBeforeInTranslationUnit method.
mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
// Cache for the "fake" buffer used for error-recovery purposes.
mutable llvm::MemoryBuffer *FakeBufferForRecovery;
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&);
void operator=(const SourceManager&);
@ -438,6 +468,12 @@ class SourceManager {
FileManager &getFileManager() const { return FileMgr; }
/// \brief Set true if the SourceManager should report the original file name
/// for contents of files that were overriden by other files.Defaults to true.
void setOverridenFilesKeepOriginalName(bool value) {
OverridenFilesKeepOriginalName = value;
}
//===--------------------------------------------------------------------===//
// MainFileID creation and querying methods.
//===--------------------------------------------------------------------===//
@ -527,6 +563,15 @@ class SourceManager {
const llvm::MemoryBuffer *Buffer,
bool DoNotFree = false);
/// \brief Override the the given source file with another one.
///
/// \param SourceFile the source file which will be overriden.
///
/// \param NewFile the file whose contents will be used as the
/// data instead of the contents of the given source file.
void overrideFileContents(const FileEntry *SourceFile,
const FileEntry *NewFile);
//===--------------------------------------------------------------------===//
// FileID manipulation methods.
//===--------------------------------------------------------------------===//
@ -536,18 +581,48 @@ class SourceManager {
/// buffer and returns a non-empty error string.
const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
bool *Invalid = 0) const {
return getSLocEntry(FID).getFile().getContentCache()
->getBuffer(Diag, *this, Loc, Invalid);
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
if (Invalid)
*Invalid = true;
return getFakeBufferForRecovery();
}
return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc,
Invalid);
}
const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
return getSLocEntry(FID).getFile().getContentCache()
->getBuffer(Diag, *this, SourceLocation(), Invalid);
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
if (Invalid)
*Invalid = true;
return getFakeBufferForRecovery();
}
return Entry.getFile().getContentCache()->getBuffer(Diag, *this,
SourceLocation(),
Invalid);
}
/// getFileEntryForID - Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
return getSLocEntry(FID).getFile().getContentCache()->Entry;
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile())
return 0;
return Entry.getFile().getContentCache()->OrigEntry;
}
/// Returns the FileEntry record for the provided SLocEntry.
const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
{
return sloc.getFile().getContentCache()->OrigEntry;
}
/// getBufferData - Return a StringRef to the source buffer data for the
@ -581,8 +656,12 @@ class SourceManager {
/// first byte of the specified file.
SourceLocation getLocForStartOfFile(FileID FID) const {
assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
assert(getSLocEntry(FID).isFile() && "FileID is not a file");
unsigned FileOffset = getSLocEntry(FID).getOffset();
bool Invalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
if (Invalid || !Entry.isFile())
return SourceLocation();
unsigned FileOffset = Entry.getOffset();
return SourceLocation::getFileLoc(FileOffset);
}
@ -774,6 +853,28 @@ class SourceManager {
/// \brief Retrieve the stored line table.
LineTableInfo &getLineTable();
//===--------------------------------------------------------------------===//
// Queries for performance analysis.
//===--------------------------------------------------------------------===//
/// Return the total amount of physical memory allocated by the
/// ContentCache allocator.
size_t getContentCacheSize() const {
return ContentCacheAlloc.getTotalMemory();
}
struct MemoryBufferSizes {
const size_t malloc_bytes;
const size_t mmap_bytes;
MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
: malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
};
/// Return the amount of memory used by memory buffers, breaking down
/// by heap-backed versus mmap'ed memory.
MemoryBufferSizes getMemoryBufferSizes() const;
//===--------------------------------------------------------------------===//
// Other miscellaneous methods.
//===--------------------------------------------------------------------===//
@ -810,17 +911,22 @@ class SourceManager {
// any other external source).
unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
const SrcMgr::SLocEntry &getSLocEntry(unsigned ID, bool *Invalid = 0) const {
assert(ID < SLocEntryTable.size() && "Invalid id");
// If we haven't loaded this source-location entry from the external source
// yet, do so now.
if (ExternalSLocEntries &&
ID < SLocEntryLoaded.size() &&
!SLocEntryLoaded[ID])
ExternalSLocEntries->ReadSLocEntry(ID);
!SLocEntryLoaded[ID] &&
ExternalSLocEntries->ReadSLocEntry(ID) &&
Invalid)
*Invalid = true;
return SLocEntryTable[ID];
}
const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
return getSLocEntry(FID.ID);
const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const {
return getSLocEntry(FID.ID, Invalid);
}
unsigned getNextOffset() const { return NextOffset; }
@ -836,6 +942,8 @@ class SourceManager {
void ClearPreallocatedSLocEntries();
private:
const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
/// isOffsetInFileID - Return true if the specified FileID contains the
/// specified SourceLocation offset. This is a very hot method.
inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const {

View File

@ -55,6 +55,7 @@ namespace clang {
TST_typeofExpr,
TST_decltype, // C++0x decltype
TST_auto, // C++0x auto
TST_unknown_anytype, // __unknown_anytype extension
TST_error // erroneous type
};

View File

@ -41,6 +41,7 @@ def ObjCForCollectionStmt : Stmt;
// C++ statments
def CXXCatchStmt : Stmt;
def CXXTryStmt : Stmt;
def CXXForRangeStmt : Stmt;
// Expressions
def Expr : Stmt<1>;
@ -54,7 +55,7 @@ def CharacterLiteral : DStmt<Expr>;
def ParenExpr : DStmt<Expr>;
def UnaryOperator : DStmt<Expr>;
def OffsetOfExpr : DStmt<Expr>;
def SizeOfAlignOfExpr : DStmt<Expr>;
def UnaryExprOrTypeTraitExpr : DStmt<Expr>;
def ArraySubscriptExpr : DStmt<Expr>;
def CallExpr : DStmt<Expr>;
def MemberExpr : DStmt<Expr>;
@ -74,6 +75,7 @@ def DesignatedInitExpr : DStmt<Expr>;
def ImplicitValueInitExpr : DStmt<Expr>;
def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;
// GNU Extensions.
def AddrLabelExpr : DStmt<Expr>;
@ -102,6 +104,8 @@ def CXXDeleteExpr : DStmt<Expr>;
def CXXPseudoDestructorExpr : DStmt<Expr>;
def UnaryTypeTraitExpr : DStmt<Expr>;
def BinaryTypeTraitExpr : DStmt<Expr>;
def ArrayTypeTraitExpr : DStmt<Expr>;
def ExpressionTraitExpr : DStmt<Expr>;
def DependentScopeDeclRefExpr : DStmt<Expr>;
def CXXConstructExpr : DStmt<Expr>;
def CXXBindTemporaryExpr : DStmt<Expr>;
@ -138,4 +142,7 @@ def OpaqueValueExpr : DStmt<Expr>;
// Microsoft Extensions.
def CXXUuidofExpr : DStmt<Expr>;
def SEHTryStmt : Stmt;
def SEHExceptStmt : Stmt;
def SEHFinallyStmt : Stmt;

View File

@ -35,6 +35,17 @@ namespace clang {
};
}
/// PTX builtins
namespace PTX {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsPTX.def"
LastTSBuiltin
};
}
/// X86 builtins
namespace X86 {
enum {

View File

@ -14,18 +14,20 @@
#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
#define LLVM_CLANG_BASIC_TARGETINFO_H
// FIXME: Daniel isn't smart enough to use a prototype for this.
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/VersionTuple.h"
#include <cassert>
#include <vector>
#include <string>
namespace llvm {
struct fltSemantics;
class StringRef;
}
namespace clang {
@ -56,7 +58,7 @@ enum TargetCXXABI {
/// TargetInfo - This class exposes information about the current target.
///
class TargetInfo {
class TargetInfo : public llvm::RefCountedBase<TargetInfo> {
llvm::Triple Triple;
protected:
// Target values set by the ctor of the actual target implementation. Default
@ -78,6 +80,10 @@ class TargetInfo {
const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI CXXABI;
const LangAS::Map *AddrSpaceMap;
mutable llvm::StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
unsigned HasAlignMac68kSupport : 1;
unsigned RealTypeUsesObjCFPRet : 3;
@ -530,6 +536,19 @@ class TargetInfo {
virtual const char *getStaticInitSectionSpecifier() const {
return 0;
}
const LangAS::Map &getAddressSpaceMap() const {
return *AddrSpaceMap;
}
/// \brief Retrieve the name of the platform as it is used in the
/// availability attribute.
llvm::StringRef getPlatformName() const { return PlatformName; }
/// \brief Retrieve the minimum desired version of the platform, to
/// which the program should be compiled.
VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
protected:
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
return PointerWidth;

View File

@ -38,6 +38,9 @@
#ifndef OBJC2_AT_KEYWORD
#define OBJC2_AT_KEYWORD(X)
#endif
#ifndef TESTING_KEYWORD
#define TESTING_KEYWORD(X, L) KEYWORD(X, L)
#endif
#ifndef ANNOTATION
#define ANNOTATION(X) TOK(annot_ ## X)
#endif
@ -94,7 +97,8 @@ PPKEYWORD(unassert)
TOK(unknown) // Not a token.
TOK(eof) // End of file.
TOK(eom) // End of macro (end of line inside a macro).
TOK(eod) // End of preprocessing directive (end of line inside a
// directive).
TOK(code_completion) // Code completion marker
TOK(cxx_defaultarg_end) // C++ default argument end marker
@ -186,6 +190,7 @@ PUNCTUATOR(greatergreatergreater, ">>>")
// is a keyword in the implementation namespace that should
// always be treated as a keyword
// KEYC99 - This is a keyword introduced to C in C99
// KEYC1X - This is a keyword introduced to C in C1X
// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
// implementation namespace
// KEYNOCXX - This is a keyword in every non-C++ dialect.
@ -195,6 +200,7 @@ PUNCTUATOR(greatergreatergreater, ">>>")
// KEYOPENCL - This is a keyword in OpenCL
// KEYALTIVEC - This is a keyword in AltiVec
// KEYBORLAND - This is a keyword if Borland extensions are enabled
// BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
@ -232,7 +238,9 @@ KEYWORD(volatile , KEYALL)
KEYWORD(while , KEYALL)
KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
KEYWORD(_Imaginary , KEYALL)
KEYWORD(_Static_assert , KEYALL)
KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
@ -251,7 +259,7 @@ KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
KEYWORD(new , KEYCXX)
KEYWORD(operator , KEYCXX)
KEYWORD(private , KEYCXX)
KEYWORD(private , KEYCXX|KEYOPENCL)
KEYWORD(protected , KEYCXX)
KEYWORD(public , KEYCXX)
KEYWORD(reinterpret_cast , KEYCXX)
@ -328,11 +336,50 @@ KEYWORD(__is_class , KEYCXX)
KEYWORD(__is_convertible_to , KEYCXX)
KEYWORD(__is_empty , KEYCXX)
KEYWORD(__is_enum , KEYCXX)
KEYWORD(__is_pod , KEYCXX)
KEYWORD(__is_polymorphic , KEYCXX)
KEYWORD(__is_union , KEYCXX)
// Tentative name - there's no implementation of std::is_literal_type yet.
KEYWORD(__is_literal , KEYCXX)
// Name for GCC 4.6 compatibility - people have already written libraries using
// this name unfortunately.
KEYWORD(__is_literal_type , KEYCXX)
KEYWORD(__is_pod , KEYCXX)
KEYWORD(__is_polymorphic , KEYCXX)
KEYWORD(__is_trivial , KEYCXX)
KEYWORD(__is_union , KEYCXX)
// Embarcadero Expression Traits
KEYWORD(__is_lvalue_expr , KEYCXX)
KEYWORD(__is_rvalue_expr , KEYCXX)
// Embarcadero Unary Type Traits
KEYWORD(__is_arithmetic , KEYCXX)
KEYWORD(__is_floating_point , KEYCXX)
KEYWORD(__is_integral , KEYCXX)
KEYWORD(__is_complete_type , KEYCXX)
KEYWORD(__is_void , KEYCXX)
KEYWORD(__is_array , KEYCXX)
KEYWORD(__is_function , KEYCXX)
KEYWORD(__is_reference , KEYCXX)
KEYWORD(__is_lvalue_reference , KEYCXX)
KEYWORD(__is_rvalue_reference , KEYCXX)
KEYWORD(__is_fundamental , KEYCXX)
KEYWORD(__is_object , KEYCXX)
KEYWORD(__is_scalar , KEYCXX)
KEYWORD(__is_compound , KEYCXX)
KEYWORD(__is_pointer , KEYCXX)
KEYWORD(__is_member_object_pointer , KEYCXX)
KEYWORD(__is_member_function_pointer, KEYCXX)
KEYWORD(__is_member_pointer , KEYCXX)
KEYWORD(__is_const , KEYCXX)
KEYWORD(__is_volatile , KEYCXX)
KEYWORD(__is_standard_layout , KEYCXX)
KEYWORD(__is_signed , KEYCXX)
KEYWORD(__is_unsigned , KEYCXX)
// Embarcadero Binary Type Traits
KEYWORD(__is_same , KEYCXX)
KEYWORD(__is_convertible , KEYCXX)
KEYWORD(__array_rank , KEYCXX)
KEYWORD(__array_extent , KEYCXX)
// Apple Extension.
KEYWORD(__private_extern__ , KEYALL)
@ -345,9 +392,23 @@ KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
KEYWORD(__forceinline , KEYALL)
// OpenCL-specific keywords (see OpenCL 1.1 [6.1.9])
// OpenCL-specific keywords
KEYWORD(__kernel , KEYOPENCL)
ALIAS("kernel", __kernel , KEYOPENCL)
KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC)
KEYWORD(__private , KEYOPENCL)
KEYWORD(__global , KEYOPENCL)
KEYWORD(__local , KEYOPENCL)
KEYWORD(__constant , KEYOPENCL)
ALIAS("global", __global , KEYOPENCL)
ALIAS("local", __local , KEYOPENCL)
ALIAS("constant", __constant , KEYOPENCL)
KEYWORD(__read_only , KEYOPENCL)
KEYWORD(__write_only , KEYOPENCL)
KEYWORD(__read_write , KEYOPENCL)
ALIAS("read_only", __read_only , KEYOPENCL)
ALIAS("write_only", __write_only , KEYOPENCL)
ALIAS("read_write", __read_write , KEYOPENCL)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
@ -358,18 +419,19 @@ KEYWORD(__pixel , KEYALTIVEC)
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
ALIAS("__attribute__", __attribute, KEYALL)
ALIAS("__const" , const , KEYALL)
ALIAS("__const__" , const , KEYALL)
ALIAS("__alignof__" , __alignof , KEYALL)
ALIAS("__asm" , asm , KEYALL)
ALIAS("__asm__" , asm , KEYALL)
ALIAS("__attribute__", __attribute, KEYALL)
ALIAS("__complex" , _Complex , KEYALL)
ALIAS("__complex__" , _Complex , KEYALL)
ALIAS("__const" , const , KEYALL)
ALIAS("__const__" , const , KEYALL)
ALIAS("__decltype" , decltype , KEYCXX)
ALIAS("__imag__" , __imag , KEYALL)
ALIAS("__inline" , inline , KEYALL)
ALIAS("__inline__" , inline , KEYALL)
ALIAS("__nullptr" , nullptr , KEYCXX)
ALIAS("__nullptr" , nullptr , KEYCXX)
ALIAS("__real__" , __real , KEYALL)
ALIAS("__restrict" , restrict , KEYALL)
ALIAS("__restrict__" , restrict , KEYALL)
@ -384,6 +446,14 @@ ALIAS("__volatile__" , volatile , KEYALL)
KEYWORD(__ptr64 , KEYMS)
KEYWORD(__w64 , KEYMS)
KEYWORD(__uuidof , KEYMS | KEYBORLAND)
KEYWORD(__try , KEYMS | KEYBORLAND)
KEYWORD(__except , KEYMS | KEYBORLAND)
KEYWORD(__finally , KEYMS | KEYBORLAND)
KEYWORD(__leave , KEYMS | KEYBORLAND)
KEYWORD(__int64 , KEYMS)
ALIAS("__int8" , char , KEYMS)
ALIAS("__int16" , short , KEYMS)
ALIAS("__int32" , int , KEYMS)
ALIAS("_asm" , asm , KEYMS)
ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND)
ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND)
@ -391,6 +461,8 @@ ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND)
ALIAS("_thiscall" , __thiscall , KEYMS)
ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND)
ALIAS("_inline" , inline , KEYMS)
ALIAS("_declspec" , __declspec , KEYMS)
ALIAS("__interface" , class , KEYMS)
// Borland Extensions which should be disabled in strict conformance mode.
ALIAS("_pascal" , __pascal , KEYBORLAND)
@ -399,9 +471,12 @@ ALIAS("_pascal" , __pascal , KEYBORLAND)
ALIAS("__char16_t" , char16_t , KEYCXX)
ALIAS("__char32_t" , char32_t , KEYCXX)
// Clang-specific keywords enabled only in testing.
TESTING_KEYWORD(__unknown_anytype , KEYALL)
//===----------------------------------------------------------------------===//
// Objective-C @-preceeded keywords.
// Objective-C @-preceded keywords.
//===----------------------------------------------------------------------===//
// These have meaning after an '@' in Objective-C mode. These define enums in
@ -443,6 +518,7 @@ ANNOTATION(typename) // annotation for a C typedef name, a C++ (possibly
ANNOTATION(template_id) // annotation for a C++ template-id that names a
// function template specialization (not a type),
// e.g., "std::swap<int>"
ANNOTATION(primary_expr) // annotation for a primary expression
// Annotation for #pragma unused(...)
// For each argument inside the parentheses the pragma handler will produce
@ -450,6 +526,7 @@ ANNOTATION(template_id) // annotation for a C++ template-id that names a
ANNOTATION(pragma_unused)
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC2_AT_KEYWORD
#undef OBJC1_AT_KEYWORD
#undef CXX_KEYWORD_OPERATOR

View File

@ -27,20 +27,59 @@ namespace clang {
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
UTT_IsArithmetic,
UTT_IsArray,
UTT_IsClass,
UTT_IsCompleteType,
UTT_IsCompound,
UTT_IsConst,
UTT_IsEmpty,
UTT_IsEnum,
UTT_IsFloatingPoint,
UTT_IsFunction,
UTT_IsFundamental,
UTT_IsIntegral,
UTT_IsLiteral,
UTT_IsLvalueReference,
UTT_IsMemberFunctionPointer,
UTT_IsMemberObjectPointer,
UTT_IsMemberPointer,
UTT_IsObject,
UTT_IsPOD,
UTT_IsPointer,
UTT_IsPolymorphic,
UTT_IsReference,
UTT_IsRvalueReference,
UTT_IsScalar,
UTT_IsSigned,
UTT_IsStandardLayout,
UTT_IsTrivial,
UTT_IsUnion,
UTT_IsLiteral
UTT_IsUnsigned,
UTT_IsVoid,
UTT_IsVolatile
};
/// BinaryTypeTrait - Names for the binary type traits.
enum BinaryTypeTrait {
BTT_IsBaseOf,
BTT_TypeCompatible,
BTT_IsConvertibleTo
BTT_IsConvertible,
BTT_IsConvertibleTo,
BTT_IsSame,
BTT_TypeCompatible
};
/// ArrayTypeTrait - Names for the array type traits.
enum ArrayTypeTrait {
ATT_ArrayRank,
ATT_ArrayExtent
};
/// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
enum UnaryExprOrTypeTrait {
UETT_SizeOf,
UETT_AlignOf,
UETT_VecStep
};
}

View File

@ -58,6 +58,11 @@ namespace clang {
/// which includes the clang version number, the repository version,
/// and the vendor tag.
std::string getClangFullVersion();
/// \brief Retrieves a string representing the complete clang version suitable
/// for use in the CPP __VERSION__ macro, which includes the clang version
/// number, the repository version, and the vendor tag.
std::string getClangFullCPPVersion();
}
#endif // LLVM_CLANG_BASIC_VERSION_H

View File

@ -0,0 +1,126 @@
//===- VersionTuple.h - Version Number Handling -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header defines the VersionTuple class, which represents a version in
// the form major[.minor[.subminor]].
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H
#define LLVM_CLANG_BASIC_VERSIONTUPLE_H
#include "llvm/ADT/Optional.h"
#include <string>
namespace llvm {
class raw_ostream;
}
namespace clang {
/// \brief Represents a version number in the form major[.minor[.subminor]].
class VersionTuple {
unsigned Major;
unsigned Minor : 31;
unsigned Subminor : 31;
unsigned HasMinor : 1;
unsigned HasSubminor : 1;
public:
VersionTuple()
: Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false) { }
explicit VersionTuple(unsigned Major)
: Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false)
{ }
explicit VersionTuple(unsigned Major, unsigned Minor)
: Major(Major), Minor(Minor), Subminor(0), HasMinor(true),
HasSubminor(false)
{ }
explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
: Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true),
HasSubminor(true)
{ }
/// \brief Determine whether this version information is empty
/// (e.g., all version components are zero).
bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; }
/// \brief Retrieve the major version number.
unsigned getMajor() const { return Major; }
/// \brief Retrieve the minor version number, if provided.
llvm::Optional<unsigned> getMinor() const {
if (!HasMinor)
return llvm::Optional<unsigned>();
return Minor;
}
/// \brief Retrieve the subminor version number, if provided.
llvm::Optional<unsigned> getSubminor() const {
if (!HasSubminor)
return llvm::Optional<unsigned>();
return Subminor;
}
/// \brief Determine if two version numbers are equivalent. If not
/// provided, minor and subminor version numbers are considered to be zero.
friend bool operator==(const VersionTuple& X, const VersionTuple &Y) {
return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor;
}
/// \brief Determine if two version numbers are not equivalent. If
/// not provided, minor and subminor version numbers are considered to be
/// zero.
friend bool operator!=(const VersionTuple &X, const VersionTuple &Y) {
return !(X == Y);
}
/// \brief Determine whether one version number precedes another. If not
/// provided, minor and subminor version numbers are considered to be zero.
friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
if (X.Major != Y.Major)
return X.Major < Y.Major;
if (X.Minor != Y.Minor)
return X.Minor < Y.Minor;
return X.Subminor < Y.Subminor;
}
/// \brief Determine whether one version number follows another. If not
/// provided, minor and subminor version numbers are considered to be zero.
friend bool operator>(const VersionTuple &X, const VersionTuple &Y) {
return Y < X;
}
/// \brief Determine whether one version number precedes or is
/// equivalent to another. If not provided, minor and subminor
/// version numbers are considered to be zero.
friend bool operator<=(const VersionTuple &X, const VersionTuple &Y) {
return !(Y < X);
}
/// \brief Determine whether one version number follows or is
/// equivalent to another. If not provided, minor and subminor
/// version numbers are considered to be zero.
friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
return !(X < Y);
}
/// \brief Retrieve a string representation of the version number/
std::string getAsString() const;
};
/// \brief Print a version number.
llvm::raw_ostream& operator<<(llvm::raw_ostream &Out, const VersionTuple &V);
} // end namespace clang
#endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H

View File

@ -22,13 +22,11 @@ def OP_SUB : Op;
def OP_SUBL : Op;
def OP_SUBW : Op;
def OP_MUL : Op;
def OP_MULL : Op;
def OP_MLA : Op;
def OP_MLAL : Op;
def OP_MLS : Op;
def OP_MLSL : Op;
def OP_MUL_N : Op;
def OP_MULL_N: Op;
def OP_MLA_N : Op;
def OP_MLS_N : Op;
def OP_MLAL_N : Op;
@ -144,8 +142,7 @@ def VQDMULH : SInst<"vqdmulh", "ddd", "siQsQi">;
def VQRDMULH : SInst<"vqrdmulh", "ddd", "siQsQi">;
def VQDMLAL : SInst<"vqdmlal", "wwdd", "si">;
def VQDMLSL : SInst<"vqdmlsl", "wwdd", "si">;
def VMULL : Inst<"vmull", "wdd", "csiUcUsUi", OP_MULL>;
def VMULLP : SInst<"vmull", "wdd", "Pc">;
def VMULL : SInst<"vmull", "wdd", "csiUcUsUiPc">;
def VQDMULL : SInst<"vqdmull", "wdd", "si">;
////////////////////////////////////////////////////////////////////////////////
@ -331,7 +328,7 @@ def VMLSL_LANE : Inst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>;
def VQDMLSL_LANE : Inst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>;
def VMUL_N : Inst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>;
def VMUL_LANE : Inst<"vmul_lane", "ddgi", "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>;
def VMULL_N : Inst<"vmull_n", "wda", "siUsUi", OP_MULL_N>;
def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">;
def VMULL_LANE : Inst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>;
def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">;
def VQDMULL_LANE : Inst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>;

View File

@ -13,7 +13,6 @@
#include "Util.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <vector>
#include <string>
namespace clang {

View File

@ -29,6 +29,10 @@ def I : JoinedOrSeparate<"-I">, MetaVarName<"<directory>">,
HelpText<"Add directory to include search path">;
def n : Flag<"-n">,
HelpText<"Don't automatically start assembly file with a text section">;
def L : Flag<"-L">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics, it should almost never be used "
"on compiler generated code!">;
//===----------------------------------------------------------------------===//
// Frontend Options
@ -72,4 +76,4 @@ def relax_all : Flag<"-relax-all">,
HelpText<"Relax all fixups (for performance testing)">;
def no_exec_stack : Flag<"--noexecstack">,
HelpText<"Mark the file as not needing an executable stack">;
HelpText<"Mark the file as not needing an executable stack">;

View File

@ -42,14 +42,6 @@ def analysis_CFGAddImplicitDtors : Flag<"-cfg-add-implicit-dtors">,
HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
def analysis_CFGAddInitializers : Flag<"-cfg-add-initializers">,
HelpText<"Add C++ initializers to CFGs for all analyses">;
def analysis_WarnUninitVals : Flag<"-warn-uninit-values">,
HelpText<"Warn about uses of uninitialized variables">;
def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
HelpText<"Run the [Core] Foundation reference count checker">;
def analysis_AnalyzerStats : Flag<"-analyzer-stats">,
HelpText<"Emit warnings with analyzer statistics">;
def analysis_WarnBufferOverflows : Flag<"-analyzer-check-buffer-overflows">,
HelpText<"Warn about buffer overflows">;
def analyzer_store : Separate<"-analyzer-store">,
HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@ -71,8 +63,6 @@ def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-bloc
HelpText<"Analyze the definitions of blocks in addition to functions">;
def analyzer_display_progress : Flag<"-analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">;
def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
HelpText<"Use experimental path-sensitive checks">;
def analyze_function : Separate<"-analyze-function">,
HelpText<"Run analysis on specific function">;
def analyze_function_EQ : Joined<"-analyze-function=">, Alias<analyze_function>;
@ -120,7 +110,10 @@ def disable_red_zone : Flag<"-disable-red-zone">,
HelpText<"Do not emit code that uses the red zone.">;
def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
HelpText<"The string to embed in the Dwarf debug flags record.">;
def fforbid_guard_variables : Flag<"-fforbid-guard-variables">,
HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
def g : Flag<"-g">, HelpText<"Generate source level debug information">;
def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">, HelpText<"Don't use the cfi directives">;
def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">,
HelpText<"Generate runtime checks for undefined behavior.">;
def flimit_debug_info : Flag<"-flimit-debug-info">,
@ -143,6 +136,10 @@ def fdata_sections : Flag<"-fdata-sections">,
HelpText<"Place each data in its own section (ELF Only)">;
def funroll_loops : Flag<"-funroll-loops">,
HelpText<"Turn on loop unroller">;
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 relaxed_aliasing : Flag<"-relaxed-aliasing">,
HelpText<"Turn off Type Based Alias Analysis">;
def masm_verbose : Flag<"-masm-verbose">,
@ -163,10 +160,16 @@ def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">,
HelpText<"Omit frame pointer setup for leaf functions.">;
def msoft_float : Flag<"-msoft-float">,
HelpText<"Use software floating point">;
def backend_option : Separate<"-backend-option">,
HelpText<"Additional arguments to forward to LLVM backend (during code gen)">;
def mregparm : Separate<"-mregparm">,
HelpText<"Limit the number of registers available for integer arguments">;
def mrelax_all : Flag<"-mrelax-all">,
HelpText<"Relax all machine instructions">;
HelpText<"(integrated-as) Relax all machine instructions">;
def msave_temp_labels : Flag<"-msave-temp-labels">,
HelpText<"(integrated-as) Save temporary labels">;
def mrtd: Flag<"-mrtd">,
HelpText<"Make StdCall calling convention the default">;
def mrelocation_model : Separate<"-mrelocation-model">,
HelpText<"The relocation model to use">;
def munwind_tables : Flag<"-munwind-tables">,
@ -177,6 +180,7 @@ def mms_bitfields : Flag<"-mms-bitfields">,
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard.">;
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">;
def pg : Flag<"-pg">, HelpText<"Enable mcount instrumentation">;
//===----------------------------------------------------------------------===//
@ -203,6 +207,8 @@ def MP : Flag<"-MP">,
def dump_build_information : Separate<"-dump-build-information">,
MetaVarName<"<filename>">,
HelpText<"output a dump of some build information to a file">;
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 fno_show_source_location : Flag<"-fno-show-source-location">,
@ -214,6 +220,9 @@ def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">,
HelpText<"Do not include source line and caret with diagnostics">;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">,
HelpText<"Do not include fixit information in diagnostics">;
def fno_diagnostics_show_note_include_stack :
Flag<"-fno-diagnostics-show-note-include-stack">,
HelpText<"Display include stacks for diagnostic notes">;
def w : Flag<"-w">, HelpText<"Suppress all warnings">;
def pedantic : Flag<"-pedantic">;
def pedantic_errors : Flag<"-pedantic-errors">;
@ -227,11 +236,15 @@ def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-rang
HelpText<"Print source range spans in numeric form">;
def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">,
HelpText<"Print fix-its in machine parseable form">;
def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">,
HelpText<"Print diagnostic name">;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print diagnostic name with mappable diagnostics">;
HelpText<"Print option name with mappable diagnostics">;
def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
def fdiagnostics_show_note_include_stack :
Flag<"-fdiagnostics-show-note-include-stack">,
HelpText<"Display include stacks for diagnostic notes">;
def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
HelpText<"Set the tab stop distance.">;
def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
@ -246,8 +259,6 @@ def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,
HelpText<"Use colors in diagnostics">;
def Wno_rewrite_macros : Flag<"-Wno-rewrite-macros">,
HelpText<"Silence ObjC rewriting warnings">;
def Wwrite_strings : Flag<"-Wwrite-strings">,
HelpText<"Remove const qualifier from string literals">;
def verify : Flag<"-verify">,
HelpText<"Verify emitted diagnostics and warnings">;
@ -326,8 +337,6 @@ def emit_html : Flag<"-emit-html">,
HelpText<"Output input source as HTML">;
def ast_print : Flag<"-ast-print">,
HelpText<"Build ASTs and then pretty-print them">;
def ast_print_xml : Flag<"-ast-print-xml">,
HelpText<"Build ASTs and then print them in XML format">;
def ast_dump : Flag<"-ast-dump">,
HelpText<"Build ASTs and then debug dump them">;
def ast_dump_xml : Flag<"-ast-dump-xml">,
@ -517,8 +526,25 @@ def trigraphs : Flag<"-trigraphs">,
HelpText<"Process trigraph sequences">;
def fwritable_strings : Flag<"-fwritable-strings">,
HelpText<"Store string literals as writable data">;
def fconst_strings : Flag<"-fconst-strings">,
HelpText<"Use a const qualified type for string literals in C and ObjC">;
def fno_const_strings : Flag<"-fno-const-strings">,
HelpText<"Don't use a const qualified type for string literals in C and ObjC">;
def fno_bitfield_type_align : Flag<"-fno-bitfield-type-align">,
HelpText<"Ignore bit-field types when aligning structures">;
def traditional_cpp : Flag<"-traditional-cpp">,
HelpText<"Enable some traditional CPP emulation">;
def ffake_address_space_map : Flag<"-ffake-address-space-map">,
HelpText<"Use a fake address space map; OpenCL testing purposes only">;
def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">,
HelpText<"Parse templated function definitions at the end of the "
"translation unit ">;
def funknown_anytype : Flag<"-funknown-anytype">,
HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">;
def fdeprecated_macro : Flag<"-fdeprecated-macro">,
HelpText<"Defines the __DEPRECATED macro">;
def fno_deprecated_macro : Flag<"-fno-deprecated-macro">,
HelpText<"Undefines the __DEPRECATED macro">;
//===----------------------------------------------------------------------===//
// Header Search Options
@ -570,6 +596,8 @@ def include_pch : Separate<"-include-pch">, MetaVarName<"<file>">,
HelpText<"Include precompiled header file">;
def include_pth : Separate<"-include-pth">, MetaVarName<"<file>">,
HelpText<"Include file before parsing">;
def chain_include : Separate<"-chain-include">, MetaVarName<"<file>">,
HelpText<"Include and chain a header file after turning it into PCH">;
def preamble_bytes_EQ : Joined<"-preamble-bytes=">,
HelpText<"Assume that the precompiled header is a precompiled preamble "
"covering the first N bytes of the main file">;

View File

@ -25,6 +25,7 @@
namespace llvm {
class raw_ostream;
template<typename T> class ArrayRef;
}
namespace clang {
namespace driver {
@ -77,6 +78,12 @@ class Driver {
typedef llvm::SmallVector<std::string, 4> prefix_list;
prefix_list PrefixDirs;
/// sysroot, if present
std::string SysRoot;
/// If the standard library is used
bool UseStdLib;
/// Default host triple.
std::string DefaultHostTriple;
@ -90,7 +97,7 @@ class Driver {
/// will generally be the actual host platform, but not always.
const HostInfo *Host;
/// Information about the host which can be overriden by the user.
/// Information about the host which can be overridden by the user.
std::string HostBits, HostMachine, HostSystem, HostRelease;
/// The file to log CC_PRINT_OPTIONS output to, if enabled.
@ -99,9 +106,15 @@ class Driver {
/// The file to log CC_PRINT_HEADERS output to, if enabled.
const char *CCPrintHeadersFilename;
/// The file to log CC_LOG_DIAGNOSTICS output to, if enabled.
const char *CCLogDiagnosticsFilename;
/// Whether the driver should follow g++ like behavior.
unsigned CCCIsCXX : 1;
/// Whether the driver is just the preprocessor
unsigned CCCIsCPP : 1;
/// Echo commands while executing (in -v style).
unsigned CCCEcho : 1;
@ -116,8 +129,13 @@ class Driver {
/// information to CCPrintHeadersFilename or to stderr.
unsigned CCPrintHeaders : 1;
/// Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics
/// to CCLogDiagnosticsFilename or to stderr, in a stable machine readable
/// format.
unsigned CCLogDiagnostics : 1;
private:
/// Name to use when calling the generic gcc.
/// Name to use when invoking gcc/g++.
std::string CCCGenericGCCName;
/// Whether to check that input files exist when constructing compilation
@ -165,7 +183,7 @@ class Driver {
/// @name Accessors
/// @{
/// Name to use when calling the generic gcc.
/// Name to use when invoking gcc/g++.
const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
@ -206,14 +224,14 @@ class Driver {
/// argument vector. A null return value does not necessarily
/// indicate an error condition, the diagnostics should be queried
/// to determine if an error occurred.
Compilation *BuildCompilation(int argc, const char **argv);
Compilation *BuildCompilation(llvm::ArrayRef<const char *> Args);
/// @name Driver Steps
/// @{
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
InputArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
InputArgList *ParseArgStrings(llvm::ArrayRef<const char *> Args);
/// BuildActions - Construct the list of actions to perform for the
/// given arguments, which are only done for a single architecture.
@ -221,7 +239,7 @@ class Driver {
/// \param TC - The default host tool chain.
/// \param Args - The input arguments.
/// \param Actions - The list to store the resulting actions onto.
void BuildActions(const ToolChain &TC, const ArgList &Args,
void BuildActions(const ToolChain &TC, const DerivedArgList &Args,
ActionList &Actions) const;
/// BuildUniversalActions - Construct the list of actions to perform
@ -230,7 +248,7 @@ class Driver {
/// \param TC - The default host tool chain.
/// \param Args - The input arguments.
/// \param Actions - The list to store the resulting actions onto.
void BuildUniversalActions(const ToolChain &TC, const ArgList &Args,
void BuildUniversalActions(const ToolChain &TC, const DerivedArgList &Args,
ActionList &Actions) const;
/// BuildJobs - Bind actions to concrete tools and translate

View File

@ -15,7 +15,8 @@
namespace clang {
namespace diag {
enum {
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\
SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM,
#define DRIVERSTART
#include "clang/Basic/DiagnosticDriverKinds.inc"
#undef DIAG

View File

@ -78,7 +78,7 @@ def RenderSeparate : OptionFlag;
def Unsupported : OptionFlag;
// HelpHidden - The option should not be displayed in --help, even if it has
// help text. Clients *can* use this in conjuction with the OptTable::PrintHelp
// help text. Clients *can* use this in conjunction with the OptTable::PrintHelp
// arguments to implement hidden help groups.
def HelpHidden : OptionFlag;

View File

@ -29,6 +29,7 @@ def X_Group : OptionGroup<"<X group>">;
def a_Group : OptionGroup<"<a group>">;
def d_Group : OptionGroup<"<d group>">;
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
def g_Group : OptionGroup<"<g group>">;
def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
@ -165,6 +166,8 @@ def Wa_COMMA : CommaJoined<"-Wa,">,
HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
MetaVarName<"<arg>">;
def Wall : Flag<"-Wall">, Group<W_Group>;
def Wdeprecated : Flag<"-Wdeprecated">, Group<W_Group>;
def Wno_deprecated : Flag<"-Wno-deprecated">, Group<W_Group>;
def Wextra : Flag<"-Wextra">, Group<W_Group>;
def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
@ -174,6 +177,8 @@ def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>;
def Wp_COMMA : CommaJoined<"-Wp,">,
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
MetaVarName<"<arg>">;
def Wwrite_strings : Flag<"-Wwrite-strings">, Group<W_Group>;
def Wno_write_strings : Flag<"-Wno-write-strings">, Group<W_Group>;
def W_Joined : Joined<"-W">, Group<W_Group>;
def Xanalyzer : Separate<"-Xanalyzer">,
HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
@ -264,18 +269,24 @@ def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<f_Group>;
def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
def fcxx_exceptions: Flag<"-fcxx-exceptions">, Group<f_Group>;
def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_Group>;
def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_clang_Group>;
def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_clang_Group>;
def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_clang_Group>;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, 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_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>;
def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">, Group<f_Group>;
def felide_constructors : Flag<"-felide-constructors">, Group<f_Group>;
def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>;
def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>;
def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>;
def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
def fhosted : Flag<"-fhosted">, Group<f_Group>;
@ -301,6 +312,7 @@ def flimit_debug_info : Flag<"-flimit-debug-info">, Group<f_Group>,
HelpText<"Limit debug information produced to reduce size of debug binary">;
def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
def flto : Flag<"-flto">, Group<f_Group>;
def fno_lto : Flag<"-fno-lto">, Group<f_Group>;
def fmacro_backtrace_limit_EQ : Joined<"-fmacro-backtrace-limit=">,
Group<f_Group>;
def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
@ -308,6 +320,7 @@ def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>;
def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>;
def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>;
def fmsc_version : Joined<"-fmsc-version=">, Group<f_Group>;
def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>;
def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
@ -325,8 +338,11 @@ def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>;
def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
def fno_common : Flag<"-fno-common">, Group<f_Group>;
def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
def fno_cxx_exceptions: Flag<"-fno-cxx-exceptions">, Group<f_Group>;
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
def fno_diagnostics_show_name : Flag<"-fno-diagnostics-show-name">, Group<f_Group>;
def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
def fno_diagnostics_show_note_include_stack : Flag<"-fno-diagnostics-show-note-include-stack">, Group<f_Group>;
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
def fno_elide_constructors : Flag<"-fno-elide-constructors">, Group<f_Group>;
def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
@ -340,6 +356,7 @@ def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Gr
def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
def fno_delayed_template_parsing : Flag<"-fno-delayed-template-parsing">, Group<f_Group>;
def fno_objc_default_synthesize_properties
: Flag<"-fno-objc-default-synthesize-properties">, Group<f_Group>;
def fno_objc_exceptions: Flag<"-fno-objc-exceptions">, Group<f_Group>;
@ -353,12 +370,14 @@ def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>
def fno_spell_checking : Flag<"-fno-spell-checking">, Group<f_Group>;
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<f_Group>;
def fno_strict_overflow : Flag<"-fno-strict-overflow">, Group<f_Group>;
def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>;
def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
def fno_verbose_asm : Flag<"-fno-verbose-asm">, Group<f_Group>;
def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
def fno_wrapv : Flag<"-fno-wrapv">, Group<f_Group>;
def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
@ -406,19 +425,30 @@ def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<f_Group>;
def fstrict_overflow : Flag<"-fstrict-overflow">, Group<f_Group>;
def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>;
def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">,
Group<f_Group>;
def ftest_coverage : Flag<"-ftest-coverage">, Group<f_Group>;
def Wlarge_by_value_copy_def : Flag<"-Wlarge-by-value-copy">;
def Wlarge_by_value_copy_EQ : Joined<"-Wlarge-by-value-copy=">;
// Just silence warnings about -Wlarger-than, -Wframe-larger-than for now.
def Wlarger_than : Separate<"-Wlarger-than">, Group<clang_ignored_f_Group>;
def Wlarger_than_EQ : Joined<"-Wlarger-than=">, Alias<Wlarger_than>;
def Wlarger_than_ : Joined<"-Wlarger-than-">, Alias<Wlarger_than>;
def Wframe_larger_than : Separate<"-Wframe-larger-than">, Group<clang_ignored_f_Group>;
def Wframe_larger_than_EQ : Joined<"-Wframe-larger-than=">, Alias<Wframe_larger_than>;
def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
def ftrapv_handler_EQ : Joined<"-ftrapv-handler=">, Group<f_Group>;
def ftrap_function_EQ : Joined<"-ftrap-function=">, Group<f_Group>,
HelpText<"Issue call to specified function rather than a trap instruction">;
def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
def funroll_loops : Flag<"-funroll-loops">, Group<f_Group>;
def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
@ -465,11 +495,11 @@ def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>;
def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>;
def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>;
def m64 : Flag<"-m64">, Group<m_Group>, Flags<[DriverOption]>;
def mabi_EQ : Joined<"-mabi=">, Group<m_Group>, Flags<[DriverOption]>;
def march_EQ : Joined<"-march=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>, Flags<[DriverOption]>;
def mabi_EQ : Joined<"-mabi=">, Group<m_Group>;
def march_EQ : Joined<"-march=">, Group<m_Group>;
def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>;
def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>, Flags<[DriverOption]>;
def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>;
def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
@ -477,6 +507,7 @@ def mfpu_EQ : Joined<"-mfpu=">, Group<m_Group>;
def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>;
def mios_version_min_EQ : Joined<"-mios-version-min=">, Alias<miphoneos_version_min_EQ>;
def mios_simulator_version_min_EQ : Joined<"-mios-simulator-version-min=">, Group<m_Group>;
def mkernel : Flag<"-mkernel">, Group<m_Group>;
def mlinker_version_EQ : Joined<"-mlinker-version=">, Flags<[NoForward]>;
def mllvm : Separate<"-mllvm">;
@ -490,6 +521,7 @@ def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
def mno_relax_all : Flag<"-mno-relax-all">, Group<m_Group>;
def mno_rtd: Flag<"-mno-rtd">, Group<m_Group>;
def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>;
def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
@ -512,6 +544,7 @@ def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
def mregparm_EQ : Joined<"-mregparm=">, Group<m_Group>;
def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>;
def mrtd: Flag<"-mrtd">, Group<m_Group>;
def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;

View File

@ -88,8 +88,10 @@ class ToolChain {
return 0;
}
/// SelectTool - Choose a tool to use to handle the action \arg JA.
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const = 0;
/// SelectTool - Choose a tool to use to handle the action \arg JA with the
/// given \arg Inputs.
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const = 0;
// Helper methods
@ -151,6 +153,9 @@ class ToolChain {
/// particular PIC mode.
virtual const char *GetForcedPicModel() const = 0;
/// SupportsProfiling - Does this tool chain support -pg.
virtual bool SupportsProfiling() const { return true; }
/// Does this tool chain support Objective-C garbage collection.
virtual bool SupportsObjCGC() const { return false; }

View File

@ -14,8 +14,6 @@
#ifndef DRIVER_ASTCONSUMERS_H
#define DRIVER_ASTCONSUMERS_H
#include <string>
namespace llvm {
class raw_ostream;
namespace sys { class Path; }
@ -36,12 +34,6 @@ class TargetOptions;
// implementation is still incomplete.
ASTConsumer *CreateASTPrinter(llvm::raw_ostream *OS);
// AST XML-printer: prints out the AST in a XML format
// The output is intended to be in a format such that
// clang or any other tool could re-parse the output back into the same AST,
// but the implementation is still incomplete.
ASTConsumer *CreateASTPrinterXML(llvm::raw_ostream *OS);
// AST dumper: dumps the raw AST in human-readable form to stderr; this is
// intended for debugging.
ASTConsumer *CreateASTDumper();

View File

@ -71,12 +71,12 @@ class ASTUnit {
private:
llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
llvm::OwningPtr<FileManager> FileMgr;
llvm::OwningPtr<SourceManager> SourceMgr;
llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
llvm::OwningPtr<HeaderSearch> HeaderInfo;
llvm::OwningPtr<TargetInfo> Target;
llvm::OwningPtr<Preprocessor> PP;
llvm::OwningPtr<ASTContext> Ctx;
llvm::IntrusiveRefCntPtr<TargetInfo> Target;
llvm::IntrusiveRefCntPtr<Preprocessor> PP;
llvm::IntrusiveRefCntPtr<ASTContext> Ctx;
FileSystemOptions FileSystemOpts;
@ -90,7 +90,7 @@ class ASTUnit {
/// Optional owned invocation, just used to make the invocation used in
/// LoadFromCommandLine available.
llvm::OwningPtr<CompilerInvocation> Invocation;
llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
/// \brief The set of target features.
///
@ -115,6 +115,9 @@ class ASTUnit {
/// \brief Whether we should time each operation.
bool WantTiming;
/// \brief Whether the ASTUnit should delete the remapped buffers.
bool OwnsRemappedFileBuffers;
/// Track the top-level decls which appeared in an ASTUnit which was loaded
/// from a source file.
@ -393,11 +396,11 @@ class ASTUnit {
const SourceManager &getSourceManager() const { return *SourceMgr; }
SourceManager &getSourceManager() { return *SourceMgr; }
const Preprocessor &getPreprocessor() const { return *PP.get(); }
Preprocessor &getPreprocessor() { return *PP.get(); }
const Preprocessor &getPreprocessor() const { return *PP; }
Preprocessor &getPreprocessor() { return *PP; }
const ASTContext &getASTContext() const { return *Ctx.get(); }
ASTContext &getASTContext() { return *Ctx.get(); }
const ASTContext &getASTContext() const { return *Ctx; }
ASTContext &getASTContext() { return *Ctx; }
bool hasSema() const { return TheSema; }
Sema &getSema() const {
@ -422,6 +425,9 @@ class ASTUnit {
bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
/// \brief Retrieve the maximum PCH level of declarations that a
/// traversal of the translation unit should consider.
unsigned getMaxPCHLevel() const;
@ -529,10 +535,16 @@ class ASTUnit {
/// that might still be used as a precompiled header or preamble.
bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; }
typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *>
FilenameOrMemBuf;
/// \brief A mapping from a file name to the memory buffer that stores the
/// remapped contents of that file.
typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile;
typedef std::pair<std::string, FilenameOrMemBuf> RemappedFile;
/// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
static ASTUnit *create(CompilerInvocation *CI,
llvm::IntrusiveRefCntPtr<Diagnostic> Diags);
/// \brief Create a ASTUnit from an AST file.
///
/// \param Filename - The AST file to load.
@ -603,6 +615,7 @@ class ASTUnit {
bool CaptureDiagnostics = false,
RemappedFile *RemappedFiles = 0,
unsigned NumRemappedFiles = 0,
bool RemappedFilesKeepOriginalName = true,
bool PrecompilePreamble = false,
bool CompleteTranslationUnit = true,
bool CacheCodeCompletionResults = false,
@ -647,6 +660,11 @@ class ASTUnit {
///
/// \returns True if an error occurred, false otherwise.
bool Save(llvm::StringRef File);
/// \brief Serialize this translation unit with the given output stream.
///
/// \returns True if an error occurred, false otherwise.
bool serialize(llvm::raw_ostream &OS);
};
} // namespace clang

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