2006-11-09 14:54:47 +08:00
|
|
|
//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===//
|
2006-11-03 14:42:29 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-11-03 14:42:29 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2006-11-09 14:54:47 +08:00
|
|
|
// This file defines the Sema class, which performs semantic analysis and
|
|
|
|
// builds ASTs.
|
2006-11-03 14:42:29 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-11-09 14:54:47 +08:00
|
|
|
#ifndef LLVM_CLANG_AST_SEMA_H
|
|
|
|
#define LLVM_CLANG_AST_SEMA_H
|
2006-11-03 14:42:29 +08:00
|
|
|
|
2008-04-11 15:00:53 +08:00
|
|
|
#include "IdentifierResolver.h"
|
2008-07-01 18:37:29 +08:00
|
|
|
#include "CXXFieldCollector.h"
|
2008-10-22 00:13:35 +08:00
|
|
|
#include "SemaOverload.h"
|
2009-01-15 06:20:51 +08:00
|
|
|
#include "clang/AST/DeclBase.h"
|
2009-01-23 07:26:18 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2006-11-03 14:42:29 +08:00
|
|
|
#include "clang/Parse/Action.h"
|
2008-11-22 16:28:49 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
2007-07-22 15:07:56 +08:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2007-10-06 02:00:57 +08:00
|
|
|
#include "llvm/ADT/DenseSet.h"
|
2007-10-07 09:13:46 +08:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
2008-07-01 18:37:29 +08:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
2009-01-16 08:38:09 +08:00
|
|
|
#include <string>
|
2008-10-24 12:54:22 +08:00
|
|
|
#include <vector>
|
2006-11-03 14:42:29 +08:00
|
|
|
|
2007-08-23 13:46:52 +08:00
|
|
|
namespace llvm {
|
|
|
|
class APSInt;
|
|
|
|
}
|
|
|
|
|
2006-11-03 14:42:29 +08:00
|
|
|
namespace clang {
|
2006-11-10 14:20:45 +08:00
|
|
|
class ASTContext;
|
2008-02-06 08:46:58 +08:00
|
|
|
class ASTConsumer;
|
2006-11-03 14:42:29 +08:00
|
|
|
class Preprocessor;
|
|
|
|
class Decl;
|
2008-04-06 12:47:34 +08:00
|
|
|
class DeclContext;
|
2008-08-11 11:27:53 +08:00
|
|
|
class DeclSpec;
|
2008-04-02 07:04:06 +08:00
|
|
|
class NamedDecl;
|
2008-12-14 00:23:55 +08:00
|
|
|
class Stmt;
|
2007-04-03 06:55:05 +08:00
|
|
|
class Expr;
|
2007-09-02 23:34:30 +08:00
|
|
|
class InitListExpr;
|
2009-01-22 08:58:24 +08:00
|
|
|
class DesignatedInitExpr;
|
2007-12-28 13:29:59 +08:00
|
|
|
class CallExpr;
|
2009-01-06 13:10:23 +08:00
|
|
|
class DeclRefExpr;
|
2007-01-21 15:42:07 +08:00
|
|
|
class VarDecl;
|
2007-06-14 04:44:40 +08:00
|
|
|
class ParmVarDecl;
|
2007-01-28 03:27:06 +08:00
|
|
|
class TypedefDecl;
|
|
|
|
class FunctionDecl;
|
2007-04-06 06:36:20 +08:00
|
|
|
class QualType;
|
2007-09-04 10:45:27 +08:00
|
|
|
struct LangOptions;
|
2007-07-21 00:59:19 +08:00
|
|
|
class Token;
|
2007-05-07 08:24:15 +08:00
|
|
|
class IntegerLiteral;
|
2008-01-22 08:55:40 +08:00
|
|
|
class StringLiteral;
|
2007-05-09 05:09:37 +08:00
|
|
|
class ArrayType;
|
2007-05-28 14:28:18 +08:00
|
|
|
class LabelStmt;
|
2007-07-22 15:07:56 +08:00
|
|
|
class SwitchStmt;
|
2008-04-19 07:10:10 +08:00
|
|
|
class ExtVectorType;
|
2007-07-30 00:33:31 +08:00
|
|
|
class TypedefDecl;
|
2008-01-08 03:49:32 +08:00
|
|
|
class ObjCInterfaceDecl;
|
2008-04-02 07:04:06 +08:00
|
|
|
class ObjCCompatibleAliasDecl;
|
2008-01-08 03:49:32 +08:00
|
|
|
class ObjCProtocolDecl;
|
|
|
|
class ObjCImplementationDecl;
|
|
|
|
class ObjCCategoryImplDecl;
|
|
|
|
class ObjCCategoryDecl;
|
|
|
|
class ObjCIvarDecl;
|
|
|
|
class ObjCMethodDecl;
|
2008-05-01 08:03:38 +08:00
|
|
|
class ObjCPropertyDecl;
|
2009-01-09 01:28:14 +08:00
|
|
|
class ObjCContainerDecl;
|
2008-09-04 02:15:37 +08:00
|
|
|
struct BlockSemaInfo;
|
2008-10-24 12:54:22 +08:00
|
|
|
class BasePaths;
|
2009-01-15 08:26:24 +08:00
|
|
|
class MemberLookupCriteria;
|
2007-07-30 00:33:31 +08:00
|
|
|
|
2008-10-14 13:35:18 +08:00
|
|
|
/// PragmaPackStack - Simple class to wrap the stack used by #pragma
|
|
|
|
/// pack.
|
|
|
|
class PragmaPackStack {
|
2008-11-19 18:32:38 +08:00
|
|
|
typedef std::vector< std::pair<unsigned, IdentifierInfo*> > stack_ty;
|
2008-10-14 13:35:18 +08:00
|
|
|
|
|
|
|
/// Alignment - The current user specified alignment.
|
|
|
|
unsigned Alignment;
|
|
|
|
|
2008-11-19 18:32:38 +08:00
|
|
|
/// Stack - Entries in the #pragma pack stack, consisting of saved
|
|
|
|
/// alignments and optional names.
|
2008-10-14 13:35:18 +08:00
|
|
|
stack_ty Stack;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PragmaPackStack(unsigned A) : Alignment(A) {}
|
|
|
|
|
|
|
|
void setAlignment(unsigned A) { Alignment = A; }
|
|
|
|
unsigned getAlignment() { return Alignment; }
|
|
|
|
|
|
|
|
/// push - Push the current alignment onto the stack, optionally
|
2008-11-19 18:32:38 +08:00
|
|
|
/// using the given \arg Name for the record, if non-zero.
|
2008-10-14 13:35:18 +08:00
|
|
|
void push(IdentifierInfo *Name) {
|
2008-11-19 18:32:38 +08:00
|
|
|
Stack.push_back(std::make_pair(Alignment, Name));
|
2008-10-14 13:35:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// pop - Pop a record from the stack and restore the current
|
|
|
|
/// alignment to the previous value. If \arg Name is non-zero then
|
|
|
|
/// the first such named record is popped, otherwise the top record
|
|
|
|
/// is popped. Returns true if the pop succeeded.
|
|
|
|
bool pop(IdentifierInfo *Name);
|
|
|
|
};
|
|
|
|
|
2006-11-09 14:54:47 +08:00
|
|
|
/// Sema - This implements semantic analysis and AST building for C.
|
|
|
|
class Sema : public Action {
|
2008-06-29 08:28:59 +08:00
|
|
|
public:
|
2009-01-23 03:21:44 +08:00
|
|
|
const LangOptions &LangOpts;
|
2007-02-28 09:22:02 +08:00
|
|
|
Preprocessor &PP;
|
2006-11-10 14:20:45 +08:00
|
|
|
ASTContext &Context;
|
2008-02-06 08:46:58 +08:00
|
|
|
ASTConsumer &Consumer;
|
2008-11-22 16:28:49 +08:00
|
|
|
Diagnostic &Diags;
|
|
|
|
SourceManager &SourceMgr;
|
2008-04-04 14:12:32 +08:00
|
|
|
|
2008-06-28 14:07:14 +08:00
|
|
|
/// CurContext - This is the current declaration context of parsing.
|
2008-04-06 12:47:34 +08:00
|
|
|
DeclContext *CurContext;
|
2008-04-04 14:12:32 +08:00
|
|
|
|
2008-11-09 01:17:31 +08:00
|
|
|
/// PreDeclaratorDC - Keeps the declaration context before switching to the
|
|
|
|
/// context of a declarator's nested-name-specifier.
|
|
|
|
DeclContext *PreDeclaratorDC;
|
|
|
|
|
2008-09-04 02:15:37 +08:00
|
|
|
/// CurBlock - If inside of a block definition, this contains a pointer to
|
|
|
|
/// the active block object that represents it.
|
|
|
|
BlockSemaInfo *CurBlock;
|
|
|
|
|
2008-10-14 13:35:18 +08:00
|
|
|
/// PackContext - Manages the stack for #pragma pack. An alignment
|
|
|
|
/// of 0 indicates default alignment.
|
|
|
|
PragmaPackStack PackContext;
|
|
|
|
|
2007-05-28 14:28:18 +08:00
|
|
|
/// LabelMap - This is a mapping from label identifiers to the LabelStmt for
|
|
|
|
/// it (which acts like the label decl in some ways). Forward referenced
|
|
|
|
/// labels have a LabelStmt created for them with a null location & SubStmt.
|
2007-06-16 07:05:46 +08:00
|
|
|
llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
|
2007-07-22 15:07:56 +08:00
|
|
|
|
|
|
|
llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
|
2007-07-30 00:33:31 +08:00
|
|
|
|
2008-04-19 07:10:10 +08:00
|
|
|
/// ExtVectorDecls - This is a list all the extended vector types. This allows
|
|
|
|
/// us to associate a raw vector type with one of the ext_vector type names.
|
2007-07-30 00:33:31 +08:00
|
|
|
/// This is only necessary for issuing pretty diagnostics.
|
2008-04-19 07:10:10 +08:00
|
|
|
llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
|
2007-08-11 04:18:51 +08:00
|
|
|
|
2008-09-28 22:55:53 +08:00
|
|
|
/// ObjCImplementations - Keep track of all class @implementations
|
|
|
|
/// so we can emit errors on duplicates.
|
2008-01-08 03:49:32 +08:00
|
|
|
llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
|
2007-10-07 09:13:46 +08:00
|
|
|
|
2008-09-28 22:55:53 +08:00
|
|
|
/// ObjCCategoryImpls - Maintain a list of category implementations so
|
|
|
|
/// we can check for duplicates and find local method declarations.
|
|
|
|
llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
|
|
|
|
|
2008-01-08 03:49:32 +08:00
|
|
|
/// ObjCProtocols - Keep track of all protocol declarations declared
|
2007-10-10 02:03:53 +08:00
|
|
|
/// with @protocol keyword, so that we can emit errors on duplicates and
|
2007-10-10 02:18:24 +08:00
|
|
|
/// find the declarations when needed.
|
2008-01-08 03:49:32 +08:00
|
|
|
llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols;
|
2008-04-03 02:30:49 +08:00
|
|
|
|
|
|
|
/// ObjCInterfaceDecls - Keep track of all class declarations declared
|
|
|
|
/// with @interface, so that we can emit errors on duplicates and
|
|
|
|
/// find the declarations when needed.
|
|
|
|
typedef llvm::DenseMap<const IdentifierInfo*,
|
|
|
|
ObjCInterfaceDecl*> ObjCInterfaceDeclsTy;
|
|
|
|
ObjCInterfaceDeclsTy ObjCInterfaceDecls;
|
|
|
|
|
2008-04-02 07:04:06 +08:00
|
|
|
/// ObjCAliasDecls - Keep track of all class declarations declared
|
|
|
|
/// with @compatibility_alias, so that we can emit errors on duplicates and
|
|
|
|
/// find the declarations when needed. This construct is ancient and will
|
|
|
|
/// likely never be seen. Nevertheless, it is here for compatibility.
|
2008-04-02 08:39:51 +08:00
|
|
|
typedef llvm::DenseMap<const IdentifierInfo*,
|
|
|
|
ObjCCompatibleAliasDecl*> ObjCAliasTy;
|
2008-04-02 07:04:06 +08:00
|
|
|
ObjCAliasTy ObjCAliasDecls;
|
2008-04-03 02:30:49 +08:00
|
|
|
|
2008-07-01 18:37:29 +08:00
|
|
|
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
|
|
|
|
llvm::OwningPtr<CXXFieldCollector> FieldCollector;
|
|
|
|
|
2008-04-11 15:00:53 +08:00
|
|
|
IdentifierResolver IdResolver;
|
|
|
|
|
2007-08-11 04:18:51 +08:00
|
|
|
// Enum values used by KnownFunctionIDs (see below).
|
|
|
|
enum {
|
2008-10-03 02:44:07 +08:00
|
|
|
id_NSLog,
|
|
|
|
id_asprintf,
|
2007-08-11 04:18:51 +08:00
|
|
|
id_fprintf,
|
2008-10-03 02:44:07 +08:00
|
|
|
id_printf,
|
2007-08-11 04:18:51 +08:00
|
|
|
id_snprintf,
|
2008-10-03 02:44:07 +08:00
|
|
|
id_snprintf_chk,
|
|
|
|
id_sprintf,
|
|
|
|
id_sprintf_chk,
|
2007-08-11 04:18:51 +08:00
|
|
|
id_vasprintf,
|
2008-10-03 02:44:07 +08:00
|
|
|
id_vfprintf,
|
|
|
|
id_vsnprintf,
|
|
|
|
id_vsnprintf_chk,
|
2007-08-11 04:18:51 +08:00
|
|
|
id_vsprintf,
|
2008-10-03 02:44:07 +08:00
|
|
|
id_vsprintf_chk,
|
2007-08-11 04:18:51 +08:00
|
|
|
id_vprintf,
|
|
|
|
id_num_known_functions
|
|
|
|
};
|
|
|
|
|
|
|
|
/// KnownFunctionIDs - This is a list of IdentifierInfo objects to a set
|
|
|
|
/// of known functions used by the semantic analysis to do various
|
|
|
|
/// kinds of checking (e.g. checking format string errors in printf calls).
|
|
|
|
/// This list is populated upon the creation of a Sema object.
|
2008-08-23 10:00:52 +08:00
|
|
|
IdentifierInfo* KnownFunctionIDs[id_num_known_functions];
|
2008-08-15 06:04:54 +08:00
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
/// Translation Unit Scope - useful to Objective-C actions that need
|
|
|
|
/// to lookup file scope declarations in the "ordinary" C decl namespace.
|
|
|
|
/// For example, user-defined classes, built-in "id" type, etc.
|
2007-10-10 06:01:59 +08:00
|
|
|
Scope *TUScope;
|
2008-11-11 19:37:55 +08:00
|
|
|
|
|
|
|
/// The C++ "std" namespace, where the standard library resides. Cached here
|
|
|
|
/// by GetStdNamespace
|
|
|
|
NamespaceDecl *StdNamespace;
|
2008-12-04 04:26:15 +08:00
|
|
|
|
|
|
|
/// A flag to remember whether the implicit forms of operator new and delete
|
|
|
|
/// have been declared.
|
|
|
|
bool GlobalNewDeleteDeclared;
|
2007-10-11 05:53:07 +08:00
|
|
|
|
2007-10-14 08:58:41 +08:00
|
|
|
/// ObjCMethodList - a linked list of methods with different signatures.
|
2008-01-08 03:49:32 +08:00
|
|
|
struct ObjCMethodList {
|
|
|
|
ObjCMethodDecl *Method;
|
|
|
|
ObjCMethodList *Next;
|
2007-10-14 08:58:41 +08:00
|
|
|
|
2008-01-08 03:49:32 +08:00
|
|
|
ObjCMethodList() {
|
2007-10-14 08:58:41 +08:00
|
|
|
Method = 0;
|
|
|
|
Next = 0;
|
|
|
|
}
|
2008-01-08 03:49:32 +08:00
|
|
|
ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
|
2007-10-14 08:58:41 +08:00
|
|
|
Method = M;
|
|
|
|
Next = C;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/// Instance/Factory Method Pools - allows efficient lookup when typechecking
|
|
|
|
/// messages to "id". We need to maintain a list, since selectors can have
|
|
|
|
/// differing signatures across classes. In Cocoa, this happens to be
|
|
|
|
/// extremely uncommon (only 1% of selectors are "overloaded").
|
2008-01-08 03:49:32 +08:00
|
|
|
llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool;
|
|
|
|
llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;
|
2006-11-03 14:42:29 +08:00
|
|
|
public:
|
2008-02-06 08:46:58 +08:00
|
|
|
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
|
2006-11-03 14:42:29 +08:00
|
|
|
|
2009-01-23 03:21:44 +08:00
|
|
|
const LangOptions &getLangOptions() const { return LangOpts; }
|
2008-11-22 16:28:49 +08:00
|
|
|
Diagnostic &getDiagnostics() const { return Diags; }
|
|
|
|
SourceManager &getSourceManager() const { return SourceMgr; }
|
|
|
|
|
2008-11-19 05:53:24 +08:00
|
|
|
/// The primitive diagnostic helpers.
|
2008-11-22 16:28:49 +08:00
|
|
|
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
|
|
|
|
return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
|
|
|
|
}
|
2007-05-19 06:53:50 +08:00
|
|
|
|
2007-08-31 12:53:24 +08:00
|
|
|
virtual void DeleteExpr(ExprTy *E);
|
|
|
|
virtual void DeleteStmt(StmtTy *S);
|
|
|
|
|
2008-12-14 00:23:55 +08:00
|
|
|
OwningExprResult Owned(Expr* E) { return OwningExprResult(*this, E); }
|
2009-01-19 08:08:26 +08:00
|
|
|
OwningExprResult Owned(ExprResult R) {
|
2009-01-22 06:32:33 +08:00
|
|
|
if (R.isInvalid)
|
|
|
|
return ExprError();
|
|
|
|
return OwningExprResult(*this, R.Val);
|
2009-01-19 08:08:26 +08:00
|
|
|
}
|
2008-12-14 00:23:55 +08:00
|
|
|
OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); }
|
|
|
|
|
2008-08-23 11:19:52 +08:00
|
|
|
virtual void ActOnEndOfTranslationUnit();
|
2009-01-20 06:31:54 +08:00
|
|
|
|
2006-11-12 06:59:23 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Type Analysis / Processing: SemaType.cpp.
|
|
|
|
//
|
2008-06-26 14:27:57 +08:00
|
|
|
QualType ConvertDeclSpecToType(const DeclSpec &DS);
|
2008-06-29 08:50:08 +08:00
|
|
|
void ProcessTypeAttributeList(QualType &Result, const AttributeList *AL);
|
2008-12-02 22:43:59 +08:00
|
|
|
QualType GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip = 0);
|
2008-11-18 06:58:34 +08:00
|
|
|
DeclarationName GetNameForDeclarator(Declarator &D);
|
|
|
|
|
2008-01-08 03:49:32 +08:00
|
|
|
QualType ObjCGetTypeForMethodDefinition(DeclTy *D);
|
2007-11-09 07:49:49 +08:00
|
|
|
|
2008-10-22 22:17:15 +08:00
|
|
|
bool UnwrapSimilarPointerTypes(QualType& T1, QualType& T2);
|
|
|
|
|
2008-12-02 22:43:59 +08:00
|
|
|
virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
|
2008-11-08 21:00:26 +08:00
|
|
|
|
2009-01-20 03:26:10 +08:00
|
|
|
bool DiagnoseIncompleteType(SourceLocation Loc, QualType T, unsigned diag,
|
|
|
|
SourceRange Range1 = SourceRange(),
|
|
|
|
SourceRange Range2 = SourceRange(),
|
|
|
|
QualType PrintType = QualType());
|
|
|
|
|
2006-11-03 14:42:29 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
2006-11-10 13:29:30 +08:00
|
|
|
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
|
2006-11-03 14:42:29 +08:00
|
|
|
//
|
2008-11-18 04:34:05 +08:00
|
|
|
virtual TypeTy *isTypeName(IdentifierInfo &II, Scope *S,
|
2008-11-09 00:45:02 +08:00
|
|
|
const CXXScopeSpec *SS);
|
2008-12-16 07:53:10 +08:00
|
|
|
virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) {
|
|
|
|
return ActOnDeclarator(S, D, LastInGroup, false);
|
|
|
|
}
|
|
|
|
DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup,
|
|
|
|
bool IsFunctionDefinition);
|
2009-01-20 09:17:11 +08:00
|
|
|
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|
|
|
QualType R, Decl* LastDeclarator,
|
|
|
|
Decl* PrevDecl, bool& InvalidDecl);
|
|
|
|
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|
|
|
QualType R, Decl* LastDeclarator,
|
2009-01-16 10:36:34 +08:00
|
|
|
Decl* PrevDecl, bool& InvalidDecl);
|
2009-01-20 09:17:11 +08:00
|
|
|
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|
|
|
QualType R, Decl *LastDeclarator,
|
|
|
|
Decl* PrevDecl, bool IsFunctionDefinition,
|
|
|
|
bool& InvalidDecl);
|
2008-04-08 12:40:51 +08:00
|
|
|
virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D);
|
|
|
|
virtual void ActOnParamDefaultArgument(DeclTy *param,
|
|
|
|
SourceLocation EqualLoc,
|
|
|
|
ExprTy *defarg);
|
2008-12-24 08:01:03 +08:00
|
|
|
virtual void ActOnParamUnparsedDefaultArgument(DeclTy *param,
|
|
|
|
SourceLocation EqualLoc);
|
2008-12-17 05:30:33 +08:00
|
|
|
virtual void ActOnParamDefaultArgumentError(DeclTy *param);
|
2009-01-14 23:45:31 +08:00
|
|
|
virtual void AddInitializerToDecl(DeclTy *dcl, ExprArg init);
|
|
|
|
void AddInitializerToDecl(DeclTy *dcl, ExprArg init, bool DirectInit);
|
2008-10-29 08:13:59 +08:00
|
|
|
void ActOnUninitializedDecl(DeclTy *dcl);
|
2007-06-09 08:53:06 +08:00
|
|
|
virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
|
|
|
|
|
2009-01-24 00:23:13 +08:00
|
|
|
virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);
|
2007-10-10 01:14:05 +08:00
|
|
|
virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
|
2008-07-01 18:37:29 +08:00
|
|
|
virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, DeclTy *D);
|
2008-01-08 03:49:32 +08:00
|
|
|
virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
|
2009-01-20 06:31:54 +08:00
|
|
|
|
2008-12-14 00:23:55 +08:00
|
|
|
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body);
|
|
|
|
virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
|
2008-02-08 08:33:21 +08:00
|
|
|
|
2007-10-10 06:01:59 +08:00
|
|
|
/// Scope actions.
|
|
|
|
virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
|
|
|
|
virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
|
2007-01-28 03:27:06 +08:00
|
|
|
|
2006-11-19 10:43:37 +08:00
|
|
|
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
|
|
|
|
/// no declarator (e.g. "struct foo;") is parsed.
|
2008-12-28 23:28:59 +08:00
|
|
|
virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
|
2006-11-19 10:43:37 +08:00
|
|
|
|
2009-01-07 08:43:41 +08:00
|
|
|
bool InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
|
|
|
|
RecordDecl *AnonRecord);
|
|
|
|
virtual DeclTy *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
|
|
|
RecordDecl *Record);
|
|
|
|
|
2009-01-17 08:42:38 +08:00
|
|
|
virtual DeclTy *ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
|
2008-11-09 00:45:02 +08:00
|
|
|
SourceLocation KWLoc, const CXXScopeSpec &SS,
|
|
|
|
IdentifierInfo *Name, SourceLocation NameLoc,
|
2008-12-24 10:52:09 +08:00
|
|
|
AttributeList *Attr,
|
|
|
|
MultiTemplateParamsArg TemplateParameterLists);
|
Change struct forward declarations and definitions to use unique RecordDecls, as opposed to creating a single RecordDecl and reusing it.
This change effects both RecordDecls and CXXRecordDecls, but does not effect EnumDecls (yet).
The motivation of this patch is as follows:
- Capture more source information, necessary for refactoring/rewriting clients.
- Pave the way to resolve ownership issues with RecordDecls with the forthcoming
addition of DeclGroups.
Current caveats:
- Until DeclGroups are in place, we will leak RecordDecls not explicitly
referenced by the AST. For example:
typedef struct { ... } x;
The RecordDecl for the struct will be leaked because the TypedefDecl doesn't
refer to it. This will be solved with DeclGroups.
- This patch also (temporarily) breaks CodeGen. More below.
High-level changes:
- As before, TagType still refers to a TagDecl, but it doesn't own it. When
a struct/union/class is first referenced, a RecordType and RecordDecl are
created for it, and the RecordType refers to that RecordDecl. Later, if
a new RecordDecl is created, the pointer to a RecordDecl in RecordType is
updated to point to the RecordDecl that defines the struct/union/class.
- TagDecl and RecordDecl now how a method 'getDefinition()' to return the
TagDecl*/RecordDecl* that refers to the TagDecl* that defines a particular
enum/struct/class/union. This is useful from going from a RecordDecl* that
defines a forward declaration to the RecordDecl* that provides the actual
definition. Note that this also works for EnumDecls, except that in this case
there is no distinction between forward declarations and definitions (yet).
- Clients should no longer assume that 'isDefinition()' returns true from a
RecordDecl if the corresponding struct/union/class has been defined.
isDefinition() only returns true if a particular RecordDecl is the defining
Decl. Use 'getDefinition()' instead to determine if a struct has been defined.
- The main changes to Sema happen in ActOnTag. To make the changes more
incremental, I split off the processing of enums and structs et al into two
code paths. Enums use the original code path (which is in ActOnTag) and
structs use the ActOnTagStruct. Eventually the two code paths will be merged,
but the idea was to preserve the original logic both for comparison and not to
change the logic for both enums and structs all at once.
- There is NO CHAINING of RecordDecls for the same RecordType. All RecordDecls
that correspond to the same type simply have a pointer to that type. If we
need to figure out what are all the RecordDecls for a given type we can build
a backmap.
- The diff in CXXRecordDecl.[cpp,h] is actually very small; it just mimics the
changes to RecordDecl. For some reason 'svn' marks the entire file as changed.
Why is CodeGen broken:
- Codegen assumes that there is an equivalence between RecordDecl* and
RecordType*. This was true before because we only created one RecordDecl* for
a given RecordType*, but it is no longer true. I believe this shouldn't be too
hard to change, but the patch was big enough as it is.
I have tested this patch on both the clang test suite, and by running the static analyzer over Postgresql and a large Apple-internal project (mix of Objective-C and C).
llvm-svn: 55839
2008-09-06 01:16:31 +08:00
|
|
|
|
2008-12-12 00:49:14 +08:00
|
|
|
virtual void ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
|
2008-08-23 10:00:52 +08:00
|
|
|
IdentifierInfo *ClassName,
|
|
|
|
llvm::SmallVectorImpl<DeclTy*> &Decls);
|
2008-12-12 00:49:14 +08:00
|
|
|
virtual DeclTy *ActOnField(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
|
2007-01-24 07:42:53 +08:00
|
|
|
Declarator &D, ExprTy *BitfieldWidth);
|
2008-04-11 07:32:45 +08:00
|
|
|
|
|
|
|
virtual DeclTy *ActOnIvar(Scope *S, SourceLocation DeclStart,
|
|
|
|
Declarator &D, ExprTy *BitfieldWidth,
|
2008-04-12 00:55:42 +08:00
|
|
|
tok::ObjCKeywordKind visibility);
|
2008-04-11 07:32:45 +08:00
|
|
|
|
2007-09-15 07:09:53 +08:00
|
|
|
// This is used for both record definitions and ObjC interface declarations.
|
2007-09-29 08:54:24 +08:00
|
|
|
virtual void ActOnFields(Scope* S,
|
2007-10-30 05:38:07 +08:00
|
|
|
SourceLocation RecLoc, DeclTy *TagDecl,
|
|
|
|
DeclTy **Fields, unsigned NumFields,
|
2008-10-03 10:03:53 +08:00
|
|
|
SourceLocation LBrac, SourceLocation RBrac,
|
|
|
|
AttributeList *AttrList);
|
Unify the code for defining tags in C and C++, so that we always
introduce a Scope for the body of a tag. This reduces the number of
semantic differences between C and C++ structs and unions, and will
help with other features (e.g., anonymous unions) in C. Some important
points:
- Fields are now in the "member" namespace (IDNS_Member), to keep
them separate from tags and ordinary names in C. See the new test
in Sema/member-reference.c for an example of why this matters. In
C++, ordinary and member name lookup will find members in both the
ordinary and member namespace, so the difference between
IDNS_Member and IDNS_Ordinary is erased by Sema::LookupDecl (but
only in C++!).
- We always introduce a Scope and push a DeclContext when we're
defining a tag, in both C and C++. Previously, we had different
actions and different Scope/CurContext behavior for enums, C
structs/unions, and C++ structs/unions/classes. Now, it's one pair
of actions. (Yay!)
There's still some fuzziness in the handling of struct/union/enum
definitions within other struct/union/enum definitions in C. We'll
need to do some more cleanup to eliminate some reliance on CurContext
before we can solve this issue for real. What we want is for something
like this:
struct X {
struct T { int x; } t;
};
to introduce T into translation unit scope (placing it at the
appropriate point in the IdentifierResolver chain, too), but it should
still have struct X as its lexical declaration
context. PushOnScopeChains isn't smart enough to do that yet, though,
so there's a FIXME test in nested-redef.c
llvm-svn: 61940
2009-01-09 04:45:30 +08:00
|
|
|
|
|
|
|
/// ActOnTagStartDefinition - Invoked when we have entered the
|
|
|
|
/// scope of a tag's definition (e.g., for an enumeration, class,
|
|
|
|
/// struct, or union).
|
|
|
|
virtual void ActOnTagStartDefinition(Scope *S, DeclTy *TagDecl);
|
|
|
|
|
|
|
|
/// ActOnTagFinishDefinition - Invoked once we have finished parsing
|
|
|
|
/// the definition of a tag (enumeration, class, struct, or union).
|
|
|
|
virtual void ActOnTagFinishDefinition(Scope *S, DeclTy *TagDecl);
|
|
|
|
|
2007-09-16 02:49:24 +08:00
|
|
|
virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
|
2007-06-11 09:28:17 +08:00
|
|
|
DeclTy *LastEnumConstant,
|
2007-01-25 15:29:02 +08:00
|
|
|
SourceLocation IdLoc, IdentifierInfo *Id,
|
|
|
|
SourceLocation EqualLoc, ExprTy *Val);
|
2007-09-16 02:49:24 +08:00
|
|
|
virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
|
2007-01-25 15:29:02 +08:00
|
|
|
DeclTy **Elements, unsigned NumElements);
|
2008-11-08 21:00:26 +08:00
|
|
|
|
2008-11-09 01:17:31 +08:00
|
|
|
DeclContext *getContainingDC(DeclContext *DC);
|
2008-07-01 18:37:29 +08:00
|
|
|
|
2008-04-04 14:12:32 +08:00
|
|
|
/// Set the current declaration context until it gets popped.
|
2008-12-12 00:49:14 +08:00
|
|
|
void PushDeclContext(Scope *S, DeclContext *DC);
|
2008-04-06 12:47:34 +08:00
|
|
|
void PopDeclContext();
|
2008-06-28 14:07:14 +08:00
|
|
|
|
2008-12-05 07:50:19 +08:00
|
|
|
/// getCurFunctionDecl - If inside of a function body, this returns a pointer
|
|
|
|
/// to the function decl for the function being parsed. If we're currently
|
|
|
|
/// in a 'block', this returns the containing context.
|
|
|
|
FunctionDecl *getCurFunctionDecl();
|
|
|
|
|
|
|
|
/// getCurMethodDecl - If inside of a method body, this returns a pointer to
|
|
|
|
/// the method decl for the method being parsed. If we're currently
|
|
|
|
/// in a 'block', this returns the containing context.
|
2008-08-11 13:35:13 +08:00
|
|
|
ObjCMethodDecl *getCurMethodDecl();
|
2008-04-04 14:12:32 +08:00
|
|
|
|
2008-12-05 07:50:19 +08:00
|
|
|
/// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
|
|
|
|
/// or C function we're in, otherwise return null. If we're currently
|
|
|
|
/// in a 'block', this returns the containing context.
|
|
|
|
NamedDecl *getCurFunctionOrMethodDecl();
|
|
|
|
|
2008-04-12 08:47:19 +08:00
|
|
|
/// Add this decl to the scope shadowed decl chains.
|
|
|
|
void PushOnScopeChains(NamedDecl *D, Scope *S);
|
|
|
|
|
2008-09-10 05:18:04 +08:00
|
|
|
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
|
|
|
|
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
|
|
|
|
/// true if 'D' belongs to the given declaration context.
|
|
|
|
bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0) {
|
2008-12-12 00:49:14 +08:00
|
|
|
return IdResolver.isDeclInScope(D, Ctx, Context, S);
|
2008-09-10 05:18:04 +08:00
|
|
|
}
|
|
|
|
|
2008-02-21 09:07:18 +08:00
|
|
|
/// Subroutines of ActOnDeclarator().
|
2007-11-14 14:34:38 +08:00
|
|
|
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
|
2009-01-20 09:17:11 +08:00
|
|
|
Decl *LastDecl);
|
2008-04-02 07:04:06 +08:00
|
|
|
TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
2008-04-21 10:02:58 +08:00
|
|
|
FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old,
|
|
|
|
bool &Redeclaration);
|
2008-04-02 07:04:06 +08:00
|
|
|
VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
|
2008-04-08 12:40:51 +08:00
|
|
|
FunctionDecl *MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
|
2008-08-09 01:50:35 +08:00
|
|
|
void CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD);
|
2008-10-22 00:13:35 +08:00
|
|
|
|
|
|
|
/// C++ Overloading.
|
|
|
|
bool IsOverload(FunctionDecl *New, Decl* OldD,
|
|
|
|
OverloadedFunctionDecl::function_iterator &MatchedDecl);
|
2008-11-04 03:09:14 +08:00
|
|
|
ImplicitConversionSequence
|
|
|
|
TryImplicitConversion(Expr* From, QualType ToType,
|
2009-01-14 23:45:31 +08:00
|
|
|
bool SuppressUserConversions = false,
|
|
|
|
bool AllowExplicit = false);
|
2008-11-01 00:23:19 +08:00
|
|
|
bool IsStandardConversion(Expr *From, QualType ToType,
|
|
|
|
StandardConversionSequence& SCS);
|
2008-10-22 00:13:35 +08:00
|
|
|
bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
|
|
|
|
bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
|
|
|
|
bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
2008-12-20 01:40:08 +08:00
|
|
|
QualType& ConvertedType, bool &IncompatibleObjC);
|
2008-12-20 03:13:09 +08:00
|
|
|
bool isObjCPointerConversion(QualType FromType, QualType ToType,
|
|
|
|
QualType& ConvertedType, bool &IncompatibleObjC);
|
2008-10-24 12:54:22 +08:00
|
|
|
bool CheckPointerConversion(Expr *From, QualType ToType);
|
2008-10-22 07:43:52 +08:00
|
|
|
bool IsQualificationConversion(QualType FromType, QualType ToType);
|
2008-11-01 00:23:19 +08:00
|
|
|
bool IsUserDefinedConversion(Expr *From, QualType ToType,
|
2009-01-14 23:45:31 +08:00
|
|
|
UserDefinedConversionSequence& User,
|
|
|
|
bool AllowExplicit = false);
|
2008-10-22 00:13:35 +08:00
|
|
|
|
|
|
|
ImplicitConversionSequence::CompareKind
|
|
|
|
CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
|
|
|
|
const ImplicitConversionSequence& ICS2);
|
|
|
|
|
|
|
|
ImplicitConversionSequence::CompareKind
|
|
|
|
CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
|
|
|
const StandardConversionSequence& SCS2);
|
|
|
|
|
2008-10-22 22:17:15 +08:00
|
|
|
ImplicitConversionSequence::CompareKind
|
|
|
|
CompareQualificationConversions(const StandardConversionSequence& SCS1,
|
|
|
|
const StandardConversionSequence& SCS2);
|
|
|
|
|
2008-10-23 08:40:37 +08:00
|
|
|
ImplicitConversionSequence::CompareKind
|
|
|
|
CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
|
|
|
|
const StandardConversionSequence& SCS2);
|
|
|
|
|
2008-11-04 03:09:14 +08:00
|
|
|
ImplicitConversionSequence
|
|
|
|
TryCopyInitialization(Expr* From, QualType ToType,
|
|
|
|
bool SuppressUserConversions = false);
|
2008-10-29 08:13:59 +08:00
|
|
|
bool PerformCopyInitialization(Expr *&From, QualType ToType,
|
|
|
|
const char *Flavor);
|
|
|
|
|
2008-11-19 07:14:02 +08:00
|
|
|
ImplicitConversionSequence
|
|
|
|
TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method);
|
|
|
|
bool PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method);
|
|
|
|
|
2009-01-14 23:45:31 +08:00
|
|
|
ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
|
|
|
|
bool PerformContextuallyConvertToBool(Expr *&From);
|
|
|
|
|
2008-10-22 00:13:35 +08:00
|
|
|
/// OverloadingResult - Capture the result of performing overload
|
|
|
|
/// resolution.
|
|
|
|
enum OverloadingResult {
|
|
|
|
OR_Success, ///< Overload resolution succeeded.
|
|
|
|
OR_No_Viable_Function, ///< No viable function found.
|
|
|
|
OR_Ambiguous ///< Ambiguous candidates found.
|
|
|
|
};
|
|
|
|
|
|
|
|
void AddOverloadCandidate(FunctionDecl *Function,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
2008-11-04 03:09:14 +08:00
|
|
|
OverloadCandidateSet& CandidateSet,
|
|
|
|
bool SuppressUserConversions = false);
|
2008-11-19 07:14:02 +08:00
|
|
|
void AddMethodCandidate(CXXMethodDecl *Method,
|
|
|
|
Expr *Object, Expr **Args, unsigned NumArgs,
|
|
|
|
OverloadCandidateSet& CandidateSet,
|
2008-12-22 13:46:06 +08:00
|
|
|
bool SuppressUserConversions = false);
|
2008-11-08 06:36:19 +08:00
|
|
|
void AddConversionCandidate(CXXConversionDecl *Conversion,
|
|
|
|
Expr *From, QualType ToType,
|
|
|
|
OverloadCandidateSet& CandidateSet);
|
2008-11-20 06:57:39 +08:00
|
|
|
void AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
|
|
|
const FunctionTypeProto *Proto,
|
|
|
|
Expr *Object, Expr **Args, unsigned NumArgs,
|
|
|
|
OverloadCandidateSet& CandidateSet);
|
2008-11-19 07:14:02 +08:00
|
|
|
void AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
OverloadCandidateSet& CandidateSet);
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
llvm-svn: 59148
2008-11-13 01:17:38 +08:00
|
|
|
void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
2009-01-13 08:52:54 +08:00
|
|
|
OverloadCandidateSet& CandidateSet,
|
2009-01-14 23:45:31 +08:00
|
|
|
bool IsAssignmentOperator = false,
|
|
|
|
unsigned NumContextualBoolArguments = 0);
|
2008-11-19 23:42:04 +08:00
|
|
|
void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
OverloadCandidateSet& CandidateSet);
|
2008-11-04 04:45:27 +08:00
|
|
|
void AddOverloadCandidates(const OverloadedFunctionDecl *Ovl,
|
2008-10-22 00:13:35 +08:00
|
|
|
Expr **Args, unsigned NumArgs,
|
2008-11-04 03:09:14 +08:00
|
|
|
OverloadCandidateSet& CandidateSet,
|
|
|
|
bool SuppressUserConversions = false);
|
2008-10-22 00:13:35 +08:00
|
|
|
bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
|
|
|
|
const OverloadCandidate& Cand2);
|
|
|
|
OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
|
|
|
|
OverloadCandidateSet::iterator& Best);
|
|
|
|
void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
|
|
|
bool OnlyViable);
|
|
|
|
|
2008-11-11 04:40:00 +08:00
|
|
|
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|
|
|
bool Complain);
|
|
|
|
void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
|
|
|
|
|
2008-11-26 14:01:48 +08:00
|
|
|
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, OverloadedFunctionDecl *Ovl,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
2008-12-22 13:46:06 +08:00
|
|
|
ExprResult
|
|
|
|
BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
|
|
|
|
SourceLocation LParenLoc, Expr **Args,
|
|
|
|
unsigned NumArgs, SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
2008-11-20 05:05:33 +08:00
|
|
|
ExprResult
|
2008-12-06 08:22:45 +08:00
|
|
|
BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
|
2008-11-20 05:05:33 +08:00
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
2008-10-22 00:13:35 +08:00
|
|
|
|
2008-12-23 08:26:44 +08:00
|
|
|
ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
|
2008-11-21 00:27:02 +08:00
|
|
|
SourceLocation MemberLoc,
|
|
|
|
IdentifierInfo &Member);
|
2009-01-14 23:45:31 +08:00
|
|
|
|
2009-01-06 15:27:21 +08:00
|
|
|
/// Helpers for dealing with function parameters.
|
2008-04-08 12:40:51 +08:00
|
|
|
bool CheckParmsForFunctionDef(FunctionDecl *FD);
|
|
|
|
void CheckCXXDefaultArguments(FunctionDecl *FD);
|
2008-05-07 12:49:29 +08:00
|
|
|
void CheckExtraCXXDefaultArguments(Declarator &D);
|
2007-03-16 08:33:25 +08:00
|
|
|
|
2008-12-30 11:27:21 +08:00
|
|
|
// FIXME: NamespaceNameOnly parameter is added temporarily
|
|
|
|
// we will need a better way to specify lookup criteria for things
|
2009-01-06 15:27:21 +08:00
|
|
|
// like template specializations, explicit template instantiations, etc.
|
2008-12-30 11:27:21 +08:00
|
|
|
|
2009-01-13 02:45:55 +08:00
|
|
|
Scope *getNonFieldDeclScope(Scope *S);
|
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// \name Name lookup
|
|
|
|
///
|
|
|
|
/// These routines provide name lookup that is used during semantic
|
|
|
|
/// analysis to resolve the various kinds of names (identifiers,
|
|
|
|
/// overloaded operator names, constructor names, etc.) into zero or
|
|
|
|
/// more declarations within a particular scope. The major entry
|
|
|
|
/// points are LookupName, which performs unqualified name lookup,
|
|
|
|
/// and LookupQualifiedName, which performs qualified name lookup.
|
|
|
|
///
|
|
|
|
/// All name lookup is performed based on some specific criteria,
|
|
|
|
/// which specify what names will be visible to name lookup and how
|
|
|
|
/// far name lookup should work. These criteria are important both
|
|
|
|
/// for capturing language semantics (certain lookups will ignore
|
|
|
|
/// certain names, for example) and for performance, since name
|
|
|
|
/// lookup is often a bottleneck in the compilation of C++. Name
|
|
|
|
/// lookup criteria is specified via the LookupCriteria class.
|
|
|
|
///
|
|
|
|
/// The results of name lookup can vary based on the kind of name
|
|
|
|
/// lookup performed, the current language, and the translation
|
|
|
|
/// unit. In C, for example, name lookup will either return nothing
|
|
|
|
/// (no entity found) or a single declaration. In C++, name lookup
|
|
|
|
/// can additionally refer to a set of overloaded functions or
|
|
|
|
/// result in an ambiguity. All of the possible results of name
|
|
|
|
/// lookup are captured by the LookupResult class, which provides
|
|
|
|
/// the ability to distinguish among them.
|
|
|
|
//@{
|
|
|
|
|
|
|
|
/// @brief Describes the criteria by which name lookup will
|
|
|
|
/// determine whether a given name will be found.
|
|
|
|
///
|
|
|
|
/// The LookupCriteria class captures the information required to
|
|
|
|
/// direct name lookup to find the appropriate kind of name. It
|
|
|
|
/// includes information about which kinds of names to consider
|
|
|
|
/// (ordinary names, tag names, class/struct/union member names,
|
|
|
|
/// namespace names, etc.) and where to look for those
|
|
|
|
/// names. LookupCriteria is used throughout semantic analysis to
|
|
|
|
/// specify how to search for a name, e.g., with the LookupName and
|
|
|
|
/// LookupQualifiedName functions.
|
|
|
|
struct LookupCriteria {
|
|
|
|
/// NameKind - The kinds of names that we are looking for.
|
|
|
|
enum NameKind {
|
|
|
|
/// Ordinary - Ordinary name lookup, which finds ordinary names
|
|
|
|
/// (functions, variables, typedefs, etc.) in C and most kinds
|
|
|
|
/// of names (functions, variables, members, types, etc.) in
|
|
|
|
/// C++.
|
|
|
|
Ordinary,
|
|
|
|
/// Tag - Tag name lookup, which finds the names of enums,
|
|
|
|
/// classes, structs, and unions.
|
|
|
|
Tag,
|
|
|
|
/// Member - Member name lookup, which finds the names of
|
|
|
|
/// class/struct/union members.
|
|
|
|
Member,
|
|
|
|
/// NestedNameSpecifier - Look up of a name that precedes the
|
|
|
|
/// '::' scope resolution operator in C++. This lookup
|
|
|
|
/// completely ignores operator, function, and enumerator names
|
|
|
|
/// (C++ [basic.lookup.qual]p1).
|
|
|
|
NestedNameSpecifier,
|
|
|
|
/// Namespace - Look up a namespace name within a C++
|
|
|
|
/// using directive or namespace alias definition, ignoring
|
|
|
|
/// non-namespace names (C++ [basic.lookup.udir]p1).
|
|
|
|
Namespace
|
|
|
|
} Kind;
|
|
|
|
|
|
|
|
/// AllowLazyBuiltinCreation - If true, permits name lookup to
|
|
|
|
/// lazily build declarations for built-in names, e.g.,
|
|
|
|
/// __builtin_expect.
|
|
|
|
bool AllowLazyBuiltinCreation;
|
|
|
|
|
|
|
|
/// RedeclarationOnly - If true, the lookup will only
|
|
|
|
/// consider entities within the scope where the lookup
|
|
|
|
/// began. Entities that might otherwise meet the lookup criteria
|
|
|
|
/// but are not within the original lookup scope will be ignored.
|
|
|
|
bool RedeclarationOnly;
|
|
|
|
|
|
|
|
/// IDNS - Bitwise OR of the appropriate Decl::IDNS_* flags that
|
|
|
|
/// describe the namespaces where we should look for names. This
|
|
|
|
/// field is determined by the kind of name we're searching for.
|
|
|
|
unsigned IDNS;
|
|
|
|
|
2009-01-15 08:26:24 +08:00
|
|
|
LookupCriteria()
|
|
|
|
: Kind(Ordinary), AllowLazyBuiltinCreation(true),
|
|
|
|
RedeclarationOnly(false), IDNS(Decl::IDNS_Ordinary) { }
|
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
LookupCriteria(NameKind K, bool RedeclarationOnly, bool CPlusPlus);
|
|
|
|
|
|
|
|
bool isLookupResult(Decl *D) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// @brief Represents the results of name lookup.
|
|
|
|
///
|
|
|
|
/// An instance of the LookupResult class captures the results of a
|
|
|
|
/// single name lookup, which can return no result (nothing found),
|
|
|
|
/// a single declaration, a set of overloaded functions, or an
|
|
|
|
/// ambiguity. Use the getKind() method to determine which of these
|
|
|
|
/// results occurred for a given lookup.
|
|
|
|
///
|
|
|
|
/// Any non-ambiguous lookup can be converted into a single
|
|
|
|
/// (possibly NULL) @c Decl* via a conversion function or the
|
|
|
|
/// getAsDecl() method. This conversion permits the common-case
|
|
|
|
/// usage in C and Objective-C where name lookup will always return
|
|
|
|
/// a single declaration.
|
2009-01-17 09:13:24 +08:00
|
|
|
struct LookupResult {
|
2009-01-15 06:20:51 +08:00
|
|
|
/// The kind of entity that is actually stored within the
|
|
|
|
/// LookupResult object.
|
2009-01-17 09:13:24 +08:00
|
|
|
enum {
|
2009-01-15 06:20:51 +08:00
|
|
|
/// First is a single declaration (a Decl*), which may be NULL.
|
|
|
|
SingleDecl,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// [First, Last) is an iterator range represented as opaque
|
|
|
|
/// pointers used to reconstruct IdentifierResolver::iterators.
|
|
|
|
OverloadedDeclFromIdResolver,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// [First, Last) is an iterator range represented as opaque
|
|
|
|
/// pointers used to reconstruct DeclContext::lookup_iterators.
|
|
|
|
OverloadedDeclFromDeclContext,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
|
|
|
/// First is a pointer to a BasePaths structure, which is owned
|
|
|
|
/// by the LookupResult. Last is non-zero to indicate that the
|
|
|
|
/// ambiguity is caused by two names found in base class
|
|
|
|
/// subobjects of different types.
|
2009-01-17 09:13:24 +08:00
|
|
|
AmbiguousLookup
|
2009-01-15 06:20:51 +08:00
|
|
|
} StoredKind;
|
|
|
|
|
|
|
|
/// The first lookup result, whose contents depend on the kind of
|
|
|
|
/// lookup result. This may be a Decl* (if StoredKind ==
|
|
|
|
/// SingleDecl), the opaque pointer from an
|
|
|
|
/// IdentifierResolver::iterator (if StoredKind ==
|
2009-01-15 08:26:24 +08:00
|
|
|
/// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
|
|
|
|
/// (if StoredKind == OverloadedDeclFromDeclContext), or a
|
|
|
|
/// BasePaths pointer (if StoredKind == AmbiguousLookup).
|
2009-01-15 06:20:51 +08:00
|
|
|
mutable uintptr_t First;
|
|
|
|
|
|
|
|
/// The last lookup result, whose contents depend on the kind of
|
|
|
|
/// lookup result. This may be unused (if StoredKind ==
|
2009-01-15 08:26:24 +08:00
|
|
|
/// SingleDecl), it may have the same type as First (for
|
|
|
|
/// overloaded function declarations), or is may be used as a
|
|
|
|
/// Boolean value (if StoredKind == AmbiguousLookup).
|
2009-01-15 06:20:51 +08:00
|
|
|
mutable uintptr_t Last;
|
|
|
|
|
|
|
|
/// Context - The context in which we will build any
|
|
|
|
/// OverloadedFunctionDecl nodes needed by the conversion to
|
|
|
|
/// Decl*.
|
|
|
|
ASTContext *Context;
|
|
|
|
|
|
|
|
/// @brief The kind of entity found by name lookup.
|
|
|
|
enum LookupKind {
|
|
|
|
/// @brief No entity found met the criteria.
|
|
|
|
NotFound = 0,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// @brief Name lookup found a single declaration that met the
|
2009-01-15 08:26:24 +08:00
|
|
|
/// criteria. getAsDecl will return this declaration.
|
2009-01-15 06:20:51 +08:00
|
|
|
Found,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// @brief Name lookup found a set of overloaded functions that
|
2009-01-15 08:26:24 +08:00
|
|
|
/// met the criteria. getAsDecl will turn this set of overloaded
|
|
|
|
/// functions into an OverloadedFunctionDecl.
|
2009-01-15 06:20:51 +08:00
|
|
|
FoundOverloaded,
|
2009-01-15 08:26:24 +08:00
|
|
|
|
|
|
|
/// Name lookup results in an ambiguity because multiple
|
|
|
|
/// entities that meet the lookup criteria were found in
|
|
|
|
/// subobjects of different types. For example:
|
|
|
|
/// @code
|
|
|
|
/// struct A { void f(int); }
|
|
|
|
/// struct B { void f(double); }
|
|
|
|
/// struct C : A, B { };
|
|
|
|
/// void test(C c) {
|
|
|
|
/// c.f(0); // error: A::f and B::f come from subobjects of different
|
|
|
|
/// // types. overload resolution is not performed.
|
|
|
|
/// }
|
|
|
|
/// @endcode
|
|
|
|
AmbiguousBaseSubobjectTypes,
|
|
|
|
|
|
|
|
/// Name lookup results in an ambiguity because multiple
|
|
|
|
/// nonstatic entities that meet the lookup criteria were found
|
|
|
|
/// in different subobjects of the same type. For example:
|
|
|
|
/// @code
|
|
|
|
/// struct A { int x; };
|
|
|
|
/// struct B : A { };
|
|
|
|
/// struct C : A { };
|
|
|
|
/// struct D : B, C { };
|
|
|
|
/// int test(D d) {
|
|
|
|
/// return d.x; // error: 'x' is found in two A subobjects (of B and C)
|
|
|
|
/// }
|
|
|
|
/// @endcode
|
|
|
|
AmbiguousBaseSubobjects
|
2009-01-15 06:20:51 +08:00
|
|
|
};
|
|
|
|
|
2009-01-17 09:13:24 +08:00
|
|
|
static LookupResult CreateLookupResult(ASTContext &Context, Decl *D) {
|
|
|
|
LookupResult Result;
|
|
|
|
Result.StoredKind = SingleDecl;
|
|
|
|
Result.First = reinterpret_cast<uintptr_t>(D);
|
|
|
|
Result.Last = 0;
|
|
|
|
Result.Context = &Context;
|
|
|
|
return Result;
|
|
|
|
}
|
2009-01-15 10:19:31 +08:00
|
|
|
|
2009-01-17 09:13:24 +08:00
|
|
|
static LookupResult CreateLookupResult(ASTContext &Context,
|
|
|
|
IdentifierResolver::iterator F,
|
|
|
|
IdentifierResolver::iterator L);
|
|
|
|
|
|
|
|
static LookupResult CreateLookupResult(ASTContext &Context,
|
|
|
|
DeclContext::lookup_iterator F,
|
|
|
|
DeclContext::lookup_iterator L);
|
|
|
|
|
|
|
|
static LookupResult CreateLookupResult(ASTContext &Context, BasePaths *Paths,
|
|
|
|
bool DifferentSubobjectTypes) {
|
|
|
|
LookupResult Result;
|
|
|
|
Result.StoredKind = AmbiguousLookup;
|
|
|
|
Result.First = reinterpret_cast<uintptr_t>(Paths);
|
|
|
|
Result.Last = DifferentSubobjectTypes? 1 : 0;
|
|
|
|
Result.Context = &Context;
|
|
|
|
return Result;
|
|
|
|
}
|
2009-01-15 10:19:31 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
LookupKind getKind() const;
|
|
|
|
|
|
|
|
/// @brief Determine whether name look found something.
|
|
|
|
operator bool() const { return getKind() != NotFound; }
|
|
|
|
|
2009-01-15 08:26:24 +08:00
|
|
|
/// @brief Determines whether the lookup resulted in an ambiguity.
|
|
|
|
bool isAmbiguous() const { return StoredKind == AmbiguousLookup; }
|
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
/// @brief Allows conversion of a lookup result into a
|
|
|
|
/// declaration, with the same behavior as getAsDecl.
|
|
|
|
operator Decl*() const { return getAsDecl(); }
|
|
|
|
|
|
|
|
Decl* getAsDecl() const;
|
2009-01-15 08:26:24 +08:00
|
|
|
|
|
|
|
BasePaths *getBasePaths() const;
|
2009-01-15 06:20:51 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
LookupResult LookupName(Scope *S, DeclarationName Name,
|
|
|
|
LookupCriteria Criteria);
|
|
|
|
LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
|
|
|
|
LookupCriteria Criteria);
|
|
|
|
LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS,
|
|
|
|
DeclarationName Name, LookupCriteria Criteria);
|
|
|
|
LookupResult LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
|
|
|
const DeclContext *LookupCtx = 0,
|
|
|
|
bool enableLazyBuiltinCreation = true,
|
|
|
|
bool LookInParent = true,
|
|
|
|
bool NamespaceNameOnly = false);
|
2009-01-15 08:26:24 +08:00
|
|
|
|
|
|
|
bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
SourceRange LookupRange = SourceRange());
|
2009-01-15 06:20:51 +08:00
|
|
|
//@}
|
|
|
|
|
2008-01-08 03:49:32 +08:00
|
|
|
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
|
2009-01-20 09:17:11 +08:00
|
|
|
NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
|
2007-03-15 05:52:03 +08:00
|
|
|
Scope *S);
|
2009-01-20 09:17:11 +08:00
|
|
|
NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
|
|
|
|
Scope *S);
|
2009-01-15 06:20:51 +08:00
|
|
|
|
|
|
|
// More parsing and symbol table subroutines.
|
|
|
|
|
2007-06-11 08:35:03 +08:00
|
|
|
// Decl attributes - this routine is the top level dispatcher.
|
2008-06-29 08:16:31 +08:00
|
|
|
void ProcessDeclAttributes(Decl *D, const Declarator &PD);
|
2008-06-29 07:58:55 +08:00
|
|
|
void ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList);
|
2008-02-04 10:31:56 +08:00
|
|
|
|
2008-02-11 05:38:56 +08:00
|
|
|
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
|
|
|
|
bool &IncompleteImpl);
|
2008-12-06 02:18:52 +08:00
|
|
|
void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
|
|
|
|
ObjCMethodDecl *IntfMethod);
|
2008-11-11 19:37:55 +08:00
|
|
|
|
|
|
|
NamespaceDecl *GetStdNamespace();
|
2009-01-13 03:55:42 +08:00
|
|
|
|
|
|
|
bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
|
|
|
|
ObjCInterfaceDecl *IDecl) const;
|
2008-02-11 05:38:56 +08:00
|
|
|
|
2009-01-06 15:27:21 +08:00
|
|
|
/// CheckProtocolMethodDefs - This routine checks unimplemented
|
2008-09-05 04:01:15 +08:00
|
|
|
/// methods declared in protocol, and those referenced by it.
|
|
|
|
/// \param IDecl - Used for checking for methods which may have been
|
|
|
|
/// inherited.
|
2008-02-09 06:06:17 +08:00
|
|
|
void CheckProtocolMethodDefs(SourceLocation ImpLoc,
|
|
|
|
ObjCProtocolDecl *PDecl,
|
2007-10-03 04:06:01 +08:00
|
|
|
bool& IncompleteImpl,
|
2007-10-09 05:05:34 +08:00
|
|
|
const llvm::DenseSet<Selector> &InsMap,
|
2008-09-05 04:01:15 +08:00
|
|
|
const llvm::DenseSet<Selector> &ClsMap,
|
|
|
|
ObjCInterfaceDecl *IDecl);
|
2007-09-30 01:14:55 +08:00
|
|
|
|
2007-10-03 05:43:37 +08:00
|
|
|
/// CheckImplementationIvars - This routine checks if the instance variables
|
|
|
|
/// listed in the implelementation match those listed in the interface.
|
2008-01-08 03:49:32 +08:00
|
|
|
void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
|
|
|
|
ObjCIvarDecl **Fields, unsigned nIvars,
|
2008-02-11 05:38:56 +08:00
|
|
|
SourceLocation Loc);
|
2007-10-03 05:43:37 +08:00
|
|
|
|
2007-09-30 01:14:55 +08:00
|
|
|
/// ImplMethodsVsClassMethods - This is main routine to warn if any method
|
|
|
|
/// remains unimplemented in the @implementation class.
|
2008-01-08 03:49:32 +08:00
|
|
|
void ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
|
|
|
|
ObjCInterfaceDecl* IDecl);
|
2007-09-30 01:14:55 +08:00
|
|
|
|
2007-10-03 00:38:50 +08:00
|
|
|
/// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
|
|
|
|
/// category interface is implemented in the category @implementation.
|
2008-01-08 03:49:32 +08:00
|
|
|
void ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
|
|
|
|
ObjCCategoryDecl *CatClassDecl);
|
2007-10-06 02:00:57 +08:00
|
|
|
/// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
|
|
|
|
/// true, or false, accordingly.
|
2008-01-08 03:49:32 +08:00
|
|
|
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
|
2008-10-21 18:37:50 +08:00
|
|
|
const ObjCMethodDecl *PrevMethod,
|
|
|
|
bool matchBasedOnSizeAndAlignment = false);
|
2007-10-11 05:53:07 +08:00
|
|
|
|
2007-10-14 08:58:41 +08:00
|
|
|
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
|
|
|
|
/// unit are added to a global pool. This allows us to efficiently associate
|
|
|
|
/// a selector with a method declaraation for purposes of typechecking
|
|
|
|
/// messages sent to "id" (where the class of the object is unknown).
|
2008-01-08 03:49:32 +08:00
|
|
|
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
|
2007-10-14 08:58:41 +08:00
|
|
|
|
2008-09-30 22:38:43 +08:00
|
|
|
/// LookupInstanceMethodInGlobalPool - Returns the method and warns if
|
|
|
|
/// there are multiple signatures.
|
|
|
|
ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R);
|
|
|
|
|
2007-10-14 08:58:41 +08:00
|
|
|
/// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
|
2008-01-08 03:49:32 +08:00
|
|
|
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
|
2006-11-03 14:42:29 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
2006-11-10 13:29:30 +08:00
|
|
|
// Statement Parsing Callbacks: SemaStmt.cpp.
|
2007-03-15 05:52:03 +08:00
|
|
|
public:
|
2008-12-21 20:04:03 +08:00
|
|
|
virtual OwningStmtResult ActOnExprStmt(ExprArg Expr);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc);
|
|
|
|
virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
|
|
|
|
MultiStmtArg Elts,
|
|
|
|
bool isStmtExpr);
|
|
|
|
virtual OwningStmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
|
|
|
|
SourceLocation EndLoc);
|
2008-12-29 00:13:43 +08:00
|
|
|
virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
|
|
|
|
SourceLocation DotDotDotLoc, ExprArg RHSVal,
|
|
|
|
SourceLocation ColonLoc, StmtArg SubStmt);
|
|
|
|
virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
|
|
|
|
SourceLocation ColonLoc,
|
|
|
|
StmtArg SubStmt, Scope *CurScope);
|
2009-01-11 08:38:46 +08:00
|
|
|
virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
|
|
|
|
IdentifierInfo *II,
|
|
|
|
SourceLocation ColonLoc,
|
|
|
|
StmtArg SubStmt);
|
|
|
|
virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal,
|
|
|
|
StmtArg ThenVal, SourceLocation ElseLoc,
|
|
|
|
StmtArg ElseVal);
|
|
|
|
virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond);
|
|
|
|
virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
|
|
|
|
StmtArg Switch, StmtArg Body);
|
2009-01-17 07:28:06 +08:00
|
|
|
virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprArg Cond,
|
|
|
|
StmtArg Body);
|
|
|
|
virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
|
|
|
|
SourceLocation WhileLoc, ExprArg Cond);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
StmtArg First, ExprArg Second,
|
|
|
|
ExprArg Third, SourceLocation RParenLoc,
|
|
|
|
StmtArg Body);
|
|
|
|
virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
StmtArg First, ExprArg Second,
|
|
|
|
SourceLocation RParenLoc, StmtArg Body);
|
2009-01-18 21:19:59 +08:00
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
|
|
|
|
SourceLocation LabelLoc,
|
|
|
|
IdentifierInfo *LabelII);
|
|
|
|
virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
|
|
|
|
SourceLocation StarLoc,
|
|
|
|
ExprArg DestExp);
|
|
|
|
virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
|
|
|
|
Scope *CurScope);
|
|
|
|
virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
|
|
|
|
Scope *CurScope);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
|
|
|
|
ExprArg RetValExp);
|
|
|
|
OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
|
|
|
|
Expr *RetValExp);
|
|
|
|
|
2009-01-19 00:53:17 +08:00
|
|
|
virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
|
|
|
|
bool IsSimple,
|
|
|
|
bool IsVolatile,
|
|
|
|
unsigned NumOutputs,
|
|
|
|
unsigned NumInputs,
|
|
|
|
std::string *Names,
|
|
|
|
MultiExprArg Constraints,
|
|
|
|
MultiExprArg Exprs,
|
|
|
|
ExprArg AsmString,
|
|
|
|
MultiExprArg Clobbers,
|
|
|
|
SourceLocation RParenLoc);
|
2009-01-19 01:43:11 +08:00
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
|
|
|
|
SourceLocation RParen,
|
|
|
|
StmtArg Parm, StmtArg Body,
|
|
|
|
StmtArg CatchList);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
|
|
|
|
StmtArg Body);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
|
|
|
|
StmtArg Try,
|
|
|
|
StmtArg Catch, StmtArg Finally);
|
|
|
|
|
|
|
|
virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
|
|
|
|
ExprArg Throw);
|
|
|
|
virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
|
|
|
|
ExprArg SynchExpr,
|
|
|
|
StmtArg SynchBody);
|
2008-12-22 00:41:36 +08:00
|
|
|
|
2008-12-23 03:15:10 +08:00
|
|
|
virtual DeclTy *ActOnExceptionDeclarator(Scope *S, Declarator &D);
|
|
|
|
virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
|
|
|
|
DeclTy *ExDecl,
|
|
|
|
StmtArg HandlerBlock);
|
2008-12-23 05:35:02 +08:00
|
|
|
virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
|
|
|
|
StmtArg TryBlock,
|
|
|
|
MultiStmtArg Handlers);
|
2008-12-22 00:41:36 +08:00
|
|
|
|
2006-11-03 14:42:29 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
2006-11-10 13:29:30 +08:00
|
|
|
// Expression Parsing Callbacks: SemaExpr.cpp.
|
2006-11-03 14:42:29 +08:00
|
|
|
|
|
|
|
// Primary Expressions.
|
2009-01-19 02:53:16 +08:00
|
|
|
virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
|
|
|
|
IdentifierInfo &II,
|
|
|
|
bool HasTrailingLParen,
|
|
|
|
const CXXScopeSpec *SS = 0);
|
|
|
|
virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S,
|
2008-11-20 03:09:45 +08:00
|
|
|
SourceLocation OperatorLoc,
|
|
|
|
OverloadedOperatorKind Op,
|
|
|
|
bool HasTrailingLParen,
|
|
|
|
const CXXScopeSpec &SS);
|
2009-01-19 02:53:16 +08:00
|
|
|
virtual OwningExprResult ActOnCXXConversionFunctionExpr(Scope *S,
|
2008-11-20 03:09:45 +08:00
|
|
|
SourceLocation OperatorLoc,
|
|
|
|
TypeTy *Ty,
|
|
|
|
bool HasTrailingLParen,
|
|
|
|
const CXXScopeSpec &SS);
|
2009-01-06 13:10:23 +08:00
|
|
|
DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
|
|
|
|
bool TypeDependent, bool ValueDependent,
|
|
|
|
const CXXScopeSpec *SS = 0);
|
2009-01-19 02:53:16 +08:00
|
|
|
OwningExprResult
|
2009-01-07 08:43:41 +08:00
|
|
|
BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
|
|
|
|
FieldDecl *Field,
|
|
|
|
Expr *BaseObjectExpr = 0,
|
|
|
|
SourceLocation OpLoc = SourceLocation());
|
2009-01-19 02:53:16 +08:00
|
|
|
OwningExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|
|
|
DeclarationName Name,
|
|
|
|
bool HasTrailingLParen,
|
|
|
|
const CXXScopeSpec *SS,
|
|
|
|
bool ForceResolution = false);
|
|
|
|
|
|
|
|
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
|
|
|
|
tok::TokenKind Kind);
|
|
|
|
virtual OwningExprResult ActOnNumericConstant(const Token &);
|
|
|
|
virtual OwningExprResult ActOnCharacterConstant(const Token &);
|
|
|
|
virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
|
|
|
|
ExprArg Val);
|
2006-11-09 14:32:27 +08:00
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
/// ActOnStringLiteral - The specified tokens were lexed as pasted string
|
2006-11-09 14:32:27 +08:00
|
|
|
/// fragments (e.g. "foo" "bar" L"baz").
|
2009-01-19 08:08:26 +08:00
|
|
|
virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
|
|
|
|
unsigned NumToks);
|
2009-01-19 02:53:16 +08:00
|
|
|
|
2006-11-03 14:42:29 +08:00
|
|
|
// Binary/Unary Operators. 'Tok' is the token for the operator.
|
2009-01-19 08:08:26 +08:00
|
|
|
virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
|
|
|
|
tok::TokenKind Op, ExprArg Input);
|
|
|
|
virtual OwningExprResult
|
2008-11-12 01:56:53 +08:00
|
|
|
ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
|
|
|
|
void *TyOrEx, const SourceRange &ArgRange);
|
|
|
|
|
2009-01-25 04:17:12 +08:00
|
|
|
bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R);
|
2008-11-12 01:56:53 +08:00
|
|
|
bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
|
|
|
|
const SourceRange &R, bool isSizeof);
|
2009-01-19 08:08:26 +08:00
|
|
|
|
|
|
|
virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
|
|
|
|
tok::TokenKind Kind,
|
|
|
|
ExprArg Input);
|
|
|
|
|
|
|
|
virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
|
|
|
|
SourceLocation LLoc,
|
|
|
|
ExprArg Idx,
|
|
|
|
SourceLocation RLoc);
|
|
|
|
virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
|
|
|
|
SourceLocation OpLoc,
|
|
|
|
tok::TokenKind OpKind,
|
|
|
|
SourceLocation MemberLoc,
|
|
|
|
IdentifierInfo &Member);
|
|
|
|
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
|
2008-12-22 13:46:06 +08:00
|
|
|
FunctionDecl *FDecl,
|
|
|
|
const FunctionTypeProto *Proto,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation RParenLoc);
|
2009-01-19 08:08:26 +08:00
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
|
2006-11-03 14:42:29 +08:00
|
|
|
/// This provides the location of the left/right parens and a list of comma
|
|
|
|
/// locations.
|
2009-01-19 08:08:26 +08:00
|
|
|
virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
MultiExprArg Args,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2009-01-20 06:31:54 +08:00
|
|
|
virtual OwningExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
|
|
|
|
SourceLocation RParenLoc, ExprArg Op);
|
|
|
|
|
|
|
|
virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
|
|
|
|
TypeTy *Ty,
|
|
|
|
SourceLocation RParenLoc,
|
|
|
|
ExprArg Op);
|
|
|
|
|
|
|
|
virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
|
|
|
|
MultiExprArg InitList,
|
|
|
|
InitListDesignations &Designators,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2009-01-22 08:58:24 +08:00
|
|
|
virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
|
|
|
|
SourceLocation Loc,
|
|
|
|
bool UsedColonSyntax,
|
|
|
|
OwningExprResult Init);
|
|
|
|
|
2009-01-20 06:31:54 +08:00
|
|
|
virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
|
|
|
|
tok::TokenKind Kind,
|
|
|
|
ExprArg LHS, ExprArg RHS);
|
|
|
|
OwningExprResult CreateBuiltinBinOp(SourceLocation TokLoc,
|
|
|
|
unsigned Opc, Expr *lhs, Expr *rhs);
|
2008-11-07 07:29:22 +08:00
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
|
2006-11-03 14:42:29 +08:00
|
|
|
/// in the case of a the GNU conditional expr extension.
|
2009-01-20 06:31:54 +08:00
|
|
|
virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
|
|
|
|
SourceLocation ColonLoc,
|
|
|
|
ExprArg Cond, ExprArg LHS,
|
|
|
|
ExprArg RHS);
|
2006-12-05 02:06:35 +08:00
|
|
|
|
2007-09-16 22:56:35 +08:00
|
|
|
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
|
|
|
|
virtual ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
|
2007-05-28 14:56:27 +08:00
|
|
|
IdentifierInfo *LabelII);
|
|
|
|
|
2007-09-16 22:56:35 +08:00
|
|
|
virtual ExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
|
2007-07-25 00:58:17 +08:00
|
|
|
SourceLocation RPLoc); // "({..})"
|
2007-08-31 01:45:32 +08:00
|
|
|
|
|
|
|
/// __builtin_offsetof(type, a.b[123][456].c)
|
2008-12-23 08:26:44 +08:00
|
|
|
virtual ExprResult ActOnBuiltinOffsetOf(Scope *S,
|
|
|
|
SourceLocation BuiltinLoc,
|
2007-08-31 01:45:32 +08:00
|
|
|
SourceLocation TypeLoc, TypeTy *Arg1,
|
|
|
|
OffsetOfComponent *CompPtr,
|
|
|
|
unsigned NumComponents,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2007-08-02 06:05:33 +08:00
|
|
|
// __builtin_types_compatible_p(type1, type2)
|
2007-09-16 22:56:35 +08:00
|
|
|
virtual ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
|
2007-08-02 06:05:33 +08:00
|
|
|
TypeTy *arg1, TypeTy *arg2,
|
|
|
|
SourceLocation RPLoc);
|
2007-08-04 05:21:27 +08:00
|
|
|
|
|
|
|
// __builtin_choose_expr(constExpr, expr1, expr2)
|
2007-09-16 22:56:35 +08:00
|
|
|
virtual ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
|
2007-08-04 05:21:27 +08:00
|
|
|
ExprTy *cond, ExprTy *expr1, ExprTy *expr2,
|
|
|
|
SourceLocation RPLoc);
|
2007-07-25 00:58:17 +08:00
|
|
|
|
2008-01-18 01:46:27 +08:00
|
|
|
// __builtin_overload(...)
|
|
|
|
virtual ExprResult ActOnOverloadExpr(ExprTy **Args, unsigned NumArgs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation BuiltinLoc,
|
|
|
|
SourceLocation RParenLoc);
|
2008-03-08 04:04:22 +08:00
|
|
|
|
2007-10-16 04:28:48 +08:00
|
|
|
// __builtin_va_arg(expr, type)
|
|
|
|
virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
|
|
|
|
ExprTy *expr, TypeTy *type,
|
|
|
|
SourceLocation RPLoc);
|
2008-09-04 02:15:37 +08:00
|
|
|
|
2008-11-29 12:51:27 +08:00
|
|
|
// __null
|
|
|
|
virtual ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
|
|
|
|
|
2008-09-04 02:15:37 +08:00
|
|
|
//===------------------------- "Block" Extension ------------------------===//
|
|
|
|
|
|
|
|
/// ActOnBlockStart - This callback is invoked when a block literal is
|
|
|
|
/// started.
|
2008-10-10 09:28:17 +08:00
|
|
|
virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
|
|
|
|
|
|
|
|
/// ActOnBlockArguments - This callback allows processing of block arguments.
|
|
|
|
/// If there are no arguments, this is still invoked.
|
|
|
|
virtual void ActOnBlockArguments(Declarator &ParamInfo);
|
2008-09-04 02:15:37 +08:00
|
|
|
|
|
|
|
/// ActOnBlockError - If there is an error parsing a block, this callback
|
|
|
|
/// is invoked to pop the information about the block from the action impl.
|
|
|
|
virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
|
|
|
|
|
|
|
|
/// ActOnBlockStmtExpr - This is called when the body of a block statement
|
|
|
|
/// literal was successfully completed. ^(int x){...}
|
|
|
|
virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
|
|
|
|
Scope *CurScope);
|
|
|
|
|
2008-04-27 21:50:30 +08:00
|
|
|
// Act on C++ namespaces
|
|
|
|
virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
|
|
|
|
IdentifierInfo *Ident,
|
|
|
|
SourceLocation LBrace);
|
|
|
|
virtual void ActOnFinishNamespaceDef(DeclTy *Dcl, SourceLocation RBrace);
|
|
|
|
|
2008-12-30 11:27:21 +08:00
|
|
|
virtual DeclTy *ActOnUsingDirective(Scope *CurScope,
|
|
|
|
SourceLocation UsingLoc,
|
|
|
|
SourceLocation NamespcLoc,
|
|
|
|
const CXXScopeSpec &SS,
|
|
|
|
SourceLocation IdentLoc,
|
|
|
|
IdentifierInfo *NamespcName,
|
|
|
|
AttributeList *AttrList);
|
|
|
|
|
2008-10-07 01:10:33 +08:00
|
|
|
/// AddCXXDirectInitializerToDecl - This action is called immediately after
|
|
|
|
/// ActOnDeclarator, when a C++ direct initializer is present.
|
|
|
|
/// e.g: "int x(1);"
|
|
|
|
virtual void AddCXXDirectInitializerToDecl(DeclTy *Dcl,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
ExprTy **Exprs, unsigned NumExprs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2008-11-05 23:29:30 +08:00
|
|
|
/// InitializationKind - Represents which kind of C++ initialization
|
|
|
|
/// [dcl.init] a routine is to perform.
|
|
|
|
enum InitializationKind {
|
|
|
|
IK_Direct, ///< Direct initialization
|
|
|
|
IK_Copy, ///< Copy initialization
|
|
|
|
IK_Default ///< Default initialization
|
|
|
|
};
|
|
|
|
|
2008-11-04 04:45:27 +08:00
|
|
|
CXXConstructorDecl *
|
2008-11-05 23:29:30 +08:00
|
|
|
PerformInitializationByConstructor(QualType ClassType,
|
|
|
|
Expr **Args, unsigned NumArgs,
|
|
|
|
SourceLocation Loc, SourceRange Range,
|
2008-11-24 13:29:24 +08:00
|
|
|
DeclarationName InitEntity,
|
2008-11-05 23:29:30 +08:00
|
|
|
InitializationKind Kind);
|
2008-11-04 04:45:27 +08:00
|
|
|
|
2008-10-28 03:41:14 +08:00
|
|
|
/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
|
|
|
|
virtual ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
|
|
|
|
SourceLocation LAngleBracketLoc, TypeTy *Ty,
|
|
|
|
SourceLocation RAngleBracketLoc,
|
|
|
|
SourceLocation LParenLoc, ExprTy *E,
|
|
|
|
SourceLocation RParenLoc);
|
2007-02-13 09:51:42 +08:00
|
|
|
|
2008-11-11 19:37:55 +08:00
|
|
|
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
|
|
|
|
virtual ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
|
|
|
|
SourceLocation LParenLoc, bool isType,
|
|
|
|
void *TyOrExpr, SourceLocation RParenLoc);
|
|
|
|
|
2008-07-01 18:37:29 +08:00
|
|
|
//// ActOnCXXThis - Parse 'this' pointer.
|
|
|
|
virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc);
|
|
|
|
|
2007-09-16 22:56:35 +08:00
|
|
|
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
|
|
|
|
virtual ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
|
2007-02-14 04:09:46 +08:00
|
|
|
tok::TokenKind Kind);
|
2007-08-22 01:43:55 +08:00
|
|
|
|
2008-02-26 08:51:44 +08:00
|
|
|
//// ActOnCXXThrow - Parse throw expressions.
|
|
|
|
virtual ExprResult ActOnCXXThrow(SourceLocation OpLoc,
|
|
|
|
ExprTy *expr);
|
|
|
|
|
2008-08-22 23:38:55 +08:00
|
|
|
/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
|
|
|
|
/// Can be interpreted either as function-style casting ("int(x)")
|
|
|
|
/// or class type construction ("ClassType(x,y,z)")
|
|
|
|
/// or creation of a value-initialized type ("int()").
|
|
|
|
virtual ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
|
|
|
|
TypeTy *TypeRep,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
ExprTy **Exprs,
|
|
|
|
unsigned NumExprs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2008-11-22 03:14:01 +08:00
|
|
|
/// ActOnCXXNew - Parsed a C++ 'new' expression.
|
|
|
|
virtual ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
|
|
|
|
SourceLocation PlacementLParen,
|
|
|
|
ExprTy **PlacementArgs, unsigned NumPlaceArgs,
|
|
|
|
SourceLocation PlacementRParen,
|
2008-12-02 22:43:59 +08:00
|
|
|
bool ParenTypeId, Declarator &D,
|
2008-11-22 03:14:01 +08:00
|
|
|
SourceLocation ConstructorLParen,
|
|
|
|
ExprTy **ConstructorArgs, unsigned NumConsArgs,
|
|
|
|
SourceLocation ConstructorRParen);
|
2008-12-02 22:43:59 +08:00
|
|
|
bool CheckAllocatedType(QualType AllocType, const Declarator &D);
|
2008-12-04 04:26:15 +08:00
|
|
|
bool FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal,
|
|
|
|
QualType AllocType, bool IsArray,
|
|
|
|
Expr **PlaceArgs, unsigned NumPlaceArgs,
|
|
|
|
FunctionDecl *&OperatorNew,
|
|
|
|
FunctionDecl *&OperatorDelete);
|
2008-12-05 06:20:51 +08:00
|
|
|
bool FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name,
|
|
|
|
Expr** Args, unsigned NumArgs, DeclContext *Ctx,
|
|
|
|
bool AllowMissing, FunctionDecl *&Operator);
|
2008-12-04 04:26:15 +08:00
|
|
|
void DeclareGlobalNewDelete();
|
|
|
|
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
|
|
|
|
QualType Argument);
|
2008-11-22 03:14:01 +08:00
|
|
|
|
|
|
|
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
|
|
|
|
virtual ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|
|
|
bool ArrayForm, ExprTy *Operand);
|
|
|
|
|
2008-09-10 10:17:11 +08:00
|
|
|
/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
|
|
|
|
/// C++ if/switch/while/for statement.
|
|
|
|
/// e.g: "if (int x = f()) {...}"
|
|
|
|
virtual ExprResult ActOnCXXConditionDeclarationExpr(Scope *S,
|
|
|
|
SourceLocation StartLoc,
|
|
|
|
Declarator &D,
|
|
|
|
SourceLocation EqualLoc,
|
|
|
|
ExprTy *AssignExprVal);
|
|
|
|
|
2009-01-06 04:52:13 +08:00
|
|
|
/// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
|
|
|
|
/// pseudo-functions.
|
|
|
|
virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
|
|
|
|
SourceLocation KWLoc,
|
|
|
|
SourceLocation LParen,
|
|
|
|
TypeTy *Ty,
|
|
|
|
SourceLocation RParen);
|
|
|
|
|
2008-11-09 01:17:31 +08:00
|
|
|
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
|
|
|
|
/// global scope ('::').
|
|
|
|
virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
|
|
|
|
SourceLocation CCLoc);
|
|
|
|
|
|
|
|
/// ActOnCXXNestedNameSpecifier - Called during parsing of a
|
|
|
|
/// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now
|
|
|
|
/// we want to resolve "bar::". 'SS' is empty or the previously parsed
|
|
|
|
/// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar',
|
|
|
|
/// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'.
|
|
|
|
/// Returns a CXXScopeTy* object representing the C++ scope.
|
|
|
|
virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
|
|
|
|
const CXXScopeSpec &SS,
|
|
|
|
SourceLocation IdLoc,
|
|
|
|
SourceLocation CCLoc,
|
2008-11-18 04:34:05 +08:00
|
|
|
IdentifierInfo &II);
|
2008-11-09 01:17:31 +08:00
|
|
|
|
|
|
|
/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
|
|
|
|
/// scope or nested-name-specifier) is parsed, part of a declarator-id.
|
|
|
|
/// After this method is called, according to [C++ 3.4.3p3], names should be
|
|
|
|
/// looked up in the declarator-id's scope, until the declarator is parsed and
|
|
|
|
/// ActOnCXXExitDeclaratorScope is called.
|
|
|
|
/// The 'SS' should be a non-empty valid CXXScopeSpec.
|
|
|
|
virtual void ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
|
|
|
|
|
|
|
|
/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
|
|
|
|
/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
|
|
|
|
/// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
|
|
|
|
/// Used to indicate that names should revert to being looked up in the
|
|
|
|
/// defining scope.
|
2008-12-16 08:38:16 +08:00
|
|
|
virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
|
2008-11-09 01:17:31 +08:00
|
|
|
|
2007-08-22 01:43:55 +08:00
|
|
|
// ParseObjCStringLiteral - Parse Objective-C string literals.
|
2007-12-12 09:04:12 +08:00
|
|
|
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
|
|
|
|
ExprTy **Strings,
|
|
|
|
unsigned NumStrings);
|
2007-08-22 23:14:15 +08:00
|
|
|
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
|
2007-10-17 06:51:17 +08:00
|
|
|
SourceLocation EncodeLoc,
|
2007-08-22 23:14:15 +08:00
|
|
|
SourceLocation LParenLoc,
|
|
|
|
TypeTy *Ty,
|
|
|
|
SourceLocation RParenLoc);
|
2007-10-17 04:40:23 +08:00
|
|
|
|
|
|
|
// ParseObjCSelectorExpression - Build selector expression for @selector
|
|
|
|
virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
|
|
|
|
SourceLocation AtLoc,
|
2007-10-17 07:21:02 +08:00
|
|
|
SourceLocation SelLoc,
|
2007-10-17 04:40:23 +08:00
|
|
|
SourceLocation LParenLoc,
|
|
|
|
SourceLocation RParenLoc);
|
2007-08-22 23:14:15 +08:00
|
|
|
|
2007-10-18 00:58:11 +08:00
|
|
|
// ParseObjCProtocolExpression - Build protocol expression for @protocol
|
|
|
|
virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
|
|
|
|
SourceLocation AtLoc,
|
|
|
|
SourceLocation ProtoLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
SourceLocation RParenLoc);
|
2008-04-14 05:30:24 +08:00
|
|
|
|
2009-01-06 03:45:36 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// C++ Declarations
|
|
|
|
//
|
|
|
|
virtual DeclTy *ActOnStartLinkageSpecification(Scope *S,
|
|
|
|
SourceLocation ExternLoc,
|
|
|
|
SourceLocation LangLoc,
|
|
|
|
const char *Lang,
|
|
|
|
unsigned StrSize,
|
|
|
|
SourceLocation LBraceLoc);
|
|
|
|
virtual DeclTy *ActOnFinishLinkageSpecification(Scope *S,
|
|
|
|
DeclTy *LinkageSpec,
|
|
|
|
SourceLocation RBraceLoc);
|
|
|
|
|
|
|
|
|
2008-04-14 05:30:24 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// C++ Classes
|
|
|
|
//
|
2008-11-09 00:45:02 +08:00
|
|
|
virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
|
|
|
|
const CXXScopeSpec *SS);
|
2008-10-31 17:07:45 +08:00
|
|
|
|
2008-07-01 18:37:29 +08:00
|
|
|
virtual DeclTy *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
|
|
|
|
Declarator &D, ExprTy *BitfieldWidth,
|
|
|
|
ExprTy *Init, DeclTy *LastInGroup);
|
|
|
|
|
2008-11-05 12:29:56 +08:00
|
|
|
virtual MemInitResult ActOnMemInitializer(DeclTy *ConstructorD,
|
|
|
|
Scope *S,
|
|
|
|
IdentifierInfo *MemberOrBase,
|
|
|
|
SourceLocation IdLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
ExprTy **Args, unsigned NumArgs,
|
|
|
|
SourceLocation *CommaLocs,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2008-11-04 01:51:48 +08:00
|
|
|
void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
|
|
|
|
|
2008-07-01 18:37:29 +08:00
|
|
|
virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
|
|
|
|
DeclTy *TagDecl,
|
|
|
|
SourceLocation LBrac,
|
|
|
|
SourceLocation RBrac);
|
|
|
|
|
2008-12-17 05:30:33 +08:00
|
|
|
virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclTy *Method);
|
|
|
|
virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclTy *Param);
|
|
|
|
virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclTy *Method);
|
|
|
|
|
2008-11-06 04:51:48 +08:00
|
|
|
bool CheckConstructorDeclarator(Declarator &D, QualType &R,
|
|
|
|
FunctionDecl::StorageClass& SC);
|
2008-12-17 05:30:33 +08:00
|
|
|
bool CheckConstructor(CXXConstructorDecl *Constructor);
|
2008-11-06 04:51:48 +08:00
|
|
|
bool CheckDestructorDeclarator(Declarator &D, QualType &R,
|
|
|
|
FunctionDecl::StorageClass& SC);
|
2008-11-08 04:08:42 +08:00
|
|
|
bool CheckConversionDeclarator(Declarator &D, QualType &R,
|
|
|
|
FunctionDecl::StorageClass& SC);
|
|
|
|
DeclTy *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
|
2008-10-31 17:07:45 +08:00
|
|
|
|
2008-10-23 08:40:37 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// C++ Derived Classes
|
|
|
|
//
|
|
|
|
|
|
|
|
/// ActOnBaseSpecifier - Parsed a base specifier
|
|
|
|
virtual BaseResult ActOnBaseSpecifier(DeclTy *classdecl,
|
|
|
|
SourceRange SpecifierRange,
|
|
|
|
bool Virtual, AccessSpecifier Access,
|
|
|
|
TypeTy *basetype, SourceLocation BaseLoc);
|
|
|
|
|
|
|
|
virtual void ActOnBaseSpecifiers(DeclTy *ClassDecl, BaseTy **Bases,
|
|
|
|
unsigned NumBases);
|
|
|
|
|
|
|
|
bool IsDerivedFrom(QualType Derived, QualType Base);
|
2008-10-24 12:54:22 +08:00
|
|
|
bool IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths);
|
2009-01-15 08:26:24 +08:00
|
|
|
bool LookupInBases(CXXRecordDecl *Class, const MemberLookupCriteria& Criteria,
|
|
|
|
BasePaths &Paths);
|
2008-10-25 00:17:19 +08:00
|
|
|
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
|
|
|
|
SourceLocation Loc, SourceRange Range);
|
2009-01-16 08:38:09 +08:00
|
|
|
std::string getAmbiguousPathsDisplayString(BasePaths &Paths);
|
2008-04-14 05:30:24 +08:00
|
|
|
|
2008-11-07 06:13:31 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// C++ Overloaded Operators [C++ 13.5]
|
|
|
|
//
|
|
|
|
|
|
|
|
bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
|
|
|
|
|
2008-12-06 02:15:24 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// C++ Templates [C++ 14]
|
|
|
|
//
|
2008-12-19 03:37:40 +08:00
|
|
|
virtual DeclTy *isTemplateName(IdentifierInfo &II, Scope *S,
|
|
|
|
const CXXScopeSpec *SS = 0);
|
2008-12-06 02:15:24 +08:00
|
|
|
bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
|
|
|
|
virtual DeclTy *ActOnTypeParameter(Scope *S, bool Typename,
|
|
|
|
SourceLocation KeyLoc,
|
|
|
|
IdentifierInfo *ParamName,
|
2008-12-24 10:52:09 +08:00
|
|
|
SourceLocation ParamNameLoc,
|
|
|
|
unsigned Depth, unsigned Position);
|
|
|
|
virtual DeclTy *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
|
|
|
|
unsigned Depth,
|
|
|
|
unsigned Position);
|
|
|
|
virtual TemplateParamsTy *
|
|
|
|
ActOnTemplateParameterList(unsigned Depth,
|
|
|
|
SourceLocation ExportLoc,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation LAngleLoc,
|
|
|
|
DeclTy **Params, unsigned NumParams,
|
|
|
|
SourceLocation RAngleLoc);
|
|
|
|
|
2007-09-07 05:24:23 +08:00
|
|
|
// Objective-C declarations.
|
2008-07-26 12:13:19 +08:00
|
|
|
virtual DeclTy *ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|
|
|
IdentifierInfo *ClassName,
|
|
|
|
SourceLocation ClassLoc,
|
|
|
|
IdentifierInfo *SuperName,
|
|
|
|
SourceLocation SuperLoc,
|
|
|
|
DeclTy * const *ProtoRefs,
|
|
|
|
unsigned NumProtoRefs,
|
|
|
|
SourceLocation EndProtoLoc,
|
|
|
|
AttributeList *AttrList);
|
2007-10-12 07:42:27 +08:00
|
|
|
|
|
|
|
virtual DeclTy *ActOnCompatiblityAlias(
|
|
|
|
SourceLocation AtCompatibilityAliasLoc,
|
|
|
|
IdentifierInfo *AliasName, SourceLocation AliasLocation,
|
|
|
|
IdentifierInfo *ClassName, SourceLocation ClassLocation);
|
2007-09-07 05:24:23 +08:00
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
virtual DeclTy *ActOnStartProtocolInterface(
|
2008-02-21 06:57:40 +08:00
|
|
|
SourceLocation AtProtoInterfaceLoc,
|
2007-09-18 05:07:36 +08:00
|
|
|
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
|
2008-07-26 12:03:38 +08:00
|
|
|
DeclTy * const *ProtoRefNames, unsigned NumProtoRefs,
|
2008-09-26 12:48:09 +08:00
|
|
|
SourceLocation EndProtoLoc,
|
|
|
|
AttributeList *AttrList);
|
2007-09-18 05:07:36 +08:00
|
|
|
|
2008-07-26 12:07:02 +08:00
|
|
|
virtual DeclTy *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
|
|
|
IdentifierInfo *ClassName,
|
|
|
|
SourceLocation ClassLoc,
|
|
|
|
IdentifierInfo *CategoryName,
|
|
|
|
SourceLocation CategoryLoc,
|
|
|
|
DeclTy * const *ProtoRefs,
|
|
|
|
unsigned NumProtoRefs,
|
|
|
|
SourceLocation EndProtoLoc);
|
2007-09-19 04:26:58 +08:00
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
virtual DeclTy *ActOnStartClassImplementation(
|
2008-02-21 06:57:40 +08:00
|
|
|
SourceLocation AtClassImplLoc,
|
2007-09-26 02:38:09 +08:00
|
|
|
IdentifierInfo *ClassName, SourceLocation ClassLoc,
|
|
|
|
IdentifierInfo *SuperClassname,
|
|
|
|
SourceLocation SuperClassLoc);
|
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
virtual DeclTy *ActOnStartCategoryImplementation(
|
2007-10-03 00:38:50 +08:00
|
|
|
SourceLocation AtCatImplLoc,
|
|
|
|
IdentifierInfo *ClassName,
|
|
|
|
SourceLocation ClassLoc,
|
|
|
|
IdentifierInfo *CatName,
|
|
|
|
SourceLocation CatLoc);
|
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
virtual DeclTy *ActOnForwardClassDeclaration(SourceLocation Loc,
|
2007-10-03 06:39:18 +08:00
|
|
|
IdentifierInfo **IdentList,
|
|
|
|
unsigned NumElts);
|
|
|
|
|
2007-10-11 01:32:04 +08:00
|
|
|
virtual DeclTy *ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
|
2008-07-22 06:17:28 +08:00
|
|
|
const IdentifierLocPair *IdentList,
|
2008-12-17 09:07:27 +08:00
|
|
|
unsigned NumElts,
|
|
|
|
AttributeList *attrList);
|
2007-10-06 05:01:53 +08:00
|
|
|
|
2008-07-26 12:03:38 +08:00
|
|
|
virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
|
2008-07-22 06:17:28 +08:00
|
|
|
const IdentifierLocPair *ProtocolId,
|
2007-10-11 08:55:41 +08:00
|
|
|
unsigned NumProtocols,
|
2008-07-22 06:17:28 +08:00
|
|
|
llvm::SmallVectorImpl<DeclTy *> &Protocols);
|
2008-05-01 08:03:38 +08:00
|
|
|
|
2008-09-24 05:53:23 +08:00
|
|
|
/// Ensure attributes are consistent with type.
|
|
|
|
/// \param [in, out] Attributes The attributes to check; they will
|
|
|
|
/// be modified to be consistent with \arg PropertyTy.
|
|
|
|
void CheckObjCPropertyAttributes(QualType PropertyTy,
|
|
|
|
SourceLocation Loc,
|
|
|
|
unsigned &Attributes);
|
2009-01-09 01:28:14 +08:00
|
|
|
void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
|
2008-05-01 08:03:38 +08:00
|
|
|
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
|
|
|
|
ObjCPropertyDecl *SuperProperty,
|
2008-11-24 11:54:41 +08:00
|
|
|
const IdentifierInfo *Name);
|
2008-05-01 08:03:38 +08:00
|
|
|
void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
|
2008-04-25 03:58:34 +08:00
|
|
|
|
2008-12-07 07:03:39 +08:00
|
|
|
void MergeProtocolPropertiesIntoClass(Decl *CDecl,
|
2008-05-03 03:17:30 +08:00
|
|
|
DeclTy *MergeProtocols);
|
|
|
|
|
2008-12-07 07:03:39 +08:00
|
|
|
void MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
|
2008-05-03 03:17:30 +08:00
|
|
|
ObjCProtocolDecl *PDecl);
|
|
|
|
|
2007-11-12 01:19:15 +08:00
|
|
|
virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|
|
|
DeclTy **allMethods = 0, unsigned allNum = 0,
|
|
|
|
DeclTy **allProperties = 0, unsigned pNum = 0);
|
2007-09-27 02:27:25 +08:00
|
|
|
|
2008-04-15 07:36:35 +08:00
|
|
|
virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
|
2008-05-06 02:51:55 +08:00
|
|
|
FieldDeclarator &FD, ObjCDeclSpec &ODS,
|
2008-05-07 02:09:04 +08:00
|
|
|
Selector GetterSel, Selector SetterSel,
|
2008-11-27 04:01:34 +08:00
|
|
|
DeclTy *ClassCategory, bool *OverridingProperty,
|
2008-05-06 02:51:55 +08:00
|
|
|
tok::ObjCKeywordKind MethodImplKind);
|
|
|
|
|
2008-04-18 08:19:30 +08:00
|
|
|
virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|
|
|
SourceLocation PropertyLoc,
|
|
|
|
bool ImplKind, DeclTy *ClassImplDecl,
|
|
|
|
IdentifierInfo *PropertyId,
|
|
|
|
IdentifierInfo *PropertyIvar);
|
|
|
|
|
2007-10-27 04:53:56 +08:00
|
|
|
virtual DeclTy *ActOnMethodDeclaration(
|
|
|
|
SourceLocation BeginLoc, // location of the + or -.
|
|
|
|
SourceLocation EndLoc, // location of the ; or {.
|
2007-11-10 03:52:12 +08:00
|
|
|
tok::TokenKind MethodType,
|
2008-01-08 03:49:32 +08:00
|
|
|
DeclTy *ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
|
2007-11-01 07:53:01 +08:00
|
|
|
Selector Sel,
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
// optional arguments. The number of types/arguments is obtained
|
|
|
|
// from the Sel.getNumArgs().
|
2008-01-08 03:49:32 +08:00
|
|
|
ObjCDeclSpec *ArgQT, TypeTy **ArgTypes, IdentifierInfo **ArgNames,
|
2009-01-09 08:38:19 +08:00
|
|
|
llvm::SmallVectorImpl<Declarator> &Cdecls,
|
2007-11-15 20:35:21 +08:00
|
|
|
AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
|
|
|
|
bool isVariadic = false);
|
2007-10-17 07:12:48 +08:00
|
|
|
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
// ActOnClassMessage - used for both unary and keyword messages.
|
|
|
|
// ArgExprs is optional - if it is present, the number of expressions
|
2007-11-15 21:05:42 +08:00
|
|
|
// is obtained from NumArgs.
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
virtual ExprResult ActOnClassMessage(
|
2007-11-13 04:13:27 +08:00
|
|
|
Scope *S,
|
2007-09-29 06:22:11 +08:00
|
|
|
IdentifierInfo *receivingClassName, Selector Sel,
|
2008-11-19 23:54:23 +08:00
|
|
|
SourceLocation lbrac, SourceLocation receiverLoc, SourceLocation rbrac,
|
2007-11-15 21:05:42 +08:00
|
|
|
ExprTy **ArgExprs, unsigned NumArgs);
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
|
|
|
|
// ActOnInstanceMessage - used for both unary and keyword messages.
|
|
|
|
// ArgExprs is optional - if it is present, the number of expressions
|
2007-11-15 21:05:42 +08:00
|
|
|
// is obtained from NumArgs.
|
Add SelectorInfo (similar in spirit to IdentifierInfo). The key difference is SelectorInfo is not string-oriented, it is a unique aggregate of IdentifierInfo's (using a folding set). SelectorInfo also has a richer API that simplifies the parser/action interface. 3 noteworthy benefits:
#1: It is cleaner. I never "liked" storing keyword selectors (i.e. foo:bar:baz) in the IdentifierTable.
#2: It is more space efficient. Since Cocoa keyword selectors can be quite long, this technique is space saving. For Cocoa.h, pulling the keyword selectors out saves ~180k. The cost of the SelectorInfo data is ~100k. Saves ~80k, or 43%.
#3: It results in many API simplifications. Here are some highlights:
- Removed 3 actions (ActOnKeywordMessage, ActOnUnaryMessage, & one flavor of ObjcBuildMethodDeclaration that was specific to unary messages).
- Removed 3 funky structs from DeclSpec.h (ObjcKeywordMessage, ObjcKeywordDecl, and ObjcKeywordInfo).
- Removed 2 ivars and 2 constructors from ObjCMessageExpr (fyi, this space savings has not been measured).
I am happy with the way it turned out (though it took a bit more hacking than I expected). Given the central role of selectors in ObjC, making sure this is "right" will pay dividends later.
Thanks to Chris for talking this through with me and suggesting this approach.
llvm-svn: 42395
2007-09-27 22:38:14 +08:00
|
|
|
virtual ExprResult ActOnInstanceMessage(
|
2007-09-29 06:22:11 +08:00
|
|
|
ExprTy *receiver, Selector Sel,
|
2007-11-15 21:05:42 +08:00
|
|
|
SourceLocation lbrac, SourceLocation rbrac,
|
|
|
|
ExprTy **ArgExprs, unsigned NumArgs);
|
2008-10-14 13:35:18 +08:00
|
|
|
|
|
|
|
/// ActOnPragmaPack - Called on well formed #pragma pack(...).
|
|
|
|
virtual void ActOnPragmaPack(PragmaPackKind Kind,
|
|
|
|
IdentifierInfo *Name,
|
|
|
|
ExprTy *Alignment,
|
|
|
|
SourceLocation PragmaLoc,
|
|
|
|
SourceLocation LParenLoc,
|
|
|
|
SourceLocation RParenLoc);
|
|
|
|
|
2008-01-17 03:17:22 +08:00
|
|
|
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
|
|
|
|
/// cast. If there is already an implicit cast, merge into the existing one.
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
llvm-svn: 59148
2008-11-13 01:17:38 +08:00
|
|
|
/// If isLvalue, the result of the cast is an lvalue.
|
|
|
|
void ImpCastExprToType(Expr *&Expr, QualType Type, bool isLvalue = false);
|
2008-01-17 03:17:22 +08:00
|
|
|
|
2007-06-05 06:22:31 +08:00
|
|
|
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
2007-12-28 13:29:59 +08:00
|
|
|
// functions and arrays to their respective pointers (C99 6.3.2.1).
|
|
|
|
Expr *UsualUnaryConversions(Expr *&expr);
|
2008-05-27 11:33:27 +08:00
|
|
|
|
2007-07-17 05:54:35 +08:00
|
|
|
// DefaultFunctionArrayConversion - converts functions and arrays
|
|
|
|
// to their respective pointers (C99 6.3.2.1).
|
|
|
|
void DefaultFunctionArrayConversion(Expr *&expr);
|
2007-07-14 07:32:42 +08:00
|
|
|
|
2007-08-29 07:30:39 +08:00
|
|
|
// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
|
|
|
|
// do not have a prototype. Integer promotions are performed on each
|
|
|
|
// argument, and arguments that have type float are promoted to double.
|
2007-12-28 13:29:59 +08:00
|
|
|
void DefaultArgumentPromotion(Expr *&Expr);
|
2009-01-17 00:48:51 +08:00
|
|
|
|
|
|
|
// Used for emitting the right warning by DefaultVariadicArgumentPromotion
|
|
|
|
enum VariadicCallType {
|
|
|
|
VariadicFunction,
|
|
|
|
VariadicBlock,
|
|
|
|
VariadicMethod
|
|
|
|
};
|
|
|
|
|
|
|
|
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
|
|
|
|
// will warn if the resulting type is not a POD type.
|
|
|
|
void DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
|
2007-08-29 07:30:39 +08:00
|
|
|
|
2007-06-05 06:22:31 +08:00
|
|
|
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
|
|
|
|
// operands and then handles various conversions that are common to binary
|
|
|
|
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
|
|
|
|
// routine returns the first non-arithmetic type found. The client is
|
|
|
|
// responsible for emitting appropriate error diagnostics.
|
2007-08-25 03:07:16 +08:00
|
|
|
QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
|
|
|
|
bool isCompAssign = false);
|
2008-01-05 02:22:42 +08:00
|
|
|
|
Implement support for operator overloading using candidate operator
functions for built-in operators, e.g., the builtin
bool operator==(int const*, int const*)
can be used for the expression "x1 == x2" given:
struct X {
operator int const*();
} x1, x2;
The scheme for handling these built-in operators is relatively simple:
for each candidate required by the standard, create a special kind of
candidate function for the built-in. If overload resolution picks the
built-in operator, we perform the appropriate conversions on the
arguments and then let the normal built-in operator take care of it.
There may be some optimization opportunity left: if we can reduce the
number of built-in operator overloads we generate, overload resolution
for these cases will go faster. However, one must be careful when
doing this: GCC generates too few operator overloads in our little
test program, and fails to compile it because none of the overloads it
generates match.
Note that we only support operator overload for non-member binary
operators at the moment. The other operators will follow.
As part of this change, ImplicitCastExpr can now be an lvalue.
llvm-svn: 59148
2008-11-13 01:17:38 +08:00
|
|
|
/// UsualArithmeticConversionsType - handles the various conversions
|
|
|
|
/// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9)
|
|
|
|
/// and returns the result type of that conversion.
|
|
|
|
QualType UsualArithmeticConversionsType(QualType lhs, QualType rhs);
|
|
|
|
|
|
|
|
|
2008-01-05 02:22:42 +08:00
|
|
|
/// AssignConvertType - All of the 'assignment' semantic checks return this
|
|
|
|
/// enum to indicate whether the assignment was allowed. These checks are
|
|
|
|
/// done for simple assignments, as well as initialization, return from
|
|
|
|
/// function, argument passing, etc. The query is phrased in terms of a
|
|
|
|
/// source and destination type.
|
2008-01-05 02:04:52 +08:00
|
|
|
enum AssignConvertType {
|
2008-01-05 02:22:42 +08:00
|
|
|
/// Compatible - the types are compatible according to the standard.
|
2007-05-04 05:03:48 +08:00
|
|
|
Compatible,
|
2008-01-05 02:22:42 +08:00
|
|
|
|
|
|
|
/// PointerToInt - The assignment converts a pointer to an int, which we
|
|
|
|
/// accept as an extension.
|
|
|
|
PointerToInt,
|
|
|
|
|
|
|
|
/// IntToPointer - The assignment converts an int to a pointer, which we
|
|
|
|
/// accept as an extension.
|
|
|
|
IntToPointer,
|
|
|
|
|
|
|
|
/// FunctionVoidPointer - The assignment is between a function pointer and
|
|
|
|
/// void*, which the standard doesn't allow, but we accept as an extension.
|
2008-01-04 06:56:36 +08:00
|
|
|
FunctionVoidPointer,
|
2008-01-05 02:22:42 +08:00
|
|
|
|
|
|
|
/// IncompatiblePointer - The assignment is between two pointers types that
|
|
|
|
/// are not compatible, but we accept them as an extension.
|
2007-05-11 12:00:31 +08:00
|
|
|
IncompatiblePointer,
|
2008-01-05 02:22:42 +08:00
|
|
|
|
|
|
|
/// CompatiblePointerDiscardsQualifiers - The assignment discards
|
|
|
|
/// c/v/r qualifiers, which we accept as an extension.
|
|
|
|
CompatiblePointerDiscardsQualifiers,
|
2008-09-04 23:10:53 +08:00
|
|
|
|
2008-09-04 23:31:07 +08:00
|
|
|
/// IntToBlockPointer - The assignment converts an int to a block
|
2008-09-04 23:10:53 +08:00
|
|
|
/// pointer. We disallow this.
|
|
|
|
IntToBlockPointer,
|
|
|
|
|
2008-09-04 23:31:07 +08:00
|
|
|
/// IncompatibleBlockPointer - The assignment is between two block
|
2008-09-04 23:10:53 +08:00
|
|
|
/// pointers types that are not compatible.
|
|
|
|
IncompatibleBlockPointer,
|
|
|
|
|
2008-10-15 06:18:38 +08:00
|
|
|
/// IncompatibleObjCQualifiedId - The assignment is between a qualified
|
|
|
|
/// id type and something else (that is incompatible with it). For example,
|
|
|
|
/// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
|
|
|
|
IncompatibleObjCQualifiedId,
|
|
|
|
|
2008-01-05 02:22:42 +08:00
|
|
|
/// Incompatible - We reject this conversion outright, it is invalid to
|
|
|
|
/// represent it in the AST.
|
|
|
|
Incompatible
|
2007-05-04 05:03:48 +08:00
|
|
|
};
|
2008-01-05 02:04:52 +08:00
|
|
|
|
|
|
|
/// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
|
|
|
|
/// assignment conversion type specified by ConvTy. This returns true if the
|
|
|
|
/// conversion was invalid or false if the conversion was accepted.
|
|
|
|
bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|
|
|
SourceLocation Loc,
|
|
|
|
QualType DstType, QualType SrcType,
|
|
|
|
Expr *SrcExpr, const char *Flavor);
|
|
|
|
|
|
|
|
/// CheckAssignmentConstraints - Perform type checking for assignment,
|
|
|
|
/// argument passing, variable initialization, and function return values.
|
|
|
|
/// This routine is only used by the following two methods. C99 6.5.16.
|
|
|
|
AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
|
2007-07-14 07:32:42 +08:00
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
// CheckSingleAssignmentConstraints - Currently used by ActOnCallExpr,
|
2007-09-16 22:56:35 +08:00
|
|
|
// CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
|
2007-07-14 07:32:42 +08:00
|
|
|
// this routine performs the default function/array converions.
|
2008-01-05 02:04:52 +08:00
|
|
|
AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
|
|
|
|
Expr *&rExpr);
|
2007-07-14 07:32:42 +08:00
|
|
|
// CheckCompoundAssignmentConstraints - Type check without performing any
|
|
|
|
// conversions. For compound assignments, the "Check...Operands" methods
|
|
|
|
// perform the necessary conversions.
|
2008-01-05 02:04:52 +08:00
|
|
|
AssignConvertType CheckCompoundAssignmentConstraints(QualType lhs,
|
|
|
|
QualType rhs);
|
2007-07-14 07:32:42 +08:00
|
|
|
|
2007-06-07 02:38:38 +08:00
|
|
|
// Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
|
2008-01-05 02:04:52 +08:00
|
|
|
AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
|
|
|
|
QualType rhsType);
|
2008-09-04 23:10:53 +08:00
|
|
|
|
|
|
|
// Helper function for CheckAssignmentConstraints involving two
|
|
|
|
// blcok pointer types.
|
|
|
|
AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
|
|
|
|
QualType rhsType);
|
2008-09-12 08:47:35 +08:00
|
|
|
|
|
|
|
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
|
2008-10-24 12:54:22 +08:00
|
|
|
|
2008-12-20 01:40:08 +08:00
|
|
|
bool PerformImplicitConversion(Expr *&From, QualType ToType,
|
2009-01-14 23:45:31 +08:00
|
|
|
const char *Flavor, bool AllowExplicit = false);
|
|
|
|
bool PerformImplicitConversion(Expr *&From, QualType ToType,
|
|
|
|
const ImplicitConversionSequence& ICS,
|
2008-12-20 01:40:08 +08:00
|
|
|
const char *Flavor);
|
2008-10-24 12:54:22 +08:00
|
|
|
bool PerformImplicitConversion(Expr *&From, QualType ToType,
|
2008-12-20 01:40:08 +08:00
|
|
|
const StandardConversionSequence& SCS,
|
|
|
|
const char *Flavor);
|
2007-05-03 05:58:15 +08:00
|
|
|
|
2007-05-09 05:09:37 +08:00
|
|
|
/// the following "Check" methods will return a valid/converted QualType
|
|
|
|
/// or a null QualType (indicating an error diagnostic was issued).
|
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
/// type checking binary operators (subroutines of ActOnBinOp).
|
2007-12-12 13:47:28 +08:00
|
|
|
inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckRemainderOperands( // C99 6.5.5
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckAdditionOperands( // C99 6.5.6
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckSubtractionOperands( // C99 6.5.6
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckShiftOperands( // C99 6.5.7
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
2007-08-26 09:18:55 +08:00
|
|
|
inline QualType CheckCompareOperands( // C99 6.5.8/9
|
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isRelational);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckBitwiseOperands( // C99 6.5.[10...12]
|
2007-08-25 03:07:16 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckLogicalOperands( // C99 6.5.[13,14]
|
2007-07-14 00:58:59 +08:00
|
|
|
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
2007-05-07 08:24:15 +08:00
|
|
|
// CheckAssignmentOperands is used for both simple and compound assignment.
|
|
|
|
// For simple assignment, pass both expressions and a null converted type.
|
|
|
|
// For compound assignment, pass both expressions and the converted type.
|
|
|
|
inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
|
2007-08-25 06:33:52 +08:00
|
|
|
Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
|
Bug #:
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
2007-05-05 05:54:46 +08:00
|
|
|
inline QualType CheckCommaOperands( // C99 6.5.17
|
2008-11-18 09:30:42 +08:00
|
|
|
Expr *lex, Expr *&rex, SourceLocation OpLoc);
|
2007-05-16 04:29:32 +08:00
|
|
|
inline QualType CheckConditionalOperands( // C99 6.5.15
|
2007-07-14 00:58:59 +08:00
|
|
|
Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
|
2008-07-15 02:02:46 +08:00
|
|
|
|
|
|
|
/// type checking for vector binary operators.
|
|
|
|
inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
|
|
|
|
inline QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
|
|
|
|
SourceLocation l, bool isRel);
|
2007-03-31 07:47:58 +08:00
|
|
|
|
2007-09-16 11:34:24 +08:00
|
|
|
/// type checking unary operators (subroutines of ActOnUnaryOp).
|
2007-05-28 07:58:33 +08:00
|
|
|
/// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
|
2008-12-20 17:35:34 +08:00
|
|
|
QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
|
|
|
|
bool isInc);
|
2007-05-19 06:53:50 +08:00
|
|
|
QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
|
|
|
|
QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
|
2007-08-25 05:41:10 +08:00
|
|
|
QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc);
|
2007-07-28 06:15:19 +08:00
|
|
|
|
|
|
|
/// type checking primary expressions.
|
2008-04-19 07:10:10 +08:00
|
|
|
QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
|
2007-07-28 06:15:19 +08:00
|
|
|
IdentifierInfo &Comp, SourceLocation CmpLoc);
|
|
|
|
|
2007-09-02 10:04:30 +08:00
|
|
|
/// type checking declaration initializers (C99 6.7.8)
|
2008-05-02 06:18:59 +08:00
|
|
|
friend class InitListChecker;
|
2008-11-05 23:29:30 +08:00
|
|
|
bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType,
|
2009-01-14 23:45:31 +08:00
|
|
|
SourceLocation InitLoc,DeclarationName InitEntity,
|
|
|
|
bool DirectInit);
|
|
|
|
bool CheckSingleInitializer(Expr *&simpleInit, QualType declType,
|
|
|
|
bool DirectInit);
|
2008-01-11 06:15:12 +08:00
|
|
|
bool CheckForConstantInitializer(Expr *e, QualType t);
|
2008-05-20 21:48:25 +08:00
|
|
|
bool CheckArithmeticConstantExpression(const Expr* e);
|
|
|
|
bool CheckAddressConstantExpression(const Expr* e);
|
|
|
|
bool CheckAddressConstantExpressionLValue(const Expr* e);
|
2008-10-27 19:34:16 +08:00
|
|
|
void InitializerElementNotConstant(const Expr *e);
|
2007-12-11 06:44:33 +08:00
|
|
|
|
2008-01-22 08:55:40 +08:00
|
|
|
StringLiteral *IsStringLiteralInit(Expr *Init, QualType DeclType);
|
|
|
|
bool CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT);
|
2008-08-17 04:27:34 +08:00
|
|
|
|
2008-10-29 08:13:59 +08:00
|
|
|
// type checking C++ declaration initializers (C++ [dcl.init]).
|
|
|
|
|
|
|
|
/// ReferenceCompareResult - Expresses the result of comparing two
|
|
|
|
/// types (cv1 T1 and cv2 T2) to determine their compatibility for the
|
|
|
|
/// purposes of initialization by reference (C++ [dcl.init.ref]p4).
|
|
|
|
enum ReferenceCompareResult {
|
|
|
|
/// Ref_Incompatible - The two types are incompatible, so direct
|
|
|
|
/// reference binding is not possible.
|
|
|
|
Ref_Incompatible = 0,
|
|
|
|
/// Ref_Related - The two types are reference-related, which means
|
|
|
|
/// that their unqualified forms (T1 and T2) are either the same
|
|
|
|
/// or T1 is a base class of T2.
|
|
|
|
Ref_Related,
|
|
|
|
/// Ref_Compatible_With_Added_Qualification - The two types are
|
|
|
|
/// reference-compatible with added qualification, meaning that
|
|
|
|
/// they are reference-compatible and the qualifiers on T1 (cv1)
|
|
|
|
/// are greater than the qualifiers on T2 (cv2).
|
|
|
|
Ref_Compatible_With_Added_Qualification,
|
|
|
|
/// Ref_Compatible - The two types are reference-compatible and
|
|
|
|
/// have equivalent qualifiers (cv1 == cv2).
|
|
|
|
Ref_Compatible
|
|
|
|
};
|
|
|
|
|
2008-10-29 10:00:59 +08:00
|
|
|
ReferenceCompareResult CompareReferenceRelationship(QualType T1, QualType T2,
|
|
|
|
bool& DerivedToBase);
|
2008-10-29 08:13:59 +08:00
|
|
|
|
|
|
|
bool CheckReferenceInit(Expr *&simpleInit_or_initList, QualType &declType,
|
2008-11-04 03:09:14 +08:00
|
|
|
ImplicitConversionSequence *ICS = 0,
|
2009-01-14 23:45:31 +08:00
|
|
|
bool SuppressUserConversions = false,
|
|
|
|
bool AllowExplicit = false);
|
2008-10-29 08:13:59 +08:00
|
|
|
|
2008-08-17 04:27:34 +08:00
|
|
|
/// CheckCastTypes - Check type constraints for casting between types.
|
2008-08-20 11:55:42 +08:00
|
|
|
bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr);
|
2008-01-22 08:55:40 +08:00
|
|
|
|
2007-11-27 15:16:40 +08:00
|
|
|
// CheckVectorCast - check type constraints for vectors.
|
|
|
|
// Since vectors are an extension, there are no C standard reference for this.
|
|
|
|
// We allow casting between vectors and integer datatypes of the same size.
|
2007-11-27 13:51:55 +08:00
|
|
|
// returns true if the cast is invalid
|
|
|
|
bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
|
|
|
|
|
2008-09-11 08:01:56 +08:00
|
|
|
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
|
|
|
|
/// \param Method - May be null.
|
|
|
|
/// \param [out] ReturnType - The return type of the send.
|
|
|
|
/// \return true iff there were any incompatible types.
|
2008-09-11 08:50:25 +08:00
|
|
|
bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
|
2008-11-24 11:33:13 +08:00
|
|
|
ObjCMethodDecl *Method, bool isClassMessage,
|
2008-09-11 08:01:56 +08:00
|
|
|
SourceLocation lbrac, SourceLocation rbrac,
|
|
|
|
QualType &ReturnType);
|
2008-09-10 10:17:11 +08:00
|
|
|
|
|
|
|
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
|
|
|
|
bool CheckCXXBooleanCondition(Expr *&CondExpr);
|
2007-10-17 07:12:48 +08:00
|
|
|
|
2007-08-23 13:46:52 +08:00
|
|
|
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
|
|
|
|
/// the specified width and sign. If an overflow occurs, detect it and emit
|
|
|
|
/// the specified diagnostic.
|
|
|
|
void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
|
|
|
|
unsigned NewWidth, bool NewSign,
|
|
|
|
SourceLocation Loc, unsigned DiagID);
|
|
|
|
|
2008-04-07 13:30:13 +08:00
|
|
|
bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
|
|
|
|
bool ForCompare);
|
|
|
|
|
2008-11-05 00:57:32 +08:00
|
|
|
/// Checks that the Objective-C declaration is declared in the global scope.
|
|
|
|
/// Emits an error and marks the declaration as invalid if it's not declared
|
|
|
|
/// in the global scope.
|
|
|
|
bool CheckObjCDeclScope(Decl *D);
|
|
|
|
|
2007-10-16 04:28:48 +08:00
|
|
|
void InitBuiltinVaListType();
|
2008-06-04 05:01:11 +08:00
|
|
|
|
2008-12-01 03:50:32 +08:00
|
|
|
/// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
|
|
|
|
/// and reports the appropriate diagnostics. Returns false on success.
|
|
|
|
/// Can optionally return the value of the expression.
|
2008-12-07 04:33:04 +08:00
|
|
|
bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
|
2008-12-01 10:17:22 +08:00
|
|
|
|
2008-12-07 04:33:04 +08:00
|
|
|
/// VerifyBitField - verifies that a bit field expression is an ICE and has
|
|
|
|
/// the correct width, and that the field type is valid.
|
|
|
|
/// Returns false on success.
|
|
|
|
bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
|
|
|
|
QualType FieldTy, const Expr *BitWidth);
|
2009-01-19 08:08:26 +08:00
|
|
|
|
2007-08-11 04:18:51 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Extra semantic analysis beyond the C type system
|
2007-12-28 13:29:59 +08:00
|
|
|
private:
|
2009-01-19 08:08:26 +08:00
|
|
|
Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl,
|
|
|
|
CallExpr *TheCall);
|
2007-12-28 13:29:59 +08:00
|
|
|
bool CheckBuiltinCFStringArgument(Expr* Arg);
|
|
|
|
bool SemaBuiltinVAStart(CallExpr *TheCall);
|
|
|
|
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
|
2008-05-20 16:23:37 +08:00
|
|
|
bool SemaBuiltinStackAddress(CallExpr *TheCall);
|
2009-01-19 08:08:26 +08:00
|
|
|
Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
|
2008-07-22 06:59:13 +08:00
|
|
|
bool SemaBuiltinPrefetch(CallExpr *TheCall);
|
2008-09-04 05:13:56 +08:00
|
|
|
bool SemaBuiltinObjectSize(CallExpr *TheCall);
|
2009-01-13 07:09:09 +08:00
|
|
|
bool SemaCheckStringLiteral(Expr *E, CallExpr *TheCall, bool HasVAListArg,
|
|
|
|
unsigned format_idx);
|
|
|
|
void CheckPrintfString(StringLiteral *FExpr, Expr *OrigFormatExpr,
|
|
|
|
CallExpr *TheCall, bool HasVAListArg,
|
|
|
|
unsigned format_idx);
|
2007-12-28 13:29:59 +08:00
|
|
|
void CheckPrintfArguments(CallExpr *TheCall,
|
|
|
|
bool HasVAListArg, unsigned format_idx);
|
2007-08-18 00:46:58 +08:00
|
|
|
void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
|
|
|
|
SourceLocation ReturnLoc);
|
2007-11-25 08:58:00 +08:00
|
|
|
void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
|
2006-11-03 14:42:29 +08:00
|
|
|
};
|
|
|
|
|
2008-05-02 06:18:59 +08:00
|
|
|
class InitListChecker {
|
|
|
|
Sema *SemaRef;
|
|
|
|
bool hadError;
|
|
|
|
|
|
|
|
void CheckImplicitInitList(InitListExpr *ParentIList, QualType T,
|
|
|
|
unsigned &Index);
|
2008-05-06 08:23:44 +08:00
|
|
|
void CheckExplicitInitList(InitListExpr *IList, QualType &T,
|
2008-05-02 06:18:59 +08:00
|
|
|
unsigned &Index);
|
|
|
|
|
2008-05-20 03:16:24 +08:00
|
|
|
void CheckListElementTypes(InitListExpr *IList, QualType &DeclType,
|
2009-01-23 07:26:18 +08:00
|
|
|
bool SubobjectIsDesignatorContext,
|
2008-05-20 03:16:24 +08:00
|
|
|
unsigned &Index);
|
|
|
|
void CheckSubElementType(InitListExpr *IList, QualType ElemType,
|
2009-01-22 08:58:24 +08:00
|
|
|
Expr *expr, unsigned &Index);
|
2008-05-02 06:18:59 +08:00
|
|
|
// FIXME: Does DeclType need to be a reference type?
|
|
|
|
void CheckScalarType(InitListExpr *IList, QualType &DeclType,
|
2009-01-22 08:58:24 +08:00
|
|
|
Expr *expr, unsigned &Index);
|
2008-05-02 06:18:59 +08:00
|
|
|
void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index);
|
|
|
|
void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType,
|
2009-01-23 07:26:18 +08:00
|
|
|
RecordDecl::field_iterator Field,
|
|
|
|
bool SubobjectIsDesignatorContext, unsigned &Index);
|
|
|
|
void CheckArrayType(InitListExpr *IList, QualType &DeclType,
|
|
|
|
llvm::APSInt elementIndex,
|
|
|
|
bool SubobjectIsDesignatorContext, unsigned &Index);
|
2009-01-22 08:58:24 +08:00
|
|
|
bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE,
|
2009-01-23 07:26:18 +08:00
|
|
|
DesignatedInitExpr::designators_iterator D,
|
|
|
|
QualType &CurrentObjectType,
|
|
|
|
RecordDecl::field_iterator *NextField,
|
|
|
|
llvm::APSInt *NextElementIndex,
|
|
|
|
unsigned &Index);
|
2008-05-02 06:18:59 +08:00
|
|
|
int numArrayElements(QualType DeclType);
|
|
|
|
int numStructUnionElements(QualType DeclType);
|
|
|
|
public:
|
|
|
|
InitListChecker(Sema *S, InitListExpr *IL, QualType &T);
|
|
|
|
bool HadError() { return hadError; }
|
|
|
|
};
|
|
|
|
|
2008-09-04 02:15:37 +08:00
|
|
|
/// BlockSemaInfo - When a block is being parsed, this contains information
|
|
|
|
/// about the block. It is pointed to from Sema::CurBlock.
|
|
|
|
struct BlockSemaInfo {
|
|
|
|
llvm::SmallVector<ParmVarDecl*, 8> Params;
|
|
|
|
bool hasPrototype;
|
|
|
|
bool isVariadic;
|
|
|
|
|
2008-10-09 02:44:00 +08:00
|
|
|
BlockDecl *TheDecl;
|
|
|
|
|
2008-09-04 02:15:37 +08:00
|
|
|
/// TheScope - This is the scope for the block itself, which contains
|
|
|
|
/// arguments etc.
|
|
|
|
Scope *TheScope;
|
|
|
|
|
|
|
|
/// ReturnType - This will get set to block result type, by looking at
|
|
|
|
/// return types, if any, in the block body.
|
|
|
|
Type *ReturnType;
|
|
|
|
|
|
|
|
/// PrevBlockInfo - If this is nested inside another block, this points
|
|
|
|
/// to the outer block.
|
|
|
|
BlockSemaInfo *PrevBlockInfo;
|
|
|
|
};
|
|
|
|
|
2006-11-03 14:42:29 +08:00
|
|
|
|
|
|
|
} // end namespace clang
|
|
|
|
|
|
|
|
#endif
|