Update clang to r96341.

This commit is contained in:
Roman Divacky 2010-02-16 09:31:36 +00:00
parent 5044f5c816
commit ecb7e5c8af
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=203955
725 changed files with 29387 additions and 10475 deletions

View File

@ -0,0 +1,18 @@
//===----------------------------------------------------------------------===//
// Clang Python Bindings
//===----------------------------------------------------------------------===//
This directory implements Python bindings for Clang. Currently, only bindings
for the CIndex C API exist.
You may need to alter LD_LIBRARY_PATH so that the CIndex library can be
found. The unit tests are designed to be run with 'nosetests'. For example:
--
$ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \
LD_LIBRARY_PATH=$(llvm-config --libdir) \
nosetests -v
tests.cindex.test_index.test_create ... ok
...
OK
--

View File

@ -0,0 +1,24 @@
#===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
r"""
Clang Library Bindings
======================
This package provides access to the Clang compiler and libraries.
The available modules are:
cindex
Bindings for the Clang indexing library.
"""
__all__ = ['cindex']

View File

@ -0,0 +1,933 @@
#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
r"""
Clang Indexing Library Bindings
===============================
This module provides an interface to the Clang indexing library. It is a
low-level interface to the indexing library which attempts to match the Clang
API directly while also being "pythonic". Notable differences from the C API
are:
* string results are returned as Python strings, not CXString objects.
* null cursors are translated to None.
* access to child cursors is done via iteration, not visitation.
The major indexing objects are:
Index
The top-level object which manages some global library state.
TranslationUnit
High-level object encapsulating the AST for a single translation unit. These
can be loaded from .ast files or parsed on the fly.
Cursor
Generic object for representing a node in the AST.
SourceRange, SourceLocation, and File
Objects representing information about the input source.
Most object information is exposed using properties, when the underlying API
call is efficient.
"""
# TODO
# ====
#
# o API support for invalid translation units. Currently we can't even get the
# diagnostics on failure because they refer to locations in an object that
# will have been invalidated.
#
# o fix memory management issues (currently client must hold on to index and
# translation unit, or risk crashes).
#
# o expose code completion APIs.
#
# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
# clearly, and hide from the external interface (i.e., help(cindex)).
#
# o implement additional SourceLocation, SourceRange, and File methods.
from ctypes import *
def get_cindex_library():
# FIXME: It's probably not the case that the library is actually found in
# this location. We need a better system of identifying and loading the
# CIndex library. It could be on path or elsewhere, or versioned, etc.
import platform
name = platform.system()
if name == 'Darwin':
return cdll.LoadLibrary('libCIndex.dylib')
elif name == 'Windows':
return cdll.LoadLibrary('libCIndex.dll')
else:
return cdll.LoadLibrary('libCIndex.so')
# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
# object. This is a problem, because it means that from_parameter will see an
# integer and pass the wrong value on platforms where int != void*. Work around
# this by marshalling object arguments as void**.
c_object_p = POINTER(c_void_p)
lib = get_cindex_library()
### Structures and Utility Classes ###
class _CXString(Structure):
"""Helper for transforming CXString results."""
_fields_ = [("spelling", c_char_p), ("free", c_int)]
def __del__(self):
_CXString_dispose(self)
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, _CXString)
return _CXString_getCString(res)
class SourceLocation(Structure):
"""
A SourceLocation represents a particular location within a source file.
"""
_fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
_data = None
def _get_instantiation(self):
if self._data is None:
f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
f = File(f) if f else None
self._data = (f, int(l.value), int(c.value), int(c.value))
return self._data
@property
def file(self):
"""Get the file represented by this source location."""
return self._get_instantiation()[0]
@property
def line(self):
"""Get the line represented by this source location."""
return self._get_instantiation()[1]
@property
def column(self):
"""Get the column represented by this source location."""
return self._get_instantiation()[2]
@property
def offset(self):
"""Get the file offset represented by this source location."""
return self._get_instantiation()[3]
def __repr__(self):
return "<SourceLocation file %r, line %r, column %r>" % (
self.file.name if self.file else None, self.line, self.column)
class SourceRange(Structure):
"""
A SourceRange describes a range of source locations within the source
code.
"""
_fields_ = [
("ptr_data", c_void_p * 2),
("begin_int_data", c_uint),
("end_int_data", c_uint)]
# FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
# object.
@staticmethod
def from_locations(start, end):
return SourceRange_getRange(start, end)
@property
def start(self):
"""
Return a SourceLocation representing the first character within a
source range.
"""
return SourceRange_start(self)
@property
def end(self):
"""
Return a SourceLocation representing the last character within a
source range.
"""
return SourceRange_end(self)
def __repr__(self):
return "<SourceRange start %r, end %r>" % (self.start, self.end)
class Diagnostic(object):
"""
A Diagnostic is a single instance of a Clang diagnostic. It includes the
diagnostic severity, the message, the location the diagnostic occurred, as
well as additional source ranges and associated fix-it hints.
"""
Ignored = 0
Note = 1
Warning = 2
Error = 3
Fatal = 4
def __init__(self, severity, location, spelling, ranges, fixits):
self.severity = severity
self.location = location
self.spelling = spelling
self.ranges = ranges
self.fixits = fixits
def __repr__(self):
return "<Diagnostic severity %r, location %r, spelling %r>" % (
self.severity, self.location, self.spelling)
class FixIt(object):
"""
A FixIt represents a transformation to be applied to the source to
"fix-it". The fix-it shouldbe applied by replacing the given source range
with the given value.
"""
def __init__(self, range, value):
self.range = range
self.value = value
def __repr__(self):
return "<FixIt range %r, value %r>" % (self.range, self.value)
### Cursor Kinds ###
class CursorKind(object):
"""
A CursorKind describes the kind of entity that a cursor points to.
"""
# The unique kind objects, indexed by id.
_kinds = []
_name_map = None
def __init__(self, value):
if value >= len(CursorKind._kinds):
CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
if CursorKind._kinds[value] is not None:
raise ValueError,'CursorKind already loaded'
self.value = value
CursorKind._kinds[value] = self
CursorKind._name_map = None
def from_param(self):
return self.value
@property
def name(self):
"""Get the enumeration name of this cursor kind."""
if self._name_map is None:
self._name_map = {}
for key,value in CursorKind.__dict__.items():
if isinstance(value,CursorKind):
self._name_map[value] = key
return self._name_map[self]
@staticmethod
def from_id(id):
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
raise ValueError,'Unknown cursor kind'
return CursorKind._kinds[id]
@staticmethod
def get_all_kinds():
"""Return all CursorKind enumeration instances."""
return filter(None, CursorKind._kinds)
def is_declaration(self):
"""Test if this is a declaration kind."""
return CursorKind_is_decl(self)
def is_reference(self):
"""Test if this is a reference kind."""
return CursorKind_is_ref(self)
def is_expression(self):
"""Test if this is an expression kind."""
return CursorKind_is_expr(self)
def is_statement(self):
"""Test if this is a statement kind."""
return CursorKind_is_stmt(self)
def is_invalid(self):
"""Test if this is an invalid kind."""
return CursorKind_is_inv(self)
def __repr__(self):
return 'CursorKind.%s' % (self.name,)
# FIXME: Is there a nicer way to expose this enumeration? We could potentially
# represent the nested structure, or even build a class hierarchy. The main
# things we want for sure are (a) simple external access to kinds, (b) a place
# to hang a description and name, (c) easy to keep in sync with Index.h.
###
# Declaration Kinds
# A declaration whose specific kind is not exposed via this interface.
#
# Unexposed declarations have the same operations as any other kind of
# declaration; one can extract their location information, spelling, find their
# definitions, etc. However, the specific kind of the declaration is not
# reported.
CursorKind.UNEXPOSED_DECL = CursorKind(1)
# A C or C++ struct.
CursorKind.STRUCT_DECL = CursorKind(2)
# A C or C++ union.
CursorKind.UNION_DECL = CursorKind(3)
# A C++ class.
CursorKind.CLASS_DECL = CursorKind(4)
# An enumeration.
CursorKind.ENUM_DECL = CursorKind(5)
# A field (in C) or non-static data member (in C++) in a struct, union, or C++
# class.
CursorKind.FIELD_DECL = CursorKind(6)
# An enumerator constant.
CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
# A function.
CursorKind.FUNCTION_DECL = CursorKind(8)
# A variable.
CursorKind.VAR_DECL = CursorKind(9)
# A function or method parameter.
CursorKind.PARM_DECL = CursorKind(10)
# An Objective-C @interface.
CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
# An Objective-C @interface for a category.
CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
# An Objective-C @protocol declaration.
CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
# An Objective-C @property declaration.
CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
# An Objective-C instance variable.
CursorKind.OBJC_IVAR_DECL = CursorKind(15)
# An Objective-C instance method.
CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
# An Objective-C class method.
CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
# An Objective-C @implementation.
CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
# An Objective-C @implementation for a category.
CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
# A typedef.
CursorKind.TYPEDEF_DECL = CursorKind(20)
###
# Reference Kinds
CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
CursorKind.OBJC_CLASS_REF = CursorKind(42)
# A reference to a type declaration.
#
# A type reference occurs anywhere where a type is named but not
# declared. For example, given:
# typedef unsigned size_type;
# size_type size;
#
# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
# while the type of the variable "size" is referenced. The cursor
# referenced by the type of size is the typedef for size_type.
CursorKind.TYPE_REF = CursorKind(43)
###
# Invalid/Error Kinds
CursorKind.INVALID_FILE = CursorKind(70)
CursorKind.NO_DECL_FOUND = CursorKind(71)
CursorKind.NOT_IMPLEMENTED = CursorKind(72)
###
# Expression Kinds
# An expression whose specific kind is not exposed via this interface.
#
# Unexposed expressions have the same operations as any other kind of
# expression; one can extract their location information, spelling, children,
# etc. However, the specific kind of the expression is not reported.
CursorKind.UNEXPOSED_EXPR = CursorKind(100)
# An expression that refers to some value declaration, such as a function,
# varible, or enumerator.
CursorKind.DECL_REF_EXPR = CursorKind(101)
# An expression that refers to a member of a struct, union, class, Objective-C
# class, etc.
CursorKind.MEMBER_REF_EXPR = CursorKind(102)
# An expression that calls a function.
CursorKind.CALL_EXPR = CursorKind(103)
# An expression that sends a message to an Objective-C object or class.
CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
# A statement whose specific kind is not exposed via this interface.
#
# Unexposed statements have the same operations as any other kind of statement;
# one can extract their location information, spelling, children, etc. However,
# the specific kind of the statement is not reported.
CursorKind.UNEXPOSED_STMT = CursorKind(200)
###
# Other Kinds
# Cursor that represents the translation unit itself.
#
# The translation unit cursor exists primarily to act as the root cursor for
# traversing the contents of a translation unit.
CursorKind.TRANSLATION_UNIT = CursorKind(300)
### Cursors ###
class Cursor(Structure):
"""
The Cursor class represents a reference to an element within the AST. It
acts as a kind of iterator.
"""
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
def __eq__(self, other):
return Cursor_eq(self, other)
def __ne__(self, other):
return not Cursor_eq(self, other)
def is_definition(self):
"""
Returns true if the declaration pointed at by the cursor is also a
definition of that entity.
"""
return Cursor_is_def(self)
def get_definition(self):
"""
If the cursor is a reference to a declaration or a declaration of
some entity, return a cursor that points to the definition of that
entity.
"""
# TODO: Should probably check that this is either a reference or
# declaration prior to issuing the lookup.
return Cursor_def(self)
def get_usr(self):
"""Return the Unified Symbol Resultion (USR) for the entity referenced
by the given cursor (or None).
A Unified Symbol Resolution (USR) is a string that identifies a
particular entity (function, class, variable, etc.) within a
program. USRs can be compared across translation units to determine,
e.g., when references in one translation refer to an entity defined in
another translation unit."""
return Cursor_usr(self)
@property
def kind(self):
"""Return the kind of this cursor."""
return CursorKind.from_id(self._kind_id)
@property
def spelling(self):
"""Return the spelling of the entity pointed at by the cursor."""
if not self.kind.is_declaration():
# FIXME: clang_getCursorSpelling should be fixed to not assert on
# this, for consistency with clang_getCursorUSR.
return None
return Cursor_spelling(self)
@property
def location(self):
"""
Return the source location (the starting character) of the entity
pointed at by the cursor.
"""
return Cursor_loc(self)
@property
def extent(self):
"""
Return the source range (the range of text) occupied by the entity
pointed at by the cursor.
"""
return Cursor_extent(self)
def get_children(self):
"""Return an iterator for accessing the children of this cursor."""
# FIXME: Expose iteration from CIndex, PR6125.
def visitor(child, parent, children):
# FIXME: Document this assertion in API.
# FIXME: There should just be an isNull method.
assert child != Cursor_null()
children.append(child)
return 1 # continue
children = []
Cursor_visit(self, Cursor_visit_callback(visitor), children)
return iter(children)
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, Cursor)
# FIXME: There should just be an isNull method.
if res == Cursor_null():
return None
return res
## CIndex Objects ##
# CIndex objects (derived from ClangObject) are essentially lightweight
# wrappers attached to some underlying object, which is exposed via CIndex as
# a void*.
class ClangObject(object):
"""
A helper for Clang objects. This class helps act as an intermediary for
the ctypes library and the Clang CIndex library.
"""
def __init__(self, obj):
assert isinstance(obj, c_object_p) and obj
self.obj = self._as_parameter_ = obj
def from_param(self):
return self._as_parameter_
class _CXUnsavedFile(Structure):
"""Helper for passing unsaved file arguments."""
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
## Diagnostic Conversion ##
# Diagnostic objects are temporary, we must extract all the information from the
# diagnostic object when it is passed to the callback.
_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
_clang_getDiagnosticSeverity.argtypes = [c_object_p]
_clang_getDiagnosticSeverity.restype = c_int
_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
_clang_getDiagnosticLocation.argtypes = [c_object_p]
_clang_getDiagnosticLocation.restype = SourceLocation
_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
_clang_getDiagnosticSpelling.argtypes = [c_object_p]
_clang_getDiagnosticSpelling.restype = _CXString
_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
_clang_getDiagnosticNumRanges.argtypes = [c_object_p]
_clang_getDiagnosticNumRanges.restype = c_uint
_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
_clang_getDiagnosticRange.argtypes = [c_object_p, c_uint]
_clang_getDiagnosticRange.restype = SourceRange
_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
_clang_getDiagnosticNumFixIts.argtypes = [c_object_p]
_clang_getDiagnosticNumFixIts.restype = c_uint
_clang_getDiagnosticFixItKind = lib.clang_getDiagnosticFixItKind
_clang_getDiagnosticFixItKind.argtypes = [c_object_p, c_uint]
_clang_getDiagnosticFixItKind.restype = c_int
_clang_getDiagnosticFixItInsertion = lib.clang_getDiagnosticFixItInsertion
_clang_getDiagnosticFixItInsertion.argtypes = [c_object_p, c_uint,
POINTER(SourceLocation)]
_clang_getDiagnosticFixItInsertion.restype = _CXString
_clang_getDiagnosticFixItInsertion.errcheck = _CXString.from_result
_clang_getDiagnosticFixItRemoval = lib.clang_getDiagnosticFixItRemoval
_clang_getDiagnosticFixItRemoval.argtypes = [c_object_p, c_uint,
POINTER(SourceLocation)]
_clang_getDiagnosticFixItRemoval.restype = _CXString
_clang_getDiagnosticFixItRemoval.errcheck = _CXString.from_result
_clang_getDiagnosticFixItReplacement = lib.clang_getDiagnosticFixItReplacement
_clang_getDiagnosticFixItReplacement.argtypes = [c_object_p, c_uint,
POINTER(SourceRange)]
_clang_getDiagnosticFixItReplacement.restype = _CXString
_clang_getDiagnosticFixItReplacement.errcheck = _CXString.from_result
def _convert_fixit(diag_ptr, index):
# We normalize all the fix-its to a single representation, this is more
# convenient.
#
# FIXME: Push this back into API? It isn't exactly clear what the
# SourceRange semantics are, we should make sure we can represent an empty
# range.
kind = _clang_getDiagnosticFixItKind(diag_ptr, index)
range = None
value = None
if kind == 0: # insertion
location = SourceLocation()
value = _clang_getDiagnosticFixItInsertion(diag_ptr, index,
byref(location))
range = SourceRange.from_locations(location, location)
elif kind == 1: # removal
range = _clang_getDiagnosticFixItRemoval(diag_ptr, index)
value = ''
else: # replacement
assert kind == 2
range = SourceRange()
value = _clang_getDiagnosticFixItReplacement(diag_ptr, index,
byref(range))
return FixIt(range, value)
def _convert_diag(diag_ptr, diag_list):
severity = _clang_getDiagnosticSeverity(diag_ptr)
loc = _clang_getDiagnosticLocation(diag_ptr)
spelling = _clang_getDiagnosticSpelling(diag_ptr)
# Diagnostic ranges.
num_ranges = _clang_getDiagnosticNumRanges(diag_ptr)
ranges = [_clang_getDiagnosticRange(diag_ptr, i)
for i in range(num_ranges)]
fixits = [_convert_fixit(diag_ptr, i)
for i in range(_clang_getDiagnosticNumFixIts(diag_ptr))]
diag_list.append(Diagnostic(severity, loc, spelling, ranges, fixits))
###
class Index(ClangObject):
"""
The Index type provides the primary interface to the Clang CIndex library,
primarily by providing an interface for reading and parsing translation
units.
"""
@staticmethod
def create(excludeDecls=False):
"""
Create a new Index.
Parameters:
excludeDecls -- Exclude local declarations from translation units.
"""
return Index(Index_create(excludeDecls))
def __del__(self):
Index_dispose(self)
def read(self, path):
"""Load the translation unit from the given AST file."""
# FIXME: In theory, we could support streaming diagnostics. It's hard to
# integrate this into the API cleanly, however. Resolve.
diags = []
ptr = TranslationUnit_read(self, path,
Diagnostic_callback(_convert_diag), diags)
return TranslationUnit(ptr) if ptr else None
def parse(self, path, args = [], unsaved_files = []):
"""
Load the translation unit from the given source code file by running
clang and generating the AST before loading. Additional command line
parameters can be passed to clang via the args parameter.
In-memory contents for files can be provided by passing a list of pairs
to as unsaved_files, the first item should be the filenames to be mapped
and the second should be the contents to be substituted for the
file. The contents may be passed as strings or file objects.
"""
arg_array = 0
if len(args):
arg_array = (c_char_p * len(args))(* args)
unsaved_files_array = 0
if len(unsaved_files):
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
for i,(name,value) in enumerate(unsaved_files):
if not isinstance(value, str):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
print value
if not isinstance(value, str):
raise TypeError,'Unexpected unsaved file contents.'
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
# FIXME: In theory, we could support streaming diagnostics. It's hard to
# integrate this into the API cleanly, however. Resolve.
diags = []
ptr = TranslationUnit_parse(self, path, len(args), arg_array,
len(unsaved_files), unsaved_files_array,
Diagnostic_callback(_convert_diag), diags)
return TranslationUnit(ptr, diags) if ptr else None
class TranslationUnit(ClangObject):
"""
The TranslationUnit class represents a source code translation unit and
provides read-only access to its top-level declarations.
"""
def __init__(self, ptr, diagnostics):
ClangObject.__init__(self, ptr)
self.diagnostics = diagnostics
def __del__(self):
TranslationUnit_dispose(self)
@property
def cursor(self):
"""Retrieve the cursor that represents the given translation unit."""
return TranslationUnit_cursor(self)
@property
def spelling(self):
"""Get the original translation unit source file name."""
return TranslationUnit_spelling(self)
def get_includes(self):
"""
Return an iterable sequence of FileInclusion objects that describe the
sequence of inclusions in a translation unit. The first object in
this sequence is always the input file. Note that this method will not
recursively iterate over header files included through precompiled
headers.
"""
def visitor(fobj, lptr, depth, includes):
loc = lptr.contents
includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
# Automatically adapt CIndex/ctype pointers to python objects
includes = []
TranslationUnit_includes(self,
TranslationUnit_includes_callback(visitor),
includes)
return iter(includes)
class File(ClangObject):
"""
The File class represents a particular source file that is part of a
translation unit.
"""
@property
def name(self):
"""Return the complete file and path name of the file."""
return File_name(self)
@property
def time(self):
"""Return the last modification time of the file."""
return File_time(self)
class FileInclusion(object):
"""
The FileInclusion class represents the inclusion of one source file by
another via a '#include' directive or as the input file for the translation
unit. This class provides information about the included file, the including
file, the location of the '#include' directive and the depth of the included
file in the stack. Note that the input file has depth 0.
"""
def __init__(self, src, tgt, loc, depth):
self.source = src
self.include = tgt
self.location = loc
self.depth = depth
@property
def is_input_file(self):
"""True if the included file is the input file."""
return self.depth == 0
# Additional Functions and Types
# String Functions
_CXString_dispose = lib.clang_disposeString
_CXString_dispose.argtypes = [_CXString]
_CXString_getCString = lib.clang_getCString
_CXString_getCString.argtypes = [_CXString]
_CXString_getCString.restype = c_char_p
# Source Location Functions
SourceLocation_loc = lib.clang_getInstantiationLocation
SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
POINTER(c_uint), POINTER(c_uint),
POINTER(c_uint)]
# Source Range Functions
SourceRange_getRange = lib.clang_getRange
SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
SourceRange_getRange.restype = SourceRange
SourceRange_start = lib.clang_getRangeStart
SourceRange_start.argtypes = [SourceRange]
SourceRange_start.restype = SourceLocation
SourceRange_end = lib.clang_getRangeEnd
SourceRange_end.argtypes = [SourceRange]
SourceRange_end.restype = SourceLocation
# CursorKind Functions
CursorKind_is_decl = lib.clang_isDeclaration
CursorKind_is_decl.argtypes = [CursorKind]
CursorKind_is_decl.restype = bool
CursorKind_is_ref = lib.clang_isReference
CursorKind_is_ref.argtypes = [CursorKind]
CursorKind_is_ref.restype = bool
CursorKind_is_expr = lib.clang_isExpression
CursorKind_is_expr.argtypes = [CursorKind]
CursorKind_is_expr.restype = bool
CursorKind_is_stmt = lib.clang_isStatement
CursorKind_is_stmt.argtypes = [CursorKind]
CursorKind_is_stmt.restype = bool
CursorKind_is_inv = lib.clang_isInvalid
CursorKind_is_inv.argtypes = [CursorKind]
CursorKind_is_inv.restype = bool
# Cursor Functions
# TODO: Implement this function
Cursor_get = lib.clang_getCursor
Cursor_get.argtypes = [TranslationUnit, SourceLocation]
Cursor_get.restype = Cursor
Cursor_null = lib.clang_getNullCursor
Cursor_null.restype = Cursor
Cursor_usr = lib.clang_getCursorUSR
Cursor_usr.argtypes = [Cursor]
Cursor_usr.restype = _CXString
Cursor_usr.errcheck = _CXString.from_result
Cursor_is_def = lib.clang_isCursorDefinition
Cursor_is_def.argtypes = [Cursor]
Cursor_is_def.restype = bool
Cursor_def = lib.clang_getCursorDefinition
Cursor_def.argtypes = [Cursor]
Cursor_def.restype = Cursor
Cursor_def.errcheck = Cursor.from_result
Cursor_eq = lib.clang_equalCursors
Cursor_eq.argtypes = [Cursor, Cursor]
Cursor_eq.restype = c_uint
Cursor_spelling = lib.clang_getCursorSpelling
Cursor_spelling.argtypes = [Cursor]
Cursor_spelling.restype = _CXString
Cursor_spelling.errcheck = _CXString.from_result
Cursor_loc = lib.clang_getCursorLocation
Cursor_loc.argtypes = [Cursor]
Cursor_loc.restype = SourceLocation
Cursor_extent = lib.clang_getCursorExtent
Cursor_extent.argtypes = [Cursor]
Cursor_extent.restype = SourceRange
Cursor_ref = lib.clang_getCursorReferenced
Cursor_ref.argtypes = [Cursor]
Cursor_ref.restype = Cursor
Cursor_ref.errcheck = Cursor.from_result
Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
Cursor_visit = lib.clang_visitChildren
Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
Cursor_visit.restype = c_uint
# Index Functions
Index_create = lib.clang_createIndex
Index_create.argtypes = [c_int]
Index_create.restype = c_object_p
Index_dispose = lib.clang_disposeIndex
Index_dispose.argtypes = [Index]
# Translation Unit Functions
Diagnostic_callback = CFUNCTYPE(None, c_object_p, py_object)
TranslationUnit_read = lib.clang_createTranslationUnit
TranslationUnit_read.argtypes = [Index, c_char_p,
Diagnostic_callback, py_object]
TranslationUnit_read.restype = c_object_p
TranslationUnit_parse = lib.clang_createTranslationUnitFromSourceFile
TranslationUnit_parse.argtypes = [Index, c_char_p, c_int, c_void_p,
c_int, c_void_p,
Diagnostic_callback, py_object]
TranslationUnit_parse.restype = c_object_p
TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
TranslationUnit_cursor.argtypes = [TranslationUnit]
TranslationUnit_cursor.restype = Cursor
TranslationUnit_cursor.errcheck = Cursor.from_result
TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
TranslationUnit_spelling.argtypes = [TranslationUnit]
TranslationUnit_spelling.restype = _CXString
TranslationUnit_spelling.errcheck = _CXString.from_result
TranslationUnit_dispose = lib.clang_disposeTranslationUnit
TranslationUnit_dispose.argtypes = [TranslationUnit]
TranslationUnit_includes_callback = CFUNCTYPE(None,
c_object_p,
POINTER(SourceLocation),
c_uint, py_object)
TranslationUnit_includes = lib.clang_getInclusions
TranslationUnit_includes.argtypes = [TranslationUnit,
TranslationUnit_includes_callback,
py_object]
# File Functions
File_name = lib.clang_getFileName
File_name.argtypes = [File]
File_name.restype = c_char_p
File_time = lib.clang_getFileTime
File_time.argtypes = [File]
File_time.restype = c_uint
###
__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
'Diagnostic', 'FixIt', 'SourceRange', 'SourceLocation', 'File']

View File

@ -0,0 +1,87 @@
#!/usr/bin/env python
#===- cindex-dump.py - cindex/Python Source Dump -------------*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
"""
A simple command line tool for dumping a source file using the Clang Index
Library.
"""
def get_diag_info(diag):
return { 'severity' : diag.severity,
'location' : diag.location,
'spelling' : diag.spelling,
'ranges' : diag.ranges,
'fixits' : diag.fixits }
def get_cursor_id(cursor, cursor_list = []):
if not opts.showIDs:
return None
if cursor is None:
return None
# FIXME: This is really slow. It would be nice if the index API exposed
# something that let us hash cursors.
for i,c in enumerate(cursor_list):
if cursor == c:
return i
cursor_list.append(cursor)
return len(cursor_list) - 1
def get_info(node, depth=0):
if opts.maxDepth is not None and depth >= opts.maxDepth:
children = None
else:
children = [get_info(c, depth+1)
for c in node.get_children()]
return { 'id' : get_cursor_id(node),
'kind' : node.kind,
'usr' : node.get_usr(),
'spelling' : node.spelling,
'location' : node.location,
'extent.start' : node.extent.start,
'extent.end' : node.extent.end,
'is_definition' : node.is_definition(),
'definition id' : get_cursor_id(node.get_definition()),
'children' : children }
def main():
from clang.cindex import Index
from pprint import pprint
from optparse import OptionParser, OptionGroup
global opts
parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
parser.add_option("", "--show-ids", dest="showIDs",
help="Don't compute cursor IDs (very slow)",
default=False)
parser.add_option("", "--max-depth", dest="maxDepth",
help="Limit cursor expansion to depth N",
metavar="N", type=int, default=None)
parser.disable_interspersed_args()
(opts, args) = parser.parse_args()
if len(args) == 0:
parser.error('invalid number arguments')
index = Index.create()
tu = index.parse(None, args)
if not tu:
parser.error("unable to load input")
pprint(('diags', map(get_diag_info, tu.diagnostics)))
pprint(('nodes', get_info(tu.cursor)))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,58 @@
#!/usr/bin/env python
#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
"""
A simple command line tool for dumping a Graphviz description (dot) that
describes include dependencies.
"""
def main():
import sys
from clang.cindex import Index
from optparse import OptionParser, OptionGroup
parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
parser.disable_interspersed_args()
(opts, args) = parser.parse_args()
if len(args) == 0:
parser.error('invalid number arguments')
# FIXME: Add an output file option
out = sys.stdout
index = Index.create()
tu = index.parse(None, args)
if not tu:
parser.error("unable to load input")
# A helper function for generating the node name.
def name(f):
if f:
return "\"" + f.name + "\""
# Generate the include graph
out.write("digraph G {\n")
for i in tu.get_includes():
line = " ";
if i.is_input_file:
# Always write the input file as a node just in case it doesn't
# actually include anything. This would generate a 1 node graph.
line += name(i.include)
else:
line += '%s->%s' % (name(i.source), name(i.include))
line += "\n";
out.write(line)
out.write("}\n")
if __name__ == '__main__':
main()

