mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-08 17:40:31 +00:00
Update clang to r104832.
This commit is contained in:
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
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
5
include/clang/AST/CMakeLists.txt
Normal file
5
include/clang/AST/CMakeLists.txt
Normal 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)
|
|
@ -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; }
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
13
include/clang/AST/Makefile
Normal file
13
include/clang/AST/Makefile
Normal 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, $@) $<
|
||||
|
|
@ -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!");
|
||||
|
||||
|
|
768
include/clang/AST/RecursiveASTVisitor.h
Normal file
768
include/clang/AST/RecursiveASTVisitor.h
Normal 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
|
|
@ -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) {
|
||||
|
|
127
include/clang/AST/StmtNodes.td
Normal file
127
include/clang/AST/StmtNodes.td
Normal 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>;
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -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<
|
||||
|
|
10
include/clang/Basic/DiagnosticCategories.td
Normal file
10
include/clang/Basic/DiagnosticCategories.td
Normal 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">;
|
|
@ -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<
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]>;
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
add_subdirectory(AST)
|
||||
add_subdirectory(Basic)
|
||||
add_subdirectory(Driver)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
/// @{
|
||||
|
||||
|
|
32
include/clang/Driver/CC1AsOptions.h
Normal file
32
include/clang/Driver/CC1AsOptions.h
Normal 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
|
71
include/clang/Driver/CC1AsOptions.td
Normal file
71
include/clang/Driver/CC1AsOptions.td
Normal 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)">;
|
|
@ -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">,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, $@) $<
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -57,6 +57,11 @@ class EmitLLVMOnlyAction : public CodeGenAction {
|
|||
EmitLLVMOnlyAction();
|
||||
};
|
||||
|
||||
class EmitCodeGenOnlyAction : public CodeGenAction {
|
||||
public:
|
||||
EmitCodeGenOnlyAction();
|
||||
};
|
||||
|
||||
class EmitObjAction : public CodeGenAction {
|
||||
public:
|
||||
EmitObjAction();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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))
|
||||
<< "\"";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -39,4 +39,4 @@ add_clang_library(clangAST
|
|||
TypePrinter.cpp
|
||||
)
|
||||
|
||||
add_dependencies(clangAST ClangDiagnosticAST)
|
||||
add_dependencies(clangAST ClangDiagnosticAST ClangStmtNodes)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
419
lib/AST/Expr.cpp
419
lib/AST/Expr.cpp
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
Loading…
Reference in a new issue