diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 35 |
4 files changed, 73 insertions, 38 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index da78ec06787..9e379e4be74 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -59,7 +59,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { TUScope->AddDecl(IDecl); // Synthesize "typedef struct objc_selector *SEL;" - RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, + RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, CurContext, SourceLocation(), &Context.Idents.get("objc_selector"), 0); @@ -67,7 +67,8 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { TUScope->AddDecl(SelTag); QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag)); - TypedefDecl *SelTypedef = TypedefDecl::Create(Context, SourceLocation(), + TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext, + SourceLocation(), &Context.Idents.get("SEL"), SelT, 0); SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef); @@ -77,7 +78,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) : PP(pp), Context(ctxt), Consumer(consumer), - CurFunctionDecl(0), CurMethodDecl(0) { + CurFunctionDecl(0), CurMethodDecl(0), CurContext(0) { // Get IdentifierInfo objects for known functions for which we // do extra checking. @@ -99,11 +100,12 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) if (PP.getLangOptions().ObjC1) { // Synthesize "typedef struct objc_class *Class;" RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct, - SourceLocation(), + NULL, + SourceLocation(), &IT.get("objc_class"), 0); QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag)); TypedefDecl *ClassTypedef = - TypedefDecl::Create(Context, SourceLocation(), + TypedefDecl::Create(Context, NULL, SourceLocation(), &Context.Idents.get("Class"), ClassT, 0); Context.setObjCClassType(ClassTypedef); @@ -115,13 +117,16 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) // Synthesize "typedef struct objc_object { Class isa; } *id;" RecordDecl *ObjectTag = - RecordDecl::Create(Context, Decl::Struct, SourceLocation(), + RecordDecl::Create(Context, Decl::Struct, NULL, + SourceLocation(), &IT.get("objc_object"), 0); - FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0, + FieldDecl *IsaDecl = FieldDecl::Create(Context, ObjectTag, + SourceLocation(), 0, Context.getObjCClassType()); ObjectTag->defineBody(&IsaDecl, 1); QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag)); - TypedefDecl *IdTypedef = TypedefDecl::Create(Context, SourceLocation(), + TypedefDecl *IdTypedef = TypedefDecl::Create(Context, NULL, + SourceLocation(), &Context.Idents.get("id"), ObjT, 0); Context.setObjCIdType(IdTypedef); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index d2ad5c5f754..b1d0499d137 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -32,6 +32,7 @@ namespace clang { class ASTConsumer; class Preprocessor; class Decl; + class ContextDecl; class NamedDecl; class ScopedDecl; class Expr; @@ -73,7 +74,9 @@ class Sema : public Action { /// CurMethodDecl - If inside of a method body, this contains a pointer to /// the method decl for the method being parsed. ObjCMethodDecl *CurMethodDecl; - + + ContextDecl *CurContext; + /// 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. @@ -246,6 +249,10 @@ private: virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl, DeclTy **Elements, unsigned NumElements); private: + /// Set the current declaration context until it gets popped. + void PushContextDecl(ContextDecl *CD); + void PopContextDecl(); + /// Subroutines of ActOnDeclarator(). TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, ScopedDecl *LastDecl); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c9ea54fa0e9..6f0f351000c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -40,6 +40,17 @@ Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) { return 0; } +void Sema::PushContextDecl(ContextDecl *CD) { + assert(CD->getParent() == CurContext && + "The next ContextDecl should be directly contained in the current one."); + CurContext = CD; +} + +void Sema::PopContextDecl() { + assert(CurContext && "ContextDecl imbalance!"); + CurContext = CurContext->getParent(); +} + void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (S->decl_empty()) return; assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!"); @@ -156,7 +167,8 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, InitBuiltinVaListType(); QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context); - FunctionDecl *New = FunctionDecl::Create(Context, SourceLocation(), II, R, + FunctionDecl *New = FunctionDecl::Create(Context, CurContext, + SourceLocation(), II, R, FunctionDecl::Extern, false, 0); // Find translation-unit scope to insert this function into. @@ -744,7 +756,8 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { } bool isInline = D.getDeclSpec().isInlineSpecified(); - FunctionDecl *NewFD = FunctionDecl::Create(Context, D.getIdentifierLoc(), + FunctionDecl *NewFD = FunctionDecl::Create(Context, CurContext, + D.getIdentifierLoc(), II, R, SC, isInline, LastDeclarator); // Handle attributes. @@ -784,10 +797,12 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { R.getAsString()); InvalidDecl = true; } - NewVD = FileVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC, + NewVD = FileVarDecl::Create(Context, CurContext, D.getIdentifierLoc(), + II, R, SC, LastDeclarator); } else { - NewVD = BlockVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC, + NewVD = BlockVarDecl::Create(Context, CurContext, D.getIdentifierLoc(), + II, R, SC, LastDeclarator); } // Handle attributes prior to checking for duplicates in MergeVarDecl @@ -1000,7 +1015,8 @@ Sema::ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI, } else if (parmDeclType->isFunctionType()) parmDeclType = Context.getPointerType(parmDeclType); - ParmVarDecl *New = ParmVarDecl::Create(Context, PI.IdentLoc, II, parmDeclType, + ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, PI.IdentLoc, II, + parmDeclType, VarDecl::None, 0); if (PI.InvalidType) @@ -1060,6 +1076,7 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0)); FunctionDecl *FD = cast<FunctionDecl>(decl); CurFunctionDecl = FD; + PushContextDecl(FD); // Create Decl objects for each parameter, adding them to the FunctionDecl. llvm::SmallVector<ParmVarDecl*, 16> Params; @@ -1104,6 +1121,7 @@ Sema::DeclTy *Sema::ActOnFinishFunctionBody(DeclTy *D, StmtTy *Body) { MD->setBody((Stmt*)Body); CurMethodDecl = 0; } + PopContextDecl(); // Verify and clean out per-function state. // Check goto/label use. @@ -1173,7 +1191,8 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); // Scope manipulation handled by caller. - TypedefDecl *NewTD = TypedefDecl::Create(Context, D.getIdentifierLoc(), + TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext, + D.getIdentifierLoc(), D.getIdentifier(), T, LastDeclarator); if (D.getInvalidType()) @@ -1253,7 +1272,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, case Decl::Enum: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // enum X { A, B, C } D; D should chain to X. - New = EnumDecl::Create(Context, Loc, Name, 0); + New = EnumDecl::Create(Context, CurContext, Loc, Name, 0); // If this is an undefined enum, warn. if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum); break; @@ -1262,7 +1281,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, case Decl::Class: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // struct X { int A; } D; D should chain to X. - New = RecordDecl::Create(Context, Kind, Loc, Name, 0); + New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name, 0); break; } @@ -1326,8 +1345,8 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, // FIXME: Chain fielddecls together. FieldDecl *NewFD; - if (isa<RecordDecl>(TagDecl)) - NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth); + if (RecordDecl *RD = dyn_cast<RecordDecl>(TagDecl)) + NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth); else if (isa<ObjCInterfaceDecl>(TagDecl) || isa<ObjCImplementationDecl>(TagDecl) || isa<ObjCCategoryDecl>(TagDecl) || @@ -1335,7 +1354,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, // properties can appear within a protocol. // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl. isa<ObjCProtocolDecl>(TagDecl)) - NewFD = ObjCIvarDecl::Create(Context, Loc, II, T); + NewFD = ObjCIvarDecl::Create(Context, dyn_cast<ObjCInterfaceDecl>(TagDecl), Loc, II, T); else assert(0 && "Sema::ActOnField(): Unknown TagDecl"); @@ -1515,7 +1534,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, DeclTy *lastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, SourceLocation EqualLoc, ExprTy *val) { - theEnumDecl = theEnumDecl; // silence unused warning. + EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(theEnumDecl)); EnumConstantDecl *LastEnumConst = cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst)); Expr *Val = static_cast<Expr*>(val); @@ -1576,7 +1595,8 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, } EnumConstantDecl *New = - EnumConstantDecl::Create(Context, IdLoc, Id, EltTy, Val, EnumVal, + EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy, + Val, EnumVal, LastEnumConst); // Register this decl in the current scope stack. diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 69a102203f4..6b9b9e2d431 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -33,6 +33,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { // Allow all of Sema to see that we are entering a method definition. CurMethodDecl = MDecl; + PushContextDecl(MDecl); // Create Decl objects for each parameter, entrring them in the scope for // binding to their use. @@ -813,6 +814,21 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( Diag(MethodLoc, diag::error_missing_method_context); return 0; } + QualType resultDeclType; + + if (ReturnType) + resultDeclType = QualType::getFromOpaquePtr(ReturnType); + else // get the type for "id". + resultDeclType = Context.getObjCIdType(); + + ObjCMethodDecl* ObjCMethod = + ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType, + ClassDecl, AttrList, + MethodType == tok::minus, isVariadic, + MethodDeclKind == tok::objc_optional ? + ObjCMethodDecl::Optional : + ObjCMethodDecl::Required); + llvm::SmallVector<ParmVarDecl*, 16> Params; for (unsigned i = 0; i < Sel.getNumArgs(); i++) { @@ -823,28 +839,15 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( argType = QualType::getFromOpaquePtr(ArgTypes[i]); else argType = Context.getObjCIdType(); - ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/), + ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod, + SourceLocation(/*FIXME*/), ArgNames[i], argType, VarDecl::None, 0); Param->setObjCDeclQualifier( CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier())); Params.push_back(Param); } - QualType resultDeclType; - - if (ReturnType) - resultDeclType = QualType::getFromOpaquePtr(ReturnType); - else // get the type for "id". - resultDeclType = Context.getObjCIdType(); - - ObjCMethodDecl* ObjCMethod = - ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType, - ClassDecl, AttrList, - MethodType == tok::minus, isVariadic, - MethodDeclKind == tok::objc_optional ? - ObjCMethodDecl::Optional : - ObjCMethodDecl::Required); - + ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs()); ObjCMethod->setObjCDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); |