Update clang to r104832.

This commit is contained in:
Roman Divacky 2010-05-27 15:17:06 +00:00
parent be17651f5c
commit d7279c4c17
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=208600
svn path=/vendor/clang/clang-r104832/; revision=208977; tag=vendor/clang/clang-r104832
486 changed files with 22073 additions and 9977 deletions

View File

@ -441,43 +441,42 @@
1AA963AB10D8576800786C86 /* FullExpr.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = FullExpr.h; path = clang/AST/FullExpr.h; sourceTree = "<group>"; tabWidth = 2; };
1AB290021045858B00FE33D8 /* PartialDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = PartialDiagnostic.h; sourceTree = "<group>"; tabWidth = 2; };
1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = lib/CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B11182449800A48E65 /* APValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APValue.cpp; sourceTree = "<group>"; };
1ABD23B21182449800A48E65 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTConsumer.cpp; sourceTree = "<group>"; };
1ABD23B31182449800A48E65 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTContext.cpp; sourceTree = "<group>"; };
1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTDiagnostic.cpp; sourceTree = "<group>"; };
1ABD23B51182449800A48E65 /* ASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ASTImporter.cpp; sourceTree = "<group>"; };
1ABD23B61182449800A48E65 /* AttrImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttrImpl.cpp; sourceTree = "<group>"; };
1ABD23B71182449800A48E65 /* CXXInheritance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CXXInheritance.cpp; sourceTree = "<group>"; };
1ABD23B81182449800A48E65 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decl.cpp; sourceTree = "<group>"; };
1ABD23B91182449800A48E65 /* DeclarationName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclarationName.cpp; sourceTree = "<group>"; };
1ABD23BA1182449800A48E65 /* DeclBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclBase.cpp; sourceTree = "<group>"; };
1ABD23BB1182449800A48E65 /* DeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclCXX.cpp; sourceTree = "<group>"; };
1ABD23BC1182449800A48E65 /* DeclFriend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclFriend.cpp; sourceTree = "<group>"; };
1ABD23BD1182449800A48E65 /* DeclGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclGroup.cpp; sourceTree = "<group>"; };
1ABD23BE1182449800A48E65 /* DeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclObjC.cpp; sourceTree = "<group>"; };
1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclPrinter.cpp; sourceTree = "<group>"; };
1ABD23C01182449800A48E65 /* DeclTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeclTemplate.cpp; sourceTree = "<group>"; };
1ABD23C11182449800A48E65 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Expr.cpp; sourceTree = "<group>"; };
1ABD23C21182449800A48E65 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExprConstant.cpp; sourceTree = "<group>"; };
1ABD23C31182449800A48E65 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExprCXX.cpp; sourceTree = "<group>"; };
1ABD23C41182449800A48E65 /* FullExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FullExpr.cpp; sourceTree = "<group>"; };
1ABD23C51182449800A48E65 /* InheritViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InheritViz.cpp; sourceTree = "<group>"; };
1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NestedNameSpecifier.cpp; sourceTree = "<group>"; };
1ABD23C71182449800A48E65 /* ParentMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParentMap.cpp; sourceTree = "<group>"; };
1ABD23C81182449800A48E65 /* RecordLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayout.cpp; sourceTree = "<group>"; };
1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayoutBuilder.cpp; sourceTree = "<group>"; };
1ABD23CA1182449800A48E65 /* RecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordLayoutBuilder.h; sourceTree = "<group>"; };
1ABD23CB1182449800A48E65 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stmt.cpp; sourceTree = "<group>"; };
1ABD23CC1182449800A48E65 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtDumper.cpp; sourceTree = "<group>"; };
1ABD23CD1182449800A48E65 /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtIterator.cpp; sourceTree = "<group>"; };
1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtPrinter.cpp; sourceTree = "<group>"; };
1ABD23CF1182449800A48E65 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtProfile.cpp; sourceTree = "<group>"; };
1ABD23D01182449800A48E65 /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StmtViz.cpp; sourceTree = "<group>"; };
1ABD23D11182449800A48E65 /* TemplateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateBase.cpp; sourceTree = "<group>"; };
1ABD23D21182449800A48E65 /* TemplateName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateName.cpp; sourceTree = "<group>"; };
1ABD23D31182449800A48E65 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Type.cpp; sourceTree = "<group>"; };
1ABD23D41182449800A48E65 /* TypeLoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLoc.cpp; sourceTree = "<group>"; };
1ABD23D51182449800A48E65 /* TypePrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypePrinter.cpp; sourceTree = "<group>"; };
1ABD23B11182449800A48E65 /* APValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = APValue.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B21182449800A48E65 /* ASTConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B31182449800A48E65 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTContext.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B41182449800A48E65 /* ASTDiagnostic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTDiagnostic.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B51182449800A48E65 /* ASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ASTImporter.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B61182449800A48E65 /* AttrImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = AttrImpl.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B71182449800A48E65 /* CXXInheritance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = CXXInheritance.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B81182449800A48E65 /* Decl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Decl.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23B91182449800A48E65 /* DeclarationName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclarationName.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BA1182449800A48E65 /* DeclBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclBase.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BB1182449800A48E65 /* DeclCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BC1182449800A48E65 /* DeclFriend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclFriend.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BD1182449800A48E65 /* DeclGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclGroup.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BE1182449800A48E65 /* DeclObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclObjC.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23BF1182449800A48E65 /* DeclPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclPrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C01182449800A48E65 /* DeclTemplate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = DeclTemplate.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C11182449800A48E65 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Expr.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C21182449800A48E65 /* ExprConstant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ExprConstant.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C31182449800A48E65 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ExprCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C41182449800A48E65 /* FullExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = FullExpr.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C51182449800A48E65 /* InheritViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = InheritViz.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C61182449800A48E65 /* NestedNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = NestedNameSpecifier.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C71182449800A48E65 /* ParentMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = ParentMap.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C81182449800A48E65 /* RecordLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayout.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = RecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23CB1182449800A48E65 /* Stmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Stmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23CC1182449800A48E65 /* StmtDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtDumper.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23CD1182449800A48E65 /* StmtIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtIterator.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23CE1182449800A48E65 /* StmtPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtPrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23CF1182449800A48E65 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D01182449800A48E65 /* StmtViz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = StmtViz.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D11182449800A48E65 /* TemplateBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateBase.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D21182449800A48E65 /* TemplateName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateName.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D31182449800A48E65 /* Type.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = Type.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D41182449800A48E65 /* TypeLoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TypeLoc.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ABD23D51182449800A48E65 /* TypePrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; path = TypePrinter.cpp; sourceTree = "<group>"; tabWidth = 2; };
1ACB57DB1105820D0047B991 /* CompilerInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerInstance.cpp; path = lib/Frontend/CompilerInstance.cpp; sourceTree = "<group>"; };
1ACB57DC1105820D0047B991 /* CompilerInvocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerInvocation.cpp; path = lib/Frontend/CompilerInvocation.cpp; sourceTree = "<group>"; };
1ACB57DD1105820D0047B991 /* DeclXML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeclXML.cpp; path = lib/Frontend/DeclXML.cpp; sourceTree = "<group>"; };
@ -1494,7 +1493,6 @@
1ABD23C71182449800A48E65 /* ParentMap.cpp */,
1ABD23C81182449800A48E65 /* RecordLayout.cpp */,
1ABD23C91182449800A48E65 /* RecordLayoutBuilder.cpp */,
1ABD23CA1182449800A48E65 /* RecordLayoutBuilder.h */,
1ABD23CB1182449800A48E65 /* Stmt.cpp */,
1ABD23CC1182449800A48E65 /* StmtDumper.cpp */,
1ABD23CD1182449800A48E65 /* StmtIterator.cpp */,

View File

@ -532,12 +532,12 @@ source code of the program. Important design points include:</p>
</ol>
<p>In practice, the SourceLocation works together with the SourceManager class
to encode two pieces of information about a location: it's spelling location
and it's instantiation location. For most tokens, these will be the same. However,
for a macro expansion (or tokens that came from a _Pragma directive) these will
describe the location of the characters corresponding to the token and the
location where the token was used (i.e. the macro instantiation point or the
location of the _Pragma itself).</p>
to encode two pieces of information about a location: its spelling location
and its instantiation location. For most tokens, these will be the same.
However, for a macro expansion (or tokens that came from a _Pragma directive)
these will describe the location of the characters corresponding to the token
and the location where the token was used (i.e. the macro instantiation point
or the location of the _Pragma itself).</p>
<p>The Clang front-end inherently depends on the location of a token being
tracked correctly. If it is ever incorrect, the front-end may get confused and

View File

@ -36,6 +36,7 @@ td {
<ul>
<li><a href="#diagnostics_display">Controlling How Clang Displays Diagnostics</a></li>
<li><a href="#diagnostics_mappings">Diagnostic Mappings</a></li>
<li><a href="#diagnostics_categories">Diagnostic Categories</a><li>
<li><a href="#diagnostics_commandline">Controlling Diagnostics via Command Line Flags</a></li>
<li><a href="#diagnostics_pragmas">Controlling Diagnostics via Pragmas</a></li>
</ul>
@ -286,6 +287,30 @@ diagnostic. This information tells you the flag needed to enable or disable the
diagnostic, either from the command line or through <a
href="#pragma_GCC_diagnostic">#pragma GCC diagnostic</a>.</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-show-category"><b>-fdiagnostics-show-category=none/id/name</b>:
Enable printing category information in diagnostic line.</dt>
<dd>This option, which defaults to "none",
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>
<p>For example, a format string warning will produce these three renditions
based on the setting of this option:</p>
<pre>
t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat]
t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat<b>,1</b>]
t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat<b>,Format String</b>]
</pre>
<p>This category can be used by clients that want to group diagnostics by
category, so it should be a high level category. We want dozens of these, not
hundreds or thousands of them.</p>
</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-fixit-info"><b>-f[no-]diagnostics-fixit-info</b>:
@ -393,6 +418,10 @@ it:</p>
<li>An option that indicates how to control the diagnostic (for diagnostics that
support it) [<a
href="#opt_fdiagnostics-show-option">-fdiagnostics-show-option</a>].</li>
<li>A <a href="#diagnostics_categories">high-level category</a> for the
diagnostic for clients that want to group diagnostics by class (for
diagnostics that support it) [<a
href="#opt_fdiagnostics-show-category">-fdiagnostics-show-category</a>].</li>
<li>The line of source code that the issue occurs on, along with a caret and
ranges that indicate the important locations [<a
href="opt_fcaret-diagnostics">-fcaret-diagnostics</a>].</li>
@ -407,6 +436,7 @@ it:</p>
<p>For more information please see <a href="#cl_diag_formatting">Formatting of
Diagnostics</a>.</p>
<h4 id="diagnostics_mappings">Diagnostic Mappings</h4>
<p>All diagnostics are mapped into one of these 5 classes:</p>
@ -420,7 +450,23 @@ Diagnostics</a>.</p>
<li>Fatal</li>
</ul></p>
<h4 id="diagnostics_commandline">Controlling Diagnostics via Command Line Flags</h4>
<h4 id="diagnostics_categories">Diagnostic Categories</h4>
<p>Though not shown by default, diagnostics may each be associated with a
high-level category. This category is intended to make it possible to triage
builds that produce a large number of errors or warnings in a grouped way.
</p>
<p>Categories are not shown by default, but they can be turned on with the
<a href="#opt_fdiagnostics-show-category">-fdiagnostics-show-category</a> option.
When set to "<tt>name</tt>", the category is printed textually in the diagnostic
output. When it is set to "<tt>id</tt>", a category number is printed. The
mapping of category names to category id's can be obtained by running '<tt>clang
--print-diagnostic-categories</tt>'.
</p>
<h4 id="diagnostics_commandline">Controlling Diagnostics via Command Line
Flags</h4>
<p>-W flags, -pedantic, etc</p>

View File

@ -50,10 +50,13 @@ parse errors. The output of this stage is an "Abstract Syntax Tree" (AST).
=item B<Code Generation and Optimization>
This stage translates an AST into low-level intermediate code (known as "LLVM
IR") and ultimately to machine code (depending on the optimization level). This
phase is responsible for optimizing the generated code and handling
target-specfic code generation. The output of this stage is typically called a
".s" file or "assembly" file.
IR") and ultimately to machine code. This phase is responsible for optimizing
the generated code and handling target-specfic 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
generator produces object files directly. This avoids the overhead of generating
the ".s" file and of calling the target assembler.
=item B<Assembler>
@ -325,17 +328,21 @@ Pass I<arg> to the assembler.
=item B<-Xclang> I<arg>
Pass I<arg> to the clang compiler.
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.
=item B<-o> I<file>
=item B<-o> I<file>
Write output to I<file>.
@ -359,6 +366,12 @@ Print the paths used for finding libraries and programs.
Save intermediate compilation results.
=item B<-integrated-as> B<-no-integrated-as>
Used to enable and disable, respectively, the use of the integrated
assembler. Whether the integrated assembler is on by default is target
dependent.
=item B<-time>
Time individual commands.

View File

@ -342,6 +342,12 @@ CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range);
*/
CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
/**
* \brief Determine if the source location occurs within the main file
* of the translation unit (as opposed to an included header).
*/
CINDEX_LINKAGE unsigned clang_isFromMainFile(CXSourceLocation loc);
/**
* @}
*/
@ -648,7 +654,6 @@ CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit);
*/
enum CXCursorKind {
/* Declarations */
CXCursor_FirstDecl = 1,
/**
* \brief A declaration whose specific kind is not exposed via this
* interface.
@ -700,11 +705,15 @@ enum CXCursorKind {
CXCursor_ObjCCategoryImplDecl = 19,
/** \brief A typedef */
CXCursor_TypedefDecl = 20,
/** \brief A C++ class method. */
CXCursor_CXXMethod = 21,
/** \brief A C++ namespace. */
CXCursor_Namespace = 22,
/** \brief A linkage specification, e.g. 'extern "C"'. */
CXCursor_LinkageSpec = 23,
CXCursor_LastDecl = 21,
CXCursor_FirstDecl = CXCursor_UnexposedDecl,
CXCursor_LastDecl = CXCursor_LinkageSpec,
/* References */
CXCursor_FirstRef = 40, /* Decl references */
@ -807,7 +816,8 @@ enum CXCursorKind {
CXCursor_IBActionAttr = 401,
CXCursor_IBOutletAttr = 402,
CXCursor_LastAttr = CXCursor_IBOutletAttr,
CXCursor_IBOutletCollectionAttr = 403,
CXCursor_LastAttr = CXCursor_IBOutletCollectionAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@ -1016,6 +1026,124 @@ CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor);
*/
CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor);
/**
* @}
*/
/**
* \defgroup CINDEX_TYPES Type information for CXCursors
*
* @{
*/
/**
* \brief Describes the kind of type
*/
enum CXTypeKind {
/**
* \brief Reprents an invalid type (e.g., where no type is available).
*/
CXType_Invalid = 0,
/**
* \brief A type whose specific kind is not exposed via this
* interface.
*/
CXType_Unexposed = 1,
/* Builtin types */
CXType_Void = 2,
CXType_Bool = 3,
CXType_Char_U = 4,
CXType_UChar = 5,
CXType_Char16 = 6,
CXType_Char32 = 7,
CXType_UShort = 8,
CXType_UInt = 9,
CXType_ULong = 10,
CXType_ULongLong = 11,
CXType_UInt128 = 12,
CXType_Char_S = 13,
CXType_SChar = 14,
CXType_WChar = 15,
CXType_Short = 16,
CXType_Int = 17,
CXType_Long = 18,
CXType_LongLong = 19,
CXType_Int128 = 20,
CXType_Float = 21,
CXType_Double = 22,
CXType_LongDouble = 23,
CXType_NullPtr = 24,
CXType_Overload = 25,
CXType_Dependent = 26,
CXType_ObjCId = 27,
CXType_ObjCClass = 28,
CXType_ObjCSel = 29,
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_ObjCSel,
CXType_Complex = 100,
CXType_Pointer = 101,
CXType_BlockPointer = 102,
CXType_LValueReference = 103,
CXType_RValueReference = 104,
CXType_Record = 105,
CXType_Enum = 106,
CXType_Typedef = 107,
CXType_ObjCInterface = 108,
CXType_ObjCObjectPointer = 109
};
/**
* \brief The type of an element in the abstract syntax tree.
*
*/
typedef struct {
enum CXTypeKind kind;
void *data[2];
} CXType;
/**
* \brief Retrieve the type of a CXCursor (if any).
*/
CINDEX_LINKAGE CXType clang_getCursorType(CXCursor C);
/**
* \determine Determine whether two CXTypes represent the same type.
*
* \returns non-zero if the CXTypes represent the same type and
zero otherwise.
*/
CINDEX_LINKAGE unsigned clang_equalTypes(CXType A, CXType B);
/**
* \brief Return the canonical type for a CXType.
*
* Clang's type system explicitly models typedefs and all the ways
* a specific type can be represented. The canonical type is the underlying
* type with all the "sugar" removed. For example, if 'T' is a typedef
* for 'int', the canonical type for 'T' would be 'int'.
*/
CINDEX_LINKAGE CXType clang_getCanonicalType(CXType T);
/**
* \brief For pointer types, returns the type of the pointee.
*
*/
CINDEX_LINKAGE CXType clang_getPointeeType(CXType T);
/**
* \brief Return the cursor for the declaration of the given type.
*/
CINDEX_LINKAGE CXCursor clang_getTypeDeclaration(CXType T);
/**
* \brief Retrieve the spelling of a given CXTypeKind.
*/
CINDEX_LINKAGE CXString clang_getTypeKindSpelling(enum CXTypeKind K);
/**
* @}
*/
@ -1215,6 +1343,24 @@ CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor);
*/
CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor);
/**
* @}
*/
/**
* \defgroup CINDEX_CPP C++ AST introspection
*
* The routines in this group provide access information in the ASTs specific
* to C++ language features.
*
* @{
*/
/**
* \brief Determine if a C++ member function is declared 'static'.
*/
CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
/**
* @}
*/
@ -1648,6 +1794,21 @@ clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
CINDEX_LINKAGE unsigned
clang_getNumCompletionChunks(CXCompletionString completion_string);
/**
* \brief Determine the priority of this code completion.
*
* The priority of a code completion indicates how likely it is that this
* particular completion is the completion that the user will select. The
* priority is selected by various internal heuristics.
*
* \param completion_string The completion string to query.
*
* \returns The priority of this completion string. Smaller values indicate
* higher-priority (more likely) completions.
*/
CINDEX_LINKAGE unsigned
clang_getCompletionPriority(CXCompletionString completion_string);
/**
* \brief Contains the results of code-completion.
*

View File

@ -16,6 +16,7 @@
namespace clang {
class ASTContext;
class CXXRecordDecl;
class DeclGroupRef;
class TagDecl;
class HandleTagDeclDefinition;
@ -68,6 +69,17 @@ class ASTConsumer {
/// modified by the introduction of an implicit zero initializer.
virtual void CompleteTentativeDefinition(VarDecl *D) {}
/// \brief Callback involved at the end of a translation unit to
/// notify the consumer that a vtable for the given C++ class is
/// required.
///
/// \param RD The class whose vtable was used.
///
/// \param DefinitionRequired Whether a definition of this vtable is
/// required in this translation unit; otherwise, it is only needed if
/// it was actually used.
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}

View File

@ -96,11 +96,10 @@ class ASTContext {
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@ -483,7 +482,7 @@ class ASTContext {
/// This gets the struct used to keep track of pointer to blocks, complete
/// with captured variables.
QualType getBlockParmType(bool BlockHasCopyDispose,
llvm::SmallVector<const Expr *, 8> &BDRDs);
llvm::SmallVectorImpl<const Expr *> &Layout);
/// This builds the struct used for __block variables.
QualType BuildByRefType(const char *DeclName, QualType Ty);
@ -613,8 +612,9 @@ class ASTContext {
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
QualType NamedType);
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@ -623,19 +623,16 @@ class ASTContext {
NestedNameSpecifier *NNS,
const TemplateSpecializationType *TemplateId,
QualType Canon = QualType());
QualType getElaboratedType(QualType UnderlyingType,
ElaboratedType::TagKind Tag);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
ObjCProtocolDecl **Protocols = 0,
unsigned NumProtocols = 0);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for the
/// given interface decl and the conforming protocol list.
QualType getObjCObjectPointerType(QualType OIT,
ObjCProtocolDecl **ProtocolList = 0,
unsigned NumProtocols = 0,
unsigned Quals = 0);
QualType getObjCObjectType(QualType Base,
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols);
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type
/// for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT);
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
@ -913,6 +910,9 @@ class ASTContext {
CharUnits getTypeAlignInChars(QualType T);
CharUnits getTypeAlignInChars(const Type *T);
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T);
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T);
/// getPreferredTypeAlign - Return the "preferred" alignment of the specified
/// type for the current target in bits. This can be different than the ABI
/// alignment in cases where it is beneficial for performance to overalign
@ -1184,8 +1184,8 @@ class ASTContext {
// Check the safety of assignment from LHS to RHS
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
const ObjCInterfaceType *RHS);
bool canAssignObjCInterfaces(const ObjCObjectType *LHS,
const ObjCObjectType *RHS);
bool canAssignObjCInterfacesInBlockPointer(
const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT);
@ -1196,6 +1196,8 @@ class ASTContext {
// Functions for calculating composite types
QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false);
QualType mergeObjCGCQualifiers(QualType, QualType);
/// UsualArithmeticConversionsType - handles the various conversions
/// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
@ -1270,6 +1272,15 @@ class ASTContext {
TypeSourceInfo *
getTrivialTypeSourceInfo(QualType T, SourceLocation Loc = SourceLocation());
/// \brief Add a deallocation callback that will be invoked when the
/// ASTContext is destroyed.
///
/// \brief Callback A callback function that will be invoked on destruction.
///
/// \brief Data Pointer data that will be provided to the callback function
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
void operator=(const ASTContext&); // DO NOT IMPLEMENT
@ -1284,16 +1295,21 @@ class ASTContext {
const FieldDecl *Field,
bool OutermostType = false,
bool EncodingProperty = false);
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
private:
/// \brief A set of deallocations that should be performed when the
/// ASTContext is destroyed.
llvm::SmallVector<std::pair<void (*)(void*), void *>, 16> Deallocations;
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
};

View File

@ -23,9 +23,10 @@ using llvm::dyn_cast;
namespace clang {
class ASTContext;
class IdentifierInfo;
class ObjCInterfaceDecl;
}
// Defined in ASTContext.h
void *operator new(size_t Bytes, clang::ASTContext &C,
size_t Alignment = 16) throw ();
@ -44,6 +45,7 @@ class Attr {
enum Kind {
Alias,
Aligned,
AlignMac68k,
AlwaysInline,
AnalyzerNoReturn, // Clang-specific.
Annotate,
@ -63,8 +65,10 @@ class Attr {
GNUInline,
Hiding,
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
IBOutletCollectionKind, // Clang-specific.
IBActionKind, // Clang-specific. Use "Kind" suffix to not conflict w/ macro.
Malloc,
MaxFieldAlignment,
NoDebug,
NoInline,
NonNull,
@ -79,13 +83,13 @@ class Attr {
NSReturnsNotRetained, // Clang/Checker-specific.
Overloadable, // Clang-specific
Packed,
PragmaPack,
Pure,
Regparm,
ReqdWorkGroupSize, // OpenCL-specific
Section,
Sentinel,
StdCall,
ThisCall,
TransparentUnion,
Unavailable,
Unused,
@ -183,11 +187,14 @@ public: \
DEF_SIMPLE_ATTR(Packed);
class PragmaPackAttr : public Attr {
/// \brief Attribute for specifying a maximum field alignment; this is only
/// valid on record decls.
class MaxFieldAlignmentAttr : public Attr {
unsigned Alignment;
public:
PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
MaxFieldAlignmentAttr(unsigned alignment)
: Attr(MaxFieldAlignment), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
@ -196,11 +203,13 @@ class PragmaPackAttr : public Attr {
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == PragmaPack;
return A->getKind() == MaxFieldAlignment;
}
static bool classof(const PragmaPackAttr *A) { return true; }
static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
};
DEF_SIMPLE_ATTR(AlignMac68k);
class AlignedAttr : public Attr {
unsigned Alignment;
public:
@ -317,6 +326,23 @@ class IBOutletAttr : public Attr {
static bool classof(const IBOutletAttr *A) { return true; }
};
class IBOutletCollectionAttr : public Attr {
const ObjCInterfaceDecl *D;
public:
IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
: Attr(IBOutletCollectionKind), D(d) {}
const ObjCInterfaceDecl *getClass() const { return D; }
virtual Attr *clone(ASTContext &C) const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == IBOutletCollectionKind;
}
static bool classof(const IBOutletCollectionAttr *A) { return true; }
};
class IBActionAttr : public Attr {
public:
IBActionAttr() : Attr(IBActionKind) {}
@ -457,6 +483,7 @@ class VisibilityAttr : public Attr {
DEF_SIMPLE_ATTR(FastCall);
DEF_SIMPLE_ATTR(StdCall);
DEF_SIMPLE_ATTR(ThisCall);
DEF_SIMPLE_ATTR(CDecl);
DEF_SIMPLE_ATTR(TransparentUnion);
DEF_SIMPLE_ATTR(ObjCNSObject);

View File

@ -0,0 +1,5 @@
set(LLVM_TARGET_DEFINITIONS StmtNodes.td)
tablegen(StmtNodes.inc
-gen-clang-stmt-nodes)
add_custom_target(ClangStmtNodes
DEPENDS StmtNodes.inc)

View File

@ -196,7 +196,7 @@ class CXXBasePaths {
/// \brief Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
/// the same base type).
bool isAmbiguous(QualType BaseType);
bool isAmbiguous(CanQualType BaseType);
/// \brief Whether we are finding multiple paths to detect ambiguities.
bool isFindingAmbiguities() const { return FindAmbiguities; }

View File

@ -642,6 +642,24 @@ struct CanProxyAdaptor<TemplateTypeParmType>
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(IdentifierInfo *, getName)
};
template<>
struct CanProxyAdaptor<ObjCObjectType>
: public CanProxyBase<ObjCObjectType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const ObjCInterfaceDecl *,
getInterface)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedId)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCUnqualifiedClass)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
typedef ObjCObjectPointerType::qual_iterator qual_iterator;
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumProtocols)
};
template<>
struct CanProxyAdaptor<ObjCObjectPointerType>
: public CanProxyBase<ObjCObjectPointerType> {

View File

@ -55,7 +55,7 @@ class TypeSourceInfo {
QualType getType() const { return Ty; }
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const;
TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
};
/// TranslationUnitDecl - The top declaration context.
@ -138,6 +138,8 @@ class NamedDecl : public Decl {
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
void printName(llvm::raw_ostream &os) const { return Name.printName(os); }
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
DeclarationName getDeclName() const { return Name; }
@ -265,18 +267,25 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
// \brief Returns true if this is an anonymous namespace declaration.
//
// For example:
/// \code
// namespace {
// ...
// };
// \endcode
// q.v. C++ [namespace.unnamed]
bool isAnonymousNamespace() const {
return !getIdentifier();
}
/// \brief Return the next extended namespace declaration or null if this
/// is none.
NamespaceDecl *getNextNamespace() { return NextNamespace; }
const NamespaceDecl *getNextNamespace() const { return NextNamespace; }
/// \brief Set the next extended namespace declaration.
void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
/// \brief Get the original (first) namespace declaration.
NamespaceDecl *getOriginalNamespace() const {
if (OrigOrAnonNamespace.getInt())
return const_cast<NamespaceDecl *>(this);
@ -284,6 +293,14 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
return OrigOrAnonNamespace.getPointer();
}
/// \brief Return true if this declaration is an original (first) declaration
/// of the namespace. This is false for non-original (subsequent) namespace
/// declarations and anonymous namespaces.
bool isOriginalNamespace() const {
return getOriginalNamespace() == this;
}
/// \brief Set the original (first) namespace declaration.
void setOriginalNamespace(NamespaceDecl *ND) {
if (ND != this) {
OrigOrAnonNamespace.setPointer(ND);
@ -502,6 +519,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// or an Objective-C @catch statement.
bool 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;
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
@ -509,7 +530,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
DeclaredInCondition(false), ExceptionVar(false) {
DeclaredInCondition(false), ExceptionVar(false), NRVOVariable(false) {
SClass = SC;
SClassAsWritten = SCAsWritten;
}
@ -852,6 +873,19 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
}
void setExceptionVariable(bool EV) { ExceptionVar = EV; }
/// \brief Determine whether this local variable can be used with the named
/// return value optimization (NRVO).
///
/// The named return value optimization (NRVO) works by marking certain
/// non-volatile local variables of class type as NRVO objects. These
/// locals can be allocated within the return slot of their containing
/// function, in which case there is no need to copy the object to the
/// 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; }
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
@ -1390,6 +1424,16 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// returns NULL.
const TemplateArgumentList *getTemplateSpecializationArgs() const;
/// \brief Retrieve the template argument list as written in the sources,
/// if any.
///
/// If this function declaration is not a function template specialization
/// or if it had no explicit template argument list, returns NULL.
/// Note that it an explicit template argument list may be written empty,
/// e.g., template<> void foo<>(char* s);
const TemplateArgumentListInfo*
getTemplateSpecializationArgsAsWritten() const;
/// \brief Specify that this function declaration is actually a function
/// template specialization.
///
@ -1409,7 +1453,8 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
const TemplateArgumentListInfo *TemplateArgsAsWritten = 0);
/// \brief Specifies that this function declaration is actually a
/// dependent function template specialization.
@ -1593,7 +1638,19 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
: TypeDecl(Typedef, DC, L, Id), TInfo(TInfo) {}
virtual ~TypedefDecl();
protected:
typedef Redeclarable<TypedefDecl> redeclarable_base;
virtual TypedefDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
public:
typedef redeclarable_base::redecl_iterator redecl_iterator;
redecl_iterator redecls_begin() const {
return redeclarable_base::redecls_begin();
}
redecl_iterator redecls_end() const {
return redeclarable_base::redecls_end();
}
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@ -1631,11 +1688,7 @@ class TagDecl
: public TypeDecl, public DeclContext, public Redeclarable<TagDecl> {
public:
// This is really ugly.
typedef ElaboratedType::TagKind TagKind;
static const TagKind TK_struct = ElaboratedType::TK_struct;
static const TagKind TK_union = ElaboratedType::TK_union;
static const TagKind TK_class = ElaboratedType::TK_class;
static const TagKind TK_enum = ElaboratedType::TK_enum;
typedef TagTypeKind TagKind;
private:
// FIXME: This can be packed into the bitfields in Decl.
@ -1651,6 +1704,12 @@ class TagDecl
/// in the syntax of a declarator.
bool IsEmbeddedInDeclarator : 1;
protected:
// These are used by (and only defined for) EnumDecl.
unsigned NumPositiveBits : 8;
unsigned NumNegativeBits : 8;
private:
SourceLocation TagKeywordLoc;
SourceLocation RBraceLoc;
@ -1680,7 +1739,8 @@ class TagDecl
TagDecl *PrevDecl, SourceLocation TKL = SourceLocation())
: TypeDecl(DK, DC, L, Id), DeclContext(DK), TagKeywordLoc(TKL),
TypedefDeclOrQualifier((TypedefDecl*) 0) {
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
TagDeclKind = TK;
IsDefinition = false;
IsEmbeddedInDeclarator = false;
@ -1753,30 +1813,26 @@ class TagDecl
void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
return ElaboratedType::getNameForTagKind(getTagKind());
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
/// getTagKindForTypeSpec - Converts a type specifier (DeclSpec::TST)
/// into a tag kind. It is an error to provide a type specifier
/// which *isn't* a tag kind here.
static TagKind getTagKindForTypeSpec(unsigned TypeSpec);
TagKind getTagKind() const {
return TagKind(TagDeclKind);
}
void setTagKind(TagKind TK) { TagDeclKind = TK; }
bool isStruct() const { return getTagKind() == TK_struct; }
bool isClass() const { return getTagKind() == TK_class; }
bool isUnion() const { return getTagKind() == TK_union; }
bool isEnum() const { return getTagKind() == TK_enum; }
bool isStruct() const { return getTagKind() == TTK_Struct; }
bool isClass() const { return getTagKind() == TTK_Class; }
bool isUnion() const { return getTagKind() == TTK_Union; }
bool isEnum() const { return getTagKind() == TTK_Enum; }
TypedefDecl *getTypedefForAnonDecl() const {
return hasExtInfo() ? 0 : TypedefDeclOrQualifier.get<TypedefDecl*>();
}
void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefDeclOrQualifier = TDD; }
void setTypedefForAnonDecl(TypedefDecl *TDD);
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? TypedefDeclOrQualifier.get<ExtInfo*>()->NNS : 0;
}
@ -1820,9 +1876,16 @@ class EnumDecl : public TagDecl {
/// enumeration declared within the template.
EnumDecl *InstantiatedFrom;
// The number of positive and negative bits required by the
// enumerators are stored in the SubclassBits field.
enum {
NumBitsWidth = 8,
NumBitsMask = (1 << NumBitsWidth) - 1
};
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL)
: TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
: TagDecl(Enum, TTK_Enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) {
IntegerType = QualType();
}
public:
@ -1845,7 +1908,9 @@ class EnumDecl : public TagDecl {
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(QualType NewType,
QualType PromotionType);
QualType PromotionType,
unsigned NumPositiveBits,
unsigned NumNegativeBits);
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
@ -1873,6 +1938,32 @@ class EnumDecl : public TagDecl {
/// \brief Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T; }
/// \brief Returns the width in bits requred to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
return NumPositiveBits;
}
void setNumPositiveBits(unsigned Num) {
NumPositiveBits = Num;
assert(NumPositiveBits == Num && "can't store this bitcount");
}
/// \brief Returns the width in bits requred to store all the
/// negative enumerators of this enum. These widths include
/// the rightmost leading 1; that is:
///
/// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS
/// ------------------------ ------- -----------------
/// -1 1111111 1
/// -10 1110110 5
/// -101 1001011 8
unsigned getNumNegativeBits() const {
return NumNegativeBits;
}
void setNumNegativeBits(unsigned Num) {
NumNegativeBits = Num;
}
/// \brief Returns the enumeration (declared within the template)
/// from which this enumeration type was instantiated, or NULL if
/// this enumeration was not instantiated from any template.
@ -1942,6 +2033,11 @@ class RecordDecl : public TagDecl {
AnonymousStructOrUnion = Anon;
}
ValueDecl *getAnonymousStructOrUnionObject();
const ValueDecl *getAnonymousStructOrUnionObject() const {
return const_cast<RecordDecl*>(this)->getAnonymousStructOrUnionObject();
}
bool hasObjectMember() const { return HasObjectMember; }
void setHasObjectMember (bool val) { HasObjectMember = val; }

View File

@ -76,6 +76,11 @@ class Decl {
#include "clang/AST/DeclNodes.def"
};
/// \brief A placeholder type used to construct an empty shell of a
/// decl-derived type that will be filled in later (e.g., by some
/// deserialization method).
struct EmptyShell { };
/// IdentifierNamespace - The different namespaces in which
/// declarations may appear. According to C99 6.2.3, there are
/// four namespaces, labels, tags, members and ordinary

View File

@ -1061,10 +1061,6 @@ class CXXBaseOrMemberInitializer {
/// In above example, BaseOrMember holds the field decl. for anonymous union
/// and AnonUnionMember holds field decl for au_i1.
FieldDecl *AnonUnionMember;
/// IsVirtual - If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
bool IsVirtual;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@ -1072,6 +1068,28 @@ class CXXBaseOrMemberInitializer {
/// RParenLoc - Location of the right paren of the ctor-initializer.
SourceLocation RParenLoc;
/// IsVirtual - If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
bool IsVirtual : 1;
/// IsWritten - Whether or not the initializer is explicitly written
/// in the sources.
bool IsWritten : 1;
/// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
/// number keeps track of the textual order of this initializer in the
/// original sources, counting from 0; otherwise, if IsWritten is false,
/// it stores the number of array index variables stored after this
/// object in memory.
unsigned SourceOrderOrNumArrayIndices : 14;
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
SourceLocation L,
Expr *Init,
SourceLocation R,
VarDecl **Indices,
unsigned NumIndices);
public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
@ -1089,6 +1107,17 @@ class CXXBaseOrMemberInitializer {
Expr *Init,
SourceLocation R);
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
FieldDecl *Member,
SourceLocation MemberLoc,
SourceLocation L,
Expr *Init,
SourceLocation R,
VarDecl **Indices,
unsigned NumIndices);
/// \brief Destroy the base or member initializer.
void Destroy(ASTContext &Context);
@ -1146,6 +1175,30 @@ class CXXBaseOrMemberInitializer {
/// \brief Determine the source range covering the entire initializer.
SourceRange getSourceRange() const;
/// isWritten - Returns true if this initializer is explicitly written
/// in the source code.
bool isWritten() const { return IsWritten; }
/// \brief Return the source position of the initializer, counting from 0.
/// If the initializer was implicit, -1 is returned.
int getSourceOrder() const {
return IsWritten ? static_cast<int>(SourceOrderOrNumArrayIndices) : -1;
}
/// \brief Set the source order of this initializer. This method can only
/// be called once for each initializer; it cannot be called on an
/// initializer having a positive number of (implicit) array indices.
void setSourceOrder(int pos) {
assert(!IsWritten &&
"calling twice setSourceOrder() on the same initializer");
assert(SourceOrderOrNumArrayIndices == 0 &&
"setSourceOrder() used when there are implicit array indices");
assert(pos >= 0 &&
"setSourceOrder() used to make an initializer implicit");
IsWritten = true;
SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
}
FieldDecl *getAnonUnionMember() const {
return AnonUnionMember;
@ -1154,9 +1207,31 @@ class CXXBaseOrMemberInitializer {
AnonUnionMember = anonMember;
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
/// \brief Determine the number of implicit array indices used while
/// described an array member initialization.
unsigned getNumArrayIndices() const {
return IsWritten ? 0 : SourceOrderOrNumArrayIndices;
}
/// \brief Retrieve a particular array index variable used to
/// describe an array member initialization.
VarDecl *getArrayIndex(unsigned I) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
return reinterpret_cast<VarDecl **>(this + 1)[I];
}
const VarDecl *getArrayIndex(unsigned I) const {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
return reinterpret_cast<const VarDecl * const *>(this + 1)[I];
}
void setArrayIndex(unsigned I, VarDecl *Index) {
assert(I < getNumArrayIndices() && "Out of bounds member array index");
reinterpret_cast<VarDecl **>(this + 1)[I] = Index;
}
Expr *getInit() { return static_cast<Expr *>(Init); }
};
@ -1201,6 +1276,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
virtual void Destroy(ASTContext& C);
public:
static CXXConstructorDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@ -1343,6 +1419,7 @@ class CXXDestructorDecl : public CXXMethodDecl {
}
public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, bool isInline,
@ -1398,6 +1475,7 @@ class CXXConversionDecl : public CXXMethodDecl {
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, EmptyShell Empty);
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
@ -1438,8 +1516,10 @@ class LinkageSpecDecl : public Decl, public DeclContext {
/// ASTs and cannot be changed without altering that abi. To help
/// ensure a stable abi for this, we choose the DW_LANG_ encodings
/// from the dwarf standard.
enum LanguageIDs { lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 };
enum LanguageIDs {
lang_c = /* DW_LANG_C */ 0x0002,
lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004
};
private:
/// Language - The language for this linkage specification.
LanguageIDs Language;
@ -1457,12 +1537,20 @@ class LinkageSpecDecl : public Decl, public DeclContext {
SourceLocation L, LanguageIDs Lang,
bool Braces);
/// \brief Return the language specified by this linkage specification.
LanguageIDs getLanguage() const { return Language; }
/// hasBraces - Determines whether this linkage specification had
/// braces in its syntactic form.
/// \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; }
/// \brief Set whether this linkage specification has braces in its
/// syntactic form.
void setHasBraces(bool B) { HadBraces = B; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const LinkageSpecDecl *D) { return true; }
static bool classofKind(Kind K) { return K == LinkageSpec; }
@ -1528,13 +1616,21 @@ class UsingDirectiveDecl : public NamedDecl {
public:
/// \brief Retrieve the source range of the nested-name-specifier
/// that qualifiers the namespace name.
/// that qualifies the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Set the source range of the nested-name-specifier that
/// qualifies the namespace name.
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// \brief Set the nested-name-specifier that qualifes the name of the
/// namespace.
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
NamedDecl *getNominatedNamespaceAsWritten() { return NominatedNamespace; }
const NamedDecl *getNominatedNamespaceAsWritten() const {
return NominatedNamespace;
@ -1547,17 +1643,32 @@ class UsingDirectiveDecl : public NamedDecl {
return const_cast<UsingDirectiveDecl*>(this)->getNominatedNamespace();
}
/// getCommonAncestor - returns common ancestor context of using-directive,
/// and nominated by it namespace.
/// setNominatedNamespace - Set the namespace nominataed by the
/// using-directive.
void setNominatedNamespace(NamedDecl* NS);
/// \brief Returns the common ancestor context of this using-directive and
/// its nominated namespace.
DeclContext *getCommonAncestor() { return CommonAncestor; }
const DeclContext *getCommonAncestor() const { return CommonAncestor; }
/// \brief Set the common ancestor context of this using-directive and its
/// nominated namespace.
void setCommonAncestor(DeclContext* Cxt) { CommonAncestor = Cxt; }
// FIXME: Could omit 'Key' in name.
/// getNamespaceKeyLocation - Returns location of namespace keyword.
SourceLocation getNamespaceKeyLocation() const { return NamespaceLoc; }
/// setNamespaceKeyLocation - Set the the location of the namespacekeyword.
void setNamespaceKeyLocation(SourceLocation L) { NamespaceLoc = L; }
/// getIdentLocation - Returns location of identifier.
SourceLocation getIdentLocation() const { return IdentLoc; }
/// setIdentLocation - set the location of the identifier.
void setIdentLocation(SourceLocation L) { IdentLoc = L; }
static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation NamespaceLoc,
@ -1591,7 +1702,7 @@ class NamespaceAliasDecl : public NamedDecl {
/// name, if any.
NestedNameSpecifier *Qualifier;
/// IdentLoc - Location of namespace identifier.
/// IdentLoc - Location of namespace identifier. Accessed by TargetNameLoc.
SourceLocation IdentLoc;
/// Namespace - The Decl that this alias points to. Can either be a
@ -1612,10 +1723,19 @@ class NamespaceAliasDecl : public NamedDecl {
/// that qualifiers the namespace name.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Set the source range of the nested-name-specifier that qualifies
/// the namespace name.
void setQualifierRange(SourceRange R) { QualifierRange = R; }
/// \brief Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// \brief Set the nested-name-specifier that qualifies the name of the
/// namespace.
void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; }
/// \brief Retrieve the namespace declaration aliased by this directive.
NamespaceDecl *getNamespace() {
if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(Namespace))
return AD->getNamespace();
@ -1631,16 +1751,31 @@ class NamespaceAliasDecl : public NamedDecl {
/// "namespace foo = ns::bar;".
SourceLocation getAliasLoc() const { return AliasLoc; }
/// Set the location o;f the alias name, e.e., 'foo' in
/// "namespace foo = ns::bar;".
void setAliasLoc(SourceLocation L) { AliasLoc = L; }
/// Returns the location of the 'namespace' keyword.
SourceLocation getNamespaceLoc() const { return getLocation(); }
/// Returns the location of the identifier in the named namespace.
SourceLocation getTargetNameLoc() const { return IdentLoc; }
/// Set the location of the identifier in the named namespace.
void setTargetNameLoc(SourceLocation L) { IdentLoc = L; }
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
/// \brief Set the namespace or namespace alias pointed to by this
/// alias decl.
void setAliasedNamespace(NamedDecl *ND) {
assert((isa<NamespaceAliasDecl>(ND) || isa<NamespaceDecl>(ND)) &&
"expecting namespace or namespace alias decl");
Namespace = ND;
}
static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, SourceLocation AliasLoc,
IdentifierInfo *Alias,
@ -1687,16 +1822,20 @@ class UsingShadowDecl : public NamedDecl {
return new (C) UsingShadowDecl(DC, Loc, Using, Target);
}
/// Gets the underlying declaration which has been brought into the
/// \brief Gets the underlying declaration which has been brought into the
/// local scope.
NamedDecl *getTargetDecl() const {
return Underlying;
}
NamedDecl *getTargetDecl() const { return Underlying; }
/// Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const {
return Using;
}
/// \brief Sets the underlying declaration which has been brought into the
/// local scope.
void setTargetDecl(NamedDecl* ND) { Underlying = ND; }
/// \brief Gets the using declaration to which this declaration is tied.
UsingDecl *getUsingDecl() const { return Using; }
/// \brief Sets the using declaration that introduces this target
/// declaration.
void setUsingDecl(UsingDecl* UD) { Using = UD; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
@ -1733,21 +1872,39 @@ class UsingDecl : public NamedDecl {
}
public:
// FIXME: Should be const?
/// \brief Returns the source range that covers the nested-name-specifier
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
/// \brief Returns the source location of the "using" location itself.
/// \brief Set the source range of the nested-name-specifier.
void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
// FIXME; Should be const?
// FIXME: Naming is inconsistent with other get*Loc functions.
/// \brief Returns the source location of the "using" keyword.
SourceLocation getUsingLocation() { return UsingLocation; }
/// \brief Get target nested name declaration.
/// \brief Set the source location of the 'using' keyword.
void setUsingLocation(SourceLocation L) { UsingLocation = L; }
/// \brief Get the target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
return TargetNestedName;
}
/// isTypeName - Return true if using decl has 'typename'.
/// \brief Set the target nested name declaration.
void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
TargetNestedName = NNS;
}
/// \brief Return true if the using declaration has 'typename'.
bool isTypeName() const { return IsTypeName; }
/// \brief Sets whether the using declaration has 'typename'.
void setTypeName(bool TN) { IsTypeName = TN; }
typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
shadow_iterator shadow_begin() const { return Shadows.begin(); }
shadow_iterator shadow_end() const { return Shadows.end(); }
@ -1765,6 +1922,12 @@ class UsingDecl : public NamedDecl {
}
}
/// \brief Return the number of shadowed declarations associated with this
/// using declaration.
unsigned getNumShadowDecls() const {
return Shadows.size();
}
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
@ -1807,14 +1970,26 @@ class UnresolvedUsingValueDecl : public ValueDecl {
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
/// \brief Set the source range coverting the nested-name-specifier preceding
/// the namespace name.
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
/// \brief Set the nested name declaration.
void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
TargetNestedNameSpecifier = NNS;
}
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
static UnresolvedUsingValueDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
@ -1861,17 +2036,32 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
/// preceding the namespace name.
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
/// \brief Set the source range coverting the nested-name-specifier preceding
/// the namespace name.
void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameSpecifier() {
return TargetNestedNameSpecifier;
}
/// \brief Set the nested name declaration.
void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
TargetNestedNameSpecifier = NNS;
}
/// \brief Returns the source location of the 'using' keyword.
SourceLocation getUsingLoc() const { return UsingLocation; }
/// \brief Set the source location of the 'using' keyword.
void setUsingLoc(SourceLocation L) { UsingLocation = L; }
/// \brief Returns the source location of the 'typename' keyword.
SourceLocation getTypenameLoc() const { return TypenameLocation; }
/// \brief Set the source location of the 'typename' keyword.
void setTypenameLoc(SourceLocation L) { TypenameLocation = L; }
static UnresolvedUsingTypenameDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
SourceLocation TypenameLoc,