View File

View File

@ -0,0 +1,6 @@
#ifndef HEADER1
#define HEADER1
#include "header3.h"
#endif

View File

@ -0,0 +1,6 @@
#ifndef HEADER2
#define HEADER2
#include "header3.h"
#endif

View File

@ -0,0 +1,3 @@
// Not a guarded header!
void f();

View File

@ -0,0 +1,6 @@
#include "stdio.h"
int main(int argc, char* argv[]) {
printf("hello world\n");
return 0;
}

View File

@ -0,0 +1,5 @@
#include "header1.h"
#include "header2.h"
#include "header1.h"
int main() { }

View File

@ -0,0 +1,2 @@
int DECL_ONE = 1;
int DECL_TWO = 2;

View File

View File

@ -0,0 +1,59 @@
from clang.cindex import Index, CursorKind
kInput = """\
// FIXME: Find nicer way to drop builtins and other cruft.
int start_decl;
struct s0 {
int a;
int b;
};
struct s1;
void f0(int a0, int a1) {
int l0, l1;
if (a0)
return;
for (;;) {
break;
}
}
"""
def test_get_children():
index = Index.create()
tu = index.parse('t.c', unsaved_files = [('t.c',kInput)])
# Skip until past start_decl.
it = tu.cursor.get_children()
while it.next().spelling != 'start_decl':
pass
tu_nodes = list(it)
assert len(tu_nodes) == 3
assert tu_nodes[0].kind == CursorKind.STRUCT_DECL
assert tu_nodes[0].spelling == 's0'
assert tu_nodes[0].is_definition() == True
assert tu_nodes[0].location.file.name == 't.c'
assert tu_nodes[0].location.line == 4
assert tu_nodes[0].location.column == 8
s0_nodes = list(tu_nodes[0].get_children())
assert len(s0_nodes) == 2
assert s0_nodes[0].kind == CursorKind.FIELD_DECL
assert s0_nodes[0].spelling == 'a'
assert s0_nodes[1].kind == CursorKind.FIELD_DECL
assert s0_nodes[1].spelling == 'b'
assert tu_nodes[1].kind == CursorKind.STRUCT_DECL
assert tu_nodes[1].spelling == 's1'
assert tu_nodes[1].is_definition() == False
assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL
assert tu_nodes[2].spelling == 'f0'
assert tu_nodes[2].is_definition() == True

View File

@ -0,0 +1,27 @@
from clang.cindex import CursorKind
def test_name():
assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL'
def test_get_all_kinds():
assert CursorKind.UNEXPOSED_DECL in CursorKind.get_all_kinds()
assert CursorKind.TRANSLATION_UNIT in CursorKind.get_all_kinds()
def test_kind_groups():
"""Check that every kind classifies to exactly one group."""
assert CursorKind.UNEXPOSED_DECL.is_declaration()
assert CursorKind.TYPE_REF.is_reference()
assert CursorKind.DECL_REF_EXPR.is_expression()
assert CursorKind.UNEXPOSED_STMT.is_statement()
assert CursorKind.INVALID_FILE.is_invalid()
for k in CursorKind.get_all_kinds():
group = [n for n in ('is_declaration', 'is_reference', 'is_expression',
'is_statement', 'is_invalid')
if getattr(k, n)()]
if k == CursorKind.TRANSLATION_UNIT:
assert len(group) == 0
else:
assert len(group) == 1

View File

@ -0,0 +1,48 @@
from clang.cindex import *
def tu_from_source(source):
index = Index.create()
tu = index.parse('INPUT.c', unsaved_files = [('INPUT.c', source)])
# FIXME: Remove the need for this.
tu.index = index
return tu
# FIXME: We need support for invalid translation units to test better.
def test_diagnostic_warning():
tu = tu_from_source("""int f0() {}\n""")
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 1
assert tu.diagnostics[0].location.column == 11
assert (tu.diagnostics[0].spelling ==
'control reaches end of non-void function')
def test_diagnostic_note():
# FIXME: We aren't getting notes here for some reason.
index = Index.create()
tu = tu_from_source("""#define A x\nvoid *A = 1;\n""")
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 2
assert tu.diagnostics[0].location.column == 7
assert 'incompatible' in tu.diagnostics[0].spelling
# assert tu.diagnostics[1].severity == Diagnostic.Note
# assert tu.diagnostics[1].location.line == 1
# assert tu.diagnostics[1].location.column == 11
# assert tu.diagnostics[1].spelling == 'instantiated from'
def test_diagnostic_fixit():
index = Index.create()
tu = tu_from_source("""struct { int f0; } x = { f0 : 1 };""")
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 1
assert tu.diagnostics[0].location.column == 31
assert tu.diagnostics[0].spelling.startswith('use of GNU old-style')
assert len(tu.diagnostics[0].fixits) == 1
assert tu.diagnostics[0].fixits[0].range.start.line == 1
assert tu.diagnostics[0].fixits[0].range.start.column == 26
assert tu.diagnostics[0].fixits[0].range.end.line == 1
assert tu.diagnostics[0].fixits[0].range.end.column == 30
assert tu.diagnostics[0].fixits[0].value == '.f0 = '

View File

@ -0,0 +1,15 @@
from clang.cindex import *
import os
kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
def test_create():
index = Index.create()
# FIXME: test Index.read
def test_parse():
index = Index.create()
assert isinstance(index, Index)
tu = index.parse(os.path.join(kInputsDir, 'hello.cpp'))
assert isinstance(tu, TranslationUnit)

View File

