diff --git a/Sema/ParseAST.cpp b/Sema/ParseAST.cpp index 92e8d247e6..8fd14d17d1 100644 --- a/Sema/ParseAST.cpp +++ b/Sema/ParseAST.cpp @@ -38,7 +38,7 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, bool PrintStats) { ASTContext Context(PP.getSourceManager(), PP.getTargetInfo(), PP.getIdentifierTable(), PP.getSelectorTable()); - Parser P(PP, *new Sema(PP, Context)); + Parser P(PP, *new Sema(PP, Context, *Consumer)); PP.EnterMainSourceFile(); // Initialize the parser. diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp index b53147f6eb..ffa81a2736 100644 --- a/Sema/Sema.cpp +++ b/Sema/Sema.cpp @@ -42,43 +42,44 @@ bool Sema::isObjCObjectPointerType(QualType type) const { void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { TUScope = S; - if (PP.getLangOptions().ObjC1) { - TypedefType *t; - - // Add the built-in ObjC types. - t = dyn_cast(Context.getObjCIdType().getTypePtr()); - t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); - TUScope->AddDecl(t->getDecl()); - t = dyn_cast(Context.getObjCClassType().getTypePtr()); - t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); - TUScope->AddDecl(t->getDecl()); - ObjCInterfaceType *it = dyn_cast(Context.getObjCProtoType()); - ObjCInterfaceDecl *IDecl = it->getDecl(); - IDecl->getIdentifier()->setFETokenInfo(IDecl); - TUScope->AddDecl(IDecl); - t = dyn_cast(Context.getObjCSelType().getTypePtr()); - t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); - TUScope->AddDecl(t->getDecl()); - } + if (!PP.getLangOptions().ObjC1) return; + + TypedefType *t; + + // Add the built-in ObjC types. + t = cast(Context.getObjCIdType().getTypePtr()); + t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); + TUScope->AddDecl(t->getDecl()); + t = cast(Context.getObjCClassType().getTypePtr()); + t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); + TUScope->AddDecl(t->getDecl()); + ObjCInterfaceType *it = cast(Context.getObjCProtoType()); + ObjCInterfaceDecl *IDecl = it->getDecl(); + IDecl->getIdentifier()->setFETokenInfo(IDecl); + TUScope->AddDecl(IDecl); + t = cast(Context.getObjCSelType().getTypePtr()); + t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); + TUScope->AddDecl(t->getDecl()); } -Sema::Sema(Preprocessor &pp, ASTContext &ctxt) - : PP(pp), Context(ctxt), CurFunctionDecl(0), CurMethodDecl(0) { +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(); + 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"); + 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"); if (PP.getLangOptions().ObjC1) { // Synthesize "typedef struct objc_class *Class;" diff --git a/Sema/Sema.h b/Sema/Sema.h index 3b463eb407..06a12e4f7f 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -29,6 +29,7 @@ namespace llvm { namespace clang { class ASTContext; + class ASTConsumer; class Preprocessor; class Decl; class ScopedDecl; @@ -60,8 +61,8 @@ namespace clang { /// 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. @@ -139,7 +140,7 @@ class Sema : public Action { llvm::DenseMap InstanceMethodPool; llvm::DenseMap FactoryMethodPool; public: - Sema(Preprocessor &pp, ASTContext &ctxt); + Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer); const LangOptions &getLangOptions() const; diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index e894492808..a6bff1111d 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -624,8 +624,8 @@ DEC8D98B0A9433BC00353FCA /* AST */ = { isa = PBXGroup; children = ( - 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */, DEC8D9A30A94346E00353FCA /* AST.h */, + 35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */, DE75ED280B044DC90020CF81 /* ASTContext.h */, DED676D00B6C786700AAD4A3 /* Builtins.def */, DED676F90B6C797B00AAD4A3 /* Builtins.h */, diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 5e0ed75bbf..bfaa141573 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -17,6 +17,8 @@ namespace clang { class ASTContext; class Decl; + class TagDecl; + class HandleTagDeclDefinition; /// ASTConsumer - This is an abstract interface that should be implemented by /// clients that read ASTs. This abstraction layer allows the client to be @@ -31,7 +33,7 @@ public: /// HandleTopLevelDecl - Handle the specified top-level declaration. This is /// called by HandleTopLevelDeclaration to process every top-level Decl*. - virtual void HandleTopLevelDecl(Decl *D) {}; + virtual void HandleTopLevelDecl(Decl *D) {} /// HandleTopLevelDeclaration - Handle the specified top-level declaration. @@ -40,6 +42,13 @@ public: /// can override its behavior; by default it calls HandleTopLevelDecl /// for every Decl* in a decl chain. virtual void HandleTopLevelDeclaration(Decl *D); + + + /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl + /// (e.g. struct, union, enum, class) is completed. This allows the client to + /// hack on the type, which can occur at any point in the file (because these + /// can be defined in declspecs). + virtual void HandleTagDeclDefinition(TagDecl *D) {} /// PrintStats - If desired, print any statistics. virtual void PrintStats() {