View File

@ -156,7 +156,8 @@ struct StoredDeclsList {
/// represents.
DeclContext::lookup_result getLookupResult(ASTContext &Context) {
if (isNull())
return DeclContext::lookup_result(0, 0);
return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
DeclContext::lookup_iterator(0));
if (hasDeclarationIDs())
materializeDecls(Context);

View File

@ -1421,13 +1421,21 @@ class ObjCPropertyImplDecl : public Decl {
/// Null for @dynamic. Required for @synthesize.
ObjCIvarDecl *PropertyIvarDecl;
/// Null for @dynamic. Non-null if property must be copy-constructed in getter
Expr *GetterCXXConstructor;
/// Null for @dynamic. Non-null if property has assignment operator to call
/// in Setter synthesis.
Expr *SetterCXXAssignment;
ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl)
: Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
PropertyDecl(property), PropertyIvarDecl(ivarDecl),
GetterCXXConstructor(0), SetterCXXAssignment(0) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@ -1457,7 +1465,21 @@ class ObjCPropertyImplDecl : public Decl {
return PropertyIvarDecl;
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
Expr *getGetterCXXConstructor() const {
return GetterCXXConstructor;
}
void setGetterCXXConstructor(Expr *getterCXXConstructor) {
GetterCXXConstructor = getterCXXConstructor;
}
Expr *getSetterCXXAssignment() const {
return SetterCXXAssignment;
}
void setSetterCXXAssignment(Expr *setterCXXAssignment) {
SetterCXXAssignment = setterCXXAssignment;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyImplDecl *D) { return true; }
static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }

View File

@ -112,7 +112,7 @@ class TemplateArgumentListBuilder {
unsigned MaxStructuredArgs;
unsigned NumStructuredArgs;
TemplateArgument *FlatArgs;
llvm::SmallVector<TemplateArgument, 4> FlatArgs;
unsigned MaxFlatArgs;
unsigned NumFlatArgs;
@ -127,18 +127,12 @@ class TemplateArgumentListBuilder {
MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
AddingToPack(false), PackBeginIndex(0) { }
void Append(const TemplateArgument& Arg);
void Append(const TemplateArgument &Arg);
void BeginPack();
void EndPack();
void ReleaseArgs();
unsigned flatSize() const {
return NumFlatArgs;
}
const TemplateArgument *getFlatArguments() const {
return FlatArgs;
}
unsigned flatSize() const { return FlatArgs.size(); }
const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
unsigned structuredSize() const {
// If we don't have any structured args, just reuse the flat size.
@ -165,7 +159,7 @@ class TemplateArgumentList {
/// \brief The template argument list.
///
/// The integer value will be non-zero to indicate that this
/// template argument list does not own the pointer.
/// template argument list does own the pointer.
llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
/// \brief The number of template arguments in this template
@ -175,14 +169,28 @@ class TemplateArgumentList {
llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
unsigned NumStructuredArguments;
TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
public:
/// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
/// it copies them into a locally new[]'d array. If passed "false", then it
/// just references the array passed in. This is only safe if the builder
/// outlives it, but saves a copy.
TemplateArgumentList(ASTContext &Context,
TemplateArgumentListBuilder &Builder,
bool TakeArgs);
/// \brief Produces a shallow copy of the given template argument list
TemplateArgumentList(const TemplateArgumentList &Other);
/// Produces a shallow copy of the given template argument list. This
/// assumes that the input argument list outlives it. This takes the list as
/// a pointer to avoid looking like a copy constructor, since this really
/// really isn't safe to use that way.
explicit TemplateArgumentList(const TemplateArgumentList *Other);
/// Used to release the memory associated with a TemplateArgumentList
/// object. FIXME: This is currently not called anywhere, but the
/// memory will still be freed when using a BumpPtrAllocator.
void Destroy(ASTContext &C);
~TemplateArgumentList();
/// \brief Retrieve the template argument at a given index.
@ -280,6 +288,9 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
/// specialization from the function template.
const TemplateArgumentList *TemplateArguments;
/// \brief The template arguments as written in the sources, if provided.
const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
/// \brief The point at which this function template specialization was
/// first instantiated.
SourceLocation PointOfInstantiation;
@ -454,6 +465,8 @@ class DependentFunctionTemplateSpecializationInfo {
/// Declaration of a template function.
class FunctionTemplateDecl : public TemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
/// \brief Data that is common to all of the declarations of a given
/// function template.
@ -862,7 +875,7 @@ class ClassTemplateSpecializationDecl
unsigned SpecializationKind : 3;
protected:
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@ -870,7 +883,7 @@ class ClassTemplateSpecializationDecl
public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
@ -1024,7 +1037,7 @@ class ClassTemplatePartialSpecializationDecl
llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
InstantiatedFromMember;
ClassTemplatePartialSpecializationDecl(ASTContext &Context,
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
@ -1035,7 +1048,7 @@ class ClassTemplatePartialSpecializationDecl
unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
TK, DC, L, SpecializedTemplate, Builder,
PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
@ -1043,7 +1056,7 @@ class ClassTemplatePartialSpecializationDecl
public:
static ClassTemplatePartialSpecializationDecl *
Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@ -1158,6 +1171,8 @@ class ClassTemplatePartialSpecializationDecl
/// Declaration of a class template.
class ClassTemplateDecl : public TemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
/// \brief Data that is common to all of the declarations of a given
/// class template.

View File

@ -314,15 +314,16 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
/// retrieved using its member functions (e.g.,
/// getCXXConstructorName).
class DeclarationNameTable {
ASTContext &Ctx;
void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
CXXOperatorIdName *CXXOperatorNames; // Operator names
void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> *
void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName*
DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE
DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
public:
DeclarationNameTable();
DeclarationNameTable(ASTContext &C);
~DeclarationNameTable();
/// getIdentifier - Create a declaration name that is a simple

View File

@ -51,6 +51,7 @@ typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
class Expr : public Stmt {
QualType TR;
virtual void ANCHOR(); // key function.
protected:
/// TypeDependent - Whether this expression is type-dependent
/// (C++ [temp.dep.expr]).
@ -247,6 +248,15 @@ class Expr : public Stmt {
SourceLocation DiagLoc;
EvalResult() : HasSideEffects(false), Diag(0), DiagExpr(0) {}
// isGlobalLValue - Return true if the evaluated lvalue expression
// is global.
bool isGlobalLValue() const;
// hasSideEffects - Return true if the evaluated expression has
// side effects.
bool hasSideEffects() const {
return HasSideEffects;
}
};
/// Evaluate - Return true if this is a constant which we can fold using
@ -255,10 +265,6 @@ class Expr : public Stmt {
/// in Result.
bool Evaluate(EvalResult &Result, ASTContext &Ctx) const;
/// EvaluateAsAny - The same as Evaluate, except that it also succeeds on
/// stack based objects.
bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const;
/// EvaluateAsBooleanCondition - Return true if this is a constant
/// which we we can fold and convert to a boolean condition using
/// any crazy technique that we want to.
@ -282,8 +288,7 @@ class Expr : public Stmt {
/// with link time known address.
bool EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const;
/// EvaluateAsAnyLValue - The same as EvaluateAsLValue, except that it
/// also succeeds on stack based, immutable address lvalues.
/// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue.
bool EvaluateAsAnyLValue(EvalResult &Result, ASTContext &Ctx) const;
/// \brief Enumeration used to describe how \c isNullPointerConstant()
@ -321,6 +326,10 @@ class Expr : public Stmt {
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts();
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off any
/// ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts();
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
@ -1468,13 +1477,10 @@ class CallExpr : public Expr {
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CallExprClass ||
T->getStmtClass() == CXXOperatorCallExprClass ||
T->getStmtClass() == CXXMemberCallExprClass;
return T->getStmtClass() >= firstCallExprConstant &&
T->getStmtClass() <= lastCallExprConstant;
}
static bool classof(const CallExpr *) { return true; }
static bool classof(const CXXOperatorCallExpr *) { return true; }
static bool classof(const CXXMemberCallExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
@ -1933,14 +1939,8 @@ class CastExpr : public Expr {
const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
if (SC >= ImplicitCastExprClass && SC <= CStyleCastExprClass)
return true;
return false;
return T->getStmtClass() >= firstCastExprConstant &&
T->getStmtClass() <= lastCastExprConstant;
}
static bool classof(const CastExpr *) { return true; }
@ -2037,13 +2037,8 @@ class ExplicitCastExpr : public CastExpr {
QualType getTypeAsWritten() const { return TInfo->getType(); }
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
return true;
if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
return false;
return T->getStmtClass() >= firstExplicitCastExprConstant &&
T->getStmtClass() <= lastExplicitCastExprConstant;
}
static bool classof(const ExplicitCastExpr *) { return true; }
};
@ -2198,8 +2193,8 @@ class BinaryOperator : public Expr {
bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
static bool classof(const Stmt *S) {
return S->getStmtClass() == BinaryOperatorClass ||
S->getStmtClass() == CompoundAssignOperatorClass;
return S->getStmtClass() >= firstBinaryOperatorConstant &&
S->getStmtClass() <= lastBinaryOperatorConstant;
}
static bool classof(const BinaryOperator *) { return true; }

View File

@ -88,10 +88,13 @@ class CXXOperatorCallExpr : public CallExpr {
/// the object argument).
class CXXMemberCallExpr : public CallExpr {
public:
CXXMemberCallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs,
CXXMemberCallExpr(ASTContext &C, Expr *fn, Expr **args, unsigned numargs,
QualType t, SourceLocation rparenloc)
: CallExpr(C, CXXMemberCallExprClass, fn, args, numargs, t, rparenloc) {}
CXXMemberCallExpr(ASTContext &C, EmptyShell Empty)
: CallExpr(C, CXXMemberCallExprClass, Empty) { }
/// getImplicitObjectArgument - Retrieves the implicit object
/// argument for the member call. For example, in "x.f(5)", this
/// operation would return "x".
@ -318,6 +321,14 @@ class CXXTypeidExpr : public Expr {
Operand->isTypeDependent() || Operand->isValueDependent()),
Operand(Operand), Range(R) { }
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
if (isExpr)
Operand = (Expr*)0;
else
Operand = (TypeSourceInfo*)0;
}
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
/// \brief Retrieves the type operand of this typeid() expression after
@ -329,15 +340,25 @@ class CXXTypeidExpr : public Expr {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
return Operand.get<TypeSourceInfo *>();
}
void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
Operand = TSI;
}
Expr* getExprOperand() const {
Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
return static_cast<Expr*>(Operand.get<Stmt *>());
}
virtual SourceRange getSourceRange() const {
return Range;
void setExprOperand(Expr *E) {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
Operand = E;
}
virtual SourceRange getSourceRange() const { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTypeidExprClass;
}
@ -371,6 +392,11 @@ class CXXThisExpr : public Expr {
Type->isDependentType(), Type->isDependentType()),
Loc(L), Implicit(isImplicit) { }
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
bool isImplicit() const { return Implicit; }
@ -399,6 +425,8 @@ class CXXThrowExpr : public Expr {
// can by null, if the optional expression to throw isn't present.
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {}
CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
void setSubExpr(Expr *E) { Op = E; }
@ -448,8 +476,7 @@ class CXXDefaultArgExpr : public Expr {
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param,
Expr *SubExpr)
: Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc)
{
: Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) {
*reinterpret_cast<Expr **>(this + 1) = SubExpr;
}
@ -457,6 +484,9 @@ class CXXDefaultArgExpr : public Expr {
virtual void DoDestroy(ASTContext &C);
public:
CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
// Param is the parameter whose default argument is used by this
// expression.
static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
@ -475,6 +505,9 @@ class CXXDefaultArgExpr : public Expr {
const ParmVarDecl *getParam() const { return Param.getPointer(); }
ParmVarDecl *getParam() { return Param.getPointer(); }
/// isExprStored - Return true if this expression owns the expression.
bool isExprStored() const { return Param.getInt(); }
// Retrieve the actual argument to the function call.
const Expr *getExpr() const {
if (Param.getInt())
@ -486,10 +519,16 @@ class CXXDefaultArgExpr : public Expr {
return *reinterpret_cast<Expr **> (this + 1);
return getParam()->getDefaultArg();
}
void setExpr(Expr *E) {
Param.setInt(true);
Param.setPointer((ParmVarDecl*)E);
}
/// \brief Retrieve the location where this default argument was actually
/// used.
SourceLocation getUsedLocation() const { return Loc; }
void setUsedLocation(SourceLocation L) { Loc = L; }
virtual SourceRange getSourceRange() const {
// Default argument expressions have no representation in the
@ -525,8 +564,20 @@ class CXXTemporary {
const CXXDestructorDecl *getDestructor() const { return Destructor; }
};
/// CXXBindTemporaryExpr - Represents binding an expression to a temporary,
/// so its destructor can be called later.
/// \brief Represents binding an expression to a temporary.
///
/// This ensures the destructor is called for the temporary. It should only be
/// needed for non-POD, non-trivially destructable class types. For example:
///
/// \code
/// struct S {
/// S() { } // User defined constructor makes S non-POD.
/// ~S() { } // User defined destructor makes it non-trivial.
/// };
/// void test() {
/// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
/// }
/// \endcode
class CXXBindTemporaryExpr : public Expr {
CXXTemporary *Temp;
@ -541,11 +592,15 @@ class CXXBindTemporaryExpr : public Expr {
virtual void DoDestroy(ASTContext &C);
public:
CXXBindTemporaryExpr(EmptyShell Empty)
: Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
CXXTemporary *getTemporary() { return Temp; }
const CXXTemporary *getTemporary() const { return Temp; }
void setTemporary(CXXTemporary *T) { Temp = T; }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
@ -572,8 +627,8 @@ class CXXBindTemporaryExpr : public Expr {
/// const int &i = 10;
///
/// a bind reference expression is inserted to indicate that 10 is bound to
/// a reference. (Ans also that a temporary needs to be created to hold the
/// value).
/// a reference, and that a temporary needs to be created to hold the
/// value.
class CXXBindReferenceExpr : public Expr {
// SubExpr - The expression being bound.
Stmt *SubExpr;
@ -827,10 +882,15 @@ class CXXZeroInitValueExpr : public Expr {
SourceLocation rParenLoc ) :
Expr(CXXZeroInitValueExprClass, ty, false, false),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
explicit CXXZeroInitValueExpr(EmptyShell Shell)
: Expr(CXXZeroInitValueExprClass, Shell) { }
SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
/// @brief Whether this initialization expression was
/// implicitly-generated.
bool isImplicit() const {
@ -891,6 +951,11 @@ class CXXNewExpr : public Expr {
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
SourceLocation startLoc, SourceLocation endLoc);
explicit CXXNewExpr(EmptyShell Shell)
: Expr(CXXNewExprClass, Shell), SubExprs(0) { }
void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
unsigned numConsArgs);
virtual void DoDestroy(ASTContext &C);
@ -900,8 +965,11 @@ class CXXNewExpr : public Expr {
}
FunctionDecl *getOperatorNew() const { return OperatorNew; }
void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
CXXConstructorDecl *getConstructor() const { return Constructor; }
void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
bool isArray() const { return Array; }
Expr *getArraySize() {
@ -922,8 +990,11 @@ class CXXNewExpr : public Expr {
}
bool isGlobalNew() const { return GlobalNew; }
void setGlobalNew(bool V) { GlobalNew = V; }
bool isParenTypeId() const { return ParenTypeId; }
void setParenTypeId(bool V) { ParenTypeId = V; }
bool hasInitializer() const { return Initializer; }
void setHasInitializer(bool V) { Initializer = V; }
unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
Expr *getConstructorArg(unsigned i) {
@ -963,7 +1034,21 @@ class CXXNewExpr : public Expr {
const_arg_iterator constructor_arg_end() const {
return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
}
typedef Stmt **raw_arg_iterator;
raw_arg_iterator raw_arg_begin() { return SubExprs; }
raw_arg_iterator raw_arg_end() {
return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
}
const_arg_iterator raw_arg_begin() const { return SubExprs; }
const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
SourceLocation getStartLoc() const { return StartLoc; }
void setStartLoc(SourceLocation L) { StartLoc = L; }
SourceLocation getEndLoc() const { return EndLoc; }
void setEndLoc(SourceLocation L) { EndLoc = L; }
virtual SourceRange getSourceRange() const {
return SourceRange(StartLoc, EndLoc);
}
@ -1260,7 +1345,9 @@ class OverloadExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls. Access is relative to the naming
/// class.
UnresolvedSet<4> Results;
// FIXME: Allocate this data after the OverloadExpr subclass.
DeclAccessPair *Results;
unsigned NumResults;
/// The common name of these declarations.
DeclarationName Name;
@ -1278,14 +1365,11 @@ class OverloadExpr : public Expr {
bool HasExplicitTemplateArgs;
protected:
OverloadExpr(StmtClass K, QualType T, bool Dependent,
OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool Dependent,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool HasTemplateArgs)
: Expr(K, T, Dependent, Dependent),
Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
{}
bool HasTemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
public:
/// Computes whether an unresolved lookup on the given declarations
@ -1309,22 +1393,17 @@ class OverloadExpr : public Expr {
return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
}
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
Results.append(Begin, End);
}
/// Gets the naming class of this lookup, if any.
CXXRecordDecl *getNamingClass() const;
typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
/// Gets the decls as an unresolved set.
const UnresolvedSetImpl &getDecls() { return Results; }
decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); }
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
/// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return Results.size(); }
unsigned getNumDecls() const { return NumResults; }
/// Gets the name looked up.
DeclarationName getName() const { return Name; }
@ -1390,12 +1469,14 @@ class UnresolvedLookupExpr : public OverloadExpr {
/// against the qualified-lookup bits.
CXXRecordDecl *NamingClass;
UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
UnresolvedLookupExpr(ASTContext &C, QualType T, bool Dependent,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
: OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
Name, NameLoc, HasTemplateArgs),
bool RequiresADL, bool Overloaded, bool HasTemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End)
: OverloadExpr(UnresolvedLookupExprClass, C, T, Dependent, Qualifier,
QRange, Name, NameLoc, HasTemplateArgs, Begin, End),
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
@ -1407,11 +1488,15 @@ class UnresolvedLookupExpr : public OverloadExpr {
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
bool ADL, bool Overloaded) {
return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
bool ADL, bool Overloaded,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C,
Dependent ? C.DependentTy : C.OverloadTy,
Dependent, NamingClass,
Qualifier, QualifierRange,
Name, NameLoc, ADL, Overloaded, false);
Name, NameLoc, ADL, Overloaded, false,
Begin, End);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
@ -1422,7 +1507,9 @@ class UnresolvedLookupExpr : public OverloadExpr {
DeclarationName Name,
SourceLocation NameLoc,
bool ADL,
const TemplateArgumentListInfo &Args);
const TemplateArgumentListInfo &Args,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End);
/// True if this declaration should be extended by
/// argument-dependent lookup.
@ -1611,7 +1698,7 @@ class CXXExprWithTemporaries : public Expr {
CXXTemporary **Temps;
unsigned NumTemps;
CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps,
CXXExprWithTemporaries(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps,
unsigned NumTemps);
~CXXExprWithTemporaries();
@ -1619,11 +1706,17 @@ class CXXExprWithTemporaries : public Expr {
virtual void DoDestroy(ASTContext &C);
public:
CXXExprWithTemporaries(EmptyShell Empty)
: Expr(CXXExprWithTemporariesClass, Empty),
SubExpr(0), Temps(0), NumTemps(0) {}
static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
CXXTemporary **Temps,
unsigned NumTemps);
unsigned getNumTemporaries() const { return NumTemps; }
void setNumTemporaries(ASTContext &C, unsigned N);
CXXTemporary *getTemporary(unsigned i) {
assert(i < NumTemps && "Index out of range");
return Temps[i];
@ -1631,6 +1724,10 @@ class CXXExprWithTemporaries : public Expr {
const CXXTemporary *getTemporary(unsigned i) const {
return const_cast<CXXExprWithTemporaries*>(this)->getTemporary(i);
}
void setTemporary(unsigned i, CXXTemporary *T) {
assert(i < NumTemps && "Index out of range");
Temps[i] = T;
}
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
@ -2020,7 +2117,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
UnresolvedMemberExpr(QualType T, bool Dependent,
UnresolvedMemberExpr(ASTContext &C, QualType T, bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
SourceLocation OperatorLoc,
@ -2028,7 +2125,8 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceRange QualifierRange,
DeclarationName Member,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
public:
static UnresolvedMemberExpr *
@ -2039,7 +2137,8 @@ class UnresolvedMemberExpr : public OverloadExpr {
SourceRange QualifierRange,
DeclarationName Member,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
/// \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

View File

@ -0,0 +1,13 @@
LEVEL = ../../../../..
BUILT_SOURCES = StmtNodes.inc
TABLEGEN_INC_FILES_COMMON = 1
include $(LEVEL)/Makefile.common
INPUT_TDS = $(PROJ_SRC_DIR)/StmtNodes.td
$(ObjDir)/StmtNodes.inc.tmp : StmtNodes.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
$(Verb) $(TableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $<

View File

@ -109,6 +109,11 @@ class ASTRecordLayout {
/// which is the alignment of the object without virtual bases.
uint64_t NonVirtualAlign;
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
/// (either a base or a member). Will be zero if the class doesn't contain
/// any empty subobjects.
uint64_t SizeOfLargestEmptySubobject;
/// PrimaryBase - The primary base info for this record.
PrimaryBaseInfo PrimaryBase;
@ -127,7 +132,6 @@ class ASTRecordLayout {
CXXRecordLayoutInfo *CXXInfo;
friend class ASTContext;
friend class ASTRecordLayoutBuilder;
ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
unsigned datasize, const uint64_t *fieldoffsets,
@ -139,7 +143,9 @@ class ASTRecordLayout {
uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
const PrimaryBaseInfo &PrimaryBase,
uint64_t SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool PrimaryBaseIsVirtual,
const BaseOffsetsMapTy& BaseOffsets,
const BaseOffsetsMapTy& VBaseOffsets);
@ -222,6 +228,11 @@ class ASTRecordLayout {
return CXXInfo->VBaseOffsets[VBase];
}
uint64_t getSizeOfLargestEmptySubobject() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->SizeOfLargestEmptySubobject;
}
primary_base_info_iterator primary_base_begin() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");

View File

@ -0,0 +1,768 @@
//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- 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 RecursiveASTVisitor interface, which recursively
// traverses the entire AST.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
namespace clang {
#define DISPATCH(NAME, CLASS, Var) \
return getDerived().Visit ## NAME(static_cast<CLASS*>(Var))
// We use preprocessor meta-programming to generate the Visit*()
// methods for all subclasses of Stmt, Decl, and Type. Some of the
// generated definitions, however, need to be customized. The
// meta-programming technique we use doesn't let us select which
// methods to generate. Therefore we have to generate ALL of them in
// a helper class RecursiveASTVisitorImpl, and override the ones we
// don't like in a child class RecursiveASTVisitor (C++ doesn't allow
// overriding a method in the same class).
//
// Do not use this class directly - use RecursiveASTVisitor instead.
template<typename Derived>
class RecursiveASTVisitorImpl {
public:
/// \brief Return a reference to the derived class.
Derived &getDerived() { return *static_cast<Derived*>(this); }
/// \brief Recursively visit a statement or expression, by
/// dispatching to Visit*() based on the argument's dynamic type.
/// This is NOT meant to be overridden by a subclass.
///
/// \returns true if the visitation was terminated early, false
/// otherwise (including when the argument is NULL).
bool Visit(Stmt *S);
/// \brief Recursively visit a type, by dispatching to
/// Visit*Type() based on the argument's getTypeClass() property.
/// This is NOT meant to be overridden by a subclass.
///
/// \returns true if the visitation was terminated early, false
/// otherwise (including when the argument is a Null type).
bool Visit(QualType T);
/// \brief Recursively visit a declaration, by dispatching to
/// Visit*Decl() based on the argument's dynamic type. This is
/// NOT meant to be overridden by a subclass.
///
/// \returns true if the visitation was terminated early, false
/// otherwise (including when the argument is NULL).
bool Visit(Decl *D);
/// \brief Recursively visit a C++ nested-name-specifier.
///
/// \returns true if the visitation was terminated early, false otherwise.
bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
/// \brief Recursively visit a template name.
///
/// \returns true if the visitation was terminated early, false otherwise.
bool VisitTemplateName(TemplateName Template);
/// \brief Recursively visit a template argument.
///
/// \returns true if the visitation was terminated early, false otherwise.
bool VisitTemplateArgument(const TemplateArgument &Arg);
/// \brief Recursively visit a set of template arguments.
///
/// \returns true if the visitation was terminated early, false otherwise.
bool VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
// If the implementation chooses not to implement a certain visit method, fall
// back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \
bool Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT, S); }
#include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.
#define BINOP_FALLBACK(NAME) \
bool VisitBin ## NAME(BinaryOperator *S) { \
DISPATCH(BinaryOperator, BinaryOperator, S); \
}
BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI)
BINOP_FALLBACK(Mul) BINOP_FALLBACK(Div) BINOP_FALLBACK(Rem)
BINOP_FALLBACK(Add) BINOP_FALLBACK(Sub) BINOP_FALLBACK(Shl)
BINOP_FALLBACK(Shr)
BINOP_FALLBACK(LT) BINOP_FALLBACK(GT) BINOP_FALLBACK(LE)
BINOP_FALLBACK(GE) BINOP_FALLBACK(EQ) BINOP_FALLBACK(NE)
BINOP_FALLBACK(And) BINOP_FALLBACK(Xor) BINOP_FALLBACK(Or)
BINOP_FALLBACK(LAnd) BINOP_FALLBACK(LOr)
BINOP_FALLBACK(Assign)
BINOP_FALLBACK(Comma)
#undef BINOP_FALLBACK
// If the implementation doesn't implement compound assignment operator
// methods, fall back on VisitCompoundAssignOperator.
#define CAO_FALLBACK(NAME) \
bool VisitBin ## NAME(CompoundAssignOperator *S) { \
DISPATCH(CompoundAssignOperator, CompoundAssignOperator, S); \
}
CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
CAO_FALLBACK(AddAssign) CAO_FALLBACK(SubAssign) CAO_FALLBACK(ShlAssign)
CAO_FALLBACK(ShrAssign) CAO_FALLBACK(AndAssign) CAO_FALLBACK(OrAssign)
CAO_FALLBACK(XorAssign)
#undef CAO_FALLBACK
// If the implementation doesn't implement unary operator methods, fall back
// on VisitUnaryOperator.
#define UNARYOP_FALLBACK(NAME) \
bool VisitUnary ## NAME(UnaryOperator *S) { \
DISPATCH(UnaryOperator, UnaryOperator, S); \
}
UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec)
UNARYOP_FALLBACK(PreInc) UNARYOP_FALLBACK(PreDec)
UNARYOP_FALLBACK(AddrOf) UNARYOP_FALLBACK(Deref)
UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus)
UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot)
UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag)
UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf)
#undef UNARYOP_FALLBACK
/// \brief Basis for statement and expression visitation, which
/// visits all of the substatements and subexpressions.
///
/// The relation between Visit(Stmt *S) and this method is that
/// the former dispatches to Visit*() based on S's dynamic type,
/// which forwards the call up the inheritance chain until
/// reaching VisitStmt(), which then calls Visit() on each
/// substatement/subexpression.
bool VisitStmt(Stmt *S);
/// \brief Basis for type visitation, which by default does nothing.
///
/// The relation between Visit(QualType T) and this method is
/// that the former dispatches to Visit*Type(), which forwards the
/// call up the inheritance chain until reaching VisitType().
bool VisitType(Type *T);
#define TYPE(Class, Base) \
bool Visit##Class##Type(Class##Type *T);
#include "clang/AST/TypeNodes.def"
/// \brief Basis for declaration and definition visitation, which
/// visits all of the subnodes.
///
/// The relation between Visit(Decl *) and this method is that the
/// former dispatches to Visit*Decl(), which forwards the call up
/// the inheritance chain until reaching VisitDecl().
bool VisitDecl(Decl *D);
#define DECL(Class, Base) \
bool Visit##Class##Decl(Class##Decl *D) { \
return getDerived().Visit##Base(D); \
}
#define ABSTRACT_DECL(Class, Base) DECL(Class, Base)
#include "clang/AST/DeclNodes.def"
};
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::Visit(Stmt *S) {
if (!S)
return false;
// If we have a binary expr, dispatch to the subcode of the binop. A smart
// optimizer (e.g. LLVM) will fold this comparison into the switch stmt
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
case BinaryOperator::PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator, S);
case BinaryOperator::PtrMemI: DISPATCH(BinPtrMemI, BinaryOperator, S);
case BinaryOperator::Mul: DISPATCH(BinMul, BinaryOperator, S);
case BinaryOperator::Div: DISPATCH(BinDiv, BinaryOperator, S);
case BinaryOperator::Rem: DISPATCH(BinRem, BinaryOperator, S);
case BinaryOperator::Add: DISPATCH(BinAdd, BinaryOperator, S);
case BinaryOperator::Sub: DISPATCH(BinSub, BinaryOperator, S);
case BinaryOperator::Shl: DISPATCH(BinShl, BinaryOperator, S);
case BinaryOperator::Shr: DISPATCH(BinShr, BinaryOperator, S);
case BinaryOperator::LT: DISPATCH(BinLT, BinaryOperator, S);
case BinaryOperator::GT: DISPATCH(BinGT, BinaryOperator, S);
case BinaryOperator::LE: DISPATCH(BinLE, BinaryOperator, S);
case BinaryOperator::GE: DISPATCH(BinGE, BinaryOperator, S);
case BinaryOperator::EQ: DISPATCH(BinEQ, BinaryOperator, S);
case BinaryOperator::NE: DISPATCH(BinNE, BinaryOperator, S);
case BinaryOperator::And: DISPATCH(BinAnd, BinaryOperator, S);
case BinaryOperator::Xor: DISPATCH(BinXor, BinaryOperator, S);
case BinaryOperator::Or : DISPATCH(BinOr, BinaryOperator, S);
case BinaryOperator::LAnd: DISPATCH(BinLAnd, BinaryOperator, S);
case BinaryOperator::LOr : DISPATCH(BinLOr, BinaryOperator, S);
case BinaryOperator::Assign: DISPATCH(BinAssign, BinaryOperator, S);
case BinaryOperator::MulAssign:
DISPATCH(BinMulAssign, CompoundAssignOperator, S);
case BinaryOperator::DivAssign:
DISPATCH(BinDivAssign, CompoundAssignOperator, S);
case BinaryOperator::RemAssign:
DISPATCH(BinRemAssign, CompoundAssignOperator, S);
case BinaryOperator::AddAssign:
DISPATCH(BinAddAssign, CompoundAssignOperator, S);
case BinaryOperator::SubAssign:
DISPATCH(BinSubAssign, CompoundAssignOperator, S);
case BinaryOperator::ShlAssign:
DISPATCH(BinShlAssign, CompoundAssignOperator, S);
case BinaryOperator::ShrAssign:
DISPATCH(BinShrAssign, CompoundAssignOperator, S);
case BinaryOperator::AndAssign:
DISPATCH(BinAndAssign, CompoundAssignOperator, S);
case BinaryOperator::OrAssign:
DISPATCH(BinOrAssign, CompoundAssignOperator, S);
case BinaryOperator::XorAssign:
DISPATCH(BinXorAssign, CompoundAssignOperator, S);
case BinaryOperator::Comma: DISPATCH(BinComma, BinaryOperator, S);
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
case UnaryOperator::PostInc: DISPATCH(UnaryPostInc, UnaryOperator, S);
case UnaryOperator::PostDec: DISPATCH(UnaryPostDec, UnaryOperator, S);
case UnaryOperator::PreInc: DISPATCH(UnaryPreInc, UnaryOperator, S);
case UnaryOperator::PreDec: DISPATCH(UnaryPreDec, UnaryOperator, S);
case UnaryOperator::AddrOf: DISPATCH(UnaryAddrOf, UnaryOperator, S);
case UnaryOperator::Deref: DISPATCH(UnaryDeref, UnaryOperator, S);
case UnaryOperator::Plus: DISPATCH(UnaryPlus, UnaryOperator, S);
case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator, S);
case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator, S);
case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator, S);
case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator, S);
case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator, S);
case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator, S);
case UnaryOperator::OffsetOf: DISPATCH(UnaryOffsetOf, UnaryOperator, S);
}
}
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
case Stmt::NoStmtClass: break;
#define ABSTRACT_STMT(STMT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::Visit(QualType T) {
if (T.isNull())
return false;
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(Class, Base)
#define TYPE(Class, Base) \
case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
#include "clang/AST/TypeNodes.def"
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::Visit(Decl *D) {
if (!D)
return false;
switch (D->getKind()) {
#define ABSTRACT_DECL(Class, Base)
#define DECL(Class, Base) \
case Decl::Class: DISPATCH(Class##Decl, Class##Decl, D);
#include "clang/AST/DeclNodes.def"
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitNestedNameSpecifier(
NestedNameSpecifier *NNS) {
if (NNS->getPrefix() &&
getDerived().VisitNestedNameSpecifier(NNS->getPrefix()))
return true;
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::Global:
return false;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
return Visit(QualType(NNS->getAsType(), 0));
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTemplateName(TemplateName Template) {
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
return DTN->getQualifier() &&
getDerived().VisitNestedNameSpecifier(DTN->getQualifier());
if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
return getDerived().VisitNestedNameSpecifier(QTN->getQualifier());
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArgument(
const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
return false;
case TemplateArgument::Type:
return Visit(Arg.getAsType());
case TemplateArgument::Template:
return getDerived().VisitTemplateName(Arg.getAsTemplate());
case TemplateArgument::Expression:
return getDerived().Visit(Arg.getAsExpr());
case TemplateArgument::Pack:
return getDerived().VisitTemplateArguments(Arg.pack_begin(),
Arg.pack_size());
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTemplateArguments(
const TemplateArgument *Args,
unsigned NumArgs) {
for (unsigned I = 0; I != NumArgs; ++I)
if (getDerived().VisitTemplateArgument(Args[I]))
return true;
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitStmt(Stmt *Node) {
for (Stmt::child_iterator C = Node->child_begin(), CEnd = Node->child_end();
C != CEnd; ++C) {
if (Visit(*C))
return true;
}
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitType(Type *T) {
return false;
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitBuiltinType(BuiltinType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitComplexType(ComplexType *T) {
if (Visit(T->getElementType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitPointerType(PointerType *T) {
if (Visit(T->getPointeeType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitBlockPointerType(
BlockPointerType *T) {
if (Visit(T->getPointeeType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitReferenceType(ReferenceType *T) {
if (Visit(T->getPointeeType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitLValueReferenceType(
LValueReferenceType *T) {
return getDerived().VisitReferenceType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitRValueReferenceType(
RValueReferenceType *T) {
return getDerived().VisitReferenceType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitMemberPointerType(
MemberPointerType *T) {
if (Visit(QualType(T->getClass(), 0)) || Visit(T->getPointeeType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitArrayType(ArrayType *T) {
if (Visit(T->getElementType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitConstantArrayType(
ConstantArrayType *T) {
return getDerived().VisitArrayType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitIncompleteArrayType(
IncompleteArrayType *T) {
return getDerived().VisitArrayType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitVariableArrayType(
VariableArrayType *T) {
if (Visit(T->getSizeExpr()))
return true;
return getDerived().VisitArrayType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedArrayType(
DependentSizedArrayType *T) {
if (T->getSizeExpr() && Visit(T->getSizeExpr()))
return true;
return getDerived().VisitArrayType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitDependentSizedExtVectorType(
DependentSizedExtVectorType *T) {
if ((T->getSizeExpr() && Visit(T->getSizeExpr())) ||
Visit(T->getElementType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitVectorType(VectorType *T) {
if (Visit(T->getElementType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitExtVectorType(ExtVectorType *T) {
return getDerived().VisitVectorType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitFunctionType(FunctionType *T) {
if (Visit(T->getResultType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitFunctionNoProtoType(
FunctionNoProtoType *T) {
return getDerived().VisitFunctionType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitFunctionProtoType(
FunctionProtoType *T) {
for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
AEnd = T->arg_type_end();
A != AEnd; ++A) {
if (Visit(*A))
return true;
}
for (FunctionProtoType::exception_iterator E = T->exception_begin(),
EEnd = T->exception_end();
E != EEnd; ++E) {
if (Visit(*E))
return true;
}
return getDerived().VisitFunctionType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitUnresolvedUsingType(
UnresolvedUsingType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTypedefType(TypedefType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfExprType(TypeOfExprType *T) {
if (Visit(T->getUnderlyingExpr()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTypeOfType(TypeOfType *T) {
if (Visit(T->getUnderlyingType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitDecltypeType(DecltypeType *T) {
if (Visit(T->getUnderlyingExpr()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTagType(TagType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitRecordType(RecordType *T) {
return getDerived().VisitTagType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitEnumType(EnumType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTemplateTypeParmType(
TemplateTypeParmType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitSubstTemplateTypeParmType(
SubstTemplateTypeParmType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitTemplateSpecializationType(
TemplateSpecializationType *T) {
if (getDerived().VisitTemplateName(T->getTemplateName()) ||
getDerived().VisitTemplateArguments(T->getArgs(), T->getNumArgs()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitInjectedClassNameType(
InjectedClassNameType *T) {
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitElaboratedType(ElaboratedType *T) {
if (T->getQualifier() &&
getDerived().VisitNestedNameSpecifier(T->getQualifier()))
return true;
if (Visit(T->getNamedType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitDependentNameType(
DependentNameType *T) {
if (T->getQualifier() &&
getDerived().VisitNestedNameSpecifier(T->getQualifier()))
return true;
if (T->getTemplateId() &&
getDerived().VisitTemplateSpecializationType(
const_cast<TemplateSpecializationType *>(T->getTemplateId())))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitObjCInterfaceType(
ObjCInterfaceType *T) {
return getDerived().VisitObjCObjectType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectType(ObjCObjectType *T) {
// We have to watch out here because an ObjCInterfaceType's base
// type is itself.
if (T->getBaseType().getTypePtr() != T)
if (Visit(T->getBaseType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitObjCObjectPointerType(
ObjCObjectPointerType *T) {
if (Visit(T->getPointeeType()))
return true;
return getDerived().VisitType(T);
}
template<typename Derived>
bool RecursiveASTVisitorImpl<Derived>::VisitDecl(Decl *D) {
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
for (DeclContext::decl_iterator Child = DC->decls_begin(),
ChildEnd = DC->decls_end();
Child != ChildEnd; ++Child)
if (Visit(*Child))
return true;
return false;
}
return false;
}
/// \brief A visitor that recursively walks the entire Clang AST.
///
/// Clients of this visitor should subclass the visitor (providing
/// themselves as the template argument, using the curiously
/// recurring template pattern) and override any of the Visit*
/// methods (except Visit()) for declaration, type, statement,
/// expression, or other AST nodes where the visitor should customize
/// behavior. Returning "true" from one of these overridden functions
/// will abort the entire traversal. An overridden Visit* method
/// will not descend further into the AST for that node unless
/// Base::Visit* is called.
template<typename Derived>
class RecursiveASTVisitor : public RecursiveASTVisitorImpl<Derived> {
typedef RecursiveASTVisitorImpl<Derived> Impl;
public:
typedef RecursiveASTVisitor<Derived> Base;
bool VisitDeclaratorDecl(DeclaratorDecl *D);
bool VisitFunctionDecl(FunctionDecl *D);
bool VisitVarDecl(VarDecl *D);
bool VisitBlockDecl(BlockDecl *D);
bool VisitDeclStmt(DeclStmt *S);
bool VisitFunctionType(FunctionType *F);
bool VisitFunctionProtoType(FunctionProtoType *F);
};
#define DEFINE_VISIT(Type, Name, Statement) \
template<typename Derived> \
bool RecursiveASTVisitor<Derived>::Visit ## Type (Type *Name) { \
if (Impl::Visit ## Type (Name)) return true; \
{ Statement; } \
return false; \
}
DEFINE_VISIT(DeclaratorDecl, D, {
if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
return this->Visit(TInfo->getType());
})
DEFINE_VISIT(FunctionDecl, D, {
if (D->isThisDeclarationADefinition())
return this->Visit(D->getBody());
})
DEFINE_VISIT(VarDecl, D, return this->Visit(D->getInit()))
DEFINE_VISIT(BlockDecl, D, return this->Visit(D->getBody()))
DEFINE_VISIT(DeclStmt, S, {
for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
if (this->Visit(*I))
return true;
}
})
// FunctionType is the common base class of FunctionNoProtoType (a
// K&R-style function declaration that has no information about
// its arguments) and FunctionProtoType.
DEFINE_VISIT(FunctionType, F, return this->Visit(F->getResultType()))
DEFINE_VISIT(FunctionProtoType, F, {
for (unsigned i = 0; i != F->getNumArgs(); ++i) {
if (this->Visit(F->getArgType(i)))
return true;
}
for (unsigned i = 0; i != F->getNumExceptions(); ++i) {
if (this->Visit(F->getExceptionType(i)))
return true;
}
})
#undef DEFINE_VISIT
#undef DISPATCH
} // end namespace clang
#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H

View File

@ -98,12 +98,14 @@ class Stmt {
enum StmtClass {
NoStmtClass = 0,
#define STMT(CLASS, PARENT) CLASS##Class,
#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
#define ABSTRACT_EXPR(CLASS, PARENT)
#include "clang/AST/StmtNodes.def"
#define STMT_RANGE(BASE, FIRST, LAST) \
first##BASE##Constant = FIRST##Class, \
last##BASE##Constant = LAST##Class,
#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
first##BASE##Constant = FIRST##Class, \
last##BASE##Constant = LAST##Class
#define ABSTRACT_STMT(STMT)
#include "clang/AST/StmtNodes.inc"
};
private:
/// \brief The statement class.
@ -1083,9 +1085,15 @@ class BreakStmt : public Stmt {
class ReturnStmt : public Stmt {
Stmt *RetExpr;
SourceLocation RetLoc;
const VarDecl *NRVOCandidate;
public:
ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
RetExpr((Stmt*) E), RetLoc(RL) {}
ReturnStmt(SourceLocation RL)
: Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
: Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
NRVOCandidate(NRVOCandidate) {}
/// \brief Build an empty return expression.
explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
@ -1097,6 +1105,14 @@ class ReturnStmt : public Stmt {
SourceLocation getReturnLoc() const { return RetLoc; }
void setReturnLoc(SourceLocation L) { RetLoc = L; }
/// \brief Retrieve the variable that might be used for the named return
/// value optimization.
///
/// The optimization itself can only be performed if the variable is
/// also marked as an NRVO object.
const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
virtual SourceRange getSourceRange() const;
static bool classof(const Stmt *T) {

View File

@ -0,0 +1,127 @@
class Stmt<bit abstract = 0> {
bit Abstract = abstract;
}
class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
Stmt Base = base;
}
// Statements
def NullStmt : Stmt;
def CompoundStmt : Stmt;
def LabelStmt : Stmt;
def IfStmt : Stmt;
def SwitchStmt : Stmt;
def WhileStmt : Stmt;
def DoStmt : Stmt;
def ForStmt : Stmt;
def GotoStmt : Stmt;
def IndirectGotoStmt : Stmt;
def ContinueStmt : Stmt;
def BreakStmt : Stmt;
def ReturnStmt : Stmt;
def DeclStmt : Stmt;
def SwitchCase : Stmt;
def CaseStmt : DStmt<SwitchCase>;
def DefaultStmt : DStmt<SwitchCase>;
// GNU Extensions
def AsmStmt : Stmt;
// Obj-C statements
def ObjCAtTryStmt : Stmt;
def ObjCAtCatchStmt : Stmt;
def ObjCAtFinallyStmt : Stmt;
def ObjCAtThrowStmt : Stmt;
def ObjCAtSynchronizedStmt : Stmt;
def ObjCForCollectionStmt : Stmt;
// C++ statments
def CXXCatchStmt : Stmt;
def CXXTryStmt : Stmt;
// Expressions
def Expr : Stmt<1>;
def PredefinedExpr : DStmt<Expr>;
def DeclRefExpr : DStmt<Expr>;
def IntegerLiteral : DStmt<Expr>;
def FloatingLiteral : DStmt<Expr>;
def ImaginaryLiteral : DStmt<Expr>;
def StringLiteral : DStmt<Expr>;
def CharacterLiteral : DStmt<Expr>;
def ParenExpr : DStmt<Expr>;
def UnaryOperator : DStmt<Expr>;
def OffsetOfExpr : DStmt<Expr>;
def SizeOfAlignOfExpr : DStmt<Expr>;
def ArraySubscriptExpr : DStmt<Expr>;
def CallExpr : DStmt<Expr>;
def MemberExpr : DStmt<Expr>;
def CastExpr : DStmt<Expr, 1>;
def BinaryOperator : DStmt<Expr>;
def CompoundAssignOperator : DStmt<BinaryOperator>;
def ConditionalOperator : DStmt<Expr>;
def ImplicitCastExpr : DStmt<CastExpr>;
def ExplicitCastExpr : DStmt<CastExpr, 1>;
def CStyleCastExpr : DStmt<ExplicitCastExpr>;
def CompoundLiteralExpr : DStmt<Expr>;
def ExtVectorElementExpr : DStmt<Expr>;
def InitListExpr : DStmt<Expr>;
def DesignatedInitExpr : DStmt<Expr>;
def ImplicitValueInitExpr : DStmt<Expr>;
def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
// GNU Extensions.
def AddrLabelExpr : DStmt<Expr>;
def StmtExpr : DStmt<Expr>;
def TypesCompatibleExpr : DStmt<Expr>;
def ChooseExpr : DStmt<Expr>;
def GNUNullExpr : DStmt<Expr>;
// C++ Expressions.
def CXXOperatorCallExpr : DStmt<CallExpr>;
def CXXMemberCallExpr : DStmt<CallExpr>;
def CXXNamedCastExpr : DStmt<ExplicitCastExpr, 1>;
def CXXStaticCastExpr : DStmt<CXXNamedCastExpr>;
def CXXDynamicCastExpr : DStmt<CXXNamedCastExpr>;
def CXXReinterpretCastExpr : DStmt<CXXNamedCastExpr>;
def CXXConstCastExpr : DStmt<CXXNamedCastExpr>;
def CXXFunctionalCastExpr : DStmt<ExplicitCastExpr>;
def CXXTypeidExpr : DStmt<Expr>;
def CXXBoolLiteralExpr : DStmt<Expr>;
def CXXNullPtrLiteralExpr : DStmt<Expr>;
def CXXThisExpr : DStmt<Expr>;
def CXXThrowExpr : DStmt<Expr>;
def CXXDefaultArgExpr : DStmt<Expr>;
def CXXZeroInitValueExpr : DStmt<Expr>;
def CXXNewExpr : DStmt<Expr>;
def CXXDeleteExpr : DStmt<Expr>;
def CXXPseudoDestructorExpr : DStmt<Expr>;
def UnresolvedLookupExpr : DStmt<Expr>;
def UnaryTypeTraitExpr : DStmt<Expr>;
def DependentScopeDeclRefExpr : DStmt<Expr>;
def CXXConstructExpr : DStmt<Expr>;
def CXXBindTemporaryExpr : DStmt<Expr>;
def CXXBindReferenceExpr : DStmt<Expr>;
def CXXExprWithTemporaries : DStmt<Expr>;
def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>;
def CXXUnresolvedConstructExpr : DStmt<Expr>;
def CXXDependentScopeMemberExpr : DStmt<Expr>;
def UnresolvedMemberExpr : DStmt<Expr>;
// Obj-C Expressions.
def ObjCStringLiteral : DStmt<Expr>;
def ObjCEncodeExpr : DStmt<Expr>;
def ObjCMessageExpr : DStmt<Expr>;
def ObjCSelectorExpr : DStmt<Expr>;
def ObjCProtocolExpr : DStmt<Expr>;
def ObjCIvarRefExpr : DStmt<Expr>;
def ObjCPropertyRefExpr : DStmt<Expr>;
def ObjCImplicitSetterGetterRefExpr : DStmt<Expr>;
def ObjCSuperExpr : DStmt<Expr>;
def ObjCIsaExpr : DStmt<Expr>;
// Clang Extensions.
def ShuffleVectorExpr : DStmt<Expr>;
def BlockExpr : DStmt<Expr>;
def BlockDeclRefExpr : DStmt<Expr>;

View File

@ -105,10 +105,10 @@ class StmtVisitor {
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
switch (S->getStmtClass()) {
default: assert(0 && "Unknown stmt kind!");
#define ABSTRACT_EXPR(CLASS, PARENT)
#define ABSTRACT_STMT(STMT)
#define STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
#include "clang/AST/StmtNodes.def"
#include "clang/AST/StmtNodes.inc"
}
}
@ -116,7 +116,7 @@ class StmtVisitor {
// back on VisitExpr or whatever else is the superclass.
#define STMT(CLASS, PARENT) \
RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); }
#include "clang/AST/StmtNodes.def"
#include "clang/AST/StmtNodes.inc"
// If the implementation doesn't implement binary operator methods, fall back
// on VisitBinaryOperator.

View File

@ -28,6 +28,7 @@ namespace llvm {
namespace clang {
class Decl;
class DiagnosticBuilder;
class Expr;
class TypeSourceInfo;
@ -473,6 +474,9 @@ class TemplateArgumentListInfo {
}
};
}
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const TemplateArgument &Arg);
} // end namespace clang
#endif

View File

@ -188,7 +188,7 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
/// declaration for "vector". The QualifiedTemplateName class is only
/// used to provide "sugar" for template names that were expressed
/// with a qualified name, and has no semantic meaning. In this
/// manner, it is to TemplateName what QualifiedNameType is to Type,
/// manner, it is to TemplateName what ElaboratedType is to Type,
/// providing extra syntactic sugar for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode {
/// \brief The nested name specifier that qualifies the template name.

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Specifiers.h"
@ -84,21 +85,20 @@ class TypeLoc {
return Data;
}
/// \brief Get the begin source location.
SourceLocation getBeginLoc() const;
/// \brief Get the end source location.
SourceLocation getEndLoc() const;
/// \brief Get the full source range.
SourceRange getFullSourceRange() const {
SourceLocation End = getSourceRange().getEnd();
TypeLoc Cur = *this;
while (true) {
TypeLoc Next = Cur.getNextTypeLoc();
if (Next.isNull()) break;
Cur = Next;
}
return SourceRange(Cur.getSourceRange().getBegin(), End);
SourceRange getSourceRange() const {
return SourceRange(getBeginLoc(), getEndLoc());
}
/// \brief Get the local source range.
SourceRange getSourceRange() const {
return getSourceRangeImpl(*this);
SourceRange getLocalSourceRange() const {
return getLocalSourceRangeImpl(*this);
}
/// \brief Returns the size of the type source info data block.
@ -137,9 +137,14 @@ class TypeLoc {
private:
static void initializeImpl(TypeLoc TL, SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
static SourceRange getSourceRangeImpl(TypeLoc TL);
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
/// \brief Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
return TypeLoc(Ty, (void*)(this + 1));
}
/// \brief Wrapper of type source information for a type with
/// no direct quqlaifiers.
class UnqualTypeLoc : public TypeLoc {
@ -168,7 +173,7 @@ class UnqualTypeLoc : public TypeLoc {
/// type qualifiers.
class QualifiedTypeLoc : public TypeLoc {
public:
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange();
}
@ -263,6 +268,16 @@ class ConcreteTypeLoc : public Base {
return TypeClass::classof(Ty);
}
static bool classof(const TypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const Derived *TL) {
return true;
}
TypeLoc getNextTypeLoc() const {
return getNextTypeLoc(asDerived()->getInnerType());
}
@ -361,7 +376,7 @@ class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
@ -413,7 +428,7 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getBuiltinLoc(), getBuiltinLoc());
}
@ -553,6 +568,7 @@ class SubstTemplateTypeParmTypeLoc :
struct ObjCProtocolListLocInfo {
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
bool HasBaseTypeAsWritten;
};
// A helper class for defining ObjC TypeLocs that can qualified with
@ -560,24 +576,15 @@ struct ObjCProtocolListLocInfo {
//
// TypeClass basically has to be either ObjCInterfaceType or
// ObjCObjectPointerType.
template <class Derived, class TypeClass, class LocalData>
class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
Derived,
TypeClass,
LocalData> {
class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ObjCObjectTypeLoc,
ObjCObjectType,
ObjCProtocolListLocInfo> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
return (SourceLocation*) this->getExtraLocalData();
}
protected:
void initializeLocalBase(SourceLocation Loc) {
setLAngleLoc(Loc);
setRAngleLoc(Loc);
for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
setProtocolLoc(i, Loc);
}
public:
SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc;
@ -611,29 +618,49 @@ class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
return *(this->getTypePtr()->qual_begin() + i);
}
SourceRange getSourceRange() const {
bool hasBaseTypeAsWritten() const {
return getLocalData()->HasBaseTypeAsWritten;
}
void setHasBaseTypeAsWritten(bool HasBaseType) {
getLocalData()->HasBaseTypeAsWritten = HasBaseType;
}
TypeLoc getBaseLoc() const {
return getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
void initializeLocal(SourceLocation Loc) {
initializeLocalBase(Loc);
setHasBaseTypeAsWritten(true);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
setProtocolLoc(i, Loc);
}
unsigned getExtraLocalDataSize() const {
return this->getNumProtocols() * sizeof(SourceLocation);
}
QualType getInnerType() const {
return getTypePtr()->getBaseType();
}
};
struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
struct ObjCInterfaceLocInfo {
SourceLocation NameLoc;
};
/// \brief Wrapper for source info for ObjC interfaces.
class ObjCInterfaceTypeLoc :
public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
ObjCInterfaceType,
ObjCInterfaceLocInfo> {
class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ObjCInterfaceTypeLoc,
ObjCInterfaceType,
ObjCInterfaceLocInfo> {
public:
ObjCInterfaceDecl *getIFaceDecl() const {
return getTypePtr()->getDecl();
@ -647,85 +674,16 @@ class ObjCInterfaceTypeLoc :
getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
if (getNumProtocols())
return SourceRange(getNameLoc(), getRAngleLoc());
else
return SourceRange(getNameLoc(), getNameLoc());
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc());
}
void initializeLocal(SourceLocation Loc) {
initializeLocalBase(Loc);
setNameLoc(Loc);
}
};
struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
SourceLocation StarLoc;
bool HasProtocols;
bool HasBaseType;
};
/// Wraps an ObjCPointerType with source location information. Note
/// that not all ObjCPointerTypes actually have a star location; nor
/// are protocol locations necessarily written in the source just
/// because they're present on the type.
class ObjCObjectPointerTypeLoc :
public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
ObjCObjectPointerType,
ObjCObjectPointerLocInfo> {
public:
bool hasProtocolsAsWritten() const {
return getLocalData()->HasProtocols;
}
void setHasProtocolsAsWritten(bool HasProtocols) {
getLocalData()->HasProtocols = HasProtocols;
}
bool hasBaseTypeAsWritten() const {
return getLocalData()->HasBaseType;
}
void setHasBaseTypeAsWritten(bool HasBaseType) {
getLocalData()->HasBaseType = HasBaseType;
}
SourceLocation getStarLoc() const {
return getLocalData()->StarLoc;
}
void setStarLoc(SourceLocation Loc) {
getLocalData()->StarLoc = Loc;
}
SourceRange getSourceRange() const {
// Being written with protocols is incompatible with being written
// with a star.
if (hasProtocolsAsWritten())
return SourceRange(getLAngleLoc(), getRAngleLoc());
else
return SourceRange(getStarLoc(), getStarLoc());
}
void initializeLocal(SourceLocation Loc) {
initializeLocalBase(Loc);
setHasProtocolsAsWritten(false);
setHasBaseTypeAsWritten(false);
setStarLoc(Loc);
}
TypeLoc getBaseTypeLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return getTypePtr()->getPointeeType();
}
};
struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
@ -746,7 +704,7 @@ class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
return this->getInnerTypeLoc();
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getSigilLoc(), getSigilLoc());
}
@ -798,6 +756,20 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
}
};
/// Wraps an ObjCPointerType with source location information.
class ObjCObjectPointerTypeLoc :
public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
ObjCObjectPointerType> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
ReferenceType> {
@ -871,13 +843,11 @@ class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
TypeLoc getArgLoc(unsigned i) const;
TypeLoc getResultLoc() const {
return getInnerTypeLoc();
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
@ -950,7 +920,7 @@ class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
return getInnerTypeLoc();
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
@ -1055,7 +1025,7 @@ class TemplateSpecializationTypeLoc :
memcpy(Data, Loc.Data, size);
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getTemplateNameLoc(), getRAngleLoc());
}
@ -1183,7 +1153,7 @@ class TypeofLikeTypeLoc
setRParenLoc(range.getEnd());
}
SourceRange getSourceRange() const {
SourceRange getLocalSourceRange() const {
return SourceRange(getTypeofLoc(), getRParenLoc());
}
@ -1204,7 +1174,7 @@ class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
// Reimplemented to account for GNU/C++ extension
// typeof unary-expression
// where there are no parentheses.
SourceRange getSourceRange() const;
SourceRange getLocalSourceRange() const;
};
class TypeOfTypeLoc
@ -1227,24 +1197,110 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeType> {
};
// FIXME: location of the tag keyword.
class ElaboratedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
ElaboratedTypeLoc,
ElaboratedType> {
struct ElaboratedLocInfo {
SourceLocation KeywordLoc;
SourceRange QualifierRange;
};
// FIXME: locations for the nested name specifier; at the very least,
// a SourceRange.
class QualifiedNameTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
QualifiedNameTypeLoc,
QualifiedNameType> {
class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ElaboratedTypeLoc,
ElaboratedType,
ElaboratedLocInfo> {
public:
SourceLocation getKeywordLoc() const {
return this->getLocalData()->KeywordLoc;
}
void setKeywordLoc(SourceLocation Loc) {
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
}
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
if (getQualifierRange().getEnd().isValid())
return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
else
return SourceRange(getKeywordLoc());
else
return getQualifierRange();
}
void initializeLocal(SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
}
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return getTypePtr()->getNamedType();
}
void copy(ElaboratedTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
};
// FIXME: locations for the typename keyword and nested name specifier.
class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DependentNameTypeLoc,
DependentNameType> {
struct DependentNameLocInfo {
SourceLocation KeywordLoc;
SourceRange QualifierRange;
SourceLocation NameLoc;
};
class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
DependentNameTypeLoc,
DependentNameType,
DependentNameLocInfo> {
public:
SourceLocation getKeywordLoc() const {
return this->getLocalData()->KeywordLoc;
}
void setKeywordLoc(SourceLocation Loc) {
this->getLocalData()->KeywordLoc = Loc;
}
SourceRange getQualifierRange() const {
return this->getLocalData()->QualifierRange;
}
void setQualifierRange(SourceRange Range) {
this->getLocalData()->QualifierRange = Range;
}
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getNameLoc());
else
return SourceRange(getQualifierRange().getBegin(), getNameLoc());
}
void copy(DependentNameTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
void initializeLocal(SourceLocation Loc) {
setKeywordLoc(Loc);
setQualifierRange(SourceRange(Loc));
setNameLoc(Loc);
}
};
}

View File

@ -59,6 +59,20 @@ class TypeLocBuilder {
grow(Requested);
}
/// Pushes a copy of the given TypeLoc onto this builder. The builder
/// must be empty for this to work.
void pushFullCopy(TypeLoc L) {
#ifndef NDEBUG
assert(LastTy.isNull() && "pushing copy on non-empty TypeLocBuilder");
LastTy = L.getNextTypeLoc().getType();
#endif
assert(Index == Capacity && "pushing copy on non-empty TypeLocBuilder");
unsigned Size = L.getFullDataSize();
TypeLoc Copy = pushImpl(L.getType(), Size);
memcpy(Copy.getOpaqueData(), L.getOpaqueData(), Size);
}
/// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
/// previously retrieved from this builder.
TypeSpecTypeLoc pushTypeSpec(QualType T) {

View File

@ -90,10 +90,10 @@ NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
#ifdef LAST_TYPE

View File

@ -1,4 +1,4 @@
//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -25,7 +25,7 @@ template<typename ImplClass, typename RetTy=void>
class TypeVisitor {
public:
RetTy Visit(Type *T) {
// Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
// Top switch stmt: dispatch to VisitFooType for each FooType.
switch (T->getTypeClass()) {
default: assert(0 && "Unknown type class!");
#define ABSTRACT_TYPE(CLASS, PARENT)

View File

@ -31,9 +31,13 @@ class UnresolvedSetIterator {
IteratorTy ir;
friend class UnresolvedSetImpl;
friend class OverloadExpr;
explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {}
explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) :
ir(const_cast<DeclsTy::iterator>(ir)) {}
IteratorTy getIterator() const { return ir; }
public:
UnresolvedSetIterator() {}
@ -81,9 +85,7 @@ class UnresolvedSetIterator {
bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; }
};
/// UnresolvedSet - A set of unresolved declarations. This is needed
/// in a lot of places, but isn't really worth breaking into its own
/// header right now.
/// UnresolvedSet - A set of unresolved declarations.
class UnresolvedSetImpl {
typedef UnresolvedSetIterator::DeclsTy DeclsTy;

View File

@ -59,7 +59,7 @@ class ProgramPoint {
protected:
ProgramPoint(const void* P, Kind k, const LocationContext *l,
const void *tag = 0)
: Data(P, NULL), K(k), L(l), Tag(tag) {}
: Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
const void *tag = 0)

View File

@ -423,6 +423,14 @@ class Diagnostic : public llvm::RefCountedBase<Diagnostic> {
/// the diagnostic, this returns null.
static const char *getWarningOptionForDiag(unsigned DiagID);
/// getWarningOptionForDiag - Return the category number that a specified
/// DiagID belongs to, or 0 if no category.
static unsigned getCategoryNumberForDiag(unsigned DiagID);
/// getCategoryNameFromID - Given a category ID, return the name of the
/// category.
static const char *getCategoryNameFromID(unsigned CategoryID);
/// \brief Enumeration describing how the the emission of a diagnostic should
/// be treated when it occurs during C++ template argument deduction.
enum SFINAEResponse {

View File

@ -42,7 +42,10 @@ class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
// This defines the diagnostic groups that have references to them.
// This defines all of the named diagnostic categories.
include "DiagnosticCategories.td"
// This defines all of the named diagnostic groups.
include "DiagnosticGroups.td"

View File

@ -14,17 +14,20 @@ let Component = "AST" in {
def note_expr_divide_by_zero : Note<"division by zero">;
// inline asm related.
def err_asm_invalid_escape : Error<
"invalid %% escape in inline assembly string">;
def err_asm_unknown_symbolic_operand_name : Error<
"unknown symbolic operand name in inline assembly string">;
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<
"invalid %% escape in inline assembly string">;
def err_asm_unknown_symbolic_operand_name : Error<
"unknown symbolic operand name in inline assembly string">;
def err_asm_unterminated_symbolic_operand_name : Error<
"unterminated symbolic operand name in inline assembly string">;
def err_asm_empty_symbolic_operand_name : Error<
"empty symbolic operand name in inline assembly string">;
def err_asm_invalid_operand_number : Error<
"invalid operand number in inline asm string">;
}
def err_asm_unterminated_symbolic_operand_name : Error<
"unterminated symbolic operand name in inline assembly string">;
def err_asm_empty_symbolic_operand_name : Error<
"empty symbolic operand name in inline assembly string">;
def err_asm_invalid_operand_number : Error<
"invalid operand number in inline asm string">;
// Importing ASTs
def err_odr_variable_type_inconsistent : Error<

View File

@ -0,0 +1,10 @@
//==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
class CatInlineAsm : DiagCategory<"Inline Assembly Issue">;

View File

@ -49,6 +49,8 @@ def err_drv_no_ast_support : Error<
"'%0': unable to use AST files with this tool">;
def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
def err_drv_command_signalled : Error<

View File

@ -16,7 +16,8 @@ def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
DefaultFatal;
def err_fe_inline_asm : Error<"%0">; // Error generated by the backend.
// Error generated by the backend.
def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
def note_fe_inline_asm_here : Note<"generated from here">;
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;

View File

@ -40,6 +40,9 @@ def ExtraTokens : DiagGroup<"extra-tokens">;
def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
def CXXHexFloats : DiagGroup<"c++-hex-floats">;
def : DiagGroup<"c++0x-compat", [CXXHexFloats]>;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
def : DiagGroup<"idiomatic-parentheses">;
def : DiagGroup<"import">;
@ -120,6 +123,7 @@ def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">;
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">;
def CharSubscript : DiagGroup<"char-subscripts">;
@ -134,16 +138,17 @@ def Parentheses : DiagGroup<"parentheses", [DiagGroup<"idiomatic-parentheses">]>
// legacy reasons.
def Conversion : DiagGroup<"conversion",
[DiagGroup<"shorten-64-to-32">]>,
DiagCategory<"Value Conversion">;
DiagCategory<"Value Conversion Issue">;
def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
// UnusedParameter, (matches GCC's behavior)
UnusedValue, UnusedVariable]>;
UnusedValue, UnusedVariable]>,
DiagCategory<"Unused Entity Issue">;
// Format settings.
def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>,
DiagCategory<"Format String">;
DiagCategory<"Format String Issue">;
def FormatSecurity : DiagGroup<"format-security", [Format]>;
def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
def FormatY2K : DiagGroup<"format-y2k", [Format]>;
@ -190,4 +195,4 @@ def NonGCC : DiagGroup<"non-gcc",
[SignCompare, Conversion, LiteralRange]>;
// A warning group for warnings about GCC extensions.
def GNU : DiagGroup<"gnu", [GNUDesignator]>;
def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;

View File

@ -11,7 +11,7 @@
// Lexer Diagnostics
//===----------------------------------------------------------------------===//
let Component = "Lex" in {
let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in {
def null_in_string : Warning<"null character(s) preserved in string literal">;
def null_in_char : Warning<"null character(s) preserved in character literal">;
@ -84,9 +84,9 @@ def err_exponent_has_no_digits : Error<"exponent has no digits">;
def ext_imaginary_constant : Extension<"imaginary constants are an extension">;
def err_hexconstant_requires_exponent : Error<
"hexadecimal floating constants require an exponent">;
def ext_hexconstant_cplusplus : ExtWarn<
def ext_hexconstant_cplusplus : Extension<
"hexadecimal floating constants are a C99 feature that is incompatible with "
"C++0x">;
"C++0x">, InGroup<CXXHexFloats>;
def ext_hexconstant_invalid : Extension<
"hexadecimal floating constants are a C99 feature">;
def ext_binary_literal : Extension<

View File

@ -13,9 +13,12 @@
let Component = "Parse" in {
def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">,
CatInlineAsm;
def warn_file_asm_volatile : Warning<
"meaningless 'volatile' on asm outside function">;
"meaningless 'volatile' on asm outside function">, CatInlineAsm;
let CategoryName = "Parse Issue" in {
def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
def ext_top_level_semi : Extension<
@ -119,6 +122,8 @@ def err_expected_semi_after_namespace_name : Error<
"expected ';' after namespace name">;
def err_unexpected_namespace_attributes_alias : Error<
"attributes can not be specified on namespace alias">;
def err_namespace_nonnamespace_scope : Error<
"namespaces can only be defined in global or namespace scope">;
def err_expected_semi_after_attribute_list : Error<
"expected ';' after attribute list">;
def err_expected_semi_after_static_assert : Error<
@ -129,7 +134,7 @@ def err_label_end_of_compound_statement : Error<
"label at end of compound statement: expected statement">;
def err_expected_string_literal : Error<"expected string literal">;
def err_expected_asm_operand : Error<
"expected string literal or '[' for asm operand">;
"expected string literal or '[' for asm operand">, CatInlineAsm;
def err_expected_selector_for_method : Error<
"expected selector for Objective-C method">;
def err_expected_property_name : Error<"expected property name">;
@ -311,6 +316,9 @@ def err_explicit_instantiation_with_definition : Error<
"'template' keyword">;
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">;
// Constructor template diagnostics.
def err_out_of_line_constructor_template_id : Error<
"out-of-line constructor for %0 cannot have template arguments">;
@ -355,6 +363,13 @@ def warn_pragma_expected_identifier : Warning<
"expected identifier in '#pragma %0' - ignored">;
def warn_pragma_extra_tokens_at_eol : Warning<
"extra tokens at end of '#pragma %0' - ignored">;
// - #pragma options
def warn_pragma_options_expected_align : Warning<
"expected 'align' following '#pragma options' - ignored">;
def warn_pragma_options_expected_equal : Warning<
"expected '=' following '#pragma options align' - ignored">;
def warn_pragma_options_invalid_option : Warning<
"invalid alignment option in '#pragma options align' - ignored">;
// - #pragma pack
def warn_pragma_pack_invalid_action : Warning<
"unknown action for '#pragma pack' - ignored">;
@ -368,4 +383,5 @@ def warn_pragma_unused_expected_var : Warning<
def warn_pragma_unused_expected_punc : Warning<
"expected ')' or ',' in '#pragma unused'">;
} // end of Parse Issue category.
} // end of Parser diagnostics

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
let Component = "Sema" in {
let CategoryName = "Semantic Issue" in {
// Constant expressions
def err_expr_not_ice : Error<
@ -36,6 +37,28 @@ def warn_float_underflow : Warning<
"magnitude of floating-point constant too small for type %0; minimum is %1">,
InGroup<LiteralRange>;
// C99 variable-length arrays
def ext_vla : Extension<
"variable length arrays are a C99 feature, accepted as an extension">,
InGroup<VLA>;
def err_vla_non_pod : Error<"variable length array of non-POD element type %0">;
def err_vla_in_sfinae : Error<
"variable length array cannot be formed during template argument deduction">;
def err_array_star_in_function_definition : Error<
"variable length array must be bound in function definition">;
def err_vla_decl_in_file_scope : Error<
"variable length array declaration not allowed at file scope">;
def err_vla_decl_has_static_storage : Error<
"variable length array declaration can not have 'static' storage duration">;
def err_vla_decl_has_extern_linkage : Error<
"variable length array declaration can not have 'extern' linkage">;
// C99 variably modified types
def err_variably_modified_template_arg : Error<
"variably modified type %0 cannot be used as a template argument">;
def err_variably_modified_nontype_template_param : Error<
"non-type template parameter of variably modified type %0">;
// C99 Designated Initializers
def err_array_designator_negative : Error<
"array designator value '%0' is negative">;
@ -71,11 +94,6 @@ def ext_flexible_array_init : Extension<
"flexible array initialization is a GNU extension">, InGroup<GNU>;
// Declarations.
def ext_vla : Extension<
"variable length arrays are a C99 feature, accepted as an extension">;
def err_vla_cxx : Error<
"variable length arrays are not permitted in C++">;
def ext_anon_param_requires_type_specifier : Extension<
"type specifier required for unnamed parameter, defaults to int">;
def err_bad_variable_name : Error<
@ -89,8 +107,6 @@ def warn_unused_exception_param : Warning<"unused exception parameter %0">,
InGroup<UnusedExceptionParameter>, DefaultIgnore;
def warn_decl_in_param_list : Warning<
"declaration of %0 will not be visible outside of this function">;
def err_array_star_in_function_definition : Error<
"variable length array must be bound in function definition">;
def warn_unused_function : Warning<"unused function %0">,
InGroup<UnusedFunction>, DefaultIgnore;
@ -220,6 +236,12 @@ def err_object_cannot_be_passed_returned_by_value : Error<
"interface type %1 cannot be %select{returned|passed}0 by value"
"; did you forget * in %1">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
def warn_pragma_options_align_unsupported_option : Warning<
"unsupported alignment option in '#pragma options align'">;
def warn_pragma_options_align_reset_failed : Warning<
"#pragma options align=reset failed: %0">;
def err_pragma_options_align_mac68k_target_unsupported : Error<
"mac68k alignment pragma is not supported on this target">;
def warn_pragma_pack_invalid_alignment : Warning<
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
// Follow the MSVC implementation.
@ -293,6 +315,8 @@ def warn_conflicting_ret_types : Warning<
def warn_conflicting_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">;
def warn_conflicting_variadic :Warning<
"conflicting variadic declaration of method and its implementation">;
def warn_implements_nscopying : Warning<
"default assign attribute on property %0 which implements "
@ -503,6 +527,10 @@ def err_access_copy_field :
def err_access_copy_base :
Error<"base class %0 has %select{private|protected}1 copy constructor">,
NoSFINAE;
def err_access_dtor_ivar :
Error<"instance variable of type %0 has %select{private|protected}1 "
"destructor">,
NoSFINAE;
def note_previous_access_declaration : Note<
"previously declared '%1' here">;
def err_access_outside_class : Error<
@ -709,6 +737,7 @@ def note_uninit_reference_member : Note<
"uninitialized reference member is here">;
def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
InGroup<DiagGroup<"uninitialized">>;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
def err_temp_copy_no_viable : Error<
"no viable constructor %select{copying variable|copying parameter|"
@ -883,6 +912,12 @@ def warn_impcast_float_precision : Warning<
def warn_impcast_float_integer : Warning<
"implicit cast turns floating-point number into integer: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
"implicit cast changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign_conditional : Warning<
"operand of ? changes signedness: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
"implicit cast loses integer precision: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
@ -951,8 +986,7 @@ def err_attribute_regparm_invalid_number : Error<
// Clang-Specific Attributes
def err_attribute_iboutlet : Error<
"iboutlet attribute can only be applied to instance variables or "
"properties">;
"%0 attribute can only be applied to instance variables or properties">;
def err_attribute_ibaction: Error<
"ibaction attribute can only be applied to Objective-C instance methods">;
def err_attribute_overloadable_not_function : Error<
@ -1054,15 +1088,29 @@ def note_ovl_candidate_bad_deduction : Note<
"candidate template ignored: failed template argument deduction">;
def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
"couldn't infer template argument %0">;
def note_ovl_candidate_inconsistent_deduction : Note<
"candidate template ignored: deduced conflicting %select{types|values|"
"templates}0 for parameter %1 (%2 vs. %3)">;
def note_ovl_candidate_explicit_arg_mismatch_named : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for template parameter %0">;
def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
"candidate template ignored: invalid explicitly-specified argument "
"for %ordinal0 template parameter">;
def note_ovl_candidate_instantiation_depth : Note<
"candidate template ignored: substitution exceeded maximum template "
"instantiation depth">;
def note_ovl_candidate_substitution_failure : Note<
"candidate template ignored: substitution failure %0">;
// Note that we don't treat templates differently for this diagnostic.
def note_ovl_candidate_arity : 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)}0 not viable: requires"
"%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 "
"provided">;
"function (the implicit copy assignment operator)}0 %select{|template }1"
"not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 "
"%plural{1:was|:were}4 provided">;
def note_ovl_candidate_deleted : Note<
"candidate %select{function|function|constructor|"
@ -1484,6 +1532,12 @@ def err_explicit_instantiation_out_of_scope : Error<
"explicit instantiation of %0 not in a namespace enclosing %1">;
def err_explicit_instantiation_must_be_global : Error<
"explicit instantiation of %0 must occur at global scope">;
def warn_explicit_instantiation_out_of_scope_0x : Warning<
"explicit instantiation of %0 not in a namespace enclosing %1">,
InGroup<DiagGroup<"-Wc++0x-compat"> >;
def warn_explicit_instantiation_must_be_global_0x : Warning<
"explicit instantiation of %0 must occur at global scope">,
InGroup<DiagGroup<"-Wc++0x-compat"> >;
def err_explicit_instantiation_requires_name : Error<
"explicit instantiation declaration requires a name">;
@ -1512,6 +1566,9 @@ def err_explicit_instantiation_without_qualified_id_quals : Error<
"qualifier in explicit instantiation of '%0%1' requires a template-id">;
def err_explicit_instantiation_unqualified_wrong_namespace : Error<
"explicit instantiation of %q0 must occur in %1">;
def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
"explicit instantiation of %q0 must occur in %1">,
InGroup<DiagGroup<"c++0x-compat"> >;
def err_explicit_instantiation_undefined_member : Error<
"explicit instantiation of undefined %select{member class|member function|"
"static data member}0 %1 of class template %2">;
@ -1631,12 +1688,6 @@ def warn_enumerator_too_large : Warning<
def warn_illegal_constant_array_size : Extension<
"size of static array must be an integer constant expression">;
def err_vla_decl_in_file_scope : Error<
"variable length array declaration not allowed at file scope">;
def err_vla_decl_has_static_storage : Error<
"variable length array declaration can not have 'static' storage duration">;
def err_vla_decl_has_extern_linkage : Error<
"variable length array declaration can not have 'extern' linkage">;
def err_vm_decl_in_file_scope : Error<
"variably modified type declaration not allowed at file scope">;
def err_vm_decl_has_extern_linkage : Error<
@ -1725,20 +1776,20 @@ def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
def err_goto_into_protected_scope : Error<"illegal goto into protected scope">;
def err_switch_into_protected_scope : Error<
"illegal switch case into protected scope">;
def err_indirect_goto_in_protected_scope : Warning<
"illegal indirect goto in protected scope, unknown effect on scopes">,
InGroup<DiagGroup<"label-address-scope">>;
def err_addr_of_label_in_protected_scope : Warning<
"address taken of label in protected scope, jump to it would have "
"unknown effect on scope">, InGroup<DiagGroup<"label-address-scope">>;
def err_indirect_goto_without_addrlabel : Error<
"indirect goto in function with no address-of-label expressions">;
def warn_indirect_goto_in_protected_scope : Warning<
"indirect goto might cross protected scopes">,
InGroup<DiagGroup<"label-address-scope">>;
def note_indirect_goto_target : Note<"possible target of indirect goto">;
def note_protected_by_variable_init : Note<
"jump bypasses variable initialization">;
def note_protected_by_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 : Note<
"jump bypasses initialization of variable length array">;
def note_protected_by_cleanup : Note<
"jump bypasses initialization of declaration with __attribute__((cleanup))">;
def note_protected_by_objc_try : Note<
"jump bypasses initialization of @try block">;
def note_protected_by_objc_catch : Note<
@ -1754,6 +1805,25 @@ def note_protected_by_cxx_catch : Note<
def note_protected_by___block : Note<
"jump bypasses setup of __block variable">;
def note_exits_cleanup : Note<
"jump exits scope of variable with __attribute__((cleanup))">;
def note_exits_dtor : Note<
"jump exits scope of variable with non-trivial destructor">;
def note_exits___block : Note<
"jump exits scope of __block variable">;
def note_exits_objc_try : Note<
"jump exits @try block">;
def note_exits_objc_catch : Note<
"jump exits @catch block">;
def note_exits_objc_finally : Note<
"jump exits @finally block">;
def note_exits_objc_synchronized : Note<
"jump exits @synchronized block">;
def note_exits_cxx_try : Note<
"jump exits try block">;
def note_exits_cxx_catch : Note<
"jump exits catch block">;
def err_func_returning_array_function : Error<
"function cannot return %select{array|function}0 type %1">;
def err_field_declared_as_function : Error<"field %0 declared as a function">;
@ -1764,6 +1834,8 @@ def ext_variable_sized_type_in_struct : ExtWarn<
def err_flexible_array_empty_struct : Error<
"flexible array %0 not allowed in otherwise empty struct">;
def err_flexible_array_has_nonpod_type : Error<
"flexible array member %0 of non-POD element type %1">;
def ext_flexible_array_in_struct : Extension<
"%0 may not be nested in a struct due to flexible array member">;
def ext_flexible_array_in_array : Extension<
@ -1806,6 +1878,9 @@ def err_func_def_incomplete_result : Error<
// Expressions.
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">;
def ext_sizeof_void_type : Extension<
"invalid application of '%0' to a void type">, InGroup<PointerArith>;
def err_sizeof_alignof_incomplete_type : Error<
@ -2196,6 +2271,8 @@ def err_default_init_const : Error<
"default initialization of an object of const type %0"
"%select{| requires a user-provided default constructor}1">;
def err_delete_operand : Error<"cannot delete expression of type %0">;
def ext_delete_void_ptr_operand : ExtWarn<
"cannot delete expression with pointer-to-'void' type %0">;
def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
@ -2293,7 +2370,9 @@ def err_cannot_form_pointer_to_member_of_reference_type : Error<
"cannot form a pointer-to-member to member %0 of reference type %1">;
def err_incomplete_object_call : Error<
"incomplete type in call to object of type %0">;
def err_incomplete_pointer_to_member_return : Error<
"incomplete return type %0 of pointer-to-member constant">;
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
InGroup<Parentheses>;
@ -2510,31 +2589,35 @@ 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_expected_ident_or_lparen : Error<"expected identifier or '('">;
} // End of general sema category.
// inline asm.
def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
def err_asm_invalid_output_constraint : Error<
"invalid output constraint '%0' in asm">;
def err_asm_invalid_lvalue_in_input : Error<
"invalid lvalue in asm input for constraint '%0'">;
def err_asm_invalid_input_constraint : Error<
"invalid input constraint '%0' in asm">;
def err_asm_invalid_type_in_input : Error<
"invalid type %0 in asm input for constraint '%1'">;
def err_asm_tying_incompatible_types : Error<
"unsupported inline asm: input with type %0 matching output with type %1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
def warn_invalid_asm_cast_lvalue : Warning<
"invalid use of a cast in a inline asm context requiring an l-value: "
"accepted due to -fheinous-gnu-extensions, but clang may remove support "
"for this in the future">;
let CategoryName = "Inline Assembly Issue" in {
def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
def err_asm_invalid_output_constraint : Error<
"invalid output constraint '%0' in asm">;
def err_asm_invalid_lvalue_in_input : Error<
"invalid lvalue in asm input for constraint '%0'">;
def err_asm_invalid_input_constraint : Error<
"invalid input constraint '%0' in asm">;
def err_asm_invalid_type_in_input : Error<
"invalid type %0 in asm input for constraint '%1'">;
def err_asm_tying_incompatible_types : Error<
"unsupported inline asm: input with type %0 matching output with type %1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
def warn_invalid_asm_cast_lvalue : Warning<
"invalid use of a cast in a inline asm context requiring an l-value: "
"accepted due to -fheinous-gnu-extensions, but clang may remove support "
"for this in the future">;
}
let CategoryName = "Semantic Issue" in {
def err_invalid_conversion_between_vectors : Error<
"invalid conversion between vector type %0 and %1 of different size">;
@ -2842,9 +2925,11 @@ def warn_case_value_overflow : Warning<
InGroup<DiagGroup<"switch">>;
def err_duplicate_case : Error<"duplicate case value '%0'">;
def warn_case_empty_range : Warning<"empty case range specified">;
def warn_missing_case_for_condition :
Warning<"no case matching constant switch condition '%0'">;
def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">,
InGroup<DiagGroup<"switch-enum"> >;
def not_in_enum : Warning<"case value not in enumerated type %0">,
def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
InGroup<DiagGroup<"switch-enum"> >;
def err_typecheck_statement_requires_scalar : Error<
"statement requires expression of scalar type (%0 invalid)">;
@ -3010,6 +3095,6 @@ def err_undeclared_protocol_suggest : Error<
def note_base_class_specified_here : Note<
"base class %0 specified here">;
}
} // end of sema category
} // end of sema component.

View File

@ -280,6 +280,57 @@ class ExternalSLocEntrySource {
/// \brief Read the source location entry with index ID.
virtual void ReadSLocEntry(unsigned ID) = 0;
};
/// IsBeforeInTranslationUnitCache - This class holds the cache used by
/// isBeforeInTranslationUnit. The cache structure is complex enough to be
/// worth breaking out of SourceManager.
class IsBeforeInTranslationUnitCache {
/// L/R QueryFID - These are the FID's of the cached query. If these match up
/// with a subsequent query, the result can be reused.
FileID LQueryFID, RQueryFID;
/// CommonFID - This is the file found in common between the two #include
/// traces. It is the nearest common ancestor of the #include tree.
FileID CommonFID;
/// L/R CommonOffset - This is the offset of the previous query in CommonFID.
/// Usually, this represents the location of the #include for QueryFID, but if
/// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a
/// random token in the parent.
unsigned LCommonOffset, RCommonOffset;
public:
/// isCacheValid - Return true if the currently cached values match up with
/// the specified LHS/RHS query. If not, we can't use the cache.
bool isCacheValid(FileID LHS, FileID RHS) const {
return LQueryFID == LHS && RQueryFID == RHS;
}
/// getCachedResult - If the cache is valid, compute the result given the
/// specified offsets in the LHS/RHS FID's.
bool getCachedResult(unsigned LOffset, unsigned ROffset) const {
// If one of the query files is the common file, use the offset. Otherwise,
// use the #include loc in the common file.
if (LQueryFID != CommonFID) LOffset = LCommonOffset;
if (RQueryFID != CommonFID) ROffset = RCommonOffset;
return LOffset < ROffset;
}
// Set up a new query.
void setQueryFIDs(FileID LHS, FileID RHS) {
LQueryFID = LHS;
RQueryFID = RHS;
}
void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
unsigned rCommonOffset) {
CommonFID = commonFID;
LCommonOffset = lCommonOffset;
RCommonOffset = rCommonOffset;
}
};
/// SourceManager - This file handles loading and caching of source files into
/// memory. This object owns the MemoryBuffer objects for all of the loaded
@ -347,9 +398,7 @@ class SourceManager {
mutable unsigned NumLinearScans, NumBinaryProbes;
// Cache results for the isBeforeInTranslationUnit method.
mutable FileID LastLFIDForBeforeTUCheck;
mutable FileID LastRFIDForBeforeTUCheck;
mutable bool LastResForBeforeTUCheck;
mutable IsBeforeInTranslationUnitCache IsBeforeInTUCache;
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&);

View File

@ -58,6 +58,8 @@ class TargetInfo {
const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat;
unsigned char RegParmMax, SSERegParmMax;
unsigned HasAlignMac68kSupport : 1;
// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const std::string &T);
@ -210,6 +212,12 @@ class TargetInfo {
return UseBitFieldTypeAlignment;
}
/// hasAlignMac68kSupport - Check whether this target support '#pragma options
/// align=mac68k'.
bool hasAlignMac68kSupport() const {
return HasAlignMac68kSupport;
}
/// getTypeName - Return the user string for the specified integer type enum.
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);

View File

@ -220,7 +220,7 @@ KEYWORD(unsigned , KEYALL)
KEYWORD(void , KEYALL)
KEYWORD(volatile , KEYALL)
KEYWORD(while , KEYALL)
KEYWORD(_Bool , KEYALL)
KEYWORD(_Bool , KEYNOMS)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Imaginary , KEYALL)
KEYWORD(__func__ , KEYALL)
@ -336,6 +336,7 @@ KEYWORD(__declspec , KEYALL)
KEYWORD(__cdecl , KEYALL)
KEYWORD(__stdcall , KEYALL)
KEYWORD(__fastcall , KEYALL)
KEYWORD(__thiscall , KEYALL)
KEYWORD(__forceinline , KEYALL)
// Altivec Extension.
@ -372,6 +373,7 @@ ALIAS("_asm" , asm , KEYMS)
ALIAS("_cdecl" , __cdecl , KEYMS)
ALIAS("_fastcall" , __fastcall , KEYMS)
ALIAS("_stdcall" , __stdcall , KEYMS)
ALIAS("_thiscall" , __thiscall , KEYMS)
//===----------------------------------------------------------------------===//
// Objective-C @-preceeded keywords.

View File

@ -1,2 +1,3 @@
add_subdirectory(AST)
add_subdirectory(Basic)
add_subdirectory(Driver)

View File

@ -37,8 +37,12 @@ class AnalysisManager : public BugReporterData {
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
// The maximum number of exploded nodes the analyzer will generate.
unsigned MaxNodes;
// The maximum number of times the analyzer will go through a loop.
unsigned MaxLoop;
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
@ -52,19 +56,22 @@ class AnalysisManager : public BugReporterData {
// bifurcates paths.
bool EagerlyAssume;
bool TrimGraph;
bool InlineCall;
public:
AnalysisManager(ASTContext &ctx, Diagnostic &diags,
const LangOptions &lang, PathDiagnosticClient *pd,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr, unsigned maxnodes,
bool vizdot, bool vizubi, bool purge, bool eager, bool trim)
unsigned maxloop,
bool vizdot, bool vizubi, bool purge, bool eager, bool trim,
bool inlinecall)
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
AScope(ScopeDecl), MaxNodes(maxnodes),
AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {}
~AnalysisManager() { FlushDiagnostics(); }
@ -108,6 +115,8 @@ class AnalysisManager : public BugReporterData {
unsigned getMaxNodes() const { return MaxNodes; }
unsigned getMaxLoop() const { return MaxLoop; }
bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
@ -122,6 +131,8 @@ class AnalysisManager : public BugReporterData {
bool shouldEagerlyAssume() const { return EagerlyAssume; }
bool shouldInlineCall() const { return InlineCall; }
CFG *getCFG(Decl const *D) {
return AnaCtxMgr.getContext(D)->getCFG();
}

View File

@ -456,6 +456,8 @@ class GRExprEngine : public GRSubEngine {
void EvalLocation(ExplodedNodeSet &Dst, Stmt *S, ExplodedNode* Pred,
const GRState* St, SVal location,
const void *tag, bool isLoad);
bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
};
} // end clang namespace

View File

@ -18,6 +18,7 @@
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
namespace clang {
@ -143,9 +144,9 @@ class StoreManager {
return UnknownVal();
}
virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
const StackFrameContext *LCtx,
SymbolReaper& SymReaper,
virtual const GRState *RemoveDeadBindings(GRState &state, Stmt* Loc,
const StackFrameContext *LCtx,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0;
@ -167,10 +168,15 @@ class StoreManager {
// FIXME: Make out-of-line.
virtual const GRState *setExtent(const GRState *state,
const MemRegion *region, SVal extent) {
const MemRegion *region, SVal extent) {
return state;
}
virtual llvm::Optional<SVal> getExtent(const GRState *state,
const MemRegion *R) {
return llvm::Optional<SVal>();
}
/// EnterStackFrame - Let the StoreManager to do something when execution
/// engine is about to execute into a callee.
virtual const GRState *EnterStackFrame(const GRState *state,

View File

@ -54,6 +54,7 @@ class CodeGenOptions {
unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
unsigned RelaxAll : 1; /// Relax all machine code instructions.
unsigned SoftFloat : 1; /// -soft-float.
unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
unsigned UnitAtATime : 1; /// Unused. For mirroring GCC optimization
@ -108,6 +109,7 @@ class CodeGenOptions {
ObjCDispatchMethod = Legacy;
OptimizationLevel = 0;
OptimizeSize = 0;
RelaxAll = 0;
SoftFloat = 0;
TimePasses = 0;
UnitAtATime = 1;

View File

@ -17,12 +17,15 @@
#include <list>
#include <string>
#include <vector>
namespace llvm {
class Twine;
}
namespace clang {
class Diagnostic;
namespace driver {
class Arg;
class ArgList;
@ -175,6 +178,25 @@ namespace driver {
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
/// @}
/// @name Argument Lookup Utilities
/// @{
/// getLastArgValue - Return the value of the last argument, or a default.
llvm::StringRef getLastArgValue(OptSpecifier Id,
llvm::StringRef Default = "") const;
/// getLastArgValue - Return the value of the last argument as an integer,
/// or a default. Emits an error if the argument is given, but non-integral.
int getLastArgIntValue(OptSpecifier Id, int Default,
Diagnostic &Diags) const;
/// getAllArgValues - Get the values of all instances of the given argument
/// as strings.
std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
/// @}
/// @name Translation Utilities
/// @{

View File

@ -0,0 +1,32 @@
//===--- CC1AsOptions.h - Clang Assembler Options Table ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_DRIVER_CC1ASOPTIONS_H
#define CLANG_DRIVER_CC1ASOPTIONS_H
namespace clang {
namespace driver {
class OptTable;
namespace cc1asoptions {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
#include "clang/Driver/CC1AsOptions.inc"
LastOption
#undef OPTION
};
}
OptTable *createCC1AsOptTable();
}
}
#endif

View File

@ -0,0 +1,71 @@
//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===//
//
// 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 options accepted by clang -cc1as.
//
//===----------------------------------------------------------------------===//
// Include the common option parsing interfaces.
include "OptParser.td"
//===----------------------------------------------------------------------===//
// Target Options
//===----------------------------------------------------------------------===//
def triple : Separate<"-triple">,
HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//
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">;
//===----------------------------------------------------------------------===//
// Frontend Options
//===----------------------------------------------------------------------===//
def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
def filetype : Separate<"-filetype">,
HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
def help : Flag<"-help">,
HelpText<"Print this help text">;
def _help : Flag<"--help">, Alias<help>;
def version : Flag<"-version">,
HelpText<"Print the assembler version">;
def _version : Flag<"--version">, Alias<version>;
// Generic forwarding to LLVM options. This should only be used for debugging
// and experimental features.
def mllvm : Separate<"-mllvm">,
HelpText<"Additional arguments to forward to LLVM's option processing">;
//===----------------------------------------------------------------------===//
// Transliterate Options
//===----------------------------------------------------------------------===//
def output_asm_variant : Separate<"-output-asm-variant">,
HelpText<"Select the asm variant index to use for output">;
def show_encoding : Flag<"-show-encoding">,
HelpText<"Show instruction encoding information in transliterate mode">;
def show_inst : Flag<"-show-inst">,
HelpText<"Show internal instruction representation in transliterate mode">;
//===----------------------------------------------------------------------===//
// Assemble Options
//===----------------------------------------------------------------------===//
def relax_all : Flag<"-relax-all">,
HelpText<"Relax all fixups (for performance testing)">;

View File

@ -56,8 +56,6 @@ def analysis_ObjCMemChecker : Flag<"-analyzer-check-objc-mem">,
HelpText<"Run the [Core] Foundation reference count checker">;
def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
def analysis_InlineCall : Flag<"-inline-call">,
HelpText<"Experimental transfer function inlining callees when its definition is available.">;
def analyzer_store : Separate<"-analyzer-store">,
HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@ -97,8 +95,12 @@ def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">,
HelpText<"Display exploded graph using GraphViz">;
def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
HelpText<"Display exploded graph using Ubigraph">;
def analyzer_inline_call : Flag<"-analyzer-inline-call">,
HelpText<"Experimental transfer function inlining callees when its definition is available.">;
def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
HelpText<"The maximum number of nodes the analyzer can generate">;
def analyzer_max_loop : Separate<"-analyzer-max-loop">,
HelpText<"The maximum number of times the analyzer will go through a loop">;
//===----------------------------------------------------------------------===//
// CodeGen Options
@ -145,6 +147,8 @@ def mno_zero_initialized_in_bss : Flag<"-mno-zero-initialized-in-bss">,
HelpText<"Do not put zero initialized data in the BSS">;
def msoft_float : Flag<"-msoft-float">,
HelpText<"Use software floating point">;
def mrelax_all : Flag<"-mrelax-all">,
HelpText<"Relax all machine instructions">;
def mrelocation_model : Separate<"-mrelocation-model">,
HelpText<"The relocation model to use">;
def munwind_tables : Flag<"-munwind-tables">,
@ -196,6 +200,9 @@ def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-rang
HelpText<"Print source range spans in numeric form">;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print diagnostic name with mappable diagnostics">;
def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
HelpText<"Set the tab stop distance.">;
def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
@ -238,6 +245,8 @@ def no_code_completion_debug_printer : Flag<"-no-code-completion-debug-printer">
HelpText<"Don't use the \"debug\" code-completion print">;
def code_completion_macros : Flag<"-code-completion-macros">,
HelpText<"Include macros in code-completion results">;
def code_completion_patterns : Flag<"-code-completion-patterns">,
HelpText<"Include code patterns in code-completion results">;
def disable_free : Flag<"-disable-free">,
HelpText<"Disable freeing of memory on exit">;
def help : Flag<"-help">,
@ -293,6 +302,8 @@ def ast_dump : Flag<"-ast-dump">,
HelpText<"Build ASTs and then debug dump them">;
def ast_view : Flag<"-ast-view">,
HelpText<"Build ASTs and view them with GraphViz">;
def boostcon : Flag<"-boostcon">,
HelpText<"BoostCon workshop mode">;
def print_decl_contexts : Flag<"-print-decl-contexts">,
HelpText<"Print DeclContexts and their Decls">;
def emit_pth : Flag<"-emit-pth">,
@ -307,6 +318,8 @@ def emit_llvm_bc : Flag<"-emit-llvm-bc">,
HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
def emit_llvm_only : Flag<"-emit-llvm-only">,
HelpText<"Build ASTs and convert to LLVM, discarding output">;
def emit_codegen_only : Flag<"-emit-codegen-only">,
HelpText<"Generate machine code, but discard output">;
def emit_obj : Flag<"-emit-obj">,
HelpText<"Emit native object files">;
def rewrite_test : Flag<"-rewrite-test">,

View File

@ -9,3 +9,9 @@ tablegen(CC1Options.inc
-gen-opt-parser-defs)
add_custom_target(ClangCC1Options
DEPENDS CC1Options.inc)
set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td)
tablegen(CC1AsOptions.inc
-gen-opt-parser-defs)
add_custom_target(ClangCC1AsOptions
DEPENDS CC1AsOptions.inc)

View File

@ -1,5 +1,5 @@
LEVEL = ../../../../..
BUILT_SOURCES = Options.inc CC1Options.inc
BUILT_SOURCES = Options.inc CC1Options.inc CC1AsOptions.inc
TABLEGEN_INC_FILES_COMMON = 1
@ -13,4 +13,6 @@ $(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(TBLGEN) $(ObjDir)/.d
$(Echo) "Building Clang CC1 Option tables with tblgen"
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td OptParser.td $(TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang CC1 Assembler Option tables with tblgen"
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<

View File

@ -139,6 +139,7 @@ def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>;
def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
def Mach : Flag<"-Mach">;
def M : Flag<"-M">, Group<M_Group>;
def O0 : Joined<"-O0">, Group<O_Group>;
def O4 : Joined<"-O4">, Group<O_Group>;
def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>,
HelpText<"Treat source input files as Objective-C++ inputs">;
@ -231,6 +232,7 @@ def fPIC : Flag<"-fPIC">, Group<f_Group>;
def fPIE : Flag<"-fPIE">, Group<f_Group>;
def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
def fasm : Flag<"-fasm">, Group<f_Group>;
def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>;
def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>;
def fastcp : Flag<"-fastcp">, Group<f_Group>;
@ -257,6 +259,7 @@ def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[H
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_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_Group>;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, 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>;
@ -265,10 +268,7 @@ def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
def fhosted : Flag<"-fhosted">, Group<f_Group>;
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
def fasm : Flag<"-fasm">, Alias<fgnu_keywords>;
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
@ -291,6 +291,7 @@ def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>;
def fno_access_control : Flag<"-fno-access-control">, Group<f_Group>;
def fno_asm : Flag<"-fno-asm">, Group<f_Group>;
def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>;
def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>;
def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
@ -306,10 +307,7 @@ def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>;
def fno_asm : Flag<"-fno-asm">, Alias<fno_gnu_keywords>;
def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
@ -329,6 +327,7 @@ 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_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>;
@ -384,6 +383,8 @@ def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
def ffunction_sections: Flag <"-ffunction-sections">, Group<f_Group>;
def fdata_sections : Flag <"-fdata-sections">, Group<f_Group>;
def f : Joined<"-f">, Group<f_Group>;
def g0 : Joined<"-g0">, Group<g_Group>;
def g3 : Joined<"-g3">, Group<g_Group>;
@ -436,6 +437,7 @@ def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>;
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_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>;
@ -453,6 +455,7 @@ def marm : Flag<"-marm">, Alias<mno_thumb>;
def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
def mrelax_all : Flag<"-mrelax-all">, 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>;
@ -667,6 +670,7 @@ def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
def _prefix : Separate<"--prefix">, Alias<B>;
def _preprocess : Flag<"--preprocess">, Alias<E>;
def _print_diagnostic_categories : Flag<"--print-diagnostic-categories">;
def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>;
def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>;
def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>;

View File

@ -30,17 +30,23 @@ class Tool {
/// The tool name (for debugging).
const char *Name;
/// The human readable name for the tool, for use in diagnostics.
const char *ShortName;
/// The tool chain this tool is a part of.
const ToolChain &TheToolChain;
public:
Tool(const char *Name, const ToolChain &TC);
Tool(const char *Name, const char *ShortName,
const ToolChain &TC);
public:
virtual ~Tool();
const char *getName() const { return Name; }
const char *getShortName() const { return ShortName; }
const ToolChain &getToolChain() const { return TheToolChain; }
virtual bool acceptsPipedInput() const = 0;

View File

@ -61,6 +61,7 @@ class AnalyzerOptions {
AnalysisDiagClients AnalysisDiagOpt;
std::string AnalyzeSpecificFunction;
unsigned MaxNodes;
unsigned MaxLoop;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
@ -71,6 +72,8 @@ class AnalyzerOptions {
unsigned VisualizeEGUbi : 1;
unsigned EnableExperimentalChecks : 1;
unsigned EnableExperimentalInternalChecks : 1;
unsigned InlineCall : 1;
public:
AnalyzerOptions() {
AnalysisStoreOpt = BasicStoreModel;

View File

@ -57,6 +57,11 @@ class EmitLLVMOnlyAction : public CodeGenAction {
EmitLLVMOnlyAction();
};
class EmitCodeGenOnlyAction : public CodeGenAction {
public:
EmitCodeGenOnlyAction();
};
class EmitObjAction : public CodeGenAction {
public:
EmitObjAction();

View File

@ -519,7 +519,7 @@ class CompilerInstance {
createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
unsigned Line, unsigned Column,
bool UseDebugPrinter, bool ShowMacros,
llvm::raw_ostream &OS);
bool ShowCodePatterns, llvm::raw_ostream &OS);
/// Create the frontend timer and replace any existing one with it.
void createFrontendTimer();

View File

@ -84,6 +84,7 @@
NODE_XML(Decl, "FIXME_Decl")
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclKindName(), "unhandled_decl_name")
END_NODE_XML
NODE_XML(FunctionDecl, "Function")
@ -106,7 +107,7 @@ NODE_XML(FunctionDecl, "Function")
SUB_NODE_FN_BODY_XML
END_NODE_XML
NODE_XML(CXXMethodDecl, "CXXMethodDecl")
NODE_XML(CXXMethodDecl, "CXXMethod")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
@ -116,6 +117,79 @@ NODE_XML(CXXMethodDecl, "CXXMethodDecl")
ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
ATTRIBUTE_OPT_XML(isStatic(), "static")
ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
ENUM_XML(AS_none, "")
ENUM_XML(AS_public, "public")
ENUM_XML(AS_protected, "protected")
ENUM_XML(AS_private, "private")
END_ENUM_XML
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
SUB_NODE_FN_BODY_XML
END_NODE_XML
NODE_XML(CXXConstructorDecl, "CXXConstructor")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit")
ATTRIBUTE_OPT_XML(isDefaultConstructor(), "is_default_ctor")
ATTRIBUTE_OPT_XML(isCopyConstructor(), "is_copy_ctor")
ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
ATTRIBUTE_OPT_XML(isStatic(), "static")
ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
ENUM_XML(AS_none, "")
ENUM_XML(AS_public, "public")
ENUM_XML(AS_protected, "protected")
ENUM_XML(AS_private, "private")
END_ENUM_XML
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
SUB_NODE_FN_BODY_XML
END_NODE_XML
NODE_XML(CXXDestructorDecl, "CXXDestructor")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
ATTRIBUTE_OPT_XML(isStatic(), "static")
ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
ENUM_XML(AS_none, "")
ENUM_XML(AS_public, "public")
ENUM_XML(AS_protected, "protected")
ENUM_XML(AS_private, "private")
END_ENUM_XML
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
SUB_NODE_FN_BODY_XML
END_NODE_XML
NODE_XML(CXXConversionDecl, "CXXConversion")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
TYPE_ATTRIBUTE_XML(getType()->getAs<FunctionType>()->getResultType())
ATTRIBUTE_XML(getType()->getAs<FunctionType>(), "function_type")
ATTRIBUTE_OPT_XML(isExplicit(), "is_explicit")
ATTRIBUTE_OPT_XML(isInlineSpecified(), "inline")
ATTRIBUTE_OPT_XML(isStatic(), "static")
ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
ENUM_XML(AS_none, "")
ENUM_XML(AS_public, "public")
ENUM_XML(AS_protected, "protected")
ENUM_XML(AS_private, "private")
END_ENUM_XML
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
SUB_NODE_FN_BODY_XML
@ -126,6 +200,7 @@ NODE_XML(NamespaceDecl, "Namespace")
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
SUB_NODE_SEQUENCE_XML(DeclContext)
END_NODE_XML
NODE_XML(UsingDirectiveDecl, "UsingDirective")
@ -189,6 +264,12 @@ NODE_XML(FieldDecl, "Field")
ATTRIBUTE_XML(getNameAsString(), "name")
TYPE_ATTRIBUTE_XML(getType())
ATTRIBUTE_OPT_XML(isMutable(), "mutable")
ATTRIBUTE_ENUM_OPT_XML(getAccess(), "access")
ENUM_XML(AS_none, "")
ENUM_XML(AS_public, "public")
ENUM_XML(AS_protected, "protected")
ENUM_XML(AS_private, "private")
END_ENUM_XML
ATTRIBUTE_OPT_XML(isBitField(), "bitfield")
SUB_NODE_OPT_XML(Expr) // init expr of a bit field
END_NODE_XML
@ -237,6 +318,35 @@ NODE_XML(LinkageSpecDecl, "LinkageSpec")
END_ENUM_XML
END_NODE_XML
NODE_XML(TemplateDecl, "Template")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
END_NODE_XML
NODE_XML(TemplateTypeParmDecl, "TemplateTypeParm")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getNameAsString(), "name")
END_NODE_XML
NODE_XML(UsingShadowDecl, "UsingShadow")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getTargetDecl(), "target_decl")
ATTRIBUTE_XML(getUsingDecl(), "using_decl")
END_NODE_XML
NODE_XML(UsingDecl, "Using")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
ATTRIBUTE_XML(getDeclContext(), "context")
ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl")
ATTRIBUTE_XML(isTypeName(), "is_typename")
END_NODE_XML
//===----------------------------------------------------------------------===//
#undef NODE_XML

View File

@ -30,6 +30,8 @@ class DiagnosticOptions {
unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form.
unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable
/// diagnostics.
unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
/// 2 -> Full Name.
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
unsigned VerifyDiagnostics: 1; /// Check that diagnostics match the expected
/// diagnostics, indicated by markers in the
@ -74,12 +76,13 @@ class DiagnosticOptions {
ShowFixits = 1;
ShowLocation = 1;
ShowOptionNames = 0;
ShowCategories = 0;
ShowSourceRanges = 0;
VerifyDiagnostics = 0;
BinaryOutput = 0;
ErrorLimit = 0;
TemplateBacktraceLimit = 0;
MacroBacktraceLimit = 0;
TemplateBacktraceLimit = DefaultTemplateBacktraceLimit;
MacroBacktraceLimit = DefaultMacroBacktraceLimit;
}
};

View File

@ -114,6 +114,7 @@ class DocumentXML {
void addPtrAttribute(const char* pName, const NamedDecl* D);
void addPtrAttribute(const char* pName, const DeclContext* D);
void addPtrAttribute(const char* pName, const NamespaceDecl* D); // disambiguation
void addPtrAttribute(const char* pName, const NestedNameSpecifier* N);
void addPtrAttribute(const char* pName, const LabelStmt* L);
void addPtrAttribute(const char* pName, const char* text);
@ -145,12 +146,23 @@ inline void DocumentXML::initialize(ASTContext &Context) {
//---------------------------------------------------------
template<class T>
inline void DocumentXML::addAttribute(const char* pName, const T& value) {
Out << ' ' << pName << "=\"" << value << "\"";
std::string repr;
{
llvm::raw_string_ostream buf(repr);
buf << value;
buf.flush();
}
Out << ' ' << pName << "=\""
<< DocumentXML::escapeString(repr.c_str(), repr.size())
<< "\"";
}
//---------------------------------------------------------
inline void DocumentXML::addPtrAttribute(const char* pName, const char* text) {
Out << ' ' << pName << "=\"" << text << "\"";
Out << ' ' << pName << "=\""
<< DocumentXML::escapeString(text, strlen(text))
<< "\"";
}
//---------------------------------------------------------

View File

@ -75,12 +75,10 @@ class DeclContextPrintAction : public ASTFrontendAction {
};
class FixItAction : public ASTFrontendAction {
private:
protected:
llvm::OwningPtr<FixItRewriter> Rewriter;
llvm::OwningPtr<FixItPathRewriter> PathRewriter;
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile);
@ -133,6 +131,12 @@ class SyntaxOnlyAction : public ASTFrontendAction {
virtual bool hasCodeCompletionSupport() const { return true; }
};
class BoostConAction : public SyntaxOnlyAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile);
};
/**
* \brief Frontend action adaptor that merges ASTs together.
*

View File

@ -23,13 +23,15 @@ namespace frontend {
ASTPrint, ///< Parse ASTs and print them.
ASTPrintXML, ///< Parse ASTs and print them in XML.
ASTView, ///< Parse ASTs and view them in Graphviz.
BoostCon, ///< BoostCon mode.
DumpRawTokens, ///< Dump out raw tokens.
DumpTokens, ///< Dump out preprocessed tokens.
EmitAssembly, ///< Emit a .s file.
EmitBC, ///< Emit a .bc file.
EmitHTML, ///< Translate input source into HTML.
EmitLLVM, ///< Emit a .ll file.
EmitLLVMOnly, ///< Generate LLVM IR, but do not
EmitLLVMOnly, ///< Generate LLVM IR, but do not emit anything.
EmitCodeGenOnly, ///< Generate machine code, but don't emit anything.
EmitObj, ///< Emit a .o file.
FixIt, ///< Parse and apply any fixits to the source.
GeneratePCH, ///< Generate pre-compiled header.
@ -77,6 +79,8 @@ class FrontendOptions {
unsigned ShowHelp : 1; ///< Show the -help text.
unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion
/// results.
unsigned ShowCodePatternsInCodeCompletion : 1; ///< Show code patterns in code
/// completion results.
unsigned ShowStats : 1; ///< Show frontend performance
/// metrics and statistics.
unsigned ShowTimers : 1; ///< Show timers for individual
@ -123,6 +127,7 @@ class FrontendOptions {
RelocatablePCH = 0;
ShowHelp = 0;
ShowMacrosInCodeCompletion = 0;
ShowCodePatternsInCodeCompletion = 0;
ShowStats = 0;
ShowTimers = 0;
ShowVersion = 0;

View File

@ -415,7 +415,9 @@ namespace clang {
/// \brief An UnresolvedUsingType record.
TYPE_UNRESOLVED_USING = 26,
/// \brief An InjectedClassNameType record.
TYPE_INJECTED_CLASS_NAME = 27
TYPE_INJECTED_CLASS_NAME = 27,
/// \brief An ObjCObjectType record.
TYPE_OBJC_OBJECT = 28
};
/// \brief The type IDs for special types constructed by semantic
@ -534,8 +536,46 @@ namespace clang {
/// IDs. This data is used when performing qualified name lookup
/// into a DeclContext via DeclContext::lookup.
DECL_CONTEXT_VISIBLE,
/// \brief A NamespaceDecl record.
DECL_NAMESPACE
/// \brief A NamespaceDecl rcord.
DECL_NAMESPACE,
/// \brief A NamespaceAliasDecl record.
DECL_NAMESPACE_ALIAS,
/// \brief A UsingDecl record.
DECL_USING,
/// \brief A UsingShadowDecl record.
DECL_USING_SHADOW,
/// \brief A UsingDirecitveDecl record.
DECL_USING_DIRECTIVE,
/// \brief An UnresolvedUsingValueDecl record.
DECL_UNRESOLVED_USING_VALUE,
/// \brief An UnresolvedUsingTypenameDecl record.
DECL_UNRESOLVED_USING_TYPENAME,
/// \brief A LinkageSpecDecl record.
DECL_LINKAGE_SPEC,
/// \brief A CXXRecordDecl record.
DECL_CXX_RECORD,
/// \brief A CXXMethodDecl record.
DECL_CXX_METHOD,
/// \brief A CXXConstructorDecl record.
DECL_CXX_CONSTRUCTOR,
/// \brief A CXXDestructorDecl record.
DECL_CXX_DESTRUCTOR,
/// \brief A CXXConversionDecl record.
DECL_CXX_CONVERSION,
// FIXME: Implement serialization for these decl types. This just
// allocates the order in which
DECL_FRIEND,
DECL_FRIEND_TEMPLATE,
DECL_TEMPLATE,
DECL_CLASS_TEMPLATE,
DECL_CLASS_TEMPLATE_SPECIALIZATION,
DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
DECL_FUNCTION_TEMPLATE,
DECL_TEMPLATE_TYPE_PARM,
DECL_NON_TYPE_TEMPLATE_PARM,
DECL_TEMPLATE_TEMPLATE_PARM,
DECL_STATIC_ASSERT
};
/// \brief Record codes for each kind of statement or expression.
@ -692,6 +732,8 @@ namespace clang {
/// \brief A CXXOperatorCallExpr record.
EXPR_CXX_OPERATOR_CALL,
/// \brief A CXXMemberCallExpr record.
EXPR_CXX_MEMBER_CALL,
/// \brief A CXXConstructExpr record.
EXPR_CXX_CONSTRUCT,
// \brief A CXXStaticCastExpr record.
@ -706,8 +748,18 @@ namespace clang {
EXPR_CXX_FUNCTIONAL_CAST,
// \brief A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
// \brief A CXXNullPtrLiteralExpr record.
EXPR_CXX_NULL_PTR_LITERAL
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
EXPR_CXX_THIS, // CXXThisExpr
EXPR_CXX_THROW, // CXXThrowExpr
EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr
EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr
//
EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr
EXPR_CXX_NEW, // CXXNewExpr
EXPR_CXX_EXPR_WITH_TEMPORARIES // CXXExprWithTemporaries
};
/// \brief The kinds of designators that can occur in a

View File

@ -52,6 +52,9 @@ class ASTContext;
class Attr;
class Decl;
class DeclContext;
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXBaseOrMemberInitializer;
class GotoStmt;
class LabelStmt;
class MacroDefinition;
@ -649,8 +652,8 @@ class PCHReader
/// declarations with this name are visible from translation unit scope, their
/// declarations will be deserialized and introduced into the declaration
/// chain of the identifier.
virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd);
IdentifierInfo* get(llvm::StringRef Name) {
virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
IdentifierInfo *get(llvm::StringRef Name) {
return get(Name.begin(), Name.end());
}
@ -694,8 +697,21 @@ class PCHReader
Selector GetSelector(const RecordData &Record, unsigned &Idx) {
return DecodeSelector(Record[Idx++]);
}
/// \brief Read a declaration name.
DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx);
NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
unsigned &Idx);
/// \brief Read a source location.
SourceLocation ReadSourceLocation(const RecordData &Record, unsigned& Idx) {
return SourceLocation::getFromRawEncoding(Record[Idx++]);
}
/// \brief Read a source range.
SourceRange ReadSourceRange(const RecordData &Record, unsigned& Idx);
/// \brief Read an integral value
llvm::APInt ReadAPInt(const RecordData &Record, unsigned &Idx);
@ -708,6 +724,8 @@ class PCHReader
// \brief Read a string
std::string ReadString(const RecordData &Record, unsigned &Idx);
CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
/// \brief Reads attributes from the current stream position.
Attr *ReadAttributes();

View File

@ -32,6 +32,9 @@ namespace llvm {
namespace clang {
class ASTContext;
class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXBaseOrMemberInitializer;
class LabelStmt;
class MacroDefinition;
class MemorizeStatCalls;
@ -251,6 +254,9 @@ class PCHWriter {
/// \brief Emit a source location.
void AddSourceLocation(SourceLocation Loc, RecordData &Record);
/// \brief Emit a source range.
void AddSourceRange(SourceRange Range, RecordData &Record);
/// \brief Emit an integral value.
void AddAPInt(const llvm::APInt &Value, RecordData &Record);
@ -260,12 +266,15 @@ class PCHWriter {
/// \brief Emit a floating-point value.
void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
/// \brief Emit a reference to an identifier
/// \brief Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
/// \brief Emit a Selector (which is a smart pointer reference)
void AddSelectorRef(const Selector, RecordData &Record);
/// \brief Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector, RecordData &Record);
/// \brief Emit a CXXTemporary.
void AddCXXTemporary(const CXXTemporary *Temp, RecordData &Record);
/// \brief Get the unique number used to refer to the given
/// identifier.
pch::IdentID getIdentifierRef(const IdentifierInfo *II);
@ -304,6 +313,9 @@ class PCHWriter {
/// \brief Emit a declaration name.
void AddDeclarationName(DeclarationName Name, RecordData &Record);
/// \brief Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordData &Record);
/// \brief Add a string to the given record.
void AddString(const std::string &Str, RecordData &Record);

View File

@ -61,6 +61,10 @@
# define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
#endif
NODE_XML(Type, "FIXME_Type")
ID_ATTRIBUTE_XML
ATTRIBUTE_XML(getTypeClassName(), "unhandled_type_name")
END_NODE_XML
NODE_XML(QualType, "CvQualifiedType")
ID_ATTRIBUTE_XML
@ -207,9 +211,9 @@ NODE_XML(RecordType, "Record")
ID_ATTRIBUTE_XML
ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // string
ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
ENUM_XML(TagDecl::TK_struct, "struct")
ENUM_XML(TagDecl::TK_union, "union")
ENUM_XML(TagDecl::TK_class, "class")
ENUM_XML(TTK_Struct, "struct")
ENUM_XML(TTK_Union, "union")
ENUM_XML(TTK_Class, "class")
END_ENUM_XML
CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
END_NODE_XML
@ -228,11 +232,23 @@ NODE_XML(TemplateSpecializationType, "TemplateSpecializationType")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(QualifiedNameType, "QualifiedNameType")
NODE_XML(ElaboratedType, "ElaboratedType")
ID_ATTRIBUTE_XML
ATTRIBUTE_ENUM_XML(getKeyword(), "keyword")
ENUM_XML(ETK_None, "none")
ENUM_XML(ETK_Typename, "typename")
ENUM_XML(ETK_Struct, "struct")
ENUM_XML(ETK_Union, "union")
ENUM_XML(ETK_Class, "class")
ENUM_XML(ETK_Enum, "enum")
END_ENUM_XML
TYPE_ATTRIBUTE_XML(getNamedType())
END_NODE_XML
NODE_XML(InjectedClassNameType, "InjectedClassNameType")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(DependentNameType, "DependentNameType")
ID_ATTRIBUTE_XML
END_NODE_XML
@ -245,6 +261,29 @@ NODE_XML(ObjCObjectPointerType, "ObjCObjectPointerType")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(SubstTemplateTypeParmType, "SubstTemplateTypeParm")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(DependentSizedExtVectorType, "DependentSizedExtVector")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(UnresolvedUsingType, "UnresolvedUsing")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(DependentTypeOfExprType, "DependentTypeOfExpr")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(DecltypeType, "Decltype")
ID_ATTRIBUTE_XML
END_NODE_XML
NODE_XML(DependentDecltypeType, "DependentDecltype")
ID_ATTRIBUTE_XML
END_NODE_XML
//===----------------------------------------------------------------------===//
#undef NODE_XML

View File

@ -147,7 +147,7 @@ class StringLiteralParser {
char *ResultPtr; // cursor
public:
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
Preprocessor &PP);
Preprocessor &PP, bool Complain = true);
bool hadError;
bool AnyWide;
bool Pascal;
@ -164,7 +164,7 @@ class StringLiteralParser {
/// specified byte of the string data represented by Token. This handles
/// advancing over escape sequences in the string.
static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo,
Preprocessor &PP);
Preprocessor &PP, bool Complain = true);
};
} // end namespace clang

View File

@ -290,8 +290,8 @@ class Preprocessor {
/// expansions going on at the time.
PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
/// getCurrentFileLexer - Return the current file lexer being lexed from. Note
/// that this ignores any potentially active macro expansions and _Pragma
/// getCurrentFileLexer - Return the current file lexer being lexed from.
/// Note that this ignores any potentially active macro expansions and _Pragma
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
@ -753,9 +753,9 @@ class Preprocessor {
/// #include FOO
/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
///
/// This code concatenates and consumes tokens up to the '>' token. It returns
/// false if the > was found, otherwise it returns true if it finds and consumes
/// the EOM marker.
/// This code concatenates and consumes tokens up to the '>' token. It
/// returns false if the > was found, otherwise it returns true if it finds
/// and consumes the EOM marker.
bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer);
private:
@ -900,8 +900,6 @@ class Preprocessor {
// Macro handling.
void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
// HandleAssertDirective(Token &Tok);
// HandleUnassertDirective(Token &Tok);
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,

View File

@ -1,5 +1,5 @@
LEVEL = ../../../..
DIRS := Basic Driver
DIRS := AST Basic Driver
include $(LEVEL)/Makefile.common
@ -10,7 +10,7 @@ install-local::
cd $(PROJ_SRC_ROOT)/tools/clang/include && \
for hdr in `find clang -type f '!' '(' -name '*~' \
-o -name '.#*' -o -name '*.in' -o -name '*.txt' \
-o -name 'Makefile' -o -name '*.td' ')' -print \
-o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -print \
| grep -v CVS | grep -v .svn | grep -v .dir` ; do \
instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
if test \! -d "$$instdir" ; then \

View File

@ -105,12 +105,19 @@ class Action : public ActionBase {
class FullExprArg {
public:
FullExprArg(ActionBase &actions) : Expr(actions) { }
// FIXME: The const_cast here is ugly. RValue references would make this
// much nicer (or we could duplicate a bunch of the move semantics
// emulation code from Ownership.h).
FullExprArg(const FullExprArg& Other)
: Expr(move(const_cast<FullExprArg&>(Other).Expr)) {}
FullExprArg &operator=(const FullExprArg& Other) {
Expr.operator=(move(const_cast<FullExprArg&>(Other).Expr));
return *this;
}
OwningExprResult release() {
return move(Expr);
}
@ -279,13 +286,18 @@ class Action : public ActionBase {
/// \param Template if the name does refer to a template, the declaration
/// of the template that the name refers to.
///
/// \param MemberOfUnknownSpecialization Will be set true if the resulting
/// member would be a member of an unknown specialization, in which case this
/// lookup cannot possibly pass at this time.
///
/// \returns the kind of template that this name refers to.
virtual TemplateNameKind isTemplateName(Scope *S,
CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
bool EnteringContext,
TemplateTy &Template) = 0;
TemplateTy &Template,
bool &MemberOfUnknownSpecialization) = 0;
/// \brief Action called as part of error recovery when the parser has
/// determined that the given name must refer to a template, but
@ -566,7 +578,9 @@ class Action : public ActionBase {
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
/// no declarator (e.g. "struct foo;") is parsed.
virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S,
AccessSpecifier Access,
DeclSpec &DS) {
return DeclPtrTy();
}
@ -826,21 +840,19 @@ class Action : public ActionBase {
/// \brief Parsed the start of a "switch" statement.
///
/// \param SwitchLoc The location of the "switch" keyword.
///
/// \param Cond if the "switch" condition was parsed as an expression,
/// the expression itself.
///
/// \param CondVar if the "switch" condition was parsed as a condition
/// variable, the condition variable itself.
virtual OwningStmtResult ActOnStartOfSwitchStmt(FullExprArg Cond,
virtual OwningStmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
ExprArg Cond,
DeclPtrTy CondVar) {
return StmtEmpty();
}
/// ActOnSwitchBodyError - This is called if there is an error parsing the
/// body of the switch stmt instead of ActOnFinishSwitchStmt.
virtual void ActOnSwitchBodyError(SourceLocation SwitchLoc, StmtArg Switch,
StmtArg Body) {}
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
StmtArg Switch, StmtArg Body) {
return StmtEmpty();
@ -1609,6 +1621,22 @@ class Action : public ActionBase {
return DeclResult();
}
/// \brief Parsed an expression that will be handled as the condition in
/// an if/while/for statement.
///
/// This routine handles the conversion of the expression to 'bool'.
///
/// \param S The scope in which the expression occurs.
///
/// \param Loc The location of the construct that requires the conversion to
/// a boolean value.
///
/// \param SubExpr The expression that is being converted to bool.
virtual OwningExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
ExprArg SubExpr) {
return move(SubExpr);
}
/// ActOnCXXNew - Parsed a C++ 'new' expression. UseGlobal is true if the
/// new was qualified (::new). In a full new like
/// @code new (p1, p2) type(c1, c2) @endcode
@ -2303,6 +2331,7 @@ class Action : public ActionBase {
}
// ActOnPropertyImplDecl - called for every property implementation
virtual DeclPtrTy ActOnPropertyImplDecl(
Scope *S,
SourceLocation AtLoc, // location of the @synthesize/@dynamic
SourceLocation PropertyNameLoc, // location for the property name
bool ImplKind, // true for @synthesize, false for
@ -2346,7 +2375,7 @@ class Action : public ActionBase {
// protocols, categories), the parser passes all methods/properties.
// For class implementations, these values default to 0. For implementations,
// methods are processed incrementally (by ActOnMethodDeclaration above).
virtual void ActOnAtEnd(SourceRange AtEnd,
virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
DeclPtrTy classDecl,
DeclPtrTy *allMethods = 0,
unsigned allNum = 0,
@ -2535,6 +2564,21 @@ class Action : public ActionBase {
//===---------------------------- Pragmas -------------------------------===//
enum PragmaOptionsAlignKind {
POAK_Natural, // #pragma options align=natural
POAK_Power, // #pragma options align=power
POAK_Mac68k, // #pragma options align=mac68k
POAK_Reset // #pragma options align=reset
};
/// ActOnPragmaOptionsAlign - Called on well formed #pragma options
/// align={...}.
virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
SourceLocation PragmaLoc,
SourceLocation KindLoc) {
return;
}
enum PragmaPackKind {
PPK_Default, // #pragma pack([n])
PPK_Show, // #pragma pack(show), only supported by MSVC.
@ -2620,9 +2664,13 @@ class Action : public ActionBase {
/// \brief Code completion occurs at the beginning of the
/// initialization statement (or expression) in a for loop.
CCC_ForInit,
/// \brief Code completion ocurs within the condition of an if,
/// \brief Code completion occurs within the condition of an if,
/// while, switch, or for statement.
CCC_Condition
CCC_Condition,
/// \brief Code completion occurs within the body of a function on a
/// recovery path, where we do not have a specific handle on our position
/// in the grammar.
CCC_RecoveryInFunction
};
/// \brief Code completion for an ordinary name that occurs within the given
@ -3003,7 +3051,9 @@ class MinimalAction : public Action {
UnqualifiedId &Name,
TypeTy *ObjectType,
bool EnteringContext,
TemplateTy &Template);
TemplateTy &Template,
bool &MemberOfUnknownSpecialization);
/// ActOnDeclarator - If this is a typedef declarator, we modify the
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is

View File

@ -55,6 +55,7 @@ class AttributeList {
enum Kind { // Please keep this list alphabetized.
AT_IBAction, // Clang-specific.
AT_IBOutlet, // Clang-specific.
AT_IBOutletCollection, // Clang-specific.
AT_address_space,
AT_alias,
AT_aligned,
@ -102,6 +103,7 @@ class AttributeList {
AT_section,
AT_sentinel,
AT_stdcall,
AT_thiscall,
AT_transparent_union,
AT_unavailable,
AT_unused,

View File

@ -166,7 +166,7 @@ namespace llvm {
// conversions.
// Flip this switch to measure performance impact of the smart pointers.
//#define DISABLE_SMART_POINTERS
// #define DISABLE_SMART_POINTERS
namespace llvm {
template<>
@ -403,8 +403,10 @@ namespace clang {
friend class moving::ASTResultMover<Destroyer>;
#if !(defined(_MSC_VER) && _MSC_VER >= 1600)
ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT
ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT
#endif
void destroy() {
if (Ptr) {
@ -444,6 +446,19 @@ namespace clang {
return *this;
}
#if defined(_MSC_VER) && _MSC_VER >= 1600
// Emulated move semantics don't work with msvc.
ASTOwningResult(ASTOwningResult &&mover)
: ActionInv(mover.ActionInv),
Ptr(mover.Ptr) {
mover.Ptr = 0;
}
ASTOwningResult &operator=(ASTOwningResult &&mover) {
*this = moving::ASTResultMover<Destroyer>(mover);
return *this;
}
#endif
/// Assignment from a raw pointer. Takes ownership - beware!
ASTOwningResult &operator=(void *raw) {
destroy();

View File

@ -110,6 +110,7 @@ class Parser {
IdentifierInfo *Ident_vector;
IdentifierInfo *Ident_pixel;
llvm::OwningPtr<PragmaHandler> OptionsHandler;
llvm::OwningPtr<PragmaHandler> PackHandler;
llvm::OwningPtr<PragmaHandler> UnusedHandler;
llvm::OwningPtr<PragmaHandler> WeakHandler;
@ -234,6 +235,11 @@ class Parser {
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
if (Tok.is(tok::code_completion)) {
CodeCompletionRecovery();
return ConsumeCodeCompletionToken();
}
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
return PrevTokLocation;
@ -308,6 +314,22 @@ class Parser {
return PrevTokLocation;
}
/// \brief Consume the current code-completion token.
///
/// This routine should be called to consume the code-completion token once
/// a code-completion action has already been invoked.
SourceLocation ConsumeCodeCompletionToken() {
assert(Tok.is(tok::code_completion));
PrevTokLocation = Tok.getLocation();
PP.Lex(Tok);
return PrevTokLocation;
}
///\ brief When we are consuming a code-completion token within having
/// matched specific position in the grammar, provide code-completion results
/// based on context.
void CodeCompletionRecovery();
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
/// returns the token after Tok, etc.
@ -1004,7 +1026,8 @@ class Parser {
//===--------------------------------------------------------------------===//
// C++ if/switch/while condition expression.
bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult);
bool ParseCXXCondition(OwningExprResult &ExprResult, DeclPtrTy &DeclResult,
SourceLocation Loc, bool ConvertToBoolean);
//===--------------------------------------------------------------------===//
// C++ types
@ -1060,7 +1083,9 @@ class Parser {
bool isStmtExpr = false);
OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(OwningExprResult &ExprResult,
DeclPtrTy &DeclResult);
DeclPtrTy &DeclResult,
SourceLocation Loc,
bool ConvertToBoolean);
OwningStmtResult ParseIfStatement(AttributeList *Attr);
OwningStmtResult ParseSwitchStatement(AttributeList *Attr);
OwningStmtResult ParseWhileStatement(AttributeList *Attr);
@ -1348,6 +1373,8 @@ class Parser {
AttributeList *AttrList = 0,
bool RequiresArg = false);
void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
IdentifierInfo *FirstIdent,
SourceLocation FirstIdentLoc,
Declarator &D);
void ParseBracketDeclarator(Declarator &D);
@ -1403,7 +1430,8 @@ class Parser {
bool EnteringContext,
TypeTy *ObjectType,
UnqualifiedId &Id,
bool AssumeTemplateId = false);
bool AssumeTemplateId,
SourceLocation TemplateKWLoc);
bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
TypeTy *ObjectType,
UnqualifiedId &Result);
@ -1457,6 +1485,7 @@ class Parser {
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
bool IsTemplateArgumentList(unsigned Skip = 0);
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();

View File

@ -74,7 +74,7 @@ class Scope {
/// It always has FnScope and DeclScope set as well.
ObjCMethodScope = 0x400,
/// ElseScope - This scoep corresponds to an 'else' scope of an if/then/else
/// ElseScope - This scope corresponds to an 'else' scope of an if/then/else
/// statement.
ElseScope = 0x800
};

View File

@ -24,6 +24,41 @@ class raw_ostream;
namespace clang {
/// \brief Default priority values for code-completion results based
/// on their kind.
enum {
/// \brief Priority for a declaration that is in the local scope.
CCP_LocalDeclaration = 8,
/// \brief Priority for a member declaration found from the current
/// method or member function.
CCP_MemberDeclaration = 20,
/// \brief Priority for a language keyword (that isn't any of the other
/// categories).
CCP_Keyword = 30,
/// \brief Priority for a code pattern.
CCP_CodePattern = 30,
/// \brief Priority for a type.
CCP_Type = 40,
/// \brief Priority for a non-type declaration.
CCP_Declaration = 50,
/// \brief Priority for a constant value (e.g., enumerator).
CCP_Constant = 60,
/// \brief Priority for a preprocessor macro.
CCP_Macro = 70,
/// \brief Priority for a nested-name-specifier.
CCP_NestedNameSpecifier = 75,
/// \brief Priority for a result that isn't likely to be what the user wants,
/// but is included for completeness.
CCP_Unlikely = 80
};
/// \brief Priority value deltas that are applied to code-completion results
/// based on the context of the result.
enum {
/// \brief The result is in a base class.
CCD_InBaseClass = 2
};
class FunctionDecl;
class FunctionType;
class FunctionTemplateDecl;
@ -156,13 +191,14 @@ class CodeCompletionString {
public:
CodeCompletionString() { }
~CodeCompletionString();
~CodeCompletionString() { clear(); }
typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator;
iterator begin() const { return Chunks.begin(); }
iterator end() const { return Chunks.end(); }
bool empty() const { return Chunks.empty(); }
unsigned size() const { return Chunks.size(); }
void clear();
Chunk &operator[](unsigned I) {
assert(I < size() && "Chunk index out-of-range");
@ -232,8 +268,9 @@ class CodeCompletionString {
void Serialize(llvm::raw_ostream &OS) const;
/// \brief Deserialize a code-completion string from the given string.
static CodeCompletionString *Deserialize(const char *&Str,
const char *StrEnd);
///
/// \returns true if successful, false otherwise.
bool Deserialize(const char *&Str, const char *StrEnd);
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@ -246,6 +283,10 @@ class CodeCompleteConsumer {
/// \brief Whether to include macros in the code-completion results.
bool IncludeMacros;
/// \brief Whether to include code patterns (such as for loops) within
/// the completion results.
bool IncludeCodePatterns;
/// \brief Whether the output format for the code-completion consumer is
/// binary.
bool OutputIsBinary;
@ -280,8 +321,11 @@ class CodeCompleteConsumer {
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
IdentifierInfo *Macro;
};
/// \brief Specifiers which parameter (of a function, Objective-C method,
/// \brief The priority of this particular code-completion result.
unsigned Priority;
/// \brief Specifies which parameter (of a function, Objective-C method,
/// macro, etc.) we should start with when formatting the result.
unsigned StartParameter;
@ -309,29 +353,30 @@ class CodeCompleteConsumer {
NestedNameSpecifier *Qualifier = 0,
bool QualifierIsInformative = false)
: Kind(RK_Declaration), Declaration(Declaration),
StartParameter(0), Hidden(false),
QualifierIsInformative(QualifierIsInformative),
Priority(getPriorityFromDecl(Declaration)), StartParameter(0),
Hidden(false), QualifierIsInformative(QualifierIsInformative),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(Qualifier) { }
Qualifier(Qualifier) {
}
/// \brief Build a result that refers to a keyword or symbol.
Result(const char *Keyword)
: Kind(RK_Keyword), Keyword(Keyword), StartParameter(0),
Hidden(false), QualifierIsInformative(0),
Result(const char *Keyword, unsigned Priority = CCP_Keyword)
: Kind(RK_Keyword), Keyword(Keyword), Priority(Priority),
StartParameter(0), Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(0) { }
/// \brief Build a result that refers to a macro.
Result(IdentifierInfo *Macro)
: Kind(RK_Macro), Macro(Macro), StartParameter(0),
Result(IdentifierInfo *Macro, unsigned Priority = CCP_Macro)
: Kind(RK_Macro), Macro(Macro), Priority(Priority), StartParameter(0),
Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(0) { }
/// \brief Build a result that refers to a pattern.
Result(CodeCompletionString *Pattern)
: Kind(RK_Pattern), Pattern(Pattern), StartParameter(0),
Hidden(false), QualifierIsInformative(0),
Result(CodeCompletionString *Pattern, unsigned Priority = CCP_CodePattern)
: Kind(RK_Pattern), Pattern(Pattern), Priority(Priority),
StartParameter(0), Hidden(false), QualifierIsInformative(0),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(0) { }
@ -352,6 +397,9 @@ class CodeCompleteConsumer {
CodeCompletionString *CreateCodeCompletionString(Sema &S);
void Destroy();
/// brief Determine a base priority for the given declaration.
static unsigned getPriorityFromDecl(NamedDecl *ND);
};
class OverloadCandidate {
@ -420,12 +468,17 @@ class CodeCompleteConsumer {
CodeCompleteConsumer() : IncludeMacros(false), OutputIsBinary(false) { }
CodeCompleteConsumer(bool IncludeMacros, bool OutputIsBinary)
: IncludeMacros(IncludeMacros), OutputIsBinary(OutputIsBinary) { }
CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
bool OutputIsBinary)
: IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns),
OutputIsBinary(OutputIsBinary) { }
/// \brief Whether the code-completion consumer wants to see macros.
bool includeMacros() const { return IncludeMacros; }
/// \brief Whether the code-completion consumer wants to see code patterns.
bool includeCodePatterns() const { return IncludeCodePatterns; }
/// \brief Determine whether the output of this consumer is binary.
bool isOutputBinary() const { return OutputIsBinary; }
@ -461,9 +514,9 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer {
public:
/// \brief Create a new printing code-completion consumer that prints its
/// results to the given raw output stream.
PrintingCodeCompleteConsumer(bool IncludeMacros,
PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
llvm::raw_ostream &OS)
: CodeCompleteConsumer(IncludeMacros, false), OS(OS) { }
: CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, false), OS(OS) {}
/// \brief Prints the finalized code-completion results.
virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
@ -484,8 +537,9 @@ class CIndexCodeCompleteConsumer : public CodeCompleteConsumer {
/// \brief Create a new CIndex code-completion consumer that prints its
/// results to the given raw output stream in a format readable to the CIndex
/// library.
CIndexCodeCompleteConsumer(bool IncludeMacros, llvm::raw_ostream &OS)
: CodeCompleteConsumer(IncludeMacros, true), OS(OS) { }
CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns,
llvm::raw_ostream &OS)
: CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, true), OS(OS) {}
/// \brief Prints the finalized code-completion results.
virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,

View File

@ -18,6 +18,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/Builtins.h"
@ -27,7 +28,6 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "RecordLayoutBuilder.h"
using namespace clang;
@ -46,7 +46,9 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0),
SourceMgr(SM), LangOpts(LOpts), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts),
BuiltinInfo(builtins),
DeclarationNames(*this),
ExternalSource(0), PrintingPolicy(LOpts),
LastSDM(0, 0) {
ObjCIdRedefinitionType = QualType();
ObjCClassRedefinitionType = QualType();
@ -61,6 +63,12 @@ ASTContext::~ASTContext() {
// FIXME: Is this the ideal solution?
ReleaseDeclContextMaps();
if (!FreeMemory) {
// Call all of the deallocation functions.
for (unsigned I = 0, N = Deallocations.size(); I != N; ++I)
Deallocations[I].first(Deallocations[I].second);
}
// Release all of the memory associated with overridden C++ methods.
for (llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::iterator
OM = OverriddenMethods.begin(), OMEnd = OverriddenMethods.end();
@ -111,6 +119,10 @@ ASTContext::~ASTContext() {
TUDecl->Destroy(*this);
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
Deallocations.push_back(std::make_pair(Callback, Data));
}
void
ASTContext::setExternalSource(llvm::OwningPtr<ExternalASTSource> &Source) {
ExternalSource.reset(Source.take());
@ -419,6 +431,18 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
return CharUnits::fromQuantity(Align / Target.getCharWidth());
}
std::pair<CharUnits, CharUnits>
ASTContext::getTypeInfoInChars(const Type *T) {
std::pair<uint64_t, unsigned> Info = getTypeInfo(T);
return std::make_pair(CharUnits::fromQuantity(Info.first / getCharWidth()),
CharUnits::fromQuantity(Info.second / getCharWidth()));
}
std::pair<CharUnits, CharUnits>
ASTContext::getTypeInfoInChars(QualType T) {
return getTypeInfoInChars(T.getTypePtr());
}
/// getTypeSize - Return the size of the specified type, in bits. This method
/// does not work on incomplete types.
///
@ -593,6 +617,8 @@ ASTContext::getTypeInfo(const Type *T) {
Align = EltInfo.second;
break;
}
case Type::ObjCObject:
return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
case Type::ObjCInterface: {
const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@ -624,10 +650,6 @@ ASTContext::getTypeInfo(const Type *T) {
return getTypeInfo(cast<SubstTemplateTypeParmType>(T)->
getReplacementType().getTypePtr());
case Type::Elaborated:
return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType()
.getTypePtr());
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
@ -650,8 +672,8 @@ ASTContext::getTypeInfo(const Type *T) {
return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType()
.getTypePtr());
case Type::QualifiedName:
return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
case Type::Elaborated:
return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
case Type::TemplateSpecialization:
assert(getCanonicalType(T) != T &&
@ -875,40 +897,6 @@ TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
return DI;
}
/// getInterfaceLayoutImpl - Get or compute information about the
/// layout of the given interface.
///
/// \param Impl - If given, also include the layout of the interface's
/// implementation. This may differ by including synthesized ivars.
const ASTRecordLayout &
ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) {
assert(!D->isForwardDecl() && "Invalid interface decl!");
// Look up this layout, if already laid out, return what we have.
ObjCContainerDecl *Key =
Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D;
if (const ASTRecordLayout *Entry = ObjCLayouts[Key])
return *Entry;
// Add in synthesized ivar count if laying out an implementation.
if (Impl) {
unsigned SynthCount = CountNonClassIvars(D);
// If there aren't any sythesized ivars then reuse the interface
// entry. Note we can't cache this because we simply free all
// entries later; however we shouldn't look up implementations
// frequently.
if (SynthCount == 0)
return getObjCLayout(D, 0);
}
const ASTRecordLayout *NewEntry =
ASTRecordLayoutBuilder::ComputeLayout(*this, D, Impl);
ObjCLayouts[Key] = NewEntry;
return *NewEntry;
}
const ASTRecordLayout &
ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
return getObjCLayout(D, 0);
@ -919,45 +907,6 @@ ASTContext::getASTObjCImplementationLayout(const ObjCImplementationDecl *D) {
return getObjCLayout(D->getClassInterface(), D);
}
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
/// position information.
const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
D = D->getDefinition();
assert(D && "Cannot get layout of forward declarations!");
// Look up this layout, if already laid out, return what we have.
// Note that we can't save a reference to the entry because this function
// is recursive.
const ASTRecordLayout *Entry = ASTRecordLayouts[D];
if (Entry) return *Entry;
const ASTRecordLayout *NewEntry =
ASTRecordLayoutBuilder::ComputeLayout(*this, D);
ASTRecordLayouts[D] = NewEntry;
if (getLangOptions().DumpRecordLayouts) {
llvm::errs() << "\n*** Dumping AST Record Layout\n";
DumpRecordLayout(D, llvm::errs());
}
return *NewEntry;
}
const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
RD = cast<CXXRecordDecl>(RD->getDefinition());
assert(RD && "Cannot get key function for forward declarations!");
const CXXMethodDecl *&Entry = KeyFunctions[RD];
if (!Entry)
Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
else
assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
"Key function changed!");
return Entry;
}
//===----------------------------------------------------------------------===//
// Type creation/memoization methods
//===----------------------------------------------------------------------===//
@ -1343,9 +1292,17 @@ QualType ASTContext::getVariableArrayType(QualType EltTy,
SourceRange Brackets) {
// Since we don't unique expressions, it isn't possible to unique VLA's
// that have an expression provided for their size.
QualType CanonType;
if (!EltTy.isCanonical()) {
if (NumElts)
NumElts->Retain();
CanonType = getVariableArrayType(getCanonicalType(EltTy), NumElts, ASM,
EltTypeQuals, Brackets);
}
VariableArrayType *New = new(*this, TypeAlignment)
VariableArrayType(EltTy, QualType(), NumElts, ASM, EltTypeQuals, Brackets);
VariableArrayType(EltTy, CanonType, NumElts, ASM, EltTypeQuals, Brackets);
VariableArrayTypes.push_back(New);
Types.push_back(New);
@ -1694,10 +1651,6 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) {
if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
return getTypedefType(Typedef);
if (const ObjCInterfaceDecl *ObjCInterface
= dyn_cast<ObjCInterfaceDecl>(Decl))
return getObjCInterfaceType(ObjCInterface);
assert(!isa<TemplateTypeParmDecl>(Decl) &&
"Template type parameter types are always available.");
@ -1888,29 +1841,28 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
}
QualType
ASTContext::getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType) {
ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
QualType NamedType) {
llvm::FoldingSetNodeID ID;
QualifiedNameType::Profile(ID, NNS, NamedType);
ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
void *InsertPos = 0;
QualifiedNameType *T
= QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
QualType Canon = NamedType;
if (!Canon.isCanonical()) {
Canon = getCanonicalType(NamedType);
QualifiedNameType *CheckT
= QualifiedNameTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!CheckT && "Qualified name canonical type broken");
ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!CheckT && "Elaborated canonical type broken");
(void)CheckT;
}
T = new (*this) QualifiedNameType(NNS, NamedType, Canon);
T = new (*this) ElaboratedType(Keyword, NNS, NamedType, Canon);
Types.push_back(T);
QualifiedNameTypes.InsertNode(T, InsertPos);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
}
@ -1987,30 +1939,6 @@ ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
return QualType(T, 0);
}
QualType
ASTContext::getElaboratedType(QualType UnderlyingType,
ElaboratedType::TagKind Tag) {
llvm::FoldingSetNodeID ID;
ElaboratedType::Profile(ID, UnderlyingType, Tag);
void *InsertPos = 0;
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
QualType Canon = UnderlyingType;
if (!Canon.isCanonical()) {
Canon = getCanonicalType(Canon);
ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!CheckT && "Elaborated canonical type is broken"); (void)CheckT;
}
T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon);
Types.push_back(T);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
}
/// CmpProtocolNames - Comparison predicate for sorting protocols
/// alphabetically.
static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
@ -2018,7 +1946,7 @@ static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
return LHS->getDeclName() < RHS->getDeclName();
}
static bool areSortedAndUniqued(ObjCProtocolDecl **Protocols,
static bool areSortedAndUniqued(ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) {
if (NumProtocols == 0) return true;
@ -2040,94 +1968,96 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **Protocols,
NumProtocols = ProtocolsEnd-Protocols;
}
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
/// the given interface decl and the conforming protocol list.
QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
ObjCProtocolDecl **Protocols,
unsigned NumProtocols,
unsigned Quals) {
QualType ASTContext::getObjCObjectType(QualType BaseType,
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) {
// If the base type is an interface and there aren't any protocols
// to add, then the interface type will do just fine.
if (!NumProtocols && isa<ObjCInterfaceType>(BaseType))
return BaseType;
// Look in the folding set for an existing type.
llvm::FoldingSetNodeID ID;
ObjCObjectPointerType::Profile(ID, InterfaceT, Protocols, NumProtocols);
Qualifiers Qs = Qualifiers::fromCVRMask(Quals);
ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
void *InsertPos = 0;
if (ObjCObjectPointerType *QT =
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return getQualifiedType(QualType(QT, 0), Qs);
if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
// Sort the protocol list alphabetically to canonicalize it.
// Build the canonical type, which has the canonical base type and
// a sorted-and-uniqued list of protocols.
QualType Canonical;
if (!InterfaceT.isCanonical() ||
!areSortedAndUniqued(Protocols, NumProtocols)) {
if (!areSortedAndUniqued(Protocols, NumProtocols)) {
bool ProtocolsSorted = areSortedAndUniqued(Protocols, NumProtocols);
if (!ProtocolsSorted || !BaseType.isCanonical()) {
if (!ProtocolsSorted) {
llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,
Protocols + NumProtocols);
unsigned UniqueCount = NumProtocols;
SortAndUniqueProtocols(&Sorted[0], UniqueCount);
Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
&Sorted[0], UniqueCount);
Canonical = getObjCObjectType(getCanonicalType(BaseType),
&Sorted[0], UniqueCount);
} else {
Canonical = getObjCObjectPointerType(getCanonicalType(InterfaceT),
Protocols, NumProtocols);
Canonical = getObjCObjectType(getCanonicalType(BaseType),
Protocols, NumProtocols);
}
// Regenerate InsertPos.
ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos);
}
unsigned Size = sizeof(ObjCObjectTypeImpl);
Size += NumProtocols * sizeof(ObjCProtocolDecl *);
void *Mem = Allocate(Size, TypeAlignment);
ObjCObjectTypeImpl *T =
new (Mem) ObjCObjectTypeImpl(Canonical, BaseType, Protocols, NumProtocols);
Types.push_back(T);
ObjCObjectTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
}
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
/// the given object type.
QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) {
llvm::FoldingSetNodeID ID;
ObjCObjectPointerType::Profile(ID, ObjectT);
void *InsertPos = 0;
if (ObjCObjectPointerType *QT =
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
// Find the canonical object type.
QualType Canonical;
if (!ObjectT.isCanonical()) {
Canonical = getObjCObjectPointerType(getCanonicalType(ObjectT));
// Regenerate InsertPos.
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
}
// No match.
unsigned Size = sizeof(ObjCObjectPointerType)
+ NumProtocols * sizeof(ObjCProtocolDecl *);
void *Mem = Allocate(Size, TypeAlignment);
ObjCObjectPointerType *QType = new (Mem) ObjCObjectPointerType(Canonical,
InterfaceT,
Protocols,
NumProtocols);
void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment);
ObjCObjectPointerType *QType =
new (Mem) ObjCObjectPointerType(Canonical, ObjectT);
Types.push_back(QType);
ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
return getQualifiedType(QualType(QType, 0), Qs);
return QualType(QType, 0);
}
/// getObjCInterfaceType - Return the unique reference to the type for the
/// specified ObjC interface decl. The list of protocols is optional.
QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
ObjCProtocolDecl **Protocols, unsigned NumProtocols) {
llvm::FoldingSetNodeID ID;
ObjCInterfaceType::Profile(ID, Decl, Protocols, NumProtocols);
QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) {
if (Decl->TypeForDecl)
return QualType(Decl->TypeForDecl, 0);
void *InsertPos = 0;
if (ObjCInterfaceType *QT =
ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
// Sort the protocol list alphabetically to canonicalize it.
QualType Canonical;
if (NumProtocols && !areSortedAndUniqued(Protocols, NumProtocols)) {
llvm::SmallVector<ObjCProtocolDecl*, 8> Sorted(Protocols,
Protocols + NumProtocols);
unsigned UniqueCount = NumProtocols;
SortAndUniqueProtocols(&Sorted[0], UniqueCount);
Canonical = getObjCInterfaceType(Decl, &Sorted[0], UniqueCount);
ObjCInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos);
}
unsigned Size = sizeof(ObjCInterfaceType)
+ NumProtocols * sizeof(ObjCProtocolDecl *);
void *Mem = Allocate(Size, TypeAlignment);
ObjCInterfaceType *QType = new (Mem) ObjCInterfaceType(Canonical,
const_cast<ObjCInterfaceDecl*>(Decl),
Protocols,
NumProtocols);
Types.push_back(QType);
ObjCInterfaceTypes.InsertNode(QType, InsertPos);
return QualType(QType, 0);
// FIXME: redeclarations?
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
Decl->TypeForDecl = T;
Types.push_back(T);
return QualType(T, 0);
}
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
@ -2362,26 +2292,35 @@ CanQualType ASTContext::getCanonicalType(QualType T) {
QualType ASTContext::getUnqualifiedArrayType(QualType T,
Qualifiers &Quals) {
Quals = T.getQualifiers();
if (!isa<ArrayType>(T)) {
const ArrayType *AT = getAsArrayType(T);
if (!AT) {
return T.getUnqualifiedType();
}
const ArrayType *AT = cast<ArrayType>(T);
QualType Elt = AT->getElementType();
QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals);
if (Elt == UnqualElt)
return T;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T)) {
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
return getConstantArrayType(UnqualElt, CAT->getSize(),
CAT->getSizeModifier(), 0);
}
if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(T)) {
if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
return getIncompleteArrayType(UnqualElt, IAT->getSizeModifier(), 0);
}
const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(T);
if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) {
return getVariableArrayType(UnqualElt,
VAT->getSizeExpr() ?
VAT->getSizeExpr()->Retain() : 0,
VAT->getSizeModifier(),
VAT->getIndexTypeCVRQualifiers(),
VAT->getBracketsRange());
}
const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(AT);
return getDependentSizedArrayType(UnqualElt, DSAT->getSizeExpr()->Retain(),
DSAT->getSizeModifier(), 0,
SourceRange());
@ -2716,6 +2655,9 @@ unsigned ASTContext::getIntegerRank(Type *T) {
/// \returns the type this bit-field will promote to, or NULL if no
/// promotion occurs.
QualType ASTContext::isPromotableBitField(Expr *E) {
if (E->isTypeDependent() || E->isValueDependent())
return QualType();
FieldDecl *Field = E->getBitField();
if (!Field)
return QualType();
@ -2811,7 +2753,7 @@ CreateRecordDecl(ASTContext &Ctx, RecordDecl::TagKind TK, DeclContext *DC,
QualType ASTContext::getCFConstantStringType() {
if (!CFConstantStringTypeDecl) {
CFConstantStringTypeDecl =
CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get("NSConstantString"));
CFConstantStringTypeDecl->startDefinition();
@ -2853,7 +2795,7 @@ void ASTContext::setCFConstantStringType(QualType T) {
QualType ASTContext::getNSConstantStringType() {
if (!NSConstantStringTypeDecl) {
NSConstantStringTypeDecl =
CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get("__builtin_NSString"));
NSConstantStringTypeDecl->startDefinition();
@ -2892,7 +2834,7 @@ void ASTContext::setNSConstantStringType(QualType T) {
QualType ASTContext::getObjCFastEnumerationStateType() {
if (!ObjCFastEnumerationStateTypeDecl) {
ObjCFastEnumerationStateTypeDecl =
CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get("__objcFastEnumerationState"));
ObjCFastEnumerationStateTypeDecl->startDefinition();
@ -2927,7 +2869,7 @@ QualType ASTContext::getBlockDescriptorType() {
RecordDecl *T;
// FIXME: Needs the FlagAppleBlock bit.
T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get("__block_descriptor"));
T->startDefinition();
@ -2972,7 +2914,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() {
RecordDecl *T;
// FIXME: Needs the FlagAppleBlock bit.
T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get("__block_descriptor_withcopydispose"));
T->startDefinition();
@ -3044,7 +2986,7 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
llvm::raw_svector_ostream(Name) << "__Block_byref_" <<
++UniqueBlockByRefTypeID << '_' << DeclName;
RecordDecl *T;
T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get(Name.str()));
T->startDefinition();
QualType Int32Ty = IntTy;
@ -3088,14 +3030,15 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) {
QualType ASTContext::getBlockParmType(
bool BlockHasCopyDispose,
llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
llvm::SmallVectorImpl<const Expr *> &Layout) {
// FIXME: Move up
static unsigned int UniqueBlockParmTypeID = 0;
llvm::SmallString<36> Name;
llvm::raw_svector_ostream(Name) << "__block_literal_"
<< ++UniqueBlockParmTypeID;
RecordDecl *T;
T = CreateRecordDecl(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
&Idents.get(Name.str()));
T->startDefinition();
QualType FieldTypes[] = {
@ -3125,22 +3068,28 @@ QualType ASTContext::getBlockParmType(
T->addDecl(Field);
}
for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) {
const Expr *E = BlockDeclRefDecls[i];
const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
clang::IdentifierInfo *Name = 0;
if (BDRE) {
const ValueDecl *D = BDRE->getDecl();
Name = &Idents.get(D->getName());
}
QualType FieldType = E->getType();
for (unsigned i = 0; i < Layout.size(); ++i) {
const Expr *E = Layout[i];
if (BDRE && BDRE->isByRef())
FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(),
FieldType);
QualType FieldType = E->getType();
IdentifierInfo *FieldName = 0;
if (isa<CXXThisExpr>(E)) {
FieldName = &Idents.get("this");
} else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E)) {
const ValueDecl *D = BDRE->getDecl();
FieldName = D->getIdentifier();
if (BDRE->isByRef())
FieldType = BuildByRefType(D->getNameAsCString(), FieldType);
} else {
// Padding.
assert(isa<ConstantArrayType>(FieldType) &&
isa<DeclRefExpr>(E) &&
!cast<DeclRefExpr>(E)->getDecl()->getDeclName() &&
"doesn't match characteristics of padding decl");
}
FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
Name, FieldType, /*TInfo=*/0,
FieldName, FieldType, /*TInfo=*/0,
/*BitWidth=*/0, /*Mutable=*/false);
Field->setAccess(AS_public);
T->addDecl(Field);
@ -3593,6 +3542,17 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
S += II->getName();
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(),
TemplateArgs.flat_size(),
(*this).PrintingPolicy);
S += TemplateArgsStr;
}
} else {
S += '?';
}
@ -3636,6 +3596,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
return;
}
// Ignore protocol qualifiers when mangling at this level.
if (const ObjCObjectType *OT = T->getAs<ObjCObjectType>())
T = OT->getBaseType();
if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
// @encode(class_name)
ObjCInterfaceDecl *OI = OIT->getDecl();
@ -3718,6 +3682,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
return;
}
// gcc just blithely ignores member pointers.
// TODO: maybe there should be a mangling for these
if (T->getAs<MemberPointerType>())
return;
assert(0 && "@encode for type not implemented!");
}
@ -4106,18 +4075,21 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
///
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT) {
const ObjCObjectType* LHS = LHSOPT->getObjectType();
const ObjCObjectType* RHS = RHSOPT->getObjectType();
// If either type represents the built-in 'id' or 'Class' types, return true.
if (LHSOPT->isObjCBuiltinType() || RHSOPT->isObjCBuiltinType())
if (LHS->isObjCUnqualifiedIdOrClass() ||
RHS->isObjCUnqualifiedIdOrClass())
return true;
if (LHSOPT->isObjCQualifiedIdType() || RHSOPT->isObjCQualifiedIdType())
if (LHS->isObjCQualifiedId() || RHS->isObjCQualifiedId())
return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0),
QualType(RHSOPT,0),
false);
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
if (LHS && RHS) // We have 2 user-defined types.
// If we have 2 user-defined types, fall into that path.
if (LHS->getInterface() && RHS->getInterface())
return canAssignObjCInterfaces(LHS, RHS);
return false;
@ -4168,8 +4140,10 @@ void getIntersectionOfProtocols(ASTContext &Context,
const ObjCObjectPointerType *RHSOPT,
llvm::SmallVectorImpl<ObjCProtocolDecl *> &IntersectionOfProtocols) {
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
const ObjCObjectType* LHS = LHSOPT->getObjectType();
const ObjCObjectType* RHS = RHSOPT->getObjectType();
assert(LHS->getInterface() && "LHS must have an interface base");
assert(RHS->getInterface() && "RHS must have an interface base");
llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocolSet;
unsigned LHSNumProtocols = LHS->getNumProtocols();
@ -4177,7 +4151,8 @@ void getIntersectionOfProtocols(ASTContext &Context,
InheritedProtocolSet.insert(LHS->qual_begin(), LHS->qual_end());
else {
llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;
Context.CollectInheritedProtocols(LHS->getDecl(), LHSInheritedProtocols);
Context.CollectInheritedProtocols(LHS->getInterface(),
LHSInheritedProtocols);
InheritedProtocolSet.insert(LHSInheritedProtocols.begin(),
LHSInheritedProtocols.end());
}
@ -4192,7 +4167,8 @@ void getIntersectionOfProtocols(ASTContext &Context,
}
else {
llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSInheritedProtocols;
Context.CollectInheritedProtocols(RHS->getDecl(), RHSInheritedProtocols);
Context.CollectInheritedProtocols(RHS->getInterface(),
RHSInheritedProtocols);
for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
RHSInheritedProtocols.begin(),
E = RHSInheritedProtocols.end(); I != E; ++I)
@ -4206,37 +4182,40 @@ void getIntersectionOfProtocols(ASTContext &Context,
/// last type comparison in a ?-exp of ObjC pointer types before a
/// warning is issued. So, its invokation is extremely rare.
QualType ASTContext::areCommonBaseCompatible(
const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT) {
const ObjCInterfaceType* LHS = LHSOPT->getInterfaceType();
const ObjCInterfaceType* RHS = RHSOPT->getInterfaceType();
if (!LHS || !RHS)
const ObjCObjectPointerType *Lptr,
const ObjCObjectPointerType *Rptr) {
const ObjCObjectType *LHS = Lptr->getObjectType();
const ObjCObjectType *RHS = Rptr->getObjectType();
const ObjCInterfaceDecl* LDecl = LHS->getInterface();
const ObjCInterfaceDecl* RDecl = RHS->getInterface();
if (!LDecl || !RDecl)
return QualType();
while (const ObjCInterfaceDecl *LHSIDecl = LHS->getDecl()->getSuperClass()) {
QualType LHSTy = getObjCInterfaceType(LHSIDecl);
LHS = LHSTy->getAs<ObjCInterfaceType>();
while ((LDecl = LDecl->getSuperClass())) {
LHS = cast<ObjCInterfaceType>(getObjCInterfaceType(LDecl));
if (canAssignObjCInterfaces(LHS, RHS)) {
llvm::SmallVector<ObjCProtocolDecl *, 8> IntersectionOfProtocols;
getIntersectionOfProtocols(*this,
LHSOPT, RHSOPT, IntersectionOfProtocols);
if (IntersectionOfProtocols.empty())
LHSTy = getObjCObjectPointerType(LHSTy);
else
LHSTy = getObjCObjectPointerType(LHSTy, &IntersectionOfProtocols[0],
IntersectionOfProtocols.size());
return LHSTy;
llvm::SmallVector<ObjCProtocolDecl *, 8> Protocols;
getIntersectionOfProtocols(*this, Lptr, Rptr, Protocols);
QualType Result = QualType(LHS, 0);
if (!Protocols.empty())
Result = getObjCObjectType(Result, Protocols.data(), Protocols.size());
Result = getObjCObjectPointerType(Result);
return Result;
}
}
return QualType();
}
bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
const ObjCInterfaceType *RHS) {
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
const ObjCObjectType *RHS) {
assert(LHS->getInterface() && "LHS is not an interface type");
assert(RHS->getInterface() && "RHS is not an interface type");
// Verify that the base decls are compatible: the RHS must be a subclass of
// the LHS.
if (!LHS->getDecl()->isSuperClassOf(RHS->getDecl()))
if (!LHS->getInterface()->isSuperClassOf(RHS->getInterface()))
return false;
// RHS must have a superset of the protocols in the LHS. If the LHS is not
@ -4249,15 +4228,15 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
if (RHS->getNumProtocols() == 0)
return true; // FIXME: should return false!
for (ObjCInterfaceType::qual_iterator LHSPI = LHS->qual_begin(),
LHSPE = LHS->qual_end();
for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
LHSPE = LHS->qual_end();
LHSPI != LHSPE; LHSPI++) {
bool RHSImplementsProtocol = false;
// If the RHS doesn't implement the protocol on the left, the types
// are incompatible.
for (ObjCInterfaceType::qual_iterator RHSPI = RHS->qual_begin(),
RHSPE = RHS->qual_end();
for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
RHSPE = RHS->qual_end();
RHSPI != RHSPE; RHSPI++) {
if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
RHSImplementsProtocol = true;
@ -4483,6 +4462,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (RHSClass == Type::VariableArray || RHSClass == Type::IncompleteArray)
RHSClass = Type::ConstantArray;
// ObjCInterfaces are just specialized ObjCObjects.
if (LHSClass == Type::ObjCInterface) LHSClass = Type::ObjCObject;
if (RHSClass == Type::ObjCInterface) RHSClass = Type::ObjCObject;
// Canonicalize ExtVector -> Vector.
if (LHSClass == Type::ExtVector) LHSClass = Type::Vector;
if (RHSClass == Type::ExtVector) RHSClass = Type::Vector;
@ -4522,6 +4505,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
assert(false && "C++ should never be in mergeTypes");
return QualType();
case Type::ObjCInterface:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::FunctionProto:
@ -4614,14 +4598,13 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
RHSCan->getAs<VectorType>()))
return LHS;
return QualType();
case Type::ObjCInterface: {
// Check if the interfaces are assignment compatible.
case Type::ObjCObject: {
// Check if the types are assignment compatible.
// FIXME: This should be type compatibility, e.g. whether
// "LHS x; RHS x;" at global scope is legal.
const ObjCInterfaceType* LHSIface = LHS->getAs<ObjCInterfaceType>();
const ObjCInterfaceType* RHSIface = RHS->getAs<ObjCInterfaceType>();
if (LHSIface && RHSIface &&
canAssignObjCInterfaces(LHSIface, RHSIface))
const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>();
const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>();
if (canAssignObjCInterfaces(LHSIface, RHSIface))
return LHS;
return QualType();
@ -4645,6 +4628,87 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return QualType();
}
/// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and
/// 'RHS' attributes and returns the merged version; including for function
/// return types.
QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
QualType LHSCan = getCanonicalType(LHS),
RHSCan = getCanonicalType(RHS);
// If two types are identical, they are compatible.
if (LHSCan == RHSCan)
return LHS;
if (RHSCan->isFunctionType()) {
if (!LHSCan->isFunctionType())
return QualType();
QualType OldReturnType =
cast<FunctionType>(RHSCan.getTypePtr())->getResultType();
QualType NewReturnType =
cast<FunctionType>(LHSCan.getTypePtr())->getResultType();
QualType ResReturnType =
mergeObjCGCQualifiers(NewReturnType, OldReturnType);
if (ResReturnType.isNull())
return QualType();
if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) {
// id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo();
// In either case, use OldReturnType to build the new function type.
const FunctionType *F = LHS->getAs<FunctionType>();
if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) {
FunctionType::ExtInfo Info = getFunctionExtInfo(LHS);
QualType ResultType
= getFunctionType(OldReturnType, FPT->arg_type_begin(),
FPT->getNumArgs(), FPT->isVariadic(),
FPT->getTypeQuals(),
FPT->hasExceptionSpec(),
FPT->hasAnyExceptionSpec(),
FPT->getNumExceptions(),
FPT->exception_begin(),
Info);
return ResultType;
}
}
return QualType();
}
// If the qualifiers are different, the types can still be merged.
Qualifiers LQuals = LHSCan.getLocalQualifiers();
Qualifiers RQuals = RHSCan.getLocalQualifiers();
if (LQuals != RQuals) {
// If any of these qualifiers are different, we have a type mismatch.
if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||
LQuals.getAddressSpace() != RQuals.getAddressSpace())
return QualType();
// Exactly one GC qualifier difference is allowed: __strong is
// okay if the other type has no GC qualifier but is an Objective
// C object pointer (i.e. implicitly strong by default). We fix
// this by pretending that the unqualified type was actually
// qualified __strong.
Qualifiers::GC GC_L = LQuals.getObjCGCAttr();
Qualifiers::GC GC_R = RQuals.getObjCGCAttr();
assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
return QualType();
if (GC_L == Qualifiers::Strong)
return LHS;
if (GC_R == Qualifiers::Strong)
return RHS;
return QualType();
}
if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) {
QualType LHSBaseQT = LHS->getAs<ObjCObjectPointerType>()->getPointeeType();
QualType RHSBaseQT = RHS->getAs<ObjCObjectPointerType>()->getPointeeType();
QualType ResQT = mergeObjCGCQualifiers(LHSBaseQT, RHSBaseQT);
if (ResQT == LHSBaseQT)
return LHS;
if (ResQT == RHSBaseQT)
return RHS;
}
return QualType();
}
//===----------------------------------------------------------------------===//
// Integer Predicates
//===----------------------------------------------------------------------===//

View File

@ -19,65 +19,41 @@
using namespace clang;
/// Determines whether we should have an a.k.a. clause when
/// pretty-printing a type. There are three main criteria:
///
/// 1) Some types provide very minimal sugar that doesn't impede the
/// user's understanding --- for example, elaborated type
/// specifiers. If this is all the sugar we see, we don't want an
/// a.k.a. clause.
/// 2) Some types are technically sugared but are much more familiar
/// when seen in their sugared form --- for example, va_list,
/// vector types, and the magic Objective C types. We don't
/// want to desugar these, even if we do produce an a.k.a. clause.
/// 3) Some types may have already been desugared previously in this diagnostic.
/// if this is the case, doing another "aka" would just be clutter.
///
static bool ShouldAKA(ASTContext &Context, QualType QT,
const Diagnostic::ArgumentValue *PrevArgs,
unsigned NumPrevArgs,
QualType &DesugaredQT) {
QualType InputTy = QT;
bool AKA = false;
QualifierCollector Qc;
// Returns a desugared version of the QualType, and marks ShouldAKA as true
// whenever we remove significant sugar from the type.
static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QualifierCollector QC;
while (true) {
const Type *Ty = Qc.strip(QT);
const Type *Ty = QC.strip(QT);
// Don't aka just because we saw an elaborated type...
if (isa<ElaboratedType>(Ty)) {
QT = cast<ElaboratedType>(Ty)->desugar();
continue;
}
// ...or a qualified name type...
if (isa<QualifiedNameType>(Ty)) {
QT = cast<QualifiedNameType>(Ty)->desugar();
continue;
}
// ...or a substituted template type parameter.
if (isa<SubstTemplateTypeParmType>(Ty)) {
QT = cast<SubstTemplateTypeParmType>(Ty)->desugar();
continue;
}
// Don't desugar template specializations.
if (isa<TemplateSpecializationType>(Ty))
break;
// Don't desugar magic Objective-C types.
if (QualType(Ty,0) == Context.getObjCIdType() ||
QualType(Ty,0) == Context.getObjCClassType() ||
QualType(Ty,0) == Context.getObjCSelType() ||
QualType(Ty,0) == Context.getObjCProtoType())
break;
// Don't desugar va_list.
if (QualType(Ty,0) == Context.getBuiltinVaListType())
break;
// Otherwise, do a single-step desugar.
QualType Underlying;
bool IsSugar = false;
@ -94,50 +70,56 @@ break; \
}
#include "clang/AST/TypeNodes.def"
}
// If it wasn't sugared, we're done.
if (!IsSugar)
break;
// If the desugared type is a vector type, we don't want to expand
// it, it will turn into an attribute mess. People want their "vec4".
if (isa<VectorType>(Underlying))
break;
// Don't desugar through the primary typedef of an anonymous type.
if (isa<TagType>(Underlying) && isa<TypedefType>(QT))
if (cast<TagType>(Underlying)->getDecl()->getTypedefForAnonDecl() ==
cast<TypedefType>(QT)->getDecl())
break;
// Otherwise, we're tearing through something opaque; note that
// we'll eventually need an a.k.a. clause and keep going.
AKA = true;
// Record that we actually looked through an opaque type here.
ShouldAKA = true;
QT = Underlying;
continue;
}
// If we never tore through opaque sugar, don't print aka.
if (!AKA) return false;
// If we did, check to see if we already desugared this type in this
// diagnostic. If so, don't do it again.
for (unsigned i = 0; i != NumPrevArgs; ++i) {
// TODO: Handle ak_declcontext case.
if (PrevArgs[i].first == Diagnostic::ak_qualtype) {
void *Ptr = (void*)PrevArgs[i].second;
QualType PrevTy(QualType::getFromOpaquePtr(Ptr));
if (PrevTy == InputTy)
return false;
}
// If we have a pointer-like type, desugar the pointee as well.
// FIXME: Handle other pointer-like types.
if (const PointerType *Ty = QT->getAs<PointerType>()) {
QT = Context.getPointerType(Desugar(Context, Ty->getPointeeType(),
ShouldAKA));
} else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(),
ShouldAKA));
}
DesugaredQT = Qc.apply(QT);
return true;
return QC.apply(QT);
}
/// \brief Convert the given type to a string suitable for printing as part of
/// a diagnostic.
/// a diagnostic.
///
/// There are three main criteria when determining whether we should have an
/// a.k.a. clause when pretty-printing a type:
///
/// 1) Some types provide very minimal sugar that doesn't impede the
/// user's understanding --- for example, elaborated type
/// specifiers. If this is all the sugar we see, we don't want an
/// a.k.a. clause.
/// 2) Some types are technically sugared but are much more familiar
/// when seen in their sugared form --- for example, va_list,
/// vector types, and the magic Objective C types. We don't
/// want to desugar these, even if we do produce an a.k.a. clause.
/// 3) Some types may have already been desugared previously in this diagnostic.
/// if this is the case, doing another "aka" would just be clutter.
///
/// \param Context the context in which the type was allocated
/// \param Ty the type to print
@ -147,18 +129,35 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
unsigned NumPrevArgs) {
// FIXME: Playing with std::string is really slow.
std::string S = Ty.getAsString(Context.PrintingPolicy);
// Check to see if we already desugared this type in this
// diagnostic. If so, don't do it again.
bool Repeated = false;
for (unsigned i = 0; i != NumPrevArgs; ++i) {
// TODO: Handle ak_declcontext case.
if (PrevArgs[i].first == Diagnostic::ak_qualtype) {
void *Ptr = (void*)PrevArgs[i].second;
QualType PrevTy(QualType::getFromOpaquePtr(Ptr));
if (PrevTy == Ty) {
Repeated = true;
break;
}
}
}
// Consider producing an a.k.a. clause if removing all the direct
// sugar gives us something "significantly different".
QualType DesugaredTy;
if (ShouldAKA(Context, Ty, PrevArgs, NumPrevArgs, DesugaredTy)) {
S = "'"+S+"' (aka '";
S += DesugaredTy.getAsString(Context.PrintingPolicy);
S += "')";
return S;
if (!Repeated) {
bool ShouldAKA = false;
QualType DesugaredTy = Desugar(Context, Ty, ShouldAKA);
if (ShouldAKA) {
S = "'"+S+"' (aka '";
S += DesugaredTy.getAsString(Context.PrintingPolicy);
S += "')";
return S;
}
}
S = "'" + S + "'";
return S;
}

View File

@ -68,13 +68,13 @@ namespace {
// FIXME: DependentDecltypeType
QualType VisitRecordType(RecordType *T);
QualType VisitEnumType(EnumType *T);
QualType VisitElaboratedType(ElaboratedType *T);
// FIXME: TemplateTypeParmType
// FIXME: SubstTemplateTypeParmType
// FIXME: TemplateSpecializationType
QualType VisitQualifiedNameType(QualifiedNameType *T);
QualType VisitElaboratedType(ElaboratedType *T);
// FIXME: DependentNameType
QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
QualType VisitObjCObjectType(ObjCObjectType *T);
QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
// Importing declarations
@ -532,19 +532,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
cast<TagType>(T2)->getDecl()))
return false;
break;
case Type::Elaborated: {
const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
if (Elab1->getTagKind() != Elab2->getTagKind())
return false;
if (!IsStructurallyEquivalent(Context,
Elab1->getUnderlyingType(),
Elab2->getUnderlyingType()))
return false;
break;
}
case Type::TemplateTypeParm: {
const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
@ -594,16 +582,19 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
case Type::QualifiedName: {
const QualifiedNameType *Qual1 = cast<QualifiedNameType>(T1);
const QualifiedNameType *Qual2 = cast<QualifiedNameType>(T2);
case Type::Elaborated: {
const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
// CHECKME: what if a keyword is ETK_None or ETK_typename ?
if (Elab1->getKeyword() != Elab2->getKeyword())
return false;
if (!IsStructurallyEquivalent(Context,
Qual1->getQualifier(),
Qual2->getQualifier()))
Elab1->getQualifier(),
Elab2->getQualifier()))
return false;
if (!IsStructurallyEquivalent(Context,
Qual1->getNamedType(),
Qual2->getNamedType()))
Elab1->getNamedType(),
Elab2->getNamedType()))
return false;
break;
}
@ -642,12 +633,22 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context,
Iface1->getDecl(), Iface2->getDecl()))
return false;
if (Iface1->getNumProtocols() != Iface2->getNumProtocols())
break;
}
case Type::ObjCObject: {
const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
if (!IsStructurallyEquivalent(Context,
Obj1->getBaseType(),
Obj2->getBaseType()))
return false;
for (unsigned I = 0, N = Iface1->getNumProtocols(); I != N; ++I) {
if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
return false;
for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
if (!IsStructurallyEquivalent(Context,
Iface1->getProtocol(I),
Iface2->getProtocol(I)))
Obj1->getProtocol(I),
Obj2->getProtocol(I)))
return false;
}
break;
@ -660,14 +661,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Ptr1->getPointeeType(),
Ptr2->getPointeeType()))
return false;
if (Ptr1->getNumProtocols() != Ptr2->getNumProtocols())
return false;
for (unsigned I = 0, N = Ptr1->getNumProtocols(); I != N; ++I) {
if (!IsStructurallyEquivalent(Context,
Ptr1->getProtocol(I),
Ptr2->getProtocol(I)))
return false;
}
break;
}
@ -1293,24 +1286,20 @@ QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
}
QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
if (ToUnderlyingType.isNull())
return QualType();
return Importer.getToContext().getElaboratedType(ToUnderlyingType,
T->getTagKind());
}
QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
if (!ToQualifier)
return QualType();
NestedNameSpecifier *ToQualifier = 0;
// Note: the qualifier in an ElaboratedType is optional.
if (T->getQualifier()) {
ToQualifier = Importer.Import(T->getQualifier());
if (!ToQualifier)
return QualType();
}
QualType ToNamedType = Importer.Import(T->getNamedType());
if (ToNamedType.isNull())
return QualType();
return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
return Importer.getToContext().getElaboratedType(T->getKeyword(),
ToQualifier, ToNamedType);
}
QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
@ -1319,8 +1308,16 @@ QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
if (!Class)
return QualType();
return Importer.getToContext().getObjCInterfaceType(Class);
}
QualType ASTNodeImporter::VisitObjCObjectType(ObjCObjectType *T) {
QualType ToBaseType = Importer.Import(T->getBaseType());
if (ToBaseType.isNull())
return QualType();
llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
for (ObjCObjectType::qual_iterator P = T->qual_begin(),
PEnd = T->qual_end();
P != PEnd; ++P) {
ObjCProtocolDecl *Protocol
@ -1330,9 +1327,9 @@ QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
Protocols.push_back(Protocol);
}
return Importer.getToContext().getObjCInterfaceType(Class,
Protocols.data(),
Protocols.size());
return Importer.getToContext().getObjCObjectType(ToBaseType,
Protocols.data(),
Protocols.size());
}
QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
@ -1340,20 +1337,7 @@ QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
if (ToPointeeType.isNull())
return QualType();
llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
PEnd = T->qual_end();
P != PEnd; ++P) {
ObjCProtocolDecl *Protocol
= dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
if (!Protocol)
return QualType();
Protocols.push_back(Protocol);
}
return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
Protocols.data(),
Protocols.size());
return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
}
//----------------------------------------------------------------------------
@ -1617,7 +1601,12 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
D2->startDefinition();
ImportDeclContext(D);
D2->completeDefinition(T, ToPromotionType);
// FIXME: we might need to merge the number of positive or negative bits
// if the enumerator lists don't match.
D2->completeDefinition(T, ToPromotionType,
D->getNumPositiveBits(),
D->getNumNegativeBits());
}
return D2;
@ -2961,7 +2950,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
return 0;
return ToContext.getTrivialTypeSourceInfo(T,
FromTSI->getTypeLoc().getFullSourceRange().getBegin());
FromTSI->getTypeLoc().getSourceRange().getBegin());
}
Decl *ASTImporter::Import(Decl *FromD) {

View File

@ -74,6 +74,7 @@ void NonNullAttr::Destroy(ASTContext &C) {
// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for
// "non-simple" classes?
DEF_SIMPLE_ATTR_CLONE(AlignMac68k)
DEF_SIMPLE_ATTR_CLONE(AlwaysInline)
DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn)
DEF_SIMPLE_ATTR_CLONE(BaseCheck)
@ -100,6 +101,7 @@ DEF_SIMPLE_ATTR_CLONE(Override)
DEF_SIMPLE_ATTR_CLONE(Packed)
DEF_SIMPLE_ATTR_CLONE(Pure)
DEF_SIMPLE_ATTR_CLONE(StdCall)
DEF_SIMPLE_ATTR_CLONE(ThisCall)
DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
DEF_SIMPLE_ATTR_CLONE(Unavailable)
DEF_SIMPLE_ATTR_CLONE(Unused)
@ -110,8 +112,8 @@ DEF_SIMPLE_ATTR_CLONE(WeakImport)
DEF_SIMPLE_ATTR_CLONE(WeakRef)
DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer)
Attr* PragmaPackAttr::clone(ASTContext &C) const {
return ::new (C) PragmaPackAttr(Alignment);
Attr* MaxFieldAlignmentAttr::clone(ASTContext &C) const {
return ::new (C) MaxFieldAlignmentAttr(Alignment);
}
Attr* AlignedAttr::clone(ASTContext &C) const {
@ -142,6 +144,10 @@ Attr *IBOutletAttr::clone(ASTContext &C) const {
return ::new (C) IBOutletAttr;
}
Attr *IBOutletCollectionAttr::clone(ASTContext &C) const {
return ::new (C) IBOutletCollectionAttr(D);
}
Attr *IBActionAttr::clone(ASTContext &C) const {
return ::new (C) IBActionAttr;
}

View File

@ -39,4 +39,4 @@ add_clang_library(clangAST
TypePrinter.cpp
)
add_dependencies(clangAST ClangDiagnosticAST)
add_dependencies(clangAST ClangDiagnosticAST ClangStmtNodes)

View File

@ -49,9 +49,8 @@ CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
/// ambiguous, i.e., there are two or more paths that refer to
/// different base class subobjects of the same type. BaseType must be
/// an unqualified, canonical class type.
bool CXXBasePaths::isAmbiguous(QualType BaseType) {
assert(BaseType.isCanonical() && "Base type must be the canonical type");
assert(BaseType.hasQualifiers() == 0 && "Base type must be unqualified");
bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
BaseType = BaseType.getUnqualifiedType();
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
}

View File

@ -23,16 +23,11 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Parse/DeclSpec.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc TypeSourceInfo::getTypeLoc() const {
return TypeLoc(Ty, (void*)(this + 1));
}
//===----------------------------------------------------------------------===//
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
@ -541,7 +536,7 @@ SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
while (true) {
TypeLoc NextTL = TL.getNextTypeLoc();
if (!NextTL)
return TL.getSourceRange().getBegin();
return TL.getLocalSourceRange().getBegin();
TL = NextTL;
}
}
@ -1224,9 +1219,8 @@ FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD,
}
bool FunctionDecl::isImplicitlyInstantiable() const {
// If this function already has a definition or is invalid, it can't be
// implicitly instantiated.
if (isInvalidDecl() || getBody())
// If the function is invalid, it can't be implicitly instantiated.
if (isInvalidDecl())
return false;
switch (getTemplateSpecializationKind()) {
@ -1295,11 +1289,22 @@ FunctionDecl::getTemplateSpecializationArgs() const {
return 0;
}
const TemplateArgumentListInfo *
FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
if (FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArgumentsAsWritten;
}
return 0;
}
void
FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK) {
TemplateSpecializationKind TSK,
const TemplateArgumentListInfo *TemplateArgsAsWritten) {
assert(TSK != TSK_Undeclared &&
"Must specify the type of function template specialization");
FunctionTemplateSpecializationInfo *Info
@ -1311,6 +1316,7 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
Info->Template.setPointer(Template);
Info->Template.setInt(TSK - 1);
Info->TemplateArguments = TemplateArgs;
Info->TemplateArgumentsAsWritten = TemplateArgsAsWritten;
TemplateOrSpecialization = Info;
// Insert this function template specialization into the set of known
@ -1475,6 +1481,12 @@ TagDecl* TagDecl::getCanonicalDecl() {
return getFirstDeclaration();
}
void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) {
TypedefDeclOrQualifier = TDD;
if (TypeForDecl)
TypeForDecl->ClearLinkageCache();
}
void TagDecl::startDefinition() {
if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
TagT->decl.setPointer(this);
@ -1509,6 +1521,7 @@ void TagDecl::completeDefinition() {
TypeForDecl->getAs<InjectedClassNameType>())) {
assert(Injected->Decl == this &&
"Attempt to redefine a class template definition?");
(void)Injected;
}
}
@ -1524,16 +1537,6 @@ TagDecl* TagDecl::getDefinition() const {
return 0;
}
TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
default: llvm_unreachable("unexpected type specifier");
case DeclSpec::TST_struct: return TK_struct;
case DeclSpec::TST_class: return TK_class;
case DeclSpec::TST_union: return TK_union;
case DeclSpec::TST_enum: return TK_enum;
}
}
void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange) {
if (Qualifier) {
@ -1571,10 +1574,14 @@ void EnumDecl::Destroy(ASTContext& C) {
}
void EnumDecl::completeDefinition(QualType NewType,
QualType NewPromotionType) {
QualType NewPromotionType,
unsigned NumPositiveBits,
unsigned NumNegativeBits) {
assert(!isDefinition() && "Cannot redefine enums!");
IntegerType = NewType;
PromotionType = NewPromotionType;
setNumPositiveBits(NumPositiveBits);
setNumNegativeBits(NumNegativeBits);
TagDecl::completeDefinition();
}
@ -1620,6 +1627,17 @@ void RecordDecl::completeDefinition() {
TagDecl::completeDefinition();
}
ValueDecl *RecordDecl::getAnonymousStructOrUnionObject() {
// Force the decl chain to come into existence properly.
if (!getNextDeclInContext()) getParent()->decls_begin();
assert(isAnonymousStructOrUnion());
ValueDecl *D = cast<ValueDecl>(getNextDeclInContext());
assert(D->getType()->isRecordType());
assert(D->getType()->getAs<RecordType>()->getDecl() == this);
return D;
}
//===----------------------------------------------------------------------===//
// BlockDecl Implementation
//===----------------------------------------------------------------------===//

View File

@ -811,12 +811,12 @@ DeclContext::lookup(DeclarationName Name) {
buildLookup(this);
if (!LookupPtr)
return lookup_result(0, 0);
return lookup_result(lookup_iterator(0), lookup_iterator(0));
}
StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
if (Pos == LookupPtr->end())
return lookup_result(0, 0);
return lookup_result(lookup_iterator(0), lookup_iterator(0));
return Pos->second.getLookupResult(getParentASTContext());
}

View File

@ -137,7 +137,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().VBases[I] =
CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
VBaseClassDecl->getTagKind() == TTK_Class,
VBases[I]->getAccessSpecifier(), VBaseType);
}
}
@ -700,8 +700,9 @@ CXXBaseOrMemberInitializer::
CXXBaseOrMemberInitializer(ASTContext &Context,
TypeSourceInfo *TInfo, bool IsVirtual,
SourceLocation L, Expr *Init, SourceLocation R)
: BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), IsVirtual(IsVirtual),
LParenLoc(L), RParenLoc(R)
: BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false),
SourceOrderOrNumArrayIndices(0)
{
}
@ -709,14 +710,46 @@ CXXBaseOrMemberInitializer::
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
SourceLocation L, Expr *Init, SourceLocation R)
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
AnonUnionMember(0), LParenLoc(L), RParenLoc(R)
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
IsWritten(false), SourceOrderOrNumArrayIndices(0)
{
}
CXXBaseOrMemberInitializer::
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
SourceLocation L, Expr *Init, SourceLocation R,
VarDecl **Indices,
unsigned NumIndices)
: BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init),
AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false),
IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
{
VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
}
CXXBaseOrMemberInitializer *
CXXBaseOrMemberInitializer::Create(ASTContext &Context,
FieldDecl *Member,
SourceLocation MemberLoc,
SourceLocation L,
Expr *Init,
SourceLocation R,
VarDecl **Indices,
unsigned NumIndices) {
void *Mem = Context.Allocate(sizeof(CXXBaseOrMemberInitializer) +
sizeof(VarDecl *) * NumIndices,
llvm::alignof<CXXBaseOrMemberInitializer>());
return new (Mem) CXXBaseOrMemberInitializer(Context, Member, MemberLoc,
L, Init, R, Indices, NumIndices);
}
void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
if (Init)
Init->Destroy(Context);
// FIXME: Destroy indices
this->~CXXBaseOrMemberInitializer();
}
@ -745,13 +778,19 @@ SourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const {
if (isMemberInitializer())
return getMemberLocation();
return getBaseClassLoc().getSourceRange().getBegin();
return getBaseClassLoc().getLocalSourceRange().getBegin();
}
SourceRange CXXBaseOrMemberInitializer::getSourceRange() const {
return SourceRange(getSourceLocation(), getRParenLoc());
}
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXConstructorDecl(0, SourceLocation(), DeclarationName(),
QualType(), 0, false, false, false);
}
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -854,6 +893,12 @@ bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const {
return true;
}
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXDestructorDecl(0, SourceLocation(), DeclarationName(),
QualType(), false, false);
}
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -870,6 +915,12 @@ CXXConstructorDecl::Destroy(ASTContext& C) {
CXXMethodDecl::Destroy(C);
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) CXXConversionDecl(0, SourceLocation(), DeclarationName(),
QualType(), 0, false, false);
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@ -908,6 +959,12 @@ NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
return cast_or_null<NamespaceDecl>(NominatedNamespace);
}
void UsingDirectiveDecl::setNominatedNamespace(NamedDecl* ND) {
assert((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
"expected a NamespaceDecl or NamespaceAliasDecl");
NominatedNamespace = ND;
}
NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
SourceLocation AliasLoc,

View File

@ -94,6 +94,10 @@ TemplateDecl::~TemplateDecl() {
// FunctionTemplateDecl Implementation
//===----------------------------------------------------------------------===//
void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
static_cast<Common *>(Ptr)->~Common();
}
FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
@ -129,8 +133,9 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
First = First->getPreviousDeclaration();
if (First->CommonOrPrev.isNull()) {
// FIXME: Allocate with the ASTContext
First->CommonOrPrev = new Common;
Common *CommonPtr = new (getASTContext()) Common;
getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
First->CommonOrPrev = CommonPtr;
}
return First->CommonOrPrev.get<Common*>();
}
@ -139,6 +144,10 @@ FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
static_cast<Common *>(Ptr)->~Common();
}
ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
ClassTemplateDecl *Template = this;
while (Template->getPreviousDeclaration())
@ -156,8 +165,10 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
Common *CommonPtr;
if (PrevDecl)
CommonPtr = PrevDecl->CommonPtr;
else
else {
CommonPtr = new (C) Common;
C.AddDeallocation(DeallocateCommon, CommonPtr);
}
return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
CommonPtr);
@ -259,7 +270,7 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
}
SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
return DefaultArgument->getTypeLoc().getSourceRange().getBegin();
}
unsigned TemplateTypeParmDecl::getDepth() const {
@ -303,22 +314,14 @@ TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
// TemplateArgumentListBuilder Implementation
//===----------------------------------------------------------------------===//
void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
switch (Arg.getKind()) {
default: break;
case TemplateArgument::Type:
assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
break;
}
assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
void TemplateArgumentListBuilder::Append(const TemplateArgument &Arg) {
assert((Arg.getKind() != TemplateArgument::Type ||
Arg.getAsType().isCanonical()) && "Type must be canonical!");
assert(FlatArgs.size() < MaxFlatArgs && "Argument list builder is full!");
assert(!StructuredArgs &&
"Can't append arguments when an argument pack has been added!");
if (!FlatArgs)
FlatArgs = new TemplateArgument[MaxFlatArgs];
FlatArgs[NumFlatArgs++] = Arg;
FlatArgs.push_back(Arg);
}
void TemplateArgumentListBuilder::BeginPack() {
@ -326,7 +329,7 @@ void TemplateArgumentListBuilder::BeginPack() {
assert(!StructuredArgs && "Argument list already contains a pack!");
AddingToPack = true;
PackBeginIndex = NumFlatArgs;
PackBeginIndex = FlatArgs.size();
}
void TemplateArgumentListBuilder::EndPack() {
@ -335,6 +338,7 @@ void TemplateArgumentListBuilder::EndPack() {
AddingToPack = false;
// FIXME: This is a memory leak!
StructuredArgs = new TemplateArgument[MaxStructuredArgs];
// First copy the flat entries over to the list (if any)
@ -346,22 +350,14 @@ void TemplateArgumentListBuilder::EndPack() {
// Next, set the pack.
TemplateArgument *PackArgs = 0;
unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
// FIXME: NumPackArgs shouldn't be negative here???
if (NumPackArgs)
PackArgs = &FlatArgs[PackBeginIndex];
PackArgs = FlatArgs.data()+PackBeginIndex;
StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
/*CopyArgs=*/false);
}
void TemplateArgumentListBuilder::ReleaseArgs() {
FlatArgs = 0;
NumFlatArgs = 0;
MaxFlatArgs = 0;
StructuredArgs = 0;
NumStructuredArgs = 0;
MaxStructuredArgs = 0;
}
//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
@ -376,35 +372,56 @@ TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
if (!TakeArgs)
return;
if (Builder.getStructuredArguments() == Builder.getFlatArguments())
// If this does take ownership of the arguments, then we have to new them
// and copy over.
TemplateArgument *NewArgs =
new (Context) TemplateArgument[Builder.flatSize()];
std::copy(Builder.getFlatArguments(),
Builder.getFlatArguments()+Builder.flatSize(), NewArgs);
FlatArguments.setPointer(NewArgs);
// Just reuse the structured and flat arguments array if possible.
if (Builder.getStructuredArguments() == Builder.getFlatArguments()) {
StructuredArguments.setPointer(NewArgs);
StructuredArguments.setInt(0);
Builder.ReleaseArgs();
} else {
TemplateArgument *NewSArgs =
new (Context) TemplateArgument[Builder.flatSize()];
std::copy(Builder.getFlatArguments(),
Builder.getFlatArguments()+Builder.flatSize(), NewSArgs);
StructuredArguments.setPointer(NewSArgs);
}
}
TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
: FlatArguments(Other.FlatArguments.getPointer(), 1),
NumFlatArguments(Other.flat_size()),
StructuredArguments(Other.StructuredArguments.getPointer(), 1),
NumStructuredArguments(Other.NumStructuredArguments) { }
/// Produces a shallow copy of the given template argument list. This
/// assumes that the input argument list outlives it. This takes the list as
/// a pointer to avoid looking like a copy constructor, since this really
/// really isn't safe to use that way.
TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other)
: FlatArguments(Other->FlatArguments.getPointer(), false),
NumFlatArguments(Other->flat_size()),
StructuredArguments(Other->StructuredArguments.getPointer(), false),
NumStructuredArguments(Other->NumStructuredArguments) { }
TemplateArgumentList::~TemplateArgumentList() {
// FIXME: Deallocate template arguments
void TemplateArgumentList::Destroy(ASTContext &C) {
if (FlatArguments.getInt())
C.Deallocate((void*)FlatArguments.getPointer());
if (StructuredArguments.getInt())
C.Deallocate((void*)StructuredArguments.getPointer());
}
TemplateArgumentList::~TemplateArgumentList() {}
//===----------------------------------------------------------------------===//
// ClassTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl)
: CXXRecordDecl(DK,
SpecializedTemplate->getTemplatedDecl()->getTagKind(),
DC, L,
// FIXME: Should we use DeclarationName for the name of
// class template specializations?
: CXXRecordDecl(DK, TK, DC, L,
SpecializedTemplate->getIdentifier(),
PrevDecl),
SpecializedTemplate(SpecializedTemplate),
@ -414,7 +431,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
}
ClassTemplateSpecializationDecl *
ClassTemplateSpecializationDecl::Create(ASTContext &Context,
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@ -422,7 +439,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context,
ClassTemplateSpecializationDecl *Result
= new (Context)ClassTemplateSpecializationDecl(Context,
ClassTemplateSpecialization,
DC, L,
TK, DC, L,
SpecializedTemplate,
Builder,
PrevDecl);
@ -464,7 +481,7 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
//===----------------------------------------------------------------------===//
ClassTemplatePartialSpecializationDecl *
ClassTemplatePartialSpecializationDecl::
Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
@ -478,7 +495,7 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
ClonedArgs[I] = ArgInfos[I];
ClassTemplatePartialSpecializationDecl *Result
= new (Context)ClassTemplatePartialSpecializationDecl(Context,
= new (Context)ClassTemplatePartialSpecializationDecl(Context, TK,
DC, L, Params,
SpecializedTemplate,
Builder,

View File

@ -11,10 +11,11 @@
// classes.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@ -383,12 +384,12 @@ void DeclarationName::dump() const {
llvm::errs() << '\n';
}
DeclarationNameTable::DeclarationNameTable() {
DeclarationNameTable::DeclarationNameTable(ASTContext &C) : Ctx(C) {
CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
// Initialize the overloaded operator names.
CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
CXXOperatorNames[Op].ExtraKindOrNumArgs
= Op + DeclarationNameExtra::CXXConversionFunction;
@ -399,29 +400,32 @@ DeclarationNameTable::DeclarationNameTable() {
DeclarationNameTable::~DeclarationNameTable() {
llvm::FoldingSet<CXXSpecialName> *SpecialNames =
static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
llvm::FoldingSetIterator<CXXSpecialName>
SI = SpecialNames->begin(), SE = SpecialNames->end();
while (SI != SE) {
CXXSpecialName *n = &*SI++;
delete n;
}
llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
= static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
(CXXLiteralOperatorNames);
llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
LI = LiteralNames->begin(), LE = LiteralNames->end();
(CXXLiteralOperatorNames);
while (LI != LE) {
CXXLiteralOperatorIdName *n = &*LI++;
delete n;
if (Ctx.FreeMemory) {
llvm::FoldingSetIterator<CXXSpecialName>
SI = SpecialNames->begin(), SE = SpecialNames->end();
while (SI != SE) {
CXXSpecialName *n = &*SI++;
Ctx.Deallocate(n);
}
llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
LI = LiteralNames->begin(), LE = LiteralNames->end();
while (LI != LE) {
CXXLiteralOperatorIdName *n = &*LI++;
Ctx.Deallocate(n);
}
Ctx.Deallocate(CXXOperatorNames);
}
delete SpecialNames;
delete LiteralNames;
delete [] CXXOperatorNames;
}
DeclarationName
@ -459,7 +463,7 @@ DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
return DeclarationName(Name);
CXXSpecialName *SpecialName = new CXXSpecialName;
CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
SpecialName->ExtraKindOrNumArgs = EKind;
SpecialName->Type = Ty;
SpecialName->FETokenInfo = 0;
@ -487,7 +491,7 @@ DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
return DeclarationName (Name);
CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
LiteralName->ID = II;

View File

@ -27,6 +27,8 @@
#include <algorithm>
using namespace clang;
void Expr::ANCHOR() {} // key function for Expr class.
/// isKnownToHaveBooleanValue - Return true if this is an integer expression
/// that is known to return 0 or 1. This happens for _Bool/bool expressions
/// but also int expressions which are produced by things like comparisons in
@ -161,8 +163,19 @@ void DeclRefExpr::computeDependence() {
if (const Expr *Init = Var->getAnyInitializer())
if (Init->isValueDependent())
ValueDependent = true;
}
}
}
// (VD) - FIXME: Missing from the standard:
// - a member function or a static data member of the current
// instantiation
else if (Var->isStaticDataMember() &&
Var->getDeclContext()->isDependentContext())
ValueDependent = true;
}
// (VD) - FIXME: Missing from the standard:
// - a member function or a static data member of the current
// instantiation
else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext())
ValueDependent = true;
// (TD) - a nested-name-specifier or a qualified-id that names a
// member of an unknown specialization.
// (handled by DependentScopeDeclRefExpr)
@ -976,6 +989,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return true;
}
case CompoundAssignOperatorClass:
case VAArgExprClass:
return false;
case ConditionalOperatorClass: {
@ -1557,6 +1571,18 @@ Expr *Expr::IgnoreParenCasts() {
}
}
Expr *Expr::IgnoreParenImpCasts() {
Expr *E = this;
while (true) {
if (ParenExpr *P = dyn_cast<ParenExpr>(E))
E = P->getSubExpr();
else if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E))
E = P->getSubExpr();
else
return E;
}
}
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
@ -1757,385 +1783,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
return isEvaluatable(Ctx);
}
/// isIntegerConstantExpr - this recursive routine will test if an expression is
/// an integer constant expression.
/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero,
/// comma, etc
///
/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof
/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer
/// cast+dereference.
// CheckICE - This function does the fundamental ICE checking: the returned
// ICEDiag contains a Val of 0, 1, or 2, and a possibly null SourceLocation.
// Note that to reduce code duplication, this helper does no evaluation
// itself; the caller checks whether the expression is evaluatable, and
// in the rare cases where CheckICE actually cares about the evaluated
// value, it calls into Evalute.
//
// Meanings of Val:
// 0: This expression is an ICE if it can be evaluated by Evaluate.
// 1: This expression is not an ICE, but if it isn't evaluated, it's
// a legal subexpression for an ICE. This return value is used to handle
// the comma operator in C99 mode.
// 2: This expression is not an ICE, and is not a legal subexpression for one.
struct ICEDiag {
unsigned Val;
SourceLocation Loc;
public:
ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {}
ICEDiag() : Val(0) {}
};
ICEDiag NoDiag() { return ICEDiag(); }
static ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) {
Expr::EvalResult EVResult;
if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
!EVResult.Val.isInt()) {
return ICEDiag(2, E->getLocStart());
}
return NoDiag();
}
static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
assert(!E->isValueDependent() && "Should not see value dependent exprs!");
if (!E->getType()->isIntegralType()) {
return ICEDiag(2, E->getLocStart());
}
switch (E->getStmtClass()) {
#define STMT(Node, Base) case Expr::Node##Class:
#define EXPR(Node, Base)
#include "clang/AST/StmtNodes.def"
case Expr::PredefinedExprClass:
case Expr::FloatingLiteralClass:
case Expr::ImaginaryLiteralClass:
case Expr::StringLiteralClass:
case Expr::ArraySubscriptExprClass:
case Expr::MemberExprClass:
case Expr::CompoundAssignOperatorClass:
case Expr::CompoundLiteralExprClass:
case Expr::ExtVectorElementExprClass:
case Expr::InitListExprClass:
case Expr::DesignatedInitExprClass:
case Expr::ImplicitValueInitExprClass:
case Expr::ParenListExprClass:
case Expr::VAArgExprClass:
case Expr::AddrLabelExprClass:
case Expr::StmtExprClass:
case Expr::CXXMemberCallExprClass:
case Expr::CXXDynamicCastExprClass:
case Expr::CXXTypeidExprClass:
case Expr::CXXNullPtrLiteralExprClass:
case Expr::CXXThisExprClass:
case Expr::CXXThrowExprClass:
case Expr::CXXNewExprClass:
case Expr::CXXDeleteExprClass:
case Expr::CXXPseudoDestructorExprClass:
case Expr::UnresolvedLookupExprClass:
case Expr::DependentScopeDeclRefExprClass:
case Expr::CXXConstructExprClass:
case Expr::CXXBindTemporaryExprClass:
case Expr::CXXBindReferenceExprClass:
case Expr::CXXExprWithTemporariesClass:
case Expr::CXXTemporaryObjectExprClass:
case Expr::CXXUnresolvedConstructExprClass:
case Expr::CXXDependentScopeMemberExprClass:
case Expr::UnresolvedMemberExprClass:
case Expr::ObjCStringLiteralClass:
case Expr::ObjCEncodeExprClass:
case Expr::ObjCMessageExprClass:
case Expr::ObjCSelectorExprClass:
case Expr::ObjCProtocolExprClass:
case Expr::ObjCIvarRefExprClass:
case Expr::ObjCPropertyRefExprClass:
case Expr::ObjCImplicitSetterGetterRefExprClass:
case Expr::ObjCSuperExprClass:
case Expr::ObjCIsaExprClass:
case Expr::ShuffleVectorExprClass:
case Expr::BlockExprClass:
case Expr::BlockDeclRefExprClass:
case Expr::NoStmtClass:
return ICEDiag(2, E->getLocStart());
case Expr::GNUNullExprClass:
// GCC considers the GNU __null value to be an integral constant expression.
return NoDiag();
case Expr::ParenExprClass:
return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
case Expr::IntegerLiteralClass:
case Expr::CharacterLiteralClass:
case Expr::CXXBoolLiteralExprClass:
case Expr::CXXZeroInitValueExprClass:
case Expr::TypesCompatibleExprClass:
case Expr::UnaryTypeTraitExprClass:
return NoDiag();
case Expr::CallExprClass:
case Expr::CXXOperatorCallExprClass: {
const CallExpr *CE = cast<CallExpr>(E);
if (CE->isBuiltinCall(Ctx))
return CheckEvalInICE(E, Ctx);
return ICEDiag(2, E->getLocStart());
}
case Expr::DeclRefExprClass:
if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
return NoDiag();
if (Ctx.getLangOptions().CPlusPlus &&
E->getType().getCVRQualifiers() == Qualifiers::Const) {
const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
// Parameter variables are never constants. Without this check,
// getAnyInitializer() can find a default argument, which leads
// to chaos.
if (isa<ParmVarDecl>(D))
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
// C++ 7.1.5.1p2
// A variable of non-volatile const-qualified integral or enumeration
// type initialized by an ICE can be used in ICEs.
if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
Qualifiers Quals = Ctx.getCanonicalType(Dcl->getType()).getQualifiers();
if (Quals.hasVolatile() || !Quals.hasConst())
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
// Look for a declaration of this variable that has an initializer.
const VarDecl *ID = 0;
const Expr *Init = Dcl->getAnyInitializer(ID);
if (Init) {
if (ID->isInitKnownICE()) {
// We have already checked whether this subexpression is an
// integral constant expression.
if (ID->isInitICE())
return NoDiag();
else
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
}
// It's an ICE whether or not the definition we found is
// out-of-line. See DR 721 and the discussion in Clang PR
// 6206 for details.
if (Dcl->isCheckingICE()) {
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
}
Dcl->setCheckingICE();
ICEDiag Result = CheckICE(Init, Ctx);
// Cache the result of the ICE test.
Dcl->setInitKnownICE(Result.Val == 0);
return Result;
}
}
}
return ICEDiag(2, E->getLocStart());
case Expr::UnaryOperatorClass: {
const UnaryOperator *Exp = cast<UnaryOperator>(E);
switch (Exp->getOpcode()) {
case UnaryOperator::PostInc:
case UnaryOperator::PostDec:
case UnaryOperator::PreInc:
case UnaryOperator::PreDec:
case UnaryOperator::AddrOf:
case UnaryOperator::Deref:
return ICEDiag(2, E->getLocStart());
case UnaryOperator::Extension:
case UnaryOperator::LNot:
case UnaryOperator::Plus:
case UnaryOperator::Minus:
case UnaryOperator::Not:
case UnaryOperator::Real:
case UnaryOperator::Imag:
return CheckICE(Exp->getSubExpr(), Ctx);
case UnaryOperator::OffsetOf:
break;
}
// OffsetOf falls through here.
}
case Expr::OffsetOfExprClass: {
// Note that per C99, offsetof must be an ICE. And AFAIK, using
// Evaluate matches the proposed gcc behavior for cases like
// "offsetof(struct s{int x[4];}, x[!.0])". This doesn't affect
// compliance: we should warn earlier for offsetof expressions with
// array subscripts that aren't ICEs, and if the array subscripts
// are ICEs, the value of the offsetof must be an integer constant.
return CheckEvalInICE(E, Ctx);
}
case Expr::SizeOfAlignOfExprClass: {
const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(E);
if (Exp->isSizeOf() && Exp->getTypeOfArgument()->isVariableArrayType())
return ICEDiag(2, E->getLocStart());
return NoDiag();
}
case Expr::BinaryOperatorClass: {
const BinaryOperator *Exp = cast<BinaryOperator>(E);
switch (Exp->getOpcode()) {
case BinaryOperator::PtrMemD:
case BinaryOperator::PtrMemI:
case BinaryOperator::Assign:
case BinaryOperator::MulAssign:
case BinaryOperator::DivAssign:
case BinaryOperator::RemAssign:
case BinaryOperator::AddAssign:
case BinaryOperator::SubAssign:
case BinaryOperator::ShlAssign:
case BinaryOperator::ShrAssign:
case BinaryOperator::AndAssign:
case BinaryOperator::XorAssign:
case BinaryOperator::OrAssign:
return ICEDiag(2, E->getLocStart());
case BinaryOperator::Mul:
case BinaryOperator::Div:
case BinaryOperator::Rem:
case BinaryOperator::Add:
case BinaryOperator::Sub:
case BinaryOperator::Shl:
case BinaryOperator::Shr:
case BinaryOperator::LT:
case BinaryOperator::GT:
case BinaryOperator::LE:
case BinaryOperator::GE:
case BinaryOperator::EQ:
case BinaryOperator::NE:
case BinaryOperator::And:
case BinaryOperator::Xor:
case BinaryOperator::Or:
case BinaryOperator::Comma: {
ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx);
ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
if (Exp->getOpcode() == BinaryOperator::Div ||
Exp->getOpcode() == BinaryOperator::Rem) {
// Evaluate gives an error for undefined Div/Rem, so make sure
// we don't evaluate one.
if (LHSResult.Val != 2 && RHSResult.Val != 2) {
llvm::APSInt REval = Exp->getRHS()->EvaluateAsInt(Ctx);
if (REval == 0)
return ICEDiag(1, E->getLocStart());
if (REval.isSigned() && REval.isAllOnesValue()) {
llvm::APSInt LEval = Exp->getLHS()->EvaluateAsInt(Ctx);
if (LEval.isMinSignedValue())
return ICEDiag(1, E->getLocStart());
}
}
}
if (Exp->getOpcode() == BinaryOperator::Comma) {
if (Ctx.getLangOptions().C99) {
// C99 6.6p3 introduces a strange edge case: comma can be in an ICE
// if it isn't evaluated.
if (LHSResult.Val == 0 && RHSResult.Val == 0)
return ICEDiag(1, E->getLocStart());
} else {
// In both C89 and C++, commas in ICEs are illegal.
return ICEDiag(2, E->getLocStart());
}
}
if (LHSResult.Val >= RHSResult.Val)
return LHSResult;
return RHSResult;
}
case BinaryOperator::LAnd:
case BinaryOperator::LOr: {
ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx);
ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
if (LHSResult.Val == 0 && RHSResult.Val == 1) {
// Rare case where the RHS has a comma "side-effect"; we need
// to actually check the condition to see whether the side
// with the comma is evaluated.
if ((Exp->getOpcode() == BinaryOperator::LAnd) !=
(Exp->getLHS()->EvaluateAsInt(Ctx) == 0))
return RHSResult;
return NoDiag();
}
if (LHSResult.Val >= RHSResult.Val)
return LHSResult;
return RHSResult;
}
}
}
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
case Expr::CXXFunctionalCastExprClass:
case Expr::CXXStaticCastExprClass:
case Expr::CXXReinterpretCastExprClass:
case Expr::CXXConstCastExprClass: {
const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
if (SubExpr->getType()->isIntegralType())
return CheckICE(SubExpr, Ctx);
if (isa<FloatingLiteral>(SubExpr->IgnoreParens()))
return NoDiag();
return ICEDiag(2, E->getLocStart());
}
case Expr::ConditionalOperatorClass: {
const ConditionalOperator *Exp = cast<ConditionalOperator>(E);
// If the condition (ignoring parens) is a __builtin_constant_p call,
// then only the true side is actually considered in an integer constant
// expression, and it is fully evaluated. This is an important GNU
// extension. See GCC PR38377 for discussion.
if (const CallExpr *CallCE
= dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts()))
if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) {
Expr::EvalResult EVResult;
if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
!EVResult.Val.isInt()) {
return ICEDiag(2, E->getLocStart());
}
return NoDiag();
}
ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx);
ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx);
ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx);
if (CondResult.Val == 2)
return CondResult;
if (TrueResult.Val == 2)
return TrueResult;
if (FalseResult.Val == 2)
return FalseResult;
if (CondResult.Val == 1)
return CondResult;
if (TrueResult.Val == 0 && FalseResult.Val == 0)
return NoDiag();
// Rare case where the diagnostics depend on which side is evaluated
// Note that if we get here, CondResult is 0, and at least one of
// TrueResult and FalseResult is non-zero.
if (Exp->getCond()->EvaluateAsInt(Ctx) == 0) {
return FalseResult;
}
return TrueResult;
}
case Expr::CXXDefaultArgExprClass:
return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
case Expr::ChooseExprClass: {
return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx);
}
}
// Silence a GCC warning
return ICEDiag(2, E->getLocStart());
}
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
ICEDiag d = CheckICE(this, Ctx);
if (d.Val != 0) {
if (Loc) *Loc = d.Loc;
return false;
}
EvalResult EvalResult;
if (!Evaluate(EvalResult, Ctx))
llvm_unreachable("ICE cannot be evaluated!");
assert(!EvalResult.HasSideEffects && "ICE with side effects!");
assert(EvalResult.Val.isInt() && "ICE that isn't integer!");
Result = EvalResult.Val.getInt();
return true;
}
/// isNullPointerConstant - C99 6.3.2.3p3 - Return true if this is either an
/// integer constant expression with the value zero, or if this is one that is
/// cast to void*.
@ -2433,9 +2080,9 @@ ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
break;
case Class:
if (const ObjCInterfaceType *Iface
= getClassReceiver()->getAs<ObjCInterfaceType>())
return Iface->getDecl();
if (const ObjCObjectType *Ty
= getClassReceiver()->getAs<ObjCObjectType>())
return Ty->getInterface();
break;
case SuperInstance:
@ -2712,7 +2359,9 @@ Stmt::child_iterator ObjCPropertyRefExpr::child_end() { return &Base+1; }
// ObjCImplicitSetterGetterRefExpr
Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_begin() {
return &Base;
// If this is accessing a class member, skip that entry.
if (Base) return &Base;
return &Base+1;
}
Stmt::child_iterator ObjCImplicitSetterGetterRefExpr::child_end() {
return &Base+1;

View File

@ -92,12 +92,11 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
SourceLocation startLoc, SourceLocation endLoc)
: Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
GlobalNew(globalNew), ParenTypeId(parenTypeId),
Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
OperatorDelete(operatorDelete), Constructor(constructor),
StartLoc(startLoc), EndLoc(endLoc) {
unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
SubExprs = new (C) Stmt*[TotalSize];
AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
unsigned i = 0;
if (Array)
SubExprs[i++] = arraySize;
@ -105,9 +104,20 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
SubExprs[i++] = placementArgs[j];
for (unsigned j = 0; j < NumConstructorArgs; ++j)
SubExprs[i++] = constructorArgs[j];
assert(i == TotalSize);
}
void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
unsigned numPlaceArgs, unsigned numConsArgs){
assert(SubExprs == 0 && "SubExprs already allocated");
Array = isArray;
NumPlacementArgs = numPlaceArgs;
NumConstructorArgs = numConsArgs;
unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
SubExprs = new (C) Stmt*[TotalSize];
}
void CXXNewExpr::DoDestroy(ASTContext &C) {
DestroyChildren(C);
if (SubExprs)
@ -134,7 +144,7 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
: Type(Info)
{
Location = Info->getTypeLoc().getSourceRange().getBegin();
Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
}
QualType CXXPseudoDestructorExpr::getDestroyedType() const {
@ -147,7 +157,7 @@ QualType CXXPseudoDestructorExpr::getDestroyedType() const {
SourceRange CXXPseudoDestructorExpr::getSourceRange() const {
SourceLocation End = DestroyedType.getLocation();
if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
End = TInfo->getTypeLoc().getSourceRange().getEnd();
End = TInfo->getTypeLoc().getLocalSourceRange().getEnd();
return SourceRange(Base->getLocStart(), End);
}
@ -159,23 +169,47 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, DeclarationName Name,
SourceLocation NameLoc, bool ADL,
const TemplateArgumentListInfo &Args)
const TemplateArgumentListInfo &Args,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
{
void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
ExplicitTemplateArgumentList::sizeFor(Args));
UnresolvedLookupExpr *ULE
= new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
= new (Mem) UnresolvedLookupExpr(C,
Dependent ? C.DependentTy : C.OverloadTy,
Dependent, NamingClass,
Qualifier, QualifierRange,
Name, NameLoc, ADL,
/*Overload*/ true,
/*ExplicitTemplateArgs*/ true);
/*ExplicitTemplateArgs*/ true,
Begin, End);
reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
return ULE;
}
OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T,
bool Dependent, NestedNameSpecifier *Qualifier,
SourceRange QRange, DeclarationName Name,
SourceLocation NameLoc, bool HasTemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
: Expr(K, T, Dependent, Dependent),
Results(0), NumResults(End - Begin), Name(Name), Qualifier(Qualifier),
QualifierRange(QRange), NameLoc(NameLoc),
HasExplicitTemplateArgs(HasTemplateArgs)
{
if (NumResults) {
Results = static_cast<DeclAccessPair *>(
C.Allocate(sizeof(DeclAccessPair) * NumResults,
llvm::alignof<DeclAccessPair>()));
memcpy(Results, &*Begin.getIterator(),
(End - Begin) * sizeof(DeclAccessPair));
}
}
bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
UnresolvedSetIterator End,
const TemplateArgumentListInfo *Args) {
@ -517,35 +551,43 @@ void CXXConstructExpr::DoDestroy(ASTContext &C) {
C.Deallocate(this);
}
CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C,
Expr *subexpr,
CXXTemporary **temps,
unsigned numtemps)
: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
subexpr->isTypeDependent(), subexpr->isValueDependent()),
SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
if (NumTemps > 0) {
Temps = new CXXTemporary*[NumTemps];
for (unsigned i = 0; i < NumTemps; ++i)
SubExpr(subexpr), Temps(0), NumTemps(0) {
if (numtemps) {
setNumTemporaries(C, numtemps);
for (unsigned i = 0; i != numtemps; ++i)
Temps[i] = temps[i];
}
}
void CXXExprWithTemporaries::setNumTemporaries(ASTContext &C, unsigned N) {
assert(Temps == 0 && "Cannot resize with this");
NumTemps = N;
Temps = new (C) CXXTemporary*[NumTemps];
}
CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Expr *SubExpr,
CXXTemporary **Temps,
unsigned NumTemps) {
return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
return new (C) CXXExprWithTemporaries(C, SubExpr, Temps, NumTemps);
}
void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
DestroyChildren(C);
if (Temps)
C.Deallocate(Temps);
this->~CXXExprWithTemporaries();
C.Deallocate(this);
}
CXXExprWithTemporaries::~CXXExprWithTemporaries() {
delete[] Temps;
}
CXXExprWithTemporaries::~CXXExprWithTemporaries() {}
// CXXBindTemporaryExpr
Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
@ -682,7 +724,8 @@ Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
return child_iterator(&Base + 1);
}
UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, QualType T,
bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType,
bool IsArrow,
@ -691,10 +734,12 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
SourceRange QualifierRange,
DeclarationName MemberName,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs)
: OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
: OverloadExpr(UnresolvedMemberExprClass, C, T, Dependent,
Qualifier, QualifierRange, MemberName, MemberLoc,
TemplateArgs != 0),
TemplateArgs != 0, Begin, End),
IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
if (TemplateArgs)
@ -710,17 +755,19 @@ UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
SourceRange QualifierRange,
DeclarationName Member,
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs) {
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End) {
std::size_t size = sizeof(UnresolvedMemberExpr);
if (TemplateArgs)
size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
return new (Mem) UnresolvedMemberExpr(
return new (Mem) UnresolvedMemberExpr(C,
Dependent ? C.DependentTy : C.OverloadTy,
Dependent, HasUnresolvedUsing, Base, BaseType,
IsArrow, OperatorLoc, Qualifier, QualifierRange,
Member, MemberLoc, TemplateArgs);
Member, MemberLoc, TemplateArgs, Begin, End);
}
CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {

File diff suppressed because it is too large Load Diff

View File

@ -145,14 +145,14 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS,
InnerPolicy.SuppressScope = true;
// Nested-name-specifiers are intended to contain minimally-qualified
// types. An actual QualifiedNameType will not occur, since we'll store
// types. An actual ElaboratedType will not occur, since we'll store
// just the type that is referred to in the nested-name-specifier (e.g.,
// a TypedefType, TagType, etc.). However, when we are dealing with
// dependent template-id types (e.g., Outer<T>::template Inner<U>),
// the type requires its own nested-name-specifier for uniqueness, so we
// suppress that nested-name-specifier during printing.
assert(!isa<QualifiedNameType>(T) &&
"Qualified name type in nested-name-specifier");
assert(!isa<ElaboratedType>(T) &&
"Elaborated type in nested-name-specifier");
if (const TemplateSpecializationType *SpecType
= dyn_cast<TemplateSpecializationType>(T)) {
// Print the template name without its corresponding

View File

@ -44,7 +44,9 @@ ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
unsigned fieldcount,
uint64_t nonvirtualsize,
unsigned nonvirtualalign,
const PrimaryBaseInfo &PrimaryBase,
uint64_t SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool PrimaryBaseIsVirtual,
const BaseOffsetsMapTy& BaseOffsets,
const BaseOffsetsMapTy& VBaseOffsets)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
@ -55,9 +57,10 @@ ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
}
CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->PrimaryBase = PrimaryBaseInfo(PrimaryBase, PrimaryBaseIsVirtual);
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
CXXInfo->BaseOffsets = BaseOffsets;
CXXInfo->VBaseOffsets = VBaseOffsets;

File diff suppressed because it is too large Load Diff

View File

@ -1,170 +0,0 @@
//===- ASTRecordLayoutBuilder.h - Helper class for building record layouts ===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
#define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/System/DataTypes.h"
#include <map>
namespace clang {
class ASTContext;
class ASTRecordLayout;
class CXXRecordDecl;
class FieldDecl;
class ObjCImplementationDecl;
class ObjCInterfaceDecl;
class RecordDecl;
class ASTRecordLayoutBuilder {
ASTContext &Context;
/// Size - The current size of the record layout.
uint64_t Size;
/// Alignment - The current alignment of the record layout.
unsigned Alignment;
llvm::SmallVector<uint64_t, 16> FieldOffsets;
/// Packed - Whether the record is packed or not.
bool Packed;
/// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
/// this contains the number of bits in the last byte that can be used for
/// an adjacent bitfield if necessary.
unsigned char UnfilledBitsInLastByte;
/// MaxFieldAlignment - The maximum allowed field alignment. This is set by
/// #pragma pack.
unsigned MaxFieldAlignment;
/// DataSize - The data size of the record being laid out.
uint64_t DataSize;
bool IsUnion;
uint64_t NonVirtualSize;
unsigned NonVirtualAlignment;
/// PrimaryBase - the primary base class (if one exists) of the class
/// we're laying out.
ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
/// Bases - base classes and their offsets in the record.
ASTRecordLayout::BaseOffsetsMapTy Bases;
// VBases - virtual base classes and their offsets in the record.
ASTRecordLayout::BaseOffsetsMapTy VBases;
/// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
/// primary base classes for some other direct or indirect base class.
llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
/// FirstNearlyEmptyVBase - The first nearly empty virtual base class in
/// inheritance graph order. Used for determining the primary base class.
const CXXRecordDecl *FirstNearlyEmptyVBase;
/// VisitedVirtualBases - A set of all the visited virtual bases, used to
/// avoid visiting virtual bases more than once.
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
/// EmptyClassOffsets - A map from offsets to empty record decls.
typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
EmptyClassOffsetsTy EmptyClassOffsets;
ASTRecordLayoutBuilder(ASTContext &Ctx);
void Layout(const RecordDecl *D);
void Layout(const CXXRecordDecl *D);
void Layout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
void LayoutFields(const RecordDecl *D);
void LayoutField(const FieldDecl *D);
void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
void LayoutBitField(const FieldDecl *D);
/// DeterminePrimaryBase - Determine the primary base of the given class.
void DeterminePrimaryBase(const CXXRecordDecl *RD);
void SelectPrimaryVBase(const CXXRecordDecl *RD);
/// IdentifyPrimaryBases - Identify all virtual base classes, direct or
/// indirect, that are primary base classes for some other direct or indirect
/// base class.
void IdentifyPrimaryBases(const CXXRecordDecl *RD);
bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
/// LayoutNonVirtualBases - Determines the primary base class (if any) and
/// lays it out. Will then proceed to lay out all non-virtual base clasess.
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
/// LayoutNonVirtualBase - Lays out a single non-virtual base.
void LayoutNonVirtualBase(const CXXRecordDecl *RD);
void AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
const CXXRecordDecl *MostDerivedClass);
/// LayoutVirtualBases - Lays out all the virtual bases.
void LayoutVirtualBases(const CXXRecordDecl *RD,
const CXXRecordDecl *MostDerivedClass);
/// LayoutVirtualBase - Lays out a single virtual base.
void LayoutVirtualBase(const CXXRecordDecl *RD);
/// LayoutBase - Will lay out a base and return the offset where it was
/// placed, in bits.
uint64_t LayoutBase(const CXXRecordDecl *RD);
/// canPlaceRecordAtOffset - Return whether a record (either a base class
/// or a field) can be placed at the given offset.
/// Returns false if placing the record will result in two components
/// (direct or indirect) of the same type having the same offset.
bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
/// canPlaceFieldAtOffset - Return whether a field can be placed at the given
/// offset.
bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const;
/// UpdateEmptyClassOffsets - Called after a record (either a base class
/// or a field) has been placed at the given offset. Will update the
/// EmptyClassOffsets map if the class is empty or has any empty bases or
/// fields.
void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset);
/// UpdateEmptyClassOffsets - Called after a field has been placed at the
/// given offset.
void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
/// FinishLayout - Finalize record layout. Adjust record size based on the
/// alignment.
void FinishLayout();
void UpdateAlignment(unsigned NewAlignment);
ASTRecordLayoutBuilder(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayoutBuilder&); // DO NOT IMPLEMENT
public:
static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
const RecordDecl *RD);
static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
};
} // end namespace clang
#endif

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