@ -0,0 +1,73 @@
from clang.cindex import *
import os
kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')
def test_spelling():
path = os.path.join(kInputsDir, 'hello.cpp')
index = Index.create()
tu = index.parse(path)
assert tu.spelling == path
def test_cursor():
path = os.path.join(kInputsDir, 'hello.cpp')
index = Index.create()
tu = index.parse(path)
c = tu.cursor
assert isinstance(c, Cursor)
assert c.kind is CursorKind.TRANSLATION_UNIT
def test_parse_arguments():
path = os.path.join(kInputsDir, 'parse_arguments.c')
index = Index.create()
tu = index.parse(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
spellings = [c.spelling for c in tu.cursor.get_children()]
assert spellings[-2] == 'hello'
assert spellings[-1] == 'hi'
def test_unsaved_files():
index = Index.create()
# FIXME: Why can't we just use "fake.h" here (instead of /tmp/fake.h)?
tu = index.parse('fake.c', unsaved_files = [
('fake.c', """
#include "/tmp/fake.h"
int x;
int SOME_DEFINE;
"""),
('/tmp/fake.h', """
#define SOME_DEFINE y
""")
])
spellings = [c.spelling for c in tu.cursor.get_children()]
assert spellings[-2] == 'x'
assert spellings[-1] == 'y'
def test_unsaved_files_2():
import StringIO
index = Index.create()
tu = index.parse('fake.c', unsaved_files = [
('fake.c', StringIO.StringIO('int x;'))])
spellings = [c.spelling for c in tu.cursor.get_children()]
assert spellings[-1] == 'x'
def test_includes():
def eq(expected, actual):
if not actual.is_input_file:
return expected[0] == actual.source.name and \
expected[1] == actual.include.name
else:
return expected[1] == actual.include.name
src = os.path.join(kInputsDir, 'include.cpp')
h1 = os.path.join(kInputsDir, "header1.h")
h2 = os.path.join(kInputsDir, "header2.h")
h3 = os.path.join(kInputsDir, "header3.h")
inc = [(None, src), (src, h1), (h1, h3), (src, h2), (h2, h3)]
index = Index.create()
tu = index.parse(src)
for i in zip(inc, tu.get_includes()):
assert eq(i[0], i[1])

View File

@ -33,6 +33,12 @@
1A4C41BF105B4C0B0047B5E7 /* CGClass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4C41BE105B4C0B0047B5E7 /* CGClass.cpp */; };
1A535ED9107BC45E000C3AE7 /* CXXInheritance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A535ED8107BC45E000C3AE7 /* CXXInheritance.cpp */; };
1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5E570E5E81010023C059 /* CGCXX.cpp */; };
1A621BB7110FE6AA009E6834 /* TargetInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */; };
1A621C4211111D61009E6834 /* CIndexCodeCompletion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */; };
1A621C4311111D61009E6834 /* CIndexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3B11111D61009E6834 /* CIndexer.cpp */; };
1A621C4411111D61009E6834 /* CIndexInclusionStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */; };
1A621C4511111D61009E6834 /* CIndexUSRs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */; };
1A621C4611111D61009E6834 /* CXCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A621C3F11111D61009E6834 /* CXCursor.cpp */; };
1A6B6CD410693FC900BB4A8F /* CodeCompleteConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */; };
1A6B6CD510693FC900BB4A8F /* SemaCodeComplete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */; };
1A6B6E9A1069833600BB4A8F /* CGExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6E991069833600BB4A8F /* CGExprCXX.cpp */; };
@ -62,7 +68,6 @@
1ADD795610A90C6100741BBA /* TemplateBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADD795310A90C6100741BBA /* TemplateBase.cpp */; };
1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */; };
1AE4EE3E103B89ED00888A23 /* StmtProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */; };
1AE4EE40103B8A0A00888A23 /* TargetABIInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */; };
1AF1B50F109A4FB800AFAFAC /* CGException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF1B50E109A4FB800AFAFAC /* CGException.cpp */; };
1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */; };
3507E4C20E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3507E4C10E27FE2D00FB7B57 /* CheckObjCInstMethSignature.cpp */; };
@ -382,6 +387,16 @@
1A535ED8107BC45E000C3AE7 /* CXXInheritance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXXInheritance.cpp; path = lib/AST/CXXInheritance.cpp; sourceTree = "<group>"; };
1A535EDB107BC47B000C3AE7 /* CanonicalType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CanonicalType.h; path = clang/AST/CanonicalType.h; sourceTree = "<group>"; };
1A5D5E570E5E81010023C059 /* CGCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXX.cpp; path = lib/CodeGen/CGCXX.cpp; sourceTree = "<group>"; tabWidth = 2; };
1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TargetInfo.cpp; path = lib/CodeGen/TargetInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
1A621BB6110FE6AA009E6834 /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TargetInfo.h; path = lib/CodeGen/TargetInfo.h; sourceTree = "<group>"; tabWidth = 2; };
1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexCodeCompletion.cpp; path = tools/CIndex/CIndexCodeCompletion.cpp; sourceTree = "<group>"; };
1A621C3B11111D61009E6834 /* CIndexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexer.cpp; path = tools/CIndex/CIndexer.cpp; sourceTree = "<group>"; };
1A621C3C11111D61009E6834 /* CIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CIndexer.h; path = tools/CIndex/CIndexer.h; sourceTree = "<group>"; };
1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexInclusionStack.cpp; path = tools/CIndex/CIndexInclusionStack.cpp; sourceTree = "<group>"; };
1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndexUSRs.cpp; path = tools/CIndex/CIndexUSRs.cpp; sourceTree = "<group>"; };
1A621C3F11111D61009E6834 /* CXCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXCursor.cpp; path = tools/CIndex/CXCursor.cpp; sourceTree = "<group>"; };
1A621C4011111D61009E6834 /* CXCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXCursor.h; path = tools/CIndex/CXCursor.h; sourceTree = "<group>"; };
1A621C4111111D61009E6834 /* CXSourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXSourceLocation.h; path = tools/CIndex/CXSourceLocation.h; sourceTree = "<group>"; };
1A649E1D0F9599D9005B965E /* CGBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGBlocks.h; path = lib/CodeGen/CGBlocks.h; sourceTree = "<group>"; };
1A649E1E0F9599DA005B965E /* CGCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGCXX.h; path = lib/CodeGen/CGCXX.h; sourceTree = "<group>"; tabWidth = 2; };
1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeCompleteConsumer.cpp; path = lib/Sema/CodeCompleteConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
@ -428,7 +443,6 @@
1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaTemplateInstantiateDecl.cpp; path = lib/Sema/SemaTemplateInstantiateDecl.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AE4EE3B103B89CA00888A23 /* TreeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = TreeTransform.h; path = lib/Sema/TreeTransform.h; sourceTree = "<group>"; tabWidth = 2; };
1AE4EE3D103B89ED00888A23 /* StmtProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = StmtProfile.cpp; path = lib/AST/StmtProfile.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = TargetABIInfo.cpp; path = lib/CodeGen/TargetABIInfo.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AF1B50E109A4FB800AFAFAC /* CGException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGException.cpp; path = lib/CodeGen/CGException.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AFF8AE11012BFC900D248DA /* CGRecordLayoutBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGRecordLayoutBuilder.cpp; path = lib/CodeGen/CGRecordLayoutBuilder.cpp; sourceTree = "<group>"; tabWidth = 2; };
1AFF8AE21012BFC900D248DA /* CGRecordLayoutBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGRecordLayoutBuilder.h; path = lib/CodeGen/CGRecordLayoutBuilder.h; sourceTree = "<group>"; tabWidth = 2; };
@ -543,7 +557,6 @@
9012911510470FCE0083456D /* Index.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Index.h; path = "clang-c/Index.h"; sourceTree = "<group>"; };
9012911C1048068D0083456D /* ASTUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTUnit.cpp; path = lib/Frontend/ASTUnit.cpp; sourceTree = "<group>"; };
9012911F104812F90083456D /* CIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndex.cpp; path = tools/CIndex/CIndex.cpp; sourceTree = "<group>"; };
90129120104812F90083456D /* CIndex.exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CIndex.exports; path = tools/CIndex/CIndex.exports; sourceTree = "<group>"; };
904753791096376F00CBDDDD /* CXXInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CXXInheritance.h; path = clang/AST/CXXInheritance.h; sourceTree = "<group>"; };
9047537A1096376F00CBDDDD /* Redeclarable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Redeclarable.h; path = clang/AST/Redeclarable.h; sourceTree = "<group>"; };
9047537B1096376F00CBDDDD /* TypeLoc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TypeLoc.h; path = clang/AST/TypeLoc.h; sourceTree = "<group>"; };
@ -727,7 +740,7 @@
DECB6F060F9D93A800F5FBC7 /* InitPreprocessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InitPreprocessor.cpp; path = lib/Frontend/InitPreprocessor.cpp; sourceTree = "<group>"; };
DECB734E0FA3ED8400F5FBC7 /* StmtObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtObjC.h; path = clang/AST/StmtObjC.h; sourceTree = "<group>"; };
DECB73550FA3EE5A00F5FBC7 /* StmtCXX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StmtCXX.h; path = clang/AST/StmtCXX.h; sourceTree = "<group>"; };
DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderStmt.cpp; path = lib/Frontend/PCHReaderStmt.cpp; sourceTree = "<group>"; };
DECB77120FA5752300F5FBC7 /* PCHReaderStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderStmt.cpp; path = lib/Frontend/PCHReaderStmt.cpp; sourceTree = "<group>"; tabWidth = 2; };
DECB77780FA579B000F5FBC7 /* PCHReaderDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHReaderDecl.cpp; path = lib/Frontend/PCHReaderDecl.cpp; sourceTree = "<group>"; };
DECB77F60FA5850200F5FBC7 /* PCHWriterDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterDecl.cpp; path = lib/Frontend/PCHWriterDecl.cpp; sourceTree = "<group>"; };
DECB78160FA5882F00F5FBC7 /* PCHWriterStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PCHWriterStmt.cpp; path = lib/Frontend/PCHWriterStmt.cpp; sourceTree = "<group>"; };
@ -1037,6 +1050,7 @@
356EF9B30C8F7DCA006650F5 /* Analysis */ = {
isa = PBXGroup;
children = (
DE67E70A0C020EC500F66BC5 /* SemaType.cpp */,
35544B840F5C7F9D00D92AA9 /* Path-Sensitive */,
3507E4CC0E27FEB900FB7B57 /* Flow-Sensitive Analyses */,
3507E4C30E27FE3800FB7B57 /* Checks */,
@ -1093,7 +1107,14 @@
isa = PBXGroup;
children = (
9012911F104812F90083456D /* CIndex.cpp */,
90129120104812F90083456D /* CIndex.exports */,
1A621C3B11111D61009E6834 /* CIndexer.cpp */,
1A621C3A11111D61009E6834 /* CIndexCodeCompletion.cpp */,
1A621C3C11111D61009E6834 /* CIndexer.h */,
1A621C3D11111D61009E6834 /* CIndexInclusionStack.cpp */,
1A621C3E11111D61009E6834 /* CIndexUSRs.cpp */,
1A621C3F11111D61009E6834 /* CXCursor.cpp */,
1A621C4011111D61009E6834 /* CXCursor.h */,
1A621C4111111D61009E6834 /* CXSourceLocation.h */,
);
name = CIndex;
sourceTree = "<group>";
@ -1265,7 +1286,6 @@
BDF87CF60FD746F300BBF872 /* SemaTemplateDeduction.cpp */,
35544B8B0F5C803200D92AA9 /* SemaTemplateInstantiate.cpp */,
1ADF47AE0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp */,
DE67E70A0C020EC500F66BC5 /* SemaType.cpp */,
1AE4EE3B103B89CA00888A23 /* TreeTransform.h */,
);
name = Sema;
@ -1330,7 +1350,8 @@
1A2193CC0F45EEB700C0713D /* Mangle.cpp */,
1A2193CD0F45EEB700C0713D /* Mangle.h */,
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
1AE4EE3F103B8A0A00888A23 /* TargetABIInfo.cpp */,
1A621BB5110FE6AA009E6834 /* TargetInfo.cpp */,
1A621BB6110FE6AA009E6834 /* TargetInfo.h */,
);
name = CodeGen;
sourceTree = "<group>";
@ -1927,7 +1948,6 @@
1AA1D91810125DE30078DEBC /* RecordLayoutBuilder.cpp in Sources */,
1AFF8AE31012BFC900D248DA /* CGRecordLayoutBuilder.cpp in Sources */,
1AE4EE3E103B89ED00888A23 /* StmtProfile.cpp in Sources */,
1AE4EE40103B8A0A00888A23 /* TargetABIInfo.cpp in Sources */,
90FD6D7B103C3D49005F5B73 /* Analyzer.cpp in Sources */,
90FD6D7C103C3D49005F5B73 /* ASTLocation.cpp in Sources */,
90FD6D7D103C3D49005F5B73 /* DeclReferenceMap.cpp in Sources */,
@ -1967,6 +1987,12 @@
1ACB57EB1105820D0047B991 /* TypeXML.cpp in Sources */,
1ACB57EC1105820D0047B991 /* VerifyDiagnosticsClient.cpp in Sources */,
1A97825B1108BA18002B98FC /* CGVTT.cpp in Sources */,
1A621BB7110FE6AA009E6834 /* TargetInfo.cpp in Sources */,
1A621C4211111D61009E6834 /* CIndexCodeCompletion.cpp in Sources */,
1A621C4311111D61009E6834 /* CIndexer.cpp in Sources */,
1A621C4411111D61009E6834 /* CIndexInclusionStack.cpp in Sources */,
1A621C4511111D61009E6834 /* CIndexUSRs.cpp in Sources */,
1A621C4611111D61009E6834 /* CXCursor.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -205,12 +205,28 @@ is used in the file argument.</p>
<h2 id="vectors">Vectors and Extended Vectors</h2>
<!-- ======================================================================= -->
<p>Supports the GCC vector extensions, plus some stuff like V[1]. ext_vector
with V.xyzw syntax and other tidbits. See also <a
href="#__builtin_shufflevector">__builtin_shufflevector</a>.</p>
<p>Supports the GCC vector extensions, plus some stuff like V[1].</p>
<p>Also supports <tt>ext_vector</tt>, which additionally support for V.xyzw
syntax and other tidbits as seen in OpenCL. An example is:</p>
<blockquote>
<pre>
typedef float float4 <b>__attribute__((ext_vector_type(4)))</b>;
typedef float float2 <b>__attribute__((ext_vector_type(2)))</b>;
float4 foo(float2 a, float2 b) {
float4 c;
c.xz = a;
c.yw = b;
return c;
}
</blockquote>
<p>Query for this feature with __has_feature(attribute_ext_vector_type).</p>
<p>See also <a href="#__builtin_shufflevector">__builtin_shufflevector</a>.</p>
<!-- ======================================================================= -->
<h2 id="checking_language_features">Checks for Standard Language Features</h2>
<!-- ======================================================================= -->

View File

@ -789,14 +789,12 @@ definition.</li>
<h2 id="cxx">C++ Language Features</h2>
<!-- ======================================================================= -->
<p>At this point, Clang C++ is not generally useful. However, Clang C++ support
<p>At this point, Clang C++ is not production-quality and is not recommended for use beyond experimentation. However, Clang C++ support
is under active development and is progressing rapidly. Please see the <a
href="http://clang.llvm.org/cxx_status.html">C++ Status</a> page for details or
ask on the mailing list about how you can help.</p>
<p>Note that the clang driver will refuse to even try to use clang to compile
C++ code unless you pass the <tt>-ccc-clang-cxx</tt> option to the driver. If
you really want to play with Clang's C++ support, please pass that flag. </p>
<p>Note that released Clang compilers will refuse to even try to use clang to compile C++ code unless you pass the <tt>-ccc-clang-cxx</tt> option to the driver. To turn on Clang's C++ support, please pass that flag. Clang compilers built from the Subversion trunk enable C++ support by default, and do not require the <tt>-ccc-clang-cxx</tt> flag.</p>
<!-- ======================================================================= -->
<h2 id="objcxx">Objective C++ Language Features</h2>

View File

@ -11,7 +11,6 @@ LEVEL = ../../../..
LIBRARYNAME = PrintFunctionNames
CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
CXXFLAGS = -fno-rtti
# Include this here so we can get the configuration of the targets that have
# been configured for construction. We have to do this early so we can set up

View File

@ -2,7 +2,6 @@ LEVEL = ../../../..
TOOLNAME = clang-wpa
CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
CXXFLAGS = -fno-rtti
NO_INSTALL = 1
# No plugins, optimize startup time.

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include <vector>
@ -46,6 +47,7 @@ namespace clang {
class SourceManager;
class TargetInfo;
// Decls
class DeclContext;
class CXXMethodDecl;
class CXXRecordDecl;
class Decl;
@ -502,7 +504,8 @@ class ASTContext {
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts);
QualType getVectorType(QualType VectorType, unsigned NumElts,
bool AltiVec, bool IsPixel);
/// getExtVectorType - Return the unique reference to an extended vector type
/// of the specified element type and size. VectorType must be a built-in
@ -534,11 +537,11 @@ class ASTContext {
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
QualType getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl=0);
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl* PrevDecl=0);
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType getTypedefType(TypedefDecl *Decl);
QualType getTypedefType(const TypedefDecl *Decl);
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
QualType Replacement);
@ -835,13 +838,23 @@ class ASTContext {
return getTypeInfo(T).second;
}
/// getTypeAlignInChars - Return the ABI-specified alignment of a type, in
/// characters. This method does not work on incomplete types.
CharUnits getTypeAlignInChars(QualType T);
CharUnits getTypeAlignInChars(const Type *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
/// a data type.
unsigned getPreferredTypeAlign(const Type *T);
unsigned getDeclAlignInBytes(const Decl *D, bool RefAsPointee = false);
/// getDeclAlign - Return a conservative estimate of the alignment of
/// the specified decl. Note that bitfields do not have a valid alignment, so
/// this method will assert on them.
/// If @p RefAsPointee, references are treated like their underlying type
/// (for alignof), else they're treated like pointers (for CodeGen).
CharUnits getDeclAlign(const Decl *D, bool RefAsPointee = false);
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
@ -878,7 +891,7 @@ class ASTContext {
unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI);
unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD);
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols);
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
//===--------------------------------------------------------------------===//
// Type Operators
@ -960,6 +973,20 @@ class ASTContext {
NestedNameSpecifier *
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS);
/// \brief Retrieves the canonical representation of the given
/// calling convention.
CallingConv getCanonicalCallConv(CallingConv CC) {
if (CC == CC_C)
return CC_Default;
return CC;
}
/// \brief Determines whether two calling conventions name the same
/// calling convention.
bool isSameCallConv(CallingConv lcc, CallingConv rcc) {
return (getCanonicalCallConv(lcc) == getCanonicalCallConv(rcc));
}
/// \brief Retrieves the "canonical" template name that refers to a
/// given template.
///
@ -1187,6 +1214,15 @@ class ASTContext {
const ASTRecordLayout &getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
private:
// 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.
std::vector<void*> SDMs;
friend class DeclContext;
void *CreateStoredDeclsMap();
void ReleaseDeclContextMaps();
};
/// @brief Utility function for constructing a nullary selector.

View File

@ -1,4 +1,4 @@
//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===//
//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -22,6 +22,26 @@ namespace clang {
NUM_BUILTIN_AST_DIAGNOSTICS
};
} // end namespace diag
/// \brief Diagnostic argument formatting function for diagnostics that
/// involve AST nodes.
///
/// This function formats diagnostic arguments for various AST nodes,
/// including types, declaration names, nested name specifiers, and
/// declaration contexts, into strings that can be printed as part of
/// diagnostics. It is meant to be used as the argument to
/// \c Diagnostic::SetArgToStringFn(), where the cookie is an \c ASTContext
/// pointer.
void FormatASTNodeDiagnosticArgument(Diagnostic::ArgumentKind Kind,
intptr_t Val,
const char *Modifier,
unsigned ModLen,
const char *Argument,
unsigned ArgLen,
const Diagnostic::ArgumentValue *PrevArgs,
unsigned NumPrevArgs,
llvm::SmallVectorImpl<char> &Output,
void *Cookie);
} // end namespace clang
#endif

View File

@ -0,0 +1,234 @@
//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- 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 ASTImporter class which imports AST nodes from one
// context into another context.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
#include "clang/AST/Type.h"
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
namespace clang {
class ASTContext;
class Decl;
class DeclContext;
class Diagnostic;
class Expr;
class FileManager;
class IdentifierInfo;
class NestedNameSpecifier;
class Stmt;
class TypeSourceInfo;
/// \brief Imports selected nodes from one AST context into another context,
/// merging AST nodes where appropriate.
class ASTImporter {
public:
typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
private:
/// \brief The contexts we're importing to and from.
ASTContext &ToContext, &FromContext;
/// \brief The file managers we're importing to and from.
FileManager &ToFileManager, &FromFileManager;
/// \brief The diagnostics object that we should use to emit diagnostics.
Diagnostic &Diags;
/// \brief Mapping from the already-imported types in the "from" context
/// to the corresponding types in the "to" context.
llvm::DenseMap<Type *, Type *> ImportedTypes;
/// \brief Mapping from the already-imported declarations in the "from"
/// context to the corresponding declarations in the "to" context.
llvm::DenseMap<Decl *, Decl *> ImportedDecls;
/// \brief Mapping from the already-imported statements in the "from"
/// context to the corresponding statements in the "to" context.
llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
/// \brief Mapping from the already-imported FileIDs in the "from" source
/// manager to the corresponding FileIDs in the "to" source manager.
llvm::DenseMap<unsigned, FileID> ImportedFileIDs;
/// \brief Imported, anonymous tag declarations that are missing their
/// corresponding typedefs.
llvm::SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
/// \brief Declaration (from, to) pairs that are known not to be equivalent
/// (which we have already complained about).
NonEquivalentDeclSet NonEquivalentDecls;
public:
ASTImporter(Diagnostic &Diags,
ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager);
virtual ~ASTImporter();
/// \brief Import the given type from the "from" context into the "to"
/// context.
///
/// \returns the equivalent type in the "to" context, or a NULL type if
/// an error occurred.
QualType Import(QualType FromT);
/// \brief Import the given type source information from the
/// "from" context into the "to" context.
///
/// \returns the equivalent type source information in the "to"
/// context, or NULL if an error occurred.
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
/// \brief Import the given declaration from the "from" context into the
/// "to" context.
///
/// \returns the equivalent declaration in the "to" context, or a NULL type
/// if an error occurred.
Decl *Import(Decl *FromD);
/// \brief Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
/// \returns the equivalent declaration context in the "to"
/// context, or a NULL type if an error occurred.
DeclContext *ImportContext(DeclContext *FromDC);
/// \brief Import the given expression from the "from" context into the
/// "to" context.
///
/// \returns the equivalent expression in the "to" context, or NULL if
/// an error occurred.
Expr *Import(Expr *FromE);
/// \brief Import the given statement from the "from" context into the
/// "to" context.
///
/// \returns the equivalent statement in the "to" context, or NULL if
/// an error occurred.
Stmt *Import(Stmt *FromS);
/// \brief Import the given nested-name-specifier from the "from"
/// context into the "to" context.
///
/// \returns the equivalent nested-name-specifier in the "to"
/// context, or NULL if an error occurred.
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
/// \brief Import the given source location from the "from" context into
/// the "to" context.
///
/// \returns the equivalent source location in the "to" context, or an
/// invalid source location if an error occurred.
SourceLocation Import(SourceLocation FromLoc);
/// \brief Import the given source range from the "from" context into
/// the "to" context.
///
/// \returns the equivalent source range in the "to" context, or an
/// invalid source location if an error occurred.
SourceRange Import(SourceRange FromRange);
/// \brief Import the given declaration name from the "from"
/// context into the "to" context.
///
/// \returns the equivalent declaration name in the "to" context,
/// or an empty declaration name if an error occurred.
DeclarationName Import(DeclarationName FromName);
/// \brief Import the given identifier from the "from" context
/// into the "to" context.
///
/// \returns the equivalent identifier in the "to" context.
IdentifierInfo *Import(IdentifierInfo *FromId);
/// \brief Import the given file ID from the "from" context into the
/// "to" context.
///
/// \returns the equivalent file ID in the source manager of the "to"
/// context.
FileID Import(FileID);
/// \brief Cope with a name conflict when importing a declaration into the
/// given context.
///
/// This routine is invoked whenever there is a name conflict while
/// importing a declaration. The returned name will become the name of the
/// imported declaration. By default, the returned name is the same as the
/// original name, leaving the conflict unresolve such that name lookup
/// for this name is likely to find an ambiguity later.
///
/// Subclasses may override this routine to resolve the conflict, e.g., by
/// renaming the declaration being imported.
///
/// \param Name the name of the declaration being imported, which conflicts
/// with other declarations.
///
/// \param DC the declaration context (in the "to" AST context) in which
/// the name is being imported.
///
/// \param IDNS the identifier namespace in which the name will be found.
///
/// \param Decls the set of declarations with the same name as the
/// declaration being imported.
///
/// \param NumDecls the number of conflicting declarations in \p Decls.
///
/// \returns the name that the newly-imported declaration should have.
virtual DeclarationName HandleNameConflict(DeclarationName Name,
DeclContext *DC,
unsigned IDNS,
NamedDecl **Decls,
unsigned NumDecls);
/// \brief Retrieve the context that AST nodes are being imported into.
ASTContext &getToContext() const { return ToContext; }
/// \brief Retrieve the context that AST nodes are being imported from.
ASTContext &getFromContext() const { return FromContext; }
/// \brief Retrieve the file manager that AST nodes are being imported into.
FileManager &getToFileManager() const { return ToFileManager; }
/// \brief Retrieve the file manager that AST nodes are being imported from.
FileManager &getFromFileManager() const { return FromFileManager; }
/// \brief Retrieve the diagnostic formatter.
Diagnostic &getDiags() const { return Diags; }
/// \brief Report a diagnostic in the "to" context.
DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
/// \brief Report a diagnostic in the "from" context.
DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
/// \brief Return the set of declarations that we know are not equivalent.
NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
/// \brief Note that we have imported the "from" declaration by mapping it
/// to the (potentially-newly-created) "to" declaration.
///
/// \returns \p To
Decl *Imported(Decl *From, Decl *To);
/// \brief Determine whether the given types are structurally
/// equivalent.
bool IsStructurallyEquivalent(QualType From, QualType To);
};
}
#endif // LLVM_CLANG_AST_ASTIMPORTER_H

View File

@ -18,7 +18,6 @@
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstring>
#include <string>
#include <algorithm>
using llvm::dyn_cast;
@ -96,7 +95,8 @@ class Attr {
FIRST_TARGET_ATTRIBUTE,
DLLExport,
DLLImport,
MSP430Interrupt
MSP430Interrupt,
X86ForceAlignArgPointer
};
private:
@ -119,8 +119,7 @@ class Attr {
assert(Next == 0 && "Destroy didn't work");
}
public:
void Destroy(ASTContext &C);
virtual void Destroy(ASTContext &C);
/// \brief Whether this attribute should be merged to new
/// declarations.
@ -156,6 +155,18 @@ class Attr {
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *) { return true; }
};
class AttrWithString : public Attr {
private:
const char *Str;
unsigned StrLen;
protected:
AttrWithString(Attr::Kind AK, ASTContext &C, llvm::StringRef s);
llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
void ReplaceString(ASTContext &C, llvm::StringRef newS);
public:
virtual void Destroy(ASTContext &C);
};
#define DEF_SIMPLE_ATTR(ATTR) \
class ATTR##Attr : public Attr { \
@ -213,12 +224,12 @@ class AlignedAttr : public Attr {
static bool classof(const AlignedAttr *A) { return true; }
};
class AnnotateAttr : public Attr {
std::string Annotation;
class AnnotateAttr : public AttrWithString {
public:
AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
AnnotateAttr(ASTContext &C, llvm::StringRef ann)
: AttrWithString(Annotate, C, ann) {}
const std::string& getAnnotation() const { return Annotation; }
llvm::StringRef getAnnotation() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@ -229,12 +240,12 @@ class AnnotateAttr : public Attr {
static bool classof(const AnnotateAttr *A) { return true; }
};
class AsmLabelAttr : public Attr {
std::string Label;
class AsmLabelAttr : public AttrWithString {
public:
AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
AsmLabelAttr(ASTContext &C, llvm::StringRef L)
: AttrWithString(AsmLabel, C, L) {}
const std::string& getLabel() const { return Label; }
llvm::StringRef getLabel() const { return getString(); }
virtual Attr* clone(ASTContext &C) const;
@ -247,12 +258,12 @@ class AsmLabelAttr : public Attr {
DEF_SIMPLE_ATTR(AlwaysInline);
class AliasAttr : public Attr {
std::string Aliasee;
class AliasAttr : public AttrWithString {
public:
AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
AliasAttr(ASTContext &C, llvm::StringRef aliasee)
: AttrWithString(Alias, C, aliasee) {}
const std::string& getAliasee() const { return Aliasee; }
llvm::StringRef getAliasee() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@ -321,12 +332,12 @@ DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
DEF_SIMPLE_ATTR(Final);
class SectionAttr : public Attr {
std::string Name;
class SectionAttr : public AttrWithString {
public:
SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
SectionAttr(ASTContext &C, llvm::StringRef N)
: AttrWithString(Section, C, N) {}
const std::string& getName() const { return Name; }
llvm::StringRef getName() const { return getString(); }
virtual Attr *clone(ASTContext &C) const;
@ -350,19 +361,9 @@ class NonNullAttr : public Attr {
unsigned* ArgNums;
unsigned Size;
public:
NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
ArgNums(0), Size(0) {
NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
if (size == 0) return;
assert(arg_nums);
ArgNums = new unsigned[size];
Size = size;
memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
}
virtual ~NonNullAttr() {
delete [] ArgNums;
}
virtual void Destroy(ASTContext &C);
typedef const unsigned *iterator;
iterator begin() const { return ArgNums; }
@ -379,15 +380,14 @@ class NonNullAttr : public Attr {
static bool classof(const NonNullAttr *A) { return true; }
};
class FormatAttr : public Attr {
std::string Type;
class FormatAttr : public AttrWithString {
int formatIdx, firstArg;
public:
FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
Type(type), formatIdx(idx), firstArg(first) {}
FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
: AttrWithString(Format, C, type), formatIdx(idx), firstArg(first) {}
const std::string& getType() const { return Type; }
void setType(llvm::StringRef type) { Type = type; }
llvm::StringRef getType() const { return getString(); }
void setType(ASTContext &C, llvm::StringRef type);
int getFormatIdx() const { return formatIdx; }
int getFirstArg() const { return firstArg; }
@ -570,6 +570,8 @@ class MSP430InterruptAttr : public Attr {
static bool classof(const MSP430InterruptAttr *A) { return true; }
};
DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
#undef DEF_SIMPLE_ATTR
} // end namespace clang

View File

@ -161,7 +161,8 @@ class CXXBasePaths {
void ComputeDeclsFound();
public:
typedef std::list<CXXBasePath>::const_iterator paths_iterator;
typedef std::list<CXXBasePath>::iterator paths_iterator;
typedef std::list<CXXBasePath>::const_iterator const_paths_iterator;
typedef NamedDecl **decl_iterator;
/// BasePaths - Construct a new BasePaths structure to record the
@ -175,8 +176,10 @@ class CXXBasePaths {
~CXXBasePaths() { delete [] DeclsFound; }
paths_iterator begin() const { return Paths.begin(); }
paths_iterator end() const { return Paths.end(); }
paths_iterator begin() { return Paths.begin(); }
paths_iterator end() { return Paths.end(); }
const_paths_iterator begin() const { return Paths.begin(); }
const_paths_iterator end() const { return Paths.end(); }
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
@ -206,7 +209,7 @@ class CXXBasePaths {
const RecordType* getDetectedVirtual() const {
return DetectedVirtual;
}
/// \brief Retrieve the type from which this base-paths search
/// began
CXXRecordDecl *getOrigin() const { return Origin; }

View File

@ -19,6 +19,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/Linkage.h"
namespace clang {
class CXXTemporary;
@ -75,8 +76,9 @@ class TranslationUnitDecl : public Decl, public DeclContext {
static TranslationUnitDecl *Create(ASTContext &C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == TranslationUnit; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TranslationUnitDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TranslationUnit; }
static DeclContext *castToDeclContext(const TranslationUnitDecl *D) {
return static_cast<DeclContext *>(const_cast<TranslationUnitDecl*>(D));
}
@ -194,23 +196,6 @@ class NamedDecl : public Decl {
return DC->isRecord();
}
/// \brief Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
enum Linkage {
/// \brief No linkage, which means that the entity is unique and
/// can only be referred to from within its scope.
NoLinkage = 0,
/// \brief Internal linkage, which indicates that the entity can
/// be referred to from within the translation unit (but not other
/// translation units).
InternalLinkage,
/// \brief External linkage, which indicates that the entity can
/// be referred to from other translation units.
ExternalLinkage
};
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
@ -221,10 +206,9 @@ class NamedDecl : public Decl {
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
static bool classof(const Decl *D) {
return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamedDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
};
/// NamespaceDecl - Represent a C++ namespace.
@ -301,8 +285,9 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
void setRBracLoc(SourceLocation RBrace) { RBracLoc = RBrace; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Namespace; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Namespace; }
static DeclContext *castToDeclContext(const NamespaceDecl *D) {
return static_cast<DeclContext *>(const_cast<NamespaceDecl*>(D));
}
@ -326,10 +311,9 @@ class ValueDecl : public NamedDecl {
void setType(QualType newType) { DeclType = newType; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ValueDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= ValueFirst && K <= ValueLast; }
};
/// \brief Represents a ValueDecl that came out of a declarator.
@ -349,10 +333,11 @@ class DeclaratorDecl : public ValueDecl {
SourceLocation getTypeSpecStartLoc() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= DeclaratorFirst && D->getKind() <= DeclaratorLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const DeclaratorDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= DeclaratorFirst && K <= DeclaratorLast;
}
};
/// \brief Structure used to store a statement, the constant value to
@ -474,14 +459,142 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
SourceLocation L, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass S);
virtual ~VarDecl();
virtual void Destroy(ASTContext& C);
virtual ~VarDecl();
virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
void setStorageClass(StorageClass SC) { SClass = SC; }
virtual SourceRange getSourceRange() const;
void setThreadSpecified(bool T) { ThreadSpecified = T; }
bool isThreadSpecified() const {
return ThreadSpecified;
}
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
if (getStorageClass() == None)
return !isFileVarDecl();
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern.
return getStorageClass() <= Register;
}
/// hasExternStorage - Returns true if a variable has extern or
/// __private_extern__ storage.
bool hasExternalStorage() const {
return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
}
/// hasGlobalStorage - Returns true for all variables that do not
/// have local storage. This includs all global variables as well
/// as static variables declared within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
/// \brief Determines whether this variable is a variable with
/// external, C linkage.
bool isExternC() const;
/// isBlockVarDecl - Returns true for local variable declarations. Note that
/// this includes static variables inside of functions.
///
/// void foo() { int x; static int y; extern int z; }
///
bool isBlockVarDecl() const {
if (getKind() != Decl::Var)
return false;
if (const DeclContext *DC = getDeclContext())
return DC->getLookupContext()->isFunctionOrMethod();
return false;
}
/// \brief Determines whether this is a static data member.
///
/// This will only be true in C++, and applies to, e.g., the
/// variable 'x' in:
/// \code
/// struct S {
/// static int x;
/// };
/// \endcode
bool isStaticDataMember() const {
// If it wasn't static, it would be a FieldDecl.
return getDeclContext()->isRecord();
}
virtual VarDecl *getCanonicalDecl();
const VarDecl *getCanonicalDecl() const {
return const_cast<VarDecl*>(this)->getCanonicalDecl();
}
enum DefinitionKind {
DeclarationOnly, ///< This declaration is only a declaration.
TentativeDefinition, ///< This declaration is a tentative definition.
Definition ///< This declaration is definitely a definition.
};
/// \brief Check whether this declaration is a definition. If this could be
/// a tentative definition (in C), don't check whether there's an overriding
/// definition.
DefinitionKind isThisDeclarationADefinition() const;
/// \brief Get the tentative definition that acts as the real definition in
/// a TU. Returns null if there is a proper definition available.
VarDecl *getActingDefinition();
const VarDecl *getActingDefinition() const {
return const_cast<VarDecl*>(this)->getActingDefinition();
}
/// \brief Determine whether this is a tentative definition of a
/// variable in C.
bool isTentativeDefinitionNow() const;
/// \brief Get the real (not just tentative) definition for this declaration.
VarDecl *getDefinition();
const VarDecl *getDefinition() const {
return const_cast<VarDecl*>(this)->getDefinition();
}
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
bool isOutOfLine() const;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
return false;
if (const DeclContext *Ctx = getDeclContext()) {
Ctx = Ctx->getLookupContext();
if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
return true;
}
if (isStaticDataMember())
return true;
return false;
}
/// getAnyInitializer - Get the initializer for this variable, no matter which
/// declaration it is attached to.
const Expr *getAnyInitializer() const {
const VarDecl *D;
return getAnyInitializer(D);
}
/// getAnyInitializer - Get the initializer for this variable, no matter which
/// declaration it is attached to. Also get that declaration.
const Expr *getAnyInitializer(const VarDecl *&D) const;
bool hasInit() const {
return !Init.isNull();
}
const Expr *getInit() const {
if (Init.isNull())
return 0;
@ -521,7 +634,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
return StmtPtr;
}
void setInit(ASTContext &C, Expr *I);
void setInit(Expr *I);
EvaluatedStmt *EnsureEvaluatedStmt() const {
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
@ -614,17 +727,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
Eval->IsICE = IsICE;
}
/// \brief Retrieve the definition of this variable, which may come
/// from a previous declaration. Def will be set to the VarDecl that
/// contains the initializer, and the result will be that
/// initializer.
const Expr *getDefinition(const VarDecl *&Def) const;
void setThreadSpecified(bool T) { ThreadSpecified = T; }
bool isThreadSpecified() const {
return ThreadSpecified;
}
void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
/// hasCXXDirectInitializer - If true, the initializer was a direct
@ -648,67 +750,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
void setDeclaredInCondition(bool InCondition) {
DeclaredInCondition = InCondition;
}
virtual VarDecl *getCanonicalDecl();
const VarDecl *getCanonicalDecl() const {
return const_cast<VarDecl*>(this)->getCanonicalDecl();
}
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
if (getStorageClass() == None)
return !isFileVarDecl();
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern.
return getStorageClass() <= Register;
}
/// hasExternStorage - Returns true if a variable has extern or
/// __private_extern__ storage.
bool hasExternalStorage() const {
return getStorageClass() == Extern || getStorageClass() == PrivateExtern;
}
/// hasGlobalStorage - Returns true for all variables that do not
/// have local storage. This includs all global variables as well
/// as static variables declared within a function.
bool hasGlobalStorage() const { return !hasLocalStorage(); }
/// isBlockVarDecl - Returns true for local variable declarations. Note that
/// this includes static variables inside of functions.
///
/// void foo() { int x; static int y; extern int z; }
///
bool isBlockVarDecl() const {
if (getKind() != Decl::Var)
return false;
if (const DeclContext *DC = getDeclContext())
return DC->getLookupContext()->isFunctionOrMethod();
return false;
}
/// \brief Determines whether this is a static data member.
///
/// This will only be true in C++, and applies to, e.g., the
/// variable 'x' in:
/// \code
/// struct S {
/// static int x;
/// };
/// \endcode
bool isStaticDataMember() const {
return getDeclContext()->isRecord();
}
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
bool isOutOfLine() const;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
@ -728,35 +769,11 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// data member of a class template, set the template specialiation kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
return false;
if (const DeclContext *Ctx = getDeclContext()) {
Ctx = Ctx->getLookupContext();
if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
return true;
}
if (isStaticDataMember())
return true;
return false;
}
/// \brief Determine whether this is a tentative definition of a
/// variable in C.
bool isTentativeDefinition(ASTContext &Context) const;
/// \brief Determines whether this variable is a variable with
/// external, C linkage.
bool isExternC() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= VarFirst && D->getKind() <= VarLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const VarDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= VarFirst && K <= VarLast; }
};
class ImplicitParamDecl : public VarDecl {
@ -770,7 +787,8 @@ class ImplicitParamDecl : public VarDecl {
QualType T);
// Implement isa/cast/dyncast/etc.
static bool classof(const ImplicitParamDecl *D) { return true; }
static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ImplicitParam; }
};
/// ParmVarDecl - Represent a parameter to a function.
@ -876,10 +894,9 @@ class ParmVarDecl : public VarDecl {
void setOwningFunction(DeclContext *FD) { setDeclContext(FD); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return (D->getKind() == ParmVar);
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ParmVarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ParmVar; }
};
/// FunctionDecl - An instance of this class is created to represent a
@ -1096,8 +1113,6 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
unsigned getBuiltinID() const;
unsigned getNumParmVarDeclsFromType() const;
// Iterator access to formal parameters.
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
@ -1110,7 +1125,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
param_const_iterator param_end() const { return ParamInfo+param_size(); }
/// getNumParams - Return the number of parameters this function must have
/// based on its functiontype. This is the length of the PararmInfo array
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned getNumParams() const;
@ -1122,7 +1137,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
@ -1267,8 +1282,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
/// be inserted.
///
/// \param TSK the kind of template specialization this is.
void setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
const TemplateArgumentList *TemplateArgs,
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
@ -1295,10 +1309,11 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
bool isOutOfLine() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= FunctionFirst && K <= FunctionLast;
}
static DeclContext *castToDeclContext(const FunctionDecl *D) {
return static_cast<DeclContext *>(const_cast<FunctionDecl*>(D));
}
@ -1347,11 +1362,20 @@ class FieldDecl : public DeclaratorDecl {
Expr *getBitWidth() const { return BitWidth; }
void setBitWidth(Expr *BW) { BitWidth = BW; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
/// getParent - Returns the parent of this field declaration, which
/// is the struct in which this method is defined.
const RecordDecl *getParent() const {
return cast<RecordDecl>(getDeclContext());
}
RecordDecl *getParent() {
return cast<RecordDecl>(getDeclContext());
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= FieldFirst && K <= FieldLast; }
};
/// EnumConstantDecl - An instance of this object exists for each enum constant
@ -1385,8 +1409,9 @@ class EnumConstantDecl : public ValueDecl {
void setInitVal(const llvm::APSInt &V) { Val = V; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumConstantDecl *D) { return true; }
static bool classofKind(Kind K) { return K == EnumConstant; }
friend class StmtIteratorBase;
};
@ -1418,10 +1443,9 @@ class TypeDecl : public NamedDecl {
void setTypeForDecl(Type *TD) { TypeForDecl = TD; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypeDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= TypeFirst && K <= TypeLast; }
};
@ -1460,8 +1484,9 @@ class TypedefDecl : public TypeDecl, public Redeclarable<TypedefDecl> {
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Typedef; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TypedefDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Typedef; }
};
class TypedefDecl;
@ -1486,6 +1511,11 @@ class TagDecl
/// it is a declaration ("struct foo;").
bool IsDefinition : 1;
/// IsEmbeddedInDeclarator - True if this tag declaration is
/// "embedded" (i.e., defined or declared for the very first time)
/// in the syntax of a declarator,
bool IsEmbeddedInDeclarator : 1;
/// TypedefForAnonDecl - If a TagDecl is anonymous and part of a typedef,
/// this points to the TypedefDecl. Used for mangling.
TypedefDecl *TypedefForAnonDecl;
@ -1502,6 +1532,7 @@ class TagDecl
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
TagDeclKind = TK;
IsDefinition = false;
IsEmbeddedInDeclarator = false;
setPreviousDeclaration(PrevDecl);
}
@ -1535,6 +1566,13 @@ class TagDecl
return IsDefinition;
}
bool isEmbeddedInDeclarator() const {
return IsEmbeddedInDeclarator;
}
void setEmbeddedInDeclarator(bool isInDeclarator) {
IsEmbeddedInDeclarator = isInDeclarator;
}
/// \brief Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
@ -1557,7 +1595,9 @@ class TagDecl
/// specific TagDecl is defining declaration, not whether or not the
/// struct/union/class/enum type is defined. This method returns NULL if
/// there is no TagDecl that defines the struct/union/class/enum.
TagDecl* getDefinition(ASTContext& C) const;
TagDecl* getDefinition() const;
void setDefinition(bool V) { IsDefinition = V; }
const char *getKindName() const {
return ElaboratedType::getNameForTagKind(getTagKind());
@ -1583,10 +1623,9 @@ class TagDecl
void setTypedefForAnonDecl(TypedefDecl *TDD) { TypedefForAnonDecl = TDD; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= TagFirst && D->getKind() <= TagLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TagDecl *D) { return true; }
static bool classofKind(Kind K) { return K >= TagFirst && K <= TagLast; }
static DeclContext *castToDeclContext(const TagDecl *D) {
return static_cast<DeclContext *>(const_cast<TagDecl*>(D));
@ -1594,8 +1633,6 @@ class TagDecl
static TagDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<TagDecl *>(const_cast<DeclContext*>(DC));
}
void setDefinition(bool V) { IsDefinition = V; }
};
/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
@ -1641,7 +1678,7 @@ class EnumDecl : public TagDecl {
/// declaration as being defined; it's enumerators have already been
/// added (via DeclContext::addDecl). NewType is the new underlying
/// type of the enumeration type.
void completeDefinition(ASTContext &C, QualType NewType,
void completeDefinition(QualType NewType,
QualType PromotionType);
// enumerator_iterator - Iterates through the enumerators of this
@ -1679,8 +1716,9 @@ class EnumDecl : public TagDecl {
void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
static bool classof(const Decl *D) { return D->getKind() == Enum; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Enum; }
};
@ -1763,8 +1801,8 @@ class RecordDecl : public TagDecl {
/// RecordDecl is defining declaration, not whether or not the record
/// type is defined. This method returns NULL if there is no RecordDecl
/// that defines the struct/union/tag.
RecordDecl* getDefinition(ASTContext& C) const {
return cast_or_null<RecordDecl>(TagDecl::getDefinition(C));
RecordDecl* getDefinition() const {
return cast_or_null<RecordDecl>(TagDecl::getDefinition());
}
// Iterator access to field members. The field iterator only visits
@ -1787,12 +1825,13 @@ class RecordDecl : public TagDecl {
/// completeDefinition - Notes that the definition of this type is
/// now complete.
void completeDefinition(ASTContext& C);
void completeDefinition();
static bool classof(const Decl *D) {
return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const RecordDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= RecordFirst && K <= RecordLast;
}
};
class FileScopeAsmDecl : public Decl {
@ -1807,10 +1846,9 @@ class FileScopeAsmDecl : public Decl {
StringLiteral *getAsmString() { return AsmString; }
void setAsmString(StringLiteral *Asm) { AsmString = Asm; }
static bool classof(const Decl *D) {
return D->getKind() == FileScopeAsm;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FileScopeAsmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
/// BlockDecl - This represents a block literal declaration, which is like an
@ -1869,11 +1907,12 @@ class BlockDecl : public Decl, public DeclContext {
assert(i < getNumParams() && "Illegal param #");
return ParamInfo[i];
}
void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams);
void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Block; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const BlockDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Block; }
static DeclContext *castToDeclContext(const BlockDecl *D) {
return static_cast<DeclContext *>(const_cast<BlockDecl*>(D));
}

View File

@ -480,6 +480,7 @@ class Decl {
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *) { return true; }
static bool classofKind(Kind K) { return true; }
static DeclContext *castToDeclContext(const Decl *);
static Decl *castFromDeclContext(const DeclContext *);
@ -1020,17 +1021,43 @@ inline bool Decl::isTemplateParameter() const {
getKind() == TemplateTemplateParm;
}
// Specialization selected when ToTy is not a known subclass of DeclContext.
template <class ToTy,
bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
struct cast_convert_decl_context {
static const ToTy *doit(const DeclContext *Val) {
return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
}
static ToTy *doit(DeclContext *Val) {
return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
}
};
// Specialization selected when ToTy is a known subclass of DeclContext.
template <class ToTy>
struct cast_convert_decl_context<ToTy, true> {
static const ToTy *doit(const DeclContext *Val) {
return static_cast<const ToTy*>(Val);
}
static ToTy *doit(DeclContext *Val) {
return static_cast<ToTy*>(Val);
}
};
} // end clang.
namespace llvm {
/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
/// a specific Decl.
/// isa<T>(DeclContext*)
template<class ToTy>
struct isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
static bool doit(const ::clang::DeclContext &Val) {
return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
return ToTy::classofKind(Val.getDeclKind());
}
};
template<class ToTy>
@ -1038,6 +1065,34 @@ struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
: public isa_impl_wrap<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {};
/// cast<T>(DeclContext*)
template<class ToTy>
struct cast_convert_val<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
static const ToTy &doit(const ::clang::DeclContext &Val) {
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
}
};
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
static ToTy &doit(::clang::DeclContext &Val) {
return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
}
};
template<class ToTy>
struct cast_convert_val<ToTy,
const ::clang::DeclContext*, const ::clang::DeclContext*> {
static const ToTy *doit(const ::clang::DeclContext *Val) {
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
}
};
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
static ToTy *doit(::clang::DeclContext *Val) {
return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
}
};
/// Implement cast_convert_val for Decl -> DeclContext conversions.
template<class FromTy>
struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
@ -1067,31 +1122,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
}
};
/// Implement cast_convert_val for DeclContext -> Decl conversions.
template<class ToTy>
struct cast_convert_val<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {
static ToTy &doit(const ::clang::DeclContext &Val) {
return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
}
};
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
: public cast_convert_val<ToTy,
const ::clang::DeclContext,const ::clang::DeclContext> {};
template<class ToTy>
struct cast_convert_val<ToTy,
const ::clang::DeclContext*, const ::clang::DeclContext*> {
static ToTy *doit(const ::clang::DeclContext *Val) {
return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
}
};
template<class ToTy>
struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
: public cast_convert_val<ToTy,
const ::clang::DeclContext*,const ::clang::DeclContext*> {};
} // end namespace llvm
#endif

View File

@ -145,6 +145,10 @@ class CXXBaseSpecifier {
/// class (or not).
bool isVirtual() const { return Virtual; }
/// \brief Determine whether this base class if a base of a class declared
/// with the 'class' keyword (vs. one declared with the 'struct' keyword).
bool isBaseOfClass() const { return BaseOfClass; }
/// getAccessSpecifier - Returns the access specifier for this base
/// specifier. This is the actual base specifier as used for
/// semantic analysis, so the result can never be AS_none. To
@ -174,115 +178,137 @@ class CXXBaseSpecifier {
/// FIXME: This class will disappear once we've properly taught RecordDecl
/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
/// UserDeclaredConstructor - True when this class has a
/// user-declared constructor.
bool UserDeclaredConstructor : 1;
/// UserDeclaredCopyConstructor - True when this class has a
/// user-declared copy constructor.
bool UserDeclaredCopyConstructor : 1;
friend void TagDecl::startDefinition();
/// UserDeclaredCopyAssignment - True when this class has a
/// user-declared copy assignment operator.
bool UserDeclaredCopyAssignment : 1;
struct DefinitionData {
DefinitionData(CXXRecordDecl *D);
/// UserDeclaredDestructor - True when this class has a
/// user-declared destructor.
bool UserDeclaredDestructor : 1;
/// UserDeclaredConstructor - True when this class has a
/// user-declared constructor.
bool UserDeclaredConstructor : 1;
/// Aggregate - True when this class is an aggregate.
bool Aggregate : 1;
/// UserDeclaredCopyConstructor - True when this class has a
/// user-declared copy constructor.
bool UserDeclaredCopyConstructor : 1;
/// PlainOldData - True when this class is a POD-type.
bool PlainOldData : 1;
/// UserDeclaredCopyAssignment - True when this class has a
/// user-declared copy assignment operator.
bool UserDeclaredCopyAssignment : 1;
/// Empty - true when this class is empty for traits purposes, i.e. has no
/// data members other than 0-width bit-fields, has no virtual function/base,
/// and doesn't inherit from a non-empty class. Doesn't take union-ness into
/// account.
bool Empty : 1;
/// UserDeclaredDestructor - True when this class has a
/// user-declared destructor.
bool UserDeclaredDestructor : 1;
/// Polymorphic - True when this class is polymorphic, i.e. has at least one
/// virtual member or derives from a polymorphic class.
bool Polymorphic : 1;
/// Aggregate - True when this class is an aggregate.
bool Aggregate : 1;
/// Abstract - True when this class is abstract, i.e. has at least one
/// pure virtual function, (that can come from a base class).
bool Abstract : 1;
/// PlainOldData - True when this class is a POD-type.
bool PlainOldData : 1;
/// HasTrivialConstructor - True when this class has a trivial constructor.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
/// implicitly-declared default constructor and if:
/// * its class has no virtual functions and no virtual base classes, and
/// * all the direct base classes of its class have trivial constructors, and
/// * for all the nonstatic data members of its class that are of class type
/// (or array thereof), each such class has a trivial constructor.
bool HasTrivialConstructor : 1;
/// Empty - true when this class is empty for traits purposes,
/// i.e. has no data members other than 0-width bit-fields, has no
/// virtual function/base, and doesn't inherit from a non-empty
/// class. Doesn't take union-ness into account.
bool Empty : 1;
/// HasTrivialCopyConstructor - True when this class has a trivial copy
/// constructor.
///
/// C++ [class.copy]p6. A copy constructor for class X is trivial
/// if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy constructor, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy constructor;
/// otherwise the copy constructor is non-trivial.
bool HasTrivialCopyConstructor : 1;
/// Polymorphic - True when this class is polymorphic, i.e. has at
/// least one virtual member or derives from a polymorphic class.
bool Polymorphic : 1;
/// HasTrivialCopyAssignment - True when this class has a trivial copy
/// assignment operator.
///
/// C++ [class.copy]p11. A copy assignment operator for class X is
/// trivial if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy assignment operator, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy assignment
/// operator;
/// otherwise the copy assignment operator is non-trivial.
bool HasTrivialCopyAssignment : 1;
/// Abstract - True when this class is abstract, i.e. has at least
/// one pure virtual function, (that can come from a base class).
bool Abstract : 1;
/// HasTrivialDestructor - True when this class has a trivial destructor.
///
/// C++ [class.dtor]p3. A destructor is trivial if it is an
/// implicitly-declared destructor and if:
/// * all of the direct base classes of its class have trivial destructors
/// and
/// * for all of the non-static data members of its class that are of class
/// type (or array thereof), each such class has a trivial destructor.
bool HasTrivialDestructor : 1;
/// HasTrivialConstructor - True when this class has a trivial constructor.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
/// implicitly-declared default constructor and if:
/// * its class has no virtual functions and no virtual base classes, and
/// * all the direct base classes of its class have trivial constructors, and
/// * for all the nonstatic data members of its class that are of class type
/// (or array thereof), each such class has a trivial constructor.
bool HasTrivialConstructor : 1;
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
/// HasTrivialCopyConstructor - True when this class has a trivial copy
/// constructor.
///
/// C++ [class.copy]p6. A copy constructor for class X is trivial
/// if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy constructor, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy constructor;
/// otherwise the copy constructor is non-trivial.
bool HasTrivialCopyConstructor : 1;
/// HasTrivialCopyAssignment - True when this class has a trivial copy
/// assignment operator.
///
/// C++ [class.copy]p11. A copy assignment operator for class X is
/// trivial if it is implicitly declared and if
/// * class X has no virtual functions and no virtual base classes, and
/// * each direct base class of X has a trivial copy assignment operator, and
/// * for all the nonstatic data members of X that are of class type (or
/// array thereof), each such class type has a trivial copy assignment
/// operator;
/// otherwise the copy assignment operator is non-trivial.
bool HasTrivialCopyAssignment : 1;
/// HasTrivialDestructor - True when this class has a trivial destructor.
///
/// C++ [class.dtor]p3. A destructor is trivial if it is an
/// implicitly-declared destructor and if:
/// * all of the direct base classes of its class have trivial destructors
/// and
/// * for all of the non-static data members of its class that are of class
/// type (or array thereof), each such class has a trivial destructor.
bool HasTrivialDestructor : 1;
/// ComputedVisibleConversions - True when visible conversion functions are
/// already computed and are available.
bool ComputedVisibleConversions : 1;
/// Bases - Base classes of this class.
/// FIXME: This is wasted space for a union.
CXXBaseSpecifier *Bases;
/// Bases - Base classes of this class.
/// FIXME: This is wasted space for a union.
CXXBaseSpecifier *Bases;
/// NumBases - The number of base class specifiers in Bases.
unsigned NumBases;
/// NumBases - The number of base class specifiers in Bases.
unsigned NumBases;
/// VBases - direct and indirect virtual base classes of this class.
CXXBaseSpecifier *VBases;
/// VBases - direct and indirect virtual base classes of this class.
CXXBaseSpecifier *VBases;
/// NumVBases - The number of virtual base class specifiers in VBases.
unsigned NumVBases;
/// NumVBases - The number of virtual base class specifiers in VBases.
unsigned NumVBases;
/// Conversions - Overload set containing the conversion functions
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
UnresolvedSet<4> Conversions;
/// Conversions - Overload set containing the conversion functions
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
/// CXXConversionDecl.
UnresolvedSet<4> Conversions;
/// VisibleConversions - Overload set containing the conversion functions
/// of this C++ class and all those inherited conversion functions that
/// are visible in this class. Each of the entries in this overload set is
/// a CXXConversionDecl or a FunctionTemplateDecl.
UnresolvedSet<4> VisibleConversions;
/// VisibleConversions - Overload set containing the conversion
/// functions of this C++ class and all those inherited conversion
/// functions that are visible in this class. Each of the entries
/// in this overload set is a CXXConversionDecl or a
/// FunctionTemplateDecl.
UnresolvedSet<4> VisibleConversions;
/// Definition - The declaration which defines this record.
CXXRecordDecl *Definition;
} *DefinitionData;
struct DefinitionData &data() {
assert(DefinitionData && "queried property of class with no definition");
return *DefinitionData;
}
const struct DefinitionData &data() const {
assert(DefinitionData && "queried property of class with no definition");
return *DefinitionData;
}
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
@ -336,6 +362,13 @@ class CXXRecordDecl : public RecordDecl {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
CXXRecordDecl *getDefinition() const {
if (!DefinitionData) return 0;
return data().Definition;
}
bool hasDefinition() const { return DefinitionData != 0; }
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
@ -345,21 +378,22 @@ class CXXRecordDecl : public RecordDecl {
virtual void Destroy(ASTContext& C);
bool isDynamicClass() const {
return Polymorphic || NumVBases != 0;
return data().Polymorphic || data().NumVBases != 0;
}
/// setBases - Sets the base classes of this struct or class.
void setBases(ASTContext &C,
CXXBaseSpecifier const * const *Bases, unsigned NumBases);
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// getNumBases - Retrieves the number of base classes of this
/// class.
unsigned getNumBases() const { return NumBases; }
unsigned getNumBases() const { return data().NumBases; }
base_class_iterator bases_begin() { return Bases; }
base_class_const_iterator bases_begin() const { return Bases; }
base_class_iterator bases_end() { return Bases + NumBases; }
base_class_const_iterator bases_end() const { return Bases + NumBases; }
base_class_iterator bases_begin() { return data().Bases; }
base_class_const_iterator bases_begin() const { return data().Bases; }
base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
base_class_const_iterator bases_end() const {
return bases_begin() + data().NumBases;
}
reverse_base_class_iterator bases_rbegin() {
return reverse_base_class_iterator(bases_end());
}
@ -375,12 +409,14 @@ class CXXRecordDecl : public RecordDecl {
/// getNumVBases - Retrieves the number of virtual base classes of this
/// class.
unsigned getNumVBases() const { return NumVBases; }
unsigned getNumVBases() const { return data().NumVBases; }
base_class_iterator vbases_begin() { return VBases; }
base_class_const_iterator vbases_begin() const { return VBases; }
base_class_iterator vbases_end() { return VBases + NumVBases; }
base_class_const_iterator vbases_end() const { return VBases + NumVBases; }
base_class_iterator vbases_begin() { return data().VBases; }
base_class_const_iterator vbases_begin() const { return data().VBases; }
base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
base_class_const_iterator vbases_end() const {
return vbases_begin() + data().NumVBases;
}
reverse_base_class_iterator vbases_rbegin() {
return reverse_base_class_iterator(vbases_end());
}
@ -445,17 +481,14 @@ class CXXRecordDecl : public RecordDecl {
/// user-declared constructors. When true, a default constructor
/// will not be implicitly declared.
bool hasUserDeclaredConstructor() const {
assert((isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"Incomplete record decl!");
return UserDeclaredConstructor;
return data().UserDeclaredConstructor;
}
/// hasUserDeclaredCopyConstructor - Whether this class has a
/// user-declared copy constructor. When false, a copy constructor
/// will be implicitly declared.
bool hasUserDeclaredCopyConstructor() const {
return UserDeclaredCopyConstructor;
return data().UserDeclaredCopyConstructor;
}
/// addedAssignmentOperator - Notify the class that another assignment
@ -467,45 +500,45 @@ class CXXRecordDecl : public RecordDecl {
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
bool hasUserDeclaredCopyAssignment() const {
return UserDeclaredCopyAssignment;
return data().UserDeclaredCopyAssignment;
}
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
bool hasUserDeclaredDestructor() const { return UserDeclaredDestructor; }
bool hasUserDeclaredDestructor() const {
return data().UserDeclaredDestructor;
}
/// setUserDeclaredDestructor - Set whether this class has a
/// user-declared destructor. If not set by the time the class is
/// fully defined, a destructor will be implicitly declared.
void setUserDeclaredDestructor(bool UCD) {
UserDeclaredDestructor = UCD;
data().UserDeclaredDestructor = UCD;
}
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
return &data().Conversions;
}
const UnresolvedSetImpl *getConversionFunctions() const {
assert((this->isDefinition() ||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
"getConversionFunctions() called on incomplete type");
return &Conversions;
return &data().Conversions;
}
typedef UnresolvedSetImpl::iterator conversion_iterator;
conversion_iterator conversion_begin() const { return Conversions.begin(); }
conversion_iterator conversion_end() const { return Conversions.end(); }
conversion_iterator conversion_begin() const {
return getConversionFunctions()->begin();
}
conversion_iterator conversion_end() const {
return getConversionFunctions()->end();
}
/// Replaces a conversion function with a new declaration.
///
/// Returns true if the old conversion was found.
bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
return Conversions.replace(Old, New);
return getConversionFunctions()->replace(Old, New);
}
/// getVisibleConversionFunctions - get all conversion functions visible
@ -532,11 +565,11 @@ class CXXRecordDecl : public RecordDecl {
/// [dcl.init.aggr]), which is a class with no user-declared
/// constructors, no private or protected non-static data members,
/// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).
bool isAggregate() const { return Aggregate; }
bool isAggregate() const { return data().Aggregate; }
/// setAggregate - Set whether this class is an aggregate (C++
/// [dcl.init.aggr]).
void setAggregate(bool Agg) { Aggregate = Agg; }
void setAggregate(bool Agg) { data().Aggregate = Agg; }
/// setMethodAsVirtual - Make input method virtual and set the necesssary
/// special function bits and other bits accordingly.
@ -546,66 +579,74 @@ class CXXRecordDecl : public RecordDecl {
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// user-defined destructor.
bool isPOD() const { return PlainOldData; }
bool isPOD() const { return data().PlainOldData; }
/// setPOD - Set whether this class is a POD-type (C++ [class]p4).
void setPOD(bool POD) { PlainOldData = POD; }
void setPOD(bool POD) { data().PlainOldData = POD; }
/// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which
/// means it has a virtual function, virtual base, data member (other than
/// 0-width bit-field) or inherits from a non-empty class. Does NOT include
/// a check for union-ness.
bool isEmpty() const { return Empty; }
bool isEmpty() const { return data().Empty; }
/// Set whether this class is empty (C++0x [meta.unary.prop])
void setEmpty(bool Emp) { Empty = Emp; }
void setEmpty(bool Emp) { data().Empty = Emp; }
/// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return Polymorphic; }
bool isPolymorphic() const { return data().Polymorphic; }
/// setPolymorphic - Set whether this class is polymorphic (C++
/// [class.virtual]).
void setPolymorphic(bool Poly) { Polymorphic = Poly; }
void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
/// isAbstract - Whether this class is abstract (C++ [class.abstract]),
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return Abstract; }
bool isAbstract() const { return data().Abstract; }
/// setAbstract - Set whether this class is abstract (C++ [class.abstract])
void setAbstract(bool Abs) { Abstract = Abs; }
void setAbstract(bool Abs) { data().Abstract = Abs; }
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return HasTrivialConstructor; }
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
// setHasTrivialConstructor - Set whether this class has a trivial constructor
// (C++ [class.ctor]p5)
void setHasTrivialConstructor(bool TC) { HasTrivialConstructor = TC; }
void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
bool hasTrivialCopyConstructor() const { return HasTrivialCopyConstructor; }
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
// setHasTrivialCopyConstructor - Set whether this class has a trivial
// copy constructor (C++ [class.copy]p6)
void setHasTrivialCopyConstructor(bool TC) { HasTrivialCopyConstructor = TC; }
void setHasTrivialCopyConstructor(bool TC) {
data().HasTrivialCopyConstructor = TC;
}
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
bool hasTrivialCopyAssignment() const { return HasTrivialCopyAssignment; }
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
// setHasTrivialCopyAssignment - Set whether this class has a
// trivial copy assignment operator (C++ [class.copy]p11)
void setHasTrivialCopyAssignment(bool TC) { HasTrivialCopyAssignment = TC; }
void setHasTrivialCopyAssignment(bool TC) {
data().HasTrivialCopyAssignment = TC;
}
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return HasTrivialDestructor; }
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
// setHasTrivialDestructor - Set whether this class has a trivial destructor
// (C++ [class.dtor]p3)
void setHasTrivialDestructor(bool TC) { HasTrivialDestructor = TC; }
void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
@ -826,10 +867,11 @@ class CXXRecordDecl : public RecordDecl {
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
static bool classof(const Decl *D) {
return D->getKind() == CXXRecord ||
D->getKind() == ClassTemplateSpecialization ||
D->getKind() == ClassTemplatePartialSpecialization;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K == CXXRecord ||
K == ClassTemplateSpecialization ||
K == ClassTemplatePartialSpecialization;
}
static bool classof(const CXXRecordDecl *D) { return true; }
static bool classof(const ClassTemplateSpecializationDecl *D) {
@ -911,10 +953,11 @@ class CXXMethodDecl : public FunctionDecl {
bool hasInlineBody() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXMethodDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= CXXMethod && K <= CXXConversion;
}
};
/// CXXBaseOrMemberInitializer - Represents a C++ base or member
@ -939,9 +982,9 @@ class CXXBaseOrMemberInitializer {
/// \brief The source location for the field name.
SourceLocation MemberLocation;
/// Args - The arguments used to initialize the base or member.
Stmt **Args;
unsigned NumArgs;
/// \brief The argument used to initialize the base or member, which may
/// end up constructing an object (when multiple arguments are involved).
Stmt *Init;
/// \brief Stores either the constructor to call to initialize this base or
/// member (a CXXConstructorDecl pointer), or stores the anonymous union of
@ -961,7 +1004,7 @@ class CXXBaseOrMemberInitializer {
/// @endcode
/// In above example, BaseOrMember holds the field decl. for anonymous union
/// and AnonUnionMember holds field decl for au_i1.
llvm::PointerUnion<CXXConstructorDecl *, FieldDecl *> CtorOrAnonUnion;
FieldDecl *AnonUnionMember;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@ -973,30 +1016,22 @@ class CXXBaseOrMemberInitializer {
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
TypeSourceInfo *TInfo, CXXConstructorDecl *C,
TypeSourceInfo *TInfo,
SourceLocation L,
Expr **Args, unsigned NumArgs,
Expr *Init,
SourceLocation R);
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
FieldDecl *Member, SourceLocation MemberLoc,
CXXConstructorDecl *C, SourceLocation L,
Expr **Args, unsigned NumArgs,
SourceLocation L,
Expr *Init,
SourceLocation R);
/// \brief Destroy the base or member initializer.
void Destroy(ASTContext &Context);
/// arg_iterator - Iterates through the member initialization
/// arguments.
typedef ExprIterator arg_iterator;
/// arg_const_iterator - Iterates through the member initialization
/// arguments.
typedef ConstExprIterator const_arg_iterator;
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
@ -1046,32 +1081,16 @@ class CXXBaseOrMemberInitializer {
SourceRange getSourceRange() const;
FieldDecl *getAnonUnionMember() const {
return CtorOrAnonUnion.dyn_cast<FieldDecl *>();
return AnonUnionMember;
}
void setAnonUnionMember(FieldDecl *anonMember) {
CtorOrAnonUnion = anonMember;
}
const CXXConstructorDecl *getConstructor() const {
return CtorOrAnonUnion.dyn_cast<CXXConstructorDecl *>();
AnonUnionMember = anonMember;
}
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
/// arg_begin() - Retrieve an iterator to the first initializer argument.
arg_iterator arg_begin() { return Args; }
/// arg_begin() - Retrieve an iterator to the first initializer argument.
const_arg_iterator const_arg_begin() const { return Args; }
/// arg_end() - Retrieve an iterator past the last initializer argument.
arg_iterator arg_end() { return Args + NumArgs; }
/// arg_end() - Retrieve an iterator past the last initializer argument.
const_arg_iterator const_arg_end() const { return Args + NumArgs; }
/// getNumArgs - Determine the number of arguments used to
/// initialize the member or base.
unsigned getNumArgs() const { return NumArgs; }
Expr *getInit() { return static_cast<Expr *>(Init); }
};
/// CXXConstructorDecl - Represents a C++ constructor within a
@ -1084,8 +1103,9 @@ class CXXBaseOrMemberInitializer {
/// };
/// @endcode
class CXXConstructorDecl : public CXXMethodDecl {
/// Explicit - Whether this constructor is explicit.
bool Explicit : 1;
/// IsExplicitSpecified - Whether this constructor declaration has the
/// 'explicit' keyword specified.
bool IsExplicitSpecified : 1;
/// ImplicitlyDefined - Whether this constructor was implicitly
/// defined by the compiler. When false, the constructor was defined
@ -1103,9 +1123,10 @@ class CXXConstructorDecl : public CXXMethodDecl {
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
: CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
Explicit(isExplicit), ImplicitlyDefined(false),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@ -1118,8 +1139,15 @@ class CXXConstructorDecl : public CXXMethodDecl {
bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
/// isExplicitSpecified - Whether this constructor declaration has the
/// 'explicit' keyword specified.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// isExplicit - Whether this constructor was marked "explicit" or not.
bool isExplicit() const { return Explicit; }
bool isExplicit() const {
return cast<CXXConstructorDecl>(getFirstDeclaration())
->isExplicitSpecified();
}
/// isImplicitlyDefined - Whether this constructor was implicitly
/// defined. If false, then this constructor was defined by the
@ -1212,10 +1240,9 @@ class CXXConstructorDecl : public CXXMethodDecl {
bool isCopyConstructorLikeSpecialization() const;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == CXXConstructor;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConstructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConstructor; }
};
/// CXXDestructorDecl - Represents a C++ destructor within a
@ -1274,10 +1301,9 @@ class CXXDestructorDecl : public CXXMethodDecl {
const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == CXXDestructor;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXDestructorDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXDestructor; }
};
/// CXXConversionDecl - Represents a C++ conversion function within a
@ -1290,16 +1316,16 @@ class CXXDestructorDecl : public CXXMethodDecl {
/// };
/// @endcode
class CXXConversionDecl : public CXXMethodDecl {
/// Explicit - Whether this conversion function is marked
/// "explicit", meaning that it can only be applied when the user
/// IsExplicitSpecified - Whether this conversion function declaration is
/// marked "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
bool Explicit : 1;
bool IsExplicitSpecified : 1;
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit)
bool isInline, bool isExplicitSpecified)
: CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
Explicit(isExplicit) { }
IsExplicitSpecified(isExplicitSpecified) { }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
@ -1307,10 +1333,18 @@ class CXXConversionDecl : public CXXMethodDecl {
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicit);
/// IsExplicitSpecified - Whether this conversion function declaration is
/// marked "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
bool isExplicitSpecified() const { return IsExplicitSpecified; }
/// isExplicit - Whether this is an explicit conversion operator
/// (C++0x only). Explicit conversion operators are only considered
/// when the user has explicitly written a cast.
bool isExplicit() const { return Explicit; }
bool isExplicit() const {
return cast<CXXConversionDecl>(getFirstDeclaration())
->isExplicitSpecified();
}
/// getConversionType - Returns the type that this conversion
/// function is converting to.
@ -1319,10 +1353,9 @@ class CXXConversionDecl : public CXXMethodDecl {
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == CXXConversion;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const CXXConversionDecl *D) { return true; }
static bool classofKind(Kind K) { return K == CXXConversion; }
};
/// FriendDecl - Represents the declaration of a friend entity,
@ -1391,10 +1424,9 @@ class FriendDecl : public Decl {
void setSpecialization(bool WS) { WasSpecialization = WS; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == Decl::Friend;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::Friend; }
};
/// LinkageSpecDecl - This represents a linkage specification. For example:
@ -1432,10 +1464,9 @@ class LinkageSpecDecl : public Decl, public DeclContext {
/// braces in its syntactic form.
bool hasBraces() const { return HadBraces; }
static bool classof(const Decl *D) {
return D->getKind() == LinkageSpec;
}
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; }
static DeclContext *castToDeclContext(const LinkageSpecDecl *D) {
return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D));
}
@ -1537,10 +1568,9 @@ class UsingDirectiveDecl : public NamedDecl {
NamedDecl *Nominated,
DeclContext *CommonAncestor);
static bool classof(const Decl *D) {
return D->getKind() == Decl::UsingDirective;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDirectiveDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UsingDirective; }
// Friend for getUsingDirectiveName.
friend class DeclContext;
@ -1598,6 +1628,16 @@ class NamespaceAliasDecl : public NamedDecl {
return const_cast<NamespaceAliasDecl*>(this)->getNamespace();
}
/// Returns the location of the alias name, i.e. 'foo' in
/// "namespace foo = ns::bar;".
SourceLocation getAliasLoc() const { return AliasLoc; }
/// 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; }
/// \brief Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
NamedDecl *getAliasedNamespace() const { return Namespace; }
@ -1610,10 +1650,9 @@ class NamespaceAliasDecl : public NamedDecl {
SourceLocation IdentLoc,
NamedDecl *Namespace);
static bool classof(const Decl *D) {
return D->getKind() == Decl::NamespaceAlias;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NamespaceAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::NamespaceAlias; }
};
/// UsingShadowDecl - Represents a shadow declaration introduced into
@ -1660,10 +1699,9 @@ class UsingShadowDecl : public NamedDecl {
return Using;
}
static bool classof(const Decl *D) {
return D->getKind() == Decl::UsingShadow;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
};
/// UsingDecl - Represents a C++ using-declaration. For example:
@ -1732,10 +1770,9 @@ class UsingDecl : public NamedDecl {
SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
static bool classof(const Decl *D) {
return D->getKind() == Decl::Using;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::Using; }
};
/// UnresolvedUsingValueDecl - Represents a dependent using
@ -1784,10 +1821,9 @@ class UnresolvedUsingValueDecl : public ValueDecl {
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
static bool classof(const Decl *D) {
return D->getKind() == Decl::UnresolvedUsingValue;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingValue; }
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
@ -1843,10 +1879,9 @@ class UnresolvedUsingTypenameDecl : public TypeDecl {
SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
SourceLocation TargetNameLoc, DeclarationName TargetName);
static bool classof(const Decl *D) {
return D->getKind() == Decl::UnresolvedUsingTypename;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingTypename; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
@ -1872,10 +1907,9 @@ class StaticAssertDecl : public Decl {
virtual ~StaticAssertDecl();
virtual void Destroy(ASTContext& C);
static bool classof(const Decl *D) {
return D->getKind() == Decl::StaticAssert;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(StaticAssertDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::StaticAssert; }
};
/// Insertion operator for diagnostics. This allows sending AccessSpecifier's

View File

@ -193,6 +193,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
ImplementationControl impControl = None);
virtual ObjCMethodDecl *getCanonicalDecl();
const ObjCMethodDecl *getCanonicalDecl() const {
return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
}
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
@ -277,8 +280,9 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
bool isThisDeclarationADefinition() const { return Body; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCMethodDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCMethod; }
static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
}
@ -383,11 +387,12 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= ObjCContainerFirst &&
D->getKind() <= ObjCContainerLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCContainerDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= ObjCContainerFirst &&
K <= ObjCContainerLast;
}
static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
@ -584,8 +589,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl {
Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(Type *TD) const { TypeForDecl = TD; }
static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCInterfaceDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCInterface; }
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@ -630,8 +636,9 @@ class ObjCIvarDecl : public FieldDecl {
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCIvarDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCIvar; }
private:
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
@ -657,8 +664,9 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
virtual void Destroy(ASTContext& C);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
};
/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
@ -749,8 +757,9 @@ class ObjCProtocolDecl : public ObjCContainerDecl {
SourceLocation getLocEnd() const { return EndLoc; }
void setLocEnd(SourceLocation LE) { EndLoc = LE; }
static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCProtocolDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
};
/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
@ -796,8 +805,9 @@ class ObjCClassDecl : public Decl {
void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
const SourceLocation *Locs, unsigned Num);
static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCClassDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCClass; }
};
/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
@ -846,10 +856,9 @@ class ObjCForwardProtocolDecl : public Decl {
const SourceLocation *Locs, ASTContext &C) {
ReferencedProtocols.set(List, Num, Locs, C);
}
static bool classof(const Decl *D) {
return D->getKind() == ObjCForwardProtocol;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCForwardProtocol; }
};
/// ObjCCategoryDecl - Represents a category declaration. A category allows
@ -940,6 +949,8 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
ClassInterface->setCategoryList(this);
}
bool IsClassExtension() const { return getIdentifier() == 0; }
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation At) { AtLoc = At; }
@ -950,8 +961,9 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
return SourceRange(AtLoc, getAtEndRange().getEnd());
}
static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCategory; }
};
class ObjCImplDecl : public ObjCContainerDecl {
@ -997,10 +1009,11 @@ class ObjCImplDecl : public ObjCContainerDecl {
return propimpl_iterator(decls_end());
}
static bool classof(const Decl *D) {
return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= ObjCImplFirst && K <= ObjCImplLast;
}
};
/// ObjCCategoryImplDecl - An object of this class encapsulates a category
@ -1068,8 +1081,9 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
return getName();
}
static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCategoryImplDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
};
/// ObjCImplementationDecl - Represents a class definition - this is where
@ -1152,10 +1166,9 @@ class ObjCImplementationDecl : public ObjCImplDecl {
return ivar_begin() == ivar_end();
}
static bool classof(const Decl *D) {
return D->getKind() == ObjCImplementation;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCImplementationDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCImplementation; }
};
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
@ -1176,10 +1189,9 @@ class ObjCCompatibleAliasDecl : public NamedDecl {
ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
static bool classof(const Decl *D) {
return D->getKind() == ObjCCompatibleAlias;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
};
@ -1294,10 +1306,9 @@ class ObjCPropertyDecl : public NamedDecl {
return PropertyIvarDecl;
}
static bool classof(const Decl *D) {
return D->getKind() == ObjCProperty;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ObjCPropertyDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ObjCProperty; }
};
/// ObjCPropertyImplDecl - Represents implementation declaration of a property
@ -1354,10 +1365,9 @@ class ObjCPropertyImplDecl : public Decl {
}
void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
static bool classof(const Decl *D) {
return D->getKind() == ObjCPropertyImpl;
}
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; }
};
} // end namespace clang

View File

@ -247,13 +247,14 @@ class TemplateDecl : public NamedDecl {
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateDecl *D) { return true; }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) {
return K >= TemplateFirst && K <= TemplateLast;
}
protected:
NamedDecl *TemplatedDecl;
@ -510,10 +511,9 @@ class FunctionTemplateDecl : public TemplateDecl {
NamedDecl *Decl);
// Implement isa/cast/dyncast support
static bool classof(const Decl *D)
{ return D->getKind() == FunctionTemplate; }
static bool classof(const FunctionTemplateDecl *D)
{ return true; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FunctionTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == FunctionTemplate; }
};
//===----------------------------------------------------------------------===//
@ -634,10 +634,9 @@ class TemplateTypeParmDecl : public TypeDecl {
bool isParameterPack() const { return ParameterPack; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == TemplateTypeParm;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTypeParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTypeParm; }
};
/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
@ -682,10 +681,9 @@ class NonTypeTemplateParmDecl
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == NonTypeTemplateParm;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
};
/// TemplateTemplateParmDecl - Declares a template template parameter,
@ -735,10 +733,9 @@ class TemplateTemplateParmDecl
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == TemplateTemplateParm;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
};
/// \brief Represents a class template specialization, which refers to
@ -903,9 +900,10 @@ class ClassTemplateSpecializationDecl
TemplateArgs[Arg].Profile(ID, Context);
}
static bool classof(const Decl *D) {
return D->getKind() == ClassTemplateSpecialization ||
D->getKind() == ClassTemplatePartialSpecialization;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K == ClassTemplateSpecialization ||
K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplateSpecializationDecl *) {
@ -1039,8 +1037,9 @@ class ClassTemplatePartialSpecializationDecl
// FIXME: Add Profile support!
static bool classof(const Decl *D) {
return D->getKind() == ClassTemplatePartialSpecialization;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K == ClassTemplatePartialSpecialization;
}
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
@ -1212,10 +1211,9 @@ class ClassTemplateDecl : public TemplateDecl {
}
// Implement isa/cast/dyncast support
static bool classof(const Decl *D)
{ return D->getKind() == ClassTemplate; }
static bool classof(const ClassTemplateDecl *D)
{ return true; }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ClassTemplateDecl *D) { return true; }
static bool classofKind(Kind K) { return K == ClassTemplate; }
virtual void Destroy(ASTContext& C);
};
@ -1293,9 +1291,8 @@ class FriendTemplateDecl : public Decl {
}
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) {
return D->getKind() == Decl::FriendTemplate;
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
static bool classof(const FriendTemplateDecl *D) { return true; }
};

View File

@ -274,30 +274,34 @@ class DeclarationName {
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
static int compare(DeclarationName LHS, DeclarationName RHS);
void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
bool operator<(DeclarationName LHS, DeclarationName RHS);
inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
return DeclarationName::compare(LHS, RHS) < 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
return RHS < LHS;
return DeclarationName::compare(LHS, RHS) > 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
return !(RHS < LHS);
return DeclarationName::compare(LHS, RHS) <= 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
return !(LHS < RHS);
return DeclarationName::compare(LHS, RHS) >= 0;
}
/// DeclarationNameTable - Used to store and retrieve DeclarationName

View File

@ -149,7 +149,8 @@ class Expr : public Stmt {
LV_DuplicateVectorComponents,
LV_InvalidExpression,
LV_MemberFunction,
LV_SubObjCPropertySetting
LV_SubObjCPropertySetting,
LV_SubObjCPropertyGetterSetting
};
isLvalueResult isLvalue(ASTContext &Ctx) const;
@ -179,7 +180,8 @@ class Expr : public Stmt {
MLV_ReadonlyProperty,
MLV_NoSetterProperty,
MLV_MemberFunction,
MLV_SubObjCPropertySetting
MLV_SubObjCPropertySetting,
MLV_SubObjCPropertyGetterSetting
};
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
SourceLocation *Loc = 0) const;
@ -192,6 +194,9 @@ class Expr : public Stmt {
return const_cast<Expr*>(this)->getBitField();
}
/// \brief Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
@ -563,7 +568,10 @@ class PredefinedExpr : public Expr {
enum IdentType {
Func,
Function,
PrettyFunction
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};
private:
@ -584,8 +592,7 @@ class PredefinedExpr : public Expr {
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
static std::string ComputeName(ASTContext &Context, IdentType IT,
const Decl *CurrentDecl);
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
@ -1745,7 +1752,7 @@ class ExplicitCastExpr : public CastExpr {
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
if (SC >= ExplicitCastExprClass && SC <= CStyleCastExprClass)
if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
return true;
if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;

View File

@ -241,10 +241,17 @@ class CXXBoolLiteralExpr : public Expr {
CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) :
Expr(CXXBoolLiteralExprClass, Ty, false, false), Value(val), Loc(l) {}
explicit CXXBoolLiteralExpr(EmptyShell Empty)
: Expr(CXXBoolLiteralExprClass, Empty) { }
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBoolLiteralExprClass;
}
@ -262,8 +269,14 @@ class CXXNullPtrLiteralExpr : public Expr {
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) :
Expr(CXXNullPtrLiteralExprClass, Ty, false, false), Loc(l) {}
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
: Expr(CXXNullPtrLiteralExprClass, Empty) { }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXNullPtrLiteralExprClass;
}
@ -544,6 +557,68 @@ class CXXBindTemporaryExpr : public Expr {
virtual child_iterator child_end();
};
/// CXXBindReferenceExpr - Represents binding an expression to a reference.
/// In the example:
///
/// 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).
class CXXBindReferenceExpr : public Expr {
// SubExpr - The expression being bound.
Stmt *SubExpr;
// ExtendsLifetime - Whether binding this reference extends the lifetime of
// the expression being bound. FIXME: Add C++ reference.
bool ExtendsLifetime;
/// RequiresTemporaryCopy - Whether binding the subexpression requires a
/// temporary copy.
bool RequiresTemporaryCopy;
CXXBindReferenceExpr(Expr *subexpr, bool ExtendsLifetime,
bool RequiresTemporaryCopy)
: Expr(CXXBindReferenceExprClass, subexpr->getType(), false, false),
SubExpr(subexpr), ExtendsLifetime(ExtendsLifetime),
RequiresTemporaryCopy(RequiresTemporaryCopy) { }
~CXXBindReferenceExpr() { }
protected:
virtual void DoDestroy(ASTContext &C);
public:
static CXXBindReferenceExpr *Create(ASTContext &C, Expr *SubExpr,
bool ExtendsLifetime,
bool RequiresTemporaryCopy);
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
void setSubExpr(Expr *E) { SubExpr = E; }
virtual SourceRange getSourceRange() const {
return SubExpr->getSourceRange();
}
/// requiresTemporaryCopy - Whether binding the subexpression requires a
/// temporary copy.
bool requiresTemporaryCopy() const { return RequiresTemporaryCopy; }
// extendsLifetime - Whether binding this reference extends the lifetime of
// the expression being bound. FIXME: Add C++ reference.
bool extendsLifetime() { return ExtendsLifetime; }
// Implement isa/cast/dyncast/etc.
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXBindReferenceExprClass;
}
static bool classof(const CXXBindReferenceExpr *) { return true; }
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
};
/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
CXXConstructorDecl *Constructor;
@ -551,6 +626,7 @@ class CXXConstructExpr : public Expr {
SourceLocation Loc;
bool Elidable : 1;
bool ZeroInitialization : 1;
bool BaseInitialization : 1;
Stmt **Args;
unsigned NumArgs;
@ -559,7 +635,8 @@ class CXXConstructExpr : public Expr {
SourceLocation Loc,
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization = false);
bool ZeroInitialization = false,
bool BaseInitialization = false);
~CXXConstructExpr() { }
virtual void DoDestroy(ASTContext &C);
@ -573,7 +650,8 @@ class CXXConstructExpr : public Expr {
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool ZeroInitialization = false);
bool ZeroInitialization = false,
bool BaseInitialization = false);
CXXConstructorDecl* getConstructor() const { return Constructor; }
@ -593,6 +671,11 @@ class CXXConstructExpr : public Expr {
ZeroInitialization = ZeroInit;
}
/// \brief Determines whether this constructor is actually constructing
/// a base class (rather than a complete object).
bool isBaseInitialization() const { return BaseInitialization; }
void setBaseInitialization(bool BI) { BaseInitialization = BI; }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
@ -779,15 +862,14 @@ class CXXNewExpr : public Expr {
SourceLocation EndLoc;
public:
CXXNewExpr(bool globalNew, FunctionDecl *operatorNew, Expr **placementArgs,
unsigned numPlaceArgs, bool ParenTypeId, Expr *arraySize,
CXXConstructorDecl *constructor, bool initializer,
CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
Expr **placementArgs, unsigned numPlaceArgs, bool ParenTypeId,
Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
SourceLocation startLoc, SourceLocation endLoc);
~CXXNewExpr() {
delete[] SubExprs;
}
virtual void DoDestroy(ASTContext &C);
QualType getAllocatedType() const {
assert(getType()->isPointerType());
@ -1059,6 +1141,112 @@ class UnaryTypeTraitExpr : public Expr {
virtual child_iterator child_end();
};
/// \brief A reference to an overloaded function set, either an
/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
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;
/// The common name of these declarations.
DeclarationName Name;
/// The scope specifier, if any.
NestedNameSpecifier *Qualifier;
/// The source range of the scope specifier.
SourceRange QualifierRange;
/// The location of the name.
SourceLocation NameLoc;
/// True if the name was a template-id.
bool HasExplicitTemplateArgs;
protected:
OverloadExpr(StmtClass K, 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)
{}
public:
/// Computes whether an unresolved lookup on the given declarations
/// and optional template arguments is type- and value-dependent.
static bool ComputeDependence(UnresolvedSetIterator Begin,
UnresolvedSetIterator End,
const TemplateArgumentListInfo *Args);
/// Finds the overloaded expression in the given expression of
/// OverloadTy.
///
/// \return the expression (which must be there) and true if it is
/// within an address-of operator.
static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
bool op = false;
E = E->IgnoreParens();
if (isa<UnaryOperator>(E))
op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
}
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
Results.append(Begin, End);
}
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; }
/// Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return Results.size(); }
/// Gets the name looked up.
DeclarationName getName() const { return Name; }
void setName(DeclarationName N) { Name = N; }
/// Gets the location of the name.
SourceLocation getNameLoc() const { return NameLoc; }
void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
/// Fetches the nested-name qualifier, if one was given.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// Fetches the range of the nested-name qualifier.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Determines whether this expression had an explicit
/// template argument list, e.g. f<int>.
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
}
ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
if (hasExplicitTemplateArgs())
return &getExplicitTemplateArgs();
return 0;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnresolvedLookupExprClass ||
T->getStmtClass() == UnresolvedMemberExprClass;
}
static bool classof(const OverloadExpr *) { return true; }
};
/// \brief A reference to a name which we were able to look up during
/// parsing but could not resolve to a specific declaration. This
/// arises in several ways:
@ -1069,23 +1257,7 @@ class UnaryTypeTraitExpr : public Expr {
/// These never include UnresolvedUsingValueDecls, which are always
/// class members and therefore appear only in
/// UnresolvedMemberLookupExprs.
class UnresolvedLookupExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls.
UnresolvedSet<4> Results;
/// The name declared.
DeclarationName Name;
/// The qualifier given, if any.
NestedNameSpecifier *Qualifier;
/// The source range of the nested name specifier.
SourceRange QualifierRange;
/// The location of the name.
SourceLocation NameLoc;
class UnresolvedLookupExpr : public OverloadExpr {
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function
/// call.
@ -1095,35 +1267,40 @@ class UnresolvedLookupExpr : public Expr {
/// trivially rederivable if we urgently need to kill this field.
bool Overloaded;
/// True if the name looked up had explicit template arguments.
/// This requires all the results to be function templates.
bool HasExplicitTemplateArgs;
/// The naming class (C++ [class.access.base]p5) of the lookup, if
/// any. This can generally be recalculated from the context chain,
/// but that can be fairly expensive for unqualified lookups. If we
/// want to improve memory use here, this could go in a union
/// against the qualified-lookup bits.
CXXRecordDecl *NamingClass;
UnresolvedLookupExpr(QualType T, bool Dependent,
UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
: Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
HasExplicitTemplateArgs(HasTemplateArgs)
: OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
Name, NameLoc, HasTemplateArgs),
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
{}
public:
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
bool ADL, bool Overloaded) {
return new(C) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
Dependent, Qualifier, QualifierRange,
Dependent, NamingClass,
Qualifier, QualifierRange,
Name, NameLoc, ADL, Overloaded, false);
}
static UnresolvedLookupExpr *Create(ASTContext &C,
bool Dependent,
CXXRecordDecl *NamingClass,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
DeclarationName Name,
@ -1131,20 +1308,6 @@ class UnresolvedLookupExpr : public Expr {
bool ADL,
const TemplateArgumentListInfo &Args);
/// Computes whether an unresolved lookup on the given declarations
/// and optional template arguments is type- and value-dependent.
static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
UnresolvedSetImpl::const_iterator End,
const TemplateArgumentListInfo *Args);
void addDecl(NamedDecl *Decl) {
Results.addDecl(Decl);
}
typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
/// True if this declaration should be extended by
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
@ -1152,25 +1315,20 @@ class UnresolvedLookupExpr : public Expr {
/// True if this lookup is overloaded.
bool isOverloaded() const { return Overloaded; }
/// Fetches the name looked up.
DeclarationName getName() const { return Name; }
/// Gets the location of the name.
SourceLocation getNameLoc() const { return NameLoc; }
/// Fetches the nested-name qualifier, if one was given.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// Fetches the range of the nested-name qualifier.
SourceRange getQualifierRange() const { return QualifierRange; }
/// Determines whether this lookup had explicit template arguments.
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
/// Gets the 'naming class' (in the sense of C++0x
/// [class.access.base]p5) of the lookup. This is the scope
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
// Note that, inconsistently with the explicit-template-argument AST
// nodes, users are *forbidden* from calling these methods on objects
// without explicit template arguments.
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(hasExplicitTemplateArgs());
return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
}
/// Gets a reference to the explicit template argument list.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
assert(hasExplicitTemplateArgs());
@ -1200,8 +1358,8 @@ class UnresolvedLookupExpr : public Expr {
}
virtual SourceRange getSourceRange() const {
SourceRange Range(NameLoc);
if (Qualifier) Range.setBegin(QualifierRange.getBegin());
SourceRange Range(getNameLoc());
if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
return Range;
}
@ -1456,11 +1614,24 @@ class CXXUnresolvedConstructExpr : public Expr {
arg_iterator arg_begin() { return reinterpret_cast<Expr**>(this + 1); }
arg_iterator arg_end() { return arg_begin() + NumArgs; }
typedef const Expr* const * const_arg_iterator;
const_arg_iterator arg_begin() const {
return reinterpret_cast<const Expr* const *>(this + 1);
}
const_arg_iterator arg_end() const {
return arg_begin() + NumArgs;
}
Expr *getArg(unsigned I) {
assert(I < NumArgs && "Argument index out-of-range");
return *(arg_begin() + I);
}
const Expr *getArg(unsigned I) const {
assert(I < NumArgs && "Argument index out-of-range");
return *(arg_begin() + I);
}
virtual SourceRange getSourceRange() const {
return SourceRange(TyBeginLoc, RParenLoc);
}
@ -1713,10 +1884,14 @@ class CXXDependentScopeMemberExpr : public Expr {
/// In the final AST, an explicit access always becomes a MemberExpr.
/// An implicit access may become either a MemberExpr or a
/// DeclRefExpr, depending on whether the member is static.
class UnresolvedMemberExpr : public Expr {
/// The results. These are undesugared, which is to say, they may
/// include UsingShadowDecls.
UnresolvedSet<4> Results;
class UnresolvedMemberExpr : public OverloadExpr {
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
/// \brief Whether the lookup results contain an unresolved using
/// declaration.
bool HasUnresolvedUsing : 1;
/// \brief The expression for the base pointer or class reference,
/// e.g., the \c x in x.f. This can be null if this is an 'unbased'
@ -1726,47 +1901,9 @@ class UnresolvedMemberExpr : public Expr {
/// \brief The type of the base expression; never null.
QualType BaseType;
/// \brief Whether this member expression used the '->' operator or
/// the '.' operator.
bool IsArrow : 1;
/// \brief Whether the lookup results contain an unresolved using
/// declaration.
bool HasUnresolvedUsing : 1;
/// \brief Whether this member expression has explicitly-specified template
/// arguments.
bool HasExplicitTemplateArgs : 1;
/// \brief The location of the '->' or '.' operator.
SourceLocation OperatorLoc;
/// \brief The nested-name-specifier that precedes the member name, if any.
NestedNameSpecifier *Qualifier;
/// \brief The source range covering the nested name specifier.
SourceRange QualifierRange;
/// \brief The member to which this member expression refers, which
/// can be a name or an overloaded operator.
DeclarationName MemberName;
/// \brief The location of the member name.
SourceLocation MemberLoc;
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
assert(HasExplicitTemplateArgs);
return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
}
UnresolvedMemberExpr(QualType T, bool Dependent,
bool HasUnresolvedUsing,
Expr *Base, QualType BaseType, bool IsArrow,
@ -1788,19 +1925,6 @@ class UnresolvedMemberExpr : public Expr {
SourceLocation MemberLoc,
const TemplateArgumentListInfo *TemplateArgs);
/// Adds a declaration to the unresolved set. By assumption, all of
/// these happen at initialization time and properties like
/// 'Dependent' and 'HasUnresolvedUsing' take them into account.
void addDecl(NamedDecl *Decl) {
Results.addDecl(Decl);
}
typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
unsigned getNumDecls() const { return Results.size(); }
/// \brief True if this is an implicit access, i.e. one in which the
/// member being accessed was not written in the source. The source
/// location of the operator is invalid in this case.
@ -1812,6 +1936,10 @@ class UnresolvedMemberExpr : public Expr {
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
const Expr *getBase() const {
assert(!isImplicitAccess());
return cast<Expr>(Base);
}
void setBase(Expr *E) { Base = E; }
QualType getBaseType() const { return BaseType; }
@ -1825,57 +1953,60 @@ class UnresolvedMemberExpr : public Expr {
SourceLocation getOperatorLoc() const { return OperatorLoc; }
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
/// \brief Retrieve the nested-name-specifier that qualifies the member
/// name.
NestedNameSpecifier *getQualifier() const { return Qualifier; }
/// \brief Retrieve the source range covering the nested-name-specifier
/// that qualifies the member name.
SourceRange getQualifierRange() const { return QualifierRange; }
/// \brief Retrieves the naming class of this lookup.
CXXRecordDecl *getNamingClass() const;
/// \brief Retrieve the name of the member that this expression
/// refers to.
DeclarationName getMemberName() const { return MemberName; }
void setMemberName(DeclarationName N) { MemberName = N; }
DeclarationName getMemberName() const { return getName(); }
void setMemberName(DeclarationName N) { setName(N); }
// \brief Retrieve the location of the name of the member that this
// expression refers to.
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
SourceLocation getMemberLoc() const { return getNameLoc(); }
void setMemberLoc(SourceLocation L) { setNameLoc(L); }
/// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>.
bool hasExplicitTemplateArgs() const {
return HasExplicitTemplateArgs;
/// \brief Retrieve the explicit template argument list that followed the
/// member template name.
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
assert(hasExplicitTemplateArgs());
return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Retrieve the explicit template argument list that followed the
/// member template name, if any.
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
assert(hasExplicitTemplateArgs());
return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
}
/// \brief Copies the template arguments into the given structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
getExplicitTemplateArgs()->copyInto(List);
getExplicitTemplateArgs().copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following
/// the member name ('<').
SourceLocation getLAngleLoc() const {
return getExplicitTemplateArgs()->LAngleLoc;
return getExplicitTemplateArgs().LAngleLoc;
}
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
return getExplicitTemplateArgs()->getTemplateArgs();
return getExplicitTemplateArgs().getTemplateArgs();
}
/// \brief Retrieve the number of template arguments provided as
/// part of this template-id.
unsigned getNumTemplateArgs() const {
return getExplicitTemplateArgs()->NumTemplateArgs;
return getExplicitTemplateArgs().NumTemplateArgs;
}
/// \brief Retrieve the location of the right angle bracket
/// following the template arguments ('>').
SourceLocation getRAngleLoc() const {
return getExplicitTemplateArgs()->RAngleLoc;
return getExplicitTemplateArgs().RAngleLoc;
}
virtual SourceRange getSourceRange() const {
@ -1885,12 +2016,12 @@ class UnresolvedMemberExpr : public Expr {
else if (getQualifier())
Range.setBegin(getQualifierRange().getBegin());
else
Range.setBegin(MemberLoc);
Range.setBegin(getMemberLoc());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
else
Range.setEnd(MemberLoc);
Range.setEnd(getMemberLoc());
return Range;
}
@ -1904,6 +2035,13 @@ class UnresolvedMemberExpr : public Expr {
virtual child_iterator child_end();
};
inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
if (isa<UnresolvedLookupExpr>(this))
return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
else
return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
}
} // end namespace clang
#endif

View File

@ -367,7 +367,7 @@ class ObjCMessageExpr : public Expr {
public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is not known.
ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@ -375,13 +375,13 @@ class ObjCMessageExpr : public Expr {
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is known.
// FIXME: clsName should be typed to ObjCInterfaceType
ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
// constructor for instance messages.
ObjCMessageExpr(Expr *receiver, Selector selInfo,
ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@ -389,9 +389,7 @@ class ObjCMessageExpr : public Expr {
explicit ObjCMessageExpr(EmptyShell Empty)
: Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
~ObjCMessageExpr() {
delete [] SubExprs;
}
virtual void DoDestroy(ASTContext &C);
/// getReceiver - Returns the receiver of the message expression.
/// This can be NULL if the message is for class methods. For

View File

@ -102,6 +102,7 @@ class Stmt {
#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"
};
private:
@ -1120,21 +1121,27 @@ class AsmStmt : public Stmt {
unsigned NumOutputs;
unsigned NumInputs;
unsigned NumClobbers;
llvm::SmallVector<std::string, 4> Names;
llvm::SmallVector<StringLiteral*, 4> Constraints;
llvm::SmallVector<Stmt*, 4> Exprs;
// FIXME: If we wanted to, we could allocate all of these in one big array.
IdentifierInfo **Names;
StringLiteral **Constraints;
Stmt **Exprs;
StringLiteral **Clobbers;
llvm::SmallVector<StringLiteral*, 4> Clobbers;
protected:
virtual void DoDestroy(ASTContext &Ctx);
public:
AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm,
unsigned numoutputs, unsigned numinputs,
std::string *names, StringLiteral **constraints,
AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
bool msasm, unsigned numoutputs, unsigned numinputs,
IdentifierInfo **names, StringLiteral **constraints,
Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
StringLiteral **clobbers, SourceLocation rparenloc);
/// \brief Build an empty inline-assembly statement.
explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { }
explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
SourceLocation getAsmLoc() const { return AsmLoc; }
void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@ -1208,14 +1215,21 @@ class AsmStmt : public Stmt {
unsigned getNumOutputs() const { return NumOutputs; }
const std::string &getOutputName(unsigned i) const {
IdentifierInfo *getOutputIdentifier(unsigned i) const {
return Names[i];
}
llvm::StringRef getOutputName(unsigned i) const {
if (IdentifierInfo *II = getOutputIdentifier(i))
return II->getName();
return llvm::StringRef();
}
/// getOutputConstraint - Return the constraint string for the specified
/// output operand. All output constraints are known to be non-empty (either
/// '=' or '+').
std::string getOutputConstraint(unsigned i) const;
llvm::StringRef getOutputConstraint(unsigned i) const;
const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
return Constraints[i];
@ -1224,7 +1238,6 @@ class AsmStmt : public Stmt {
return Constraints[i];
}
Expr *getOutputExpr(unsigned i);
const Expr *getOutputExpr(unsigned i) const {
@ -1246,13 +1259,20 @@ class AsmStmt : public Stmt {
unsigned getNumInputs() const { return NumInputs; }
const std::string &getInputName(unsigned i) const {
IdentifierInfo *getInputIdentifier(unsigned i) const {
return Names[i + NumOutputs];
}
llvm::StringRef getInputName(unsigned i) const {
if (IdentifierInfo *II = getInputIdentifier(i))
return II->getName();
return llvm::StringRef();
}
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
std::string getInputConstraint(unsigned i) const;
llvm::StringRef getInputConstraint(unsigned i) const;
const StringLiteral *getInputConstraintLiteral(unsigned i) const {
return Constraints[i + NumOutputs];
@ -1261,32 +1281,31 @@ class AsmStmt : public Stmt {
return Constraints[i + NumOutputs];
}
Expr *getInputExpr(unsigned i);
const Expr *getInputExpr(unsigned i) const {
return const_cast<AsmStmt*>(this)->getInputExpr(i);
}
void setOutputsAndInputs(unsigned NumOutputs,
unsigned NumInputs,
const std::string *Names,
StringLiteral **Constraints,
Stmt **Exprs);
void setOutputsAndInputsAndClobbers(ASTContext &C,
IdentifierInfo **Names,
StringLiteral **Constraints,
Stmt **Exprs,
unsigned NumOutputs,
unsigned NumInputs,
StringLiteral **Clobbers,
unsigned NumClobbers);
//===--- Other ---===//
/// getNamedOperand - Given a symbolic operand reference like %[foo],
/// translate this into a numeric value needed to reference the same operand.
/// This returns -1 if the operand name is invalid.
int getNamedOperand(const std::string &SymbolicName) const;
int getNamedOperand(llvm::StringRef SymbolicName) const;
unsigned getNumClobbers() const { return Clobbers.size(); }
unsigned getNumClobbers() const { return NumClobbers; }
StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers);
virtual SourceRange getSourceRange() const {
return SourceRange(AsmLoc, RParenLoc);
@ -1301,19 +1320,19 @@ class AsmStmt : public Stmt {
typedef ConstExprIterator const_inputs_iterator;
inputs_iterator begin_inputs() {
return Exprs.data() + NumOutputs;
return &Exprs[0] + NumOutputs;
}
inputs_iterator end_inputs() {
return Exprs.data() + NumOutputs + NumInputs;
return &Exprs[0] + NumOutputs + NumInputs;
}
const_inputs_iterator begin_inputs() const {
return Exprs.data() + NumOutputs;
return &Exprs[0] + NumOutputs;
}
const_inputs_iterator end_inputs() const {
return Exprs.data() + NumOutputs + NumInputs;
return &Exprs[0] + NumOutputs + NumInputs;
}
// Output expr iterators.
@ -1322,27 +1341,17 @@ class AsmStmt : public Stmt {
typedef ConstExprIterator const_outputs_iterator;
outputs_iterator begin_outputs() {
return Exprs.data();
return &Exprs[0];
}
outputs_iterator end_outputs() {
return Exprs.data() + NumOutputs;
return &Exprs[0] + NumOutputs;
}
const_outputs_iterator begin_outputs() const {
return Exprs.data();
return &Exprs[0];
}
const_outputs_iterator end_outputs() const {
return Exprs.data() + NumOutputs;
}
// Input name iterator.
const std::string *begin_output_names() const {
return &Names[0];
}
const std::string *end_output_names() const {
return &Names[0] + NumOutputs;
return &Exprs[0] + NumOutputs;
}
// Child iterators

View File

@ -59,31 +59,42 @@ class CXXCatchStmt : public Stmt {
///
class CXXTryStmt : public Stmt {
SourceLocation TryLoc;
// First place is the guarded CompoundStatement. Subsequent are the handlers.
// More than three handlers should be rare.
llvm::SmallVector<Stmt*, 4> Stmts;
unsigned NumHandlers;
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
public:
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
Stmt **handlers, unsigned numHandlers);
static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const { return Stmts.back()->getLocEnd(); }
SourceLocation getEndLoc() const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return Stmts[NumHandlers]->getLocEnd();
}
CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); }
CompoundStmt *getTryBlock() {
Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]);
}
const CompoundStmt *getTryBlock() const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]);
}
unsigned getNumHandlers() const { return Stmts.size() - 1; }
unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
}
const CXXCatchStmt *getHandler(unsigned i) const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
}

View File

@ -68,8 +68,7 @@ STMT(CXXTryStmt , Stmt)
LAST_STMT(CXXTryStmt)
// Expressions.
ABSTRACT_EXPR(Expr , Stmt)
FIRST_EXPR(Expr)
ABSTRACT_EXPR(Expr , Stmt)
EXPR(PredefinedExpr , Expr)
EXPR(DeclRefExpr , Expr)
EXPR(IntegerLiteral , Expr)
@ -83,12 +82,12 @@ EXPR(SizeOfAlignOfExpr , Expr)
EXPR(ArraySubscriptExpr , Expr)
EXPR(CallExpr , Expr)
EXPR(MemberExpr , Expr)
EXPR(CastExpr , Expr)
ABSTRACT_EXPR(CastExpr , Expr)
EXPR(BinaryOperator , Expr)
EXPR(CompoundAssignOperator, BinaryOperator)
EXPR(ConditionalOperator , Expr)
EXPR(ImplicitCastExpr , CastExpr)
EXPR(ExplicitCastExpr , CastExpr)
ABSTRACT_EXPR(ExplicitCastExpr, CastExpr)
EXPR(CStyleCastExpr , ExplicitCastExpr)
EXPR(CompoundLiteralExpr , Expr)
EXPR(ExtVectorElementExpr , Expr)
@ -129,6 +128,7 @@ EXPR(UnaryTypeTraitExpr , Expr)
EXPR(DependentScopeDeclRefExpr , Expr)
EXPR(CXXConstructExpr , Expr)
EXPR(CXXBindTemporaryExpr , Expr)
EXPR(CXXBindReferenceExpr , Expr)
EXPR(CXXExprWithTemporaries , Expr)
EXPR(CXXTemporaryObjectExpr , CXXConstructExpr)
EXPR(CXXUnresolvedConstructExpr, Expr)
@ -152,6 +152,7 @@ EXPR(ShuffleVectorExpr , Expr)
EXPR(BlockExpr , Expr)
EXPR(BlockDeclRefExpr , Expr)
FIRST_EXPR(PredefinedExpr)
LAST_EXPR(BlockDeclRefExpr)
#undef ABSTRACT_EXPR

View File

@ -105,6 +105,7 @@ 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 STMT(CLASS, PARENT) \
case Stmt::CLASS ## Class: DISPATCH(CLASS, CLASS);
#include "clang/AST/StmtNodes.def"

View File

@ -16,6 +16,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
@ -750,24 +751,22 @@ class Type {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
#define LAST_TYPE(Class) TypeLast = Class,
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
TagFirst = Record, TagLast = Enum
};
protected:
enum { TypeClassBitSize = 6 };
private:
QualType CanonicalType;
/// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
bool Dependent : 1;
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
unsigned TC : 8;
/// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
/// Note that this should stay at the end of the ivars for Type so that
/// subclasses can pack their bitfields into the same word.
unsigned TC : TypeClassBitSize;
bool Dependent : 1;
Type(const Type&); // DO NOT IMPLEMENT.
void operator=(const Type&); // DO NOT IMPLEMENT.
@ -776,7 +775,7 @@ class Type {
Type *this_() { return this; }
Type(TypeClass tc, QualType Canonical, bool dependent)
: CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical),
Dependent(dependent), TC(tc) {}
TC(tc), Dependent(dependent) {}
virtual ~Type() {}
virtual void Destroy(ASTContext& C);
friend class ASTContext;
@ -974,6 +973,9 @@ class Type {
const char *getTypeClassName() const;
/// \brief Determine the linkage of this type.
virtual Linkage getLinkage() const;
QualType getCanonicalTypeInternal() const { return CanonicalType; }
void dump() const;
static bool classof(const Type *) { return true; }
@ -1062,6 +1064,8 @@ class BuiltinType : public Type {
return TypeKind >= Float && TypeKind <= LongDouble;
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
static bool classof(const BuiltinType *) { return true; }
};
@ -1089,6 +1093,8 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
ID.AddPointer(Element.getAsOpaquePtr());
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
static bool classof(const ComplexType *) { return true; }
};
@ -1116,6 +1122,8 @@ class PointerType : public Type, public llvm::FoldingSetNode {
ID.AddPointer(Pointee.getAsOpaquePtr());
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
static bool classof(const PointerType *) { return true; }
};
@ -1146,6 +1154,8 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
ID.AddPointer(Pointee.getAsOpaquePtr());
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == BlockPointer;
}
@ -1183,7 +1193,8 @@ class ReferenceType : public Type, public llvm::FoldingSetNode {
}
public:
bool isSpelledAsLValue() const { return SpelledAsLValue; }
bool isInnerRef() const { return InnerRef; }
QualType getPointeeTypeAsWritten() const { return PointeeType; }
QualType getPointeeType() const {
// FIXME: this might strip inner qualifiers; okay?
@ -1203,6 +1214,8 @@ class ReferenceType : public Type, public llvm::FoldingSetNode {
ID.AddBoolean(SpelledAsLValue);
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == LValueReference ||
T->getTypeClass() == RValueReference;
@ -1277,6 +1290,8 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
ID.AddPointer(Class);
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == MemberPointer;
}
@ -1328,6 +1343,8 @@ class ArrayType : public Type, public llvm::FoldingSetNode {
}
unsigned getIndexTypeCVRQualifiers() const { return IndexTypeQuals; }
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
T->getTypeClass() == VariableArray ||
@ -1576,7 +1593,8 @@ class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
/// bytes. Since the constructor takes the number of vector elements, the
/// bytes; or from an Altivec __vector or vector declaration.
/// Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
protected:
@ -1586,13 +1604,21 @@ class VectorType : public Type, public llvm::FoldingSetNode {
/// NumElements - The number of elements in the vector.
unsigned NumElements;
VectorType(QualType vecType, unsigned nElements, QualType canonType) :
/// AltiVec - True if this is for an Altivec vector.
bool AltiVec;
/// Pixel - True if this is for an Altivec vector pixel.
bool Pixel;
VectorType(QualType vecType, unsigned nElements, QualType canonType,
bool isAltiVec, bool isPixel) :
Type(Vector, canonType, vecType->isDependentType()),
ElementType(vecType), NumElements(nElements) {}
ElementType(vecType), NumElements(nElements),
AltiVec(isAltiVec), Pixel(isPixel) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType)
QualType canonType, bool isAltiVec, bool isPixel)
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
NumElements(nElements) {}
NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
public:
@ -1602,15 +1628,26 @@ class VectorType : public Type, public llvm::FoldingSetNode {
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
bool isAltiVec() const { return AltiVec; }
bool isPixel() const { return Pixel; }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType(), getNumElements(), getTypeClass());
Profile(ID, getElementType(), getNumElements(), getTypeClass(),
AltiVec, Pixel);
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
unsigned NumElements, TypeClass TypeClass) {
unsigned NumElements, TypeClass TypeClass,
bool isAltiVec, bool isPixel) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
ID.AddBoolean(isAltiVec);
ID.AddBoolean(isPixel);
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
}
@ -1624,7 +1661,7 @@ class VectorType : public Type, public llvm::FoldingSetNode {
/// points, colors, and textures (modeled after OpenGL Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
VectorType(ExtVector, vecType, nElements, canonType) {}
VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
friend class ASTContext; // ASTContext creates these.
public:
static int getPointAccessorIdx(char c) {
@ -1723,6 +1760,8 @@ class FunctionType : public Type {
bool getNoReturnAttr() const { return NoReturn; }
CallingConv getCallConv() const { return (CallingConv)CallConv; }
static llvm::StringRef getNameForCallConv(CallingConv CC);
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto ||
T->getTypeClass() == FunctionProto;
@ -1745,14 +1784,17 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getResultType(), getNoReturnAttr());
Profile(ID, getResultType(), getNoReturnAttr(), getCallConv());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
bool NoReturn) {
bool NoReturn, CallingConv CallConv) {
ID.AddInteger(CallConv);
ID.AddInteger(NoReturn);
ID.AddPointer(ResultType.getAsOpaquePtr());
}
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
@ -1856,6 +1898,8 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
@ -1867,7 +1911,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
bool isVariadic, unsigned TypeQuals,
bool hasExceptionSpec, bool anyExceptionSpec,
unsigned NumExceptions, exception_iterator Exs,
bool NoReturn);
bool NoReturn, CallingConv CallConv);
};
@ -1878,8 +1922,9 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
class UnresolvedUsingType : public Type {
UnresolvedUsingTypenameDecl *Decl;
UnresolvedUsingType(UnresolvedUsingTypenameDecl *D)
: Type(UnresolvedUsing, QualType(), true), Decl(D) {}
UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
: Type(UnresolvedUsing, QualType(), true),
Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {}
friend class ASTContext; // ASTContext creates these.
public:
@ -1906,8 +1951,9 @@ class UnresolvedUsingType : public Type {
class TypedefType : public Type {
TypedefDecl *Decl;
protected:
TypedefType(TypeClass tc, TypedefDecl *D, QualType can)
: Type(tc, can, can->isDependentType()), Decl(D) {
TypedefType(TypeClass tc, const TypedefDecl *D, QualType can)
: Type(tc, can, can->isDependentType()),
Decl(const_cast<TypedefDecl*>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
@ -1950,8 +1996,12 @@ class TypeOfExprType : public Type {
static bool classof(const TypeOfExprType *) { return true; }
};
/// Subclass of TypeOfExprType that is used for canonical, dependent
/// \brief Internal representation of canonical, dependent
/// typeof(expr) types.
///
/// This class is used internally by the ASTContext to manage
/// canonical, dependent types, only. Clients will only see instances
/// of this class via TypeOfExprType nodes.
class DependentTypeOfExprType
: public TypeOfExprType, public llvm::FoldingSetNode {
ASTContext &Context;
@ -2018,8 +2068,12 @@ class DecltypeType : public Type {
static bool classof(const DecltypeType *) { return true; }
};
/// Subclass of DecltypeType that is used for canonical, dependent
/// C++0x decltype types.
/// \brief Internal representation of canonical, dependent
/// decltype(expr) types.
///
/// This class is used internally by the ASTContext to manage
/// canonical, dependent types, only. Clients will only see instances
/// of this class via DecltypeType nodes.
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
ASTContext &Context;
@ -2048,7 +2102,7 @@ class TagType : public Type {
friend class TagDecl;
protected:
TagType(TypeClass TC, TagDecl *D, QualType can);
TagType(TypeClass TC, const TagDecl *D, QualType can);
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@ -2058,6 +2112,8 @@ class TagType : public Type {
bool isBeingDefined() const { return decl.getInt(); }
void setBeingDefined(bool Def) const { decl.setInt(Def? 1 : 0); }
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
}
@ -2070,10 +2126,10 @@ class TagType : public Type {
/// to detect TagType objects of structs/unions/classes.
class RecordType : public TagType {
protected:
explicit RecordType(RecordDecl *D)
: TagType(Record, reinterpret_cast<TagDecl*>(D), QualType()) { }
explicit RecordType(const RecordDecl *D)
: TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) { }
explicit RecordType(TypeClass TC, RecordDecl *D)
: TagType(TC, reinterpret_cast<TagDecl*>(D), QualType()) { }
: TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@ -2103,8 +2159,8 @@ class RecordType : public TagType {
/// EnumType - This is a helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of enums.
class EnumType : public TagType {
explicit EnumType(EnumDecl *D)
: TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
explicit EnumType(const EnumDecl *D)
: TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@ -2512,12 +2568,12 @@ class TypenameType : public Type, public llvm::FoldingSetNode {
class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
ObjCInterfaceDecl *Decl;
// List of protocols for this protocol conforming object type
// List is sorted on protocol name. No protocol is enterred more than once.
ObjCProtocolDecl **Protocols;
/// \brief The number of protocols stored after the ObjCInterfaceType node.
/// The list of protocols is sorted on protocol name. No protocol is enterred
/// more than once.
unsigned NumProtocols;
ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D,
ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
public:
@ -2529,14 +2585,20 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
/// \brief Retrieve the Ith protocol.
ObjCProtocolDecl *getProtocol(unsigned I) const {
assert(I < getNumProtocols() && "Out-of-range protocol access");
return qual_begin()[I];
}
/// qual_iterator and friends: this provides access to the (potentially empty)
/// list of protocols qualifying this interface.
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
return Protocols;
return reinterpret_cast<qual_iterator>(this + 1);
}
qual_iterator qual_end() const {
return Protocols ? Protocols + NumProtocols : 0;
return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@ -2546,7 +2608,10 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID,
const ObjCInterfaceDecl *Decl,
ObjCProtocolDecl **protocols, unsigned NumProtocols);
ObjCProtocolDecl * const *protocols,
unsigned NumProtocols);
virtual Linkage getLinkage() const;
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCInterface;
@ -2562,12 +2627,14 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
QualType PointeeType; // A builtin or interface type.
// List of protocols for this protocol conforming object type
// List is sorted on protocol name. No protocol is entered more than once.
ObjCProtocolDecl **Protocols;
/// \brief The number of protocols stored after the ObjCObjectPointerType
/// node.
///
/// The list of protocols is sorted on protocol name. No protocol is enterred
/// more than once.
unsigned NumProtocols;
ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T,
ObjCObjectPointerType(QualType Canonical, QualType T,
ObjCProtocolDecl **Protos, unsigned NumP);
friend class ASTContext; // ASTContext creates these.
@ -2614,10 +2681,10 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
typedef ObjCProtocolDecl* const * qual_iterator;
qual_iterator qual_begin() const {
return Protocols;
return reinterpret_cast<qual_iterator> (this + 1);
}
qual_iterator qual_end() const {
return Protocols ? Protocols + NumProtocols : NULL;
return qual_begin() + NumProtocols;
}
bool qual_empty() const { return NumProtocols == 0; }
@ -2625,12 +2692,21 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
/// interface type, or 0 if there are none.
unsigned getNumProtocols() const { return NumProtocols; }
/// \brief Retrieve the Ith protocol.
ObjCProtocolDecl *getProtocol(unsigned I) const {
assert(I < getNumProtocols() && "Out-of-range protocol access");
return qual_begin()[I];
}
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
virtual Linkage getLinkage() const;
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
ObjCProtocolDecl **protocols, unsigned NumProtocols);
ObjCProtocolDecl *const *protocols,
unsigned NumProtocols);
static bool classof(const Type *T) {
return T->getTypeClass() == ObjCObjectPointer;
}

View File

@ -87,6 +87,11 @@ DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
#ifdef LAST_TYPE
LAST_TYPE(ObjCObjectPointer)
#undef LAST_TYPE
#endif
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
LEAF_TYPE(Enum)

View File

@ -16,7 +16,6 @@
#define LLVM_CLANG_AST_UNRESOLVEDSET_H
#include <iterator>
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "clang/Basic/Specifiers.h"
@ -24,12 +23,58 @@ namespace clang {
class NamedDecl;
/// A POD class for pairing a NamedDecl* with an access specifier.
/// Can be put into unions.
class DeclAccessPair {
NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
enum { Mask = 0x3 };
public:
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
DeclAccessPair p;
p.set(D, AS);
return p;
}
NamedDecl *getDecl() const {
return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
}
AccessSpecifier getAccess() const {
return AccessSpecifier(Mask & (uintptr_t) Ptr);
}
void setDecl(NamedDecl *D) {
set(D, getAccess());
}
void setAccess(AccessSpecifier AS) {
set(getDecl(), AS);
}
void set(NamedDecl *D, AccessSpecifier AS) {
Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
reinterpret_cast<uintptr_t>(D));
}
operator NamedDecl*() const { return getDecl(); }
NamedDecl *operator->() const { return getDecl(); }
};
}
// Take a moment to tell SmallVector that this is POD.
namespace llvm {
template<typename> struct isPodLike;
template<> struct isPodLike<clang::DeclAccessPair> {
static const bool value = true;
};
}
namespace clang {
/// The iterator over UnresolvedSets. Serves as both the const and
/// non-const iterator.
class UnresolvedSetIterator {
typedef llvm::PointerIntPair<NamedDecl*, 2> DeclEntry;
typedef llvm::SmallVectorImpl<DeclEntry> DeclsTy;
private:
typedef llvm::SmallVectorImpl<DeclAccessPair> DeclsTy;
typedef DeclsTy::iterator IteratorTy;
IteratorTy ir;
@ -47,8 +92,8 @@ class UnresolvedSetIterator {
typedef NamedDecl *reference;
typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category;
NamedDecl *getDecl() const { return ir->getPointer(); }
AccessSpecifier getAccess() const { return AccessSpecifier(ir->getInt()); }
NamedDecl *getDecl() const { return ir->getDecl(); }
AccessSpecifier getAccess() const { return ir->getAccess(); }
NamedDecl *operator*() const { return getDecl(); }
@ -87,7 +132,6 @@ class UnresolvedSetIterator {
/// in a lot of places, but isn't really worth breaking into its own
/// header right now.
class UnresolvedSetImpl {
typedef UnresolvedSetIterator::DeclEntry DeclEntry;
typedef UnresolvedSetIterator::DeclsTy DeclsTy;
// Don't allow direct construction, and only permit subclassing by
@ -114,7 +158,7 @@ class UnresolvedSetImpl {
}
void addDecl(NamedDecl *D, AccessSpecifier AS) {
decls().push_back(DeclEntry(D, AS));
decls().push_back(DeclAccessPair::make(D, AS));
}
/// Replaces the given declaration with the new one, once.
@ -122,19 +166,24 @@ class UnresolvedSetImpl {
/// \return true if the set changed
bool replace(const NamedDecl* Old, NamedDecl *New) {
for (DeclsTy::iterator I = decls().begin(), E = decls().end(); I != E; ++I)
if (I->getPointer() == Old)
return (I->setPointer(New), true);
if (I->getDecl() == Old)
return (I->setDecl(New), true);
return false;
}
/// Replaces the declaration at the given iterator with the new one,
/// preserving the original access bits.
void replace(iterator I, NamedDecl *New) {
I.ir->setPointer(New);
I.ir->setDecl(New);
}
void replace(iterator I, NamedDecl *New, AccessSpecifier AS) {
*I.ir = DeclEntry(New, AS);
I.ir->set(New, AS);
}
void erase(unsigned I) {
decls()[I] = decls().back();
decls().pop_back();
}
void erase(iterator I) {
@ -142,6 +191,10 @@ class UnresolvedSetImpl {
decls().pop_back();
}
void setAccess(iterator I, AccessSpecifier AS) {
I.ir->setAccess(AS);
}
void clear() { decls().clear(); }
void set_size(unsigned N) { decls().set_size(N); }
@ -152,41 +205,8 @@ class UnresolvedSetImpl {
decls().append(I.ir, E.ir);
}
/// A proxy reference for implementing operator[].
class Proxy {
DeclEntry &Ref;
friend class UnresolvedSetImpl;
Proxy(DeclEntry &Ref) : Ref(Ref) {}
public:
NamedDecl *getDecl() const { return Ref.getPointer(); }
void setDecl(NamedDecl *D) { Ref.setPointer(D); }
AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
void setAccess(AccessSpecifier AS) const { Ref.setInt(AS); }
NamedDecl* operator->() const { return getDecl(); }
operator NamedDecl*() const { return getDecl(); }
Proxy &operator=(const Proxy &D) { Ref = D.Ref; return *this; }
};
Proxy operator[](unsigned I) { return Proxy(decls()[I]); }
/// A proxy reference for implementing operator[] const.
class ConstProxy {
const DeclEntry &Ref;
friend class UnresolvedSetImpl;
ConstProxy(const DeclEntry &Ref) : Ref(Ref) {}
public:
NamedDecl *getDecl() const { return Ref.getPointer(); }
AccessSpecifier getAccess() const { return AccessSpecifier(Ref.getInt()); }
NamedDecl *operator->() const { return getDecl(); }
operator NamedDecl*() const { return getDecl(); }
};
ConstProxy operator[](unsigned I) const { return ConstProxy(decls()[I]); }
DeclAccessPair &operator[](unsigned I) { return decls()[I]; }
const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; }
private:
// These work because the only permitted subclass is UnresolvedSetImpl
@ -202,7 +222,7 @@ class UnresolvedSetImpl {
/// A set of unresolved declarations
template <unsigned InlineCapacity> class UnresolvedSet :
public UnresolvedSetImpl {
llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls;
llvm::SmallVector<DeclAccessPair, InlineCapacity> Decls;
};

View File

@ -0,0 +1,279 @@
//==- PrintfFormatStrings.h - Analysis of printf format strings --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Handling of format string in printf and friends. The structure of format
// strings for fprintf() are described in C99 7.19.6.1.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
#define LLVM_CLANG_FPRINTF_FORMAT_H
#include "clang/AST/CanonicalType.h"
namespace clang {
class ASTContext;
namespace analyze_printf {
class ArgTypeResult {
public:
enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy,
WCStrTy };
private:
const Kind K;
QualType T;
ArgTypeResult(bool) : K(InvalidTy) {}
public:
ArgTypeResult(Kind k = UnknownTy) : K(k) {}
ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
static ArgTypeResult Invalid() { return ArgTypeResult(true); }
bool isValid() const { return K != InvalidTy; }
const QualType *getSpecificType() const {
return K == SpecificTy ? &T : 0;
}
bool matchesType(ASTContext &C, QualType argTy) const;
bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
QualType getRepresentativeType(ASTContext &C) const;
};
class ConversionSpecifier {
public:
enum Kind {
InvalidSpecifier = 0,
// C99 conversion specifiers.
dArg, // 'd'
iArg, // 'i',
oArg, // 'o',
uArg, // 'u',
xArg, // 'x',
XArg, // 'X',
fArg, // 'f',
FArg, // 'F',
eArg, // 'e',
EArg, // 'E',
gArg, // 'g',
GArg, // 'G',
aArg, // 'a',
AArg, // 'A',
IntAsCharArg, // 'c'
CStrArg, // 's'
VoidPtrArg, // 'p'
OutIntPtrArg, // 'n'
PercentArg, // '%'
// Objective-C specific specifiers.
ObjCObjArg, // '@'
// GlibC specific specifiers.
PrintErrno, // 'm'
// Specifier ranges.
IntArgBeg = dArg,
IntArgEnd = iArg,
UIntArgBeg = oArg,
UIntArgEnd = XArg,
DoubleArgBeg = fArg,
DoubleArgEnd = AArg,
C99Beg = IntArgBeg,
C99End = DoubleArgEnd,
ObjCBeg = ObjCObjArg,
ObjCEnd = ObjCObjArg
};
ConversionSpecifier()
: Position(0), kind(InvalidSpecifier) {}
ConversionSpecifier(const char *pos, Kind k)
: Position(pos), kind(k) {}
const char *getStart() const {
return Position;
}
llvm::StringRef getCharacters() const {
return llvm::StringRef(getStart(), getLength());
}
bool consumesDataArgument() const {
switch (kind) {
case PercentArg:
case PrintErrno:
return false;
default:
return true;
}
}
bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
bool isIntArg() const { return kind >= dArg && kind <= iArg; }
bool isUIntArg() const { return kind >= oArg && kind <= XArg; }
bool isDoubleArg() const { return kind >= fArg && kind <= AArg; }
Kind getKind() const { return kind; }
unsigned getLength() const {
// Conversion specifiers currently only are represented by
// single characters, but we be flexible.
return 1;
}
private:
const char *Position;
Kind kind;
};
enum LengthModifier {
None,
AsChar, // 'hh'
AsShort, // 'h'
AsLong, // 'l'
AsLongLong, // 'll', 'q' (BSD, deprecated)
AsIntMax, // 'j'
AsSizeT, // 'z'
AsPtrDiff, // 't'
AsLongDouble, // 'L'
AsWideChar = AsLong // for '%ls'
};
class OptionalAmount {
public:
enum HowSpecified { NotSpecified, Constant, Arg };
OptionalAmount(HowSpecified h, const char *st)
: start(st), hs(h), amt(0) {}
OptionalAmount()
: start(0), hs(NotSpecified), amt(0) {}
OptionalAmount(unsigned i, const char *st)
: start(st), hs(Constant), amt(i) {}
HowSpecified getHowSpecified() const { return hs; }
bool hasDataArgument() const { return hs == Arg; }
unsigned getConstantAmount() const {
assert(hs == Constant);
return amt;
}
const char *getStart() const {
return start;
}
ArgTypeResult getArgType(ASTContext &Ctx) const;
private:
const char *start;
HowSpecified hs;
unsigned amt;
};
class FormatSpecifier {
LengthModifier LM;
unsigned IsLeftJustified : 1;
unsigned HasPlusPrefix : 1;
unsigned HasSpacePrefix : 1;
unsigned HasAlternativeForm : 1;
unsigned HasLeadingZeroes : 1;
unsigned flags : 5;
ConversionSpecifier CS;
OptionalAmount FieldWidth;
OptionalAmount Precision;
public:
FormatSpecifier() : LM(None),
IsLeftJustified(0), HasPlusPrefix(0), HasSpacePrefix(0),
HasAlternativeForm(0), HasLeadingZeroes(0) {}
static FormatSpecifier Parse(const char *beg, const char *end);
// Methods for incrementally constructing the FormatSpecifier.
void setConversionSpecifier(const ConversionSpecifier &cs) {
CS = cs;
}
void setLengthModifier(LengthModifier lm) {
LM = lm;
}
void setIsLeftJustified() { IsLeftJustified = 1; }
void setHasPlusPrefix() { HasPlusPrefix = 1; }
void setHasSpacePrefix() { HasSpacePrefix = 1; }
void setHasAlternativeForm() { HasAlternativeForm = 1; }
void setHasLeadingZeros() { HasLeadingZeroes = 1; }
// Methods for querying the format specifier.
const ConversionSpecifier &getConversionSpecifier() const {
return CS;
}
LengthModifier getLengthModifier() const {
return LM;
}
const OptionalAmount &getFieldWidth() const {
return FieldWidth;
}
void setFieldWidth(const OptionalAmount &Amt) {
FieldWidth = Amt;
}
void setPrecision(const OptionalAmount &Amt) {
Precision = Amt;
}
const OptionalAmount &getPrecision() const {
return Precision;
}
/// \brief Returns the builtin type that a data argument
/// paired with this format specifier should have. This method
/// will return null if the format specifier does not have
/// a matching data argument or the matching argument matches
/// more than one type.
ArgTypeResult getArgType(ASTContext &Ctx) const;
bool isLeftJustified() const { return (bool) IsLeftJustified; }
bool hasPlusPrefix() const { return (bool) HasPlusPrefix; }
bool hasAlternativeForm() const { return (bool) HasAlternativeForm; }
bool hasLeadingZeros() const { return (bool) HasLeadingZeroes; }
bool hasSpacePrefix() const { return (bool) HasSpacePrefix; }
};
class FormatStringHandler {
public:
FormatStringHandler() {}
virtual ~FormatStringHandler();
virtual void HandleIncompleteFormatSpecifier(const char *startSpecifier,
unsigned specifierLen) {}
virtual void HandleNullChar(const char *nullCharacter) {}
virtual void
HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
const char *startSpecifier,
unsigned specifierLen) {}
virtual bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
const char *startSpecifier,
unsigned specifierLen) {
return true;
}
};
bool ParseFormatString(FormatStringHandler &H,
const char *beg, const char *end);
} // end printf namespace
} // end clang namespace
#endif

View File

@ -70,5 +70,8 @@ class UninitializedValues :
void InitializeValues(const CFG& cfg);
};
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false);
} // end namespace clang
#endif

View File

@ -32,7 +32,6 @@ class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
class LocationContextManager;
class BlockDataRegion;
class StackFrameContext;
/// AnalysisContext contains the context data for the function or method under
@ -207,35 +206,23 @@ class ScopeContext : public LocationContext {
};
class BlockInvocationContext : public LocationContext {
llvm::PointerUnion<const BlockDataRegion *, const BlockDecl *> Data;
// FIXME: Add back context-sensivity (we don't want libAnalysis to know
// about MemRegion).
const BlockDecl *BD;
friend class LocationContextManager;
BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
const BlockDataRegion *br)
: LocationContext(Block, ctx, parent), Data(br) {}
BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
const BlockDecl *bd)
: LocationContext(Block, ctx, parent), Data(bd) {}
: LocationContext(Block, ctx, parent), BD(bd) {}
public:
~BlockInvocationContext() {}
const BlockDataRegion *getBlockRegion() const {
return Data.is<const BlockDataRegion*>() ?
Data.get<const BlockDataRegion*>() : 0;
}
const BlockDecl *getBlockDecl() const;
const BlockDecl *getBlockDecl() const { return BD; }
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
const LocationContext *parent, const BlockDataRegion *br){
ProfileCommon(ID, Block, ctx, parent, br);
}
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
const LocationContext *parent, const BlockDecl *bd) {
ProfileCommon(ID, Block, ctx, parent, bd);
@ -260,10 +247,6 @@ class LocationContextManager {
const LocationContext *parent,
const Stmt *s);
const BlockInvocationContext *
getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent,
const BlockDataRegion *BR);
/// Discard all previously created LocationContext objects.
void clear();
private:

View File

@ -20,19 +20,27 @@ namespace clang {
template<typename T>
class Optional {
const T x;
T x;
unsigned hasVal : 1;
public:
explicit Optional() : hasVal(false) {}
explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
Optional &operator=(const T &y) {
x = y;
hasVal = true;
return *this;
}
const T* getPointer() const { assert(hasVal); return &x; }
const T& getValue() const { assert(hasVal); return x; }
operator bool() const { return hasVal; }
bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
const T& operator*() const { assert(hasVal); return x; }
};

View File

@ -12,9 +12,6 @@
//
//===----------------------------------------------------------------------===//
// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
// adding stuff on demand.
//
// FIXME: This should really be a .td file, but that requires modifying tblgen.
// Perhaps tblgen should have plugins.
@ -52,6 +49,7 @@
// * -> pointer
// & -> reference
// C -> const
// D -> volatile
// The third value provided to the macro specifies information about attributes
// of the function. These must be kept in sync with the predicates in the
@ -235,7 +233,7 @@ BUILTIN(__builtin_islessgreater , "i.", "nc")
BUILTIN(__builtin_isunordered , "i.", "nc")
// Unary FP classification
// BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
BUILTIN(__builtin_isfinite, "i.", "nc")
BUILTIN(__builtin_isinf, "i.", "nc")
BUILTIN(__builtin_isinf_sign, "i.", "nc")
@ -277,7 +275,7 @@ BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "n")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "nF")
BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
@ -308,11 +306,19 @@ BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
BUILTIN(__builtin_frame_address, "v*Ui", "n")
BUILTIN(__builtin_flt_rounds, "i", "nc")
BUILTIN(__builtin_setjmp, "iv**", "")
BUILTIN(__builtin_longjmp, "vv**i", "")
BUILTIN(__builtin_longjmp, "vv**i", "r")
BUILTIN(__builtin_unwind_init, "v", "")
BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
// GCC exception builtins
BUILTIN(__builtin_eh_return, "vzv*", "") // FIXME: Takes intptr_t, not size_t!
BUILTIN(__builtin_frob_return_addr, "v*v*", "n")
BUILTIN(__builtin_dwarf_cfa, "v*", "n")
BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
BUILTIN(__builtin_extend_pointer, "iv*", "n")
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
@ -438,18 +444,18 @@ BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLi*LLLi.", "n")
BUILTIN(__sync_bool_compare_and_swap, "v.", "")
BUILTIN(__sync_bool_compare_and_swap_1, "bc*cc.", "n")
BUILTIN(__sync_bool_compare_and_swap_2, "bs*ss.", "n")
BUILTIN(__sync_bool_compare_and_swap_4, "bi*ii.", "n")
BUILTIN(__sync_bool_compare_and_swap_8, "bLLi*LLi.", "n")
BUILTIN(__sync_bool_compare_and_swap_16, "bLLLi*LLLiLLLi.", "n")
BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "n")
BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "n")
BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "n")
BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "n")
BUILTIN(__sync_val_compare_and_swap, "v.", "")
BUILTIN(__sync_val_compare_and_swap_1, "cc*cc.", "n")
BUILTIN(__sync_val_compare_and_swap_2, "ss*ss.", "n")
BUILTIN(__sync_val_compare_and_swap_4, "ii*ii.", "n")
BUILTIN(__sync_val_compare_and_swap_8, "LLiLLi*LLi.", "n")
BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLi*LLLiLLLi.", "n")
BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "n")
BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "n")
BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "n")
BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "n")
BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "n")
BUILTIN(__sync_lock_test_and_set, "v.", "")
BUILTIN(__sync_lock_test_and_set_1, "cc*c.", "n")
@ -527,6 +533,7 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.h")
// POSIX strings.h
LIBBUILTIN(index, "c*cC*i", "f", "strings.h")
LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h")
LIBBUILTIN(bzero, "vv*z", "f", "strings.h")
// POSIX unistd.h
LIBBUILTIN(_exit, "vi", "fr", "unistd.h")
// POSIX setjmp.h

View File

@ -23,16 +23,19 @@
namespace llvm {
template <typename T> class SmallVectorImpl;
class raw_ostream;
}
namespace clang {
class DeclContext;
class DiagnosticBuilder;
class DiagnosticClient;
class FileManager;
class IdentifierInfo;
class LangOptions;
class PartialDiagnostic;
class Preprocessor;
class SourceManager;
class SourceRange;
// Import the diagnostic enums themselves.
@ -400,6 +403,13 @@ class Diagnostic {
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
/// Deserialize - Deserialize the first diagnostic within the memory
/// [Memory, MemoryEnd), producing a new diagnostic builder describing the
/// deserialized diagnostic. If the memory does not contain a
/// diagnostic, returns a diagnostic builder with no diagnostic ID.
DiagnosticBuilder Deserialize(FileManager &FM, SourceManager &SM,
const char *&Memory, const char *MemoryEnd);
private:
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
@ -472,7 +482,7 @@ class Diagnostic {
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
const SourceRange *DiagRanges[10];
SourceRange DiagRanges[10];
enum { MaxCodeModificationHints = 3 };
@ -568,6 +578,9 @@ class DiagnosticBuilder {
/// been emitted.
~DiagnosticBuilder() { Emit(); }
/// isActive - Determine whether this diagnostic is still active.
bool isActive() const { return DiagObj != 0; }
/// Operator bool: conversion of DiagnosticBuilder to bool always returns
/// true. This allows is to be used in boolean error contexts like:
/// return Diag(...);
@ -596,7 +609,7 @@ class DiagnosticBuilder {
sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
"Too many arguments to diagnostic!");
if (DiagObj)
DiagObj->DiagRanges[NumRanges++] = &R;
DiagObj->DiagRanges[NumRanges++] = R;
}
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
@ -759,9 +772,9 @@ class DiagnosticInfo {
return DiagObj->NumDiagRanges;
}
const SourceRange &getRange(unsigned Idx) const {
SourceRange getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
return *DiagObj->DiagRanges[Idx];
return DiagObj->DiagRanges[Idx];
}
unsigned getNumCodeModificationHints() const {
@ -786,6 +799,12 @@ class DiagnosticInfo {
/// output buffer using the arguments stored in this diagnostic.
void FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
llvm::SmallVectorImpl<char> &OutStr) const;
/// Serialize - Serialize the given diagnostic (with its diagnostic
/// level) to the given stream. Serialization is a lossy operation,
/// since the specific diagnostic ID and any macro-instantiation
/// information is lost.
void Serialize(Diagnostic::Level DiagLevel, llvm::raw_ostream &OS) const;
};
/// DiagnosticClient - This is an abstract interface implemented by clients of

View File

@ -26,4 +26,33 @@ def err_asm_empty_symbolic_operand_name : Error<
def err_asm_invalid_operand_number : Error<
"invalid operand number in inline asm string">;
// Importing ASTs
def err_odr_variable_type_inconsistent : Error<
"external variable %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
def err_odr_variable_multiple_def : Error<
"external variable %0 defined in multiple translation units">;
def note_odr_value_here : Note<"declared here with type %0">;
def note_odr_defined_here : Note<"also defined here">;
def err_odr_function_type_inconsistent : Error<
"external function %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
def warn_odr_tag_type_inconsistent : Warning<
"type %0 has incompatible definitions in different translation units">;
def note_odr_tag_kind_here: Note<
"%0 is a %select{struct|union|class|enum}1 here">;
def note_odr_field : Note<"field %0 has type %1 here">;
def note_odr_missing_field : Note<"no corresponding field here">;
def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;
def note_odr_base : Note<"class has base type %0">;
def note_odr_virtual_base : Note<
"%select{non-virtual|virtual}0 derivation here">;
def note_odr_missing_base : Note<"no corresponding base class here">;
def note_odr_number_of_bases : Note<
"class has %0 base %plural{1:class|:classes}0">;
def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
}

View File

@ -31,6 +31,9 @@ def note_also_found : Note<"also found">;
// Parse && Lex
def err_expected_colon : Error<"expected ':'">;
def err_expected_colon_after_setter_name : Error<
"method name referenced in property setter attribute "
"must end with ':'">;
// Parse && Sema
def err_no_declarators : Error<"declaration does not declare anything">;

View File

@ -62,6 +62,8 @@ def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_remap_file : Error<
"invalid option '%0' not of the form <from-file>;<to-file>">;
def err_drv_invalid_gcc_output_type : Error<
"invalid output type '%0' for use with gcc tool">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
@ -85,5 +87,7 @@ def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
def warn_drv_missing_resource_library : Warning<
"missing resource library '%0', link may fail">;
def warn_drv_conflicting_deployment_targets : Warning<
"conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
}

View File

@ -19,6 +19,8 @@ def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
DefaultFatal;
def err_fe_stderr_binary : Error<"unable to change standard error to binary">,
DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
"-dependency-file requires at least one -MT option">;
def err_fe_incompatible_options : Error<
@ -80,6 +82,8 @@ def note_fixit_main_file_unchanged : Note<
def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
def err_fe_clang : Error<"error invoking%s: %s">, DefaultFatal;
// PCH reader
def err_relocatable_without_without_isysroot : Error<
"must specify system root with -isysroot when building a relocatable "
@ -105,6 +109,10 @@ def warn_pch_objective_c2 : Error<
def warn_pch_nonfragile_abi : Error<
"PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
"ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
def warn_pch_nonfragile_abi2 : Error<
"PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
"Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
"Objective-C ABI is selected">;
def warn_pch_extensions : Error<
"extensions were %select{enabled|disabled}0 in PCH file but are "
"currently %select{enabled|disabled}1">;
@ -132,6 +140,9 @@ def warn_pch_elide_constructors : Error<
def warn_pch_exceptions : Error<
"exceptions were %select{disabled|enabled}0 in PCH file but "
"are currently %select{disabled|enabled}1">;
def warn_pch_sjlj_exceptions : Error<
"sjlj-exceptions were %select{disabled|enabled}0 in PCH file but "
"are currently %select{disabled|enabled}1">;
def warn_pch_objc_runtime : Error<
"PCH file was compiled with the %select{NeXT|GNU}0 runtime but the "
"%select{NeXT|GNU}1 runtime is selected">;

View File

@ -96,7 +96,8 @@ def : DiagGroup<"strict-overflow">;
def InvalidOffsetof : DiagGroup<"invalid-offsetof">;
def : DiagGroup<"strict-prototypes">;
def : DiagGroup<"strict-selector-match">;
def Switch : DiagGroup<"switch">;
def SwitchEnum : DiagGroup<"switch-enum">;
def Switch : DiagGroup<"switch", [SwitchEnum]>;
def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
@ -118,6 +119,7 @@ def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
def CharSubscript : DiagGroup<"char-subscripts">;
def ForceAlignArgPointer : DiagGroup<"force-align-arg-pointer">;
// Aggregation warning settings.
@ -178,4 +180,4 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
// A warning group for warnings that we want to have on by default in clang,
// but which aren't on by default in GCC.
def NonGCC : DiagGroup<"non-gcc",
[SignCompare, Conversion]>;
[SignCompare, Conversion, ForceAlignArgPointer]>;

View File

@ -14,6 +14,8 @@
let Component = "Parse" in {
def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">;
def warn_file_asm_volatile : Warning<
"meaningless 'volatile' on asm outside function">;
def ext_empty_source_file : Extension<"ISO C forbids an empty source file">;
def ext_top_level_semi : Extension<
@ -158,12 +160,20 @@ def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
def err_invalid_vector_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier. \"__vector\" must be first">;
def err_invalid_pixel_decl_spec_combination : Error<
"\"__pixel\" must be preceded by \"__vector\". '%0' declaration specifier not allowed here">;
def err_invalid_vector_double_decl_spec_combination : Error<
"cannot use \"double\" with \"__vector\"">;
def warn_vector_long_decl_spec_combination : Warning<
"Use of \"long\" with \"__vector\" is deprecated">;
def err_friend_invalid_in_context : Error<
"'friend' used outside of class">;
def err_unknown_typename : Error<
"unknown type name %0">;
def err_use_of_tag_name_without_tag : Error<
"use of tagged type %0 without '%1' tag">;
"must use '%1' tag to refer to type %0%select{| in this scope}2">;
def err_expected_ident_in_using : Error<
"expected an identifier in using directive">;
def err_unexected_colon_in_nested_name_spec : Error<
@ -303,6 +313,9 @@ def err_out_of_line_type_names_constructor : Error<
def err_expected_qualified_after_typename : Error<
"expected a qualified name after 'typename'">;
def err_expected_semi_after_tagdecl : Error<
"expected ';' after %0">;
def err_typename_refers_to_non_type_template : Error<
"typename specifier refers to a non-template">;
def err_expected_type_name_after_typename : Error<

View File

@ -85,7 +85,11 @@ def warn_unused_variable : Warning<"unused variable %0">,
InGroup<UnusedVariable>, 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;
def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
@ -388,6 +392,11 @@ def err_deleted_non_function : Error<
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
def warn_weak_vtable : Warning<
"%0 has no out-of-line virtual method definitions; its vtable will be "
"emitted in every translation unit">,
InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
// C++ exception specifications
def err_exception_spec_in_typedef : Error<
"exception specifications are not allowed in typedefs">;
@ -410,17 +419,20 @@ def err_deep_exception_specs_differ : Error<
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
def err_access_private : Error<"%0 is a private member of %1">;
def err_access_ctor_private : Error<"calling a private constructor of %0">;
// Say something about the context for these?
def err_access_protected : Error<"%0 is a protected member of %1">;
def err_access_ctor_protected : Error<"calling a protected constructor of %0">;
def note_previous_access_declaration : Note<
"previously declared '%1' here">;
def err_access_outside_class : Error<
"access to %select{private|protected}0 member outside any class context">;
def note_access_natural : Note<"declared %select{private|protected}0 here">;
def note_access_natural : Note<
"%select{|implicitly }1declared %select{private|protected}0 here">;
def note_access_constrained_by_path : Note<
"access to decl constrained by %select{private|protected}0 inheritance">;
def err_access_protected : Error<
"access to protected member of %0 from %1, which is not a subclass">;
def err_access_private : Error<
"access to private member of %0 from %1">;
"constrained by %select{|implicitly }1%select{private|protected}0"
" inheritance here">;
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
@ -446,10 +458,14 @@ def err_mutable_nonmember : Error<
"'mutable' can only be applied to member variables">;
def err_virtual_non_function : Error<
"'virtual' can only appear on non-static member functions">;
def err_explicit_non_function : Error<
"'explicit' can only appear on non-static member functions">;
def err_virtual_out_of_class : Error<
"'virtual' can only be specified inside the class definition">;
def err_explicit_non_function : Error<
"'explicit' can only appear on non-static member functions">;
def err_explicit_out_of_class : Error<
"'explicit' can only be specified inside the class definition">;
def err_explicit_non_ctor_or_conv_function : Error<
"'explicit' can only be applied to a constructor or conversion function">;
def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">;
def err_static_out_of_line : Error<
"'static' can only be specified inside the class definition">;
@ -498,9 +514,8 @@ def note_overridden_virtual_function : Note<
"overridden virtual function is here">;
def err_covariant_return_inaccessible_base : Error<
"return type of virtual function %2 is not covariant with the return type "
"of the function it overrides "
"(conversion from %0 to inaccessible base class %1)">, NoSFINAE;
"invalid covariant return for virtual function: %1 is a "
"%select{private|protected}2 base class of %0">, NoSFINAE;
def err_covariant_return_ambiguous_derived_to_base_conv : Error<
"return type of virtual function %3 is not covariant with the return type of "
"the function it overrides (ambiguous conversion from derived class "
@ -547,7 +562,7 @@ def err_destructor_name : Error<
def err_init_conversion_failed : Error<
"cannot initialize %select{a variable|a parameter|return object|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|an array element}0 of type %1 with an %select{rvalue|lvalue}2 of "
"base class|a vector element}0 of type %1 with an %select{rvalue|lvalue}2 of "
"type %3">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">;
@ -556,14 +571,14 @@ def err_invalid_initialization : Error<
def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
"due to multiple conversion functions">;
def err_not_reference_to_const_init : Error<
"non-const lvalue reference to type %0 cannot be initialized "
"with a %select{value|temporary}1 of type %2">;
"%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
"initialized with a %select{value|temporary}2 of type %3">;
def err_lvalue_reference_bind_to_temporary : Error<
"non-const lvalue reference to type %0 cannot bind to a temporary of type "
"%1">;
"%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
"temporary of type %2">;
def err_lvalue_reference_bind_to_unrelated : Error<
"non-const lvalue reference to type %0 cannot bind to a value of unrelated "
"type %1">;
"%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
"value of unrelated type %2">;
def err_reference_bind_drops_quals : Error<
"binding of reference to type %0 to a value of type %1 drops qualifiers">;
def err_reference_bind_failed : Error<
@ -580,10 +595,14 @@ def err_reference_init_drops_quals : Error<
"qualifiers">;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to bit-field %1">;
def err_reference_bind_to_vector_element : Error<
"%select{non-const|volatile}0 reference cannot bind to vector element">;
def err_reference_var_requires_init : Error<
"declaration of reference variable %0 requires an initializer">;
def err_const_var_requires_init : Error<
"declaration of const variable '%0' requires an initializer">;
def err_reference_without_init : Error<
"reference to type %0 requires an initializer">;
def err_reference_has_multiple_inits : Error<
"reference cannot be initialized with multiple values">;
def err_init_non_aggr_init_list : Error<
@ -597,13 +616,16 @@ def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
def err_temp_copy_no_viable : Error<
"no viable copy constructor %select{copying variable|copying parameter|"
"returning object|throwing object}0 of type %1">;
"returning object|throwing object|copying member subobject|copying array "
"element}0 of type %1">;
def err_temp_copy_ambiguous : Error<
"ambiguous copy constructor call when %select{copying variable|copying "
"parameter|returning object|throwing object}0 of type %1">;
"parameter|returning object|throwing object|copying member subobject|copying "
"array element}0 of type %1">;
def err_temp_copy_deleted : Error<
"%select{copying variable|copying parameter|returning object|throwing "
"object}0 of type %1 invokes deleted copy constructor">;
"object|copying member subobject|copying array element}0 of type %1 invokes "
"deleted copy constructor">;
// C++0x decltype
def err_cannot_determine_declared_type_of_overloaded_function : Error<
@ -702,6 +724,9 @@ def err_attribute_aligned_not_power_of_two : Error<
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
def warn_faap_attribute_ignored : Warning<
"force_align_arg_pointer used on function pointer; attribute ignored">,
InGroup<ForceAlignArgPointer>;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
def warn_attribute_void_function : Warning<
@ -728,13 +753,18 @@ def err_attribute_wrong_decl_type : Error<
"parameter or Objective-C method |function, method or block|"
"virtual method or class|function, method, or parameter|class|virtual method"
"|member}1 types">;
def warn_function_attribute_wrong_type : Warning<
"%0 only applies to function types; type here is %1">;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
def err_cconv_change : Error<
"function declared '%0' here was previously declared "
"%select{'%2'|without calling convention}1">;
def err_cconv_knr : Error<
"function with no prototype cannot use '%0' calling convention">;
"function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
"variadic function cannot use '%0' calling convention">;
"variadic function cannot use %0 calling convention">;
def warn_impcast_vector_scalar : Warning<
"implicit cast turns vector to scalar: %0 to %1">,
@ -873,10 +903,7 @@ def err_uninitialized_member_for_assign : Error<
"assignment operator">;
def note_first_required_here : Note<
"synthesized method is first required here">;
def err_null_intialized_reference_member : Error<
"cannot initialize the member to null in default constructor because "
"reference member %0 cannot be null-initialized">;
def err_unintialized_member_in_ctor : Error<
def err_uninitialized_member_in_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{reference|const}2 member %3">;
@ -915,6 +942,12 @@ def note_ovl_candidate : Note<"candidate "
"is the implicit default constructor|"
"is the implicit copy constructor|"
"is the implicit copy assignment operator}0%1">;
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">;
// 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|"
@ -941,6 +974,13 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate "
"constructor (the implicit copy constructor)|"
"function (the implicit copy assignment operator)}0%1 "
"not viable: cannot convert argument of incomplete type %2 to %3">;
def note_ovl_candidate_bad_overload : 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%1"
" not viable: no overload of %3 matching %2 for %ordinal4 argument">;
def note_ovl_candidate_bad_conv : Note<"candidate "
"%select{function|function|constructor|"
"function |function |constructor |"
@ -1068,9 +1108,6 @@ def err_template_tag_noparams : Error<
def err_template_decl_ref : Error<
"cannot refer to class template %0 without a template argument list">;
def err_typedef_in_def_scope : Error<
"cannot use typedef %0 in scope specifier for out-of-line declaration">;
// C++ Template Argument Lists
def err_template_arg_list_different_arity : Error<
"%select{too few|too many}0 template arguments for "
@ -1122,6 +1159,8 @@ def err_template_arg_no_ref_bind : Error<
def err_template_arg_ref_bind_ignores_quals : Error<
"reference binding of non-type template parameter of type %0 to template "
"argument of type %1 ignores qualifiers">;
def err_template_arg_not_decl_ref : Error<
"non-type template argument does not refer to any declaration">;
def err_template_arg_not_object_or_func_form : Error<
"non-type template argument does not directly refer to an object or "
"function">;
@ -1236,6 +1275,8 @@ def err_partial_spec_redeclared : Error<
"class template partial specialization %0 cannot be redeclared">;
def note_prev_partial_spec_here : Note<
"previous declaration of class template partial specialization %0 is here">;
def err_partial_spec_fully_specialized : Error<
"partial specialization of %0 does not use any of its template parameters">;
// C++ Function template specializations
def err_function_template_spec_no_match : Error<
@ -1442,9 +1483,13 @@ def err_forward_ref_enum : Error<
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too large)">;
"ISO C restricts enumerator values to range of 'int' (%0 is too "
"%select{small|large}1)">;
def warn_enum_too_large : Warning<
"enumeration values exceed range of largest integer">;
def warn_enumerator_too_large : Warning<
"enumerator value %0 is not representable in the largest integer type">;
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<
@ -1677,6 +1722,8 @@ def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
def err_no_member : Error<"no member named %0 in %1">;
def err_member_redeclared : Error<"class member cannot be redeclared">;
def err_member_def_undefined_record : Error<
"out-of-line definition of %0 from class %1 without definition">;
def err_member_def_does_not_match : Error<
"out-of-line definition of %0 does not match any declaration in %1">;
def err_nonstatic_member_out_of_line : Error<
@ -1824,7 +1871,11 @@ def ext_integer_complement_complex : Extension<
def error_nosetter_property_assignment : Error<
"setter method is needed to assign to object using property" " assignment syntax">;
def error_no_subobject_property_setting : Error<
"cannot assign to a sub-structure of an ivar using property" " assignment syntax">;
"cannot assign to a sub-structure of an ivar using property"
" assignment syntax">;
def error_no_subobject_property_getter_setting : Error<
"cannot assign to a sub-structure returned via a getter using property"
" assignment syntax">;
def ext_freestanding_complex : Extension<
"complex numbers are an extension in a freestanding C99 implementation">;
@ -1915,7 +1966,9 @@ def err_ambiguous_base_to_derived_cast : Error<
def err_static_downcast_via_virtual : Error<
"cannot cast %0 to %1 via virtual base %2">;
def err_downcast_from_inaccessible_base : Error<
"cannot cast %1 to %0 due to inaccessible conversion path">;
"cannot cast %select{private|protected}2 base class %1 to %0">;
def err_upcast_to_inaccessible_base : Error<
"cannot cast %0 to its %select{private|protected}2 base class %1">;
def err_bad_dynamic_cast_not_ref_or_ptr : Error<
"%0 is not a reference or pointer">;
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
@ -1942,7 +1995,8 @@ def err_new_paren_array_nonconst : Error<
def err_array_size_not_integral : Error<
"array size expression must have integral or enumerated type, not %0">;
def err_default_init_const : Error<
"default initialization of an object of const type %0">;
"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 err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
"expression of type %0 to a pointer">;
@ -2245,8 +2299,6 @@ def error_multiple_base_initialization : Error <
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
def err_mem_initializer_mismatch : Error<
"Too many arguments for member initializer %0">;
def warn_field_initialized : Warning<
"member '%0' will be initialized after">,
@ -2435,11 +2487,16 @@ def warn_printf_write_back : Warning<
def warn_printf_insufficient_data_args : Warning<
"more '%%' conversions than data arguments">, InGroup<Format>;
def warn_printf_too_many_data_args : Warning<
"more data arguments than '%%' conversions">, InGroup<FormatExtraArgs>;
"more data arguments than format specifiers">, InGroup<FormatExtraArgs>;
def warn_printf_invalid_conversion : Warning<
"invalid conversion '%0'">, InGroup<Format>;
"invalid conversion specifier '%0'">, InGroup<Format>;
def warn_printf_incomplete_specifier : Warning<
"incomplete format specifier">, InGroup<Format>;
def warn_printf_missing_format_string : Warning<
"format string missing">, InGroup<Format>;
def warn_printf_conversion_argument_type_mismatch : Warning<
"conversion specifies type %0 but the argument has type %1">,
InGroup<Format>;
def warn_null_arg : Warning<
"null passed to a callee which requires a non-null argument">,
InGroup<NonNull>;
@ -2454,12 +2511,18 @@ def warn_printf_asterisk_width_missing_arg : Warning<
def warn_printf_asterisk_precision_missing_arg : Warning<
"'.*' specified field precision is missing a matching 'int' argument">;
def warn_printf_asterisk_width_wrong_type : Warning<
"field width should have type 'int', but argument has type %0">,
"field width should have type %0, but argument has type %1">,
InGroup<Format>;
def warn_printf_asterisk_precision_wrong_type : Warning<
"field precision should have type 'int', but argument has type %0">,
"field precision should have type %0, but argument has type %1">,
InGroup<Format>;
def warn_printf_nonsensical_precision: Warning<
"precision used in '%0' conversion specifier (where it has no meaning)">,
InGroup<Format>;
def warn_printf_nonsensical_flag: Warning<
"flag '%0' results in undefined behavior in '%1' conversion specifier">,
InGroup<Format>;
// CHECK: returning address/reference of stack memory
def warn_ret_stack_addr : Warning<
"address of stack memory associated with local variable %0 returned">;
@ -2511,6 +2574,10 @@ def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">;
def err_duplicate_case : Error<"duplicate case value '%0'">;
def warn_case_empty_range : Warning<"empty case range specified">;
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">,
InGroup<DiagGroup<"switch-enum"> >;
def err_typecheck_statement_requires_scalar : Error<
"statement requires expression of scalar type (%0 invalid)">;
def err_typecheck_statement_requires_integer : Error<
@ -2679,6 +2746,7 @@ def err_undeclared_protocol_suggest : Error<
"cannot find protocol declaration for %0; did you mean %1?">;
def note_base_class_specified_here : Note<
"base class %0 specified here">;
}

View File

@ -40,12 +40,14 @@ class LangOptions {
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled
unsigned PascalStrings : 1; // Allow Pascal strings
unsigned WritableStrings : 1; // Allow writable strings
unsigned LaxVectorConversions : 1;
unsigned AltiVec : 1; // Support AltiVec-style vector initializers.
unsigned Exceptions : 1; // Support exception handling.
unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling.
unsigned RTTI : 1; // Support RTTI information.
unsigned NeXTRuntime : 1; // Use NeXT runtime.
@ -95,7 +97,9 @@ class LangOptions {
// operators
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
// elided if possible.
unsigned CatchUndefined :1; // Generate code to check for undefined ops.
unsigned CatchUndefined : 1; // Generate code to check for undefined ops.
unsigned DumpVtableLayouts : 1; // Dump the layouts of all the emitted
// vtables.
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We
// declare this enum as unsigned because MSVC
@ -124,10 +128,10 @@ class LangOptions {
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
Exceptions = Freestanding = NoBuiltin = 0;
Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
NeXTRuntime = 1;
RTTI = 1;
LaxVectorConversions = 1;
@ -136,8 +140,7 @@ class LangOptions {
SymbolVisibility = (unsigned) Default;
// FIXME: The default should be 1.
ThreadsafeStatics = 0;
ThreadsafeStatics = 1;
POSIXThreads = 0;
Blocks = 0;
BlockIntrospection = 0;
@ -167,6 +170,7 @@ class LangOptions {
CharIsSigned = 1;
ShortWChar = 0;
CatchUndefined = 0;
DumpVtableLayouts = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }

View File

@ -0,0 +1,57 @@
//===--- Linkage.h - Linkage enumeration and utilities ----------*- 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 Linkage enumeration and various utility
// functions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H
namespace clang {
/// \brief Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
enum Linkage {
/// \brief No linkage, which means that the entity is unique and
/// can only be referred to from within its scope.
NoLinkage = 0,
/// \brief Internal linkage, which indicates that the entity can
/// be referred to from within the translation unit (but not other
/// translation units).
InternalLinkage,
/// \brief External linkage within a unique namespace. From the
/// langauge perspective, these entities have external
/// linkage. However, since they reside in an anonymous namespace,
/// their names are unique to this translation unit, which is
/// equivalent to having internal linkage from the code-generation
/// point of view.
UniqueExternalLinkage,
/// \brief External linkage, which indicates that the entity can
/// be referred to from other translation units.
ExternalLinkage
};
/// \brief Determine whether the given linkage is semantically
/// external.
inline bool isExternalLinkage(Linkage L) {
return L == UniqueExternalLinkage || L == ExternalLinkage;
}
/// \brief Compute the minimum linkage given two linages.
static inline Linkage minLinkage(Linkage L1, Linkage L2) {
return L1 < L2? L1 : L2;
}
} // end namespace clang
#endif // LLVM_CLANG_BASIC_LINKAGE_H

View File

@ -1,4 +1,4 @@
//===--- PartialDiagnostic.h - Diagnostic "closures" ----------------------===//
//===--- PartialDiagnostic.h - Diagnostic "closures" ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -669,12 +669,20 @@ class SourceManager {
::const_iterator fileinfo_iterator;
fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
bool hasFileInfo(const FileEntry *File) const {
return FileInfos.find(File) != FileInfos.end();
}
/// PrintStats - Print statistics to stderr.
///
void PrintStats() const;
unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
// FIXME: Exposing this is a little gross; what we want is a good way
// to iterate the entries that were not defined in a PCH file (or
// any other external source).
unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); }
const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
assert(ID < SLocEntryTable.size() && "Invalid id");

View File

@ -77,6 +77,7 @@ namespace clang {
AS_private,
AS_none
};
}
} // end namespace clang
#endif // LLVM_CLANG_BASIC_SPECIFIERS_H

View File

@ -226,11 +226,11 @@ class TargetInfo {
/// isValidGCCRegisterName - Returns whether the passed in string
/// is a valid register name according to GCC. This is used by Sema for
/// inline asm statements.
bool isValidGCCRegisterName(const char *Name) const;
bool isValidGCCRegisterName(llvm::StringRef Name) const;
// getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
// For example, on x86 it will return "ax" when "eax" is passed in.
const char *getNormalizedGCCRegisterName(const char *Name) const;
llvm::StringRef getNormalizedGCCRegisterName(llvm::StringRef Name) const;
struct ConstraintInfo {
enum {
@ -246,10 +246,9 @@ class TargetInfo {
std::string ConstraintStr; // constraint: "=rm"
std::string Name; // Operand name: [foo] with no []'s.
public:
ConstraintInfo(const char *str, unsigned strlen, const std::string &name)
: Flags(0), TiedOperand(-1), ConstraintStr(str, str+strlen), Name(name) {}
explicit ConstraintInfo(const std::string &Str, const std::string &name)
: Flags(0), TiedOperand(-1), ConstraintStr(Str), Name(name) {}
ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name)
: Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
Name(Name.str()) {}
const std::string &getConstraintStr() const { return ConstraintStr; }
const std::string &getName() const { return Name; }
@ -321,12 +320,6 @@ class TargetInfo {
virtual bool useGlobalsForAutomaticVariables() const { return false; }
/// getUnicodeStringSection - Return the section to use for unicode
/// string literals, or 0 if no special section is used.
virtual const char *getUnicodeStringSection() const {
return 0;
}
/// getCFStringSection - Return the section to use for CFString
/// literals, or 0 if no special section is used.
virtual const char *getCFStringSection() const {
@ -343,7 +336,7 @@ class TargetInfo {
/// and give good diagnostics in cases when the assembler or code generator
/// would otherwise reject the section specifier.
///
virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
return "";
}

View File

@ -227,7 +227,7 @@ KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
KEYWORD(bool , BOOLSUPPORT)
KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@ -235,7 +235,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
KEYWORD(false , BOOLSUPPORT)
KEYWORD(false , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@ -249,7 +249,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
KEYWORD(true , BOOLSUPPORT)
KEYWORD(true , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
@ -340,6 +340,10 @@ KEYWORD(__ptr64 , KEYALL)
KEYWORD(__w64 , KEYALL)
KEYWORD(__forceinline , KEYALL)
// Altivec Extension.
KEYWORD(__vector , KEYALTIVEC)
KEYWORD(__pixel , KEYALTIVEC)
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
ALIAS("__attribute__", __attribute, KEYALL)

View File

@ -56,16 +56,16 @@ namespace clang {
/// \brief Retrieves the repository revision number (or identifer) from which
/// this Clang was built.
llvm::StringRef getClangRevision();
std::string getClangRevision();
/// \brief Retrieves the full repository version that is an amalgamation of
/// the information in getClangRepositoryPath() and getClangRevision().
llvm::StringRef getClangFullRepositoryVersion();
std::string getClangFullRepositoryVersion();
/// \brief Retrieves a string representing the complete clang version,
/// which includes the clang version number, the repository version,
/// and the vendor tag.
const char *getClangFullVersion();
std::string getClangFullVersion();
}
#endif // LLVM_CLANG_BASIC_VERSION_H

View File

@ -17,9 +17,9 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "clang/Analysis/PathSensitive/BugType.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/ExplodedGraph.h"
#include "clang/Checker/BugReporter/BugType.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
@ -202,7 +202,7 @@ class RangedBugReport : public BugReport {
~RangedBugReport();
// FIXME: Move this out of line.
void addRange(SourceRange R) {
void addRange(SourceRange R) {
assert(R.isValid());
Ranges.push_back(R);
}
@ -464,6 +464,10 @@ const Stmt *GetRetValExpr(const ExplodedNode *N);
void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
const ExplodedNode* N);
void registerFindLastStore(BugReporterContext& BRC, const void *memregion,
const ExplodedNode *N);
} // end namespace clang::bugreporter
//===----------------------------------------------------------------------===//

View File

@ -14,7 +14,6 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include <llvm/ADT/FoldingSet.h>
#include <string>

View File

@ -31,13 +31,11 @@ class BugReporter;
class ObjCImplementationDecl;
class LangOptions;
class GRExprEngine;
class TranslationUnitDecl;
void CheckDeadStores(CFG &cfg, LiveVariables &L, ParentMap &map,
BugReporter& BR);
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
bool FullUninitTaint=false);
GRTransferFuncs* MakeCFRefCountTF(ASTContext& Ctx, bool GCEnabled,
const LangOptions& lopts);
@ -53,8 +51,8 @@ void RegisterAppleChecks(GRExprEngine& Eng, const Decl &D);
void RegisterExperimentalChecks(GRExprEngine &Eng);
void RegisterExperimentalInternalChecks(GRExprEngine &Eng);
void CheckLLVMConventions(TranslationUnitDecl &TU, BugReporter &BR);
void CheckSecuritySyntaxOnly(const Decl *D, BugReporter &BR);
void CheckSizeofPointer(const Decl *D, BugReporter &BR);
void RegisterCallInliner(GRExprEngine &Eng);

View File

@ -0,0 +1,40 @@
//===- CocoaConventions.h - Special handling of Cocoa conventions -*- 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_CHECKER_DS_COCOA
#define LLVM_CLANG_CHECKER_DS_COCOA
#include "clang/Basic/IdentifierTable.h"
#include "clang/AST/Type.h"
namespace clang {
namespace cocoa {
enum NamingConvention { NoConvention, CreateRule, InitRule };
NamingConvention deriveNamingConvention(Selector S);
static inline bool followsFundamentalRule(Selector S) {
return deriveNamingConvention(S) == CreateRule;
}
bool isRefType(QualType RetTy, llvm::StringRef Prefix,
llvm::StringRef Name = llvm::StringRef());
bool isCFObjectRef(QualType T);
bool isCocoaObjectRef(QualType T);
}}
#endif

View File

@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
#define LLVM_CLANG_ANALYSIS_MANAGER_REGISTRY_H
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRState.h"
namespace clang {

View File

@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
#define LLVM_CLANG_ANALYSIS_ANALYSISMANAGER_H
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/AnalysisContext.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Checker/BugReporter/BugReporter.h"
#include "clang/Checker/BugReporter/PathDiagnostic.h"
namespace clang {

View File

@ -16,8 +16,8 @@
#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
#include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/APSInt.h"
@ -46,19 +46,19 @@ class CompoundValData : public llvm::FoldingSetNode {
};
class LazyCompoundValData : public llvm::FoldingSetNode {
const GRState *state;
const void *store;
const TypedRegion *region;
public:
LazyCompoundValData(const GRState *st, const TypedRegion *r)
: state(st), region(r) {}
LazyCompoundValData(const void *st, const TypedRegion *r)
: store(st), region(r) {}
const GRState *getState() const { return state; }
const void *getStore() const { return store; }
const TypedRegion *getRegion() const { return region; }
static void Profile(llvm::FoldingSetNodeID& ID, const GRState *state,
static void Profile(llvm::FoldingSetNodeID& ID, const void *store,
const TypedRegion *region);
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, state, region); }
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); }
};
class BasicValueFactory {
@ -169,7 +169,7 @@ class BasicValueFactory {
const CompoundValData *getCompoundValData(QualType T,
llvm::ImmutableList<SVal> Vals);
const LazyCompoundValData *getLazyCompoundValData(const GRState *state,
const LazyCompoundValData *getLazyCompoundValData(const void *store,
const TypedRegion *region);
llvm::ImmutableList<SVal> getEmptySValList() {

View File

@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_CHECKER
#define LLVM_CLANG_ANALYSIS_CHECKER
#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtCXX.h"

View File

@ -22,7 +22,6 @@
PREVISIT(ArraySubscriptExpr, Stmt)
PREVISIT(BinaryOperator, Stmt)
PREVISIT(CallExpr, Stmt)
PREVISIT(CastExpr, Stmt)
PREVISIT(CXXOperatorCallExpr, CallExpr)
PREVISIT(DeclStmt, Stmt)
PREVISIT(ObjCMessageExpr, Stmt)

View File

@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_ANALYSIS_CHECKERVISITOR
#define LLVM_CLANG_ANALYSIS_CHECKERVISITOR
#include "clang/Analysis/PathSensitive/Checker.h"
#include "clang/Checker/PathSensitive/Checker.h"
namespace clang {
@ -42,7 +42,6 @@ class CheckerVisitor : public Checker {
return;
case Stmt::ImplicitCastExprClass:
case Stmt::ExplicitCastExprClass:
case Stmt::CStyleCastExprClass:
static_cast<ImplClass*>(this)->PreVisitCastExpr(C,
static_cast<const CastExpr*>(S));
@ -57,7 +56,7 @@ class CheckerVisitor : public Checker {
case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->PreVisit ## NAME(C,static_cast<const NAME*>(S));\
break;
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
#include "clang/Checker/PathSensitive/CheckerVisitor.def"
}
}
@ -76,24 +75,26 @@ case Stmt::NAME ## Class:\
static_cast<ImplClass*>(this)->\
PostVisit ## NAME(C,static_cast<const NAME*>(S));\
break;
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
#include "clang/Checker/PathSensitive/CheckerVisitor.def"
}
}
void PreVisitStmt(CheckerContext &C, const Stmt *S) {}
void PostVisitStmt(CheckerContext &C, const Stmt *S) {}
void PreVisitCastExpr(CheckerContext &C, const CastExpr *E) {
static_cast<ImplClass*>(this)->PreVisitStmt(C, E);
}
#define PREVISIT(NAME, FALLBACK) \
void PreVisit ## NAME(CheckerContext &C, const NAME* S) {\
PreVisit ## FALLBACK(C, S);\
static_cast<ImplClass*>(this)->PreVisit ## FALLBACK(C, S);\
}
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
#define POSTVISIT(NAME, FALLBACK) \
void PostVisit ## NAME(CheckerContext &C, const NAME* S) {\
PostVisit ## FALLBACK(C, S);\
static_cast<ImplClass*>(this)->PostVisit ## FALLBACK(C, S);\
}
#include "clang/Analysis/PathSensitive/CheckerVisitor.def"
#include "clang/Checker/PathSensitive/CheckerVisitor.def"
};
} // end clang namespace

View File

@ -15,7 +15,7 @@
#define LLVM_CLANG_ANALYSIS_CONSTRAINT_MANAGER_H
// FIXME: Typedef LiveSymbolsTy/DeadSymbolsTy at a more appropriate place.
#include "clang/Analysis/PathSensitive/Store.h"
#include "clang/Checker/PathSensitive/Store.h"
namespace llvm {
class APSInt;

View File

@ -16,11 +16,11 @@
// For using typedefs in StoreManager. Should find a better place for these
// typedefs.
#include "clang/Analysis/PathSensitive/Store.h"
#include "clang/Checker/PathSensitive/Store.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallVector.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"

View File

@ -16,7 +16,7 @@
#define LLVM_CLANG_ANALYSIS_EXPLODEDGRAPH
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/PathSensitive/AnalysisContext.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/AST/Decl.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/FoldingSet.h"

View File

@ -16,11 +16,11 @@
#define LLVM_CLANG_ANALYSIS_GRENGINE
#include "clang/AST/Expr.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "clang/Analysis/PathSensitive/GRWorkList.h"
#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
#include "clang/Analysis/PathSensitive/GRAuditor.h"
#include "clang/Analysis/PathSensitive/GRSubEngine.h"
#include "clang/Checker/PathSensitive/ExplodedGraph.h"
#include "clang/Checker/PathSensitive/GRWorkList.h"
#include "clang/Checker/PathSensitive/GRBlockCounter.h"
#include "clang/Checker/PathSensitive/GRAuditor.h"
#include "clang/Checker/PathSensitive/GRSubEngine.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {

View File

@ -16,13 +16,13 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
#include "clang/Analysis/PathSensitive/AnalysisManager.h"
#include "clang/Analysis/PathSensitive/GRSubEngine.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/GRSimpleAPICheck.h"
#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Checker/PathSensitive/AnalysisManager.h"
#include "clang/Checker/PathSensitive/GRSubEngine.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
#include "clang/Checker/BugReporter/BugReporter.h"
#include "clang/AST/Type.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprCXX.h"
@ -328,17 +328,6 @@ class GRExprEngine : public GRSubEngine {
void VisitObjCMessageExpr(ObjCMessageExpr* ME, ExplodedNode* Pred,
ExplodedNodeSet& Dst, bool asLValue);
void VisitObjCMessageExprArgHelper(ObjCMessageExpr* ME,
ObjCMessageExpr::arg_iterator I,
ObjCMessageExpr::arg_iterator E,
ExplodedNode* Pred, ExplodedNodeSet& Dst,
bool asLValue);
void VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
ExplodedNode* Pred,
ExplodedNodeSet& Dst,
bool asLValue);
/// VisitReturnStmt - Transfer function logic for return statements.
void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);

View File

@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE_BUILDERS
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/Analysis/Support/SaveAndRestore.h"
namespace clang {

View File

@ -16,8 +16,8 @@
#ifndef LLVM_CLANG_ANALYSIS_GRAPICHECKS
#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
#include "clang/Analysis/PathSensitive/GRAuditor.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRAuditor.h"
#include "clang/Checker/PathSensitive/GRState.h"
namespace clang {

View File

@ -16,11 +16,11 @@
// FIXME: Reduce the number of includes.
#include "clang/Analysis/PathSensitive/Environment.h"
#include "clang/Analysis/PathSensitive/Store.h"
#include "clang/Analysis/PathSensitive/ConstraintManager.h"
#include "clang/Analysis/PathSensitive/ValueManager.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/Environment.h"
#include "clang/Checker/PathSensitive/Store.h"
#include "clang/Checker/PathSensitive/ConstraintManager.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
@ -216,7 +216,7 @@ class GRState : public llvm::FoldingSetNode {
/// in 'state' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
const GRState *bindCompoundLiteral(const CompoundLiteralExpr* CL,
const LocationContext *LC,
SVal V) const;
@ -607,19 +607,24 @@ inline const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
inline const GRState *
GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
const LocationContext *LC, SVal V) const {
return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, LC, V);
Store new_store =
getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V);
return makeWithStore(new_store);
}
inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
return getStateManager().StoreMgr->BindDecl(this, VR, IVal);
Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
return makeWithStore(new_store);
}
inline const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
return getStateManager().StoreMgr->BindDeclWithNoInit(this, VR);
Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
return makeWithStore(new_store);
}
inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
return getStateManager().StoreMgr->Bind(this, LV, V);
Store new_store = getStateManager().StoreMgr->Bind(St, LV, V);
return makeWithStore(new_store);
}
inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
@ -671,11 +676,11 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
}
inline SVal GRState::getSVal(Loc LV, QualType T) const {
return getStateManager().StoreMgr->Retrieve(this, LV, T).getSVal();
return getStateManager().StoreMgr->Retrieve(St, LV, T);
}
inline SVal GRState::getSVal(const MemRegion* R) const {
return getStateManager().StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R));
}
inline BasicValueFactory &GRState::getBasicVals() const {

View File

@ -13,7 +13,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
#define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/SVals.h"
namespace clang {

View File

@ -15,9 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_GRTF
#define LLVM_CLANG_ANALYSIS_GRTF
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include <vector>
namespace clang {

View File

@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
#include "clang/Checker/PathSensitive/GRBlockCounter.h"
#include <cstddef>
namespace clang {

View File

@ -18,8 +18,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
@ -249,17 +249,20 @@ class SubRegion : public MemRegion {
class ElementRegion;
class RegionRawOffset : public std::pair<const MemRegion*, int64_t> {
class RegionRawOffset {
private:
friend class ElementRegion;
const MemRegion *Region;
int64_t Offset;
RegionRawOffset(const MemRegion* reg, int64_t offset = 0)
: std::pair<const MemRegion*, int64_t>(reg, offset) {}
: Region(reg), Offset(offset) {}
public:
// FIXME: Eventually support symbolic offsets.
int64_t getByteOffset() const { return second; }
const MemRegion *getRegion() const { return first; }
int64_t getByteOffset() const { return Offset; }
const MemRegion *getRegion() const { return Region; }
void dumpToStream(llvm::raw_ostream& os) const;
void dump() const;

View File

@ -15,7 +15,7 @@
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
#define LLVM_CLANG_ANALYSIS_RVALUE_H
#include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/ImmutableList.h"
@ -388,7 +388,7 @@ class LazyCompoundVal : public NonLoc {
const LazyCompoundValData *getCVData() const {
return static_cast<const LazyCompoundValData*>(Data);
}
const GRState *getState() const;
const void *getStore() const;
const TypedRegion *getRegion() const;
static bool classof(const SVal *V) {

View File

@ -16,7 +16,7 @@
#define LLVM_CLANG_ANALYSIS_SVALUATOR
#include "clang/AST/Expr.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/SVals.h"
namespace clang {
@ -38,33 +38,8 @@ class SValuator {
SValuator(ValueManager &valMgr) : ValMgr(valMgr) {}
virtual ~SValuator() {}
template <typename T>
class GenericCastResult : public std::pair<const GRState *, T> {
public:
const GRState *getState() const { return this->first; }
T getSVal() const { return this->second; }
GenericCastResult(const GRState *s, T v)
: std::pair<const GRState*,T>(s, v) {}
};
SVal EvalCast(SVal V, QualType castTy, QualType originalType);
class CastResult : public GenericCastResult<SVal> {
public:
CastResult(const GRState *s, SVal v) : GenericCastResult<SVal>(s, v) {}
};
class DefinedOrUnknownCastResult :
public GenericCastResult<DefinedOrUnknownSVal> {
public:
DefinedOrUnknownCastResult(const GRState *s, DefinedOrUnknownSVal v)
: GenericCastResult<DefinedOrUnknownSVal>(s, v) {}
};
CastResult EvalCast(SVal V, const GRState *ST,
QualType castTy, QualType originalType);
DefinedOrUnknownCastResult EvalCast(DefinedOrUnknownSVal V, const GRState *ST,
QualType castTy, QualType originalType);
virtual SVal EvalMinus(NonLoc val) = 0;
virtual SVal EvalComplement(NonLoc val) = 0;

View File

@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_ANALYSIS_STORE_H
#define LLVM_CLANG_ANALYSIS_STORE_H
#include "clang/Analysis/PathSensitive/MemRegion.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Analysis/PathSensitive/ValueManager.h"
#include "clang/Checker/PathSensitive/MemRegion.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
@ -41,6 +41,7 @@ class StoreManager {
/// MRMgr - Manages region objects associated with this StoreManager.
MemRegionManager &MRMgr;
ASTContext &Ctx;
StoreManager(GRStateManager &stateMgr);
@ -54,8 +55,7 @@ class StoreManager {
/// expected type of the returned value. This is used if the value is
/// lazily computed.
/// \return The value bound to the location \c loc.
virtual SValuator::CastResult Retrieve(const GRState *state, Loc loc,
QualType T = QualType()) = 0;
virtual SVal Retrieve(Store store, Loc loc, QualType T = QualType()) = 0;
/// Return a state with the specified value bound to the given location.
/// \param[in] state The analysis state.
@ -64,7 +64,7 @@ class StoreManager {
/// \return A pointer to a GRState object that contains the same bindings as
/// \c state with the addition of having the value specified by \c val bound
/// to the location given for \c loc.
virtual const GRState *Bind(const GRState *state, Loc loc, SVal val) = 0;
virtual Store Bind(Store store, Loc loc, SVal val) = 0;
virtual Store Remove(Store St, Loc L) = 0;
@ -72,10 +72,9 @@ class StoreManager {
/// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region
/// for the compound literal and 'BegInit' and 'EndInit' represent an
/// array of initializer values.
virtual const GRState *BindCompoundLiteral(const GRState *state,
const CompoundLiteralExpr* cl,
const LocationContext *LC,
SVal v) = 0;
virtual Store BindCompoundLiteral(Store store,
const CompoundLiteralExpr* cl,
const LocationContext *LC, SVal v) = 0;
/// getInitialStore - Returns the initial "empty" store representing the
/// value bindings upon entry to an analyzed function.
@ -88,20 +87,30 @@ class StoreManager {
/// getSubRegionMap - Returns an opaque map object that clients can query
/// to get the subregions of a given MemRegion object. It is the
// caller's responsibility to 'delete' the returned map.
virtual SubRegionMap *getSubRegionMap(const GRState *state) = 0;
virtual SubRegionMap *getSubRegionMap(Store store) = 0;
virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) = 0;
virtual SVal getLValueVar(const VarDecl *VD, const LocationContext *LC) {
return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
}
virtual SVal getLValueString(const StringLiteral* sl) = 0;
virtual SVal getLValueString(const StringLiteral* S) {
return ValMgr.makeLoc(MRMgr.getStringRegion(S));
}
SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl,
const LocationContext *LC);
SVal getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
const LocationContext *LC) {
return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
}
virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) = 0;
virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) {
return getLValueFieldOrIvar(decl, base);
}
virtual SVal getLValueField(const FieldDecl* D, SVal Base) = 0;
virtual SVal getLValueField(const FieldDecl* D, SVal Base) {
return getLValueFieldOrIvar(D, Base);
}
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0;
virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base);
// FIXME: Make out-of-line.
virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state,
@ -129,33 +138,31 @@ class StoreManager {
const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
/// EvalBinOp - Perform pointer arithmetic.
virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,
virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs, QualType resultTy) {
return UnknownVal();
}
virtual void RemoveDeadBindings(GRState &state, Stmt* Loc,
SymbolReaper& SymReaper,
virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0;
virtual const GRState *BindDecl(const GRState *ST, const VarRegion *VR,
SVal initVal) = 0;
virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0;
virtual const GRState *BindDeclWithNoInit(const GRState *ST,
const VarRegion *VR) = 0;
virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0;
typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
virtual const GRState *InvalidateRegion(const GRState *state,
const MemRegion *R,
const Expr *E, unsigned Count,
InvalidatedSymbols *IS) = 0;
virtual Store InvalidateRegion(Store store,
const MemRegion *R,
const Expr *E, unsigned Count,
InvalidatedSymbols *IS) = 0;
virtual const GRState *InvalidateRegions(const GRState *state,
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
InvalidatedSymbols *IS);
virtual Store InvalidateRegions(Store store,
const MemRegion * const *Begin,
const MemRegion * const *End,
const Expr *E, unsigned Count,
InvalidatedSymbols *IS);
// FIXME: Make out-of-line.
virtual const GRState *setExtent(const GRState *state,
@ -192,6 +199,9 @@ class StoreManager {
/// as another region.
SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy,
bool performTestOnly = true);
private:
SVal getLValueFieldOrIvar(const Decl* D, SVal Base);
};
// FIXME: Do we still need this?
@ -214,7 +224,7 @@ class SubRegionMap {
StoreManager *CreateBasicStoreManager(GRStateManager& StMgr);
StoreManager *CreateRegionStoreManager(GRStateManager& StMgr);
StoreManager *CreateFieldsOnlyRegionStoreManager(GRStateManager& StMgr);
StoreManager *CreateFlatStoreManager(GRStateManager &StMgr);
} // end clang namespace
#endif

View File

@ -0,0 +1,57 @@
//== SummaryManager.h - Generic handling of function summaries --*- 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 SummaryManager and related classes, which provides
// a generic mechanism for managing function summaries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_CHECKER_SUMMARY
#define LLVM_CLANG_CHECKER_SUMMARY
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
namespace clang {
namespace summMgr {
/* Key kinds:
- C functions
- C++ functions (name + parameter types)
- ObjC methods:
- Class, selector (class method)
- Class, selector (instance method)
- Category, selector (instance method)
- Protocol, selector (instance method)
- C++ methods
- Class, function name + parameter types + const
*/
class SummaryKey {
};
} // end namespace clang::summMgr
class SummaryManagerImpl {
};
template <typename T>
class SummaryManager : SummaryManagerImpl {
};
} // end clang namespace
#endif

