blob: 5ec5fa7ede494e21223f8c13c2a2b5bffd879259 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the actions class which performs semantic analysis and
11// builds an AST out of a parse stream.
12//
13//===----------------------------------------------------------------------===//
14
15#include "Sema.h"
16#include "clang/AST/ASTContext.h"
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Basic/Diagnostic.h"
Steve Naroffae84af82007-10-31 18:42:27 +000019#include "clang/Parse/Scope.h"
Chris Lattner2e64c072007-08-10 20:18:51 +000020
Chris Lattner4b009652007-07-25 00:24:17 +000021using namespace clang;
22
Steve Naroffae84af82007-10-31 18:42:27 +000023bool Sema::isBuiltinObjcType(TypedefDecl *TD) {
24 const char *typeName = TD->getIdentifier()->getName();
25 return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 ||
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +000026 strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0;
Steve Naroffae84af82007-10-31 18:42:27 +000027}
28
Steve Naroff9637a9b2007-10-09 22:01:59 +000029void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
30 TUScope = S;
Steve Naroffae84af82007-10-31 18:42:27 +000031 if (PP.getLangOptions().ObjC1) {
32 TypedefType *t;
Chris Lattner77470dc2007-10-30 20:57:56 +000033
Steve Naroffae84af82007-10-31 18:42:27 +000034 // Add the built-in ObjC types.
35 t = dyn_cast<TypedefType>(Context.getObjcIdType().getTypePtr());
36 t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
37 TUScope->AddDecl(t->getDecl());
38 t = dyn_cast<TypedefType>(Context.getObjcClassType().getTypePtr());
39 t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
40 TUScope->AddDecl(t->getDecl());
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +000041 ObjcInterfaceType *it = dyn_cast<ObjcInterfaceType>(Context.getObjcProtoType());
42 ObjcInterfaceDecl *IDecl = it->getDecl();
43 IDecl->getIdentifier()->setFETokenInfo(IDecl);
44 TUScope->AddDecl(IDecl);
Steve Naroffae84af82007-10-31 18:42:27 +000045 t = dyn_cast<TypedefType>(Context.getObjcSelType().getTypePtr());
46 t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
47 TUScope->AddDecl(t->getDecl());
Steve Naroffee1de132007-10-10 21:53:07 +000048 }
Steve Naroffee1de132007-10-10 21:53:07 +000049}
50
Steve Naroffca44ffd2007-11-29 23:05:20 +000051Sema::Sema(Preprocessor &pp, ASTContext &ctxt)
Anders Carlssonc9225262007-11-30 20:01:38 +000052 : PP(pp), Context(ctxt), CurFunctionDecl(0), CurMethodDecl(0) {
Chris Lattner2e64c072007-08-10 20:18:51 +000053
54 // Get IdentifierInfo objects for known functions for which we
55 // do extra checking.
56 IdentifierTable& IT = PP.getIdentifierTable();
57
58 KnownFunctionIDs[ id_printf ] = &IT.get("printf");
59 KnownFunctionIDs[ id_fprintf ] = &IT.get("fprintf");
60 KnownFunctionIDs[ id_sprintf ] = &IT.get("sprintf");
61 KnownFunctionIDs[ id_snprintf ] = &IT.get("snprintf");
Chris Lattner2e64c072007-08-10 20:18:51 +000062 KnownFunctionIDs[ id_asprintf ] = &IT.get("asprintf");
Ted Kremenek2d7e9532007-08-10 21:13:51 +000063 KnownFunctionIDs[ id_vsnprintf ] = &IT.get("vsnprintf");
Chris Lattner2e64c072007-08-10 20:18:51 +000064 KnownFunctionIDs[ id_vasprintf ] = &IT.get("vasprintf");
65 KnownFunctionIDs[ id_vfprintf ] = &IT.get("vfprintf");
66 KnownFunctionIDs[ id_vsprintf ] = &IT.get("vsprintf");
67 KnownFunctionIDs[ id_vprintf ] = &IT.get("vprintf");
Steve Naroffae84af82007-10-31 18:42:27 +000068
69 if (PP.getLangOptions().ObjC1) {
70 // Synthesize "typedef struct objc_class *Class;"
71 RecordDecl *ClassTag = new RecordDecl(Decl::Struct, SourceLocation(),
72 &IT.get("objc_class"), 0);
73 QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
74 TypedefDecl *ClassTypedef = new TypedefDecl(SourceLocation(),
75 &Context.Idents.get("Class"),
76 ClassT, 0);
77 Context.setObjcClassType(ClassTypedef);
78
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +000079 // Synthesize "@class Protocol;
80 ObjcInterfaceDecl *ProtocolDecl = new ObjcInterfaceDecl(SourceLocation(), 0,
81 &Context.Idents.get("Protocol"), true);
82 Context.setObjcProtoType(Context.getObjcInterfaceType(ProtocolDecl));
83
Steve Naroffae84af82007-10-31 18:42:27 +000084 // Synthesize "typedef struct objc_object { Class isa; } *id;"
85 RecordDecl *ObjectTag = new RecordDecl(Decl::Struct, SourceLocation(),
86 &IT.get("objc_object"), 0);
87 FieldDecl *IsaDecl = new FieldDecl(SourceLocation(), 0,
88 Context.getObjcClassType());
89 ObjectTag->defineBody(&IsaDecl, 1);
90 QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
91 TypedefDecl *IdTypedef = new TypedefDecl(SourceLocation(),
92 &Context.Idents.get("id"),
93 ObjT, 0);
94 Context.setObjcIdType(IdTypedef);
95
96 // Synthesize "typedef struct objc_selector *SEL;"
97 RecordDecl *SelTag = new RecordDecl(Decl::Struct, SourceLocation(),
98 &IT.get("objc_selector"), 0);
99 QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
100 TypedefDecl *SelTypedef = new TypedefDecl(SourceLocation(),
101 &Context.Idents.get("SEL"),
102 SelT, 0);
103 Context.setObjcSelType(SelTypedef);
Fariborz Jahanianb4452ed2007-12-07 00:18:54 +0000104
Steve Naroffae84af82007-10-31 18:42:27 +0000105 }
Steve Naroffee1de132007-10-10 21:53:07 +0000106 TUScope = 0;
Chris Lattner4b009652007-07-25 00:24:17 +0000107}
108
Chris Lattnerb26b7ad2007-08-31 04:53:24 +0000109void Sema::DeleteExpr(ExprTy *E) {
110 delete static_cast<Expr*>(E);
111}
112void Sema::DeleteStmt(StmtTy *S) {
113 delete static_cast<Stmt*>(S);
114}
115
Chris Lattner4b009652007-07-25 00:24:17 +0000116//===----------------------------------------------------------------------===//
117// Helper functions.
118//===----------------------------------------------------------------------===//
119
120bool Sema::Diag(SourceLocation Loc, unsigned DiagID) {
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000121 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager());
Chris Lattner4b009652007-07-25 00:24:17 +0000122 return true;
123}
124
125bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000126 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager(), &Msg, 1);
Chris Lattner4b009652007-07-25 00:24:17 +0000127 return true;
128}
129
130bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
131 const std::string &Msg2) {
132 std::string MsgArr[] = { Msg1, Msg2 };
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000133 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager(), MsgArr, 2);
Chris Lattner4b009652007-07-25 00:24:17 +0000134 return true;
135}
136
137bool Sema::Diag(SourceLocation Loc, unsigned DiagID, SourceRange Range) {
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000138 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager(), 0,0, &Range,1);
Chris Lattner4b009652007-07-25 00:24:17 +0000139 return true;
140}
141
142bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
143 SourceRange Range) {
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000144 PP.getDiagnostics().Report(Loc,DiagID,PP.getSourceManager(),&Msg,1,&Range,1);
Chris Lattner4b009652007-07-25 00:24:17 +0000145 return true;
146}
147
148bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg1,
149 const std::string &Msg2, SourceRange Range) {
150 std::string MsgArr[] = { Msg1, Msg2 };
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000151 PP.getDiagnostics().Report(Loc,DiagID,PP.getSourceManager(),
152 MsgArr,2,&Range,1);
Chris Lattner4b009652007-07-25 00:24:17 +0000153 return true;
154}
155
156bool Sema::Diag(SourceLocation Loc, unsigned DiagID,
157 SourceRange R1, SourceRange R2) {
158 SourceRange RangeArr[] = { R1, R2 };
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000159 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager(),
160 0, 0, RangeArr, 2);
Chris Lattner4b009652007-07-25 00:24:17 +0000161 return true;
162}
163
164bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
165 SourceRange R1, SourceRange R2) {
166 SourceRange RangeArr[] = { R1, R2 };
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000167 PP.getDiagnostics().Report(Loc, DiagID, PP.getSourceManager(), &Msg,
168 1, RangeArr, 2);
Chris Lattner4b009652007-07-25 00:24:17 +0000169 return true;
170}
171
172bool Sema::Diag(SourceLocation Range, unsigned DiagID, const std::string &Msg1,
173 const std::string &Msg2, SourceRange R1, SourceRange R2) {
174 std::string MsgArr[] = { Msg1, Msg2 };
175 SourceRange RangeArr[] = { R1, R2 };
Ted Kremenekb3ee1932007-12-11 21:27:55 +0000176 PP.getDiagnostics().Report(Range, DiagID, PP.getSourceManager(), MsgArr, 2,
177 RangeArr, 2);
Chris Lattner4b009652007-07-25 00:24:17 +0000178 return true;
179}
180
181const LangOptions &Sema::getLangOptions() const {
182 return PP.getLangOptions();
183}