diff options
Diffstat (limited to 'include/clang')
36 files changed, 541 insertions, 135 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index d12a182..e77dcf8 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -259,19 +259,11 @@ class ASTContext { /// this ASTContext object. LangOptions LangOpts; - /// \brief Whether we have already loaded comment source ranges from an - /// external source. - bool LoadedExternalComments; - /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects. bool FreeMemory; llvm::MallocAllocator MallocAlloc; llvm::BumpPtrAllocator BumpAlloc; - /// \brief Mapping from declarations to their comments, once we have - /// already looked up the comment associated with a given declaration. - llvm::DenseMap<const Decl *, std::string> DeclComments; - public: const TargetInfo &Target; IdentifierTable &Idents; @@ -287,10 +279,6 @@ public: QualType ObjCClassRedefinitionType; QualType ObjCSelRedefinitionType; - /// \brief Source ranges for all of the comments in the source file, - /// sorted in order of appearance in the translation unit. - std::vector<SourceRange> Comments; - SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } void *Allocate(unsigned Size, unsigned Align = 8) { @@ -357,8 +345,6 @@ public: TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } - const char *getCommentForDecl(const Decl *D); - // Builtin Types. CanQualType VoidTy; CanQualType BoolTy; @@ -1161,6 +1147,8 @@ public: /// Compatibility predicates used to check assignment expressions. bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1 + bool typesAreBlockPointerCompatible(QualType, QualType); + bool isObjCIdType(QualType T) const { return T == ObjCIdTypedefType; } @@ -1179,13 +1167,16 @@ public: const ObjCObjectPointerType *RHSOPT); bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS, const ObjCInterfaceType *RHS); + bool canAssignObjCInterfacesInBlockPointer( + const ObjCObjectPointerType *LHSOPT, + const ObjCObjectPointerType *RHSOPT); bool areComparableObjCPointerTypes(QualType LHS, QualType RHS); QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); // Functions for calculating composite types - QualType mergeTypes(QualType, QualType); - QualType mergeFunctionTypes(QualType, QualType); + QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false); + QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false); /// UsualArithmeticConversionsType - handles the various conversions /// that are common to binary operators (C99 6.3.1.8, C++ [expr]p9) @@ -1312,10 +1303,10 @@ static inline Selector GetUnarySelector(const char* name, ASTContext& Ctx) { /// this ever changes, this operator will have to be changed, too.) /// Usage looks like this (assuming there's an ASTContext 'Context' in scope): /// @code -/// // Default alignment (16) +/// // Default alignment (8) /// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); /// // Specific alignment -/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments); +/// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments); /// @endcode /// Please note that you cannot use delete on the pointer; it must be /// deallocated using an explicit destructor call followed by @@ -1346,10 +1337,10 @@ inline void operator delete(void *Ptr, clang::ASTContext &C, size_t) /// null on error. /// Usage looks like this (assuming there's an ASTContext 'Context' in scope): /// @code -/// // Default alignment (16) +/// // Default alignment (8) /// char *data = new (Context) char[10]; /// // Specific alignment -/// char *data = new (Context, 8) char[10]; +/// char *data = new (Context, 4) char[10]; /// @endcode /// Please note that you cannot use delete on the pointer; it must be /// deallocated using an explicit destructor call followed by @@ -1361,7 +1352,7 @@ inline void operator delete(void *Ptr, clang::ASTContext &C, size_t) /// allocator supports it). /// @return The allocated memory. Could be NULL. inline void *operator new[](size_t Bytes, clang::ASTContext& C, - size_t Alignment = 16) throw () { + size_t Alignment = 8) throw () { return C.Allocate(Bytes, Alignment); } diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 23076b9..6b14e47 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -150,7 +150,6 @@ public: LV_InvalidExpression, LV_MemberFunction, LV_SubObjCPropertySetting, - LV_SubObjCPropertyGetterSetting, LV_ClassTemporary }; isLvalueResult isLvalue(ASTContext &Ctx) const; @@ -182,7 +181,6 @@ public: MLV_NoSetterProperty, MLV_MemberFunction, MLV_SubObjCPropertySetting, - MLV_SubObjCPropertyGetterSetting, MLV_ClassTemporary }; isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 0670d1a..b8d80bc 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -58,14 +58,6 @@ public: virtual ~ExternalASTSource(); - /// \brief Reads the source ranges that correspond to comments from - /// an external AST source. - /// - /// \param Comments the contents of this vector will be - /// replaced with the sorted set of source ranges corresponding to - /// comments in the source code. - virtual void ReadComments(std::vector<SourceRange> &Comments) = 0; - /// \brief Resolve a type ID into a type, potentially building a new /// type. virtual QualType GetType(uint32_t ID) = 0; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 94caa6f..4668489 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -126,12 +126,12 @@ public: // Only allow allocation of Stmts using the allocator in ASTContext // or by doing a placement new. void* operator new(size_t bytes, ASTContext& C, - unsigned alignment = 16) throw() { + unsigned alignment = 8) throw() { return ::operator new(bytes, C, alignment); } void* operator new(size_t bytes, ASTContext* C, - unsigned alignment = 16) throw() { + unsigned alignment = 8) throw() { return ::operator new(bytes, *C, alignment); } diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index 9c59229..553f04d 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -94,6 +94,7 @@ public: NamedDecl *getDecl() const { return ir->getDecl(); } AccessSpecifier getAccess() const { return ir->getAccess(); } + DeclAccessPair getPair() const { return *ir; } NamedDecl *operator*() const { return getDecl(); } diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 9a79f90..00b076a 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -293,4 +293,28 @@ BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "") BUILTIN(__builtin_ia32_pcmpeqq, "V2LLiV2LLiV2LLi", "") BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "") +// SSE 4.2 +BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cc", "") +BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cc", "") +BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16cic", "") +BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16cic","") + +BUILTIN(__builtin_ia32_pcmpistria128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpistric128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpistrio128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpistris128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpistriz128, "iV16ciV16cic","") + +BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16cic","") +BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16cic","") + +BUILTIN(__builtin_ia32_pcmpgtq, "V2LLiV2LLiV2LLi", "") + +BUILTIN(__builtin_ia32_crc32qi, "iic", "") +BUILTIN(__builtin_ia32_crc32hi, "iis", "") +BUILTIN(__builtin_ia32_crc32si, "iii", "") +BUILTIN(__builtin_ia32_crc32di, "LLiLLiLLi", "") #undef BUILTIN diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 849e643..8e791c3 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -65,9 +65,6 @@ def err_target_invalid_feature : Error<"invalid target feature '%0'">; // Source manager def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; -def err_file_size_changed : Error< - "size of file '%0' changed since it was first processed (from %1 to %2)">, - DefaultFatal; def err_file_modified : Error< "file '%0' modified since it was first processed">, DefaultFatal; diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 2bce12d..3dbe47f 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -64,6 +64,8 @@ def err_drv_invalid_remap_file : Error< "invalid option '%0' not of the form <from-file>;<to-file>">; def err_drv_invalid_gcc_output_type : Error< "invalid output type '%0' for use with gcc tool">; +def err_drv_cc_print_options_failure : Error< + "unable to open CC_PRINT_OPTIONS file: %0">; def warn_drv_input_file_unused : Warning< "%0: '%1' input unused when '%2' is present">; diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index b77614b..3a28282 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -51,12 +51,16 @@ def err_fe_unable_to_read_pch_file : Error< "unable to read PCH file: '%0'">; def err_fe_not_a_pch_file : Error< "input is not a PCH file: '%0'">; +def err_fe_pch_malformed : Error< + "malformed or corrupted PCH file: '%0'">, DefaultFatal; def err_fe_pch_malformed_block : Error< - "malformed block record in PCH file: '%0'">; + "malformed block record in PCH file: '%0'">, DefaultFatal; def err_fe_pch_error_at_end_block : Error< - "error at end of module block in PCH file: '%0'">; + "error at end of module block in PCH file: '%0'">, DefaultFatal; def err_fe_unable_to_open_output : Error< "unable to open output file '%0': '%1'">; +def err_fe_unable_to_open_logfile : Error< + "unable to open logfile file '%0': '%1'">; def err_fe_pth_file_has_no_source_header : Error< "PTH file '%0' does not designate an original source header file for -include-pth">; def warn_fe_macro_contains_embedded_newline : Warning< diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index e5793fa..203ab1e 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -73,7 +73,7 @@ def : DiagGroup<"redundant-decls">; def ReturnType : DiagGroup<"return-type">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; def : DiagGroup<"sequence-point">; -def : DiagGroup<"shadow">; +def Shadow : DiagGroup<"shadow">; def : DiagGroup<"shorten-64-to-32">; def SignCompare : DiagGroup<"sign-compare">; def : DiagGroup<"synth">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9a9b7cc..752be5d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -107,7 +107,15 @@ def warn_use_out_of_scope_declaration : Warning< "use of out-of-scope declaration of %0">; def err_inline_non_function : Error< "'inline' can only appear on functions">; - + +def warn_decl_shadow : + Warning<"declaration shadows a %select{" + "local variable|" + "variable in %2|" + "static data member of %2|" + "field of %2}1">, + InGroup<Shadow>, DefaultIgnore; + // C++ using declarations def err_using_requires_qualname : Error< "using declaration requires a qualified name">; @@ -1529,8 +1537,7 @@ def err_forward_ref_enum : Error< "ISO C++ forbids forward references to 'enum' types">; def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">; def err_duplicate_member : Error<"duplicate member %0">; -def err_misplaced_ivar : Error<"ivar may be placed in a class extension " - "in non-fragile-abi2 mode only">; +def err_misplaced_ivar : Error<"ivars may not be placed in categories">; def ext_enum_value_not_int : Extension< "ISO C restricts enumerator values to range of 'int' (%0 is too " "%select{small|large}1)">; @@ -1881,16 +1888,16 @@ def err_stmtexpr_file_scope : Error< "statement expression not allowed at file scope">; def warn_mixed_sign_comparison : Warning< "comparison of integers of different signs: %0 and %1">, - InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; + InGroup<SignCompare>, DefaultIgnore; def warn_mixed_sign_conditional : Warning< "operands of ? are integers of different signs: %0 and %1">, - InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; + InGroup<SignCompare>, DefaultIgnore; def warn_lunsigned_always_true_comparison : Warning< "comparison of unsigned expression %0 is always %1">, - InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; + InGroup<SignCompare>, DefaultIgnore; def warn_runsigned_always_true_comparison : Warning< "comparison of %0 unsigned expression is always %1">, - InGroup<DiagGroup<"sign-compare">>, DefaultIgnore; + InGroup<SignCompare>, DefaultIgnore; def err_invalid_this_use : Error< "invalid use of 'this' outside of a nonstatic member function">; @@ -1944,11 +1951,7 @@ def ext_integer_complement_complex : Extension< def error_nosetter_property_assignment : Error< "setter method is needed to assign to object using property" " assignment syntax">; def error_no_subobject_property_setting : Error< - "cannot assign to a sub-structure of an ivar using property" - " assignment syntax">; -def error_no_subobject_property_getter_setting : Error< - "cannot assign to a sub-structure returned via a getter using property" - " assignment syntax">; + "expression is not assignable using property assignment syntax">; def ext_freestanding_complex : Extension< "complex numbers are an extension in a freestanding C99 implementation">; diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 34dfecd..f7ea331 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -200,19 +200,19 @@ public: FullSourceLoc getInstantiationLoc() const; FullSourceLoc getSpellingLoc() const; - unsigned getInstantiationLineNumber() const; - unsigned getInstantiationColumnNumber() const; + unsigned getInstantiationLineNumber(bool *Invalid = 0) const; + unsigned getInstantiationColumnNumber(bool *Invalid = 0) const; - unsigned getSpellingLineNumber() const; - unsigned getSpellingColumnNumber() const; + unsigned getSpellingLineNumber(bool *Invalid = 0) const; + unsigned getSpellingColumnNumber(bool *Invalid = 0) const; - const char *getCharacterData() const; + const char *getCharacterData(bool *Invalid = 0) const; - const llvm::MemoryBuffer* getBuffer() const; + const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const; /// getBufferData - Return a StringRef to the source buffer data for the /// specified FileID. - llvm::StringRef getBufferData() const; + llvm::StringRef getBufferData(bool *Invalid = 0) const; /// getDecomposedLoc - Decompose the specified location into a raw FileID + /// Offset pair. The first element is the FileID, the second is the diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index ef51a58..d123969 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -17,6 +17,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/Support/Allocator.h" #include "llvm/System/DataTypes.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" #include <vector> @@ -54,7 +55,8 @@ namespace SrcMgr { class ContentCache { /// Buffer - The actual buffer containing the characters from the input /// file. This is owned by the ContentCache object. - mutable const llvm::MemoryBuffer *Buffer; + /// The bit indicates whether the buffer is invalid. + mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 1, bool> Buffer; public: /// Reference to the file entry. This reference does not own @@ -92,8 +94,9 @@ namespace SrcMgr { unsigned getSizeBytesMapped() const; void setBuffer(const llvm::MemoryBuffer *B) { - assert(!Buffer && "MemoryBuffer already set."); - Buffer = B; + assert(!Buffer.getPointer() && "MemoryBuffer already set."); + Buffer.setPointer(B); + Buffer.setInt(false); } /// \brief Replace the existing buffer (which will be deleted) @@ -101,17 +104,19 @@ namespace SrcMgr { void replaceBuffer(const llvm::MemoryBuffer *B); ContentCache(const FileEntry *Ent = 0) - : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {} + : Buffer(0, false), Entry(Ent), SourceLineCache(0), NumLines(0) {} ~ContentCache(); /// The copy ctor does not allow copies where source object has either /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory /// is not transfered, so this is a logical error. - ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) { + ContentCache(const ContentCache &RHS) + : Buffer(0, false), SourceLineCache(0) + { Entry = RHS.Entry; - assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0 + assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 && "Passed ContentCache object cannot own a buffer."); NumLines = RHS.NumLines; diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h index 2728637..2e0993a 100644 --- a/include/clang/Basic/Version.h +++ b/include/clang/Basic/Version.h @@ -22,7 +22,7 @@ // FIXME: Updates to this file must also update CMakeLists.txt and VER. /// \brief Clang minor version -#define CLANG_VERSION_MINOR 1 +#define CLANG_VERSION_MINOR 5 /// \brief Clang patchlevel version // #define CLANG_VERSION_PATCHLEVEL 1 diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h index 6c41668..2c15f2a 100644 --- a/include/clang/Checker/BugReporter/BugReporter.h +++ b/include/clang/Checker/BugReporter/BugReporter.h @@ -17,13 +17,15 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Checker/PathSensitive/GRState.h" -#include "clang/Checker/PathSensitive/ExplodedGraph.h" #include "clang/Checker/BugReporter/BugType.h" +#include "clang/Checker/PathSensitive/ExplodedGraph.h" +#include "clang/Checker/PathSensitive/GRState.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/ImmutableList.h" +#include "llvm/ADT/ImmutableSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/ImmutableSet.h" #include <list> namespace clang { @@ -45,7 +47,7 @@ class ParentMap; // Interface for individual bug reports. //===----------------------------------------------------------------------===// -class BugReporterVisitor { +class BugReporterVisitor : public llvm::FoldingSetNode { public: virtual ~BugReporterVisitor(); virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, @@ -53,6 +55,7 @@ public: BugReporterContext& BRC) = 0; virtual bool isOwnedByReporterContext() { return true; } + virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0; }; // FIXME: Combine this with RangedBugReport and remove RangedBugReport. @@ -385,16 +388,18 @@ public: class BugReporterContext { GRBugReporter &BR; - std::vector<BugReporterVisitor*> Callbacks; + // Not the most efficient data structure, but we use an ImmutableList for the + // Callbacks because it is safe to make additions to list during iteration. + llvm::ImmutableList<BugReporterVisitor*>::Factory F; + llvm::ImmutableList<BugReporterVisitor*> Callbacks; + llvm::FoldingSet<BugReporterVisitor> CallbacksSet; public: - BugReporterContext(GRBugReporter& br) : BR(br) {} + BugReporterContext(GRBugReporter& br) : BR(br), Callbacks(F.GetEmptyList()) {} virtual ~BugReporterContext(); - void addVisitor(BugReporterVisitor* visitor) { - if (visitor) Callbacks.push_back(visitor); - } + void addVisitor(BugReporterVisitor* visitor); - typedef std::vector<BugReporterVisitor*>::iterator visitor_iterator; + typedef llvm::ImmutableList<BugReporterVisitor*>::iterator visitor_iterator; visitor_iterator visitor_begin() { return Callbacks.begin(); } visitor_iterator visitor_end() { return Callbacks.end(); } @@ -467,6 +472,7 @@ void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt, void registerFindLastStore(BugReporterContext& BRC, const void *memregion, const ExplodedNode *N); +void registerNilReceiverVisitor(BugReporterContext &BRC); } // end namespace clang::bugreporter diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h index 1178143..657266b 100644 --- a/include/clang/Checker/PathSensitive/GRState.h +++ b/include/clang/Checker/PathSensitive/GRState.h @@ -453,6 +453,7 @@ public: ConstraintManager& getConstraintManager() { return *ConstraintMgr; } const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, + const StackFrameContext *LCtx, SymbolReaper& SymReaper); public: diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h index c660e7b..edc3380 100644 --- a/include/clang/Checker/PathSensitive/Store.h +++ b/include/clang/Checker/PathSensitive/Store.h @@ -144,6 +144,7 @@ public: } virtual Store RemoveDeadBindings(Store store, Stmt* Loc, + const StackFrameContext *LCtx, SymbolReaper& SymReaper, llvm::SmallVectorImpl<const MemRegion*>& RegionRoots) = 0; diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h index e0e0f77..85c6c3e 100644 --- a/include/clang/CodeGen/CodeGenOptions.h +++ b/include/clang/CodeGen/CodeGenOptions.h @@ -30,6 +30,9 @@ public: }; unsigned AsmVerbose : 1; /// -dA, -fverbose-asm. + unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors. + unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker + /// aliases to base ctors when possible. unsigned DebugInfo : 1; /// Should generate deubg info (-g). unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled. unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in @@ -53,8 +56,6 @@ public: unsigned UnwindTables : 1; /// Emit unwind tables. unsigned VerifyModule : 1; /// Control whether the module should be run /// through the LLVM Verifier. - unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker - /// aliases to base ctors when possible. /// The code model to use (-mcmodel). std::string CodeModel; @@ -86,6 +87,8 @@ public: public: CodeGenOptions() { AsmVerbose = 0; + CXAAtExit = 1; + CXXCtorDtorAliases = 0; DebugInfo = 0; DisableFPElim = 0; DisableLLVMOpts = 0; @@ -103,7 +106,6 @@ public: UnrollLoops = 0; UnwindTables = 0; VerifyModule = 1; - CXXCtorDtorAliases = 0; Inlining = NoInlining; RelocationModel = "pic"; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 1ecd8d6..feebbc7 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -227,8 +227,6 @@ def code_completion_macros : Flag<"-code-completion-macros">, HelpText<"Include macros in code-completion results">; def disable_free : Flag<"-disable-free">, HelpText<"Disable freeing of memory on exit">; -def empty_input_only : Flag<"-empty-input-only">, - HelpText<"Force running on an empty input file">; def help : Flag<"-help">, HelpText<"Print this help text">; def _help : Flag<"--help">, Alias<help>; @@ -262,6 +260,8 @@ def analyze : Flag<"-analyze">, HelpText<"Run static analysis engine">; def dump_tokens : Flag<"-dump-tokens">, HelpText<"Run preprocessor, dump internal rep of tokens">; +def init_only : Flag<"-init-only">, + HelpText<"Only execute frontend initialization">; def parse_noop : Flag<"-parse-noop">, HelpText<"Run parser with noop callbacks (for timings)">; def fsyntax_only : Flag<"-fsyntax-only">, @@ -355,10 +355,12 @@ def fno_elide_constructors : Flag<"-fno-elide-constructors">, HelpText<"Disable C++ copy constructor elision">; def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">; -def fno_signed_char : Flag<"-fno-signed-char">, - HelpText<"Char is unsigned">; def fno_operator_names : Flag<"-fno-operator-names">, HelpText<"Do not treat C++ operator name keywords as synonyms for operators">; +def fno_signed_char : Flag<"-fno-signed-char">, + HelpText<"Char is unsigned">; +def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, + HelpText<"Don't use __cxa_atexit for calling destructors">; def fconstant_string_class : Separate<"-fconstant-string-class">, MetaVarName<"<class name>">, HelpText<"Specify the class to use for constant Objective-C string objects.">; @@ -448,7 +450,9 @@ def U : JoinedOrSeparate<"-U">, MetaVarName<"<macro>">, HelpText<"Undefine the specified macro">; def undef : Flag<"-undef">, MetaVarName<"<macro>">, HelpText<"undef all system defines">; - +def detailed_preprocessing_record : Flag<"-detailed-preprocessing-record">, + HelpText<"include a detailed record of preprocessing actions">; + //===----------------------------------------------------------------------===// // Preprocessed Output Options //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 59c3946..f49c3b9 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -83,6 +83,9 @@ public: /// Name to use when calling the generic gcc. std::string CCCGenericGCCName; + /// The file to log CC_PRINT_OPTIONS output to, if enabled. + const char *CCPrintOptionsFilename; + /// Whether the driver should follow g++ like behavior. unsigned CCCIsCXX : 1; @@ -92,6 +95,10 @@ public: /// Only print tool bindings, don't build any jobs. unsigned CCCPrintBindings : 1; + /// Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to + /// CCPrintOptionsFilename or to stderr. + unsigned CCPrintOptions : 1; + private: /// Whether to check that input files exist when constructing compilation /// jobs. diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 3eb74ca..71258f9 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -229,6 +229,7 @@ def exported__symbols__list : Separate<"-exported_symbols_list">; def e : JoinedOrSeparate<"-e">; def fPIC : Flag<"-fPIC">, Group<f_Group>; def fPIE : Flag<"-fPIE">, Group<f_Group>; +def faccess_control : Flag<"-faccess-control">, Group<f_Group>; def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>; def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>; def fassume_sane_operator_new : Flag<"-fassume-sane-operator-new">, Group<f_Group>; @@ -262,6 +263,7 @@ def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>; def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>; def fexceptions : Flag<"-fexceptions">, Group<f_Group>; def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>; +def fhosted : Flag<"-fhosted">, Group<f_Group>; def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>; def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; @@ -282,6 +284,7 @@ def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>; def fmudflap : Flag<"-fmudflap">, Group<f_Group>; def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>; def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>; +def fno_access_control : Flag<"-fno-access-control">, Group<f_Group>; def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>; def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, Group<f_Group>; def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>; @@ -300,6 +303,7 @@ def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>; def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>; def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>; def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>; +def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Group>; def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>; def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>; def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>; @@ -312,6 +316,7 @@ def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group> def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>; def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>; def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>; +def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>; def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>; def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>; def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>; @@ -360,6 +365,7 @@ def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>; def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>; def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>; def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>; +def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>; def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>; def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>; def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>; @@ -390,7 +396,7 @@ def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>; def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<i_Group>; def i : Joined<"-i">, Group<i_Group>; def keep__private__externs : Flag<"-keep_private_externs">; -def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput]>; +def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput, RenderJoined]>; def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>; def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>; def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>; diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 27ec12e..61db323 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -14,12 +14,14 @@ #ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H #define LLVM_CLANG_FRONTEND_ASTUNIT_H +#include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/OwningPtr.h" #include "clang/Basic/FileManager.h" #include "clang/Index/ASTLocation.h" #include "llvm/ADT/SmallVector.h" #include "llvm/System/Path.h" +#include <map> #include <string> #include <vector> #include <cassert> @@ -46,6 +48,11 @@ using namespace idx; /// \brief Utility class for loading a ASTContext from a PCH file. /// class ASTUnit { +public: + typedef std::map<FileID, std::vector<PreprocessedEntity *> > + PreprocessedEntitiesByFileMap; +private: + FileManager FileMgr; SourceManager SourceMgr; @@ -53,7 +60,7 @@ class ASTUnit { llvm::OwningPtr<TargetInfo> Target; llvm::OwningPtr<Preprocessor> PP; llvm::OwningPtr<ASTContext> Ctx; - + /// Optional owned invocation, just used to make the invocation used in /// LoadFromCommandLine available. llvm::OwningPtr<CompilerInvocation> Invocation; @@ -89,6 +96,15 @@ class ASTUnit { /// destroyed. llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles; + /// \brief A mapping from file IDs to the set of preprocessed entities + /// stored in that file. + /// + /// FIXME: This is just an optimization hack to avoid searching through + /// many preprocessed entities during cursor traversal in the CIndex library. + /// Ideally, we would just be able to perform a binary search within the + /// list of preprocessed entities. + PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile; + /// \brief Simple hack to allow us to assert that ASTUnit is not being /// used concurrently, which is not supported. /// @@ -162,6 +178,12 @@ public: return TopLevelDecls; } + /// \brief Retrieve the mapping from File IDs to the preprocessed entities + /// within that file. + PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() { + return PreprocessedEntitiesByFile; + } + // Retrieve the diagnostics associated with this AST typedef const StoredDiagnostic * diag_iterator; diag_iterator diag_begin() const { return Diagnostics.begin(); } diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 828e9b5..3444b64 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -34,7 +34,6 @@ class ExternalASTSource; class FileManager; class FrontendAction; class Preprocessor; -class Source; class SourceManager; class TargetInfo; diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 5348e6b..a7b6aa7 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -18,6 +18,22 @@ namespace clang { class FixItRewriter; //===----------------------------------------------------------------------===// +// Custom Consumer Actions +//===----------------------------------------------------------------------===// + +class InitOnlyAction : public FrontendAction { + virtual void ExecuteAction(); + + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + +public: + // Don't claim to only use the preprocessor, we want to follow the AST path, + // but do nothing. + virtual bool usesPreprocessorOnly() const { return false; } +}; + +//===----------------------------------------------------------------------===// // AST Consumer Actions //===----------------------------------------------------------------------===// diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 80ba778..ee3811a 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -36,6 +36,7 @@ namespace frontend { GeneratePCH, ///< Generate pre-compiled header. GeneratePTH, ///< Generate pre-tokenized header. InheritanceView, ///< View C++ inheritance for a specified class. + InitOnly, ///< Only execute frontend initialization. ParseNoop, ///< Parse with noop callbacks. ParsePrintCallbacks, ///< Parse and print each callback. ParseSyntaxOnly, ///< Parse and perform semantic analysis. @@ -71,9 +72,6 @@ public: unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code /// completion results. unsigned DisableFree : 1; ///< Disable memory freeing on exit. - unsigned EmptyInputOnly : 1; ///< Force input files to be treated - /// as if they were empty, for timing - /// the frontend startup. unsigned RelocatablePCH : 1; ///< When generating PCH files, /// instruct the PCH writer to create /// relocatable PCH files. @@ -117,7 +115,6 @@ public: FrontendOptions() { DebugCodeCompletionPrinter = 1; DisableFree = 0; - EmptyInputOnly = 0; ProgramAction = frontend::ParseSyntaxOnly; ActionName = ""; RelocatablePCH = 0; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index e234e98..f975c49 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -215,17 +215,18 @@ namespace clang { /// generate the precompiled header. ORIGINAL_FILE_NAME = 19, - /// \brief Record code for the sorted array of source ranges where - /// comments were encountered in the source code. - COMMENT_RANGES = 20, + /// Record #20 intentionally left blank. /// \brief Record code for the version control branch and revision /// information of the compiler used to build this PCH file. VERSION_CONTROL_BRANCH_REVISION = 21, /// \brief Record code for the array of unused static functions. - UNUSED_STATIC_FUNCS = 22 + UNUSED_STATIC_FUNCS = 22, + /// \brief Record code for the table of offsets to macro definition + /// entries in the preprocessing record. + MACRO_DEFINITION_OFFSETS = 23 }; /// \brief Record types used within a source manager block. @@ -245,10 +246,7 @@ namespace clang { SM_SLOC_INSTANTIATION_ENTRY = 4, /// \brief Describes the SourceManager's line table, with /// information about #line directives. - SM_LINE_TABLE = 5, - /// \brief Describes one header file info [isImport, DirInfo, NumIncludes] - /// ControllingMacro is optional. - SM_HEADER_FILE_INFO = 6 + SM_LINE_TABLE = 5 }; /// \brief Record types used within a preprocessor block. @@ -267,7 +265,14 @@ namespace clang { /// \brief Describes one token. /// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags] - PP_TOKEN = 3 + PP_TOKEN = 3, + + /// \brief Describes a macro instantiation within the preprocessing + /// record. + PP_MACRO_INSTANTIATION = 4, + + /// \brief Describes a macro definition within the preprocessing record. + PP_MACRO_DEFINITION = 5 }; /// \defgroup PCHAST Precompiled header AST constants diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 065006f..73c1bf4 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -21,6 +21,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TemplateBase.h" #include "clang/Lex/ExternalPreprocessorSource.h" +#include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" @@ -53,6 +54,7 @@ class Decl; class DeclContext; class GotoStmt; class LabelStmt; +class MacroDefinition; class NamedDecl; class Preprocessor; class Sema; @@ -106,7 +108,7 @@ public: } /// \brief Receives a HeaderFileInfo entry. - virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) {} + virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) {} /// \brief Receives __COUNTER__ value. virtual void ReadCounter(unsigned Value) {} @@ -130,8 +132,11 @@ public: FileID PCHBufferID, llvm::StringRef OriginalFileName, std::string &SuggestedPredefines); - virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI); + virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); virtual void ReadCounter(unsigned Value); + +private: + void Error(const char *Msg); }; /// \brief Reads a precompiled head containing the contents of a @@ -148,13 +153,14 @@ public: /// actually required will be de-serialized. class PCHReader : public ExternalPreprocessorSource, + public ExternalPreprocessingRecordSource, public ExternalSemaSource, public IdentifierInfoLookup, public ExternalIdentifierLookup, public ExternalSLocEntrySource { public: enum PCHReadResult { Success, Failure, IgnorePCH }; - + friend class PCHValidator; private: /// \ brief The receiver of some callbacks invoked by PCHReader. llvm::OwningPtr<PCHReaderListener> Listener; @@ -293,12 +299,17 @@ private: /// been loaded. llvm::SmallVector<Selector, 16> SelectorsLoaded; - /// \brief A sorted array of source ranges containing comments. - SourceRange *Comments; - - /// \brief The number of source ranges in the Comments array. - unsigned NumComments; - + /// \brief Offsets of all of the macro definitions in the preprocessing + /// record in the PCH file. + const uint32_t *MacroDefinitionOffsets; + + /// \brief The macro definitions we have already loaded. + llvm::SmallVector<MacroDefinition *, 16> MacroDefinitionsLoaded; + + /// \brief The number of preallocated preprocessing entities in the + /// preprocessing record. + unsigned NumPreallocatedPreprocessingEntities; + /// \brief The set of external definitions stored in the the PCH /// file. llvm::SmallVector<uint64_t, 16> ExternalDefinitions; @@ -472,7 +483,7 @@ private: /// /// This routine should only be used for fatal errors that have to /// do with non-routine failures (e.g., corrupted PCH file). - bool Error(const char *Msg); + void Error(const char *Msg); PCHReader(const PCHReader&); // do not implement PCHReader &operator=(const PCHReader &); // do not implement @@ -524,9 +535,7 @@ public: } /// \brief Set the Preprocessor to use. - void setPreprocessor(Preprocessor &pp) { - PP = &pp; - } + void setPreprocessor(Preprocessor &pp); /// \brief Sets and initializes the given Context. void InitializeContext(ASTContext &Context); @@ -547,14 +556,9 @@ public: /// which contains a (typically-empty) subset of the predefines /// build prior to including the precompiled header. const std::string &getSuggestedPredefines() { return SuggestedPredefines; } - - /// \brief Reads the source ranges that correspond to comments from - /// an external AST source. - /// - /// \param Comments the contents of this vector will be - /// replaced with the sorted set of source ranges corresponding to - /// comments in the source code. - virtual void ReadComments(std::vector<SourceRange> &Comments); + + /// \brief Read preprocessed entities into the + virtual void ReadPreprocessedEntities(); /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind. @@ -724,6 +728,9 @@ public: /// \brief Read the set of macros defined by this external macro source. virtual void ReadDefinedMacros(); + /// \brief Retrieve the macro definition with the given ID. + MacroDefinition *getMacroDefinition(pch::IdentID ID); + /// \brief Retrieve the AST context that this PCH reader /// supplements. ASTContext *getContext() { return Context; } @@ -790,6 +797,10 @@ private: uint64_t Offset; }; +inline void PCHValidator::Error(const char *Msg) { + Reader.Error(Msg); +} + } // end namespace clang #endif diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 212130e..e006de5 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -33,6 +33,7 @@ namespace clang { class ASTContext; class LabelStmt; +class MacroDefinition; class MemorizeStatCalls; class Preprocessor; class Sema; @@ -160,6 +161,14 @@ private: /// defined. llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets; + /// \brief Mapping from macro definitions (as they occur in the preprocessing + /// record) to the index into the macro definitions table. + llvm::DenseMap<const MacroDefinition *, pch::IdentID> MacroDefinitions; + + /// \brief Mapping from the macro definition indices in \c MacroDefinitions + /// to the corresponding offsets within the preprocessor block. + std::vector<uint32_t> MacroDefinitionOffsets; + /// \brief Declarations encountered that might be external /// definitions. /// @@ -206,7 +215,6 @@ private: const Preprocessor &PP, const char* isysroot); void WritePreprocessor(const Preprocessor &PP); - void WriteComments(ASTContext &Context); void WriteType(QualType T); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); @@ -234,6 +242,9 @@ public: /// /// \param isysroot if non-NULL, write a relocatable PCH file whose headers /// are relative to the given system root. + /// + /// \param PPRec Record of the preprocessing actions that occurred while + /// preprocessing this file, e.g., macro instantiations void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls, const char* isysroot); @@ -269,6 +280,10 @@ public: return MacroOffsets[II]; } + /// \brief Retrieve the ID number corresponding to the given macro + /// definition. + pch::IdentID getMacroDefinitionID(MacroDefinition *MD); + /// \brief Emit a reference to a type. void AddTypeRef(QualType T, RecordData &Record); diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h index 7ba7c5c..891359b 100644 --- a/include/clang/Frontend/PreprocessorOptions.h +++ b/include/clang/Frontend/PreprocessorOptions.h @@ -36,6 +36,10 @@ public: unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler /// and target specific predefines. + unsigned DetailedRecord : 1; /// Whether we should maintain a detailed + /// record of all macro definitions and + /// instantiations. + /// The implicit PCH included at the start of the translation unit, or empty. std::string ImplicitPCHInclude; @@ -77,7 +81,7 @@ public: } public: - PreprocessorOptions() : UsePredefines(true) {} + PreprocessorOptions() : UsePredefines(true), DetailedRecord(false) {} void addMacroDef(llvm::StringRef Name) { Macros.push_back(std::make_pair(Name, false)); diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 7f43b2a..c1d4831 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -59,7 +59,7 @@ void InitializePreprocessor(Preprocessor &PP, /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. -bool ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts); +void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts); /// DoPrintPreprocessedInput - Implement -E mode. void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS, diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h index 6f7ebbe..08adbb0 100644 --- a/include/clang/Frontend/VerifyDiagnosticsClient.h +++ b/include/clang/Frontend/VerifyDiagnosticsClient.h @@ -16,7 +16,6 @@ namespace clang { class Diagnostic; -class SourceMgr; class TextDiagnosticBuffer; /// VerifyDiagnosticsClient - Create a diagnostic client which will use markers diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 16b8379..978585c 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -214,9 +214,10 @@ public: void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } - typedef std::vector<HeaderFileInfo>::iterator header_file_iterator; - header_file_iterator header_file_begin() { return FileInfo.begin(); } - header_file_iterator header_file_end() { return FileInfo.end(); } + typedef std::vector<HeaderFileInfo>::const_iterator header_file_iterator; + header_file_iterator header_file_begin() const { return FileInfo.begin(); } + header_file_iterator header_file_end() const { return FileInfo.end(); } + unsigned header_file_size() const { return FileInfo.size(); } // Used by PCHReader. void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h new file mode 100644 index 0000000..ef28af9 --- /dev/null +++ b/include/clang/Lex/PreprocessingRecord.h @@ -0,0 +1,274 @@ +//===--- PreprocessingRecord.h - Record of Preprocessing --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PreprocessingRecord class, which maintains a record +// of what occurred during preprocessing. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H +#define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" +#include <vector> + +namespace clang { + class IdentifierInfo; + class PreprocessingRecord; +} + +/// \brief Allocates memory within a Clang preprocessing record. +void* operator new(size_t bytes, clang::PreprocessingRecord& PR, + unsigned alignment = 8) throw(); + +/// \brief Frees memory allocated in a Clang preprocessing record. +void operator delete(void* ptr, clang::PreprocessingRecord& PR, + unsigned) throw(); + +namespace clang { + class MacroDefinition; + + /// \brief Base class that describes a preprocessed entity, which may be a + /// preprocessor directive or macro instantiation. + class PreprocessedEntity { + public: + /// \brief The kind of preprocessed entity an object describes. + enum EntityKind { + /// \brief A macro instantiation. + MacroInstantiationKind, + + /// \brief A preprocessing directive whose kind is not specified. + /// + /// This kind will be used for any preprocessing directive that does not + /// have a more specific kind within the \c DirectiveKind enumeration. + PreprocessingDirectiveKind, + + /// \brief A macro definition. + MacroDefinitionKind, + + FirstPreprocessingDirective = PreprocessingDirectiveKind, + LastPreprocessingDirective = MacroDefinitionKind + }; + + private: + /// \brief The kind of preprocessed entity that this object describes. + EntityKind Kind; + + /// \brief The source range that covers this preprocessed entity. + SourceRange Range; + + protected: + PreprocessedEntity(EntityKind Kind, SourceRange Range) + : Kind(Kind), Range(Range) { } + + public: + /// \brief Retrieve the kind of preprocessed entity stored in this object. + EntityKind getKind() const { return Kind; } + + /// \brief Retrieve the source range that covers this entire preprocessed + /// entity. + SourceRange getSourceRange() const { return Range; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *) { return true; } + + // Only allow allocation of preprocessed entities using the allocator + // in PreprocessingRecord or by doing a placement new. + void* operator new(size_t bytes, PreprocessingRecord& PR, + unsigned alignment = 8) throw() { + return ::operator new(bytes, PR, alignment); + } + + void* operator new(size_t bytes, void* mem) throw() { + return mem; + } + + void operator delete(void* ptr, PreprocessingRecord& PR, + unsigned alignment) throw() { + return ::operator delete(ptr, PR, alignment); + } + + void operator delete(void*, std::size_t) throw() { } + void operator delete(void*, void*) throw() { } + + private: + // Make vanilla 'new' and 'delete' illegal for preprocessed entities. + void* operator new(size_t bytes) throw(); + void operator delete(void* data) throw(); + }; + + /// \brief Records the location of a macro instantiation. + class MacroInstantiation : public PreprocessedEntity { + /// \brief The name of the macro being instantiation. + IdentifierInfo *Name; + + /// \brief The definition of this macro. + MacroDefinition *Definition; + + public: + MacroInstantiation(IdentifierInfo *Name, SourceRange Range, + MacroDefinition *Definition) + : PreprocessedEntity(MacroInstantiationKind, Range), Name(Name), + Definition(Definition) { } + + /// \brief The name of the macro being instantiated. + IdentifierInfo *getName() const { return Name; } + + /// \brief The definition of the macro being instantiated. + MacroDefinition *getDefinition() const { return Definition; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *PE) { + return PE->getKind() == MacroInstantiationKind; + } + static bool classof(const MacroInstantiation *) { return true; } + + }; + + /// \brief Records the presence of a preprocessor directive. + class PreprocessingDirective : public PreprocessedEntity { + public: + PreprocessingDirective(EntityKind Kind, SourceRange Range) + : PreprocessedEntity(Kind, Range) { } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *PD) { + return PD->getKind() >= FirstPreprocessingDirective && + PD->getKind() <= LastPreprocessingDirective; + } + static bool classof(const PreprocessingDirective *) { return true; } + }; + + /// \brief Record the location of a macro definition. + class MacroDefinition : public PreprocessingDirective { + /// \brief The name of the macro being defined. + const IdentifierInfo *Name; + + /// \brief The location of the macro name in the macro definition. + SourceLocation Location; + + public: + explicit MacroDefinition(const IdentifierInfo *Name, SourceLocation Location, + SourceRange Range) + : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name), + Location(Location) { } + + /// \brief Retrieve the name of the macro being defined. + const IdentifierInfo *getName() const { return Name; } + + /// \brief Retrieve the location of the macro name in the definition. + SourceLocation getLocation() const { return Location; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const PreprocessedEntity *PE) { + return PE->getKind() == MacroDefinitionKind; + } + static bool classof(const MacroDefinition *) { return true; } + }; + + /// \brief An abstract class that should be subclassed by any external source + /// of preprocessing record entries. + class ExternalPreprocessingRecordSource { + public: + virtual ~ExternalPreprocessingRecordSource(); + + /// \brief Read any preallocated preprocessed entities from the external + /// source. + virtual void ReadPreprocessedEntities() = 0; + }; + + /// \brief A record of the steps taken while preprocessing a source file, + /// including the various preprocessing directives processed, macros + /// instantiated, etc. + class PreprocessingRecord : public PPCallbacks { + /// \brief Allocator used to store preprocessing objects. + llvm::BumpPtrAllocator BumpAlloc; + + /// \brief The set of preprocessed entities in this record, in order they + /// were seen. + std::vector<PreprocessedEntity *> PreprocessedEntities; + + /// \brief Mapping from MacroInfo structures to their definitions. + llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions; + + /// \brief External source of preprocessed entities. + ExternalPreprocessingRecordSource *ExternalSource; + + /// \brief The number of preallocated entities (that are known to the + /// external source). + unsigned NumPreallocatedEntities; + + /// \brief Whether we have already loaded all of the preallocated entities. + mutable bool LoadedPreallocatedEntities; + + void MaybeLoadPreallocatedEntities() const ; + + public: + PreprocessingRecord(); + + /// \brief Allocate memory in the preprocessing record. + void *Allocate(unsigned Size, unsigned Align = 8) { + return BumpAlloc.Allocate(Size, Align); + } + + /// \brief Deallocate memory in the preprocessing record. + void Deallocate(void *Ptr) { } + + // Iteration over the preprocessed entities. + typedef std::vector<PreprocessedEntity *>::iterator iterator; + typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator; + iterator begin(bool OnlyLocalEntities = false); + iterator end(bool OnlyLocalEntities = false); + const_iterator begin(bool OnlyLocalEntities = false) const; + const_iterator end(bool OnlyLocalEntities = false) const; + + /// \brief Add a new preprocessed entity to this record. + void addPreprocessedEntity(PreprocessedEntity *Entity); + + /// \brief Set the external source for preprocessed entities. + void SetExternalSource(ExternalPreprocessingRecordSource &Source, + unsigned NumPreallocatedEntities); + + /// \brief Set the preallocated entry at the given index to the given + /// preprocessed entity. + void SetPreallocatedEntity(unsigned Index, PreprocessedEntity *Entity); + + /// \brief Register a new macro definition. + void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *MD); + + /// \brief Retrieve the preprocessed entity at the given index. + PreprocessedEntity *getPreprocessedEntity(unsigned Index) { + assert(Index < PreprocessedEntities.size() && + "Out-of-bounds preprocessed entity"); + return PreprocessedEntities[Index]; + } + + /// \brief Retrieve the macro definition that corresponds to the given + /// \c MacroInfo. + MacroDefinition *findMacroDefinition(const MacroInfo *MI); + + virtual void MacroExpands(const Token &Id, const MacroInfo* MI); + virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI); + virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI); + }; +} // end namespace clang + +inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR, + unsigned alignment) throw() { + return PR.Allocate(bytes, alignment); +} + +inline void operator delete(void* ptr, clang::PreprocessingRecord& PR, + unsigned) throw() { + PR.Deallocate(ptr); +} + +#endif // LLVM_CLANG_LEX_PREPROCESSINGRECORD_H diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 2b27a06..23c118d 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -43,7 +43,8 @@ class ScratchBuffer; class TargetInfo; class PPCallbacks; class DirectoryLookup; - +class PreprocessingRecord; + /// Preprocessor - This object engages in a tight little dance with the lexer to /// efficiently preprocess tokens. Lexers know only about tokens within a /// single source file, and don't know anything about preprocessor-level issues @@ -209,6 +210,13 @@ class Preprocessor { unsigned NumCachedTokenLexers; TokenLexer *TokenLexerCache[TokenLexerCacheSize]; + /// \brief A record of the macro definitions and instantiations that + /// occurred during preprocessing. + /// + /// This is an optional side structure that can be enabled with + /// \c createPreprocessingRecord() prior to preprocessing. + PreprocessingRecord *Record; + private: // Cached tokens state. typedef llvm::SmallVector<Token, 1> CachedTokensTy; @@ -348,9 +356,17 @@ public: /// It is an error to remove a handler that has not been registered. void RemoveCommentHandler(CommentHandler *Handler); + /// \brief Retrieve the preprocessing record, or NULL if there is no + /// preprocessing record. + PreprocessingRecord *getPreprocessingRecord() const { return Record; } + + /// \brief Create a new preprocessing record, which will keep track of + /// all macro expansions, macro definitions, etc. + void createPreprocessingRecord(); + /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. - void EnterMainSourceFile(); + bool EnterMainSourceFile(); /// EnterSourceFile - Add a source file to the top of the include stack and /// start lexing tokens from it instead of the current buffer. Return true @@ -595,7 +611,7 @@ public: // Otherwise, fall back on getCharacterData, which is slower, but always // works. - return *SourceMgr.getCharacterData(Tok.getLocation()); + return *SourceMgr.getCharacterData(Tok.getLocation(), Invalid); } /// CreateString - Plop the specified string into a scratch buffer and set the diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index f211b5c..b79e698 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -153,10 +153,6 @@ public: /// an empty string if not. This is used for pretty crash reporting. virtual std::string getDeclName(DeclPtrTy D) { return ""; } - /// \brief Invoked for each comment in the source code, providing the source - /// range that contains the comment. - virtual void ActOnComment(SourceRange Comment) { } - //===--------------------------------------------------------------------===// // Declaration Tracking Callbacks. //===--------------------------------------------------------------------===// @@ -727,9 +723,17 @@ public: /// ActOnTagFinishDefinition - Invoked once we have finished parsing /// the definition of a tag (enumeration, class, struct, or union). + /// + /// The scope is the scope of the tag definition. virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl, SourceLocation RBraceLoc) { } + /// ActOnTagDefinitionError - Invoked if there's an unrecoverable + /// error parsing the definition of a tag. + /// + /// The scope is the scope of the tag definition. + virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl) { } + virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl, DeclPtrTy LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index f034aa1..411162b 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -90,7 +90,6 @@ class Parser { llvm::OwningPtr<PragmaHandler> PackHandler; llvm::OwningPtr<PragmaHandler> UnusedHandler; llvm::OwningPtr<PragmaHandler> WeakHandler; - llvm::OwningPtr<clang::CommentHandler> CommentHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ |