blob: 893ebeab314353e10e9964c7eaa75bbc7e15c88b [file] [log] [blame]
Chris Lattner697e5d62006-11-09 06:32:27 +00001//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
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 semantic analysis for declarations.
11//
12//===----------------------------------------------------------------------===//
13
Chris Lattnere168f762006-11-10 05:29:30 +000014#include "Sema.h"
15#include "clang/AST/Decl.h"
Chris Lattnerf84a79c2006-11-11 22:59:23 +000016#include "clang/AST/Type.h"
Chris Lattnere168f762006-11-10 05:29:30 +000017#include "clang/Parse/Scope.h"
18#include "clang/Lex/IdentifierTable.h"
Chris Lattner697e5d62006-11-09 06:32:27 +000019using namespace llvm;
20using namespace clang;
21
Chris Lattnere168f762006-11-10 05:29:30 +000022
Chris Lattnere168f762006-11-10 05:29:30 +000023bool Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
24 Decl *D = II.getFETokenInfo<Decl>();
Chris Lattnerda8aa7b2006-11-19 23:12:30 +000025
26
27 return D != 0 && isa<TypeDecl>(D);
Chris Lattnere168f762006-11-10 05:29:30 +000028}
29
Chris Lattner302b4be2006-11-19 02:31:38 +000030void Sema::PopScope(SourceLocation Loc, Scope *S) {
31 for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
32 I != E; ++I) {
33 IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
34 Decl *D = II.getFETokenInfo<Decl>();
35 assert(D && "This decl didn't get pushed??");
36
37 Decl *Next = D->getNext();
38
39 // FIXME: Push the decl on the parent function list if in a function.
40 // FIXME: Don't delete the decl when it gets popped!
41 delete D;
42
43 II.setFETokenInfo(Next);
44 }
45}
46
Chris Lattner200bdc32006-11-19 02:43:37 +000047/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
48/// no declarator (e.g. "struct foo;") is parsed.
49Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
50 // TODO: emit error on 'int;' or 'const enum foo;'.
51 // TODO: emit error on 'typedef int;'
52 // if (!DS.isMissingDeclaratorOk()) Diag(...);
53
54 // TODO: Register 'struct foo;' with the type system as an opaque struct.
55
56 // TODO: Check that we don't already have 'union foo;' or something else
57 // that conflicts.
58 return 0;
59}
60
Chris Lattnere168f762006-11-10 05:29:30 +000061Action::DeclTy *
62Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
63 DeclTy *LastInGroup) {
Chris Lattnerf84a79c2006-11-11 22:59:23 +000064 TypeRef DeclaratorType = GetTypeForDeclarator(D, S);
65
Chris Lattnere168f762006-11-10 05:29:30 +000066 IdentifierInfo *II = D.getIdentifier();
Chris Lattner302b4be2006-11-19 02:31:38 +000067 Decl *PrevDecl = 0;
68
69 if (II) {
70 PrevDecl = II->getFETokenInfo<Decl>();
71
72 // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
73 }
Chris Lattnere168f762006-11-10 05:29:30 +000074
75 Decl *New;
Chris Lattner302b4be2006-11-19 02:31:38 +000076 if (D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef) {
77 New = ParseTypedefDecl(S, D, PrevDecl);
78 } else if (D.isFunctionDeclarator())
Chris Lattnerda8aa7b2006-11-19 23:12:30 +000079 New = new FunctionDecl(II, D.getDeclSpec(), PrevDecl);
Chris Lattnere168f762006-11-10 05:29:30 +000080 else
Chris Lattnerda8aa7b2006-11-19 23:12:30 +000081 New = new VarDecl(II, D.getDeclSpec(), PrevDecl);
Chris Lattnere168f762006-11-10 05:29:30 +000082
Chris Lattner302b4be2006-11-19 02:31:38 +000083 if (!New) return 0;
84
85
Chris Lattnere168f762006-11-10 05:29:30 +000086 // If this has an identifier, add it to the scope stack.
87 if (II) {
88 // If PrevDecl includes conflicting name here, emit a diagnostic.
89 II->setFETokenInfo(New);
90 S->AddDecl(II);
91 }
92
93 // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
94 // remember this in the LastInGroupList list.
95 if (LastInGroup && S->getParent() == 0)
96 LastInGroupList.push_back((Decl*)LastInGroup);
97
98 return New;
99}
100
Chris Lattner200bdc32006-11-19 02:43:37 +0000101
102Sema::DeclTy *
Chris Lattnere168f762006-11-10 05:29:30 +0000103Sema::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
104 FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
105
106 FD->setBody((Stmt*)Body);
107
108 return FD;
109}
110
Chris Lattner302b4be2006-11-19 02:31:38 +0000111
112Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, Decl *PrevDecl) {
Chris Lattnerda8aa7b2006-11-19 23:12:30 +0000113 assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
Chris Lattner302b4be2006-11-19 02:31:38 +0000114
Chris Lattnerda8aa7b2006-11-19 23:12:30 +0000115 return new TypedefDecl(D.getIdentifier(), D.getDeclSpec(), PrevDecl);
Chris Lattnere168f762006-11-10 05:29:30 +0000116}
117