diff options
author | Ed Schouten <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-27 10:45:02 +0000 |
commit | 4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (patch) | |
tree | 2c5a83521a20c02e7805581a174008aa9bc23579 /lib/Frontend | |
parent | f698f7e71940663e26a4806a96fb0bdfa160c886 (diff) |
Notes
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 6 | ||||
-rw-r--r-- | lib/Frontend/AnalysisConsumer.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/CMakeLists.txt | 7 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 9 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 16 | ||||
-rw-r--r-- | lib/Frontend/ResolveLocation.cpp | 322 |
7 files changed, 361 insertions, 11 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index a7fbcda8fc2be..8143263ca2f94 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -113,14 +113,10 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, break; case PCHReader::Failure: - // Unrecoverable failure: don't even try to process the input - // file. + case PCHReader::IgnorePCH: if (ErrMsg) *ErrMsg = "Could not load PCH file"; return NULL; - - case PCHReader::IgnorePCH: - assert(0 && "Is there a validation that should not have happened ?"); } // PCH loaded successfully. Now create the preprocessor. diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index ae90594a40991..d8fa141d8cb6e 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -469,10 +469,6 @@ static void ActionCheckerCFRef(AnalysisManager& mgr) { } } -static void ActionCheckerSimple(AnalysisManager& mgr) { - ActionGRExprEngine(mgr, MakeGRSimpleValsTF()); -} - static void ActionDisplayLiveVariables(AnalysisManager& mgr) { if (LiveVariables* L = mgr.getLiveVariables()) { mgr.DisplayFunction(); diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt index 4ba39c9594248..f8d09dbee89e2 100644 --- a/lib/Frontend/CMakeLists.txt +++ b/lib/Frontend/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_NO_RTTI 1) add_clang_library(clangFrontend AnalysisConsumer.cpp ASTConsumers.cpp + ASTUnit.cpp Backend.cpp CacheTokens.cpp DeclXML.cpp @@ -25,6 +26,7 @@ add_clang_library(clangFrontend PlistDiagnostics.cpp PrintParserCallbacks.cpp PrintPreprocessedOutput.cpp + ResolveLocation.cpp RewriteBlocks.cpp RewriteMacros.cpp RewriteObjC.cpp @@ -36,4 +38,7 @@ add_clang_library(clangFrontend Warnings.cpp ) -add_dependencies(clangFrontend ClangDiagnosticFrontend) +add_dependencies(clangFrontend + ClangDiagnosticFrontend + ClangDiagnosticLex + ClangDiagnosticSema) diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 96f21f1128674..765655b01dd0c 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -71,6 +71,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { PARSE_LANGOPT_BENIGN(WritableStrings); PARSE_LANGOPT_IMPORTANT(LaxVectorConversions, diag::warn_pch_lax_vector_conversions); + PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec); PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions); PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime); PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding); @@ -105,6 +106,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) { } PARSE_LANGOPT_BENIGN(getVisibilityMode()); PARSE_LANGOPT_BENIGN(InstantiationDepth); + PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl); #undef PARSE_LANGOPT_IRRELEVANT #undef PARSE_LANGOPT_BENIGN @@ -1629,6 +1631,7 @@ bool PCHReader::ParseLanguageOptions( PARSE_LANGOPT(PascalStrings); PARSE_LANGOPT(WritableStrings); PARSE_LANGOPT(LaxVectorConversions); + PARSE_LANGOPT(AltiVec); PARSE_LANGOPT(Exceptions); PARSE_LANGOPT(NeXTRuntime); PARSE_LANGOPT(Freestanding); @@ -1652,6 +1655,7 @@ bool PCHReader::ParseLanguageOptions( LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]); ++Idx; PARSE_LANGOPT(InstantiationDepth); + PARSE_LANGOPT(OpenCL); #undef PARSE_LANGOPT return Listener->ReadLanguageOptions(LangOpts); @@ -1822,7 +1826,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { QualType UnderlyingType = GetType(Record[0]); return Context->getTypeOfType(UnderlyingType); } - + + case pch::TYPE_DECLTYPE: + return Context->getDecltypeType(ReadTypeExpr()); + case pch::TYPE_RECORD: assert(Record.size() == 1 && "incorrect encoding of record type"); return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0]))); diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 3dd84c7b08ad5..3f6ae354dc3f8 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -489,6 +489,14 @@ Attr *PCHReader::ReadAttributes() { New = ::new (*Context) NonNullAttr(ArgNums.data(), Size); break; } + + case Attr::ReqdWorkGroupSize: { + unsigned X = Record[Idx++]; + unsigned Y = Record[Idx++]; + unsigned Z = Record[Idx++]; + New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z); + break; + } SIMPLE_ATTR(ObjCException); SIMPLE_ATTR(ObjCNSObject); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 3b1eb080f229b..e93219e01d5c8 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -185,6 +185,11 @@ void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) { Code = pch::TYPE_TYPEOF; } +void PCHTypeWriter::VisitDecltypeType(const DecltypeType *T) { + Writer.AddStmt(T->getUnderlyingExpr()); + Code = pch::TYPE_DECLTYPE; +} + void PCHTypeWriter::VisitTagType(const TagType *T) { Writer.AddDeclRef(T->getDecl(), Record); assert(!T->isBeingDefined() && @@ -526,6 +531,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings Record.push_back(LangOpts.WritableStrings); // Allow writable strings Record.push_back(LangOpts.LaxVectorConversions); + Record.push_back(LangOpts.AltiVec); Record.push_back(LangOpts.Exceptions); // Support exception handling. Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime. @@ -563,6 +569,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.getGCMode()); Record.push_back(LangOpts.getVisibilityMode()); Record.push_back(LangOpts.InstantiationDepth); + Record.push_back(LangOpts.OpenCL); Stream.EmitRecord(pch::LANGUAGE_OPTIONS, Record); } @@ -1615,6 +1622,12 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) { case Attr::Regparm: Record.push_back(cast<RegparmAttr>(Attr)->getNumParams()); break; + + case Attr::ReqdWorkGroupSize: + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim()); + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim()); + Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim()); + break; case Attr::Section: AddString(cast<SectionAttr>(Attr)->getName(), Record); @@ -1896,6 +1909,9 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) { case BuiltinType::NullPtr: ID = pch::PREDEF_TYPE_NULLPTR_ID; break; case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break; case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break; + case BuiltinType::UndeducedAuto: + assert(0 && "Should not see undeduced auto here"); + break; } Record.push_back((ID << 3) | T.getCVRQualifiers()); diff --git a/lib/Frontend/ResolveLocation.cpp b/lib/Frontend/ResolveLocation.cpp new file mode 100644 index 0000000000000..a5f0d1f163651 --- /dev/null +++ b/lib/Frontend/ResolveLocation.cpp @@ -0,0 +1,322 @@ +//===--- ResolveLocation.cpp - Source location resolver ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines the ResolveLocationInAST function, which resolves a +// source location into a <Decl *, Stmt *> pair. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/Utils.h" +#include "clang/AST/DeclVisitor.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Lex/Lexer.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/Support/Compiler.h" +using namespace clang; + +namespace { + +/// \brief Base for the LocResolver classes. Mostly does source range checking. +class VISIBILITY_HIDDEN LocResolverBase { +protected: + ASTContext &Ctx; + SourceLocation Loc; + + Decl *Dcl; + Stmt *Stm; + bool PassedLoc; + + /// \brief Checks whether Loc is in the source range of 'D'. + /// + /// If it is, updates Dcl. If Loc is passed the source range, it sets + /// PassedLoc, otherwise it does nothing. + void CheckRange(Decl *D); + + /// \brief Checks whether Loc is in the source range of 'Node'. + /// + /// If it is, updates Stm. If Loc is passed the source range, it sets + /// PassedLoc, otherwise it does nothing. + void CheckRange(Stmt *Node); + + /// \brief Updates the end source range to cover the full length of the token + /// positioned at the end of the source range. + /// + /// e.g., + /// @code + /// int foo + /// ^ ^ + /// @endcode + /// will be updated to + /// @code + /// int foo + /// ^ ^ + /// @endcode + void FixRange(SourceRange &Range); + +public: + LocResolverBase(ASTContext &ctx, SourceLocation loc) + : Ctx(ctx), Loc(loc), Dcl(0), Stm(0), PassedLoc(0) {} + + /// \brief We found a AST node that corresponds to the source location. + bool FoundIt() const { return Dcl != 0 || Stm != 0; } + + /// \brief We either found a AST node or we passed the source location while + /// searching. + bool Finished() const { return FoundIt() || PassedLoc; } + + Decl *getDecl() const { return Dcl; } + Stmt *getStmt() const { return Stm; } + + std::pair<Decl *, Stmt *> getResult() const { + return std::make_pair(getDecl(), getStmt()); + } + + /// \brief Debugging output. + void print(Decl *D); + /// \brief Debugging output. + void print(Stmt *Node); +}; + +/// \brief Searches a statement for the AST node that corresponds to a source +/// location. +class VISIBILITY_HIDDEN StmtLocResolver : public LocResolverBase, + public StmtVisitor<StmtLocResolver> { +public: + StmtLocResolver(ASTContext &ctx, SourceLocation loc) + : LocResolverBase(ctx, loc) {} + + void VisitDeclStmt(DeclStmt *Node); + void VisitStmt(Stmt *Node); +}; + +/// \brief Searches a declaration for the AST node that corresponds to a source +/// location. +class VISIBILITY_HIDDEN DeclLocResolver : public LocResolverBase, + public DeclVisitor<DeclLocResolver> { +public: + DeclLocResolver(ASTContext &ctx, SourceLocation loc) + : LocResolverBase(ctx, loc) {} + + void VisitDeclContext(DeclContext *DC); + void VisitTranslationUnitDecl(TranslationUnitDecl *TU); + void VisitVarDecl(VarDecl *D); + void VisitFunctionDecl(FunctionDecl *D); + void VisitDecl(Decl *D); +}; + +} // anonymous namespace + +void StmtLocResolver::VisitDeclStmt(DeclStmt *Node) { + CheckRange(Node); + if (!FoundIt()) + return; + assert(Stm == Node && "Result not updated ?"); + + // Search all declarations of this DeclStmt. If we found the one corresponding + // to the source location, update this StmtLocResolver's result. + DeclLocResolver DLR(Ctx, Loc); + for (DeclStmt::decl_iterator + I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) { + DLR.Visit(*I); + if (DLR.Finished()) { + if (DLR.FoundIt()) + llvm::tie(Dcl, Stm) = DLR.getResult(); + return; + } + } +} + +void StmtLocResolver::VisitStmt(Stmt *Node) { + CheckRange(Node); + if (!FoundIt()) + return; + assert(Stm == Node && "Result not updated ?"); + + // Search the child statements. + StmtLocResolver SLR(Ctx, Loc); + for (Stmt::child_iterator + I = Node->child_begin(), E = Node->child_end(); I != E; ++I) { + SLR.Visit(*I); + if (!SLR.Finished()) + continue; + + // We either found it or we passed the source location. + + if (SLR.FoundIt()) { + // Only update Dcl if we found another more immediate 'parent' Decl for + // the statement. + if (SLR.getDecl()) + Dcl = SLR.getDecl(); + Stm = SLR.getStmt(); + } + + return; + } +} + +void DeclLocResolver::VisitDeclContext(DeclContext *DC) { + DeclLocResolver DLR(Ctx, Loc); + for (DeclContext::decl_iterator + I = DC->decls_begin(Ctx), E = DC->decls_end(Ctx); I != E; ++I) { + DLR.Visit(*I); + if (DLR.Finished()) { + if (DLR.FoundIt()) + llvm::tie(Dcl, Stm) = DLR.getResult(); + return; + } + } +} + +void DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { + VisitDeclContext(TU); +} + +void DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) { + CheckRange(D); + if (!FoundIt()) + return; + assert(Dcl == D && "Result not updated ?"); + + // First, search through the parameters of the function. + DeclLocResolver ParmRes(Ctx, Loc); + for (FunctionDecl::param_iterator + I = D->param_begin(), E = D->param_end(); I != E; ++I) { + ParmRes.Visit(*I); + if (ParmRes.Finished()) { + if (ParmRes.FoundIt()) + llvm::tie(Dcl, Stm) = ParmRes.getResult(); + return; + } + } + + // We didn't found the location in the parameters and we didn't get passed it. + + // Second, search through the declarations that are part of the function. + // If we find he location there, we won't have to search through its body. + DeclLocResolver DLR(Ctx, Loc); + DLR.VisitDeclContext(D); + if (DLR.FoundIt()) { + llvm::tie(Dcl, Stm) = DLR.getResult(); + return; + } + + // We didn't find a declaration that corresponds to the source location. + + // Finally, search through the body of the function. + if (D->isThisDeclarationADefinition()) { + StmtLocResolver SLR(Ctx, Loc); + SLR.Visit(D->getBody(Ctx)); + if (SLR.FoundIt()) { + llvm::tie(Dcl, Stm) = SLR.getResult(); + // If we didn't find a more immediate 'parent' declaration for the + // statement, set the function as the parent. + if (Dcl == 0) + Dcl = D; + } + } +} + +void DeclLocResolver::VisitVarDecl(VarDecl *D) { + CheckRange(D); + if (!FoundIt()) + return; + assert(Dcl == D && "Result not updated ?"); + + // Check whether the location points to the init expression. + if (D->getInit()) { + StmtLocResolver SLR(Ctx, Loc); + SLR.Visit(D->getInit()); + Stm = SLR.getStmt(); + } +} + +void DeclLocResolver::VisitDecl(Decl *D) { + CheckRange(D); +} + +void LocResolverBase::CheckRange(Decl *D) { + SourceRange Range = D->getSourceRange(); + if (!Range.isValid()) + return; + + FixRange(Range); + + SourceManager &SourceMgr = Ctx.getSourceManager(); + if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc)) + return; + + if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin())) + PassedLoc = true; + else + Dcl = D; +} + +void LocResolverBase::CheckRange(Stmt *Node) { + SourceRange Range = Node->getSourceRange(); + if (!Range.isValid()) + return; + + FixRange(Range); + + SourceManager &SourceMgr = Ctx.getSourceManager(); + if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc)) + return; + + if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin())) + PassedLoc = true; + else + Stm = Node; +} + +void LocResolverBase::FixRange(SourceRange &Range) { + if (!Range.isValid()) + return; + + unsigned TokSize = Lexer::MeasureTokenLength(Range.getEnd(), + Ctx.getSourceManager(), + Ctx.getLangOptions()); + Range.setEnd(Range.getEnd().getFileLocWithOffset(TokSize-1)); +} + +void LocResolverBase::print(Decl *D) { + llvm::raw_ostream &OS = llvm::outs(); + OS << "#### DECL ####\n"; + D->print(OS, Ctx); + OS << " <"; + D->getLocStart().print(OS, Ctx.getSourceManager()); + OS << " > - <"; + D->getLocEnd().print(OS, Ctx.getSourceManager()); + OS << ">\n\n"; + OS.flush(); +} + +void LocResolverBase::print(Stmt *Node) { + llvm::raw_ostream &OS = llvm::outs(); + OS << "#### STMT ####\n"; + Node->printPretty(OS, Ctx); + OS << " <"; + Node->getLocStart().print(OS, Ctx.getSourceManager()); + OS << " > - <"; + Node->getLocEnd().print(OS, Ctx.getSourceManager()); + OS << ">\n\n"; + OS.flush(); +} + + +/// \brief Returns the AST node that a source location points to. +/// +std::pair<Decl *, Stmt *> +clang::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc) { + if (Loc.isInvalid()) + return std::make_pair((Decl*)0, (Stmt*)0); + + DeclLocResolver DLR(Ctx, Loc); + DLR.Visit(Ctx.getTranslationUnitDecl()); + return DLR.getResult(); +} |