View File

@ -17,11 +17,11 @@
#define LLVM_CLANG_ANALYSIS_AGGREGATE_VALUE_MANAGER_H
#include "llvm/ADT/OwningPtr.h"
#include "clang/Analysis/PathSensitive/MemRegion.h"
#include "clang/Analysis/PathSensitive/SVals.h"
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
#include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/Analysis/PathSensitive/SValuator.h"
#include "clang/Checker/PathSensitive/MemRegion.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/BasicValueFactory.h"
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SValuator.h"
namespace llvm { class BumpPtrAllocator; }
@ -115,8 +115,8 @@ class ValueManager {
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}
NonLoc makeLazyCompoundVal(const GRState *state, const TypedRegion *R) {
return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(state, R));
NonLoc makeLazyCompoundVal(const void *store, const TypedRegion *R) {
return nonloc::LazyCompoundVal(BasicVals.getLazyCompoundValData(store, R));
}
NonLoc makeZeroArrayIndex() {

View File

@ -41,6 +41,8 @@ class CodeGenOptions {
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
unsigned ObjCLegacyDispatch: 1; /// Use legacy Objective-C dispatch, even with
/// 2.0 runtime.
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
unsigned SoftFloat : 1; /// -soft-float.
@ -90,12 +92,13 @@ class CodeGenOptions {
NoCommon = 0;
NoImplicitFloat = 0;
NoZeroInitializedInBSS = 0;
ObjCLegacyDispatch = 0;
OptimizationLevel = 0;
OptimizeSize = 0;
UnrollLoops = 0;
SoftFloat = 0;
TimePasses = 0;
UnitAtATime = 1;
UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;

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