diff options
Diffstat (limited to 'include')
38 files changed, 1664 insertions, 487 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index f11a9eb..ef17ed1 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -34,77 +34,42 @@ extern "C" { #define CINDEX_LINKAGE #endif -/* - Clang indeX abstractions. The backing store for the following API's will be - clangs AST file (currently based on PCH). AST files are created as follows: - - "clang -emit-ast <sourcefile.langsuffix> -o <sourcefile.ast>". - - Naming Conventions: To avoid namespace pollution, data types are prefixed - with "CX" and functions are prefixed with "clang_". -*/ -typedef void *CXIndex; /* An indexing instance. */ +/** \defgroup CINDEX C Interface to Clang + * + * The C Interface to Clang provides a relatively small API that exposes + * facilities for parsing source code into an abstract syntax tree (AST), + * loading already-parsed ASTs, traversing the AST, associating + * physical source locations with elements within the AST, and other + * facilities that support Clang-based development tools. + * + * This C interface to Clang will never provide all of the information + * representation stored in Clang's C++ AST, nor should it: the intent is to + * maintain an API that is relatively stable from one release to the next, + * providing only the basic functionality needed to support development tools. + * + * To avoid namespace pollution, data types are prefixed with "CX" and + * functions are prefixed with "clang_". + * + * @{ + */ + +/** + * \brief An "index" that consists of a set of translation units that would + * typically be linked together into an executable or library. + */ +typedef void *CXIndex; +/** + * \brief A single translation unit, which resides in an index. + */ typedef void *CXTranslationUnit; /* A translation unit instance. */ -typedef void *CXFile; /* A source file */ -typedef void *CXDecl; /* A specific declaration within a translation unit. */ -typedef void *CXStmt; /* A specific statement within a function/method */ - -/* Cursors represent declarations, definitions, and references. */ -enum CXCursorKind { - /* Declarations */ - CXCursor_FirstDecl = 1, - CXCursor_TypedefDecl = 2, - CXCursor_StructDecl = 3, - CXCursor_UnionDecl = 4, - CXCursor_ClassDecl = 5, - CXCursor_EnumDecl = 6, - CXCursor_FieldDecl = 7, - CXCursor_EnumConstantDecl = 8, - CXCursor_FunctionDecl = 9, - CXCursor_VarDecl = 10, - CXCursor_ParmDecl = 11, - CXCursor_ObjCInterfaceDecl = 12, - CXCursor_ObjCCategoryDecl = 13, - CXCursor_ObjCProtocolDecl = 14, - CXCursor_ObjCPropertyDecl = 15, - CXCursor_ObjCIvarDecl = 16, - CXCursor_ObjCInstanceMethodDecl = 17, - CXCursor_ObjCClassMethodDecl = 18, - CXCursor_LastDecl = 18, - - /* Definitions */ - CXCursor_FirstDefn = 32, - CXCursor_FunctionDefn = 32, - CXCursor_ObjCClassDefn = 33, - CXCursor_ObjCCategoryDefn = 34, - CXCursor_ObjCInstanceMethodDefn = 35, - CXCursor_ObjCClassMethodDefn = 36, - CXCursor_LastDefn = 36, - - /* References */ - CXCursor_FirstRef = 40, /* Decl references */ - CXCursor_ObjCSuperClassRef = 40, - CXCursor_ObjCProtocolRef = 41, - CXCursor_ObjCClassRef = 42, - - CXCursor_ObjCSelectorRef = 43, /* Expression references */ - CXCursor_ObjCIvarRef = 44, - CXCursor_VarRef = 45, - CXCursor_FunctionRef = 46, - CXCursor_EnumConstantRef = 47, - CXCursor_MemberRef = 48, - CXCursor_LastRef = 48, - - /* Error conditions */ - CXCursor_FirstInvalid = 70, - CXCursor_InvalidFile = 70, - CXCursor_NoDeclFound = 71, - CXCursor_NotImplemented = 72, - CXCursor_LastInvalid = 72 -}; - +/** + * \brief Opaque pointer representing client data that will be passed through + * to various callbacks and visitors. + */ +typedef void *CXClientData; + /** * \brief Provides the contents of a file that has not yet been saved to disk. * @@ -133,27 +98,19 @@ struct CXUnsavedFile { unsigned long Length; }; -/* A cursor into the CXTranslationUnit. */ - -typedef struct { - enum CXCursorKind kind; - CXDecl decl; - CXStmt stmt; /* expression reference */ - CXDecl referringDecl; -} CXCursor; - -/* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ -typedef struct { - CXIndex index; - void *data; -} CXEntity; - /** - * For functions returning a string that might or might not need - * to be internally allocated and freed. - * Use clang_getCString to access the C string value. - * Use clang_disposeString to free the value. - * Treat it as an opaque type. + * \defgroup CINDEX_STRING String manipulation routines + * + * @{ + */ + +/** + * \brief A character string. + * + * The \c CXString type is used to return strings from the interface when + * the ownership of that string might different from one call to the next. + * Use \c clang_getCString() to retrieve the string data and, once finished + * with the string data, call \c clang_disposeString() to free the string. */ typedef struct { const char *Spelling; @@ -162,12 +119,20 @@ typedef struct { int MustFreeString; } CXString; -/* Get C string pointer from a CXString. */ +/** + * \brief Retrieve the character data associated with the given string. + */ CINDEX_LINKAGE const char *clang_getCString(CXString string); -/* Free CXString. */ +/** + * \brief Free the given string, + */ CINDEX_LINKAGE void clang_disposeString(CXString string); +/** + * @} + */ + /** * \brief clang_createIndex() provides a shared context for creating * translation units. It provides two options: @@ -191,14 +156,16 @@ CINDEX_LINKAGE void clang_disposeString(CXString string); * TU = clang_createTranslationUnit(Idx, "IndexTest.pch"); * * // This will load all the symbols from 'IndexTest.pch' - * clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0); + * clang_visitChildren(clang_getTranslationUnitCursor(TU), + * TranslationUnitVisitor, 0); * clang_disposeTranslationUnit(TU); * * // This will load all the symbols from 'IndexTest.c', excluding symbols * // from 'IndexTest.pch'. * char *args[] = { "-Xclang", "-include-pch=IndexTest.pch", 0 }; * TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args); - * clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0); + * clang_visitChildren(clang_getTranslationUnitCursor(TU), + * TranslationUnitVisitor, 0); * clang_disposeTranslationUnit(TU); * * This process of creating the 'pch', loading it separately, and using it (via @@ -211,7 +178,7 @@ CINDEX_LINKAGE void clang_disposeIndex(CXIndex index); CINDEX_LINKAGE CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); -/* +/** * \brief Request that AST's be generated external for API calls which parse * source code on the fly, e.g. \see createTranslationUnitFromSourceFile. * @@ -224,7 +191,7 @@ clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); CINDEX_LINKAGE void clang_setUseExternalASTGeneration(CXIndex index, int value); -/* +/** * \brief Create a translation unit from an AST file (-emit-ast). */ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit( @@ -255,137 +222,632 @@ CINDEX_LINKAGE void clang_disposeTranslationUnit(CXTranslationUnit); * * \param source_filename - The name of the source file to load, or NULL if the * source file is included in clang_command_line_args. + * + * \param num_unsaved_files the number of unsaved file entries in \p + * unsaved_files. + * + * \param unsaved_files the files that have not yet been saved to disk + * but may be required for code completion, including the contents of + * those files. */ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( - CXIndex CIdx, - const char *source_filename, - int num_clang_command_line_args, - const char **clang_command_line_args -); + CXIndex CIdx, + const char *source_filename, + int num_clang_command_line_args, + const char **clang_command_line_args, + unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files); -/* - Usage: clang_loadTranslationUnit(). Will load the toplevel declarations - within a translation unit, issuing a 'callback' for each one. - - void printObjCInterfaceNames(CXTranslationUnit X, CXCursor C) { - if (clang_getCursorKind(C) == Cursor_Declaration) { - CXDecl D = clang_getCursorDecl(C); - if (clang_getDeclKind(D) == CXDecl_ObjC_interface) - printf("@interface %s in file %s on line %d column %d\n", - clang_getDeclSpelling(D), clang_getCursorSource(C), - clang_getCursorLine(C), clang_getCursorColumn(C)); - } - } - static void usage { - clang_loadTranslationUnit(CXTranslationUnit, printObjCInterfaceNames); - } -*/ -typedef void *CXClientData; -typedef void (*CXTranslationUnitIterator)(CXTranslationUnit, CXCursor, - CXClientData); -CINDEX_LINKAGE void clang_loadTranslationUnit(CXTranslationUnit, - CXTranslationUnitIterator, - CXClientData); - -/* - Usage: clang_loadDeclaration(). Will load the declaration, issuing a - 'callback' for each declaration/reference within the respective declaration. - - For interface declarations, this will index the super class, protocols, - ivars, methods, etc. For structure declarations, this will index the fields. - For functions, this will index the parameters (and body, for function - definitions), local declarations/references. - - void getInterfaceDetails(CXDecl X, CXCursor C) { - switch (clang_getCursorKind(C)) { - case Cursor_ObjC_ClassRef: - CXDecl SuperClass = clang_getCursorDecl(C); - case Cursor_ObjC_ProtocolRef: - CXDecl AdoptsProtocol = clang_getCursorDecl(C); - case Cursor_Declaration: - CXDecl AnIvarOrMethod = clang_getCursorDecl(C); - } - } - static void usage() { - if (clang_getDeclKind(D) == CXDecl_ObjC_interface) { - clang_loadDeclaration(D, getInterfaceDetails); - } - } -*/ -typedef void (*CXDeclIterator)(CXDecl, CXCursor, CXClientData); - -CINDEX_LINKAGE void clang_loadDeclaration(CXDecl, CXDeclIterator, CXClientData); - -/* - * CXFile Operations. +/** + * \defgroup CINDEX_FILES File manipulation routines + * + * @{ + */ + +/** + * \brief A particular source file that is part of a translation unit. + */ +typedef void *CXFile; + + +/** + * \brief Retrieve the complete file and path name of the given file. */ CINDEX_LINKAGE const char *clang_getFileName(CXFile SFile); + +/** + * \brief Retrieve the last modification time of the given file. + */ CINDEX_LINKAGE time_t clang_getFileTime(CXFile SFile); -/* - * CXEntity Operations. +/** + * \brief Retrieve a file handle within the given translation unit. + * + * \param tu the translation unit + * + * \param file_name the name of the file. + * + * \returns the file handle for the named file in the translation unit \p tu, + * or a NULL file handle if the file was not a part of this translation unit. */ +CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, + const char *file_name); -/* clang_getDeclaration() maps from a CXEntity to the matching CXDecl (if any) - * in a specified translation unit. */ -CINDEX_LINKAGE CXDecl clang_getDeclaration(CXEntity, CXTranslationUnit); +/** + * @} + */ -/* - * CXDecl Operations. +/** + * \defgroup CINDEX_LOCATIONS Physical source locations + * + * Clang represents physical source locations in its abstract syntax tree in + * great detail, with file, line, and column information for the majority of + * the tokens parsed in the source code. These data types and functions are + * used to represent source location information, either for a particular + * point in the program or for a range of points in the program, and extract + * specific location information from those data types. + * + * @{ */ -CINDEX_LINKAGE CXCursor clang_getCursorFromDecl(CXDecl); -CINDEX_LINKAGE CXEntity clang_getEntityFromDecl(CXIndex, CXDecl); -CINDEX_LINKAGE CXString clang_getDeclSpelling(CXDecl); -CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl); -CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl); -CINDEX_LINKAGE CXString clang_getDeclUSR(CXDecl); -CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl); /* deprecate */ -CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl); + +/** + * \brief Identifies a specific source location within a translation + * unit. + * + * Use clang_getInstantiationLocation() to map a source location to a + * particular file, line, and column. + */ +typedef struct { + void *ptr_data; + unsigned int_data; +} CXSourceLocation; -typedef struct CXSourceLineColumn { - unsigned line; - unsigned column; -} CXSourceLineColumn; +/** + * \brief Identifies a range of source locations in the source code. + * + * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the + * starting and end locations from a source range, respectively. + */ +typedef struct { + void *ptr_data; + unsigned begin_int_data; + unsigned end_int_data; +} CXSourceRange; + +/** + * \brief Retrieve a NULL (invalid) source location. + */ +CINDEX_LINKAGE CXSourceLocation clang_getNullLocation(); + +/** + * \determine Determine whether two source locations, which must refer into + * the same translation unit, refer to exactly the same point in the source + * code. + * + * \returns non-zero if the source locations refer to the same location, zero + * if they refer to different locations. + */ +CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1, + CXSourceLocation loc2); + +/** + * \brief Retrieves the source location associated with a given + * file/line/column in a particular translation unit. + */ +CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu, + CXFile file, + unsigned line, + unsigned column); + +/** + * \brief Retrieve a source range given the beginning and ending source + * locations. + */ +CINDEX_LINKAGE CXSourceRange clang_getRange(CXSourceLocation begin, + CXSourceLocation end); + +/** + * \brief Retrieve the file, line, and column represented by the + * given source location. + * + * \param location the location within a source file that will be + * decomposed into its parts. + * + * \param file if non-NULL, will be set to the file to which the given + * source location points. + * + * \param line if non-NULL, will be set to the line to which the given + * source location points. + * + * \param column if non-NULL, will be set to the column to which the + * given source location points. + */ +CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, + CXFile *file, + unsigned *line, + unsigned *column); + +/** + * \brief Retrieve a source location representing the first + * character within a source range. + */ +CINDEX_LINKAGE CXSourceLocation clang_getRangeStart(CXSourceRange range); + +/** + * \brief Retrieve a source location representing the last + * character within a source range. + */ +CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range); + +/** + * @} + */ -typedef struct CXDeclExtent { - CXSourceLineColumn begin; - CXSourceLineColumn end; -} CXSourceExtent; +/** + * \brief Describes the kind of entity that a cursor refers to. + */ +enum CXCursorKind { + /* Declarations */ + CXCursor_FirstDecl = 1, + /** + * \brief 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. + */ + CXCursor_UnexposedDecl = 1, + /** \brief A C or C++ struct. */ + CXCursor_StructDecl = 2, + /** \brief A C or C++ union. */ + CXCursor_UnionDecl = 3, + /** \brief A C++ class. */ + CXCursor_ClassDecl = 4, + /** \brief An enumeration. */ + CXCursor_EnumDecl = 5, + /** + * \brief A field (in C) or non-static data member (in C++) in a + * struct, union, or C++ class. + */ + CXCursor_FieldDecl = 6, + /** \brief An enumerator constant. */ + CXCursor_EnumConstantDecl = 7, + /** \brief A function. */ + CXCursor_FunctionDecl = 8, + /** \brief A variable. */ + CXCursor_VarDecl = 9, + /** \brief A function or method parameter. */ + CXCursor_ParmDecl = 10, + /** \brief An Objective-C @interface. */ + CXCursor_ObjCInterfaceDecl = 11, + /** \brief An Objective-C @interface for a category. */ + CXCursor_ObjCCategoryDecl = 12, + /** \brief An Objective-C @protocol declaration. */ + CXCursor_ObjCProtocolDecl = 13, + /** \brief An Objective-C @property declaration. */ + CXCursor_ObjCPropertyDecl = 14, + /** \brief An Objective-C instance variable. */ + CXCursor_ObjCIvarDecl = 15, + /** \brief An Objective-C instance method. */ + CXCursor_ObjCInstanceMethodDecl = 16, + /** \brief An Objective-C class method. */ + CXCursor_ObjCClassMethodDecl = 17, + /** \brief An Objective-C @implementation. */ + CXCursor_ObjCImplementationDecl = 18, + /** \brief An Objective-C @implementation for a category. */ + CXCursor_ObjCCategoryImplDecl = 19, + /** \brief A typedef */ + CXCursor_TypedefDecl = 20, + CXCursor_LastDecl = 20, + + /* References */ + CXCursor_FirstRef = 40, /* Decl references */ + CXCursor_ObjCSuperClassRef = 40, + CXCursor_ObjCProtocolRef = 41, + CXCursor_ObjCClassRef = 42, + /** + * \brief A reference to a type declaration. + * + * A type reference occurs anywhere where a type is named but not + * declared. For example, given: + * + * \code + * typedef unsigned size_type; + * size_type size; + * \endcode + * + * 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. + */ + CXCursor_TypeRef = 43, + CXCursor_LastRef = 43, + + /* Error conditions */ + CXCursor_FirstInvalid = 70, + CXCursor_InvalidFile = 70, + CXCursor_NoDeclFound = 71, + CXCursor_NotImplemented = 72, + CXCursor_LastInvalid = 72, + + /* Expressions */ + CXCursor_FirstExpr = 100, + + /** + * \brief 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. + */ + CXCursor_UnexposedExpr = 100, + + /** + * \brief An expression that refers to some value declaration, such + * as a function, varible, or enumerator. + */ + CXCursor_DeclRefExpr = 101, + + /** + * \brief An expression that refers to a member of a struct, union, + * class, Objective-C class, etc. + */ + CXCursor_MemberRefExpr = 102, + + /** \brief An expression that calls a function. */ + CXCursor_CallExpr = 103, + + /** \brief An expression that sends a message to an Objective-C + object or class. */ + CXCursor_ObjCMessageExpr = 104, + CXCursor_LastExpr = 104, + + /* Statements */ + CXCursor_FirstStmt = 200, + /** + * \brief 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. + */ + CXCursor_UnexposedStmt = 200, + CXCursor_LastStmt = 200, + + /** + * \brief 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. + */ + CXCursor_TranslationUnit = 300 +}; -/* clang_getDeclExtent() returns the physical extent of a declaration. The - * beginning line/column pair points to the start of the first token in the - * declaration, and the ending line/column pair points to the last character in - * the last token of the declaration. +/** + * \brief A cursor representing some element in the abstract syntax tree for + * a translation unit. + * + * The cursor abstraction unifies the different kinds of entities in a + * program--declaration, statements, expressions, references to declarations, + * etc.--under a single "cursor" abstraction with a common set of operations. + * Common operation for a cursor include: getting the physical location in + * a source file where the cursor points, getting the name associated with a + * cursor, and retrieving cursors for any child nodes of a particular cursor. + * + * Cursors can be produced in two specific ways. + * clang_getTranslationUnitCursor() produces a cursor for a translation unit, + * from which one can use clang_visitChildren() to explore the rest of the + * translation unit. clang_getCursor() maps from a physical source location + * to the entity that resides at that location, allowing one to map from the + * source code into the AST. */ -CINDEX_LINKAGE CXSourceExtent clang_getDeclExtent(CXDecl); +typedef struct { + enum CXCursorKind kind; + void *data[3]; +} CXCursor; -/* - * CXCursor Operations. +/** + * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations + * + * @{ */ + /** - Usage: clang_getCursor() will translate a source/line/column position - into an AST cursor (to derive semantic information from the source code). + * \brief Retrieve the NULL cursor, which represents no entity. */ -CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, - const char *source_name, - unsigned line, unsigned column); - CINDEX_LINKAGE CXCursor clang_getNullCursor(void); + +/** + * \brief Retrieve the cursor that represents the given translation unit. + * + * The translation unit cursor can be used to start traversing the + * various declarations within the given translation unit. + */ +CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit); +/** + * \brief Determine whether two cursors are equivalent. + */ +CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor); + +/** + * \brief Retrieve the kind of the given cursor. + */ CINDEX_LINKAGE enum CXCursorKind clang_getCursorKind(CXCursor); + +/** + * \brief Determine whether the given cursor kind represents a declaration. + */ CINDEX_LINKAGE unsigned clang_isDeclaration(enum CXCursorKind); + +/** + * \brief Determine whether the given cursor kind represents a simple + * reference. + * + * Note that other kinds of cursors (such as expressions) can also refer to + * other cursors. Use clang_getCursorReferenced() to determine whether a + * particular cursor refers to another entity. + */ CINDEX_LINKAGE unsigned clang_isReference(enum CXCursorKind); -CINDEX_LINKAGE unsigned clang_isDefinition(enum CXCursorKind); + +/** + * \brief Determine whether the given cursor kind represents an expression. + */ +CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind); + +/** + * \brief Determine whether the given cursor kind represents a statement. + */ +CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind); + +/** + * \brief Determine whether the given cursor kind represents an invalid + * cursor. + */ CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind); -CINDEX_LINKAGE unsigned clang_equalCursors(CXCursor, CXCursor); +/** + * \brief Determine whether the given cursor kind represents a translation + * unit. + */ +CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind); + +/** + * @} + */ + +/** + * \defgroup CINDEX_CURSOR_SOURCE Mapping between cursors and source code + * + * Cursors represent a location within the Abstract Syntax Tree (AST). These + * routines help map between cursors and the physical locations where the + * described entities occur in the source code. The mapping is provided in + * both directions, so one can map from source code to the AST and back. + * + * @{ + */ + +/** + * \brief Map a source location to the cursor that describes the entity at that + * location in the source code. + * + * clang_getCursor() maps an arbitrary source location within a translation + * unit down to the most specific cursor that describes the entity at that + * location. For example, given an expression \c x + y, invoking + * clang_getCursor() with a source location pointing to "x" will return the + * cursor for "x"; similarly for "y". If the cursor points anywhere between + * "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor() + * will return a cursor referring to the "+" expression. + * + * \returns a cursor representing the entity at the given source location, or + * a NULL cursor if no such entity can be found. + */ +CINDEX_LINKAGE CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation); + +/** + * \brief Retrieve the physical location of the source constructor referenced + * by the given cursor. + * + * The location of a declaration is typically the location of the name of that + * declaration, where the name of that declaration would occur if it is + * unnamed, or some keyword that introduces that particular declaration. + * The location of a reference is where that reference occurs within the + * source code. + */ +CINDEX_LINKAGE CXSourceLocation clang_getCursorLocation(CXCursor); + +/** + * \brief Retrieve the physical extent of the source construct referenced by + * the given cursor. + * + * The extent of a cursor starts with the file/line/column pointing at the + * first character within the source construct that the cursor refers to and + * ends with the last character withinin that source construct. For a + * declaration, the extent covers the declaration itself. For a reference, + * the extent covers the location of the reference (e.g., where the referenced + * entity was actually used). + */ +CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor); -CINDEX_LINKAGE unsigned clang_getCursorLine(CXCursor); -CINDEX_LINKAGE unsigned clang_getCursorColumn(CXCursor); +/** + * @} + */ + +/** + * \defgroup CINDEX_CURSOR_TRAVERSAL Traversing the AST with cursors + * + * These routines provide the ability to traverse the abstract syntax tree + * using cursors. + * + * @{ + */ + +/** + * \brief Describes how the traversal of the children of a particular + * cursor should proceed after visiting a particular child cursor. + * + * A value of this enumeration type should be returned by each + * \c CXCursorVisitor to indicate how clang_visitChildren() proceed. + */ +enum CXChildVisitResult { + /** + * \brief Terminates the cursor traversal. + */ + CXChildVisit_Break, + /** + * \brief Continues the cursor traversal with the next sibling of + * the cursor just visited, without visiting its children. + */ + CXChildVisit_Continue, + /** + * \brief Recursively traverse the children of this cursor, using + * the same visitor and client data. + */ + CXChildVisit_Recurse +}; + +/** + * \brief Visitor invoked for each cursor found by a traversal. + * + * This visitor function will be invoked for each cursor found by + * clang_visitCursorChildren(). Its first argument is the cursor being + * visited, its second argument is the parent visitor for that cursor, + * and its third argument is the client data provided to + * clang_visitCursorChildren(). + * + * The visitor should return one of the \c CXChildVisitResult values + * to direct clang_visitCursorChildren(). + */ +typedef enum CXChildVisitResult (*CXCursorVisitor)(CXCursor cursor, + CXCursor parent, + CXClientData client_data); + +/** + * \brief Visit the children of a particular cursor. + * + * This function visits all the direct children of the given cursor, + * invoking the given \p visitor function with the cursors of each + * visited child. The traversal may be recursive, if the visitor returns + * \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if + * the visitor returns \c CXChildVisit_Break. + * + * \param tu the translation unit into which the cursor refers. + * + * \param parent the cursor whose child may be visited. All kinds of + * cursors can be visited, including invalid visitors (which, by + * definition, have no children). + * + * \param visitor the visitor function that will be invoked for each + * child of \p parent. + * + * \param client_data pointer data supplied by the client, which will + * be passed to the visitor each time it is invoked. + * + * \returns a non-zero value if the traversal was terminated + * prematurely by the visitor returning \c CXChildVisit_Break. + */ +CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, + CXCursorVisitor visitor, + CXClientData client_data); + +/** + * @} + */ + +/** + * \defgroup CINDEX_CURSOR_XREF Cross-referencing in the AST + * + * These routines provide the ability to determine references within and + * across translation units, by providing the names of the entities referenced + * by cursors, follow reference cursors to the declarations they reference, + * and associate declarations with their definitions. + * + * @{ + */ + +/** + * \brief Retrieve a Unified Symbol Resolution (USR) for the entity referenced + * by the given cursor. + * + * 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. + */ +CINDEX_LINKAGE CXString clang_getCursorUSR(CXCursor); + +/** + * \brief Retrieve a name for the entity referenced by this cursor. + */ CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor); -CINDEX_LINKAGE const char *clang_getCursorSource(CXCursor); /* deprecate */ -CINDEX_LINKAGE CXFile clang_getCursorSourceFile(CXCursor); +/** \brief For a cursor that is a reference, retrieve a cursor representing the + * entity that it references. + * + * Reference cursors refer to other entities in the AST. For example, an + * Objective-C superclass reference cursor refers to an Objective-C class. + * This function produces the cursor for the Objective-C class from the + * cursor for the superclass reference. If the input cursor is a declaration or + * definition, it returns that declaration or definition unchanged. + * Othewise, returns the NULL cursor. + */ +CINDEX_LINKAGE CXCursor clang_getCursorReferenced(CXCursor); + +/** + * \brief For a cursor that is either a reference to or a declaration + * of some entity, retrieve a cursor that describes the definition of + * that entity. + * + * Some entities can be declared multiple times within a translation + * unit, but only one of those declarations can also be a + * definition. For example, given: + * + * \code + * int f(int, int); + * int g(int x, int y) { return f(x, y); } + * int f(int a, int b) { return a + b; } + * int f(int, int); + * \endcode + * + * there are three declarations of the function "f", but only the + * second one is a definition. The clang_getCursorDefinition() + * function will take any cursor pointing to a declaration of "f" + * (the first or fourth lines of the example) or a cursor referenced + * that uses "f" (the call to "f' inside "g") and will return a + * declaration cursor pointing to the definition (the second "f" + * declaration). + * + * If given a cursor for which there is no corresponding definition, + * e.g., because there is no definition of that entity within this + * translation unit, returns a NULL cursor. + */ +CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor); + +/** + * \brief Determine whether the declaration pointed to by this cursor + * is also a definition of that entity. + */ +CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); + +/** + * @} + */ + +/** + * \defgroup CINDEX_DEBUG Debugging facilities + * + * These routines are used for testing and debugging, only, and should not + * be relied upon. + * + * @{ + */ + /* for debug/testing */ CINDEX_LINKAGE const char *clang_getCursorKindSpelling(enum CXCursorKind Kind); CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor, @@ -396,13 +858,22 @@ CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor, unsigned *endLine, unsigned *endColumn); -/* - * If CXCursorKind == Cursor_Reference, then this will return the referenced - * declaration. - * If CXCursorKind == Cursor_Declaration, then this will return the declaration. +/** + * @} */ -CINDEX_LINKAGE CXDecl clang_getCursorDecl(CXCursor); - + +/** + * \defgroup CINDEX_CODE_COMPLET Code completion + * + * Code completion involves taking an (incomplete) source file, along with + * knowledge of where the user is actively editing that file, and suggesting + * syntactically- and semantically-valid constructs that the user might want to + * use at that particular point in the source code. These data structures and + * routines provide support for code completion. + * + * @{ + */ + /** * \brief A semantic string that describes a code-completion result. * @@ -771,6 +1242,27 @@ CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, CINDEX_LINKAGE void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results); +/** + * @} + */ + + +/** + * \defgroup CINDEX_MISC Miscellaneous utility functions + * + * @{ + */ + +CINDEX_LINKAGE const char *clang_getClangVersion(); + +/** + * @} + */ + +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 5db8e20..e5429be 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -61,6 +61,7 @@ namespace clang { class TypedefDecl; class UsingDecl; class UsingShadowDecl; + class UnresolvedSetIterator; namespace Builtin { class Context; } @@ -397,6 +398,11 @@ public: /// BlockPointer. QualType getNoReturnType(QualType T, bool AddNoReturn = true); + /// getCallConvType - Adds the specified calling convention attribute to + /// the given type, which must be a FunctionType or a pointer to an + /// allowable type. + QualType getCallConvType(QualType T, CallingConv CallConv); + /// getComplexType - Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T); @@ -513,7 +519,8 @@ public: /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// - QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false); + QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false, + CallingConv CallConv = CC_Default); /// getFunctionType - Return a normal function type with a typed argument /// list. isVariadic indicates whether the argument list includes '...'. @@ -522,7 +529,8 @@ public: unsigned TypeQuals, bool hasExceptionSpec = false, bool hasAnyExceptionSpec = false, unsigned NumExs = 0, const QualType *ExArray = 0, - bool NoReturn = false); + bool NoReturn = false, + CallingConv CallConv = CC_Default); /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. @@ -746,8 +754,8 @@ public: DeclarationName getNameForTemplate(TemplateName Name); - TemplateName getOverloadedTemplateName(NamedDecl * const *Begin, - NamedDecl * const *End); + TemplateName getOverloadedTemplateName(UnresolvedSetIterator Begin, + UnresolvedSetIterator End); TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 7c826fe..1491b1e 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -65,9 +65,21 @@ struct CXXBasePathElement { /// subobject is being used. class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> { public: + CXXBasePath() : Access(AS_public) {} + + /// \brief The access along this inheritance path. This is only + /// calculated when recording paths. AS_none is a special value + /// used to indicate a path which permits no legal access. + AccessSpecifier Access; + /// \brief The set of declarations found inside this base class /// subobject. DeclContext::lookup_result Decls; + + void clear() { + llvm::SmallVectorImpl<CXXBasePathElement>::clear(); + Access = AS_public; + } }; /// BasePaths - Represents the set of paths from a derived class to @@ -131,10 +143,10 @@ class CXXBasePaths { /// is also recorded. bool DetectVirtual; - /// ScratchPath - A BasePath that is used by Sema::IsDerivedFrom + /// ScratchPath - A BasePath that is used by Sema::lookupInBases /// to help build the set of paths. CXXBasePath ScratchPath; - + /// DetectedVirtual - The base class that is virtual. const RecordType *DetectedVirtual; diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 21b5909..6d52b2b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -55,32 +55,6 @@ public: TypeLoc getTypeLoc() const; }; -/// UnresolvedSet - A set of unresolved declarations. This is needed -/// in a lot of places, but isn't really worth breaking into its own -/// header right now. -class UnresolvedSet { - typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy; - DeclsTy Decls; - -public: - void addDecl(NamedDecl *D) { - Decls.push_back(D); - } - - bool replace(const NamedDecl* Old, NamedDecl *New) { - for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) - if (*I == Old) - return (*I = New, true); - return false; - } - - unsigned size() const { return Decls.size(); } - - typedef DeclsTy::const_iterator iterator; - iterator begin() const { return Decls.begin(); } - iterator end() const { return Decls.end(); } -}; - /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { ASTContext &Ctx; diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 497f863..775bce2 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -16,8 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Type.h" -// FIXME: Layering violation -#include "clang/Parse/AccessSpecifier.h" +#include "clang/Basic/Specifiers.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/ADT/PointerUnion.h" @@ -1017,13 +1016,8 @@ private: }; inline bool Decl::isTemplateParameter() const { - return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm; -} - -inline bool Decl::isDefinedOutsideFunctionOrMethod() const { - if (getDeclContext()) - return !getDeclContext()->getLookupContext()->isFunctionOrMethod(); - return true; + return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || + getKind() == TemplateTemplateParm; } } // end clang. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 336a895..73ebf52 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,6 +16,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" +#include "clang/AST/UnresolvedSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -275,13 +276,13 @@ class CXXRecordDecl : public RecordDecl { /// of this C++ class (but not its inherited conversion /// functions). Each of the entries in this overload set is a /// CXXConversionDecl. - UnresolvedSet Conversions; + 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 VisibleConversions; + UnresolvedSet<4> VisibleConversions; /// \brief The template or declaration that this declaration /// describes or was instantiated from, respectively. @@ -483,20 +484,20 @@ public: /// getConversions - Retrieve the overload set containing all of the /// conversion functions in this class. - UnresolvedSet *getConversionFunctions() { + UnresolvedSetImpl *getConversionFunctions() { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } - const UnresolvedSet *getConversionFunctions() const { + const UnresolvedSetImpl *getConversionFunctions() const { assert((this->isDefinition() || cast<RecordType>(getTypeForDecl())->isBeingDefined()) && "getConversionFunctions() called on incomplete type"); return &Conversions; } - typedef UnresolvedSet::iterator conversion_iterator; + typedef UnresolvedSetImpl::iterator conversion_iterator; conversion_iterator conversion_begin() const { return Conversions.begin(); } conversion_iterator conversion_end() const { return Conversions.end(); } @@ -509,7 +510,7 @@ public: /// getVisibleConversionFunctions - get all conversion functions visible /// in current class; including conversion function templates. - const UnresolvedSet *getVisibleConversionFunctions(); + const UnresolvedSetImpl *getVisibleConversionFunctions(); /// addVisibleConversionFunction - Add a new conversion function to the /// list of visible conversion functions. @@ -816,6 +817,15 @@ public: /// GraphViz. void viewInheritance(ASTContext& Context) const; + /// MergeAccess - Calculates the access of a decl that is reached + /// along a path. + static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, + AccessSpecifier DeclAccess) { + assert(DeclAccess != AS_none); + if (DeclAccess == AS_private) return AS_none; + return (PathAccess > DeclAccess ? PathAccess : DeclAccess); + } + static bool classof(const Decl *D) { return D->getKind() == CXXRecord || D->getKind() == ClassTemplateSpecialization || diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 920d31f..0fb0db1 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -75,6 +75,24 @@ public: } }; +/// \brief A list of Objective-C protocols, along with the source +/// locations at which they were referenced. +class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { + SourceLocation *Locations; + + using ObjCList<ObjCProtocolDecl>::set; + +public: + ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { } + + typedef const SourceLocation *loc_iterator; + loc_iterator loc_begin() const { return Locations; } + loc_iterator loc_end() const { return Locations + size(); } + + void set(ObjCProtocolDecl* const* InList, unsigned Elts, + const SourceLocation *Locs, ASTContext &Ctx); + void Destroy(ASTContext &Ctx); +}; /// ObjCMethodDecl - Represents an instance or class method declaration. @@ -410,9 +428,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl { ObjCInterfaceDecl *SuperClass; /// Protocols referenced in interface header declaration - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; - /// Instance variables in the interface. + /// Instance variables in the interface. This list is completely redundant. ObjCList<ObjCIvarDecl> IVars; /// List of categories defined for this class. @@ -442,7 +460,7 @@ public: SourceLocation ClassLoc = SourceLocation(), bool ForwardDecl = false, bool isInternal = false); - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } @@ -459,9 +477,16 @@ public: : getClassMethod(Sel); } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } unsigned protocol_size() const { return ReferencedProtocols.size(); } typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator; @@ -473,14 +498,16 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } /// mergeClassExtensionProtocolList - Merge class extension's protocol list /// into the protocol list for this class. - void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num, - ASTContext &C); + void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, + unsigned Num, + const SourceLocation *Locs, + ASTContext &C); void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { IVars.set(List, Num, C); @@ -660,7 +687,7 @@ public: /// class ObjCProtocolDecl : public ObjCContainerDecl { /// Referenced protocols - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; bool isForwardProtoDecl; // declared with @protocol. @@ -680,19 +707,26 @@ public: /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } unsigned protocol_size() const { return ReferencedProtocols.size(); } /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); @@ -772,31 +806,45 @@ public: /// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; /// class ObjCForwardProtocolDecl : public Decl { - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, ObjCProtocolDecl *const *Elts, unsigned nElts, - ASTContext &C); + const SourceLocation *Locs, ASTContext &C); virtual ~ObjCForwardProtocolDecl() {} public: static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - ObjCProtocolDecl *const *Elts = 0, - unsigned Num = 0); + ObjCProtocolDecl *const *Elts, + unsigned Num, + const SourceLocation *Locs); + + static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L) { + return Create(C, DC, L, 0, 0, 0); + } /// Destroy - Call destructors and release memory. virtual void Destroy(ASTContext& C); - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } + unsigned protocol_size() const { return ReferencedProtocols.size(); } /// setProtocolList - Set the list of forward protocols. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } static bool classof(const Decl *D) { return D->getKind() == ObjCForwardProtocol; @@ -826,22 +874,32 @@ class ObjCCategoryDecl : public ObjCContainerDecl { ObjCInterfaceDecl *ClassInterface; /// referenced protocols in this category. - ObjCList<ObjCProtocolDecl> ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; /// Next category belonging to this class. /// FIXME: this should not be a singly-linked list. Move storage elsewhere. ObjCCategoryDecl *NextClassCategory; - SourceLocation EndLoc; // marks the '>' or identifier. + /// \brief The location of the '@' in '@interface' + SourceLocation AtLoc; - ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) - : ObjCContainerDecl(ObjCCategory, DC, L, Id), - ClassInterface(0), NextClassCategory(0){ + /// \brief The location of the category name in this declaration. + SourceLocation CategoryNameLoc; + + ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, + SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, + IdentifierInfo *Id) + : ObjCContainerDecl(ObjCCategory, DC, ClassNameLoc, Id), + ClassInterface(0), NextClassCategory(0), AtLoc(AtLoc), + CategoryNameLoc(CategoryNameLoc) { } public: static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id); + SourceLocation AtLoc, + SourceLocation ClassNameLoc, + SourceLocation CategoryNameLoc, + IdentifierInfo *Id); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -853,18 +911,25 @@ public: /// setProtocolList - Set the list of protocols that this interface /// implements. void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, - ASTContext &C) { - ReferencedProtocols.set(List, Num, C); + const SourceLocation *Locs, ASTContext &C) { + ReferencedProtocols.set(List, Num, Locs, C); } - const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { + const ObjCProtocolList &getReferencedProtocols() const { return ReferencedProtocols; } - typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; + typedef ObjCProtocolList::iterator protocol_iterator; protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } unsigned protocol_size() const { return ReferencedProtocols.size(); } + typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; + protocol_loc_iterator protocol_loc_begin() const { + return ReferencedProtocols.loc_begin(); + } + protocol_loc_iterator protocol_loc_end() const { + return ReferencedProtocols.loc_end(); + } ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } void setNextClassCategory(ObjCCategoryDecl *Cat) { @@ -874,10 +939,16 @@ public: NextClassCategory = ClassInterface->getCategoryList(); ClassInterface->setCategoryList(this); } - // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const { return getLocation(); } // '@'interface - SourceLocation getLocEnd() const { return EndLoc; } - void setLocEnd(SourceLocation LE) { EndLoc = LE; } + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation At) { AtLoc = At; } + + SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } + void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } + + virtual SourceRange getSourceRange() const { + return SourceRange(AtLoc, getAtEndRange().getEnd()); + } static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } static bool classof(const ObjCCategoryDecl *D) { return true; } @@ -1133,6 +1204,7 @@ public: enum SetterKind { Assign, Retain, Copy }; enum PropertyControl { None, Required, Optional }; private: + SourceLocation AtLoc; // location of @property QualType DeclType; unsigned PropertyAttributes : 8; @@ -1147,8 +1219,8 @@ private: ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T) - : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T), + SourceLocation AtLocation, QualType T) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T), PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), GetterName(Selector()), SetterName(Selector()), @@ -1156,8 +1228,12 @@ private: public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, + IdentifierInfo *Id, SourceLocation AtLocation, + QualType T, PropertyControl propControl = None); + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + QualType getType() const { return DeclType; } void setType(QualType T) { DeclType = T; } diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index cfbae9f..2527817 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1462,14 +1462,19 @@ class CompoundLiteralExpr : public Expr { /// compound literal like "(int){4}". This can be null if this is a /// synthesized compound expression. SourceLocation LParenLoc; + + /// The type as written. This can be an incomplete array type, in + /// which case the actual expression type will be different. + TypeSourceInfo *TInfo; Stmt *Init; bool FileScope; public: // FIXME: Can compound literals be value-dependent? - CompoundLiteralExpr(SourceLocation lparenloc, QualType ty, Expr *init, - bool fileScope) - : Expr(CompoundLiteralExprClass, ty, ty->isDependentType(), false), - LParenLoc(lparenloc), Init(init), FileScope(fileScope) {} + CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, + QualType T, Expr *init, bool fileScope) + : Expr(CompoundLiteralExprClass, T, + tinfo->getType()->isDependentType(), false), + LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {} /// \brief Construct an empty compound literal. explicit CompoundLiteralExpr(EmptyShell Empty) @@ -1485,6 +1490,9 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } void setLParenLoc(SourceLocation L) { LParenLoc = L; } + TypeSourceInfo *getTypeSourceInfo() const { return TInfo; } + void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; } + virtual SourceRange getSourceRange() const { // FIXME: Init should never be null. if (!Init) @@ -1712,24 +1720,28 @@ public: /// expression will be an lvalue. The reference type, however, will /// not be used as the type of the expression. class ExplicitCastExpr : public CastExpr { - /// TypeAsWritten - The type that this expression is casting to, as - /// written in the source code. - QualType TypeAsWritten; + /// TInfo - Source type info for the (written) type + /// this expression is casting to. + TypeSourceInfo *TInfo; protected: ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind, - Expr *op, QualType writtenTy) - : CastExpr(SC, exprTy, kind, op), TypeAsWritten(writtenTy) {} + Expr *op, TypeSourceInfo *writtenTy) + : CastExpr(SC, exprTy, kind, op), TInfo(writtenTy) {} /// \brief Construct an empty explicit cast. ExplicitCastExpr(StmtClass SC, EmptyShell Shell) : CastExpr(SC, Shell) { } public: + /// getTypeInfoAsWritten - Returns the type source info for the type + /// that this expression is casting to. + TypeSourceInfo *getTypeInfoAsWritten() const { return TInfo; } + void setTypeInfoAsWritten(TypeSourceInfo *writtenTy) { TInfo = writtenTy; } + /// getTypeAsWritten - Returns the type that this expression is /// casting to, as written in the source code. - QualType getTypeAsWritten() const { return TypeAsWritten; } - void setTypeAsWritten(QualType T) { TypeAsWritten = T; } + QualType getTypeAsWritten() const { return TInfo->getType(); } static bool classof(const Stmt *T) { StmtClass SC = T->getStmtClass(); @@ -1750,8 +1762,9 @@ class CStyleCastExpr : public ExplicitCastExpr { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren public: - CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, QualType writtenTy, - SourceLocation l, SourceLocation r) : + CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op, + TypeSourceInfo *writtenTy, + SourceLocation l, SourceLocation r) : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, writtenTy), LPLoc(l), RPLoc(r) {} diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 55d5108e..6ce95ac 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -16,7 +16,7 @@ #include "clang/Basic/TypeTraits.h" #include "clang/AST/Expr.h" -#include "clang/AST/Decl.h" +#include "clang/AST/UnresolvedSet.h" #include "clang/AST/TemplateBase.h" namespace clang { @@ -118,9 +118,12 @@ private: protected: CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : ExplicitCastExpr(SC, ty, kind, op, writtenTy), Loc(l) {} + explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell) + : ExplicitCastExpr(SC, Shell) { } + public: const char *getCastName() const; @@ -154,9 +157,12 @@ public: class CXXStaticCastExpr : public CXXNamedCastExpr { public: CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXStaticCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } @@ -171,10 +177,13 @@ public: /// @c dynamic_cast<Derived*>(BasePtr). class CXXDynamicCastExpr : public CXXNamedCastExpr { public: - CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, QualType writtenTy, - SourceLocation l) + CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXDynamicCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } @@ -190,10 +199,13 @@ public: class CXXReinterpretCastExpr : public CXXNamedCastExpr { public: CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, - QualType writtenTy, SourceLocation l) + TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, writtenTy, l) {} + explicit CXXReinterpretCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } @@ -207,10 +219,13 @@ public: /// @c const_cast<char*>(PtrToConstChar). class CXXConstCastExpr : public CXXNamedCastExpr { public: - CXXConstCastExpr(QualType ty, Expr *op, QualType writtenTy, + CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l) : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, writtenTy, l) {} + explicit CXXConstCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } @@ -625,15 +640,20 @@ class CXXFunctionalCastExpr : public ExplicitCastExpr { SourceLocation TyBeginLoc; SourceLocation RParenLoc; public: - CXXFunctionalCastExpr(QualType ty, QualType writtenTy, + CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy, SourceLocation tyBeginLoc, CastKind kind, Expr *castExpr, SourceLocation rParenLoc) : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, writtenTy), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + explicit CXXFunctionalCastExpr(EmptyShell Shell) + : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { } + SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } + void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(TyBeginLoc, RParenLoc); @@ -1052,7 +1072,7 @@ public: class UnresolvedLookupExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. - UnresolvedSet Results; + UnresolvedSet<4> Results; /// The name declared. DeclarationName Name; @@ -1113,15 +1133,15 @@ public: /// Computes whether an unresolved lookup on the given declarations /// and optional template arguments is type- and value-dependent. - static bool ComputeDependence(NamedDecl * const *Begin, - NamedDecl * const *End, + static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin, + UnresolvedSetImpl::const_iterator End, const TemplateArgumentListInfo *Args); void addDecl(NamedDecl *Decl) { Results.addDecl(Decl); } - typedef UnresolvedSet::iterator decls_iterator; + typedef UnresolvedSetImpl::iterator decls_iterator; decls_iterator decls_begin() const { return Results.begin(); } decls_iterator decls_end() const { return Results.end(); } @@ -1696,7 +1716,7 @@ public: class UnresolvedMemberExpr : public Expr { /// The results. These are undesugared, which is to say, they may /// include UsingShadowDecls. - UnresolvedSet Results; + UnresolvedSet<4> Results; /// \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' @@ -1775,7 +1795,7 @@ public: Results.addDecl(Decl); } - typedef UnresolvedSet::iterator decls_iterator; + typedef UnresolvedSetImpl::iterator decls_iterator; decls_iterator decls_begin() const { return Results.begin(); } decls_iterator decls_end() const { return Results.end(); } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 9b0cdc3..b7b60df 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -385,6 +385,14 @@ public: } }; +/// CallingConv - Specifies the calling convention that a function uses. +enum CallingConv { + CC_Default, + CC_C, // __attribute__((cdecl)) + CC_X86StdCall, // __attribute__((stdcall)) + CC_X86FastCall // __attribute__((fastcall)) +}; + /// QualType - For efficiency, we don't store CV-qualified types as nodes on /// their own: instead each reference to a type stores the qualifiers. This @@ -669,6 +677,10 @@ public: /// false otherwise. bool getNoReturnAttr() const; + /// getCallConv - Returns the calling convention of the type if the type + /// is a function type, CC_Default otherwise. + CallingConv getCallConv() const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the @@ -1691,21 +1703,25 @@ class FunctionType : public Type { /// NoReturn - Indicates if the function type is attribute noreturn. unsigned NoReturn : 1; + /// CallConv - The calling convention used by the function. + unsigned CallConv : 2; + // The type returned by the function. QualType ResultType; protected: FunctionType(TypeClass tc, QualType res, bool SubclassInfo, unsigned typeQuals, QualType Canonical, bool Dependent, - bool noReturn = false) + bool noReturn = false, CallingConv callConv = CC_Default) : Type(tc, Canonical, Dependent), SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn), - ResultType(res) {} + CallConv(callConv), ResultType(res) {} bool getSubClassData() const { return SubClassData; } unsigned getTypeQuals() const { return TypeQuals; } public: QualType getResultType() const { return ResultType; } bool getNoReturnAttr() const { return NoReturn; } + CallingConv getCallConv() const { return (CallingConv)CallConv; } static bool classof(const Type *T) { return T->getTypeClass() == FunctionNoProto || @@ -1718,9 +1734,9 @@ public: /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, - bool NoReturn = false) + bool NoReturn = false, CallingConv CallConv = CC_Default) : FunctionType(FunctionNoProto, Result, false, 0, Canonical, - /*Dependent=*/false, NoReturn) {} + /*Dependent=*/false, NoReturn, CallConv) {} friend class ASTContext; // ASTContext creates these. public: // No additional state past what FunctionType provides. @@ -1762,10 +1778,12 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs, bool isVariadic, unsigned typeQuals, bool hasExs, bool hasAnyExs, const QualType *ExArray, - unsigned numExs, QualType Canonical, bool NoReturn) + unsigned numExs, QualType Canonical, bool NoReturn, + CallingConv CallConv) : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, (Result->isDependentType() || - hasAnyDependentType(ArgArray, numArgs)), NoReturn), + hasAnyDependentType(ArgArray, numArgs)), NoReturn, + CallConv), NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), AnyExceptionSpec(hasAnyExs) { // Fill in the trailing argument array. @@ -2496,26 +2514,31 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode { // List of protocols for this protocol conforming object type // List is sorted on protocol name. No protocol is enterred more than once. - llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols; + ObjCProtocolDecl **Protocols; + unsigned NumProtocols; - ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D, - ObjCProtocolDecl **Protos, unsigned NumP) : - Type(ObjCInterface, Canonical, /*Dependent=*/false), - Decl(D), Protocols(Protos, Protos+NumP) { } + ObjCInterfaceType(ASTContext &Ctx, QualType Canonical, ObjCInterfaceDecl *D, + ObjCProtocolDecl **Protos, unsigned NumP); friend class ASTContext; // ASTContext creates these. public: + void Destroy(ASTContext& C); + ObjCInterfaceDecl *getDecl() const { return Decl; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return Protocols.size(); } + unsigned getNumProtocols() const { return NumProtocols; } /// qual_iterator and friends: this provides access to the (potentially empty) /// list of protocols qualifying this interface. - typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; - qual_iterator qual_begin() const { return Protocols.begin(); } - qual_iterator qual_end() const { return Protocols.end(); } - bool qual_empty() const { return Protocols.size() == 0; } + typedef ObjCProtocolDecl* const * qual_iterator; + qual_iterator qual_begin() const { + return Protocols; + } + qual_iterator qual_end() const { + return Protocols ? Protocols + NumProtocols : 0; + } + bool qual_empty() const { return NumProtocols == 0; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2541,15 +2564,16 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { // List of protocols for this protocol conforming object type // List is sorted on protocol name. No protocol is entered more than once. - llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols; + ObjCProtocolDecl **Protocols; + unsigned NumProtocols; - ObjCObjectPointerType(QualType Canonical, QualType T, - ObjCProtocolDecl **Protos, unsigned NumP) : - Type(ObjCObjectPointer, Canonical, /*Dependent=*/false), - PointeeType(T), Protocols(Protos, Protos+NumP) { } + ObjCObjectPointerType(ASTContext &Ctx, QualType Canonical, QualType T, + ObjCProtocolDecl **Protos, unsigned NumP); friend class ASTContext; // ASTContext creates these. public: + void Destroy(ASTContext& C); + // Get the pointee type. Pointee will either be: // - a built-in type (for 'id' and 'Class'). // - an interface type (for user-defined types). @@ -2567,35 +2591,39 @@ public: /// isObjCIdType - true for "id". bool isObjCIdType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - !Protocols.size(); + !NumProtocols; } /// isObjCClassType - true for "Class". bool isObjCClassType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - !Protocols.size(); + !NumProtocols; } /// isObjCQualifiedIdType - true for "id <p>". bool isObjCQualifiedIdType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCId) && - Protocols.size(); + NumProtocols; } /// isObjCQualifiedClassType - true for "Class <p>". bool isObjCQualifiedClassType() const { return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && - Protocols.size(); + NumProtocols; } /// qual_iterator and friends: this provides access to the (potentially empty) /// list of protocols qualifying this interface. - typedef llvm::SmallVector<ObjCProtocolDecl*, 8>::const_iterator qual_iterator; + typedef ObjCProtocolDecl* const * qual_iterator; - qual_iterator qual_begin() const { return Protocols.begin(); } - qual_iterator qual_end() const { return Protocols.end(); } - bool qual_empty() const { return Protocols.size() == 0; } + qual_iterator qual_begin() const { + return Protocols; + } + qual_iterator qual_end() const { + return Protocols ? Protocols + NumProtocols : NULL; + } + bool qual_empty() const { return NumProtocols == 0; } /// getNumProtocols - Return the number of qualifying protocols in this /// interface type, or 0 if there are none. - unsigned getNumProtocols() const { return Protocols.size(); } + unsigned getNumProtocols() const { return NumProtocols; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2797,6 +2825,26 @@ inline bool QualType::getNoReturnAttr() const { return false; } +/// getCallConv - Returns the calling convention of the type if the type +/// is a function type, CC_Default otherwise. +inline CallingConv QualType::getCallConv() const { + if (const PointerType *PT = getTypePtr()->getAs<PointerType>()) + return PT->getPointeeType().getCallConv(); + else if (const ReferenceType *RT = getTypePtr()->getAs<ReferenceType>()) + return RT->getPointeeType().getCallConv(); + else if (const MemberPointerType *MPT = + getTypePtr()->getAs<MemberPointerType>()) + return MPT->getPointeeType().getCallConv(); + else if (const BlockPointerType *BPT = + getTypePtr()->getAs<BlockPointerType>()) { + if (const FunctionType *FT = BPT->getPointeeType()->getAs<FunctionType>()) + return FT->getCallConv(); + } else if (const FunctionType *FT = getTypePtr()->getAs<FunctionType>()) + return FT->getCallConv(); + + return CC_Default; +} + /// isMoreQualifiedThan - Determine whether this type is more /// qualified than the Other type. For example, "const volatile int" /// is more qualified than "const int", "volatile int", and diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index c36c0ff..6fb51ed 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -16,6 +16,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TemplateBase.h" +#include "clang/Basic/Specifiers.h" namespace clang { class ParmVarDecl; @@ -372,6 +373,111 @@ public: }; +struct BuiltinLocInfo { + SourceLocation BuiltinLoc; +}; + +/// \brief Wrapper for source info for builtin types. +class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + BuiltinTypeLoc, + BuiltinType, + BuiltinLocInfo> { +public: + enum { LocalDataSize = sizeof(BuiltinLocInfo) }; + + SourceLocation getBuiltinLoc() const { + return getLocalData()->BuiltinLoc; + } + void setBuiltinLoc(SourceLocation Loc) { + getLocalData()->BuiltinLoc = Loc; + } + + SourceLocation getNameLoc() const { return getBuiltinLoc(); } + + WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { + return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); + } + const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { + return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); + } + + bool needsExtraLocalData() const { + BuiltinType::Kind bk = getTypePtr()->getKind(); + return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) + || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) + || bk == BuiltinType::UChar + || bk == BuiltinType::SChar; + } + + unsigned getExtraLocalDataSize() const { + return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; + } + + SourceRange getSourceRange() const { + return SourceRange(getBuiltinLoc(), getBuiltinLoc()); + } + + TypeSpecifierSign getWrittenSignSpec() const { + if (needsExtraLocalData()) + return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); + else + return TSS_unspecified; + } + bool hasWrittenSignSpec() const { + return getWrittenSignSpec() != TSS_unspecified; + } + void setWrittenSignSpec(TypeSpecifierSign written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Sign = written; + } + + TypeSpecifierWidth getWrittenWidthSpec() const { + if (needsExtraLocalData()) + return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); + else + return TSW_unspecified; + } + bool hasWrittenWidthSpec() const { + return getWrittenWidthSpec() != TSW_unspecified; + } + void setWrittenWidthSpec(TypeSpecifierWidth written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Width = written; + } + + TypeSpecifierType getWrittenTypeSpec() const; + bool hasWrittenTypeSpec() const { + return getWrittenTypeSpec() != TST_unspecified; + } + void setWrittenTypeSpec(TypeSpecifierType written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().Type = written; + } + + bool hasModeAttr() const { + if (needsExtraLocalData()) + return getWrittenBuiltinSpecs().ModeAttr; + else + return false; + } + void setModeAttr(bool written) { + if (needsExtraLocalData()) + getWrittenBuiltinSpecs().ModeAttr = written; + } + + void initializeLocal(SourceLocation Loc) { + setBuiltinLoc(Loc); + if (needsExtraLocalData()) { + WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); + wbs.Sign = TSS_unspecified; + wbs.Width = TSW_unspecified; + wbs.Type = TST_unspecified; + wbs.ModeAttr = false; + } + } +}; + + /// \brief Wrapper for source info for typedefs. class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, TypedefTypeLoc, @@ -421,12 +527,6 @@ public: EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } }; -/// \brief Wrapper for source info for builtin types. -class BuiltinTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - BuiltinTypeLoc, - BuiltinType> { -}; - /// \brief Wrapper for template type parameters. class TemplateTypeParmTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index 95ec175..50fc439 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -43,6 +43,7 @@ public: case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc); #include "clang/AST/TypeLocNodes.def" } + llvm_unreachable("unexpected type loc class!"); } #define TYPELOC(CLASS, PARENT) \ diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h new file mode 100644 index 0000000..055d152 --- /dev/null +++ b/include/clang/AST/UnresolvedSet.h @@ -0,0 +1,211 @@ +//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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 UnresolvedSet class, which is used to store +// collections of declarations in the AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_UNRESOLVEDSET_H +#define LLVM_CLANG_AST_UNRESOLVEDSET_H + +#include <iterator> +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "clang/Basic/Specifiers.h" + +namespace clang { + +class NamedDecl; + +/// 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; + typedef DeclsTy::iterator IteratorTy; + + IteratorTy ir; + + friend class UnresolvedSetImpl; + explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} + explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : + ir(const_cast<DeclsTy::iterator>(ir)) {} +public: + UnresolvedSetIterator() {} + + typedef std::iterator_traits<IteratorTy>::difference_type difference_type; + typedef NamedDecl *value_type; + typedef NamedDecl **pointer; + 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 *operator*() const { return getDecl(); } + + UnresolvedSetIterator &operator++() { ++ir; return *this; } + UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } + UnresolvedSetIterator &operator--() { --ir; return *this; } + UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } + + UnresolvedSetIterator &operator+=(difference_type d) { + ir += d; return *this; + } + UnresolvedSetIterator operator+(difference_type d) const { + return UnresolvedSetIterator(ir + d); + } + UnresolvedSetIterator &operator-=(difference_type d) { + ir -= d; return *this; + } + UnresolvedSetIterator operator-(difference_type d) const { + return UnresolvedSetIterator(ir - d); + } + value_type operator[](difference_type d) const { return *(*this + d); } + + difference_type operator-(const UnresolvedSetIterator &o) const { + return ir - o.ir; + } + + bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } + bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } + bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } + bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } + bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } + bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } +}; + +/// UnresolvedSet - A set of unresolved declarations. This is needed +/// in a lot of places, but isn't really worth breaking into its own +/// header right now. +class UnresolvedSetImpl { + typedef UnresolvedSetIterator::DeclEntry DeclEntry; + typedef UnresolvedSetIterator::DeclsTy DeclsTy; + + // Don't allow direct construction, and only permit subclassing by + // UnresolvedSet. +private: + template <unsigned N> friend class UnresolvedSet; + UnresolvedSetImpl() {} + UnresolvedSetImpl(const UnresolvedSetImpl &) {} + +public: + // We don't currently support assignment through this iterator, so we might + // as well use the same implementation twice. + typedef UnresolvedSetIterator iterator; + typedef UnresolvedSetIterator const_iterator; + + iterator begin() { return iterator(decls().begin()); } + iterator end() { return iterator(decls().end()); } + + const_iterator begin() const { return const_iterator(decls().begin()); } + const_iterator end() const { return const_iterator(decls().end()); } + + void addDecl(NamedDecl *D) { + addDecl(D, AS_none); + } + + void addDecl(NamedDecl *D, AccessSpecifier AS) { + decls().push_back(DeclEntry(D, AS)); + } + + /// Replaces the given declaration with the new one, once. + /// + /// \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); + 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); + } + + void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { + *I.ir = DeclEntry(New, AS); + } + + void erase(iterator I) { + *I.ir = decls().back(); + decls().pop_back(); + } + + void clear() { decls().clear(); } + void set_size(unsigned N) { decls().set_size(N); } + + bool empty() const { return decls().empty(); } + unsigned size() const { return decls().size(); } + + void append(iterator I, iterator E) { + 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]); } + +private: + // These work because the only permitted subclass is UnresolvedSetImpl + + DeclsTy &decls() { + return *reinterpret_cast<DeclsTy*>(this); + } + const DeclsTy &decls() const { + return *reinterpret_cast<const DeclsTy*>(this); + } +}; + +/// A set of unresolved declarations +template <unsigned InlineCapacity> class UnresolvedSet : + public UnresolvedSetImpl { + llvm::SmallVector<UnresolvedSetImpl::DeclEntry, InlineCapacity> Decls; +}; + + +} // namespace clang + +#endif diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index 38d4bdf..e87784f 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -20,12 +20,14 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include "clang/Analysis/Support/BumpVector.h" +#include "clang/Basic/SourceLocation.h" #include <cassert> namespace llvm { class raw_ostream; } namespace clang { + class Decl; class Stmt; class Expr; class CFG; @@ -33,15 +35,39 @@ namespace clang { class LangOptions; class ASTContext; +namespace { +// An element of the CFG for implicit descructor calls implied by the language +// rules. +class Dtor { + // Statement that introduces the variable. + Stmt *S; + // A token which ends the scope, return, goto, throw, }. + SourceLocation Loc; +public: + Dtor(Stmt *s, SourceLocation l) : S(s), Loc(l) { + } + SourceLocation getLoc() { return Loc; } + Stmt *getStmt() { return S; } +}; +} + /// CFGElement - Represents a top-level expression in a basic block. class CFGElement { - llvm::PointerIntPair<Stmt *, 1> Data; + llvm::PointerIntPair<Stmt *, 2> Data; public: + enum Type { StartScope, EndScope }; explicit CFGElement() {} CFGElement(Stmt *S, bool lvalue) : Data(S, lvalue ? 1 : 0) {} + CFGElement(Stmt *S, Type t) : Data(S, t == StartScope ? 2 : 3) {} + // CFGElement(Dtor *S, Type t) : Data(reinterpret_cast<Stmt*>(S), 4) {} Stmt *getStmt() const { return Data.getPointer(); } bool asLValue() const { return Data.getInt() == 1; } + bool asStartScope() const { return Data.getInt() == 2; } + bool asEndScope() const { return Data.getInt() == 3; } + bool asDtor() const { return Data.getInt() == 4; } operator Stmt*() const { return getStmt(); } + operator bool() const { return getStmt() != 0; } + operator Dtor*() const { return reinterpret_cast<Dtor*>(getStmt()); } }; /// CFGBlock - Represents a single basic block in a source-level CFG. @@ -107,7 +133,7 @@ class CFGBlock { /// Label - An (optional) label that prefixes the executable /// statements in the block. When this variable is non-NULL, it is - /// either an instance of LabelStmt or SwitchCase. + /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt. Stmt *Label; /// Terminator - The terminator for a basic block that @@ -236,6 +262,12 @@ public: void appendStmt(Stmt* Statement, BumpVectorContext &C, bool asLValue) { Stmts.push_back(CFGElement(Statement, asLValue), C); } + void StartScope(Stmt* S, BumpVectorContext &C) { + Stmts.push_back(CFGElement(S, CFGElement::StartScope), C); + } + void EndScope(Stmt* S, BumpVectorContext &C) { + Stmts.push_back(CFGElement(S, CFGElement::EndScope), C); + } }; @@ -254,7 +286,9 @@ public: /// buildCFG - Builds a CFG from an AST. The responsibility to free the /// constructed CFG belongs to the caller. - static CFG* buildCFG(Stmt* AST, ASTContext *C); + static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C, + bool AddEHEdges = false, + bool AddScopes = false); /// createBlock - Create a new block in the CFG. The CFG owns the block; /// the caller should not directly free it. diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h index 63ba558..c82bb96 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -46,14 +46,21 @@ class AnalysisContext { ParentMap *PM; llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars; llvm::BumpPtrAllocator A; + bool AddEHEdges; public: - AnalysisContext(const Decl *d) : D(d), cfg(0), liveness(0), PM(0), - ReferencedBlockVars(0) {} + AnalysisContext(const Decl *d, bool addehedges = false) + : D(d), cfg(0), liveness(0), PM(0), ReferencedBlockVars(0), + AddEHEdges(addehedges) {} ~AnalysisContext(); ASTContext &getASTContext() { return D->getASTContext(); } const Decl *getDecl() { return D; } + /// getAddEHEdges - Return true iff we are adding exceptional edges from + /// callExprs. If this is false, then try/catch statements and blocks + /// reachable from them can appear to be dead in the CFG, analysis passes must + /// cope with that. + bool getAddEHEdges() const { return AddEHEdges; } Stmt *getBody(); CFG *getCFG(); ParentMap &getParentMap(); diff --git a/include/clang/Analysis/PathSensitive/CheckerVisitor.h b/include/clang/Analysis/PathSensitive/CheckerVisitor.h index f5145bb..37ec8de 100644 --- a/include/clang/Analysis/PathSensitive/CheckerVisitor.h +++ b/include/clang/Analysis/PathSensitive/CheckerVisitor.h @@ -66,6 +66,11 @@ break; default: assert(false && "Unsupport statement."); return; + case Stmt::CompoundAssignOperatorClass: + static_cast<ImplClass*>(this)->PostVisitBinaryOperator(C, + static_cast<const BinaryOperator*>(S)); + break; + #define POSTVISIT(NAME, FALLBACK) \ case Stmt::NAME ## Class:\ static_cast<ImplClass*>(this)->\ diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index fb0e883..df90ad9 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -270,8 +270,8 @@ protected: ExplodedNodeSet& Dst, bool asLValue); /// VisitCast - Transfer function logic for all casts (implicit and explicit). - void VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, - ExplodedNodeSet& Dst, bool asLValue); + void VisitCast(CastExpr *CastE, Expr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst, bool asLValue); /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. void VisitCompoundLiteralExpr(CompoundLiteralExpr* CL, ExplodedNode* Pred, diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 70c17ac..5606df0 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -105,7 +105,8 @@ public: // FIXME: Make out-of-line. virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, - const MemRegion *region) { + const MemRegion *region, + QualType EleTy) { return UnknownVal(); } diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 14f7356..0894563 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -270,6 +270,7 @@ BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") BUILTIN(__builtin_constant_p, "Us.", "nc") BUILTIN(__builtin_classify_type, "i.", "nc") BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc") +BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc") BUILTIN(__builtin_va_start, "vA.", "n") BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 6315c16..0062846 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -79,12 +79,7 @@ BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "") BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "") BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "") BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dc", "") BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dc", "") BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "") @@ -99,7 +94,6 @@ BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "") BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "") BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmullw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "") BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "") diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index dfb6f8d..8cdf850 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -83,5 +83,7 @@ def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; 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">; } diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 26a80b5..3f765bd 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -172,9 +172,6 @@ def err_pp_hash_error : Error<"#error%0">; def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; -def warn_pp_relative_include_from_framework : Warning< - "published framework headers should always #import headers within the " - "framework with framework paths">, InGroup<DiagGroup<"framework-headers">>; def err_pp_empty_filename : Error<"empty filename">; def err_pp_include_too_deep : Error<"#include nested too deeply">; def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7e59f88..8d75d2e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -412,6 +412,15 @@ def err_class_redeclared_with_different_access : Error< "%0 redeclared with '%1' access">; 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_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">; // C++ name lookup def err_incomplete_nested_name_spec : Error< @@ -537,8 +546,9 @@ def err_destructor_name : Error< // C++ initialization def err_init_conversion_failed : Error< "cannot initialize %select{a variable|a parameter|return object|an " - "exception object|a value|a base class|a member subobject|an array element}0" - " of type %1 with an %select{rvalue|lvalue}2 of type %3">; + "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 " + "type %3">; def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">; def err_invalid_initialization : Error< @@ -913,10 +923,24 @@ def note_ovl_candidate_arity : Note<"candidate " "function (the implicit copy assignment operator)}0 not viable: requires" "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 " "provided">; + def note_ovl_candidate_deleted : Note< "candidate %select{function|function|constructor|" "function |function |constructor |||}0%1 " "has been explicitly %select{made unavailable|deleted}2">; + +// Giving the index of the bad argument really clutters this message, and +// it's relatively unimportant because 1) it's generally obvious which +// argument(s) are of the given object type and 2) the fix is usually +// to complete the type, which doesn't involve changes to the call line +// anyway. If people complain, we can change it. +def note_ovl_candidate_bad_conv_incomplete : 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: cannot convert argument of incomplete type %2 to %3">; def note_ovl_candidate_bad_conv : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -1840,6 +1864,9 @@ def err_illegal_super_cast : Error< def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " "use @synthesize, @dynamic or provide a method implementation">; +def warn_setter_getter_impl_required_in_category : Warning< + "property %0 requires method %1 to be defined - " + "use @dynamic or provide a method implementation in category">; def note_property_impl_required : Note< "implementation is here">; @@ -2458,8 +2485,6 @@ def warn_stringcompare : Warning< def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks" " or pick a deployment target that supports them">; def err_expected_block_lbrace : Error<"expected '{' in block literal">; -def err_goto_in_block : Error< - "goto not allowed in block literal">; def err_return_in_block_expression : Error< "return not allowed in block expression literal">; def err_block_returns_array : Error< diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h new file mode 100644 index 0000000..3287b30 --- /dev/null +++ b/include/clang/Basic/MacroBuilder.h @@ -0,0 +1,46 @@ +//===--- MacroBuilder.h - CPP Macro building utility ------------*- 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 MacroBuilder utility class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_MACROBUILDER_H +#define LLVM_CLANG_BASIC_MACROBUILDER_H + +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +class MacroBuilder { + llvm::raw_ostream &Out; +public: + MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {} + + /// Append a #define line for macro of the form "#define Name Value\n". + void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") { + Out << "#define " << Name << ' ' << Value << '\n'; + } + + /// Append a #undef line for Name. Name should be of the form XXX + /// and we emit "#undef XXX". + void undefineMacro(const llvm::Twine &Name) { + Out << "#undef " << Name << '\n'; + } + + /// Directly append Str and a newline to the underlying buffer. + void append(const llvm::Twine &Str) { + Out << Str << '\n'; + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile index b85eb07..48f7f9d 100644 --- a/include/clang/Basic/Makefile +++ b/include/clang/Basic/Makefile @@ -11,14 +11,12 @@ include $(LEVEL)/Makefile.common INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td) -$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) +$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen" - $(Verb) -$(MKDIR) $(@D) $(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< -$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) +$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang diagnostic groups with tblgen" - $(Verb) -$(MKDIR) $(@D) $(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $< diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h new file mode 100644 index 0000000..4cace86 --- /dev/null +++ b/include/clang/Basic/Specifiers.h @@ -0,0 +1,82 @@ +//===--- Specifiers.h - Declaration and Type Specifiers ---------*- 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 various enumerations that describe declaration and +// type specifiers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_SPECIFIERS_H +#define LLVM_CLANG_BASIC_SPECIFIERS_H + +namespace clang { + /// \brief Specifies the width of a type, e.g., short, long, or long long. + enum TypeSpecifierWidth { + TSW_unspecified, + TSW_short, + TSW_long, + TSW_longlong + }; + + /// \brief Specifies the signedness of a type, e.g., signed or unsigned. + enum TypeSpecifierSign { + TSS_unspecified, + TSS_signed, + TSS_unsigned + }; + + /// \brief Specifies the kind of type. + enum TypeSpecifierType { + TST_unspecified, + TST_void, + TST_char, + TST_wchar, // C++ wchar_t + TST_char16, // C++0x char16_t + TST_char32, // C++0x char32_t + TST_int, + TST_float, + TST_double, + TST_bool, // _Bool + TST_decimal32, // _Decimal32 + TST_decimal64, // _Decimal64 + TST_decimal128, // _Decimal128 + TST_enum, + TST_union, + TST_struct, + TST_class, // C++ class type + TST_typename, // Typedef, C++ class-name or enum name, etc. + TST_typeofType, + TST_typeofExpr, + TST_decltype, // C++0x decltype + TST_auto, // C++0x auto + TST_error // erroneous type + }; + + /// WrittenBuiltinSpecs - Structure that packs information about the + /// type specifiers that were written in a particular type specifier + /// sequence. + struct WrittenBuiltinSpecs { + /*DeclSpec::TST*/ unsigned Type : 5; + /*DeclSpec::TSS*/ unsigned Sign : 2; + /*DeclSpec::TSW*/ unsigned Width : 2; + bool ModeAttr : 1; + }; + + /// AccessSpecifier - A C++ access specifier (public, private, + /// protected), plus the special value "none" which means + /// different things in different contexts. + enum AccessSpecifier { + AS_public, + AS_protected, + AS_private, + AS_none + }; +} + +#endif // LLVM_CLANG_BASIC_SPECIFIERS_H diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h index 120d5a4..4710b6b 100644 --- a/include/clang/Basic/Version.h +++ b/include/clang/Basic/Version.h @@ -15,6 +15,8 @@ #ifndef LLVM_CLANG_BASIC_VERSION_H #define LLVM_CLANG_BASIC_VERSION_H +#include "llvm/ADT/StringRef.h" + /// \brief Clang major version #define CLANG_VERSION_MAJOR 1 @@ -47,13 +49,23 @@ #endif namespace clang { - /// \brief Retrieves the Subversion path that identifies the particular - /// Clang branch, tag, or trunk from which this Clang was built. - const char *getClangSubversionPath(); + /// \brief Retrieves the repository path (e.g., Subversion path) that + /// identifies the particular Clang branch, tag, or trunk from which this + /// Clang was built. + llvm::StringRef getClangRepositoryPath(); + + /// \brief Retrieves the repository revision number (or identifer) from which + /// this Clang was built. + llvm::StringRef getClangRevision(); + + /// \brief Retrieves the full repository version that is an amalgamation of + /// the information in getClangRepositoryPath() and getClangRevision(). + llvm::StringRef getClangFullRepositoryVersion(); - /// \brief Retrieves the Subversion revision number from which this Clang - /// was built. - unsigned getClangSubversionRevision(); + /// \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(); } #endif // LLVM_CLANG_BASIC_VERSION_H diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 8933619..3186471 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -61,6 +61,9 @@ public: /// command line. std::string Dir; + /// The path to the compiler resource directory. + std::string ResourceDir; + /// Default host triple. std::string DefaultHostTriple; diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index f18972a..2659dbb 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -21,6 +21,11 @@ #include <string> #include <vector> #include <cassert> +#include <utility> + +namespace llvm { + class MemoryBuffer; +} namespace clang { class ASTContext; @@ -111,6 +116,10 @@ public: return TopLevelDecls; } + /// \brief A mapping from a file name to the memory buffer that stores the + /// remapped contents of that file. + typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile; + /// \brief Create a ASTUnit from a PCH file. /// /// \param Filename - The PCH file to load. @@ -122,7 +131,9 @@ public: static ASTUnit *LoadFromPCHFile(const std::string &Filename, Diagnostic &Diags, bool OnlyLocalDecls = false, - bool UseBumpAllocator = false); + bool UseBumpAllocator = false, + RemappedFile *RemappedFiles = 0, + unsigned NumRemappedFiles = 0); /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a /// CompilerInvocation object. @@ -158,7 +169,9 @@ public: Diagnostic &Diags, llvm::StringRef ResourceFilesPath, bool OnlyLocalDecls = false, - bool UseBumpAllocator = false); + bool UseBumpAllocator = false, + RemappedFile *RemappedFiles = 0, + unsigned NumRemappedFiles = 0); }; } // namespace clang diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 536bd41..1a9f4ce 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -30,7 +30,7 @@ namespace clang { /// designed for the previous version could not support reading /// the new version), this number should be increased. /// - /// Version 3 of PCH files also requires that the Subversion branch and + /// Version 3 of PCH files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// PCH files at this time. const unsigned VERSION_MAJOR = 3; @@ -219,9 +219,9 @@ namespace clang { /// comments were encountered in the source code. COMMENT_RANGES = 20, - /// \brief Record code for the Subversion branch and revision information - /// of the compiler used to build this PCH file. - SVN_BRANCH_REVISION = 21 + /// \brief Record code for the version control branch and revision + /// information of the compiler used to build this PCH file. + VERSION_CONTROL_BRANCH_REVISION = 21 }; /// \brief Record types used within a source manager block. @@ -676,7 +676,17 @@ namespace clang { /// \brief A CXXOperatorCallExpr record. EXPR_CXX_OPERATOR_CALL, /// \brief A CXXConstructExpr record. - EXPR_CXX_CONSTRUCT + EXPR_CXX_CONSTRUCT, + // \brief A CXXStaticCastExpr record. + EXPR_CXX_STATIC_CAST, + // \brief A CXXDynamicCastExpr record. + EXPR_CXX_DYNAMIC_CAST, + // \brief A CXXReinterpretCastExpr record. + EXPR_CXX_REINTERPRET_CAST, + // \brief A CXXConstCastExpr record. + EXPR_CXX_CONST_CAST, + // \brief A CXXFunctionalCastExpr record. + EXPR_CXX_FUNCTIONAL_CAST }; /// \brief The kinds of designators that can occur in a diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h index c43a1fe..7ba7c5c 100644 --- a/include/clang/Frontend/PreprocessorOptions.h +++ b/include/clang/Frontend/PreprocessorOptions.h @@ -16,6 +16,10 @@ #include <utility> #include <vector> +namespace llvm { + class MemoryBuffer; +} + namespace clang { class Preprocessor; @@ -48,6 +52,12 @@ public: /// pair). std::vector<std::pair<std::string, std::string> > RemappedFiles; + /// \brief The set of file-to-buffer remappings, which take existing files + /// on the system (the first part of each pair) and gives them the contents + /// of the specified memory buffer (the second part of each pair). + std::vector<std::pair<std::string, const llvm::MemoryBuffer *> > + RemappedFileBuffers; + typedef std::vector<std::pair<std::string, std::string> >::const_iterator remapped_file_iterator; remapped_file_iterator remapped_file_begin() const { @@ -57,6 +67,15 @@ public: return RemappedFiles.end(); } + typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >:: + const_iterator remapped_file_buffer_iterator; + remapped_file_buffer_iterator remapped_file_buffer_begin() const { + return RemappedFileBuffers.begin(); + } + remapped_file_buffer_iterator remapped_file_buffer_end() const { + return RemappedFileBuffers.end(); + } + public: PreprocessorOptions() : UsePredefines(true) {} @@ -69,6 +88,9 @@ public: void addRemappedFile(llvm::StringRef From, llvm::StringRef To) { RemappedFiles.push_back(std::make_pair(From, To)); } + void addRemappedFile(llvm::StringRef From, const llvm::MemoryBuffer * To) { + RemappedFileBuffers.push_back(std::make_pair(From, To)); + } }; } // end namespace clang diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index c8df494..7f43b2a 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -15,7 +15,6 @@ #define LLVM_CLANG_FRONTEND_UTILS_H #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -41,28 +40,6 @@ class Stmt; class TargetInfo; class FrontendOptions; -class MacroBuilder { - llvm::raw_ostream &Out; -public: - MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {} - - /// Append a #define line for macro of the form "#define Name Value\n". - void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") { - Out << "#define " << Name << ' ' << Value << '\n'; - } - - /// Append a #undef line for Name. Name should be of the form XXX - /// and we emit "#undef XXX". - void undefineMacro(const llvm::Twine &Name) { - Out << "#undef " << Name << '\n'; - } - - /// Directly append Str and a newline to the underlying buffer. - void append(const llvm::Twine &Str) { - Out << Str << '\n'; - } -}; - /// Normalize \arg File for use in a user defined #include directive (in the /// predefines buffer). std::string NormalizeDashIncludePath(llvm::StringRef File); diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index fc2671f..dedbbd8 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -602,7 +602,12 @@ public: /// the returned source location would not be meaningful (e.g., if /// it points into a macro), this routine returns an invalid /// source location. - SourceLocation getLocForEndOfToken(SourceLocation Loc); + /// + /// \param Offset an offset from the end of the token, where the source + /// location should refer to. The default offset (0) produces a source + /// location pointing just past the end of the token; an offset of 1 produces + /// a source location pointing to the last character in the token, etc. + SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0); /// DumpToken - Print the token to stderr, used for debugging. /// @@ -697,8 +702,7 @@ public: /// return null on failure. isAngled indicates whether the file reference is /// for system #include's or not (i.e. using <> instead of ""). const FileEntry *LookupFile(llvm::StringRef Filename, - SourceLocation FilenameTokLoc, bool isAngled, - const DirectoryLookup *FromDir, + bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir); /// GetCurLookup - The DirectoryLookup structure used to find the current @@ -884,7 +888,9 @@ public: void HandlePragmaSystemHeader(Token &SysHeaderTok); void HandlePragmaDependency(Token &DependencyTok); void HandlePragmaComment(Token &CommentTok); - void HandleComment(SourceRange Comment); + // Return true and store the first token only if any CommentHandler + // has inserted some tokens and getCommentRetentionState() is false. + bool HandleComment(Token &Token, SourceRange Comment); }; /// \brief Abstract base class that describes a handler that will receive @@ -893,7 +899,9 @@ class CommentHandler { public: virtual ~CommentHandler(); - virtual void HandleComment(Preprocessor &PP, SourceRange Comment) = 0; + // The handler shall return true if it has pushed any tokens + // to be read using e.g. EnterToken or EnterTokenStream. + virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0; }; } // end namespace clang diff --git a/include/clang/Parse/AccessSpecifier.h b/include/clang/Parse/AccessSpecifier.h deleted file mode 100644 index 8d2cee8..0000000 --- a/include/clang/Parse/AccessSpecifier.h +++ /dev/null @@ -1,30 +0,0 @@ -//===--- AccessSpecifier.h - C++ Access Specifiers -*- 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 interfaces used for C++ access specifiers. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_PARSE_ACCESS_SPECIFIER_H -#define LLVM_CLANG_PARSE_ACCESS_SPECIFIER_H - -namespace clang { - -/// AccessSpecifier - A C++ access specifier (none, public, private, -/// protected). -enum AccessSpecifier { - AS_none, - AS_public, - AS_protected, - AS_private -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 7209e0a..ff33f50 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -16,9 +16,9 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" -#include "clang/Parse/AccessSpecifier.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Ownership.h" #include "llvm/Support/PrettyStackTrace.h" @@ -2110,6 +2110,7 @@ public: SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { return DeclPtrTy(); @@ -2131,6 +2132,7 @@ public: SourceLocation ProtocolLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList) { return DeclPtrTy(); @@ -2144,6 +2146,7 @@ public: SourceLocation CategoryLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc) { return DeclPtrTy(); } @@ -2771,6 +2774,7 @@ public: SourceLocation SuperLoc, const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs, + const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); }; diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 6a3d8a9..f923b5e 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -17,6 +17,7 @@ #include "clang/Parse/AttributeList.h" #include "clang/Lex/Token.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/Specifiers.h" #include "llvm/ADT/SmallVector.h" namespace clang { @@ -78,51 +79,50 @@ public: SCS_mutable }; - // type-specifier - enum TSW { - TSW_unspecified, - TSW_short, - TSW_long, - TSW_longlong - }; - + // Import type specifier width enumeration and constants. + typedef TypeSpecifierWidth TSW; + static const TSW TSW_unspecified = clang::TSW_unspecified; + static const TSW TSW_short = clang::TSW_short; + static const TSW TSW_long = clang::TSW_long; + static const TSW TSW_longlong = clang::TSW_longlong; + enum TSC { TSC_unspecified, TSC_imaginary, TSC_complex }; - enum TSS { - TSS_unspecified, - TSS_signed, - TSS_unsigned - }; - - enum TST { - TST_unspecified, - TST_void, - TST_char, - TST_wchar, // C++ wchar_t - TST_char16, // C++0x char16_t - TST_char32, // C++0x char32_t - TST_int, - TST_float, - TST_double, - TST_bool, // _Bool - TST_decimal32, // _Decimal32 - TST_decimal64, // _Decimal64 - TST_decimal128, // _Decimal128 - TST_enum, - TST_union, - TST_struct, - TST_class, // C++ class type - TST_typename, // Typedef, C++ class-name or enum name, etc. - TST_typeofType, - TST_typeofExpr, - TST_decltype, // C++0x decltype - TST_auto, // C++0x auto - TST_error // erroneous type - }; + // Import type specifier sign enumeration and constants. + typedef TypeSpecifierSign TSS; + static const TSS TSS_unspecified = clang::TSS_unspecified; + static const TSS TSS_signed = clang::TSS_signed; + static const TSS TSS_unsigned = clang::TSS_unsigned; + + // Import type specifier type enumeration and constants. + typedef TypeSpecifierType TST; + static const TST TST_unspecified = clang::TST_unspecified; + static const TST TST_void = clang::TST_void; + static const TST TST_char = clang::TST_char; + static const TST TST_wchar = clang::TST_wchar; + static const TST TST_char16 = clang::TST_char16; + static const TST TST_char32 = clang::TST_char32; + static const TST TST_int = clang::TST_int; + static const TST TST_float = clang::TST_float; + static const TST TST_double = clang::TST_double; + static const TST TST_bool = clang::TST_bool; + static const TST TST_decimal32 = clang::TST_decimal32; + static const TST TST_decimal64 = clang::TST_decimal64; + static const TST TST_decimal128 = clang::TST_decimal128; + static const TST TST_enum = clang::TST_enum; + static const TST TST_union = clang::TST_union; + static const TST TST_struct = clang::TST_struct; + static const TST TST_class = clang::TST_class; + static const TST TST_typename = clang::TST_typename; + static const TST TST_typeofType = clang::TST_typeofType; + static const TST TST_typeofExpr = clang::TST_typeofExpr; + static const TST TST_decltype = clang::TST_decltype; + static const TST TST_auto = clang::TST_auto; + static const TST TST_error = clang::TST_error; // type-qualifiers enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. @@ -199,6 +199,9 @@ private: SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; SourceLocation FriendLoc, ConstexprLoc; + WrittenBuiltinSpecs writtenBS; + void SaveWrittenBuiltinSpecs(); + DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT void operator=(const DeclSpec&); // DO NOT IMPLEMENT public: @@ -411,6 +414,10 @@ public: /// DeclSpec is guaranteed self-consistent, even if an error occurred. void Finish(Diagnostic &D, Preprocessor &PP); + const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { + return writtenBS; + } + /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone, /// without a Declarator. Only tag declspecs can stand alone. bool isMissingDeclaratorOk(); diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 0fc9413..e7cb0a2 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -14,8 +14,8 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H +#include "clang/Basic/Specifiers.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Parse/AccessSpecifier.h" #include "clang/Parse/Action.h" #include "clang/Parse/DeclSpec.h" #include "llvm/ADT/OwningPtr.h" diff --git a/include/clang/Rewrite/DeltaTree.h b/include/clang/Rewrite/DeltaTree.h index 7e07965..f32906a 100644 --- a/include/clang/Rewrite/DeltaTree.h +++ b/include/clang/Rewrite/DeltaTree.h @@ -17,7 +17,7 @@ namespace clang { /// DeltaTree - a multiway search tree (BTree) structure with some fancy - /// features. B-Trees are are generally more memory and cache efficient than + /// features. B-Trees are generally more memory and cache efficient than /// binary trees, because they store multiple keys/values in each node. This /// implements a key/value mapping from index to delta, and allows fast lookup /// on index. However, an added (important) bonus is that it can also |