aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-03-15 23:59:48 +0000
committerChris Lattner <sabre@nondot.org>2008-03-15 23:59:48 +0000
commitbda0b626e74513950405c27525af87e214e605e2 (patch)
tree60149b18fd68ccc1281c62fe4387b5a1da39a5fa /lib/Sema
parentfbdeba1c530dc3534a6f5b788e43d1a43c260128 (diff)
Make a major restructuring of the clang tree: introduce a top-level
lib dir and move all the libraries into it. This follows the main llvm tree, and allows the libraries to be built in parallel. The top level now enforces that all the libs are built before Driver, but we don't care what order the libs are built in. This speeds up parallel builds, particularly incremental ones. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48402 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Makefile23
-rw-r--r--lib/Sema/ParseAST.cpp69
-rw-r--r--lib/Sema/Sema.cpp222
-rw-r--r--lib/Sema/Sema.h823
-rw-r--r--lib/Sema/SemaChecking.cpp802
-rw-r--r--lib/Sema/SemaDecl.cpp2297
-rw-r--r--lib/Sema/SemaDeclObjC.cpp927
-rw-r--r--lib/Sema/SemaExpr.cpp2286
-rw-r--r--lib/Sema/SemaExprCXX.cpp51
-rw-r--r--lib/Sema/SemaExprObjC.cpp297
-rw-r--r--lib/Sema/SemaStmt.cpp821
-rw-r--r--lib/Sema/SemaType.cpp498
-rw-r--r--lib/Sema/SemaUtil.h35
13 files changed, 9151 insertions, 0 deletions
diff --git a/lib/Sema/Makefile b/lib/Sema/Makefile
new file mode 100644
index 0000000000..19a00275f0
--- /dev/null
+++ b/lib/Sema/Makefile
@@ -0,0 +1,23 @@
+##===- clang/lib/Sema/Makefile -----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This implements the semantic analyzer and AST builder library for the
+# C-Language front-end.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../../..
+LIBRARYNAME := clangSEMA
+BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
new file mode 100644
index 0000000000..364b072910
--- /dev/null
+++ b/lib/Sema/ParseAST.cpp
@@ -0,0 +1,69 @@
+//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the clang::ParseAST method.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/ParseAST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "Sema.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/Parser.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Public interface to the file
+//===----------------------------------------------------------------------===//
+
+/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
+/// the file is parsed. This takes ownership of the ASTConsumer and
+/// ultimately deletes it.
+void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, bool PrintStats) {
+ // Collect global stats on Decls/Stmts (until we have a module streamer).
+ if (PrintStats) {
+ Decl::CollectingStats(true);
+ Stmt::CollectingStats(true);
+ }
+
+ ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(),
+ PP.getIdentifierTable(), PP.getSelectorTable());
+
+ Parser P(PP, *new Sema(PP, Context, *Consumer));
+ PP.EnterMainSourceFile();
+
+ // Initialize the parser.
+ P.Initialize();
+
+ Consumer->Initialize(Context);
+
+ Parser::DeclTy *ADecl;
+ while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
+ // If we got a null return and something *was* parsed, ignore it. This
+ // is due to a top-level semicolon, an action override, or a parse error
+ // skipping something.
+ if (ADecl)
+ Consumer->HandleTopLevelDecl(static_cast<Decl*>(ADecl));
+ };
+
+ if (PrintStats) {
+ fprintf(stderr, "\nSTATISTICS:\n");
+ P.getActions().PrintStats();
+ Context.PrintStats();
+ Decl::PrintStats();
+ Stmt::PrintStats();
+ Consumer->PrintStats();
+
+ Decl::CollectingStats(false);
+ Stmt::CollectingStats(false);
+ }
+
+ delete Consumer;
+}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
new file mode 100644
index 0000000000..4bd04e3a1a
--- /dev/null
+++ b/lib/Sema/Sema.cpp
@@ -0,0 +1,222 @@
+//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the actions class which performs semantic analysis and
+// builds an AST out of a parse stream.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Parse/Scope.h"
+
+using namespace clang;
+
+bool Sema::isBuiltinObjCType(TypedefDecl *TD) {
+ const char *typeName = TD->getIdentifier()->getName();
+ return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 ||
+ strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0;
+}
+
+bool Sema::isObjCObjectPointerType(QualType type) const {
+ if (!type->isPointerType() && !type->isObjCQualifiedIdType())
+ return false;
+ if (type == Context.getObjCIdType() || type == Context.getObjCClassType() ||
+ type->isObjCQualifiedIdType())
+ return true;
+
+ if (type->isPointerType()) {
+ PointerType *pointerType = static_cast<PointerType*>(type.getTypePtr());
+ type = pointerType->getPointeeType();
+ }
+ return (type->isObjCInterfaceType() || type->isObjCQualifiedIdType());
+}
+
+void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+ TUScope = S;
+ if (!PP.getLangOptions().ObjC1) return;
+
+ TypedefType *t;
+
+ // Add the built-in ObjC types.
+ t = cast<TypedefType>(Context.getObjCIdType().getTypePtr());
+ t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
+ TUScope->AddDecl(t->getDecl());
+ t = cast<TypedefType>(Context.getObjCClassType().getTypePtr());
+ t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
+ TUScope->AddDecl(t->getDecl());
+ ObjCInterfaceType *it = cast<ObjCInterfaceType>(Context.getObjCProtoType());
+ ObjCInterfaceDecl *IDecl = it->getDecl();
+ IDecl->getIdentifier()->setFETokenInfo(IDecl);
+ TUScope->AddDecl(IDecl);
+
+ // Synthesize "typedef struct objc_selector *SEL;"
+ RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct,
+ SourceLocation(),
+ &Context.Idents.get("objc_selector"),
+ 0);
+ SelTag->getIdentifier()->setFETokenInfo(SelTag);
+ TUScope->AddDecl(SelTag);
+
+ QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
+ TypedefDecl *SelTypedef = TypedefDecl::Create(Context, SourceLocation(),
+ &Context.Idents.get("SEL"),
+ SelT, 0);
+ SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef);
+ TUScope->AddDecl(SelTypedef);
+ Context.setObjCSelType(SelTypedef);
+}
+
+Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
+ : PP(pp), Context(ctxt), Consumer(consumer),
+ CurFunctionDecl(0), CurMethodDecl(0) {
+
+ // Get IdentifierInfo objects for known functions for which we
+ // do extra checking.
+ IdentifierTable &IT = PP.getIdentifierTable();
+
+ KnownFunctionIDs[id_printf] = &IT.get("printf");
+ KnownFunctionIDs[id_fprintf] = &IT.get("fprintf");
+ KnownFunctionIDs[id_sprintf] = &IT.get("sprintf");
+ KnownFunctionIDs[id_snprintf] = &IT.get("snprintf");
+ KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
+ KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
+ KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf");
+ KnownFunctionIDs[id_vfprintf] = &IT.get("vfprintf");
+ KnownFunctionIDs[id_vsprintf] = &IT.get("vsprintf");
+ KnownFunctionIDs[id_vprintf] = &IT.get("vprintf");
+
+ // FIXME: Move this initialization up to Sema::ActOnTranslationUnitScope()
+ // and make sure the decls get inserted into TUScope!
+ if (PP.getLangOptions().ObjC1) {
+ // Synthesize "typedef struct objc_class *Class;"
+ RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
+ SourceLocation(),
+ &IT.get("objc_class"), 0);
+ QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
+ TypedefDecl *ClassTypedef =
+ TypedefDecl::Create(Context, SourceLocation(),
+ &Context.Idents.get("Class"), ClassT, 0);
+ Context.setObjCClassType(ClassTypedef);
+
+ // Synthesize "@class Protocol;
+ ObjCInterfaceDecl *ProtocolDecl = new ObjCInterfaceDecl(SourceLocation(), 0,
+ &Context.Idents.get("Protocol"), true);
+ Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
+
+ // Synthesize "typedef struct objc_object { Class isa; } *id;"
+ RecordDecl *ObjectTag =
+ RecordDecl::Create(Context, Decl::Struct, SourceLocation(),
+ &IT.get("objc_object"), 0);
+ FieldDecl *IsaDecl = new FieldDecl(SourceLocation(), 0,
+ Context.getObjCClassType());
+ ObjectTag->defineBody(&IsaDecl, 1);
+ QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
+ TypedefDecl *IdTypedef = TypedefDecl::Create(Context, SourceLocation(),
+ &Context.Idents.get("id"),
+ ObjT, 0);
+ Context.setObjCIdType(IdTypedef);
+ }
+ TUScope = 0;
+}
+
+/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
+/// If there is already an implicit cast, merge into the existing one.
+void Sema::ImpCastExprToType(Expr *&Expr, QualType Type) {
+ if (Expr->getType().getCanonicalType() == Type.getCanonicalType()) return;
+
+ if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr))
+ ImpCast->setType(Type);
+ else
+ Expr = new ImplicitCastExpr(Type, Expr);
+}
+
+
+
+void Sema::DeleteExpr(ExprTy *E) {
+ delete static_cast<Expr*>(E);
+}
+void Sema::DeleteStmt(StmtTy *S) {
+ delete static_cast<Stmt*>(S);
+}
+
+//===----------------------------------------------------------------------===//
+// Helper functions.
+//===----------------------------------------------------------------------===//
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID) {
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2) {
+ std::string MsgArr[] = { Msg1, Msg2 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, SourceRange Range) {
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, &Range,1);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
+ SourceRange Range) {
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, &Range,1);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2, SourceRange Range) {
+ std::string MsgArr[] = { Msg1, Msg2 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 2, &Range, 1);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2, const std::string &Msg3,
+ SourceRange R1) {
+ std::string MsgArr[] = { Msg1, Msg2, Msg3 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, MsgArr, 3, &R1, 1);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID,
+ SourceRange R1, SourceRange R2) {
+ SourceRange RangeArr[] = { R1, R2 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, 0, 0, RangeArr, 2);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
+ SourceRange R1, SourceRange R2) {
+ SourceRange RangeArr[] = { R1, R2 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Loc), DiagID, &Msg, 1, RangeArr, 2);
+ return true;
+}
+
+bool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2, SourceRange R1, SourceRange R2) {
+ std::string MsgArr[] = { Msg1, Msg2 };
+ SourceRange RangeArr[] = { R1, R2 };
+ PP.getDiagnostics().Report(PP.getFullLoc(Range),DiagID, MsgArr,2,RangeArr, 2);
+ return true;
+}
+
+const LangOptions &Sema::getLangOptions() const {
+ return PP.getLangOptions();
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
new file mode 100644
index 0000000000..fc81781911
--- /dev/null
+++ b/lib/Sema/Sema.h
@@ -0,0 +1,823 @@
+//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Sema class, which performs semantic analysis and
+// builds ASTs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_SEMA_H
+#define LLVM_CLANG_AST_SEMA_H
+
+#include "clang/Parse/Action.h"
+#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
+#include <string>
+
+namespace llvm {
+ class APSInt;
+}
+
+namespace clang {
+ class ASTContext;
+ class ASTConsumer;
+ class Preprocessor;
+ class Decl;
+ class ScopedDecl;
+ class Expr;
+ class InitListExpr;
+ class CallExpr;
+ class VarDecl;
+ class ParmVarDecl;
+ class TypedefDecl;
+ class FunctionDecl;
+ class QualType;
+ struct LangOptions;
+ class Token;
+ class IntegerLiteral;
+ class StringLiteral;
+ class ArrayType;
+ class LabelStmt;
+ class SwitchStmt;
+ class OCUVectorType;
+ class TypedefDecl;
+ class ObjCInterfaceDecl;
+ class ObjCProtocolDecl;
+ class ObjCImplementationDecl;
+ class ObjCCategoryImplDecl;
+ class ObjCCategoryDecl;
+ class ObjCIvarDecl;
+ class ObjCMethodDecl;
+
+/// Sema - This implements semantic analysis and AST building for C.
+class Sema : public Action {
+ Preprocessor &PP;
+ ASTContext &Context;
+ ASTConsumer &Consumer;
+
+ /// CurFunctionDecl - If inside of a function body, this contains a pointer to
+ /// the function decl for the function being parsed.
+ FunctionDecl *CurFunctionDecl;
+
+ /// CurMethodDecl - If inside of a method body, this contains a pointer to
+ /// the method decl for the method being parsed.
+ ObjCMethodDecl *CurMethodDecl;
+
+ /// 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.
+ llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+
+ llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
+
+ /// OCUVectorDecls - This is a list all the OCU vector types. This allows
+ /// us to associate a raw vector type with one of the OCU type names.
+ /// This is only necessary for issuing pretty diagnostics.
+ llvm::SmallVector<TypedefDecl*, 24> OCUVectorDecls;
+
+ /// ObjCImplementations - Keep track of all of the classes with
+ /// @implementation's, so that we can emit errors on duplicates.
+ llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
+
+ /// ObjCProtocols - Keep track of all protocol declarations declared
+ /// with @protocol keyword, so that we can emit errors on duplicates and
+ /// find the declarations when needed.
+ llvm::DenseMap<IdentifierInfo*, ObjCProtocolDecl*> ObjCProtocols;
+
+ // Enum values used by KnownFunctionIDs (see below).
+ enum {
+ id_printf,
+ id_fprintf,
+ id_sprintf,
+ id_snprintf,
+ id_asprintf,
+ id_vsnprintf,
+ id_vasprintf,
+ id_vfprintf,
+ id_vsprintf,
+ 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.
+ IdentifierInfo* KnownFunctionIDs[ id_num_known_functions ];
+
+ /// 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.
+ Scope *TUScope;
+
+ /// ObjCMethodList - a linked list of methods with different signatures.
+ struct ObjCMethodList {
+ ObjCMethodDecl *Method;
+ ObjCMethodList *Next;
+
+ ObjCMethodList() {
+ Method = 0;
+ Next = 0;
+ }
+ ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) {
+ 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").
+ llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool;
+ llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;
+public:
+ Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
+
+ const LangOptions &getLangOptions() const;
+
+ /// The primitive diagnostic helpers - always returns true, which simplifies
+ /// error handling (i.e. less code).
+ bool Diag(SourceLocation Loc, unsigned DiagID);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2);
+
+ /// More expressive diagnostic helpers for expressions (say that 6 times:-)
+ bool Diag(SourceLocation Loc, unsigned DiagID, SourceRange R1);
+ bool Diag(SourceLocation Loc, unsigned DiagID,
+ SourceRange R1, SourceRange R2);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
+ SourceRange R1);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
+ SourceRange R1, SourceRange R2);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2, SourceRange R1);
+ bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
+ const std::string &Msg2, const std::string &Msg3, SourceRange R1);
+ bool Diag(SourceLocation Loc, unsigned DiagID,
+ const std::string &Msg1, const std::string &Msg2,
+ SourceRange R1, SourceRange R2);
+
+ virtual void DeleteExpr(ExprTy *E);
+ virtual void DeleteStmt(StmtTy *S);
+
+ //===--------------------------------------------------------------------===//
+ // Type Analysis / Processing: SemaType.cpp.
+ //
+ QualType ConvertDeclSpecToType(DeclSpec &DS);
+ AttributeList *ProcessTypeAttributes(QualType &Result, AttributeList *AL);
+ QualType GetTypeForDeclarator(Declarator &D, Scope *S);
+
+
+ QualType ObjCGetTypeForMethodDefinition(DeclTy *D);
+
+
+ virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
+
+ virtual TypeResult ActOnParamDeclaratorType(Scope *S, Declarator &D);
+private:
+ //===--------------------------------------------------------------------===//
+ // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
+ //
+ virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
+ virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup);
+ void AddInitializerToDecl(DeclTy *dcl, ExprTy *init);
+ virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
+
+ virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
+ virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D);
+
+ virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtTy *Body);
+ virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
+ SourceLocation RBrace, const char *Lang,
+ unsigned StrSize, DeclTy *D);
+ virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprTy *expr);
+
+ /// Scope actions.
+ virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
+ virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
+
+ /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+ /// no declarator (e.g. "struct foo;") is parsed.
+ virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);
+
+ virtual DeclTy *ActOnTag(Scope *S, unsigned TagType, TagKind TK,
+ SourceLocation KWLoc, IdentifierInfo *Name,
+ SourceLocation NameLoc, AttributeList *Attr);
+ virtual DeclTy *ActOnField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth);
+
+ // This is used for both record definitions and ObjC interface declarations.
+ virtual void ActOnFields(Scope* S,
+ SourceLocation RecLoc, DeclTy *TagDecl,
+ DeclTy **Fields, unsigned NumFields,
+ SourceLocation LBrac, SourceLocation RBrac,
+ tok::ObjCKeywordKind *visibility = 0);
+ virtual DeclTy *ActOnEnumConstant(Scope *S, DeclTy *EnumDecl,
+ DeclTy *LastEnumConstant,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ SourceLocation EqualLoc, ExprTy *Val);
+ virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
+ DeclTy **Elements, unsigned NumElements);
+private:
+ /// Subroutines of ActOnDeclarator().
+ TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
+ ScopedDecl *LastDecl);
+ TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *Old);
+ FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old);
+ VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old);
+
+ /// More parsing and symbol table subroutines...
+ ParmVarDecl *ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI,
+ Scope *FnBodyScope);
+ ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
+ SourceLocation IdLoc, Scope *S);
+ ScopedDecl *LookupInterfaceDecl(IdentifierInfo *II);
+ ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
+ ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
+ ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
+ Scope *S);
+ // Decl attributes - this routine is the top level dispatcher.
+ void HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
+ AttributeList *declarator_postfix);
+ void HandleDeclAttribute(Decl *New, AttributeList *rawAttr);
+
+ /// HandleAddressSpaceTypeAttribute - this attribute is only applicable to
+ /// objects without automatic storage duration.
+ /// The raw attribute contains 1 argument, the id of the address space
+ /// for the type.
+ QualType HandleAddressSpaceTypeAttribute(QualType curType,
+ AttributeList *rawAttr);
+
+ // HandleVectorTypeAttribute - this attribute is only applicable to
+ // integral and float scalars, although arrays, pointers, and function
+ // return values are allowed in conjunction with this construct. Aggregates
+ // with this attribute are invalid, even if they are of the same size as a
+ // corresponding scalar.
+ // The raw attribute should contain precisely 1 argument, the vector size
+ // for the variable, measured in bytes. If curType and rawAttr are well
+ // formed, this routine will return a new vector type.
+ QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
+ void HandleOCUVectorTypeAttribute(TypedefDecl *d, AttributeList *rawAttr);
+
+ void HandleAlignedAttribute(Decl *d, AttributeList *rawAttr);
+ void HandlePackedAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleAnnotateAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleNoReturnAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleDeprecatedAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleWeakAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleDLLImportAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleDLLExportAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleVisibilityAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleNothrowAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleFormatAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleStdCallAttribute(Decl *d, AttributeList *rawAttr);
+ void HandleFastCallAttribute(Decl *d, AttributeList *rawAttr);
+
+ void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
+ bool &IncompleteImpl);
+
+ /// CheckProtocolMethodDefs - This routine checks unimpletented methods
+ /// Declared in protocol, and those referenced by it.
+ void CheckProtocolMethodDefs(SourceLocation ImpLoc,
+ ObjCProtocolDecl *PDecl,
+ bool& IncompleteImpl,
+ const llvm::DenseSet<Selector> &InsMap,
+ const llvm::DenseSet<Selector> &ClsMap);
+
+ /// CheckImplementationIvars - This routine checks if the instance variables
+ /// listed in the implelementation match those listed in the interface.
+ void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
+ ObjCIvarDecl **Fields, unsigned nIvars,
+ SourceLocation Loc);
+
+ /// ImplMethodsVsClassMethods - This is main routine to warn if any method
+ /// remains unimplemented in the @implementation class.
+ void ImplMethodsVsClassMethods(ObjCImplementationDecl* IMPDecl,
+ ObjCInterfaceDecl* IDecl);
+
+ /// ImplCategoryMethodsVsIntfMethods - Checks that methods declared in the
+ /// category interface is implemented in the category @implementation.
+ void ImplCategoryMethodsVsIntfMethods(ObjCCategoryImplDecl *CatImplDecl,
+ ObjCCategoryDecl *CatClassDecl);
+ /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
+ /// true, or false, accordingly.
+ bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
+ const ObjCMethodDecl *PrevMethod);
+
+ /// isBuiltinObjCType - Returns true of the type is "id", "SEL", "Class"
+ /// or "Protocol".
+ bool isBuiltinObjCType(TypedefDecl *TD);
+
+ /// isObjCObjectPointerType - Returns true if type is an objective-c pointer
+ /// to an object type; such as "id", "Class", Intf*, id<P>, etc.
+ bool isObjCObjectPointerType(QualType type) const;
+
+ /// 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).
+ void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
+
+ /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
+ void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
+ //===--------------------------------------------------------------------===//
+ // Statement Parsing Callbacks: SemaStmt.cpp.
+public:
+ virtual StmtResult ActOnExprStmt(ExprTy *Expr);
+
+ virtual StmtResult ActOnNullStmt(SourceLocation SemiLoc);
+ virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
+ StmtTy **Elts, unsigned NumElts,
+ bool isStmtExpr);
+ virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
+ SourceLocation DotDotDotLoc, ExprTy *RHSVal,
+ SourceLocation ColonLoc, StmtTy *SubStmt);
+ virtual StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
+ SourceLocation ColonLoc, StmtTy *SubStmt,
+ Scope *CurScope);
+ virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
+ SourceLocation ColonLoc, StmtTy *SubStmt);
+ virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
+ StmtTy *ThenVal, SourceLocation ElseLoc,
+ StmtTy *ElseVal);
+ virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond);
+ virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
+ StmtTy *Switch, ExprTy *Body);
+ virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
+ StmtTy *Body);
+ virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body,
+ SourceLocation WhileLoc, ExprTy *Cond);
+
+ virtual StmtResult ActOnForStmt(SourceLocation ForLoc,
+ SourceLocation LParenLoc,
+ StmtTy *First, ExprTy *Second, ExprTy *Third,
+ SourceLocation RParenLoc, StmtTy *Body);
+ virtual StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
+ SourceLocation LParenLoc,
+ StmtTy *First, ExprTy *Second,
+ SourceLocation RParenLoc, StmtTy *Body);
+
+ virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
+ SourceLocation LabelLoc,
+ IdentifierInfo *LabelII);
+ virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
+ SourceLocation StarLoc,
+ ExprTy *DestExp);
+ virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
+ Scope *CurScope);
+ virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope);
+
+ virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
+ ExprTy *RetValExp);
+
+ virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
+ bool IsSimple,
+ bool IsVolatile,
+ unsigned NumOutputs,
+ unsigned NumInputs,
+ std::string *Names,
+ ExprTy **Constraints,
+ ExprTy **Exprs,
+ ExprTy *AsmString,
+ unsigned NumClobbers,
+ ExprTy **Clobbers,
+ SourceLocation RParenLoc);
+
+ virtual StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
+ SourceLocation RParen, StmtTy *Parm,
+ StmtTy *Body, StmtTy *CatchList);
+
+ virtual StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
+ StmtTy *Body);
+
+ virtual StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
+ StmtTy *Try,
+ StmtTy *Catch, StmtTy *Finally);
+
+ virtual StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
+ StmtTy *Throw);
+ virtual StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
+ ExprTy *SynchExpr,
+ StmtTy *SynchBody);
+
+ //===--------------------------------------------------------------------===//
+ // Expression Parsing Callbacks: SemaExpr.cpp.
+
+ // Primary Expressions.
+ virtual ExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
+ IdentifierInfo &II,
+ bool HasTrailingLParen);
+ virtual ExprResult ActOnPreDefinedExpr(SourceLocation Loc,
+ tok::TokenKind Kind);
+ virtual ExprResult ActOnNumericConstant(const Token &);
+ virtual ExprResult ActOnCharacterConstant(const Token &);
+ virtual ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
+ ExprTy *Val);
+
+ /// ActOnStringLiteral - The specified tokens were lexed as pasted string
+ /// fragments (e.g. "foo" "bar" L"baz").
+ virtual ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks);
+
+ // Binary/Unary Operators. 'Tok' is the token for the operator.
+ virtual ExprResult ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
+ ExprTy *Input);
+ virtual ExprResult
+ ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
+ SourceLocation LParenLoc, TypeTy *Ty,
+ SourceLocation RParenLoc);
+
+ virtual ExprResult ActOnPostfixUnaryOp(SourceLocation OpLoc,
+ tok::TokenKind Kind, ExprTy *Input);
+
+ virtual ExprResult ActOnArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
+ ExprTy *Idx, SourceLocation RLoc);
+ virtual ExprResult ActOnMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation MemberLoc,
+ IdentifierInfo &Member);
+
+ /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
+ /// This provides the location of the left/right parens and a list of comma
+ /// locations.
+ virtual ExprResult ActOnCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
+ ExprTy **Args, unsigned NumArgs,
+ SourceLocation *CommaLocs,