summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.cpp21
-rw-r--r--clang/lib/Sema/Sema.h9
-rw-r--r--clang/lib/Sema/SemaDecl.cpp46
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp35
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()));
OpenPOWER on IntegriCloud